Skip to content

Commit 46b02b6

Browse files
committed
[c++-interop] Adding options set struct to go with the typedef's enum bit set.
This does not work yet, but it is a proof of concept for now.
1 parent e977a21 commit 46b02b6

File tree

3 files changed

+66
-7
lines changed

3 files changed

+66
-7
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "clang/AST/Attr.h"
5555
#include "clang/AST/DeclCXX.h"
5656
#include "clang/AST/DeclObjCCommon.h"
57+
#include "clang/AST/Type.h"
5758
#include "clang/Basic/CharInfo.h"
5859
#include "clang/Basic/Specifiers.h"
5960
#include "clang/Basic/TargetInfo.h"
@@ -2856,14 +2857,46 @@ namespace {
28562857
return nullptr;
28572858

28582859
auto Loc = Impl.importSourceLoc(Decl->getLocation());
2859-
auto Result = Impl.createDeclWithClangNode<TypeAliasDecl>(Decl,
2860-
AccessLevel::Public,
2861-
Impl.importSourceLoc(Decl->getBeginLoc()),
2862-
SourceLoc(), Name,
2863-
Loc,
2864-
/*genericparams*/nullptr, DC);
28652860

2866-
Result->setUnderlyingType(SwiftType);
2861+
swift::Decl *Result = nullptr;
2862+
if (importer::isUnavailableInSwift(Decl, nullptr, true) &&
2863+
Impl.SwiftContext.LangOpts.EnableCXXInterop) {
2864+
ASTContext &ctx = Impl.SwiftContext;
2865+
2866+
// Compute the underlying type.
2867+
clang::QualType ClangType = Decl->getUnderlyingType();
2868+
auto underlyingType = Impl.importTypeIgnoreIUO(
2869+
ClangType, ImportTypeKind::Enum,
2870+
ImportDiagnosticAdder(Impl, Decl, Decl->getLocation()),
2871+
isInSystemModule(DC), Bridgeability::None, ImportTypeAttrs());
2872+
if (!underlyingType)
2873+
return nullptr;
2874+
2875+
auto structDecl = Impl.createDeclWithClangNode<StructDecl>(
2876+
Decl, AccessLevel::Public, Loc, Name, Loc, None, nullptr, DC);
2877+
2878+
addSynthesizedProtocolAttrs(Impl, structDecl,
2879+
{KnownProtocolKind::Sendable},
2880+
/*isUnchecked=*/true);
2881+
2882+
makeStructRawValued(Impl, structDecl, underlyingType,
2883+
{KnownProtocolKind::OptionSet});
2884+
auto selfType = structDecl->getDeclaredInterfaceType();
2885+
addSynthesizedTypealias(structDecl, ctx.Id_Element, selfType);
2886+
addSynthesizedTypealias(structDecl, ctx.Id_ArrayLiteralElement,
2887+
selfType);
2888+
Impl.DeclsWithSuperfluousTypedefs.insert(Decl);
2889+
2890+
Result = structDecl;
2891+
} else {
2892+
auto TypeAliasResult = Impl.createDeclWithClangNode<TypeAliasDecl>(
2893+
Decl, AccessLevel::Public,
2894+
Impl.importSourceLoc(Decl->getBeginLoc()), SourceLoc(), Name, Loc,
2895+
/*genericparams*/ nullptr, DC);
2896+
2897+
TypeAliasResult->setUnderlyingType(SwiftType);
2898+
Result = TypeAliasResult;
2899+
}
28672900

28682901
// Make Objective-C's 'id' unavailable.
28692902
if (Impl.SwiftContext.LangOpts.EnableObjCInterop && isObjCId(Decl)) {
@@ -3904,6 +3937,24 @@ namespace {
39043937
Decl *VisitEnumConstantDecl(const clang::EnumConstantDecl *decl) {
39053938
auto clangEnum = cast<clang::EnumDecl>(decl->getDeclContext());
39063939

3940+
3941+
3942+
// Note: for NSArray with C++-Interop mode it seems the anon enum is not getting
3943+
// handled by VisitEnumDecl, but the enum constant decls are getting handled here.
3944+
// I am not entirely sure why this is the case. It seems it is possible to get to the EnumDecl from the EnumConstantDecl.
3945+
3946+
3947+
3948+
llvm::errs() << "Trying to import enum constant decl:\n";
3949+
decl->dump();
3950+
clangEnum->dump();
3951+
llvm::errs() << "CLANG ENUM NAME AS STRING: " << clangEnum->getTypedefNameForAnonDecl() << "\n";
3952+
3953+
clang::QualType T = clangEnum->getIntegerType();
3954+
clang::SplitQualType T_split = T.split();
3955+
clang::PrintingPolicy PrintPolicy = clang::LangOptions();
3956+
llvm::errs() << "ENUM TYPE!!! " << clang::QualType::getAsString(T_split, PrintPolicy) << "\n";
3957+
39073958
ImportedName importedName;
39083959
Optional<ImportedName> correctSwiftName;
39093960
std::tie(importedName, correctSwiftName) = importFullName(decl);

lib/ClangImporter/ImportType.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "clang/AST/DeclCXX.h"
4040
#include "clang/AST/DeclObjCCommon.h"
4141
#include "clang/AST/DeclTemplate.h"
42+
#include "clang/AST/Type.h"
4243
#include "clang/AST/TypeVisitor.h"
4344
#include "clang/Basic/Builtins.h"
4445
#include "clang/Lex/Preprocessor.h"

test/Interop/Cxx/enum/c-enums-withOptions-omit.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33

44
import CenumsWithOptionsOmit
55

6+
// CHECK: struct NSEnumerationOptions : OptionSet {
7+
// CHECK-NEXT: init(rawValue: Int32)
8+
// CHECK-NEXT: let rawValue: Int32
9+
// CHECK-NEXT: typealias RawValue = Int32
10+
// CHECK-NEXT: typealias Element = NSEnumerationOptions
11+
// CHECK-NEXT: typealias ArrayLiteralElement = NSEnumerationOptions
12+
613
// CHECK: class NSSet {
714
// CHECK-NEXT: class func enumerateObjects(options
815
// CHECK-NEXT: func enumerateObjects(options

0 commit comments

Comments
 (0)