Skip to content

Commit b34d2c5

Browse files
committed
[AST] Add Type::wrapInPointer(PointerTypeKind)
...replacing a similar utility in the type checker and one I just added in ClangImporter earlier in this patch series. This is an ever-so-slight regression in functionality because a missing pointer declaration used to print a diagnostic and now it will just crash on an invalid standard library, but I don't think we should be optimizing for an invalid standard library anyway.
1 parent 5d4c456 commit b34d2c5

File tree

7 files changed

+58
-93
lines changed

7 files changed

+58
-93
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3647,9 +3647,6 @@ ERROR(sugar_type_not_found,none,
36473647
"broken standard library: cannot find "
36483648
"%select{Array|Optional|ImplicitlyUnwrappedOptional|Dictionary|"
36493649
"Error}0 type", (unsigned))
3650-
ERROR(pointer_type_not_found,none,
3651-
"broken standard library: cannot find "
3652-
"%select{UnsafePointer|UnsafeMutablePointer}0 type", (unsigned))
36533650
ERROR(optional_intrinsics_not_found,none,
36543651
"broken standard library: cannot find intrinsic operations on "
36553652
"Optional<T>", ())

include/swift/AST/Types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,12 @@ class alignas(1 << TypeAlignInBits) TypeBase {
706706
PointerTypeKind Ignore;
707707
return getAnyPointerElementType(Ignore);
708708
}
709+
710+
/// Returns a type representing a pointer to \c this.
711+
///
712+
/// \p kind must not be a raw pointer kind, since that would discard the
713+
/// current type.
714+
Type wrapInPointer(PointerTypeKind kind);
709715

710716
/// Determine whether the given type is "specialized", meaning that
711717
/// it involves generic types for which generic arguments have been provided.

lib/AST/Type.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,28 @@ Type TypeBase::getAnyPointerElementType(PointerTypeKind &PTK) {
624624
return Type();
625625
}
626626

