When importing a C enum with the ns_error_domain attribute, we
synthesize a struct containing an NSError object to represent errors
in that domain. That synthesized struct should have a mangled name
that ties it to the original C enum, if we want it to be stable, and
now it does.
Before: $SSC7MyErrorV (a normal struct, which is a lie)
After: $SSC11MyErrorCode13ns_error_enumLLV
kind=Global
kind=Structure
kind=Module, text="__C_Synthesized"
kind=PrivateDeclName
kind=Identifier, text="ns_error_enum"
kind=Identifier, text="MyErrorCode"
Using the "private discriminator" feature allows us to pack in extra
information about the declaration without changing the mangling
grammar, and without stepping on anything the importer is using.
More rdar://problem/24688918
This has three principal advantages:
- It gives some additional type-safety when working
with known accessors.
- It makes it significantly easier to test whether a declaration
is an accessor and encourages the use of a common idiom.
- It saves a small amount of memory in both FuncDecl and its
serialized form.
These aren't clang::TypedefNameDecls, but they should be treated like
them. There's not a great way to test this because the imported type
is a typealias and therefore not canonical, but fortunately debug info
preserves sugar.
...and "So" for the Swift-side representation of an Objective-C-side
conformance. These manglings are never used in public symbols, but
they're stil good to be consistent about.
This makes them consistent no matter what shenanigans are pulled by
the importer, particularly NS_ENUM vs. NS_OPTIONS and NS_SWIFT_NAME.
The 'NSErrorDomain' API note /nearly/ works with this, but the
synthesized error struct is still mangled as a Swift declaration,
which means it's not rename-stable. See follow-up commits.
The main place where this still falls down is NS_STRING_ENUM: when
this is applied, a typedef is imported as a unique struct, but without
it it's just a typealias for the underlying type. There's also still a
problem with synthesized conformances, which have a module mangled
into the witness table symbol even though that symbol is linkonce_odr.
rdar://problem/31616162
1) Move existing SyntaxSugarTypes under a new subclass called UnarySyntaxSugarType.
2) Make DictionaryType subclass SyntaxSugarType.
This helps improve getDesugaredType() performance by ensuring that
ImplOrContext is stored at the same field offset in memory.
This also de-boilerplates some AST walking.
Rather than storing contextual types in the type witnesses and associated
conformances of NormalProtocolConformance, store only interface types.
@huonw did most of the work here, and @DougGregor patched things up to
complete the change.
Currently if function has a single parameter we'd skip mangling some of the
parameter flags e.g. `__shared`, `inout` still works because it's part of
the type itself (currently) but would be broken too if that were to change.
Support for @noescape SILFunctionTypes.
These are the underlying SIL changes necessary to implement the new
closure capture ABI.
Note: This includes a change to function name mangling that
primarily affects reabstraction thunks.
The new ABI will allow stack allocation of non-escaping closures as a
simple optimization.
The new ABI, and the stack allocation optimization, also require
closure context to be @guaranteed. That will be implemented as the
next step.
Many SIL passes pattern match partial_apply sequences. These all
needed to be fixed to handle the convert_function that SILGen now
emits. The conversion is now needed whenever a function declaration,
which has an escaping type, is passed into a @NoEscape argument.
In addition to supporting new SIL patterns, some optimizations like
inlining and SIL combine are now stronger which could perturb some
benchmark results.
These underlying SIL changes should be merged now to avoid conflicting
with other work. Minor benchmark discrepancies can be investigated as part of
the stack-allocation work.
* Add a noescape attribute to SILFunctionType.
And set this attribute correctly when lowering formal function types to SILFunctionTypes based on @escaping.
This will allow stack allocation of closures, and unblock a related ABI change.
* Flip the polarity on @noescape on SILFunctionType and clarify that
we don't default it.
* Emit withoutActuallyEscaping using a convert_function instruction.
It might be better to use a specialized instruction here, but I'll leave that up to Andy.
Andy: And I'll leave that to Arnold who is implementing SIL support for guaranteed ownership of thick function types.
* Fix SILGen and SIL Parsing.
* Fix the LoadableByAddress pass.
* Fix ClosureSpecializer.
* Fix performance inliner constant propagation.
* Fix the PartialApplyCombiner.
* Adjust SILFunctionType for thunks.
* Add mangling for @noescape/@escaping.
* Fix test cases for @noescape attribute, mangling, convert_function, etc.
* Fix exclusivity test cases.
* Fix AccessEnforcement.
* Fix SILCombine of convert_function -> apply.
* Fix ObjC bridging thunks.
* Various MandatoryInlining fixes.
* Fix SILCombine optimizeApplyOfConvertFunction.
* Fix more test cases after merging (again).
* Fix ClosureSpecializer. Hande convert_function cloning.
Be conservative when combining convert_function. Most of our code doesn't know
how to deal with function type mismatches yet.
* Fix MandatoryInlining.
Be conservative with function conversion. The inliner does not yet know how to
cast arguments or convert between throwing forms.
* Fix PartialApplyCombiner.
Currently when function types like `(_: Int...) -> Void` are mangled
their names are going to include enclosing sugar BoundGenericType(Array),
which is not necessary and doesn’t play well with `AnyFunctionType::Param`
which strips the sugar away.
Resolves: rdar://problem/34941557
Introduce GenericSignature::requirementsNotSatisfiedBy(otherSig) to
compute the set of requirements in a generic signature that aren't satisfied
by some other generic signature. This is used both for conditional
conformances (the conditional requirements) and for name mangling of
constrained extensions/protocol conformances.
Conformance manglings, which are used for witness tables and related witness
thunks, mangle the generic signature of the conformance. Since conformances
also describe the conforming type, mangle the conformances's generic signature
relative to the conforming type's generic signature.
In practice, this means that we don't mangle any part of the generic signature
into a conformance mangling now, so we see a decent win: 2.3% smaller
trie and 6.4% smaller strings section in the standard library binary.
When conditional conformances land, we'll see some generic signatures
mangling again (for the additional requirements of the constrained
extension).
Rather than mangling the complete generic signature of a constrained
extension, only mangle the requirements not already satisfied by the
nominal type. For example, given:
extension Dictionary where Value: Equatable {
// OLD: _T0s10DictionaryV2t3s8HashableRzs9EquatableR_r0_lE3baryyF
// NEW: _T0s10DictionaryV2t3s9EquatableR_rlE3baryyF
public func bar() { }
}
In the existing mangling, we mangle the `Key: Hashable` requirement that’s
part of the generic signature. With this change, we only mangle the new
requirement (`Value: Equatable`).
This is a win for constrained extensions *except* in the case of a
constrained extension of a nominal type with a single, unconstrained
generic parameter:
extension Array where Element: Equatable {
// OLD: _T0Sa2t3s9EquatableRzlE3baryyF
// NEW would be: _T0Sa2t3s9EquatableRzrlE3baryyF
public func bar() { }
}
Check explicily for this shortcut mangling and fall back to the old
path, so this change is a strict improvement.
The mangler had some ad hoc logic for only mangling requirements in a
generic signature that are not requirements in the parent context's
generic signature. However, it was based on an heuristic that isn't
correct. Replace that logic with a check to determine whether
the requirement is satisfied by the parent generic signature, which is
far simpler.
Fixes rdar://problem/31889040 / SR-6107.
... using an inline namespace as the parent of the outermost
declaration(s) that have private or fileprivate accessability. Once
LLDB supports this we can retire the existing hack of storing it as a
fake command line argument.
rdar://problem/18296829
... using an inline namespace as the parent of the outermost
declaration(s) that have private or fileprivate accessability. Once
LLDB supports this we can retire the existing hack of storing it as a
fake command line argument.
rdar://problem/18296829
"Accessibility" has a different meaning for app developers, so we've
already deliberately excised it from our diagnostics in favor of terms
like "access control" and "access level". Do the same in the compiler
now that we aren't constantly pulling things into the release branch.
This commit changes the 'Accessibility' enum to be named 'AccessLevel'.
Also, begin to pass around base types instead of raw InOutType types. Ideally, only Sema needs to deal with them, but this means that a bunch of callers need to unwrap any inouts that might still be lying around before forming these types.
Multiple parts of the compiler were slicing, dicing, or just dropping these flags. Because I intend to use them for the new function type representation, I need them to be preserved all across the compiler. As a first pass, this stubs in what will eventually be structural rules as asserts and tracks down all callers of consequence to conform to the new invariants.
This is temporary.
Special DeclNames represent names that do not have an identifier in the
surface language. This implies serializing the information about whether
a name is special together with its identifier (if it is not special)
in both the module file and the swift lookup table.
As a step toward eliminating the single input type
representation of function parameters, add more constraints on that
input type. It can be one of:
* A tuple type, for multiple parameters,
* A parenthesized type, for a single parameter, or
* A type variable type, for specific cases in the type checker
Enforce these constraints for *canonical* types as well, so the
canonical form of:
typealias MyInt = Int
typealias MyFuncType = (MyInt) -> Int
is now:
(Int) -> Int
rather than:
Int -> Int
This affects canonicalization of FunctionType and
GenericFunctionType. Enchance both, as well as their Can*Type
counterparts, with "get" operators that take an array of
AnyFunctionType::Param, and start switching a few clients over to this
new, preferred API.
Previously, two constructors with the same full name and argument
types would get identical manglings even if they were declared
'private' or 'fileprivate' in different files. This would lead to
symbol collisions in whole-module builds. Add a new mangling node for
private discriminators on base-name-less decls to make this unique.
This still doesn't fix the existing issue with private members, named
or not, conflicting when they're in the /same/ file, but since Swift 4
makes those members visible to one another (SE-0169) that's only an
issue in Swift 3 mode anyway, and as such probably won't get fixed at
all.
rdar://problem/27758199
With the introduction of special decl names, `Identifier getName()` on
`ValueDecl` will be removed and pushed down to nominal declarations
whose name is guaranteed not to be special. Prepare for this by calling
to `DeclBaseName getBaseName()` instead where appropriate.
This reverts commit 25985cb764. For now,
we're trying to avoid spurious non-structural changes to the mangling,
so that the /old/ mangling doesn't appear to change. That doesn't mean
no changes at all, but we can save this one for later.