If the Clang declrations are *types*, canonical declaration in Swift is
imported for newest version of Swift. In interface generation, if the
declaration is versioned and it's imported as a member in either or both
version of Swift, we have to take compatibility typealias into account.
* Fixed 'ClangModuleUnit::getTopLevelDecls' to take isCompatibilityAlias() into account
* Fixed bugs in ClangImporter where member-to-member versioned types aren't properly imported.
* Fixed 'SwiftDeclConverter::importFullName' to check equality of getEffectiveContext()
* Fixed 'importer::addEntryToLookupTable' to check equality of getEffectiveContext()
(moved 'ClangImporter::Implementation::forEachDistinctName' to 'NameImporter')
When forming the Swift name lookup tables, import-as-member'd
declarations can precede the declaration of the context into which
they'll be imported as a member. In such cases, we already had logic
to delay the resolution until the end of the model (when the context
must be complete).
However, we would only delay when there is a swift_name attribute on
the declaration, which is... conceptually correct. If the swift_name
exists but is versioned (e.g., it is present only for Swift 4+), and
we're building before the swift_name took effect (e.g., in Swift 3
mode), the swift_name is buried under a "versioned" attribute in the
Clang AST. Therefore, we would end up dropping the declaration from
the name lookup table, which almost doesn't matter, except...
Serialization records the newest names for such declarations (e.g.,
Swift 4+ name in this case), so deserialization would fail to find the
declaration that had been dropped, causing a crash.
Eliminate the "optimization" that looks for the swift_name attribute
before delaying the resolution of such a declaration, so we'll visit
these later. Fixes rdar://problem/39115605.
The obsolete llvm::HashString() was equivalent to
llvm::djbHash(seed=0) and was removed from llvm. This patch replaces
all occurences of llvm::HashString() with llvm::djbHash(seed=0), no
functional change.
The default seed of llvm::djbHash() is supposed to yield a higher
quality result that using seed=0, but changing it looks like it
affects the ordering of SIL serialization.
This includes 'LONG_MAX' in the Darwin module, which is defined by the
system and then immediately redefined by Clang's copy of limits.h.
The general strategy here is that if two definitions of a macro in the
same module are in separate explicit submodules, we need to keep track
of both of them, but if they're in the same explicit submodule then
one is probably deliberately redefining the other. This isn't fully
correct because one explicit submodule could include another explicit
submodule, but it's a good first approximation, which we can refine if
we come across problem cases in practice.
Swift /also/ has the ability to distinguish between ModuleA.MACRO and
ModuleB.MACRO if you've imported both modules, although there's an
issue that the two of them end up getting the same mangled name if you
try to use both in the same compilation unit. (Filed
rdar://problem/34968281.) That ability is preserved with this change.
All of this will likely change if/when we switch to Clang's "local
submodule visibility" mode, which is needed for the C++ Modules TS but
is also incompatible with Apple's SDKs at the moment. In that case,
macros in two separate explicit submodules will no longer have an
'override' relationship just because they're mentioned sequentially in
the module map.
rdar://problem/34413934
...so that we don't have to keep coming back to update it every major
release. And also so we can actually put methods on it instead of
using free functions.
No intended behavior change (yet).
In theory, Clang's module system supports the notion of "public" and
"private" macros in a framework, currently implemented by the
supported feature at this point, but we do make sure the Swift
compiler can handle them.
However, visibility directives for built-in macros would end up
showing up in the list of defined macros that we iterate over to write
out the Swift name lookup tables for a module. Since we pack
ModuleMacro and MacroInfo pointers into the same data structure
/without/ a discriminator bit, this led to a nonsense reinterpret_cast
later on. This manifested as rare test failures later.
Bail out in this case, and assert in NDEBUG builds that it's actually
this case and not some other problematic case that we haven't
encountered yet.
I'm not filing a bug for real support of the macro visibility
directives because it wouldn't be prioritized until there's a
real-world test case anyway (sad realities of compiler development).
rdar://problem/33745657
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.
This changes `getBaseName()` on `DeclName` to return a `DeclBaseName`
instead of an `Identifier`. All places that will continue to be
expecting an `Identifier` are changed to call `getBaseIdentifier` which
will later assert that the `DeclName` is actually backed by an
identifier and not a special name.
For transitional purposes, a conversion operator from `DeclBaseName` to
`Identifier` has been added that will be removed again once migration
to DeclBaseName has been completed in other parts of the compiler.
Unify approach to printing declaration names
Printing a declaration's name using `<<` and `getBaseName()` is be
independent of the return type of `getBaseName()` which will change in
the future from `Identifier` to `DeclBaseName`
Previously this (1) did not work (the constant just disappeared), and
(2) would actually crash if the destination context was a class.
rdar://problem/32208235
...and Swift 4 versions in Swift 3, and Swift 2 and "raw" versions in
both. This allows the compiler to produce sensible errors and fix-its
when someone uses the "wrong" name for an API. The diagnostics
certainly have room to improve, but at least the essentials are there.
Note that this commit only addresses /top-level/ decls, i.e. those
found by lookup into a module. We're still limited to producing all
members of a nominal type up front, so that'll require a slightly
different approach.
Part of rdar://problem/29170671
The compiler uses the non-active names to import unavailable
declarations telling the user the correct name. Right now it's still
only importing "Swift 2" and "current", but that should change.
For reference, the best example of a declaration that has four names
is a factory method with a custom NS_SWIFT_NAME annotation:
- Its raw name is the plain Objective-C name, written as a method:
'fooByFrobnicatingBar(_:)'.
- Its "Swift 2" name is the Swift-2-style translation of that to an
initializer: 'init(byFrobnicatingBar:)'
- Its "Swift 3" name applies the "omit needless words" transformation:
'init(frobnicating:)'.
- Its "Swift 4" name uses the name specified by NS_SWIFT_NAME.
Changes:
* Terminate all namespaces with the correct closing comment.
* Make sure argument names in comments match the corresponding parameter name.
* Remove redundant get() calls on smart pointers.
* Prefer using "override" or "final" instead of "virtual". Remove "virtual" where appropriate.
Change the interfaces to ImportedName to be method based, rather than
direct struct field accesses. We're going to be changing how these are
used in the future. Also, we will be storing large quantities of
these, so we will soon want to crunch down on their size.
Rather than use importName using a set of options of what to choose,
phrase the API in terms of language version. Be explicit about what
version is being requested at the call site, as it's a necessary
consideration for the client.
Drop the ImportNameSwiftContext, which was merely used to pass around
some global state. Instead, pass the relevant parts
directly. Additionally, remove the 2-phase initialization of a
NameImporter from the module writers, as they are only invoked once
per Clang instance anyways, we can hold a local instance. Also
streamlines some APIs.
NFC
Banish the abomination that is clangSemaOverride, a previously
necessary evil. When building the module caches, different Clang
instances will be spawned than the one used by the normal
importer. Since we want to reuse code and get the same name both ways,
this meant threading through alternative clang Semas and preprocessors
throughtout, some of the time. This broke the abstraction and
encapsulation of the Impl, complicated the programming model, and
otherwise made effective caching hard.
Now that we’ve done enough ImportName refactoring, we can create a
NameImporter per Clang instance, and encapsulate naming therein. We
can now remove the sema overrides, as we have already done to the
preprocessor overrides.
This shifts the 2-phase initialization problem to the Impl and the
Clang module writers.
NFC
Delay initialization of the EnumInfoCache until a Clang instance is
ready, simplifying its interface and allowing us to finally make this
per-Clang-instance. This will allow us to further de-couple ImportName
from the importer imply, as well as allow us to use a more efficient
and simpler caching mechanism. It is now owned by the NameImporter.
NFC.
Move SwiftLookupTableReader/Writer into .cpp file, as they are
irrelevant to the rest of the importer, and this allows us to make
them more ImportName aware in the future. Pull more code out of
ClangImporter.cpp.
NFC.
We could support this in the future but right now it's causing problems.
There's also a potential ambiguity issue here where a protocol and class
could have the same name.
In addition to updating the importer, remove the two entries from the
CryptoTokenKit API notes that were trying to use this feature.
rdar://problem/27990168
...instead of picking one definition arbitrarily. This comes from the
new "lookup table" design in Swift 3---we no longer just look for any
"visible" (imported) macro definition, but instead need to know them
up front. This works fine when there's only one definition per module,
but for modules like 'OpenGL' on macOS, with mutually-exclusive
submodules 'GL' and 'GL3', the compiler was arbitrarily deciding that
all of the macros the submodules had in common belonged to 'GL'.
The new model tries to decide if it's possible for two modules to be
imported separately, and keeps both macro entries if possible, only
deduplicating equivalent definitions at the last minute (when
importing into Swift). This /still/ doesn't perfectly match the
behavior you'd get in C, where a submodule and its parent module could
theoretically have conflicting definitions and you'd be fine as long
as you only imported one of them, but hopefully (a) it's close enough,
and (b) nobody is doing that. (The Swift compiler will prefer the
definition in the parent module even if the submodule is the only one
imported.)
rdar://problem/26731529
When attempting to compile Swift 2 code (or any Swift code using the
Swift 2 names) in Swift 3, the compiler diagnostics are often entirely
useless because the names have changed radically enough that one
generally gets "no member named 'foo'" errors rather than a helpful
"'foo' was renamed to 'bar'" error. This makes for a very poor user
experience when (e.g.) trying to move Swift 2 code forward to Swift 3.
To improve the experience, when the Swift 2 and Swift 3 names of an
API differ, the Clang importer will produce a "stub" declaration that
matches the Swift 2 API. That stub will be marked with a synthesized
attribute
@available(unavailable, renamed: "the-swift-3-name")
that enables better diagnostics (e.g., "'foo' is unavailable: renamed
to 'bar') along with Fix-Its (courtesy of @jrose-apple's recent work)
that fix the Swift 2 code to compile in Swift 3.
This change addresses much of rdar://problem/25309323 (concerning QoI
of Swift 2 code compiled with a Swift 3 compiler), but some cleanup
remains.
It's possible for swift_name to make a global declaration into a
member of another entity that has not been seen yet. In such cases,
delay resolution until the end of the translation unit (module). Fixes
the rest of rdar://problem/25502497.
When printing the interface for a (sub)module, make sure that we only
print those extensions that were created to hold that submodule's
globals that were imported as members.
Whenever we add an entry that corresponds to a global Clang entity
that will be imported as a member, where that member structure isn't
inherently encoded in Clang, separately record it as being a member of
the context in a separate table. Verify that we're getting the entries
we expect in this table.
A swift_name attribute on a global declaration can specify a dotted
name (e.g., SomeStruct.member) to map that global into a member of the
(Swift-)named type. Handle this mapping in DeclName parsing, plumb it
through importFullName, and cope with it in the Swift name lookup
tables (tested via the dump) and importing into a Swift DeclContext
(as-yet-untested). Part of SE-0033.
Previously, the "effective context" parameter to importFullName was
used only during the construction of Swift name lookup tables, so we
can associate each declaration with a context. Expand the role of
"effective context" so it is always a part of ImportedName and is also
used by importDecl when actually importing the enum declaration.
This is partially a cleanup, and partially staging for SE-0033, which
will require this functionality more broadly.
The two types are nearly identical, and Fixnum is only in the Swift branches of LLVM,
not in mainline LLVM.
I do want to add ++ to PointerEmbeddedInt and fix some of this ugliness, but that'll
have to go through LLVM review, so it might take a bit.
This copes with rare (and hard-to-reproduce-in-the-small) recursive
cases where importing a declaration for a name would then perform name
lookup again, and end up not finding anything the second type around.