The `projection` flag indicates that `index_addr` projects an element address from an array base address, as opposed to being used for general pointer arithmetic.
When this flag is set, the result address can only reach the single element at the given index — it is not possible to chain multiple `index_addr` instructions to reach other array elements from the result.
Without this flag, the result may be used as the base of another `index_addr`, allowing arithmetic across element boundaries (e.g. an `index_addr` with index 1 followed by an `index_addr` with index 2 reaches the element at offset 3).
An `index_addr [projection]` is mandatory to go from an array base address to an element - even if it's the first element, i.e. the index is zero.
This means that the optimizer must not remove `index_addr [projection]` with a zero index.
If type associated with the function is `nonisolated(nonsending)`
transfer that onto the new `SILFunction` itself. Without this
`nonisolated(nonsending)` + `@_alwaysEmitIntoClient` declarations
could be optimized incorrectly.
This ensures that corrupt data doesn't cause an out of bounds read even in no-asserts builds.
Also cap NumLocs against the remaining bytes in DocRangesData so the consumer loop cannot read past the buffer.
rdar://177455633
In Embedded Swift, global variables are generally emitted into client
modules. However, if a global variable is @export(interface), we need
to treat it as something we externally reference in client modules. Do
so, by adjusting linkage on deserialization in the same manner as we do
for SIL functions.
Fixes rdar://178238940.
When a struct has stored properties from an internal bridging header,
add @_hasHiddenStoredProperties to force address-only on both library
and client sides, and resolve layout via the defining module's
HiddenTypeLayouts table in IRGen.
Making these structs loadable is challenging because library and client
must agree on the register-passing scheme (which registers carry which
fields), and that scheme depends on the full type structure that the
client cannot see. Address-only sidesteps this by passing everything
indirectly.
Tests: hidden-type-irgen.swift verifies the Client's IR has correct
alloca sizes/alignments and outlined copy witnesses without referencing
hidden C symbols. hidden-type-runtime.swift builds a dylib + executable
and verifies values round-trip correctly across the boundary at runtime.
Qualified import for macro has not been implemented. Until then, ignore macros in lookup so that a macro and a struct sharing the same name won't cause ambiguity.
rdar://174526734
Just like we do with SILFunction, allow a code generation model to be
specified on a SILGlobalVariable and maintain that through the printed
and serialized forms.
The default code generation model for Embedded Swift is "inlinable".
DeferredCodeGen made the default code generation model
"implementation", and there was no spelling for "interface".
Introduce the experimental feature CodeGenerationModel=<model>, which
can be any of those three options. The default remains "inlinable", but
one can now specify "implementation" (which keeps most everything in
SIL) or "interface" (which only keeps the generic things in SIL). The
"interface" mode is more like non-embedded Swift for non-generic
declarations, emitting them into the IR (only) but not SIL. Generic
declarations would remain in SIL.
Implements rdar://172433062.
The substitution is driven by a canonical type to mangled name table on ASTContext,
populated by exportability checking at the same site where the corresponding
diagnostics are suppressed. After this change, the module emitter and module
loader see hidden types differently: the emitter still sees the real types
defined in the bridging header, while the loader sees only a mangled name
wrapped in a HiddenType placeholder.
Add the module-format machinery that lets a Swift library record the
physical layout of hidden types (currently limited to C types imported via internal bridging header).
into binary modules, so downstream consumers can pull the layouts of these hidden types without
loading the internal dependency.
To test this, this change also added a frontend action to print hidden types' layouts
from both the module under compilation and all the modules being imported.
@_preInverseGenerics(except: <inverses>) is an extension of the existing
@_preInverseGenerics attribute that provides selective control over which
inverse requirements are mangled into a declaration's symbol name.
While the bare @_preInverseGenerics strips all inverse constraints
(~Copyable and ~Escapable) from mangling, the 'except:' form allows specific
inverses to be retained. This is needed when a type like Span already had
~Copyable mangled into its ABI-stable symbols and now needs to retroactively
adopt ~Escapable without changing those existing symbols. You can now express
that with `@_preInverseGenerics(except: ~Copyable)` to strip-out every inverse
except ~Copyable to preserve the pre-existing ~Copyable-containing symbols.
It requires the new experimental feature `PreInverseGenericsExcept`.
rdar://176395527
HiddenType is a new TypeBase subclass that carries a mangled name
without leaking the actual type definition. It serves as a type-slot
placeholder for stored-property types that have been elided from a
serialized binary module, so that the client side can either
(1) resolve this mangled name to the real type if the client has access to the owning module, or
(2) use the mangled name as a key to query abstract layout information also serialized in the binary module.
As an example — a library with a hidden field of a bridging-imported type:
```
// Utility.h (internal bridging header)
// typedef struct { int value; } Wrapper;
public struct S {
private var w: Wrapper
public var weight: Double
}
In the serialized module, the client's view reconstructs as:
public struct S {
private var w: @_hidden("$sSo7Wrappera")
public var weight: Double
}
```
Add a LAST_RECORD_KIND_MARKER sentinel at the end of the
options_block::RecordKind enum and a static_assert in writeHeader that
verifies the block's code width can encode every abbreviation the
writer may allocate. A future record kind that would overflow the
current code size now fails the build instead of producing a silent
malformed-module regression.
rdar://176522412
OPTIONS_BLOCK has historically been opened with a 4-bit abbreviation code size (BCBlockRAII(Out, OPTIONS_BLOCK_ID, 4) in Serializer::writeHeader), which permits at most 12 user-defined abbreviations (IDs 4–15, after the four reserved bitstream codes). New option records have been added incrementally, for certain flag combinations the writer now emits 13 or more abbreviations in OPTIONS_BLOCK, one past the 12-abbreviation ceiling that a 4-bit code size allows.
When that happens, the writer assigns the new abbreviation ID 16, which does not fit in 4 bits; BitstreamWriter::EmitCode silently truncates it to 0, which the reader interprets as END_BLOCK. OPTIONS_BLOCK is then popped prematurely, later records are reinterpreted as (invalid) content in the enclosing CONTROL_BLOCK, and the module fails to load with error: malformed compiled module. Widening the code size to 6 bits raises the cap to 60 user abbreviations (IDs 4–63), accommodates every currently-emitted record with substantial headroom.
rdar://176281964
Namespaces are imported into the __ObjC module. As a result, when a
Swift module is serialized, it refers to the declarations in the __ObjC
namespace. However, during deserialization, these declarations are found
in their original C++ module. The first failure triggered a recovery
that populated the __ObjC module so subsequent lookups succeed.
This PR makes sure we do not consider a declaration from the __ObjC
module that was found in a different clang module problematic.
Fixes#82318
We cannot use spare bits or other overlapping storage layout tricks with fundamentally
address-only enums, and we can take advantage of this to do borrowing switches or other
in-place projections without copying the value. However, for resilient enums, the
implementation may use spare bit packing, but the type must be handled address-only
outside of its defining module, and we didn't have a way to express that with
borrowing switch. Optimization passes have also been running into problems with the
complexity that we were using `unchecked_take_enum_data_addr` sometimes as a pure
operation. This patch splits the instruction into three:
- `unchecked_inplace_enum_data_addr` represents a nondestructive in-place enum
projection. It is only allowed for enums whose projection operation is
nondestructive.
- `unchecked_take_enum_data_addr` represents a destructive enum projection,
invalidating the enum and leaving the payload to be further consumed.
This matches the current instruction's semantics.
- `unchecked_borrow_enum_data_addr` represents a borrowing enum projection.
The instruction takes a second operand for "scratch" space, which the
enum representation may be copied into in order to avoid invalidating the
enum value, so the result is dependent on the lifetime of both the
original enum and the scratch buffer. This allows for borrowing switches
over resilient enums.
`unchecked_borrow_enum_data_addr` is implemented by taking advantage of the
"address-only enums can't do spare bit optimization" property at runtime.
We inspect the operand type's bitwise-borrowability from its metadata. If
the type is bitwise-borrowable, then we are allowed to bitwise-copy the
enum to the scratch space and apply the projection to the scratch space,
preserving the original value. If the type is not bitwise-borrowable, then
we cannot use spare bit optimization in its layout, so we apply the
projection in-place.
Fixes rdar://174952822.
Prevents situations when actor isolation ends up not being set
un-intentionally i.e. when cloning, specializating, or creating
thunks.
The thunks get `unspecified` isolation at the moment.
The `@export(interface)` and `@export(implementation)` attributes
SE-0497 are queried directly on AST nodes in several places within the
SIL pipeline. However, they don't persist when SIL functions are
serialized, meaning that clients of the original module might make
different assumptions about the availability of a given function's
definition.
Represent these attributes in a SIL function (as an optional
CodeGenerationModel), (de-)serialize them into the module, and add a
textual representation as SIL function attributes `[export_interface]`
and `[export_implementation]`.
For a given function, we might end up emitting it's definition as
object code, serialized SIL, or both. The @export, @inlinable, and
@inline(always) attributes provide control of this behavior at the
declaration level.
Centralize the query function that will look for each of these
attributes and map down to a specific "code generation model", whose 3
options follow the naming from SE-0497: interface, inlinable, and
implementation. Use this one computation to back the queries for
"always emit into client", "never emit into client", and "inlinable"
so we can't get inconsistent results from places that are doing
one-off checks for these attributes.
Generalizes how isolation is stored for SILFunctionType and
makes it possible to store not just "erased" but any future
isolation we'd need to add as well.
Add a LIBRARY_LEVEL record to the .swiftmodule options block so the
declared -library-level value survives across compilations. Without
this, imported modules have to always fell back to a path heuristic
that could only distinguish API vs SPI and never returned IPI.
rdar://174255626
If the vtable of a class has conformance entries (at negative offsets), we can do the cast by simply loading the witness table from those entries.
rdar://173916206
Conformance entries are used for fast conformance lookup, which doesn't need to query the runtime's conformance lookup table.
A conformance entry specifies if the class conforms or does not conform to a protocol.
At runtime, a type cast instruction to an existential can directly load the witness table pointer from the VTable.
If null, the class does not conform to the protocol.
Check for Embedded/normal Swift mismatches as part of module
validation, rather than after loading. Do this check as part of
canImport, so that canImport will evaluate false when there is a mismatch.
This will produce a warning in this case, because it's often a mistake
to have a module visible that isn't actually usable. However, don't
break the build over it.
Fixes#86419 / rdar://167851189
These will be used internally by the type checker to represent bindings
that are the joins and meets of types involving type variables. They
will not appear anywhere outside of the bindings code---so you won't
see them in expressions, or matchTypes(), etc.
Compute and propagate the library level (api/spi/ipi) of each module
dependency through the dependency scanner so that the compiler can
correctly enforce private module import diagnostics in CAS mode, where
path-based SPI detection fails because CAS abstracts file paths to
content IDs.
Swift modules:
- Detect library level from the module interface path using
libraryLevelFromPath() during scanning, for both textual (.swiftinterface)
and binary (.swiftmodule) Swift modules.
Clang modules:
- Expose ModuleMapIsPrivate from clang::Module in ModuleDeps via the
dependency scanning infrastructure.
- Set library level for clang modules in bridgeClangModuleDependency()
using ModuleMapIsPrivate (catches module.private.modulemap in any
SDK location) and libraryLevelFromPath() on the module map file
(catches modules under PrivateFrameworks directories).
The library level is:
- Stored in ModuleDependencyInfo and serialized in the module dependency
cache (format version bumped to v8).
- Exposed through the swiftscan C API via a new
swiftscan_module_info_get_library_level() function (API minor version
bumped to 3).
- Emitted in the dependency scanner JSON output as "libraryLevel" for
all module kinds (Swift textual, Swift binary, Clang, and main module).
- Parsed from the explicit module map JSON by ExplicitModuleMapParser
for both Swift (ExplicitSwiftModuleInputInfo) and Clang
(ExplicitClangModuleInputInfo) modules.
- Looked up in ModuleLibraryLevelRequest via
ASTContext::getExplicitModuleLibraryLevel(name, isClang), which
consults the appropriate map (Swift or Clang) based on module kind.
rdar://172693314
Assisted-By: Claude
When building the `OSLog` module, look for a variable named
`osLogStringSectionName`. It must have a string literal as its
initializer, which provides the section name where the log strings
should be emitted. The `OSLog` module should contain something like
this:
let osLogStringSectionName = "__TEXT,__logit"
When not present, the compiler will default to
`__TEXT,__oslogstring,cstring_literals`, which was previously the
hardcoded section name. Now, OSLog can customize the name.
Implements rdar://171571056