Commit Graph

3 Commits

Author SHA1 Message Date
Nuri Amari
fb14414bc9 Fix assertion failure importing NS_OPTION with differing Swift name across versions
At the call sites of `findAnonymousEnumForTypedef` we often wish to
import the returned enum declaration and return the type the declaration
creates.

Prior to this patch, we assumed that the enum declaration would be
imported as a `NominalTypeDecl`. This is not always the case. For
whatever reason, sometimes in typechecking we import a declaration
for various different naming versions. If the Swift name for an imported
enum differs between the canonical name version, and currently
requested name version, we import the enum as a `TypeAliasDecl` instead.

Prior to this patch, this meant we would hit asserts importing some
components of UIKit.

This patch relaxes the assumption that the import is a `NominalTypeDecl`
to just a `TypeDecl`, which as of yet, seems to be true.
2023-02-16 08:44:44 -08:00
Nuri Amari
3a555bd2f7 Fix effective context construction for NS_OPTIONS in linkage spec
When the ClangImporter imports a name, it associates it with a
an EffectiveClangContext. An EffectiveClangContext can be thought of
as the Clang scope the declaration will reside in, as far as importing
into Swift is concerned. This helps API notes and NS_SWIFT_NAME
to manipulate the SDK interface presented to Swift users.

When a entry is added to the Swift lookup table, it is associated
with a context. This context is a type and a name, used to effectively
namespace entries in the table. This context is derived from the
EffectiveClangContext associated with the name. This translation is
handled by SwiftLookupTable::translateContextDecl among other machinery.
This method in particular, understands only how to translate a set of
Clang nodes, and fails to create a context in other cases.

Prior to this patch, the EffectiveClangContext of declarations annotated
with UIKIT_EXTERN, with cxx-interop turned on, was a LinkageSpecDecl.
This results in context translation failure, and warnings produced in
SwiftLookupTable::finalizeLookupTable. This patch corrects name import
behavior to skip over the LinkageSpecDecl, and use the enclosing
TranslationUnit instead. This is appropriate and performed by
`determineEffectiveContext` as a LinkageSpecDecl is a so called
"transparent" context. That is its members are semantically declared and
accessible outside the context without additional qualification.

This patch tests using API notes, as that is the method UIKit uses. The
issue could just as easily be surface with a NS_SWIFT_NAME annotation.
Even without any annotation at all, the we would still fail to
translate, though there would likely be no corresponding warnings.
2022-12-03 14:05:19 -08:00
Nuri Amari
5f5bebfe3e Correct effective context translation for NS_OPTIONS anon C++ enums
Prior to this patch, SwiftLookupTable::translateDeclToContext relied
on the `TypedefNameDeclOrQualifier` field of an anonymous tag decl to
create a name for entry representing an anonymous tag in the lookup
table. This field is not always populated by Clang, it is often
populated only for the purposes of generating a linkage name when the
type is introduced via typedef as follows:

```
typedef enum { option1, option2} MyAnonEnum;
```

The field is not populated for anonymous enums introduced by NS_OPTIONS
with cxx interop enabled. This patch adds a fallback check in
`translateDeclToContext` that if the field is empty, check if the enum
is backed by a typedef that is unavailable in Swift. If that is the
case, use that name for the lookup table entry.
2022-11-18 11:12:05 -08:00