diff --git a/include/swift/ABI/Metadata.h b/include/swift/ABI/Metadata.h index 8049387c4e191..8409c8dcd724e 100644 --- a/include/swift/ABI/Metadata.h +++ b/include/swift/ABI/Metadata.h @@ -1025,7 +1025,7 @@ struct TargetAnyClassMetadata : public TargetHeapMetadata { using TargetMetadata::setClassISA; #endif - // Note that ObjC classes do not have a metadata header. + // Note that ObjC classes does not have a metadata header. /// The metadata for the superclass. This is null for the root class. ConstTargetMetadataPointer Superclass; diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 6e8c2cd1b0330..0bf41995878ab 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -852,17 +852,7 @@ class alignas(1 << TypeAlignInBits) TypeBase { /// \returns The superclass of this type, or a null type if it has no /// superclass. Type getSuperclass(bool useArchetypes = true); - - /// Retrieve the root class of this type by repeatedly retrieving the - /// superclass. - /// - /// \param useArchetypes Whether to use context archetypes for outer generic - /// parameters if the class is nested inside a generic function. - /// - /// \returns The base class of this type, or this type itself if it has no - /// superclasses. - Type getRootClass(bool useArchetypes = true); - + /// True if this type is the exact superclass of another type. /// /// \param ty The potential subclass. diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def index 5e534c3e901fe..8321255140d40 100644 --- a/include/swift/Demangling/DemangleNodes.def +++ b/include/swift/Demangling/DemangleNodes.def @@ -287,9 +287,5 @@ NODE(OpaqueTypeDescriptorAccessorVar) NODE(OpaqueReturnType) CONTEXT_NODE(OpaqueReturnTypeOf) -// Added in Swift 5.3 -NODE(CanonicalSpecializedGenericMetaclass) -NODE(CanonicalSpecializedGenericTypeMetadataAccessFunction) - #undef CONTEXT_NODE #undef NODE diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h index fac7f4510c30a..acfa09b4b9cf7 100644 --- a/include/swift/IRGen/Linking.h +++ b/include/swift/IRGen/Linking.h @@ -193,7 +193,7 @@ class LinkEntity { /// The nominal type descriptor for a nominal type. /// The pointer is a NominalTypeDecl*. NominalTypeDescriptor, - + /// The descriptor for an opaque type. /// The pointer is an OpaqueTypeDecl*. OpaqueTypeDescriptor, @@ -295,12 +295,12 @@ class LinkEntity { /// The descriptor for an extension. /// The pointer is an ExtensionDecl*. ExtensionDescriptor, - + /// The descriptor for a runtime-anonymous context. /// The pointer is the DeclContext* of a child of the context that should /// be considered private. AnonymousDescriptor, - + /// A SIL global variable. The pointer is a SILGlobalVariable*. SILGlobalVariable, @@ -384,15 +384,6 @@ class LinkEntity { /// A global function pointer for dynamically replaceable functions. DynamicallyReplaceableFunctionVariable, - - /// A reference to a metaclass-stub for a statically specialized generic - /// class. - /// The pointer is a canonical TypeBase*. - CanonicalSpecializedGenericSwiftMetaclassStub, - - /// An access function for prespecialized type metadata. - /// The pointer is a canonical TypeBase*. - CanonicalSpecializedGenericTypeMetadataAccessFunction, }; friend struct llvm::DenseMapInfo; @@ -1029,22 +1020,6 @@ class LinkEntity { return entity; } - static LinkEntity - forSpecializedGenericSwiftMetaclassStub(CanType concreteType) { - LinkEntity entity; - entity.setForType(Kind::CanonicalSpecializedGenericSwiftMetaclassStub, - concreteType); - return entity; - } - - static LinkEntity - forPrespecializedTypeMetadataAccessFunction(CanType theType) { - LinkEntity entity; - entity.setForType( - Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction, theType); - return entity; - } - void mangle(llvm::raw_ostream &out) const; void mangle(SmallVectorImpl &buffer) const; std::string mangleAsString() const; diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index cb44104a71dfe..25e6178dc2ee0 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1552,17 +1552,6 @@ Type TypeBase::getSuperclass(bool useArchetypes) { return superclassTy.subst(subMap); } -Type TypeBase::getRootClass(bool useArchetypes) { - Type iterator = this; - assert(iterator); - - while (auto superclass = iterator->getSuperclass(useArchetypes)) { - iterator = superclass; - } - - return iterator; -} - bool TypeBase::isExactSuperclassOf(Type ty) { // For there to be a superclass relationship, we must be a class, and // the potential subtype must be a class, superclass-bounded archetype, diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp index f447c2cef583b..2ea37950dd96e 100644 --- a/lib/Demangling/Demangler.cpp +++ b/lib/Demangling/Demangler.cpp @@ -1874,9 +1874,6 @@ NodePointer Demangler::demangleMetatype() { case 'A': return createWithChild(Node::Kind::ReflectionMetadataAssocTypeDescriptor, popProtocolConformance()); - case 'b': - return createWithPoppedType( - Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction); case 'B': return createWithChild(Node::Kind::ReflectionMetadataBuiltinDescriptor, popNode(Node::Kind::Type)); @@ -1920,9 +1917,6 @@ NodePointer Demangler::demangleMetatype() { return createWithPoppedType(Node::Kind::TypeMetadataLazyCache); case 'm': return createWithPoppedType(Node::Kind::Metaclass); - case 'M': - return createWithPoppedType( - Node::Kind::CanonicalSpecializedGenericMetaclass); case 'n': return createWithPoppedType(Node::Kind::NominalTypeDescriptor); case 'o': diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index 22d52337aae39..655cbac01ea24 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -540,8 +540,6 @@ class NodePrinter { case Node::Kind::OpaqueTypeDescriptorSymbolicReference: case Node::Kind::OpaqueReturnType: case Node::Kind::OpaqueReturnTypeOf: - case Node::Kind::CanonicalSpecializedGenericMetaclass: - case Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction: return false; } printer_unreachable("bad node kind"); @@ -2420,14 +2418,6 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) { case Node::Kind::AccessorFunctionReference: Printer << "accessor function at " << Node->getIndex(); return nullptr; - case Node::Kind::CanonicalSpecializedGenericMetaclass: - Printer << "specialized generic metaclass for "; - print(Node->getFirstChild()); - return nullptr; - case Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction: - Printer << "canonical specialized generic type metadata accessor for "; - print(Node->getChild(0)); - return nullptr; } printer_unreachable("bad node kind!"); } diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp index 02e974a926ee0..09b1896d9f9e1 100644 --- a/lib/Demangling/OldRemangler.cpp +++ b/lib/Demangling/OldRemangler.cpp @@ -2133,17 +2133,6 @@ void Remangler::mangleAccessorFunctionReference(Node *node) { unreachable("can't remangle"); } -void Remangler::mangleCanonicalSpecializedGenericMetaclass(Node *node) { - Buffer << "MM"; - mangleSingleChildNode(node); // type -} - -void Remangler::mangleCanonicalSpecializedGenericTypeMetadataAccessFunction( - Node *node) { - mangleSingleChildNode(node); - Buffer << "Mb"; -} - /// The top-level interface to the remangler. std::string Demangle::mangleNodeOld(NodePointer node) { if (!node) return ""; diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp index 3c8832acac374..4e9907d7d9699 100644 --- a/lib/Demangling/Remangler.cpp +++ b/lib/Demangling/Remangler.cpp @@ -2533,17 +2533,6 @@ void Remangler::mangleAccessorFunctionReference(Node *node) { unreachable("can't remangle"); } -void Remangler::mangleCanonicalSpecializedGenericMetaclass(Node *node) { - mangleChildNodes(node); - Buffer << "MM"; -} - -void Remangler::mangleCanonicalSpecializedGenericTypeMetadataAccessFunction( - Node *node) { - mangleSingleChildNode(node); - Buffer << "Mb"; -} - } // anonymous namespace /// The top-level interface to the remangler. diff --git a/lib/IRGen/ClassTypeInfo.h b/lib/IRGen/ClassTypeInfo.h deleted file mode 100644 index 0e47a01df8a43..0000000000000 --- a/lib/IRGen/ClassTypeInfo.h +++ /dev/null @@ -1,66 +0,0 @@ -//===--- ClassTypeInfo.h - The layout info for class types. -----*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 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 -// -//===----------------------------------------------------------------------===// -// -// This file contains layout information for class types. -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_IRGEN_CLASSTYPEINFO_H -#define SWIFT_IRGEN_CLASSTYPEINFO_H - -#include "ClassLayout.h" -#include "HeapTypeInfo.h" - -namespace swift { -namespace irgen { - -/// Layout information for class types. -class ClassTypeInfo : public HeapTypeInfo { - ClassDecl *TheClass; - - // The resilient layout of the class, without making any assumptions - // that violate resilience boundaries. This is used to allocate - // and deallocate instances of the class, and to access fields. - mutable Optional ResilientLayout; - - // A completely fragile layout, used for metadata emission. - mutable Optional FragileLayout; - - /// Can we use swift reference-counting, or do we have to use - /// objc_retain/release? - const ReferenceCounting Refcount; - - ClassLayout generateLayout(IRGenModule &IGM, SILType classType, - bool forBackwardDeployment) const; - -public: - ClassTypeInfo(llvm::PointerType *irType, Size size, SpareBitVector spareBits, - Alignment align, ClassDecl *theClass, - ReferenceCounting refcount) - : HeapTypeInfo(irType, size, std::move(spareBits), align), - TheClass(theClass), Refcount(refcount) {} - - ReferenceCounting getReferenceCounting() const { return Refcount; } - - ClassDecl *getClass() const { return TheClass; } - - const ClassLayout &getClassLayout(IRGenModule &IGM, SILType type, - bool forBackwardDeployment) const; - - StructLayout *createLayoutWithTailElems(IRGenModule &IGM, SILType classType, - ArrayRef tailTypes) const; -}; - -} // namespace irgen -} // namespace swift - -#endif diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index f613828649ee9..4042d8e9feb0d 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -32,7 +32,6 @@ #include "swift/SIL/SILModule.h" #include "swift/SIL/SILType.h" #include "swift/SIL/SILVTableVisitor.h" -#include "llvm/ADT/None.h" #include "llvm/ADT/SmallString.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" @@ -41,29 +40,72 @@ #include "Callee.h" #include "ClassLayout.h" -#include "ClassTypeInfo.h" #include "ConstantBuilder.h" #include "Explosion.h" #include "GenFunc.h" -#include "GenHeap.h" #include "GenMeta.h" #include "GenObjC.h" #include "GenPointerAuth.h" #include "GenProto.h" #include "GenType.h" -#include "HeapTypeInfo.h" #include "IRGenDebugInfo.h" #include "IRGenFunction.h" #include "IRGenModule.h" +#include "GenHeap.h" +#include "HeapTypeInfo.h" #include "MemberAccessStrategy.h" #include "MetadataLayout.h" #include "MetadataRequest.h" + using namespace swift; using namespace irgen; +namespace { + /// Layout information for class types. + class ClassTypeInfo : public HeapTypeInfo { + ClassDecl *TheClass; + + // The resilient layout of the class, without making any assumptions + // that violate resilience boundaries. This is used to allocate + // and deallocate instances of the class, and to access fields. + mutable Optional ResilientLayout; + + // A completely fragile layout, used for metadata emission. + mutable Optional FragileLayout; + + /// Can we use swift reference-counting, or do we have to use + /// objc_retain/release? + const ReferenceCounting Refcount; + + ClassLayout generateLayout(IRGenModule &IGM, SILType classType, + bool forBackwardDeployment) const; + + public: + ClassTypeInfo(llvm::PointerType *irType, Size size, + SpareBitVector spareBits, Alignment align, + ClassDecl *theClass, ReferenceCounting refcount) + : HeapTypeInfo(irType, size, std::move(spareBits), align), + TheClass(theClass), Refcount(refcount) {} + + ReferenceCounting getReferenceCounting() const { + return Refcount; + } + + ClassDecl *getClass() const { return TheClass; } + + + const ClassLayout &getClassLayout(IRGenModule &IGM, SILType type, + bool forBackwardDeployment) const; + + StructLayout *createLayoutWithTailElems(IRGenModule &IGM, + SILType classType, + ArrayRef tailTypes) const; + }; +} // end anonymous namespace + /// Return the lowered type for the class's 'self' type within its context. -SILType irgen::getSelfType(const ClassDecl *base) { +static SILType getSelfType(const ClassDecl *base) { auto loweredTy = base->getDeclaredTypeInContext()->getCanonicalType(); return SILType::getPrimitiveObjectType(loweredTy); } @@ -286,17 +328,12 @@ namespace { auto element = ElementLayout::getIncomplete(*eltType); bool isKnownEmpty = !addField(element, LayoutStrategy::Universal); - bool isSpecializedGeneric = - (theClass->isGenericContext() && !classType.getASTType() - ->getRecursiveProperties() - .hasUnboundGeneric()); - // The 'Elements' list only contains superclass fields when we're // building a layout for tail allocation. - if (!superclass || TailTypes || isSpecializedGeneric) + if (!superclass || TailTypes) Elements.push_back(element); - if (!superclass || isSpecializedGeneric) { + if (!superclass) { AllStoredProperties.push_back(var); AllFieldAccesses.push_back(getFieldAccess(isKnownEmpty)); } @@ -927,49 +964,26 @@ namespace { /// category data (category_t), or protocol data (protocol_t). class ClassDataBuilder : public ClassMemberVisitor { IRGenModule &IGM; - using ClassPair = std::pair; - using ClassUnion = TaggedUnion; - TaggedUnion TheEntity; + PointerUnion TheEntity; ExtensionDecl *TheExtension; const ClassLayout *FieldLayout; ClassDecl *getClass() const { - const ClassUnion *classUnion; - if (!(classUnion = TheEntity.dyn_cast())) { - return nullptr; - } - if (auto *const *theClass = classUnion->dyn_cast()) { - return *theClass; - } - auto pair = classUnion->get(); - return pair.first; + return TheEntity.get(); } ProtocolDecl *getProtocol() const { - if (auto *const *theProtocol = TheEntity.dyn_cast()) { - return *theProtocol; - } - return nullptr; + return TheEntity.get(); } - Optional getSpecializedGenericType() const { - const ClassUnion *classUnion; - if (!(classUnion = TheEntity.dyn_cast())) { - return llvm::None; - } - const ClassPair *classPair; - if (!(classPair = classUnion->dyn_cast())) { - return llvm::None; - } - auto &pair = *classPair; - return pair.second; - } - + bool isBuildingClass() const { - return TheEntity.isa() && !TheExtension; + return TheEntity.is() && !TheExtension; } bool isBuildingCategory() const { - return TheEntity.isa() && TheExtension; + return TheEntity.is() && TheExtension; + } + bool isBuildingProtocol() const { + return TheEntity.is(); } - bool isBuildingProtocol() const { return TheEntity.isa(); } bool HasNonTrivialDestructor = false; bool HasNonTrivialConstructor = false; @@ -1049,27 +1063,23 @@ namespace { public: ClassDataBuilder(IRGenModule &IGM, ClassDecl *theClass, const ClassLayout &fieldLayout) - : ClassDataBuilder(IGM, ClassUnion(theClass), fieldLayout) {} - - ClassDataBuilder( - IRGenModule &IGM, - TaggedUnion> theUnion, - const ClassLayout &fieldLayout) - : IGM(IGM), TheEntity(theUnion), TheExtension(nullptr), - FieldLayout(&fieldLayout) { - visitConformances(getClass()); - visitMembers(getClass()); - - if (Lowering::usesObjCAllocator(getClass())) { - addIVarInitializer(); - addIVarDestroyer(); + : IGM(IGM), TheEntity(theClass), TheExtension(nullptr), + FieldLayout(&fieldLayout) + { + visitConformances(theClass); + visitMembers(theClass); + + if (Lowering::usesObjCAllocator(theClass)) { + addIVarInitializer(); + addIVarDestroyer(); } } - + ClassDataBuilder(IRGenModule &IGM, ClassDecl *theClass, ExtensionDecl *theExtension) - : IGM(IGM), TheEntity(ClassUnion(theClass)), TheExtension(theExtension), - FieldLayout(nullptr) { + : IGM(IGM), TheEntity(theClass), TheExtension(theExtension), + FieldLayout(nullptr) + { buildCategoryName(CategoryName); visitConformances(theExtension); @@ -1077,7 +1087,7 @@ namespace { for (Decl *member : TheExtension->getMembers()) visit(member); } - + ClassDataBuilder(IRGenModule &IGM, ProtocolDecl *theProtocol) : IGM(IGM), TheEntity(theProtocol), TheExtension(nullptr) { @@ -1133,12 +1143,7 @@ namespace { } } - llvm::Constant *getMetaclassRefOrNull(Type specializedGenericType, - ClassDecl *theClass) { - if (specializedGenericType) { - return IGM.getAddrOfCanonicalSpecializedGenericMetaclassObject( - specializedGenericType->getCanonicalType(), NotForDefinition); - } + llvm::Constant *getMetaclassRefOrNull(ClassDecl *theClass) { if (theClass->isGenericContext() && !theClass->hasClangNode()) { return llvm::ConstantPointerNull::get(IGM.ObjCClassPtrTy); } else { @@ -1148,20 +1153,9 @@ namespace { void buildMetaclassStub() { assert(FieldLayout && "can't build a metaclass from a category"); - - auto specializedGenericType = getSpecializedGenericType().map( - [](auto canType) { return (Type)canType; }); - // The isa is the metaclass pointer for the root class. - auto rootClass = getRootClassForMetaclass(IGM, getClass()); - Type rootType; - if (specializedGenericType && rootClass->isGenericContext()) { - rootType = - (*specializedGenericType)->getRootClass(/*useArchetypes=*/false); - } else { - rootType = Type(); - } - auto rootPtr = getMetaclassRefOrNull(rootType, rootClass); + auto rootClass = getRootClassForMetaclass(IGM, TheEntity.get()); + auto rootPtr = getMetaclassRefOrNull(rootClass); // The superclass of the metaclass is the metaclass of the // superclass. Note that for metaclass stubs, we can always @@ -1172,16 +1166,10 @@ namespace { llvm::Constant *superPtr; if (getClass()->hasSuperclass()) { auto base = getClass()->getSuperclassDecl(); - if (specializedGenericType && base->isGenericContext()) { - superPtr = getMetaclassRefOrNull( - (*specializedGenericType)->getSuperclass(/*useArchetypes=*/false), - base); - } else { - superPtr = getMetaclassRefOrNull(Type(), base); - } + superPtr = getMetaclassRefOrNull(base); } else { superPtr = getMetaclassRefOrNull( - Type(), IGM.getObjCRuntimeBaseForSwiftRootClass(getClass())); + IGM.getObjCRuntimeBaseForSwiftRootClass(getClass())); } auto dataPtr = emitROData(ForMetaClass, DoesNotHaveUpdateCallback); @@ -1196,16 +1184,9 @@ namespace { }; auto init = llvm::ConstantStruct::get(IGM.ObjCClassStructTy, makeArrayRef(fields)); - llvm::Constant *uncastMetaclass; - if (auto theType = getSpecializedGenericType()) { - uncastMetaclass = - IGM.getAddrOfCanonicalSpecializedGenericMetaclassObject( - *theType, ForDefinition); - } else { - uncastMetaclass = - IGM.getAddrOfMetaclassObject(getClass(), ForDefinition); - } - auto metaclass = cast(uncastMetaclass); + auto metaclass = + cast( + IGM.getAddrOfMetaclassObject(getClass(), ForDefinition)); metaclass->setInitializer(init); } @@ -1368,20 +1349,9 @@ namespace { b.addInt32(0); } - // union { - // const uint8_t *IvarLayout; - // ClassMetadata *NonMetaClass; - // }; - Optional specializedGenericType; - if ((specializedGenericType = getSpecializedGenericType()) && forMeta) { - // ClassMetadata *NonMetaClass; - b.addBitCast(IGM.getAddrOfTypeMetadata(*specializedGenericType), - IGM.Int8PtrTy); - } else { - // const uint8_t *IvarLayout; - // GC/ARC layout. TODO. - b.addNullPointer(IGM.Int8PtrTy); - } + // const uint8_t *ivarLayout; + // GC/ARC layout. TODO. + b.addNullPointer(IGM.Int8PtrTy); // const char *name; // It is correct to use the same name for both class and metaclass. @@ -1413,8 +1383,9 @@ namespace { if (hasUpdater) { // Class _Nullable (*metadataUpdateCallback)(Class _Nonnull cls, // void * _Nullable arg); - auto *impl = IGM.getAddrOfObjCMetadataUpdateFunction(getClass(), - NotForDefinition); + auto *impl = IGM.getAddrOfObjCMetadataUpdateFunction( + TheEntity.get(), + NotForDefinition); const auto &schema = IGM.getOptions().PointerAuth.ObjCMethodListFunctionPointers; b.addSignedPointer(impl, schema, PointerAuthEntity()); @@ -2024,14 +1995,14 @@ namespace { /// Get the name of the class or protocol to mangle into the ObjC symbol /// name. StringRef getEntityName(llvm::SmallVectorImpl &buffer) const { - if (auto theClass = getClass()) { + if (auto theClass = TheEntity.dyn_cast()) { return theClass->getObjCRuntimeName(buffer); } - - if (auto theProtocol = getProtocol()) { + + if (auto theProtocol = TheEntity.dyn_cast()) { return theProtocol->getObjCRuntimeName(buffer); } - + llvm_unreachable("not a class or protocol?!"); } @@ -2166,27 +2137,18 @@ void IRGenModule::emitObjCResilientClassStub(ClassDecl *D) { defineAlias(entity, objcStub); } -static llvm::Constant *doEmitClassPrivateData( - IRGenModule &IGM, - TaggedUnion> classUnion) { +/// Emit the private data (RO-data) associated with a class. +llvm::Constant *irgen::emitClassPrivateData(IRGenModule &IGM, + ClassDecl *cls) { assert(IGM.ObjCInterop && "emitting RO-data outside of interop mode"); - - ClassDecl *cls; - - if (auto *theClass = classUnion.dyn_cast()) { - cls = *theClass; - } else { - auto pair = classUnion.get>(); - cls = pair.first; - } - + PrettyStackTraceDecl stackTraceRAII("emitting ObjC metadata for", cls); SILType selfType = getSelfType(cls); auto &classTI = IGM.getTypeInfo(selfType).as(); // FIXME: For now, always use the fragile layout when emitting metadata. auto &fieldLayout = classTI.getClassLayout(IGM, selfType, /*forBackwardDeployment=*/true); - ClassDataBuilder builder(IGM, classUnion, fieldLayout); + ClassDataBuilder builder(IGM, cls, fieldLayout); // First, build the metaclass object. builder.buildMetaclassStub(); @@ -2209,25 +2171,6 @@ static llvm::Constant *doEmitClassPrivateData( return builder.emitROData(ForClass, hasUpdater); } -llvm::Constant *irgen::emitSpecializedGenericClassPrivateData( - IRGenModule &IGM, ClassDecl *theClass, CanType theType) { - assert(theType->getClassOrBoundGenericClass() == theClass); - assert(theClass->getGenericEnvironment()); - Type ty = theType; - PrettyStackTraceType stackTraceRAII(theClass->getASTContext(), - "emitting ObjC metadata for", ty); - return doEmitClassPrivateData( - IGM, TaggedUnion>( - std::make_pair(theClass, theType))); -} - -/// Emit the private data (RO-data) associated with a class. -llvm::Constant *irgen::emitClassPrivateData(IRGenModule &IGM, ClassDecl *cls) { - PrettyStackTraceDecl stackTraceRAII("emitting ObjC metadata for", cls); - return doEmitClassPrivateData( - IGM, TaggedUnion>(cls)); -} - std::pair irgen::emitClassPrivateDataFields(IRGenModule &IGM, ConstantStructBuilder &init, diff --git a/lib/IRGen/GenClass.h b/lib/IRGen/GenClass.h index 549a4a502ec3c..834b10d32ba72 100644 --- a/lib/IRGen/GenClass.h +++ b/lib/IRGen/GenClass.h @@ -51,9 +51,6 @@ namespace irgen { enum class ClassDeallocationKind : unsigned char; enum class FieldAccess : uint8_t; - /// Return the lowered type for the class's 'self' type within its context. - SILType getSelfType(const ClassDecl *base); - OwnedAddress projectPhysicalClassMemberAddress( IRGenFunction &IGF, llvm::Value *base, SILType baseType, SILType fieldType, VarDecl *field); @@ -121,11 +118,6 @@ namespace irgen { ClassDecl *cls); llvm::Constant *emitClassPrivateData(IRGenModule &IGM, ClassDecl *theClass); - - llvm::Constant *emitSpecializedGenericClassPrivateData(IRGenModule &IGM, - ClassDecl *theClass, - CanType theType); - void emitGenericClassPrivateDataTemplate(IRGenModule &IGM, ClassDecl *theClass, llvm::SmallVectorImpl &fields, diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 290f1d24a3138..97ad57e20d1a6 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -38,7 +38,6 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/GlobalDecl.h" #include "llvm/ADT/SmallString.h" -#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Module.h" @@ -1165,8 +1164,7 @@ void IRGenerator::emitLazyDefinitions() { !LazyOpaqueTypeDescriptors.empty() || !LazyFieldDescriptors.empty() || !LazyFunctionDefinitions.empty() || - !LazyWitnessTables.empty() || - !LazyCanonicalSpecializedMetadataAccessors.empty()) { + !LazyWitnessTables.empty()) { // Emit any lazy type metadata we require. while (!LazyTypeMetadata.empty()) { @@ -1222,15 +1220,6 @@ void IRGenerator::emitLazyDefinitions() { && "function with externally-visible linkage emitted lazily?"); IGM->emitSILFunction(f); } - - while (!LazyCanonicalSpecializedMetadataAccessors.empty()) { - CanType theType = - LazyCanonicalSpecializedMetadataAccessors.pop_back_val(); - auto *nominal = theType->getAnyNominal(); - assert(nominal); - CurrentIGMPtr IGM = getGenModule(nominal->getDeclContext()); - emitLazyCanonicalSpecializedMetadataAccessor(*IGM.get(), theType); - } } while (!LazyMetadataAccessors.empty()) { @@ -1405,30 +1394,14 @@ void IRGenerator::noteUseOfFieldDescriptor(NominalTypeDecl *type) { LazyFieldDescriptors.push_back(type); } -void IRGenerator::noteUseOfCanonicalSpecializedMetadataAccessor( - CanType forType) { - auto key = forType->getAnyNominal(); - assert(key); - assert(key->isGenericContext()); - auto &enqueuedSpecializedAccessors = - CanonicalSpecializedAccessorsForGenericTypes[key]; - if (llvm::all_of(enqueuedSpecializedAccessors, - [&](CanType enqueued) { return enqueued != forType; })) { - assert(!FinishedEmittingLazyDefinitions); - LazyCanonicalSpecializedMetadataAccessors.insert(forType); - enqueuedSpecializedAccessors.push_back(forType); - } -} - void IRGenerator::noteUseOfSpecializedGenericTypeMetadata(CanType type) { auto key = type->getAnyNominal(); assert(key); - assert(key->isGenericContext()); - auto &enqueuedSpecializedTypes = CanonicalSpecializationsForGenericTypes[key]; + auto &enqueuedSpecializedTypes = this->SpecializationsForGenericTypes[key]; if (llvm::all_of(enqueuedSpecializedTypes, [&](CanType enqueued) { return enqueued != type; })) { assert(!FinishedEmittingLazyDefinitions); - LazySpecializedTypeMetadataRecords.push_back(type); + this->LazySpecializedTypeMetadataRecords.push_back(type); enqueuedSpecializedTypes.push_back(type); } } @@ -3543,22 +3516,6 @@ IRGenModule::getAddrOfMetaclassObject(ClassDecl *decl, return addr; } -llvm::Constant * -IRGenModule::getAddrOfCanonicalSpecializedGenericMetaclassObject( - CanType concreteType, ForDefinition_t forDefinition) { - auto *theClass = concreteType->getClassOrBoundGenericClass(); - assert(theClass && "only classes have metaclasses"); - assert(concreteType->getClassOrBoundGenericClass()->isGenericContext()); - - auto entity = - LinkEntity::forSpecializedGenericSwiftMetaclassStub(concreteType); - - auto DbgTy = DebugTypeInfo::getObjCClass( - theClass, ObjCClassPtrTy, getPointerSize(), getPointerAlignment()); - auto addr = getAddrOfLLVMVariable(entity, forDefinition, DbgTy); - return addr; -} - /// Fetch the declaration of an Objective-C metadata update callback. llvm::Function * IRGenModule::getAddrOfObjCMetadataUpdateFunction(ClassDecl *classDecl, @@ -3683,38 +3640,6 @@ IRGenModule::getAddrOfGenericTypeMetadataAccessFunction( return entry; } -llvm::Function * -IRGenModule::getAddrOfCanonicalSpecializedGenericTypeMetadataAccessFunction( - CanType theType, ForDefinition_t forDefinition) { - assert(shouldPrespecializeGenericMetadata()); - assert(!theType->hasUnboundGenericType()); - auto *nominal = theType->getAnyNominal(); - assert(nominal); - assert(nominal->isGenericContext()); - - IRGen.noteUseOfCanonicalSpecializedMetadataAccessor(theType); - - LinkEntity entity = - LinkEntity::forPrespecializedTypeMetadataAccessFunction(theType); - llvm::Function *&entry = GlobalFuncs[entity]; - if (entry) { - if (forDefinition) - updateLinkageForDefinition(*this, entry, entity); - return entry; - } - - llvm::Type *paramTypesArray[1]; - paramTypesArray[0] = SizeTy; // MetadataRequest - - auto paramTypes = llvm::makeArrayRef(paramTypesArray, 1); - auto functionType = - llvm::FunctionType::get(TypeMetadataResponseTy, paramTypes, false); - Signature signature(functionType, llvm::AttributeList(), SwiftCC); - LinkInfo link = LinkInfo::get(*this, entity, forDefinition); - entry = createFunction(*this, link, signature); - return entry; -} - /// Get or create a type metadata cache variable. These are an /// implementation detail of type metadata access functions. llvm::Constant * @@ -3901,19 +3826,14 @@ ConstantReference IRGenModule::getAddrOfTypeMetadata(CanType concreteType, llvm::Type *defaultVarTy; unsigned adjustmentIndex; - bool foreign = nominal && requiresForeignTypeMetadata(nominal); - bool fullMetadata = - foreign || (concreteType->getAnyGeneric() && - concreteType->getAnyGeneric()->isGenericContext()); + bool fullMetadata = (nominal && requiresForeignTypeMetadata(nominal)) || + (concreteType->getAnyGeneric() && + concreteType->getAnyGeneric()->isGenericContext()); // Foreign classes reference the full metadata with a GEP. if (fullMetadata) { defaultVarTy = FullTypeMetadataStructTy; - if (concreteType->getClassOrBoundGenericClass() && !foreign) { - adjustmentIndex = MetadataAdjustmentIndex::Class; - } else { - adjustmentIndex = MetadataAdjustmentIndex::ValueType; - } + adjustmentIndex = MetadataAdjustmentIndex::ValueType; // The symbol for other nominal type metadata is generated at the address // point. } else if (nominal) { @@ -3950,24 +3870,19 @@ ConstantReference IRGenModule::getAddrOfTypeMetadata(CanType concreteType, if (fullMetadata) { entity = LinkEntity::forTypeMetadata(concreteType, TypeMetadataAddress::FullMetadata); + DbgTy = DebugTypeInfo::getMetadata(MetatypeType::get(concreteType), + defaultVarTy->getPointerTo(), Size(0), + Alignment(1));; } else { entity = LinkEntity::forTypeMetadata(concreteType, TypeMetadataAddress::AddressPoint); - } - DbgTy = DebugTypeInfo::getMetadata(MetatypeType::get(concreteType), - defaultVarTy->getPointerTo(), Size(0), - Alignment(1)); - - ConstantReference addr; - - if (fullMetadata && !foreign) { - addr = getAddrOfLLVMVariable(*entity, ConstantInit(), DbgTy, refKind, - /*overrideDeclType=*/nullptr); - } else { - addr = getAddrOfLLVMVariable(*entity, ConstantInit(), DbgTy, refKind, - /*overrideDeclType=*/defaultVarTy); + DbgTy = DebugTypeInfo::getMetadata(MetatypeType::get(concreteType), + defaultVarTy->getPointerTo(), Size(0), + Alignment(1));; } + auto addr = getAddrOfLLVMVariable(*entity, ConstantInit(), DbgTy, refKind, + defaultVarTy); if (auto *GV = dyn_cast(addr.getValue())) GV->setComdat(nullptr); diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index 541c627bf15f4..7eca86628b80c 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -44,7 +44,6 @@ #include "Callee.h" #include "ClassLayout.h" #include "ClassMetadataVisitor.h" -#include "ClassTypeInfo.h" #include "ConstantBuilder.h" #include "EnumMetadataVisitor.h" #include "FixedTypeInfo.h" @@ -1902,25 +1901,6 @@ void irgen::emitLazyMetadataAccessor(IRGenModule &IGM, isReadNone); } -void irgen::emitLazyCanonicalSpecializedMetadataAccessor(IRGenModule &IGM, - CanType theType) { - llvm::Function *accessor = - IGM.getAddrOfCanonicalSpecializedGenericTypeMetadataAccessFunction( - theType, ForDefinition); - - if (IGM.getOptions().optimizeForSize()) { - accessor->addFnAttr(llvm::Attribute::NoInline); - } - - emitCacheAccessFunction( - IGM, accessor, /*cache=*/nullptr, CacheStrategy::None, - [&](IRGenFunction &IGF, Explosion ¶ms) { - return emitCanonicalSpecializedGenericTypeMetadataAccessFunction( - IGF, params, theType); - }, - /*isReadNone=*/true); -} - void irgen::emitLazySpecializedGenericTypeMetadata(IRGenModule &IGM, CanType type) { switch (type->getKind()) { @@ -1934,11 +1914,6 @@ void irgen::emitLazySpecializedGenericTypeMetadata(IRGenModule &IGM, emitSpecializedGenericEnumMetadata(IGM, type, *type.getEnumOrBoundGenericEnum()); break; - case TypeKind::Class: - case TypeKind::BoundGenericClass: - emitSpecializedGenericClassMetadata(IGM, type, - *type.getClassOrBoundGenericClass()); - break; default: llvm_unreachable("Cannot statically specialize types of kind other than " "struct and enum."); @@ -2687,8 +2662,6 @@ namespace { using super = ClassMetadataVisitor; protected: - using NominalDecl = ClassDecl; - using super::asImpl; using super::IGM; using super::Target; @@ -2710,34 +2683,26 @@ namespace { VTable(IGM.getSILModule().lookUpVTable(theClass)) {} public: - SILType getLoweredType() { - return IGM.getLoweredType(Target->getDeclaredTypeInContext()); - } - void noteAddressPoint() { ClassMetadataVisitor::noteAddressPoint(); AddressPoint = B.getNextOffsetFromGlobal(); } - ClassFlags getClassFlags() { return ::getClassFlags(Target); } - - void addClassFlags() { B.addInt32((uint32_t)asImpl().getClassFlags()); } + void addClassFlags() { + B.addInt32((uint32_t) getClassFlags(Target)); + } void noteResilientSuperclass() {} void noteStartOfImmediateMembers(ClassDecl *theClass) {} - ConstantReference getValueWitnessTable(bool relativeReference) { - assert( - !relativeReference && - "Cannot get a relative reference to a class' value witness table."); + void addValueWitnessTable() { switch (IGM.getClassMetadataStrategy(Target)) { case ClassMetadataStrategy::Resilient: case ClassMetadataStrategy::Singleton: // The runtime fills in the value witness table for us. - return ConstantReference( - llvm::ConstantPointerNull::get(IGM.WitnessTablePtrTy), - swift::irgen::ConstantReference::Direct); + B.add(llvm::ConstantPointerNull::get(IGM.WitnessTablePtrTy)); + break; case ClassMetadataStrategy::Update: case ClassMetadataStrategy::FixedOrUpdate: @@ -2747,20 +2712,12 @@ namespace { ? IGM.Context.getAnyObjectType() : IGM.Context.TheNativeObjectType); auto wtable = IGM.getAddrOfValueWitnessTable(type); - return ConstantReference(wtable, - swift::irgen::ConstantReference::Direct); + B.add(wtable); + break; } } } - void addValueWitnessTable() { - B.add(asImpl().getValueWitnessTable(false).getValue()); - } - - llvm::Constant *getAddrOfMetaclassObject(ForDefinition_t forDefinition) { - return IGM.getAddrOfMetaclassObject(Target, forDefinition); - } - /// The 'metadata flags' field in a class is actually a pointer to /// the metaclass object for the class. /// @@ -2773,7 +2730,8 @@ namespace { if (IGM.ObjCInterop) { // Get the metaclass pointer as an intptr_t. - auto metaclass = asImpl().getAddrOfMetaclassObject(NotForDefinition); + auto metaclass = IGM.getAddrOfMetaclassObject(Target, + NotForDefinition); auto flags = llvm::ConstantExpr::getPtrToInt(metaclass, IGM.MetadataKindTy); B.add(flags); @@ -2786,32 +2744,18 @@ namespace { } } - llvm::Constant *getSuperclassMetadata() { - Type type = Target->mapTypeIntoContext(Target->getSuperclass()); - auto *metadata = - tryEmitConstantHeapMetadataRef(IGM, type->getCanonicalType(), - /*allowUninit*/ false); - return metadata; - } - - bool shouldAddNullSuperclass() { + void addSuperclass() { // If we might have generic ancestry, leave a placeholder since - // swift_initClassMetadata() will fill in the superclass. + // swift_initClassMetdata() will fill in the superclass. switch (IGM.getClassMetadataStrategy(Target)) { case ClassMetadataStrategy::Resilient: case ClassMetadataStrategy::Singleton: - return true; + B.addNullPointer(IGM.TypeMetadataPtrTy); + return; case ClassMetadataStrategy::Update: case ClassMetadataStrategy::FixedOrUpdate: case ClassMetadataStrategy::Fixed: - return false; - } - } - - void addSuperclass() { - if (asImpl().shouldAddNullSuperclass()) { - B.addNullPointer(IGM.TypeMetadataPtrTy); - return; + break; } // If this is a root class, use SwiftObject as our formal parent. @@ -2831,7 +2775,10 @@ namespace { return; } - auto *metadata = asImpl().getSuperclassMetadata(); + Type type = Target->mapTypeIntoContext(Target->getSuperclass()); + auto *metadata = tryEmitConstantHeapMetadataRef( + IGM, type->getCanonicalType(), + /*allowUninit*/ false); assert(metadata != nullptr); B.add(metadata); } @@ -2866,12 +2813,8 @@ namespace { return ClassContextDescriptorBuilder(IGM, Target, RequireMetadata).emit(); } - llvm::Constant *getNominalTypeDescriptor() { - return emitNominalTypeDescriptor(); - } - void addNominalTypeDescriptor() { - B.addSignedPointer(asImpl().getNominalTypeDescriptor(), + B.addSignedPointer(emitNominalTypeDescriptor(), IGM.getOptions().PointerAuth.TypeDescriptors, PointerAuthEntity::Special::TypeDescriptor); } @@ -2889,13 +2832,9 @@ namespace { B.addInt32(0); } - bool hasFixedLayout() { return FieldLayout.isFixedLayout(); } - - const ClassLayout &getFieldLayout() { return FieldLayout; } - void addInstanceSize() { - if (asImpl().hasFixedLayout()) { - B.addInt32(asImpl().getFieldLayout().getSize().getValue()); + if (FieldLayout.isFixedLayout()) { + B.addInt32(FieldLayout.getSize().getValue()); } else { // Leave a zero placeholder to be filled at runtime B.addInt32(0); @@ -2903,8 +2842,8 @@ namespace { } void addInstanceAlignMask() { - if (asImpl().hasFixedLayout()) { - B.addInt16(asImpl().getFieldLayout().getAlignMask().getValue()); + if (FieldLayout.isFixedLayout()) { + B.addInt16(FieldLayout.getAlignMask().getValue()); } else { // Leave a zero placeholder to be filled at runtime B.addInt16(0); @@ -2934,12 +2873,6 @@ namespace { B.add(IGM.getObjCEmptyVTablePtr()); } - llvm::Constant *getROData() { return emitClassPrivateData(IGM, Target); } - - uint64_t getClassDataPointerHasSwiftMetadataBits() { - return IGM.UseDarwinPreStableABIBit ? 1 : 2; - } - void addClassDataPointer() { if (!IGM.ObjCInterop) { // with no Objective-C runtime, just give an empty pointer with the @@ -2950,11 +2883,11 @@ namespace { } // Derive the RO-data. - llvm::Constant *data = asImpl().getROData(); + llvm::Constant *data = emitClassPrivateData(IGM, Target); // Set a low bit to indicate this class has Swift metadata. - auto bit = llvm::ConstantInt::get( - IGM.IntPtrTy, asImpl().getClassDataPointerHasSwiftMetadataBits()); + auto bit = llvm::ConstantInt::get(IGM.IntPtrTy, + IGM.UseDarwinPreStableABIBit ? 1 : 2); // Emit data + bit. data = llvm::ConstantExpr::getPtrToInt(data, IGM.IntPtrTy); @@ -3008,14 +2941,6 @@ namespace { } }; - static void - addFixedFieldOffset(IRGenModule &IGM, ConstantStructBuilder &B, VarDecl *var, - std::function typeFromContext) { - SILType baseType = SILType::getPrimitiveObjectType( - typeFromContext(var->getDeclContext())->getCanonicalType()); - B.addInt(IGM.SizeTy, getClassFieldOffset(IGM, baseType, var).getValue()); - } - /// A builder for non-generic class metadata which does not require any /// runtime initialization, or that only requires runtime initialization /// on newer Objective-C runtimes. @@ -3032,9 +2957,10 @@ namespace { : super(IGM, theClass, builder, fieldLayout) {} void addFieldOffset(VarDecl *var) { - addFixedFieldOffset(IGM, B, var, [](DeclContext *dc) { - return dc->getDeclaredTypeInContext(); - }); + SILType baseType = SILType::getPrimitiveObjectType( + var->getDeclContext()->getDeclaredTypeInContext() + ->getCanonicalType()); + B.addInt(IGM.SizeTy, getClassFieldOffset(IGM, baseType, var).getValue()); } void addFieldOffsetPlaceholders(MissingMemberDecl *placeholder) { @@ -3056,7 +2982,6 @@ namespace { /// fields or generic ancestry. class SingletonClassMetadataBuilder : public ClassMetadataBuilderBase { - using NominalDecl = StructDecl; using super = ClassMetadataBuilderBase; using super::IGM; using super::B; @@ -3362,183 +3287,6 @@ namespace { metadata, collector); } }; - - template