Skip to content

Commit 1a81074

Browse files
authored
[AST] Consolidate Obj-C types on ASTContext (#28128)
[AST] Consolidate Obj-C types on ASTContext
2 parents b957a56 + cb0c9ad commit 1a81074

16 files changed

+99
-151
lines changed

include/swift/AST/ASTContext.h

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -447,17 +447,13 @@ class ASTContext final {
447447
/// Retrieve the type Swift.Never.
448448
CanType getNeverType() const;
449449

450-
/// Retrieve the declaration of ObjectiveC.ObjCBool.
451-
StructDecl *getObjCBoolDecl() const;
452-
453-
/// Retrieve the declaration of Foundation.NSCopying.
454-
ProtocolDecl *getNSCopyingDecl() const;
455-
/// Retrieve the declaration of Foundation.NSError.
456-
ClassDecl *getNSErrorDecl() const;
457-
/// Retrieve the declaration of Foundation.NSNumber.
458-
ClassDecl *getNSNumberDecl() const;
459-
/// Retrieve the declaration of Foundation.NSValue.
460-
ClassDecl *getNSValueDecl() const;
450+
#define KNOWN_OBJC_TYPE_DECL(MODULE, NAME, DECL_CLASS) \
451+
/** Retrieve the declaration of MODULE.NAME. */ \
452+
DECL_CLASS *get##NAME##Decl() const; \
453+
\
454+
/** Retrieve the type of MODULE.NAME. */ \
455+
Type get##NAME##Type() const;
456+
#include "swift/AST/KnownObjCTypes.def"
461457

462458
// Declare accessors for the known declarations.
463459
#define FUNC_DECL(Name, Id) \

include/swift/AST/KnownObjCTypes.def

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===--- KnownObjCTypes.def - Common Objective-C types --------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This xmacro generates code for common imported Objective-C types the
14+
// compiler has special knowledge of.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef KNOWN_OBJC_TYPE_DECL
19+
/// KNOWN_OBJC_TYPE_DECL(MODULE, NAME, DECL_CLASS)
20+
///
21+
/// The macro is expanded for each known imported Objective-C type. MODULE is
22+
/// bound to the name of the module the type comes from. NAME is bound to the
23+
/// unqualified name of the type. DECL_CLASS is bound to the Decl subclass it
24+
/// is expected to be an instance of.
25+
#define KNOWN_OBJC_TYPE_DECL(MODULE, NAME, DECL_CLASS)
26+
#endif
27+
28+
KNOWN_OBJC_TYPE_DECL(Foundation, NSCopying, ProtocolDecl)
29+
KNOWN_OBJC_TYPE_DECL(Foundation, NSError, ClassDecl)
30+
KNOWN_OBJC_TYPE_DECL(Foundation, NSNumber, ClassDecl)
31+
KNOWN_OBJC_TYPE_DECL(Foundation, NSValue, ClassDecl)
32+
33+
KNOWN_OBJC_TYPE_DECL(ObjectiveC, NSObject, ClassDecl)
34+
KNOWN_OBJC_TYPE_DECL(ObjectiveC, Selector, StructDecl)
35+
KNOWN_OBJC_TYPE_DECL(ObjectiveC, ObjCBool, StructDecl)
36+
37+
#undef KNOWN_OBJC_TYPE_DECL

lib/AST/ASTContext.cpp

Lines changed: 21 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,6 @@ using AssociativityCacheType =
9898
llvm::DenseMap<std::pair<PrecedenceGroupDecl *, PrecedenceGroupDecl *>,
9999
Associativity>;
100100

101-
#define FOR_KNOWN_FOUNDATION_TYPES(MACRO) \
102-
MACRO(NSCopying, ProtocolDecl) \
103-
MACRO(NSError, ClassDecl) \
104-
MACRO(NSNumber, ClassDecl) \
105-
MACRO(NSValue, ClassDecl)
106-
107101
struct OverrideSignatureKey {
108102
GenericSignature baseMethodSig;
109103
GenericSignature derivedClassSig;
@@ -190,6 +184,11 @@ struct ASTContext::Implementation {
190184
DECL_CLASS *NAME##Decl = nullptr;
191185
#include "swift/AST/KnownStdlibTypes.def"
192186

187+
#define KNOWN_OBJC_TYPE_DECL(MODULE, NAME, DECL_CLASS) \
188+
/** The declaration of MODULE.NAME. */ \
189+
DECL_CLASS *NAME##Decl = nullptr;
190+
#include "swift/AST/KnownObjCTypes.def"
191+
193192
/// The declaration of '+' function for two RangeReplaceableCollection.
194193
FuncDecl *PlusFunctionOnRangeReplaceableCollection = nullptr;
195194

@@ -216,15 +215,6 @@ struct ASTContext::Implementation {
216215

217216
/// The declaration of Swift.AutoreleasingUnsafeMutablePointer<T>.memory.
218217
VarDecl *AutoreleasingUnsafeMutablePointerMemoryDecl = nullptr;
219-
220-
/// The declaration of ObjectiveC.ObjCBool.
221-
StructDecl *ObjCBoolDecl = nullptr;
222-
223-
#define CACHE_FOUNDATION_DECL(NAME, DECLTYPE) \
224-
/** The declaration of Foundation.NAME. */ \
225-
DECLTYPE *NAME##Decl = nullptr;
226-
FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
227-
#undef CACHE_FOUNDATION_DECL
228218

229219
// Declare cached declarations for each of the known declarations.
230220
#define FUNC_DECL(Name, Id) FuncDecl *Get##Name = nullptr;
@@ -827,33 +817,12 @@ CanType ASTContext::getNeverType() const {
827817
return neverDecl->getDeclaredType()->getCanonicalType();
828818
}
829819

830-
StructDecl *ASTContext::getObjCBoolDecl() const {
831-
if (!getImpl().ObjCBoolDecl) {
832-
SmallVector<ValueDecl *, 1> results;
833-
auto *Context = const_cast<ASTContext *>(this);
834-
if (ModuleDecl *M = Context->getModuleByName(Id_ObjectiveC.str())) {
835-
M->lookupValue(getIdentifier("ObjCBool"), NLKind::UnqualifiedLookup,
836-
results);
837-
for (auto result : results) {
838-
if (auto structDecl = dyn_cast<StructDecl>(result)) {
839-
if (structDecl->getGenericParams() == nullptr) {
840-
getImpl().ObjCBoolDecl = structDecl;
841-
break;
842-
}
843-
}
844-
}
845-
}
846-
}
847-
848-
return getImpl().ObjCBoolDecl;
849-
}
850-
851-
#define GET_FOUNDATION_DECL(NAME, DECLTYPE) \
820+
#define KNOWN_OBJC_TYPE_DECL(MODULE, NAME, DECLTYPE) \
852821
DECLTYPE *ASTContext::get##NAME##Decl() const { \
853822
if (!getImpl().NAME##Decl) { \
854-
if (ModuleDecl *M = getLoadedModule(Id_Foundation)) { \
855-
/* Note: lookupQualified() will search both the Foundation module \
856-
* and the Clang Foundation module it imports. */ \
823+
if (ModuleDecl *M = getLoadedModule(Id_##MODULE)) { \
824+
/* Note: lookupQualified() will search both the Swift overlay \
825+
* and the Clang module it imports. */ \
857826
SmallVector<ValueDecl *, 1> decls; \
858827
M->lookupQualified(M, getIdentifier(#NAME), NL_OnlyTypes, decls); \
859828
if (decls.size() == 1 && isa<DECLTYPE>(decls[0])) { \
@@ -866,11 +835,16 @@ DECLTYPE *ASTContext::get##NAME##Decl() const { \
866835
} \
867836
\
868837
return getImpl().NAME##Decl; \
838+
} \
839+
\
840+
Type ASTContext::get##NAME##Type() const { \
841+
auto *decl = get##NAME##Decl(); \
842+
if (!decl) \
843+
return Type(); \
844+
return decl->getDeclaredInterfaceType(); \
869845
}
870846

871-
FOR_KNOWN_FOUNDATION_TYPES(GET_FOUNDATION_DECL)
872-
#undef GET_FOUNDATION_DECL
873-
#undef FOR_KNOWN_FOUNDATION_TYPES
847+
#include "swift/AST/KnownObjCTypes.def"
874848

875849
ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
876850
// Check whether we've already looked for and cached this protocol.
@@ -4291,12 +4265,12 @@ Type ASTContext::getBridgedToObjC(const DeclContext *dc, Type type,
42914265
// Check whether the type is an existential that contains
42924266
// Error. If so, it's bridged to NSError.
42934267
if (type->isExistentialWithError()) {
4294-
if (auto nsErrorDecl = getNSErrorDecl()) {
4268+
if (auto nsErrorTy = getNSErrorType()) {
42954269
// The corresponding value type is Error.
42964270
if (bridgedValueType)
42974271
*bridgedValueType = getErrorDecl()->getDeclaredInterfaceType();
42984272

4299-
return nsErrorDecl->getDeclaredInterfaceType();
4273+
return nsErrorTy;
43004274
}
43014275
}
43024276

@@ -4334,8 +4308,8 @@ Type ASTContext::getBridgedToObjC(const DeclContext *dc, Type type,
43344308
*bridgedValueType = getErrorDecl()->getDeclaredInterfaceType();
43354309

43364310
// Bridge to NSError.
4337-
if (auto nsErrorDecl = getNSErrorDecl())
4338-
return nsErrorDecl->getDeclaredInterfaceType();
4311+
if (auto nsErrorTy = getNSErrorType())
4312+
return nsErrorTy;
43394313
}
43404314

43414315
// No special bridging to Objective-C, but this can become an 'Any'.

lib/ClangImporter/ImportType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2082,7 +2082,7 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
20822082
bool paramIsIUO;
20832083
if (kind == SpecialMethodKind::NSDictionarySubscriptGetter &&
20842084
paramTy->isObjCIdType()) {
2085-
swiftParamTy = SwiftContext.getNSCopyingDecl()->getDeclaredType();
2085+
swiftParamTy = SwiftContext.getNSCopyingType();
20862086
if (optionalityOfParam != OTK_None)
20872087
swiftParamTy = OptionalType::get(swiftParamTy);
20882088

lib/PrintAsObjC/DeclAndTypePrinter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,8 +1396,8 @@ class DeclAndTypePrinter::Implementation
13961396
// upper-bounded keys.
13971397
else if (swiftNominal == ctx.getDictionaryDecl() &&
13981398
isNSObjectOrAnyHashable(ctx, typeArgs[0])) {
1399-
if (auto proto = ctx.getNSCopyingDecl()) {
1400-
rewrittenArgsBuf[0] = proto->getDeclaredInterfaceType();
1399+
if (auto protoTy = ctx.getNSCopyingType()) {
1400+
rewrittenArgsBuf[0] = protoTy;
14011401
rewrittenArgsBuf[1] = typeArgs[1];
14021402
typeArgs = rewrittenArgsBuf;
14031403
}

lib/SIL/Bridging.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,9 @@ Type TypeConverter::getLoweredCBridgedType(AbstractionPattern pattern,
232232
}
233233

234234
case ForeignRepresentableKind::BridgedError: {
235-
auto nsErrorDecl = M.getASTContext().getNSErrorDecl();
236-
assert(nsErrorDecl && "Cannot bridge when NSError isn't available");
237-
return nsErrorDecl->getDeclaredInterfaceType();
235+
auto nsErrorTy = M.getASTContext().getNSErrorType();
236+
assert(nsErrorTy && "Cannot bridge when NSError isn't available");
237+
return nsErrorTy;
238238
}
239239
}
240240

lib/SIL/SILType.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,12 +304,10 @@ static bool isBridgedErrorClass(ASTContext &ctx, Type t) {
304304
t = archetypeType->getSuperclass();
305305

306306
// NSError (TODO: and CFError) can be bridged.
307-
auto nsErrorType = ctx.getNSErrorDecl();
308-
if (t && nsErrorType &&
309-
nsErrorType->getDeclaredType()->isExactSuperclassOf(t)) {
307+
auto nsErrorType = ctx.getNSErrorType();
308+
if (t && nsErrorType && nsErrorType->isExactSuperclassOf(t))
310309
return true;
311-
}
312-
310+
313311
return false;
314312
}
315313

lib/SILGen/SILGen.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,8 @@ ProtocolConformance *SILGenModule::getNSErrorConformanceToError() {
336336
return *NSErrorConformanceToError;
337337

338338
auto &ctx = getASTContext();
339-
auto nsError = ctx.getNSErrorDecl();
340-
if (!nsError) {
339+
auto nsErrorTy = ctx.getNSErrorType();
340+
if (!nsErrorTy) {
341341
NSErrorConformanceToError = nullptr;
342342
return nullptr;
343343
}
@@ -349,8 +349,7 @@ ProtocolConformance *SILGenModule::getNSErrorConformanceToError() {
349349
}
350350

351351
auto conformance =
352-
SwiftModule->lookupConformance(nsError->getDeclaredInterfaceType(),
353-
cast<ProtocolDecl>(error));
352+
SwiftModule->lookupConformance(nsErrorTy, cast<ProtocolDecl>(error));
354353

355354
if (conformance.isConcrete())
356355
NSErrorConformanceToError = conformance.getConcrete();

lib/SILGen/SILGenConvert.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -625,11 +625,9 @@ ManagedValue SILGenFunction::emitExistentialErasure(
625625
if (ctx.LangOpts.EnableObjCInterop && conformances.size() == 1 &&
626626
conformances[0].getRequirement() == ctx.getErrorDecl() &&
627627
ctx.getNSErrorDecl()) {
628-
auto nsErrorDecl = ctx.getNSErrorDecl();
629-
630628
// If the concrete type is NSError or a subclass thereof, just erase it
631629
// directly.
632-
auto nsErrorType = nsErrorDecl->getDeclaredType()->getCanonicalType();
630+
auto nsErrorType = ctx.getNSErrorType()->getCanonicalType();
633631
if (nsErrorType->isExactSuperclassOf(concreteFormalType)) {
634632
ManagedValue nsError = F(SGFContext());
635633
if (nsErrorType != concreteFormalType) {

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,9 +1670,8 @@ namespace {
16701670
Expr *bridgeErrorToObjectiveC(Expr *value) {
16711671
auto &ctx = cs.getASTContext();
16721672

1673-
auto nsErrorDecl = ctx.getNSErrorDecl();
1674-
assert(nsErrorDecl && "Missing NSError?");
1675-
Type nsErrorType = nsErrorDecl->getDeclaredInterfaceType();
1673+
auto nsErrorType = ctx.getNSErrorType();
1674+
assert(nsErrorType && "Missing NSError?");
16761675

16771676
auto result = new (ctx) BridgeToObjCExpr(value, nsErrorType);
16781677
return cs.cacheType(result);

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2981,7 +2981,7 @@ namespace {
29812981

29822982
// Make sure we can reference ObjectiveC.Selector.
29832983
// FIXME: Fix-It to add the import?
2984-
auto type = CS.getTypeChecker().getObjCSelectorType(CS.DC);
2984+
auto type = CS.getASTContext().getSelectorType();
29852985
if (!type) {
29862986
ctx.Diags.diagnose(E->getLoc(), diag::expr_selector_module_missing);
29872987
return nullptr;

lib/Sema/CSSimplify.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6420,6 +6420,7 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
64206420
// If the bridged value type is generic, the generic arguments
64216421
// must either match or be bridged.
64226422
// FIXME: This should be an associated type of the protocol.
6423+
auto &ctx = getASTContext();
64236424
if (auto fromBGT = unwrappedToType->getAs<BoundGenericType>()) {
64246425
if (fromBGT->getDecl() == TC.Context.getArrayDecl()) {
64256426
// [AnyObject]
@@ -6429,14 +6430,14 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
64296430
LocatorPathElt::GenericArgument(0))));
64306431
} else if (fromBGT->getDecl() == TC.Context.getDictionaryDecl()) {
64316432
// [NSObject : AnyObject]
6432-
auto NSObjectType = TC.getNSObjectType(DC);
6433-
if (!NSObjectType) {
6433+
auto nsObjectType = ctx.getNSObjectType();
6434+
if (!nsObjectType) {
64346435
// Not a bridging case. Should we detect this earlier?
64356436
return SolutionKind::Error;
64366437
}
64376438

64386439
addConstraint(ConstraintKind::Bind, fromBGT->getGenericArgs()[0],
6439-
NSObjectType,
6440+
nsObjectType,
64406441
getConstraintLocator(
64416442
locator.withPathElement(
64426443
LocatorPathElt::GenericArgument(0))));
@@ -6447,13 +6448,13 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
64476448
locator.withPathElement(
64486449
LocatorPathElt::GenericArgument(1))));
64496450
} else if (fromBGT->getDecl() == TC.Context.getSetDecl()) {
6450-
auto NSObjectType = TC.getNSObjectType(DC);
6451-
if (!NSObjectType) {
6451+
auto nsObjectType = ctx.getNSObjectType();
6452+
if (!nsObjectType) {
64526453
// Not a bridging case. Should we detect this earlier?
64536454
return SolutionKind::Error;
64546455
}
64556456
addConstraint(ConstraintKind::Bind, fromBGT->getGenericArgs()[0],
6456-
NSObjectType,
6457+
nsObjectType,
64576458
getConstraintLocator(
64586459
locator.withPathElement(
64596460
LocatorPathElt::GenericArgument(0))));

lib/Sema/MiscDiagnostics.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3474,7 +3474,7 @@ class ObjCSelectorWalker : public ASTWalker {
34743474

34753475
static void diagDeprecatedObjCSelectors(TypeChecker &tc, const DeclContext *dc,
34763476
const Expr *expr) {
3477-
auto selectorTy = tc.getObjCSelectorType(const_cast<DeclContext *>(dc));
3477+
auto selectorTy = dc->getASTContext().getSelectorType();
34783478
if (!selectorTy) return;
34793479

34803480
const_cast<Expr *>(expr)->walk(ObjCSelectorWalker(tc, dc, selectorTy));
@@ -4097,9 +4097,7 @@ static OmissionTypeName getTypeNameForOmission(Type type) {
40974097
Type boolType;
40984098
if (auto boolDecl = ctx.getBoolDecl())
40994099
boolType = boolDecl->getDeclaredInterfaceType();
4100-
Type objcBoolType;
4101-
if (auto objcBoolDecl = ctx.getObjCBoolDecl())
4102-
objcBoolType = objcBoolDecl->getDeclaredInterfaceType();
4100+
auto objcBoolType = ctx.getObjCBoolType();
41034101

41044102
/// Determine the options associated with the given type.
41054103
auto getOptions = [&](Type type) {

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,7 +1994,7 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
19941994
return nullptr;
19951995

19961996
// Don't bother to convert deprecated selector syntax.
1997-
if (auto selectorTy = TC.getObjCSelectorType(DC)) {
1997+
if (auto selectorTy = TC.Context.getSelectorType()) {
19981998
if (type->isEqual(selectorTy))
19991999
return nullptr;
20002000
}
@@ -4407,7 +4407,7 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
44074407

44084408
// Objective-C metaclasses are subclasses of NSObject in the ObjC runtime,
44094409
// so casts from NSObject to potentially-class metatypes may succeed.
4410-
if (auto nsObject = getNSObjectType(dc)) {
4410+
if (auto nsObject = Context.getNSObjectType()) {
44114411
if (fromType->isEqual(nsObject)) {
44124412
if (auto toMeta = toType->getAs<MetatypeType>()) {
44134413
if (toMeta->getInstanceType()->mayHaveSuperclass()
@@ -4427,10 +4427,9 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
44274427
if (!conformsToProtocol(toType, errorTypeProto, dc,
44284428
ConformanceCheckFlags::InExpression)
44294429
.isInvalid()) {
4430-
auto nsError = Context.getNSErrorDecl();
4431-
if (nsError) {
4432-
Type NSErrorTy = nsError->getDeclaredInterfaceType();
4433-
if (isSubtypeOf(fromType, NSErrorTy, dc)
4430+
auto nsErrorTy = Context.getNSErrorType();
4431+
if (nsErrorTy) {
4432+
if (isSubtypeOf(fromType, nsErrorTy, dc)
44344433
// Don't mask "always true" warnings if NSError is cast to
44354434
// Error itself.
44364435
&& !isSubtypeOf(fromType, toType, dc))

0 commit comments

Comments
 (0)