@@ -1870,7 +1870,8 @@ namespace {
1870
1870
1871
1871
// Create the enum declaration and record it.
1872
1872
NominalTypeDecl *result;
1873
- auto enumKind = Impl.getEnumKind (decl);
1873
+ auto enumInfo = Impl.getEnumInfo (decl);
1874
+ auto enumKind = enumInfo.getKind ();
1874
1875
switch (enumKind) {
1875
1876
case EnumKind::Constants: {
1876
1877
// There is no declaration. Rather, the type is mapped to the
@@ -1954,69 +1955,139 @@ namespace {
1954
1955
}
1955
1956
1956
1957
case EnumKind::Enum: {
1958
+ auto &swiftCtx = Impl.SwiftContext ;
1957
1959
EnumDecl *nativeDecl;
1958
1960
bool declaredNative = hasNativeSwiftDecl (decl, name, dc, nativeDecl);
1959
1961
if (declaredNative && nativeDecl)
1960
1962
return nativeDecl;
1961
1963
1962
1964
// 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 );
1967
1968
if (!underlyingType)
1968
1969
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);
1974
1974
enumDecl->computeType ();
1975
-
1975
+
1976
1976
// Set up the C underlying type as its Swift raw type.
1977
1977
enumDecl->setRawType (underlyingType);
1978
-
1978
+
1979
1979
// 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));
1983
1987
enumDecl->setCheckedInheritanceClause ();
1984
1988
1989
+ // Set up error conformance to be lazily expanded
1990
+ if (enumInfo.isErrorEnum ())
1991
+ enumDecl->getAttrs ().add (new (swiftCtx) SynthesizedProtocolAttr (
1992
+ KnownProtocolKind::BridgedNSError));
1993
+
1985
1994
// Provide custom implementations of the init(rawValue:) and rawValue
1986
1995
// conversions that just do a bitcast. We can't reliably filter a
1987
1996
// C enum without additional knowledge that the type has no
1988
1997
// undeclared values, and won't ever add cases.
1989
1998
auto rawValueConstructor = makeEnumRawValueConstructor (Impl, enumDecl);
1990
1999
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);
1997
2004
rawValue->setImplicit ();
1998
2005
rawValue->setAccessibility (Accessibility::Public);
1999
2006
rawValue->setSetterAccessibility (Accessibility::Private);
2000
-
2007
+
2001
2008
// Create a pattern binding to describe the variable.
2002
2009
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);
2008
2014
2009
2015
auto rawValueGetter = makeEnumRawValueGetter (Impl, enumDecl, rawValue);
2010
2016
2011
2017
enumDecl->addMember (rawValueConstructor);
2012
2018
enumDecl->addMember (rawValueGetter);
2013
2019
enumDecl->addMember (rawValue);
2014
2020
enumDecl->addMember (rawValueBinding);
2015
-
2016
2021
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
+ }
2017
2088
break ;
2018
2089
}
2019
-
2090
+
2020
2091
case EnumKind::Options: {
2021
2092
result = importAsOptionSetType (dc, name, decl);
2022
2093
if (!result)
0 commit comments