Skip to content

Commit 4cd2c24

Browse files
authored
Merge pull request #24446 from jckarter/opaque-type-remote-5.1
[5.1] Debugger support for opaque types.
2 parents d66534f + 2d794b8 commit 4cd2c24

File tree

19 files changed

+327
-81
lines changed

19 files changed

+327
-81
lines changed

include/swift/ABI/Metadata.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ template <typename Runtime> struct TargetStructMetadata;
457457
template <typename Runtime> struct TargetOpaqueMetadata;
458458
template <typename Runtime> struct TargetValueMetadata;
459459
template <typename Runtime> struct TargetForeignClassMetadata;
460+
template <typename Runtime> struct TargetContextDescriptor;
460461
template <typename Runtime> class TargetTypeContextDescriptor;
461462
template <typename Runtime> class TargetClassDescriptor;
462463
template <typename Runtime> class TargetValueTypeDescriptor;
@@ -2085,12 +2086,12 @@ struct TargetTypeMetadataRecord {
20852086
private:
20862087
union {
20872088
/// A direct reference to a nominal type descriptor.
2088-
RelativeDirectPointerIntPair<TargetTypeContextDescriptor<Runtime>,
2089+
RelativeDirectPointerIntPair<TargetContextDescriptor<Runtime>,
20892090
TypeReferenceKind>
20902091
DirectNominalTypeDescriptor;
20912092

20922093
/// An indirect reference to a nominal type descriptor.
2093-
RelativeDirectPointerIntPair<TargetTypeContextDescriptor<Runtime> * const,
2094+
RelativeDirectPointerIntPair<TargetContextDescriptor<Runtime> * const,
20942095
TypeReferenceKind>
20952096
IndirectNominalTypeDescriptor;
20962097

@@ -2103,8 +2104,8 @@ struct TargetTypeMetadataRecord {
21032104
return DirectNominalTypeDescriptor.getInt();
21042105
}
21052106

2106-
const TargetTypeContextDescriptor<Runtime> *
2107-
getTypeContextDescriptor() const {
2107+
const TargetContextDescriptor<Runtime> *
2108+
getContextDescriptor() const {
21082109
switch (getTypeKind()) {
21092110
case TypeReferenceKind::DirectTypeDescriptor:
21102111
return DirectNominalTypeDescriptor.getPointer();
@@ -3043,11 +3044,16 @@ struct TargetOpaqueTypeDescriptor final
30433044
return getNumUnderlyingTypeArguments();
30443045
}
30453046

3047+
const RelativeDirectPointer<const char> &
3048+
getUnderlyingTypeArgumentMangledName(unsigned i) const {
3049+
assert(i < getNumUnderlyingTypeArguments());
3050+
return (this
3051+
->template getTrailingObjects<RelativeDirectPointer<const char>>())[i];
3052+
}
3053+
30463054
StringRef getUnderlyingTypeArgument(unsigned i) const {
30473055
assert(i < getNumUnderlyingTypeArguments());
3048-
const char *ptr =
3049-
(this->template getTrailingObjects<RelativeDirectPointer<const char>>())[i];
3050-
3056+
const char *ptr = getUnderlyingTypeArgumentMangledName(i);
30513057
return Demangle::makeSymbolicMangledNameStringRef(ptr);
30523058
}
30533059

include/swift/AST/ASTMangler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ class ASTMangler : public Mangler {
171171

172172
std::string mangleTypeForDebugger(Type decl, const DeclContext *DC);
173173

174+
std::string mangleOpaqueTypeDescriptor(const OpaqueTypeDecl *decl);
175+
174176
std::string mangleDeclType(const ValueDecl *decl);
175177

176178
std::string mangleObjCRuntimeName(const NominalTypeDecl *Nominal);

include/swift/AST/Types.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4790,7 +4790,7 @@ class OpaqueTypeArchetypeType final : public ArchetypeType,
47904790
return Substitutions;
47914791
}
47924792

4793-
/// Get the generic signature used to build out this archetype. This is
4793+
/// Get the generic signature used to build out this archetype. This isa
47944794
/// equivalent to the OpaqueTypeDecl's interface generic signature, with
47954795
/// all of the generic parameters aside from the opaque type's interface
47964796
/// type same-type-constrained to their substitutions for this type.
@@ -4805,6 +4805,18 @@ class OpaqueTypeArchetypeType final : public ArchetypeType,
48054805
return T->getKind() == TypeKind::OpaqueTypeArchetype;
48064806
}
48074807

4808+
/// Get the ordinal of the type within the declaration's opaque signature.
4809+
///
4810+
/// If a method declared its return type as:
4811+
///
4812+
/// func foo() -> (some P, some Q)
4813+
///
4814+
/// then the underlying type of `some P` would be ordinal 0, and `some Q` would be ordinal 1.
4815+
unsigned getOrdinal() const {
4816+
// TODO: multiple opaque types
4817+
return 0;
4818+
}
4819+
48084820
static void Profile(llvm::FoldingSetNodeID &ID,
48094821
OpaqueTypeDecl *OpaqueDecl,
48104822
SubstitutionMap Substitutions);

include/swift/IRGen/Linking.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -728,9 +728,10 @@ class LinkEntity {
728728
return entity;
729729
}
730730

731-
static LinkEntity forAnonymousDescriptor(DeclContext *dc) {
731+
static LinkEntity forAnonymousDescriptor(
732+
PointerUnion<DeclContext *, VarDecl *> dc) {
732733
LinkEntity entity;
733-
entity.Pointer = const_cast<void*>(static_cast<const void*>(dc));
734+
entity.Pointer = dc.getOpaqueValue();
734735
entity.SecondaryPointer = nullptr;
735736
entity.Data =
736737
LINKENTITY_SET_FIELD(Kind, unsigned(Kind::AnonymousDescriptor));
@@ -973,9 +974,10 @@ class LinkEntity {
973974
return reinterpret_cast<ExtensionDecl*>(Pointer);
974975
}
975976

976-
const DeclContext *getDeclContext() const {
977+
const PointerUnion<DeclContext *, VarDecl *> getAnonymousDeclContext() const {
977978
assert(getKind() == Kind::AnonymousDescriptor);
978-
return reinterpret_cast<DeclContext*>(Pointer);
979+
return PointerUnion<DeclContext *, VarDecl *>
980+
::getFromOpaqueValue(reinterpret_cast<void*>(Pointer));
979981
}
980982

981983
SILFunction *getSILFunction() const {

include/swift/Remote/MetadataReader.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,35 @@ class MetadataReader {
724724
return nullptr;
725725
return buildContextMangling(context, Dem);
726726
}
727+
728+
/// Read the mangled underlying type from an opaque type descriptor.
729+
BuiltType
730+
readUnderlyingTypeForOpaqueTypeDescriptor(StoredPointer contextAddr,
731+
unsigned ordinal) {
732+
auto context = readContextDescriptor(contextAddr);
733+
if (!context)
734+
return BuiltType();
735+
if (context->getKind() != ContextDescriptorKind::OpaqueType)
736+
return BuiltType();
737+
738+
auto opaqueType =
739+
reinterpret_cast<const TargetOpaqueTypeDescriptor<Runtime> *>(
740+
context.getLocalBuffer());
741+
742+
if (ordinal >= opaqueType->getNumUnderlyingTypeArguments())
743+
return BuiltType();
744+
745+
auto nameAddr = resolveRelativeField(context,
746+
opaqueType->getUnderlyingTypeArgumentMangledName(ordinal));
747+
748+
Demangle::Demangler Dem;
749+
auto node = readMangledName(RemoteAddress(nameAddr),
750+
MangledNameKind::Type, Dem);
751+
if (!node)
752+
return BuiltType();
753+
754+
return decodeMangledType(node);
755+
}
727756

728757
bool isTaggedPointer(StoredPointer objectAddress) {
729758
if (getTaggedPointerEncoding() != TaggedPointerEncodingKind::Extended)
@@ -1396,6 +1425,12 @@ class MetadataReader {
13961425
case ContextDescriptorKind::Protocol:
13971426
baseSize = sizeof(TargetProtocolDescriptor<Runtime>);
13981427
break;
1428+
case ContextDescriptorKind::OpaqueType:
1429+
baseSize = sizeof(TargetOpaqueTypeDescriptor<Runtime>);
1430+
metadataInitSize =
1431+
sizeof(typename Runtime::template RelativeDirectPointer<const char>)
1432+
* flags.getKindSpecificFlags();
1433+
break;
13991434
default:
14001435
// We don't know about this kind of context.
14011436
return nullptr;
@@ -2076,6 +2111,29 @@ class MetadataReader {
20762111
// contexts; just create the node directly here and return.
20772112
return dem.createNode(nodeKind, std::move(moduleName));
20782113
}
2114+
2115+
case ContextDescriptorKind::OpaqueType: {
2116+
// The opaque type may have a named anonymous context for us to map
2117+
// back to its defining decl.
2118+
if (!parentDescriptorResult)
2119+
return nullptr;
2120+
auto anonymous =
2121+
dyn_cast_or_null<TargetAnonymousContextDescriptor<Runtime>>(
2122+
parentDescriptorResult->getLocalBuffer());
2123+
if (!anonymous)
2124+
return nullptr;
2125+
2126+
auto mangledNode =
2127+
demangleAnonymousContextName(*parentDescriptorResult, dem);
2128+
if (!mangledNode)
2129+
return nullptr;
2130+
if (mangledNode->getKind() == Node::Kind::Global)
2131+
mangledNode = mangledNode->getChild(0);
2132+
2133+
auto opaqueNode = dem.createNode(Node::Kind::OpaqueReturnTypeOf);
2134+
opaqueNode->addChild(mangledNode, dem);
2135+
return opaqueNode;
2136+
}
20792137

20802138
default:
20812139
// Not a kind of context we know about.

include/swift/RemoteAST/RemoteAST.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,17 @@ class RemoteASTContext {
240240
Result<OpenedExistential>
241241
getDynamicTypeAndAddressForExistential(remote::RemoteAddress address,
242242
Type staticType);
243+
244+
/// Given a reference to an opaque type descriptor, an ordinal, and a set
245+
/// of substitutions, get the underlying type for the opaque type.
246+
///
247+
/// This does not recursively apply the transformation if the underlying
248+
/// type in turn refers to another opaque type.
249+
Result<Type>
250+
getUnderlyingTypeForOpaqueType(remote::RemoteAddress opaqueDescriptor,
251+
SubstitutionMap substitutions,
252+
unsigned ordinal);
253+
243254
};
244255

245256
} // end namespace remoteAST

lib/AST/ASTDemangler.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,14 @@ Type ASTBuilder::resolveOpaqueType(NodePointer opaqueDescriptor,
255255
unsigned ordinal) {
256256
if (opaqueDescriptor->getKind() == Node::Kind::OpaqueReturnTypeOf) {
257257
auto definingDecl = opaqueDescriptor->getChild(0);
258-
auto mangledName = mangleNode(definingDecl);
258+
auto definingGlobal = Factory.createNode(Node::Kind::Global);
259+
definingGlobal->addChild(definingDecl, Factory);
260+
auto mangledName = mangleNode(definingGlobal);
261+
259262
auto moduleNode = findModuleNode(definingDecl);
260263
if (!moduleNode)
261264
return Type();
262-
auto parentModule = findModule(findModuleNode(definingDecl));
265+
auto parentModule = findModule(moduleNode);
263266
if (!parentModule)
264267
return Type();
265268

lib/AST/ASTMangler.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2665,3 +2665,10 @@ void ASTMangler::appendOpParamForLayoutConstraint(LayoutConstraint layout) {
26652665
break;
26662666
}
26672667
}
2668+
2669+
std::string ASTMangler::mangleOpaqueTypeDescriptor(const OpaqueTypeDecl *decl) {
2670+
beginMangling();
2671+
appendOpaqueDeclName(decl);
2672+
appendOperator("MQ");
2673+
return finalize();
2674+
}

lib/IRGen/GenDecl.cpp

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -826,14 +826,16 @@ void IRGenModule::addObjCClass(llvm::Constant *classPtr, bool nonlazy) {
826826
ObjCNonLazyClasses.push_back(classPtr);
827827
}
828828

829-
void IRGenModule::addRuntimeResolvableType(NominalTypeDecl *nominal) {
829+
void IRGenModule::addRuntimeResolvableType(GenericTypeDecl *type) {
830830
// Collect the nominal type records we emit into a special section.
831-
RuntimeResolvableTypes.push_back(nominal);
831+
RuntimeResolvableTypes.push_back(type);
832832

833-
// As soon as the type metadata is available, all the type's conformances
834-
// must be available, too. The reason is that a type (with the help of its
835-
// metadata) can be checked at runtime if it conforms to a protocol.
836-
addLazyConformances(nominal);
833+
if (auto nominal = dyn_cast<NominalTypeDecl>(type)) {
834+
// As soon as the type metadata is available, all the type's conformances
835+
// must be available, too. The reason is that a type (with the help of its
836+
// metadata) can be checked at runtime if it conforms to a protocol.
837+
addLazyConformances(nominal);
838+
}
837839
}
838840

839841
ConstantReference
@@ -2634,41 +2636,49 @@ getObjCClassByNameReference(IRGenModule &IGM, ClassDecl *cls) {
26342636
SmallString<64> objcRuntimeNameBuffer;
26352637
auto ref = IGM.getAddrOfGlobalString(
26362638
cls->getObjCRuntimeName(objcRuntimeNameBuffer),
2637-
/*willByRelativelyAddressed=*/true);
2639+
/*willBeRelativelyAddressed=*/true);
26382640

26392641
return TypeEntityReference(kind, ref);
26402642
}
26412643

26422644
TypeEntityReference
2643-
IRGenModule::getTypeEntityReference(NominalTypeDecl *decl) {
2645+
IRGenModule::getTypeEntityReference(GenericTypeDecl *decl) {
26442646
if (auto protocol = dyn_cast<ProtocolDecl>(decl)) {
26452647
assert(!protocol->isObjC() && "imported protocols not handled here");
26462648
return getProtocolDescriptorEntityReference(*this, protocol);
26472649
}
2648-
2649-
auto clas = dyn_cast<ClassDecl>(decl);
2650-
if (!clas) {
2651-
return getTypeContextDescriptorEntityReference(*this, decl);
2650+
2651+
if (auto opaque = dyn_cast<OpaqueTypeDecl>(decl)) {
2652+
auto entity = LinkEntity::forOpaqueTypeDescriptor(opaque);
2653+
IRGen.noteUseOfOpaqueTypeDescriptor(opaque);
2654+
return getContextDescriptorEntityReference(*this, entity);
26522655
}
26532656

2654-
switch (clas->getForeignClassKind()) {
2655-
case ClassDecl::ForeignKind::RuntimeOnly:
2656-
return getObjCClassByNameReference(*this, clas);
2657+
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
2658+
auto clas = dyn_cast<ClassDecl>(decl);
2659+
if (!clas) {
2660+
return getTypeContextDescriptorEntityReference(*this, nominal);
2661+
}
26572662

2658-
case ClassDecl::ForeignKind::CFType:
2659-
return getTypeContextDescriptorEntityReference(*this, clas);
2663+
switch (clas->getForeignClassKind()) {
2664+
case ClassDecl::ForeignKind::RuntimeOnly:
2665+
return getObjCClassByNameReference(*this, clas);
26602666

2661-
case ClassDecl::ForeignKind::Normal:
2662-
if (hasKnownSwiftMetadata(*this, clas)) {
2667+
case ClassDecl::ForeignKind::CFType:
26632668
return getTypeContextDescriptorEntityReference(*this, clas);
2664-
}
26652669

2666-
// Note: we would like to use an Objective-C class reference, but the
2667-
// Darwin linker currently has a bug where it will coalesce these symbols
2668-
// *after* computing a relative offset, causing incorrect relative
2669-
// offsets in the metadata. Therefore, reference Objective-C classes by
2670-
// their runtime names.
2671-
return getObjCClassByNameReference(*this, clas);
2670+
case ClassDecl::ForeignKind::Normal:
2671+
if (hasKnownSwiftMetadata(*this, clas)) {
2672+
return getTypeContextDescriptorEntityReference(*this, clas);
2673+
}
2674+
2675+
// Note: we would like to use an Objective-C class reference, but the
2676+
// Darwin linker currently has a bug where it will coalesce these symbols
2677+
// *after* computing a relative offset, causing incorrect relative
2678+
// offsets in the metadata. Therefore, reference Objective-C classes by
2679+
// their runtime names.
2680+
return getObjCClassByNameReference(*this, clas);
2681+
}
26722682
}
26732683
llvm_unreachable("bad foreign type kind");
26742684
}

0 commit comments

Comments
 (0)