Skip to content

[c++-interop] Adding options set struct to go with the typedef's enum bit set. #58972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 58 additions & 7 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjCCommon.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
Expand Down Expand Up @@ -2856,14 +2857,46 @@ namespace {
return nullptr;

auto Loc = Impl.importSourceLoc(Decl->getLocation());
auto Result = Impl.createDeclWithClangNode<TypeAliasDecl>(Decl,
AccessLevel::Public,
Impl.importSourceLoc(Decl->getBeginLoc()),
SourceLoc(), Name,
Loc,
/*genericparams*/nullptr, DC);

Result->setUnderlyingType(SwiftType);
swift::Decl *Result = nullptr;
if (importer::isUnavailableInSwift(Decl, nullptr, true) &&
Impl.SwiftContext.LangOpts.EnableCXXInterop) {
ASTContext &ctx = Impl.SwiftContext;

// Compute the underlying type.
clang::QualType ClangType = Decl->getUnderlyingType();
auto underlyingType = Impl.importTypeIgnoreIUO(
ClangType, ImportTypeKind::Enum,
ImportDiagnosticAdder(Impl, Decl, Decl->getLocation()),
isInSystemModule(DC), Bridgeability::None, ImportTypeAttrs());
if (!underlyingType)
return nullptr;

auto structDecl = Impl.createDeclWithClangNode<StructDecl>(
Decl, AccessLevel::Public, Loc, Name, Loc, None, nullptr, DC);

addSynthesizedProtocolAttrs(Impl, structDecl,
{KnownProtocolKind::Sendable},
/*isUnchecked=*/true);

makeStructRawValued(Impl, structDecl, underlyingType,
{KnownProtocolKind::OptionSet});
auto selfType = structDecl->getDeclaredInterfaceType();
addSynthesizedTypealias(structDecl, ctx.Id_Element, selfType);
addSynthesizedTypealias(structDecl, ctx.Id_ArrayLiteralElement,
selfType);
Impl.DeclsWithSuperfluousTypedefs.insert(Decl);

Result = structDecl;
} else {
auto TypeAliasResult = Impl.createDeclWithClangNode<TypeAliasDecl>(
Decl, AccessLevel::Public,
Impl.importSourceLoc(Decl->getBeginLoc()), SourceLoc(), Name, Loc,
/*genericparams*/ nullptr, DC);

TypeAliasResult->setUnderlyingType(SwiftType);
Result = TypeAliasResult;
}

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



// Note: for NSArray with C++-Interop mode it seems the anon enum is not getting
// handled by VisitEnumDecl, but the enum constant decls are getting handled here.
// I am not entirely sure why this is the case. It seems it is possible to get to the EnumDecl from the EnumConstantDecl.



llvm::errs() << "Trying to import enum constant decl:\n";
decl->dump();
clangEnum->dump();
llvm::errs() << "CLANG ENUM NAME AS STRING: " << clangEnum->getTypedefNameForAnonDecl() << "\n";

clang::QualType T = clangEnum->getIntegerType();
clang::SplitQualType T_split = T.split();
clang::PrintingPolicy PrintPolicy = clang::LangOptions();
llvm::errs() << "ENUM TYPE!!! " << clang::QualType::getAsString(T_split, PrintPolicy) << "\n";

ImportedName importedName;
Optional<ImportedName> correctSwiftName;
std::tie(importedName, correctSwiftName) = importFullName(decl);
Expand Down
1 change: 1 addition & 0 deletions lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjCCommon.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Lex/Preprocessor.h"
Expand Down
7 changes: 7 additions & 0 deletions test/Interop/Cxx/enum/c-enums-withOptions-omit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@

import CenumsWithOptionsOmit

// CHECK: struct NSEnumerationOptions : OptionSet {
// CHECK-NEXT: init(rawValue: Int32)
// CHECK-NEXT: let rawValue: Int32
// CHECK-NEXT: typealias RawValue = Int32
// CHECK-NEXT: typealias Element = NSEnumerationOptions
// CHECK-NEXT: typealias ArrayLiteralElement = NSEnumerationOptions

// CHECK: class NSSet {
// CHECK-NEXT: class func enumerateObjects(options
// CHECK-NEXT: func enumerateObjects(options
Expand Down