//===--- FoundationSupport.cpp - Support functions for Foundation ---------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2020 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // Helper functions for the Foundation framework. // //===----------------------------------------------------------------------===// #include "swift/Runtime/FoundationSupport.h" #if SWIFT_OBJC_INTEROP #include "swift/Runtime/Metadata.h" #include "swift/Runtime/HeapObject.h" using namespace swift; /// Returns a boolean indicating whether the Objective-C name of a class type is /// stable across executions, i.e., if the class name is safe to serialize. (The /// names of private and local types are unstable.) bool swift::_swift_isObjCTypeNameSerializable(Class theClass) { auto type = (AnyClassMetadata *)theClass; switch (type->getKind()) { case MetadataKind::ObjCClassWrapper: case MetadataKind::ForeignClass: return true; case MetadataKind::Class: { // Pure ObjC classes always have stable names. if (type->isPureObjC()) return true; auto cls = static_cast(type); // Peek through artificial subclasses. if (cls->isArtificialSubclass()) { cls = cls->Superclass; } // A custom ObjC name is always considered stable. if (cls->getFlags() & ClassFlags::HasCustomObjCName) return true; // Otherwise the name is stable if the class has no anonymous ancestor context. auto desc = static_cast(cls->getDescription()); while (desc) { if (desc->getKind() == ContextDescriptorKind::Anonymous) { return false; } desc = desc->Parent.get(); } return true; } default: return false; } } #endif // SWIFT_OBJC_INTEROP