Following classes provide symbol mangling for specific purposes:
*) Mangler: the base mangler class, just providing some basic utilities
*) ASTMangler: for mangling AST declarations
*) SpecializationMangler: to be used in the optimizer for mangling specialized function names
*) IRGenMangler: mangling all kind of symbols in IRGen
All those classes are not used yet, so it’s basically a NFC.
Another change is that some demangler node types are added (either because they were missing or the new demangler needs them).
Those new nodes also need to be handled in the old demangler, but this should also be a NFC as those nodes are not created by the old demangler.
My plan is to keep the old and new mangling implementation in parallel for some time. After that we can remove the old mangler.
Currently the new implementation is scoped in the NewMangling namespace. This namespace should be renamed after the old mangler is removed.
Previously we had two separate mechanisms to turn a metatype
into a string. The swift_typeName() function was used to print
the metatype in a human-readable fashion, whereas the
_swift_buildDemanglingForMetadata() was used when naming
generated generic Objective-C classes.
Unify them, since what swift_typeName() does is redundant;
instead of going directly from the metatype to a human-readable
string, we can get the mangling, and print that using the
demangler.
This fixes some issues with unnecessary parenthesis when
printing function types, and also allows Objective-C classes
to be instantiated with nested generic types as parameters.
With a bit of work, we can re-purpose the existing
QualifiedArchetype mangling to cover this case.
This allows us to get rid of a usage of
ArchetypeType::getSelfProtocol(), which we want to remove.
Local generic types can appear inside functions inside extensions
of other types. When demangling bound generic arguments, the demangler
assumed that a module was the only other kind of context outside
of nominal types.
rdar://problem/27573079
* Add UnsafeRawPointer type and API.
As proposed in SE-0107: UnsafeRawPointer.
https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md
The fundamental difference between Unsafe[Mutable]RawPointer and
Unsafe[Mutable]Pointer<Pointee> is simply that the former is used for "untyped"
memory access, and the later is used for "typed" memory access. Let's refer to
these as "raw pointers" and "typed pointers". Because operations on raw pointers
access untyped memory, the compiler cannot make assumptions about the underlying
type of memory and must be conservative. With operations on typed pointers, the
compiler may make strict assumptions about the type of the underlying memory,
which allows more aggressive optimization.
Memory can only be accessed by a typed pointer when it is currently
bound to the Pointee type. Memory can be bound to type `T` via:
- `UnsafePointer<T>.allocate(capacity: n)`
- `UnsafePointer<Pointee>.withMemoryRebound(to: T.self, capacity: n) {...}`
- `UnsafeMutableRawPointer.initializeMemory(as: T.self, at: i, count: n, to: x)`
- `UnsafeMutableRawPointer.initializeMemory(as: T.self, from: p, count: n)`
- `UnsafeMutableRawPointer.moveInitializeMemory(as: T.self, from: p, count: n)`
- `UnsafeMutableRawPointer.bindMemory(to: T.self, capacity: n)`
Mangle UnsafeRawPointer as predefined substitution 'Sv' for Swift void
pointer ([urp] are taken).
* UnsafeRawPointer minor improvements.
Incorporate Dmitri's feedback.
Properly use a _memmove helper.
Add load/storeBytes alignment precondition checks.
Reword comments.
Demangler tests.
* Fix name mangling test cases.
* Fix bind_memory specialization.
- All parts of the compiler now use ‘P1 & P2’ syntax
- The demangler and AST printer wrap the composition in parens if it is
in a metatype lookup
- IRGen mangles compositions differently
- “protocol<>” is now “swift.Any”
- “protocol<_TP1P,_TP1Q>” is now “_TP1P&_TP1Q”
- Tests cases are updated and added to test the new syntax and mangling
Change the 'G' mangling to include generic parameters from
all levels of nested nominal types, and not just the innermost.
Note that the raw mangling syntax is something like this for
a nested type 'A<Int>.B<String>':
- bound_generic
- struct 'B'
- struct 'A'
- module 'M'
- args
- Int
- args
- String
However, the actual mangling tree is more along the lines of:
- bound_generic_struct 'B'
- bound_generic_struct 'A'
- module 'M'
- args
- Int
- args
- String
This arrangement improves the quality of substitutions (we are
more likely to have a substitution for the entire unbound
generic type name 'A.B' around), and simplifies a few other
details.
Unfortunately, the remangling logic becomes slightly grotesque.
A simple SILGen test for nested generics exercises the mangling,
and ensures that Sema and SILGen do not crash with nested generics.
More detailed SILGen tests, as well as IRGen support for nested
generics is next.
Rather than duplicating the constant value, use the `sizeof` operator to have
the value propogate from the static buffer allocation. Any standards conforming
implementation of `snprintf` will null-terminate the output unless the buffer is
NULL (a zero-sized buffer is passed to the call). On Windows, where this is not
the case, the function is named `_snprintf` which ensures that we do not
accidentally end up with the incorrect behaviour.
not have access to their type arguments at runtime. Use this to
fix the emission of native thunks for imported ObjC-generic
initializers, since they may need to perform bridging.
For now, pseudo-genericity is all-or-nothing, but we may want to
make it apply only to certain type arguments.
Also, clean up some code that was using dead mangling nodes.
These are really long and don't tell you anything interesting
in backtraces. They can also take up quite a bit of valuable
real estate in vertical layouts.
rdar://problem/22982415
Fixed an apparent typo where two cases tested for the same lowercase 'd' pattern, resulting in one case never being used. According to the comment block, doc/ABI.rst and lib/AST/Mangle.cpp, the second case should be an uppercase 'D'.
An upcoming change has the SIL Optimizer drop the [fragile]
attribute from the specialized callee, unless the caller
is itself [fragile].
Since we need to distinguish specializations from fragile
and non-fragile contexts, add a new mangling node to
represent this concept.
Before the refactor, a dangling reference to a string may be stored in a DemanglePrinter in at least the following cases:
1) If an lvalue DemanglePrinter is initialized with an rvalue string:
DemanglePrinter printer("abc");
2) If an lvalue DemanglePrinter is initialized with an lvalue string which doesn't live as long as the printer:
unique_ptr<DemanglePrinter> printer;
{
std::string s = "abc";
printer = make_unique<DemanglePrinter>(s);
}
// Reference stored in printer is dangling
In addition, in all existing cases in the code where an lvalue DemanglePrinter is used, an empty string is initialized just before it, which isn't DRY, and is related to the previous problem - the coder shouldn't be expected to maintain the lifetime of a string separate from the DemanglePrinter which references it.
In addition, before the refactor, in any in-line use of DemanglePrinter it is constructed with an empty string parameter (in which to construct the string), but this doesn't look very clean.
The refactor solves the above issues by maintaining its own string as a member, while still enabling the original intent of being able to use DemanglePrinter both as an lvalue constructively before getting its value, and in-line as an rvalue.
This reverts commit 2262bd579a.
This information isn't necessary for field descriptor lookup,
after all. It's only the fields that need to have generic information,
which is already in the field descriptor.
Previously, the mangling didn't include generics, but these are
needed to key off of the new field descriptor metadata, as well
as to construct type references for the nominal type.
Make it clear that this is not a nested type or submodule or anything.
Mangled: _TFE9ExtModuleV9DefModule1A4testfT_T_
Before: ext.ExtModule.DefModule.A.test () -> ()
After: (extension in ExtModule):DefModule.A.test () -> ()
of associated types in protocol witness tables.
We use the global access functions when the result isn't
dependent, and a simple accessor when the result can be cheaply
recovered from the conforming metadata. Otherwise, we add a
cache slot to a private section of the witness table, forcing
an instantiation per conformance. Like generic type metadata,
concrete instantiations of generic conformances are memoized.
There's a fair amount of code in this patch that can't be
dynamically tested at the moment because of the widespread
reliance on recursive expansion of archetypes / dependent
types. That's something we're now theoretically in a position
to change, and as we do so, we'll test more of this code.
This speculatively re-applies 7576a91009,
i.e. reverts commit 11ab3d537f.
We have not been able to duplicate the build failure in
independent testing; it might have been spurious or unrelated.
of associated types in protocol witness tables.
We use the global access functions when the result isn't
dependent, and a simple accessor when the result can be cheaply
recovered from the conforming metadata. Otherwise, we add a
cache slot to a private section of the witness table, forcing
an instantiation per conformance. Like generic type metadata,
concrete instantiations of generic conformances are memoized.
There's a fair amount of code in this patch that can't be
dynamically tested at the moment because of the widespread
reliance on recursive expansion of archetypes / dependent
types. That's something we're now theoretically in a position
to change, and as we do so, we'll test more of this code.
This reverts commit 6528ec2887, i.e.
it reapplies b1e3120a28, with a fix
to unbreak release builds.
This reverts commit b1e3120a28.
Reverting because this patch uses WitnessTableBuilder::PI in NDEBUG code.
That field only exists when NDEBUG is not defined, but now NextCacheIndex, a
field that exists regardless, is being updated based on information from PI.
This problem means that Release builds do not work.
of associated types in protocol witness tables.
We use the global access functions when the result isn't
dependent, and a simple accessor when the result can be cheaply
recovered from the conforming metadata. Otherwise, we add a
cache slot to a private section of the witness table, forcing
an instantiation per conformance. Like generic type metadata,
concrete instantiations of generic conformances are memoized.
There's a fair amount of code in this patch that can't be
dynamically tested at the moment because of the widespread
reliance on recursive expansion of archetypes / dependent
types. That's something we're now theoretically in a position
to change, and as we do so, we'll test more of this code.
Use 'XH' rather than 'H' for SIL box types to keep SIL-specific concepts
under 'X' rather than claiming more of the top-level mangling namespace.
Suggested by @jckarter.
The SIL optimizer's closure specialization pass clones functions that
take closures as arguments and generates a new function with a direct
call to the closure function. The cloned function has new arguments
added for the values that are captured by the closure.
In the cases where the closure takes a @box argument, we were hitting an
assert attempting to mangle the name of the newly generated function,
since it now has a @box argument as a parameter. We don't normally
expect @box arguments during mangling because they do not exist prior to
SILGen, but since we generate new manglings throughout the optimizer we
need to be able to mangle (and demangle) these types.
Fixes rdar://problem/23893290.
Match the new SILGen pattern, where only the box parameter is partially applied to the closure, and the address of the value is projected on the callee side.
This reverts r32940. In reality this is not dead code, because
foreign to native thunks have the _TTO mangling. We need better
tests, which I will add in an upcoming commit.
Swift SVN r32945
And include some supplementary mangling changes:
- Give the first generic param (depth=0, index=0) a single character mangling. Even after removing the self type from method declaration types, 'Self' still shows up very frequently in protocol requirement signatures.
- Fix the mangling of generic parameter counts to elide the count when there's only one parameter at the starting depth of the mangling.
Together these carve another 154KB out of a debug standard library. There's some awkwardness in demangled strings that I'll clean up in subsequent commits; since decl types now only mangle the number of generic params at their own depth, it's context-dependent what depths those represent, which we get wrong now. Currying markers are also wrong, but since free function currying is going away, we can mangle the partial application thunks in different ways.
Swift SVN r32896
Canonical dependent member types are always based from a generic parameter, so we can use a more optimal mangling that assumes this. We can also introduce substitutions for AssociatedTypeDecls, and when a generic parameter in a signature is constrained by a single protocol, we can leave that protocol qualification out of the unsubstituted associated type mangling. These optimizations together shrink the standard library by 117KB, and bring the length of the longest Swift symbol in the stdlib down from 578 to 334 characters, shorter than the longest C++ symbol in the stdlib.
Swift SVN r32786
A microoptimization; since the module is likely to come up often in the subsequent mangling, we want to make it more likely to get the coveted S_ substitution.
Swift SVN r32784