627+
Type TypeBase::wrapInPointer(PointerTypeKind kind) {
628+
ASTContext &ctx = getASTContext();
629+
NominalTypeDecl *pointerDecl = ([&ctx, kind] {
630+
switch (kind) {
631+
case PTK_UnsafeMutableRawPointer:
632+
case PTK_UnsafeRawPointer:
633+
llvm_unreachable("these pointer types don't take arguments");
634+
case PTK_UnsafePointer:
635+
return ctx.getUnsafePointerDecl();
636+
case PTK_UnsafeMutablePointer:
637+
return ctx.getUnsafeMutablePointerDecl();
638+
case PTK_AutoreleasingUnsafeMutablePointer:
639+
return ctx.getAutoreleasingUnsafeMutablePointerDecl();
640+
}
641+
llvm_unreachable("bad kind");
642+
}());
643+
644+
assert(pointerDecl);
645+
return BoundGenericType::get(pointerDecl, /*parent*/nullptr, Type(this));
646+
}
647+
648+
627649
Type TypeBase::lookThroughAllOptionalTypes() {
628650
Type type(this);
629651
while (auto objType = type->getOptionalObjectType())

lib/ClangImporter/ImportType.cpp

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -60,36 +60,6 @@ bool ClangImporter::Implementation::isOverAligned(clang::QualType type) {
6060
return align > clang::CharUnits::fromQuantity(MaximumAlignment);
6161
}
6262

63-
/// Returns a specialization of the given pointer type for the given pointee.
64-
///
65-
/// \p kind must not be a raw pointer kind.
66-
static Type getPointerTo(Type pointee, PointerTypeKind kind) {
67-
ASTContext &ctx = pointee->getASTContext();
68-
NominalTypeDecl *pointerDecl = ([&ctx, kind] {
69-
switch (kind) {
70-
case PTK_UnsafeMutableRawPointer:
71-
case PTK_UnsafeRawPointer:
72-
llvm_unreachable("these pointer types don't take arguments");
73-
case PTK_UnsafePointer:
74-
return ctx.getUnsafePointerDecl();
75-
case PTK_UnsafeMutablePointer:
76-
return ctx.getUnsafeMutablePointerDecl();
77-
case PTK_AutoreleasingUnsafeMutablePointer:
78-
return ctx.getAutoreleasingUnsafeMutablePointerDecl();
79-
}
80-
llvm_unreachable("bad kind");
81-
}());
82-
83-
// Specifically handle AUMP being missing to allow testing more of ObjC
84-
// interop on non-Apple platforms.
85-
assert((pointerDecl || kind == PTK_AutoreleasingUnsafeMutablePointer) &&
86-
"could not find standard pointer type");
87-
if (!pointerDecl)
88-
return Type();
89-
90-
return BoundGenericType::get(pointerDecl, /*parent*/nullptr, pointee);
91-
}
92-
9363
namespace {
9464
/// Various types that we want to do something interesting to after
9565
/// importing them.
@@ -438,22 +408,35 @@ namespace {
438408
};
439409
}
440410

411+
PointerTypeKind pointerKind;
441412
if (quals.hasConst()) {
442-
return {getPointerTo(pointeeType, PTK_UnsafePointer),
443-
ImportHint::OtherPointer};
444-
}
413+
pointerKind = PTK_UnsafePointer;
414+
} else {
415+
switch (quals.getObjCLifetime()) {
416+
case clang::Qualifiers::OCL_Autoreleasing:
417+
case clang::Qualifiers::OCL_ExplicitNone:
418+
// Mutable pointers with __autoreleasing or __unsafe_unretained
419+
// ownership map to AutoreleasingUnsafeMutablePointer<T>.
420+
pointerKind = PTK_AutoreleasingUnsafeMutablePointer;
421+
422+
// FIXME: We have tests using a non-Apple stdlib that nevertheless
423+
// exercise ObjC interop. Fail softly for those tests.
424+
if (!Impl.SwiftContext.getAutoreleasingUnsafeMutablePointerDecl())
425+
return Type();
426+
break;
445427

446-
// Mutable pointers with __autoreleasing or __unsafe_unretained
447-
// ownership map to AutoreleasingUnsafeMutablePointer<T>.
448-
if (quals.getObjCLifetime() == clang::Qualifiers::OCL_Autoreleasing ||
449-
quals.getObjCLifetime() == clang::Qualifiers::OCL_ExplicitNone) {
450-
return {
451-
getPointerTo(pointeeType, PTK_AutoreleasingUnsafeMutablePointer),
452-
ImportHint::OtherPointer};
428+
case clang::Qualifiers::OCL_Weak:
429+
// FIXME: We should refuse to import this.
430+
LLVM_FALLTHROUGH;
431+
432+
case clang::Qualifiers::OCL_None:
433+
case clang::Qualifiers::OCL_Strong:
434+
// All other mutable pointers map to UnsafeMutablePointer.
435+
pointerKind = PTK_UnsafeMutablePointer;
436+
}
453437
}
454438

455-
// All other mutable pointers map to UnsafeMutablePointer.
456-
return {getPointerTo(pointeeType, PTK_UnsafeMutablePointer),
439+
return {pointeeType->wrapInPointer(pointerKind),
457440
ImportHint::OtherPointer};
458441
}
459442

@@ -1269,7 +1252,7 @@ static Type maybeImportCFOutParameter(ClangImporter::Implementation &impl,
12691252
else
12701253
pointerKind = PTK_AutoreleasingUnsafeMutablePointer;
12711254

1272-
resultTy = getPointerTo(resultTy, pointerKind);
1255+
resultTy = resultTy->wrapInPointer(pointerKind);
12731256
return resultTy;
12741257
}
12751258

lib/Sema/TypeCheckDecl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3770,11 +3770,11 @@ static Type buildAddressorResultType(TypeChecker &TC,
37703770
assert(addressor->getAccessorKind() == AccessorKind::Address ||
37713771
addressor->getAccessorKind() == AccessorKind::MutableAddress);
37723772

3773-
Type pointerType =
3773+
PointerTypeKind pointerKind =
37743774
(addressor->getAccessorKind() == AccessorKind::Address)
3775-
? TC.getUnsafePointerType(addressor->getLoc(), valueType)
3776-
: TC.getUnsafeMutablePointerType(addressor->getLoc(), valueType);
3777-
return pointerType;
3775+
? PTK_UnsafePointer
3776+
: PTK_UnsafeMutablePointer;
3777+
return valueType->wrapInPointer(pointerKind);
37783778
}
37793779

37803780

lib/Sema/TypeCheckType.cpp

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -385,47 +385,6 @@ Type TypeChecker::getOptionalType(SourceLoc loc, Type elementType) {
385385
return OptionalType::get(elementType);
386386
}
387387

388-
static Type getPointerType(TypeChecker &tc, SourceLoc loc, Type pointeeType,
389-
PointerTypeKind kind) {
390-
auto pointerDecl = [&] {
391-
switch (kind) {
392-
case PTK_UnsafeMutableRawPointer:
393-
case PTK_UnsafeRawPointer:
394-
llvm_unreachable("these pointer types don't take arguments");
395-
case PTK_UnsafePointer:
396-
return tc.Context.getUnsafePointerDecl();
397-
case PTK_UnsafeMutablePointer:
398-
return tc.Context.getUnsafeMutablePointerDecl();
399-
case PTK_AutoreleasingUnsafeMutablePointer:
400-
return tc.Context.getAutoreleasingUnsafeMutablePointerDecl();
401-
}
402-
llvm_unreachable("bad kind");
403-
}();
404-
if (!pointerDecl) {
405-
tc.diagnose(loc, diag::pointer_type_not_found,
406-
kind == PTK_UnsafePointer ? 0 :
407-
kind == PTK_UnsafeMutablePointer ? 1 : 2);
408-
return Type();
409-
}
410-
411-
// FIXME(InterfaceTypeRequest): isInvalid() should be based on the interface type.
412-
(void)pointerDecl->getInterfaceType();
413-
if (pointerDecl->isInvalid())
414-
return Type();
415-
416-
// TODO: validate generic signature?
417-
418-
return BoundGenericType::get(pointerDecl, nullptr, pointeeType);
419-
}
420-
421-
Type TypeChecker::getUnsafePointerType(SourceLoc loc, Type pointeeType) {
422-
return getPointerType(*this, loc, pointeeType, PTK_UnsafePointer);
423-
}
424-
425-
Type TypeChecker::getUnsafeMutablePointerType(SourceLoc loc, Type pointeeType) {
426-
return getPointerType(*this, loc, pointeeType, PTK_UnsafeMutablePointer);
427-
}
428-
429388
Type TypeChecker::getStringType(DeclContext *dc) {
430389
if (auto typeDecl = Context.getStringDecl())
431390
return typeDecl->getDeclaredInterfaceType();

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,8 +735,6 @@ class TypeChecker final : public LazyResolver {
735735
static Type getArraySliceType(SourceLoc loc, Type elementType);
736736
static Type getDictionaryType(SourceLoc loc, Type keyType, Type valueType);
737737
static Type getOptionalType(SourceLoc loc, Type elementType);
738-
Type getUnsafePointerType(SourceLoc loc, Type pointeeType);
739-
Type getUnsafeMutablePointerType(SourceLoc loc, Type pointeeType);
740738
Type getStringType(DeclContext *dc);
741739
Type getSubstringType(DeclContext *dc);
742740
Type getIntType(DeclContext *dc);

0 commit comments

Comments
 (0)