diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 2a058ac9ed739..85fc2043cf736 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -8558,11 +8558,19 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc, // Create the expression node. StringRef printedValueCopy(context.AllocateCopy(printedValue)); if (value.getKind() == clang::APValue::Int) { - if (type->getCanonicalType()->isBool()) { - auto *boolExpr = - new (context) BooleanLiteralExpr(value.getInt().getBoolValue(), - SourceLoc(), - /**Implicit=*/true); + bool isBool = type->getCanonicalType()->isBool(); + // Check if "type" is a C++ enum with an underlying type of "bool". + if (!isBool && type->getStructOrBoundGenericStruct() && + type->getStructOrBoundGenericStruct()->getClangDecl()) { + if (auto enumDecl = dyn_cast( + type->getStructOrBoundGenericStruct()->getClangDecl())) { + isBool = enumDecl->getIntegerType()->isBooleanType(); + } + } + if (isBool) { + auto *boolExpr = new (context) + BooleanLiteralExpr(value.getInt().getBoolValue(), SourceLoc(), + /*Implicit=*/true); boolExpr->setBuiltinInitializer( context.getBoolBuiltinInitDecl()); diff --git a/test/Interop/Cxx/enum/Inputs/bool-enums.h b/test/Interop/Cxx/enum/Inputs/bool-enums.h new file mode 100644 index 0000000000000..797b3fc5987b1 --- /dev/null +++ b/test/Interop/Cxx/enum/Inputs/bool-enums.h @@ -0,0 +1,6 @@ +enum Maybe : bool { No, Yes }; +enum BinaryNumbers : bool { One = 1, Zero = 0 }; +enum class EnumClass : bool { Foo, Bar }; +struct WrapperStruct { + enum InnerBoolEnum : bool { A, B }; +}; diff --git a/test/Interop/Cxx/enum/Inputs/module.modulemap b/test/Interop/Cxx/enum/Inputs/module.modulemap new file mode 100644 index 0000000000000..b8065a9a3fe2e --- /dev/null +++ b/test/Interop/Cxx/enum/Inputs/module.modulemap @@ -0,0 +1,3 @@ +module BoolEnums { + header "bool-enums.h" +} diff --git a/test/Interop/Cxx/enum/bool-enums-module-interface.swift b/test/Interop/Cxx/enum/bool-enums-module-interface.swift new file mode 100644 index 0000000000000..3bf576cda22ed --- /dev/null +++ b/test/Interop/Cxx/enum/bool-enums-module-interface.swift @@ -0,0 +1,40 @@ +// RUN: %target-swift-ide-test -print-module -module-to-print=BoolEnums -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s + +// TODO: these should be enums eventually (especially the enum class). + +// CHECK: struct Maybe : Equatable, RawRepresentable { +// CHECK-NEXT: init(_ rawValue: Bool) +// CHECK-NEXT: init(rawValue: Bool) +// CHECK-NEXT: var rawValue: Bool +// CHECK-NEXT: typealias RawValue = Bool +// CHECK-NEXT: } + +// CHECK: var No: Maybe { get } +// CHECK: var Yes: Maybe { get } + +// CHECK: struct BinaryNumbers : Equatable, RawRepresentable { +// CHECK-NEXT: init(_ rawValue: Bool) +// CHECK-NEXT: init(rawValue: Bool) +// CHECK-NEXT: var rawValue: Bool +// CHECK-NEXT: typealias RawValue = Bool +// CHECK-NEXT: } + +// CHECK: var One: BinaryNumbers { get } +// CHECK: var Zero: BinaryNumbers { get } +// CHECK: struct EnumClass : Equatable, RawRepresentable { +// CHECK-NEXT: init(_ rawValue: Bool) +// CHECK-NEXT: init(rawValue: Bool) +// CHECK-NEXT: var rawValue: Bool +// CHECK-NEXT: typealias RawValue = Bool +// CHECK-NEXT: } + +// CHECK: struct WrapperStruct { +// TODO: where is "A" and "B"? They should be member variables. +// CHECK-NEXT: struct InnerBoolEnum : Equatable, RawRepresentable { +// CHECK-NEXT: init(_ rawValue: Bool) +// CHECK-NEXT: init(rawValue: Bool) +// CHECK-NEXT: var rawValue: Bool +// CHECK-NEXT: typealias RawValue = Bool +// CHECK-NEXT: } +// CHECK-NEXT: init() +// CHECK-NEXT: }