Skip to content

Commit 2d794b8

Browse files
committed
IRGen: Generate anonymous contexts for properties with opaque return types.
They aren't normally decl contexts, but if one has an opaque type, we want to be able to record the property as a context so that we can reconstruct it in RemoteAST.
1 parent 81c8486 commit 2d794b8

File tree

6 files changed

+93
-22
lines changed

6 files changed

+93
-22
lines changed

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 {

lib/IRGen/GenMeta.cpp

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -512,11 +512,22 @@ namespace {
512512

513513
using super = ContextDescriptorBuilderBase;
514514

515-
DeclContext *DC;
515+
PointerUnion<DeclContext *, VarDecl *> Name;
516516

517+
DeclContext *getInnermostDeclContext() {
518+
if (auto DC = Name.dyn_cast<DeclContext *>()) {
519+
return DC;
520+
}
521+
if (auto VD = Name.dyn_cast<VarDecl *>()) {
522+
return VD->getInnermostDeclContext();
523+
}
524+
llvm_unreachable("unknown name kind");
525+
}
526+
517527
public:
518-
AnonymousContextDescriptorBuilder(IRGenModule &IGM, DeclContext *DC)
519-
: super(IGM), DC(DC)
528+
AnonymousContextDescriptorBuilder(IRGenModule &IGM,
529+
PointerUnion<DeclContext *, VarDecl *> Name)
530+
: super(IGM), Name(Name)
520531
{
521532
}
522533

@@ -528,15 +539,15 @@ namespace {
528539

529540
ConstantReference getParent() {
530541
return IGM.getAddrOfParentContextDescriptor(
531-
DC, /*fromAnonymousContext=*/true);
542+
getInnermostDeclContext(), /*fromAnonymousContext=*/true);
532543
}
533544

534545
ContextDescriptorKind getContextKind() {
535546
return ContextDescriptorKind::Anonymous;
536547
}
537548

538549
GenericSignature *getGenericSignature() {
539-
return DC->getGenericSignatureOfContext();
550+
return getInnermostDeclContext()->getGenericSignatureOfContext();
540551
}
541552

542553
bool isUniqueDescriptor() {
@@ -556,7 +567,7 @@ namespace {
556567
return;
557568

558569
IRGenMangler mangler;
559-
auto mangledName = mangler.mangleContext(DC);
570+
auto mangledName = mangler.mangleAnonymousDescriptorName(Name);
560571
auto mangledNameConstant =
561572
IGM.getAddrOfGlobalString(mangledName,
562573
/*willBeRelativelyAddressed*/ true);
@@ -565,7 +576,7 @@ namespace {
565576

566577
void emit() {
567578
asImpl().layout();
568-
auto addr = IGM.getAddrOfAnonymousContextDescriptor(DC,
579+
auto addr = IGM.getAddrOfAnonymousContextDescriptor(Name,
569580
B.finishAndCreateFuture());
570581
auto var = cast<llvm::GlobalVariable>(addr);
571582

@@ -1717,6 +1728,16 @@ namespace {
17171728
}
17181729

17191730
ConstantReference getParent() {
1731+
// VarDecls aren't normally contexts, but we still want to mangle
1732+
// an anonymous context for one.
1733+
if (IGM.IRGen.Opts.EnableAnonymousContextMangledNames) {
1734+
if (auto namingVar = dyn_cast<VarDecl>(O->getNamingDecl())) {
1735+
return ConstantReference(
1736+
IGM.getAddrOfAnonymousContextDescriptor(namingVar),
1737+
ConstantReference::Direct);
1738+
}
1739+
}
1740+
17201741
DeclContext *parent = O->getNamingDecl()->getInnermostDeclContext();
17211742

17221743
// If we have debug mangled names enabled for anonymous contexts, nest
@@ -1871,8 +1892,9 @@ IRGenModule::getAddrOfExtensionContextDescriptor(ExtensionDecl *ED,
18711892
}
18721893

18731894
llvm::Constant *
1874-
IRGenModule::getAddrOfAnonymousContextDescriptor(DeclContext *DC,
1875-
ConstantInit definition) {
1895+
IRGenModule::getAddrOfAnonymousContextDescriptor(
1896+
PointerUnion<DeclContext *, VarDecl *> DC,
1897+
ConstantInit definition) {
18761898
auto entity = LinkEntity::forAnonymousDescriptor(DC);
18771899
return getAddrOfSharedContextDescriptor(entity, definition,
18781900
[&]{ AnonymousContextDescriptorBuilder(*this, DC).emit(); });

lib/IRGen/IRGenMangler.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,27 @@ class IRGenMangler : public Mangle::ASTMangler {
162162
return finalize();
163163
}
164164

165-
std::string mangleAnonymousDescriptor(const DeclContext *DC) {
165+
void appendAnonymousDescriptorName(PointerUnion<DeclContext*, VarDecl*> Name){
166+
if (auto DC = Name.dyn_cast<DeclContext *>()) {
167+
return appendContext(DC);
168+
}
169+
if (auto VD = Name.dyn_cast<VarDecl *>()) {
170+
return appendEntity(VD);
171+
}
172+
llvm_unreachable("unknown kind");
173+
}
174+
175+
std::string mangleAnonymousDescriptorName(
176+
PointerUnion<DeclContext*, VarDecl*> Name) {
166177
beginMangling();
167-
appendContext(DC);
178+
appendAnonymousDescriptorName(Name);
179+
return finalize();
180+
}
181+
182+
std::string mangleAnonymousDescriptor(
183+
PointerUnion<DeclContext*, VarDecl*> Name) {
184+
beginMangling();
185+
appendAnonymousDescriptorName(Name);
168186
appendOperator("MXX");
169187
return finalize();
170188
}

lib/IRGen/IRGenModule.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,8 +1302,9 @@ private: \
13021302
llvm::Constant *getAddrOfTypeContextDescriptor(NominalTypeDecl *D,
13031303
RequireMetadata_t requireMetadata,
13041304
ConstantInit definition = ConstantInit());
1305-
llvm::Constant *getAddrOfAnonymousContextDescriptor(DeclContext *DC,
1306-
ConstantInit definition = ConstantInit());
1305+
llvm::Constant *getAddrOfAnonymousContextDescriptor(
1306+
PointerUnion<DeclContext *, VarDecl *> Name,
1307+
ConstantInit definition = ConstantInit());
13071308
llvm::Constant *getAddrOfExtensionContextDescriptor(ExtensionDecl *ED,
13081309
ConstantInit definition = ConstantInit());
13091310
llvm::Constant *getAddrOfModuleContextDescriptor(ModuleDecl *D,

lib/IRGen/Linking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ std::string LinkEntity::mangleAsString() const {
218218
return mangler.mangleExtensionDescriptor(getExtension());
219219

220220
case Kind::AnonymousDescriptor:
221-
return mangler.mangleAnonymousDescriptor(getDeclContext());
221+
return mangler.mangleAnonymousDescriptor(getAnonymousDeclContext());
222222

223223
case Kind::ProtocolDescriptor:
224224
return mangler.mangleProtocolDescriptor(cast<ProtocolDecl>(getDecl()));

test/IRGen/opaque_result_type_debug.swift

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,30 @@ extension Int: P {}
77
// CHECK: @"$s24opaque_result_type_debug3fooQryFMXX" = {{.*}}constant{{.*}} [[DEFINER_NAME]]
88
// CHECK: @"$s24opaque_result_type_debug3fooQryFQOMQ" = {{.*}}constant{{.*}} @"$s24opaque_result_type_debug3fooQryFMXX"
99

10-
// CHECK: @"\01l_type_metadata_table" = {{.*}} @"$s24opaque_result_type_debug3fooQryFQOMQ"
11-
1210
public func foo() -> some P {
1311
return 0
1412
}
1513

14+
// CHECK: [[DEFINER_NAME:@.*]] = {{.*}}constant [{{[0-9]+}} x i8] c"$s24opaque_result_type_debug4propQrvp\00"
15+
// CHECK: @"$s24opaque_result_type_debug4propQrvpMXX" = {{.*}}constant{{.*}} [[DEFINER_NAME]]
16+
// CHECK: @"$s24opaque_result_type_debug4propQrvpQOMQ" = {{.*}}constant{{.*}} @"$s24opaque_result_type_debug4propQrvpMXX"
17+
18+
public var prop: some P {
19+
return 0
20+
}
21+
22+
// CHECK: [[DEFINER_NAME:@.*]] = {{.*}}constant [{{[0-9]+}} x i8] c"$s24opaque_result_type_debug3FooVQrycip\00"
23+
// CHECK: @"$s24opaque_result_type_debug3FooVQrycipMXX" = {{.*}}constant{{.*}} [[DEFINER_NAME]]
24+
// CHECK: @"$s24opaque_result_type_debug3FooVQrycipQOMQ" = {{.*}}constant{{.*}} @"$s24opaque_result_type_debug3FooVQrycipMXX"
25+
26+
public struct Foo {
27+
public subscript() -> some P {
28+
return 0
29+
}
30+
}
31+
32+
// CHECK: @"\01l_type_metadata_table" = {{.*}} @"$s24opaque_result_type_debug3fooQryFQOMQ"
33+
1634
@_silgen_name("use") public func use<T: P>(_: T)
1735

1836
public func bar<T: P>(genericValue: T) {
@@ -23,7 +41,17 @@ public func bar<T: P>(genericValue: T) {
2341

2442
let opaqueValue = foo()
2543
use(opaqueValue)
44+
45+
let opaquePropValue = prop
46+
use(opaquePropValue)
47+
48+
let opaqueSubValue = Foo()[]
49+
use(opaqueSubValue)
2650
}
2751

28-
// CHECK: [[OPAQUE_TYPE:![0-9]+]] = !DICompositeType({{.*}} name: "$s24opaque_result_type_debug3fooQryFQOyQo_D"
29-
// CHECK: {{![0-9]+}} = !DILocalVariable(name: "opaqueValue",{{.*}} type: [[OPAQUE_TYPE]])
52+
// CHECK-DAG: [[OPAQUE_TYPE:![0-9]+]] = !DICompositeType({{.*}} name: "$s24opaque_result_type_debug3fooQryFQOyQo_D"
53+
// CHECK-DAG: [[OPAQUE_PROP_TYPE:![0-9]+]] = !DICompositeType({{.*}} name: "$s24opaque_result_type_debug4propQrvpQOyQo_D"
54+
// CHECK-DAG: [[OPAQUE_SUB_TYPE:![0-9]+]] = !DICompositeType({{.*}} name: "$s24opaque_result_type_debug3FooVQrycipQOy_Qo_D"
55+
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaqueValue",{{.*}} type: [[OPAQUE_TYPE]])
56+
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaquePropValue",{{.*}} type: [[OPAQUE_PROP_TYPE]])
57+
// CHECK-DAG: {{![0-9]+}} = !DILocalVariable(name: "opaqueSubValue",{{.*}} type: [[OPAQUE_SUB_TYPE]])

0 commit comments

Comments
 (0)