@@ -1870,7 +1870,8 @@ namespace {
18701870
18711871 // Create the enum declaration and record it.
18721872 NominalTypeDecl *result;
1873- auto enumKind = Impl.getEnumKind (decl);
1873+ auto enumInfo = Impl.getEnumInfo (decl);
1874+ auto enumKind = enumInfo.getKind ();
18741875 switch (enumKind) {
18751876 case EnumKind::Constants: {
18761877 // There is no declaration. Rather, the type is mapped to the
@@ -1954,69 +1955,139 @@ namespace {
19541955 }
19551956
19561957 case EnumKind::Enum: {
1958+ auto &swiftCtx = Impl.SwiftContext ;
19571959 EnumDecl *nativeDecl;
19581960 bool declaredNative = hasNativeSwiftDecl (decl, name, dc, nativeDecl);
19591961 if (declaredNative && nativeDecl)
19601962 return nativeDecl;
19611963
19621964 // Compute the underlying type.
1963- auto underlyingType = Impl.importType (decl->getIntegerType (),
1964- ImportTypeKind::Enum,
1965- isInSystemModule (dc),
1966- /* isFullyBridgeable*/ false );
1965+ auto underlyingType = Impl.importType (
1966+ decl->getIntegerType (), ImportTypeKind::Enum, isInSystemModule (dc),
1967+ /* isFullyBridgeable*/ false );
19671968 if (!underlyingType)
19681969 return nullptr ;
1969-
1970- auto enumDecl = Impl.createDeclWithClangNode <EnumDecl>(decl,
1971- Impl.importSourceLoc (decl->getLocStart ()),
1972- name, Impl.importSourceLoc (decl->getLocation ()),
1973- None, nullptr , dc);
1970+
1971+ auto enumDecl = Impl.createDeclWithClangNode <EnumDecl>(
1972+ decl, Impl.importSourceLoc (decl->getLocStart ()), name,
1973+ Impl.importSourceLoc (decl->getLocation ()), None, nullptr , dc);
19741974 enumDecl->computeType ();
1975-
1975+
19761976 // Set up the C underlying type as its Swift raw type.
19771977 enumDecl->setRawType (underlyingType);
1978-
1978+
19791979 // Add protocol declarations to the enum declaration.
1980- enumDecl->setInherited (
1981- Impl.SwiftContext .AllocateCopy (
1982- llvm::makeArrayRef (TypeLoc::withoutLoc (underlyingType))));
1980+ SmallVector<TypeLoc, 2 > inheritedTypes;
1981+ inheritedTypes.push_back (TypeLoc::withoutLoc (underlyingType));
1982+ if (enumInfo.isErrorEnum ())
1983+ inheritedTypes.push_back (TypeLoc::withoutLoc (
1984+ swiftCtx.getProtocol (KnownProtocolKind::BridgedNSError)
1985+ ->getDeclaredType ()));
1986+ enumDecl->setInherited (swiftCtx.AllocateCopy (inheritedTypes));
19831987 enumDecl->setCheckedInheritanceClause ();
19841988
1989+ // Set up error conformance to be lazily expanded
1990+ if (enumInfo.isErrorEnum ())
1991+ enumDecl->getAttrs ().add (new (swiftCtx) SynthesizedProtocolAttr (
1992+ KnownProtocolKind::BridgedNSError));
1993+
19851994 // Provide custom implementations of the init(rawValue:) and rawValue
19861995 // conversions that just do a bitcast. We can't reliably filter a
19871996 // C enum without additional knowledge that the type has no
19881997 // undeclared values, and won't ever add cases.
19891998 auto rawValueConstructor = makeEnumRawValueConstructor (Impl, enumDecl);
19901999
1991- auto varName = Impl.SwiftContext .Id_rawValue ;
1992- auto rawValue = new (Impl.SwiftContext ) VarDecl (/* static*/ false ,
1993- /* IsLet*/ false ,
1994- SourceLoc (), varName,
1995- underlyingType,
1996- enumDecl);
2000+ auto varName = swiftCtx.Id_rawValue ;
2001+ auto rawValue = new (swiftCtx) VarDecl (
2002+ /* static*/ false ,
2003+ /* IsLet*/ false , SourceLoc (), varName, underlyingType, enumDecl);
19972004 rawValue->setImplicit ();
19982005 rawValue->setAccessibility (Accessibility::Public);
19992006 rawValue->setSetterAccessibility (Accessibility::Private);
2000-
2007+
20012008 // Create a pattern binding to describe the variable.
20022009 Pattern *varPattern = createTypedNamedPattern (rawValue);
2003-
2004- auto rawValueBinding =
2005- PatternBindingDecl::create (Impl.SwiftContext , SourceLoc (),
2006- StaticSpellingKind::None, SourceLoc (),
2007- varPattern, nullptr , enumDecl);
2010+
2011+ auto rawValueBinding = PatternBindingDecl::create (
2012+ swiftCtx, SourceLoc (), StaticSpellingKind::None, SourceLoc (),
2013+ varPattern, nullptr , enumDecl);
20082014
20092015 auto rawValueGetter = makeEnumRawValueGetter (Impl, enumDecl, rawValue);
20102016
20112017 enumDecl->addMember (rawValueConstructor);
20122018 enumDecl->addMember (rawValueGetter);
20132019 enumDecl->addMember (rawValue);
20142020 enumDecl->addMember (rawValueBinding);
2015-
20162021 result = enumDecl;
2022+
2023+ // Set up the domain error member to be lazily added
2024+ if (enumInfo.isErrorEnum ()) {
2025+ auto clangDomainIdent = enumInfo.getErrorDomain ();
2026+ auto &clangSema = Impl.getClangSema ();
2027+ clang::LookupResult lookupResult (
2028+ clangSema, clang::DeclarationName (clangDomainIdent),
2029+ clang::SourceLocation (),
2030+ clang::Sema::LookupNameKind::LookupOrdinaryName);
2031+
2032+ if (!clangSema.LookupName (lookupResult, clangSema.TUScope )) {
2033+ // Couldn't actually import it as an error enum, fall back to enum
2034+ break ;
2035+ }
2036+
2037+ auto clangDecl = lookupResult.getAsSingle <clang::NamedDecl>();
2038+ if (!clangDecl) {
2039+ // Couldn't actually import it as an error enum, fall back to enum
2040+ break ;
2041+ }
2042+ auto swiftDecl = Impl.importDecl (clangDecl);
2043+ if (!swiftDecl || !isa<ValueDecl>(swiftDecl)) {
2044+ // Couldn't actually import it as an error enum, fall back to enum
2045+ break ;
2046+ }
2047+ SourceLoc noLoc = SourceLoc ();
2048+ bool isStatic = true ;
2049+ bool isImplicit = true ;
2050+
2051+ DeclRefExpr *domainDeclRef = new (swiftCtx) DeclRefExpr (
2052+ ConcreteDeclRef (cast<ValueDecl>(swiftDecl)), {}, isImplicit);
2053+ auto stringTy = swiftCtx.getStringDecl ()->getDeclaredType ();
2054+ ParameterList *params[] = {
2055+ ParameterList::createWithoutLoc (
2056+ ParamDecl::createSelf (noLoc, enumDecl, isStatic)),
2057+ ParameterList::createEmpty (swiftCtx)};
2058+ auto toStringTy = ParameterList::getFullType (stringTy, params);
2059+
2060+ FuncDecl *getterDecl =
2061+ FuncDecl::create (swiftCtx, noLoc, StaticSpellingKind::None, noLoc,
2062+ {}, noLoc, noLoc, noLoc, nullptr , toStringTy,
2063+ params, TypeLoc::withoutLoc (stringTy), enumDecl);
2064+
2065+ // Make the property decl
2066+ auto errorDomainPropertyDecl = new (swiftCtx)
2067+ VarDecl (isStatic,
2068+ /* isLet=*/ false , noLoc, swiftCtx.Id_NSErrorDomain ,
2069+ stringTy, enumDecl);
2070+ errorDomainPropertyDecl->setAccessibility (Accessibility::Public);
2071+
2072+ enumDecl->addMember (errorDomainPropertyDecl);
2073+ enumDecl->addMember (getterDecl);
2074+ errorDomainPropertyDecl->makeComputed (
2075+ noLoc, getterDecl, /* Set=*/ nullptr ,
2076+ /* MaterializeForSet=*/ nullptr , noLoc);
2077+
2078+ getterDecl->setImplicit ();
2079+ getterDecl->setStatic (isStatic);
2080+ getterDecl->setBodyResultType (stringTy);
2081+ getterDecl->setAccessibility (Accessibility::Public);
2082+
2083+ auto ret = new (swiftCtx) ReturnStmt (noLoc, {domainDeclRef});
2084+ getterDecl->setBody (
2085+ BraceStmt::create (swiftCtx, noLoc, {ret}, noLoc, isImplicit));
2086+ Impl.registerExternalDecl (getterDecl);
2087+ }
20172088 break ;
20182089 }
2019-
2090+
20202091 case EnumKind::Options: {
20212092 result = importAsOptionSetType (dc, name, decl);
20222093 if (!result)
0 commit comments