Skip to content

Commit a6b5a41

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 17511c0 commit a6b5a41

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
@@ -770,9 +770,10 @@ class LinkEntity {
770770
return entity;
771771
}
772772

773-
static LinkEntity forAnonymousDescriptor(DeclContext *dc) {
773+
static LinkEntity forAnonymousDescriptor(
774+
PointerUnion<DeclContext *, VarDecl *> dc) {
774775
LinkEntity entity;
775-
entity.Pointer = const_cast<void*>(static_cast<const void*>(dc));
776+
entity.Pointer = dc.getOpaqueValue();
776777
entity.SecondaryPointer = nullptr;
777778
entity.Data =
778779
LINKENTITY_SET_FIELD(Kind, unsigned(Kind::AnonymousDescriptor));
@@ -1015,9 +1016,10 @@ class LinkEntity {
10151016
return reinterpret_cast<ExtensionDecl*>(Pointer);
10161017
}
10171018

1018-
const DeclContext *getDeclContext() const {
1019+
const PointerUnion<DeclContext *, VarDecl *> getAnonymousDeclContext() const {
10191020
assert(getKind() == Kind::AnonymousDescriptor);
1020-
return reinterpret_cast<DeclContext*>(Pointer);
1021+
return PointerUnion<DeclContext *, VarDecl *>
1022+
::getFromOpaqueValue(reinterpret_cast<void*>(Pointer));
10211023
}
10221024

10231025
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
@@ -1872,8 +1893,9 @@ IRGenModule::getAddrOfExtensionContextDescriptor(ExtensionDecl *ED,
18721893
}
18731894

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

lib/IRGen/IRGenMangler.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,27 @@ class IRGenMangler : public Mangle::ASTMangler {
186186
return finalize();
187187
}
188188

189-
std::string mangleAnonymousDescriptor(const DeclContext *DC) {
189+
void appendAnonymousDescriptorName(PointerUnion<DeclContext*, VarDecl*> Name){
190+
if (auto DC = Name.dyn_cast<DeclContext *>()) {
191+
return appendContext(DC);
192+
}
193+
if (auto VD = Name.dyn_cast<VarDecl *>()) {
194+
return appendEntity(VD);
195+
}
196+
llvm_unreachable("unknown kind");
197+
}
198+
199+
std::string mangleAnonymousDescriptorName(
200+
PointerUnion<DeclContext*, VarDecl*> Name) {
190201
beginMangling();
191-
appendContext(DC);
202+
appendAnonymousDescriptorName(Name);
203+
return finalize();
204+
}
205+
206+
std::string mangleAnonymousDescriptor(
207+
PointerUnion<DeclContext*, VarDecl*> Name) {
208+
beginMangling();
209+
appendAnonymousDescriptorName(Name);
192210
appendOperator("MXX");
193211
return finalize();
194212
}

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
@@ -234,7 +234,7 @@ std::string LinkEntity::mangleAsString() const {
234234
return mangler.mangleExtensionDescriptor(getExtension());
235235

236236
case Kind::AnonymousDescriptor:
237-
return mangler.mangleAnonymousDescriptor(getDeclContext());
237+
return mangler.mangleAnonymousDescriptor(getAnonymousDeclContext());
238238

239239
case Kind::ProtocolDescriptor:
240240
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)