Skip to content

Commit 414a4e2

Browse files
authored
Merge pull request #27467 from jckarter/symbolic-reference-all-the-things
IRGen: Always use symbolic references in mangled names (on Mach-O platforms)
2 parents 13deb3b + b93096c commit 414a4e2

17 files changed

+426
-164
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,8 @@ class ReflectionContext
393393
auto SecBuf = this->getReader().readBytes(
394394
RemoteAddress(SectionHdrAddress + (I * SectionEntrySize)),
395395
SectionEntrySize);
396+
if (!SecBuf)
397+
return false;
396398
auto SecHdr =
397399
reinterpret_cast<const typename T::Section *>(SecBuf.get());
398400
SecHdrVec.push_back(SecHdr);

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,8 @@ class TypeRefBuilder {
376376
// Try to resolve to the underlying type, if we can.
377377
if (opaqueDescriptor->getKind() ==
378378
Node::Kind::OpaqueTypeDescriptorSymbolicReference) {
379-
if (!OpaqueUnderlyingTypeReader)
380-
return nullptr;
381-
382379
auto underlyingTy = OpaqueUnderlyingTypeReader(
383-
(const void *)opaqueDescriptor->getIndex(), ordinal);
380+
opaqueDescriptor->getIndex(), ordinal);
384381

385382
if (!underlyingTy)
386383
return nullptr;
@@ -598,7 +595,7 @@ class TypeRefBuilder {
598595
unsigned PointerSize;
599596
std::function<Demangle::Node * (RemoteRef<char>)>
600597
TypeRefDemangler;
601-
std::function<const TypeRef* (const void*, unsigned)>
598+
std::function<const TypeRef* (uint64_t, unsigned)>
602599
OpaqueUnderlyingTypeReader;
603600

604601
public:
@@ -613,9 +610,8 @@ class TypeRefBuilder {
613610
Dem, /*useOpaqueTypeSymbolicReferences*/ true);
614611
}),
615612
OpaqueUnderlyingTypeReader(
616-
[&reader](const void *descriptor, unsigned ordinal) -> const TypeRef* {
617-
auto context = (typename Runtime::StoredPointer)descriptor;
618-
return reader.readUnderlyingTypeForOpaqueTypeDescriptor(context,
613+
[&reader](uint64_t descriptorAddr, unsigned ordinal) -> const TypeRef* {
614+
return reader.readUnderlyingTypeForOpaqueTypeDescriptor(descriptorAddr,
619615
ordinal);
620616
})
621617
{}

include/swift/Remote/CMemoryReader.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,13 @@ class CMemoryReader final : public MemoryReader {
6666

6767
bool readString(RemoteAddress address, std::string &dest) override {
6868
auto length = getStringLength(address);
69-
if (!length)
70-
return false;
69+
if (length == 0) {
70+
// A length of zero unfortunately might mean either that there's a zero
71+
// length string at the location we're trying to read, or that reading
72+
// failed. We can do a one-byte read to tell them apart.
73+
auto buf = readBytes(address, 1);
74+
return buf && ((const char*)buf.get())[0] == 0;
75+
}
7176

7277
auto Buf = readBytes(address, length);
7378
if (!Buf)

lib/Basic/QuotedString.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void swift::printAsQuotedString(llvm::raw_ostream &out, llvm::StringRef text) {
3636
};
3737
out << "\\u{" << hexdigit[c >> 4] << hexdigit[c & 0xF] << '}';
3838
} else {
39-
out << c;
39+
out << (char)c;
4040
}
4141
break;
4242
}

lib/Demangling/Demangler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ Node::iterator Node::end() const {
317317
}
318318

319319
void Node::addChild(NodePointer Child, NodeFactory &Factory) {
320+
assert(Child);
320321
switch (NodePayloadKind) {
321322
case PayloadKind::None:
322323
InlineChildren[0] = Child;

lib/IRGen/IRGenMangler.cpp

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -93,26 +93,43 @@ IRGenMangler::withSymbolicReferences(IRGenModule &IGM,
9393
AllowSymbolicReferences = true;
9494
CanSymbolicReference = [&IGM](SymbolicReferent s) -> bool {
9595
if (auto type = s.dyn_cast<const NominalTypeDecl *>()) {
96-
// FIXME: Sometimes we fail to emit metadata for Clang imported types
97-
// even after noting use of their type descriptor or metadata. Work
98-
// around by not symbolic-referencing imported types for now.
99-
if (type->hasClangNode())
100-
return false;
101-
102-
// TODO: We ought to be able to use indirect symbolic references even
103-
// when the referent may be in another file, once the on-disk
104-
// ObjectMemoryReader can handle them.
105-
// Private entities are known to be accessible.
106-
auto formalAccessScope = type->getFormalAccessScope(nullptr, true);
107-
if ((formalAccessScope.isPublic() || formalAccessScope.isInternal()) &&
108-
(!IGM.CurSourceFile ||
109-
IGM.CurSourceFile != type->getParentSourceFile()))
96+
// The short-substitution types in the standard library have compact
97+
// manglings already, and the runtime ought to have a lookup table for
98+
// them. Symbolic referencing would be wasteful.
99+
if (type->getModuleContext()->isStdlibModule()
100+
&& Mangle::getStandardTypeSubst(type->getName().str())) {
110101
return false;
102+
}
111103

112-
// @objc protocols don't have descriptors.
113-
if (auto proto = dyn_cast<ProtocolDecl>(type))
114-
if (proto->isObjC())
104+
// TODO: We could assign a symbolic reference discriminator to refer
105+
// to objc protocol refs.
106+
if (auto proto = dyn_cast<ProtocolDecl>(type)) {
107+
if (proto->isObjC()) {
108+
return false;
109+
}
110+
}
111+
112+
// Classes defined in Objective-C don't have descriptors.
113+
// TODO: We could assign a symbolic reference discriminator to refer
114+
// to objc class refs.
115+
if (auto clas = dyn_cast<ClassDecl>(type)) {
116+
if (clas->hasClangNode()
117+
&& clas->getForeignClassKind() != ClassDecl::ForeignKind::CFType) {
115118
return false;
119+
}
120+
}
121+
122+
// TODO: ObjectMemoryReader for ELF and PE platforms still does not
123+
// implement symbol relocations. For now, on non-Mach-O platforms,
124+
// only symbolic reference things in the same module.
125+
if (IGM.TargetInfo.OutputObjectFormat != llvm::Triple::MachO) {
126+
auto formalAccessScope = type->getFormalAccessScope(nullptr, true);
127+
if ((formalAccessScope.isPublic() || formalAccessScope.isInternal()) &&
128+
(!IGM.CurSourceFile ||
129+
IGM.CurSourceFile != type->getParentSourceFile())) {
130+
return false;
131+
}
132+
}
116133

117134
return true;
118135
} else if (auto opaque = s.dyn_cast<const OpaqueTypeDecl *>()) {

test/IRGen/access_type_metadata_by_mangled_name.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
// CHECK: @"$s36access_type_metadata_by_mangled_name3FooCyAA3BarCyAA3ZimCyAA4ZangCGGGMD" = linkonce_odr hidden global { i32, i32 }
44

5-
// CHECK-little-SAME: @"symbolic 36access_type_metadata_by_mangled_name3FooCyAA3BarCyAA3ZimCyAA4ZangCGGG"
6-
// CHECK-little-SAME: i32 -71
5+
// CHECK-little-SAME: @"symbolic{{.*}}36access_type_metadata_by_mangled_name3FooC{{.*}}AA3BarC{{.*}}AA3ZimC{{.*}}AA4ZangC{{.*}}"
6+
// CHECK-little-SAME: i32 -{{[0-9]+}}
77

8-
// CHECK-big-SAME: i32 -71
9-
// CHECK-big-SAME: @"symbolic 36access_type_metadata_by_mangled_name3FooCyAA3BarCyAA3ZimCyAA4ZangCGGG"
8+
// CHECK-big-SAME: i32 -{{[0-9]+}}
9+
// CHECK-big-SAME: @"symbolic{{.*}}36access_type_metadata_by_mangled_name3FooC{{.*}}AA3BarC{{.*}}AA3ZimCyAA4ZangC{{.*}}"
1010

1111
// CHECK-SAME: align 8
1212

test/IRGen/associated_type_witness.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ protocol HasThreeAssocTypes {
4141
// GLOBAL-SAME: @"$s23associated_type_witness13WithUniversalVAA8AssockedAAMc"
4242
// GLOBAL-SAME: @"associated conformance 23associated_type_witness13WithUniversalVAA8AssockedAA5AssocAaDP_AA1P",
4343
// GLOBAL-SAME: @"associated conformance 23associated_type_witness13WithUniversalVAA8AssockedAA5AssocAaDP_AA1Q"
44-
// GLOBAL-SAME: i64 add (i64 ptrtoint (<{ [36 x i8], i8 }>* @"symbolic 23associated_type_witness9UniversalV" to i64), i64 1) to i8*)
44+
// GLOBAL-SAME: i64 add (i64 ptrtoint (<{ {{.*}} }>* @"symbolic{{.*}}23associated_type_witness9UniversalV" to i64), i64 1) to i8*)
4545
// GLOBAL-SAME: ]
4646
struct WithUniversal : Assocked {
4747
typealias Assoc = Universal
@@ -52,7 +52,7 @@ struct WithUniversal : Assocked {
5252
// GLOBAL-SAME: @"$s23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAAMc"
5353
// GLOBAL-SAME: @"associated conformance 23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAA5Assoc_AA1P"
5454
// GLOBAL-SAME: @"associated conformance 23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAA5Assoc_AA1Q"
55-
// GLOBAL-SAME: @"symbolic 23associated_type_witness9UniversalV"
55+
// GLOBAL-SAME: @"symbolic{{.*}}23associated_type_witness9UniversalV"
5656
// GLOBAL-SAME: ]
5757
struct GenericWithUniversal<T> : Assocked {
5858
typealias Assoc = Universal
@@ -90,7 +90,7 @@ struct Pair<T, U> : P, Q {}
9090
// GLOBAL-SAME: @"$s23associated_type_witness8ComputedVyxq_GAA8AssockedAAMc"
9191
// GLOBAL-SAME: @"associated conformance 23associated_type_witness8ComputedVyxq_GAA8AssockedAA5Assoc_AA1P"
9292
// GLOBAL-SAME: @"associated conformance 23associated_type_witness8ComputedVyxq_GAA8AssockedAA5Assoc_AA1Q"
93-
// GLOBAL-SAME: @"symbolic 23associated_type_witness4PairVyxq_G"
93+
// GLOBAL-SAME: @"symbolic{{.*}}23associated_type_witness4PairV{{.*}}"
9494
// GLOBAL-SAME: ]
9595

9696
struct Computed<T, U> : Assocked {

test/IRGen/class_update_callback_with_stub.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import resilient_objc_class
2929
// -- field descriptor
3030
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMF"
3131
// -- superclass
32-
// CHECK-SAME: @"symbolic 15resilient_class22ResilientOutsideParentC"
32+
// CHECK-SAME: @"symbolic{{[^"]*}}15resilient_class22ResilientOutsideParentC"
3333
// -- metadata bounds
3434
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMo"
3535
// -- extra class flags -- has Objective-C resilient class stub

test/IRGen/keypaths.sil

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ sil_vtable C2 {}
6161
// -- %a: S.x
6262
// CHECK: [[KP_A:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
6363
// CHECK-SAME: [[WORD]]* @keypath_once
64-
// CHECK-SAME: @"symbolic 8keypaths1SV"
64+
// CHECK-SAME: @"symbolic{{.*}}8keypaths1SV"
6565
// CHECK-SAME: @"symbolic Si
6666
// -- instantiable in-line, size 4
6767
// CHECK-SAME: <i32 0x8000_0004>,
@@ -71,7 +71,7 @@ sil_vtable C2 {}
7171
// -- %b: S.y
7272
// CHECK: [[KP_B:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
7373
// CHECK-SAME: [[WORD]]* @keypath_once
74-
// CHECK-SAME: @"symbolic 8keypaths1SV
74+
// CHECK-SAME: @"symbolic{{.*}}8keypaths1SV
7575
// CHECK-SAME: @"symbolic SS
7676
// -- instantiable in-line, size 4
7777
// CHECK-SAME: <i32 0x8000_0004>,
@@ -82,8 +82,8 @@ sil_vtable C2 {}
8282
// -- %c: S.z
8383
// CHECK: [[KP_C:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
8484
// CHECK-SAME: [[WORD]]* @keypath_once
85-
// CHECK-SAME: @"symbolic 8keypaths1SV
86-
// CHECK-SAME: @"symbolic 8keypaths1CC
85+
// CHECK-SAME: @"symbolic{{.*}}8keypaths1SV
86+
// CHECK-SAME: @"symbolic{{.*}}8keypaths1CC
8787
// -- instantiable in-line, size 4
8888
// CHECK-SAME: <i32 0x8000_0004>,
8989
// -- offset of S.z, mutable
@@ -237,7 +237,7 @@ sil_vtable C2 {}
237237
// CHECK: [[KP_I:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
238238
// CHECK-SAME: i32 0
239239
// CHECK-SAME: @"generic environment l"
240-
// CHECK-SAME: @"symbolic 8keypaths3GenVyxxG"
240+
// CHECK-SAME: @"symbolic{{[^"]*}}8keypaths3GenV{{[^"]*}}"
241241
// CHECK-SAME: @"symbolic x"
242242
// -- size 8
243243
// CHECK-SAME: i32 8,
@@ -250,7 +250,7 @@ sil_vtable C2 {}
250250
// CHECK: [[KP_J:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
251251
// CHECK-SAME: i32 0
252252
// CHECK-SAME: @"generic environment l"
253-
// CHECK-SAME: @"symbolic 8keypaths3GenVyxxG"
253+
// CHECK-SAME: @"symbolic{{[^"]*}}8keypaths3GenV{{[^"]*}}"
254254
// CHECK-SAME: @"symbolic x"
255255
// -- size 8
256256
// CHECK-SAME: i32 8,
@@ -305,7 +305,7 @@ sil_vtable C2 {}
305305
// -- %gcx: GC<T>.x
306306
// CHECK: [[KP_GCX:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
307307
// CHECK-SAME: @"generic environment l"
308-
// CHECK-SAME: @"symbolic 8keypaths2GCCyxG"
308+
// CHECK-SAME: @"symbolic{{[^"]*}}8keypaths2GCC{{[^"]*}}"
309309
// CHECK-SAME: @"symbolic x"
310310
// -- class with runtime-resolved offset, mutable
311311
// CHECK-SAME: <i32 0x3fffffe>

test/IRGen/nested_generics.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,10 @@ extension Container.Conformancy3: HasAssoc where T == Outer {
156156
}
157157

158158
// CHECK-CONSTANTS-LABEL: @"$s15nested_generics9ContainerO12Conformancy3Vyx_GAA8HasAssocA2A5OuterORszrlWP" =
159-
// CHECK-CONSTANTS-SAME: @"symbolic 15nested_generics5OuterO"
159+
// CHECK-CONSTANTS-SAME: @"symbolic{{.*}}15nested_generics5OuterO"
160160

161161
// CHECK-CONSTANTS-LABEL: @"$s15nested_generics9ContainerO12Conformancy2Vyx_qd__GAA8HasAssocA2A5OuterORszrlWP" =
162-
// CHECK-CONSTANTS-SAME: @"symbolic 15nested_generics5OuterO"
162+
// CHECK-CONSTANTS-SAME: @"symbolic{{.*}}15nested_generics5OuterO"
163163

164164
// CHECK-CONSTANTS-LABEL: @"$s15nested_generics9ContainerO11ConformancyVyx_qd__GAA8HasAssocAAWP" =
165-
// CHECK-CONSTANTS-SAME: @"symbolic 15nested_generics5OuterO"
165+
// CHECK-CONSTANTS-SAME: @"symbolic{{.*}}15nested_generics5OuterO"

test/IRGen/sil_witness_tables.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct Conformer: Q, QQ {
4343
// CHECK: ]
4444
// CHECK: [[CONFORMER_P_WITNESS_TABLE]] = hidden global [5 x i8*] [
4545
// CHECK: @"associated conformance 18sil_witness_tables9ConformerVAA1PAA5AssocAaDP_AA1A"
46-
// CHECK: "symbolic 18sil_witness_tables14AssocConformerV"
46+
// CHECK: "symbolic{{.*}}18sil_witness_tables14AssocConformerV"
4747
// CHECK: i8* bitcast (void (%swift.type*, %swift.type*, i8**)* @"$s18sil_witness_tables9ConformerVAA1PA2aDP12staticMethod{{[_0-9a-zA-Z]*}}FZTW" to i8*),
4848
// CHECK: i8* bitcast (void (%T18sil_witness_tables9ConformerV*, %swift.type*, i8**)* @"$s18sil_witness_tables9ConformerVAA1PA2aDP14instanceMethod{{[_0-9a-zA-Z]*}}FTW" to i8*)
4949
// CHECK: ]

test/IRGen/witness_table_indirect_conformances.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct Z: P2 {
3333
// CHECK: @"$s35witness_table_indirect_conformances1WVAA2P3AAWP" = hidden global [5 x i8*] [
3434
// CHECK-SAME: @"$s35witness_table_indirect_conformances1WVAA2P3AAMc"
3535
// CHECK-SAME: @"associated conformance 35witness_table_indirect_conformances1WVAA2P3AA05AssocE0AaDP_AA2P2"
36-
// CHECK-SAME: @"symbolic 35witness_table_indirect_conformances1ZV"
36+
// CHECK-SAME: @"symbolic{{.*}}35witness_table_indirect_conformances1ZV"
3737
// CHECK-SAME: i8* bitcast (void (%T35witness_table_indirect_conformances1ZV*, %T35witness_table_indirect_conformances1WV*, %swift.type*, i8**)* @"$s35witness_table_indirect_conformances1WVAA2P3A2aDP08getAssocE00gE0QzyFTW" to i8*)]
3838
struct W: P3 {
3939
typealias AssocP3 = Z

test/IRGen/witness_table_objc_associated_type.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct SB: B {
2121
}
2222
// CHECK-LABEL: @"$s34witness_table_objc_associated_type2SBVAA1BAAWP" = hidden global [4 x i8*] [
2323
// CHECK: @"associated conformance 34witness_table_objc_associated_type2SBVAA1BAA2AAAaDP_AA1A"
24-
// CHECK: @"symbolic 34witness_table_objc_associated_type2SAV"
24+
// CHECK: @"symbolic{{.*}}34witness_table_objc_associated_type2SAV"
2525
// CHECK: i8* bitcast {{.*}} @"$s34witness_table_objc_associated_type2SBVAA1BA2aDP3fooyyFTW"
2626
// CHECK: ]
2727

@@ -31,7 +31,7 @@ struct SO: C {
3131
func foo() {}
3232
}
3333
// CHECK-LABEL: @"$s34witness_table_objc_associated_type2SOVAA1CAAWP" = hidden global [3 x i8*] [
34-
// CHECK: @"symbolic 34witness_table_objc_associated_type2COC"
34+
// CHECK: @"symbolic{{.*}}34witness_table_objc_associated_type2COC"
3535
// CHECK: i8* bitcast {{.*}} @"$s34witness_table_objc_associated_type2SOVAA1CA2aDP3fooyyFTW"
3636
// CHECK: ]
3737

test/Reflection/Inputs/main.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// a dummy main.swift we can use to build executables to test reflection on
2+
// intentionally left blank
3+

test/Reflection/typeref_decoding.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
// REQUIRES: no_asan
22
// RUN: %empty-directory(%t)
3+
34
// RUN: %target-build-swift -Xfrontend -enable-anonymous-context-mangled-names %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift %S/Inputs/Extensions.swift %S/Inputs/Closures.swift -parse-as-library -emit-module -emit-library -module-name TypesToReflect -o %t/%target-library-name(TypesToReflect)
5+
// RUN: %target-build-swift -Xfrontend -enable-anonymous-context-mangled-names %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift %S/Inputs/Extensions.swift %S/Inputs/Closures.swift %S/Inputs/main.swift -emit-module -emit-executable -module-name TypesToReflect -o %t/TypesToReflect
6+
47
// RUN: %target-swift-reflection-dump -binary-filename %t/%target-library-name(TypesToReflect) | %FileCheck %s
8+
// RUN: %target-swift-reflection-dump -binary-filename %t/TypesToReflect | %FileCheck %s
59

610
// CHECK: FIELDS:
711
// CHECK: =======

0 commit comments

Comments
 (0)