Skip to content

Commit 0c88b88

Browse files
committed
[ABI] Optionally emit mangled names into anonymous context metadata.
When -enable-anonymous-context-mangled-names is provided, emit mangled names as part of the metadata of an anonymous context. This will allow us to match textual mangled names to the metadata. This is a backward-compatible ABI extension. Part of rdar://problem/38231646/.
1 parent 1d2290c commit 0c88b88

File tree

8 files changed

+124
-4
lines changed

8 files changed

+124
-4
lines changed

include/swift/ABI/Metadata.h

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2808,18 +2808,67 @@ struct TargetExtensionContextDescriptor final
28082808

28092809
using ExtensionContextDescriptor = TargetExtensionContextDescriptor<InProcess>;
28102810

2811+
template<typename Runtime>
2812+
struct TargetMangledContextName {
2813+
/// The mangled name of the context.
2814+
TargetRelativeDirectPointer<Runtime, const char, /*nullable*/ false> name;
2815+
};
2816+
28112817
template<typename Runtime>
28122818
struct TargetAnonymousContextDescriptor final
28132819
: TargetContextDescriptor<Runtime>,
2814-
TrailingGenericContextObjects<TargetAnonymousContextDescriptor<Runtime>>
2820+
TrailingGenericContextObjects<TargetAnonymousContextDescriptor<Runtime>,
2821+
TargetGenericContextDescriptorHeader,
2822+
TargetMangledContextName<Runtime>>
28152823
{
28162824
private:
28172825
using TrailingGenericContextObjects
2818-
= TrailingGenericContextObjects<TargetAnonymousContextDescriptor<Runtime>>;
2826+
= TrailingGenericContextObjects<TargetAnonymousContextDescriptor<Runtime>,
2827+
TargetGenericContextDescriptorHeader,
2828+
TargetMangledContextName<Runtime>>;
2829+
using TrailingObjects =
2830+
typename TrailingGenericContextObjects::TrailingObjects;
2831+
friend TrailingObjects;
28192832

28202833
public:
2834+
using MangledContextName = TargetMangledContextName<Runtime>;
2835+
28212836
using TrailingGenericContextObjects::getGenericContext;
2837+
using TrailingGenericContextObjects::getGenericContextHeader;
2838+
using TrailingGenericContextObjects::getFullGenericContextHeader;
2839+
using TrailingGenericContextObjects::getGenericParams;
2840+
2841+
AnonymousContextDescriptorFlags getAnonymousContextDescriptorFlags() const {
2842+
return AnonymousContextDescriptorFlags(this->Flags.getKindSpecificFlags());
2843+
}
2844+
2845+
/// Whether this anonymous context descriptor contains a full mangled name,
2846+
/// which can be used to match the anonymous type to its textual form.
2847+
bool hasMangledName() const {
2848+
return getAnonymousContextDescriptorFlags().hasMangledName();
2849+
}
28222850

2851+
/// Retrieve the mangled name of this context, or NULL if it was not
2852+
/// recorded in the metadata.
2853+
ConstTargetPointer<Runtime, char> getMangledName() const {
2854+
if (!hasMangledName())
2855+
return nullptr;
2856+
2857+
return this->template getTrailingObjects<MangledContextName>()->name;
2858+
}
2859+
2860+
private:
2861+
template<typename T>
2862+
using OverloadToken =
2863+
typename TrailingGenericContextObjects::template OverloadToken<T>;
2864+
2865+
using TrailingGenericContextObjects::numTrailingObjects;
2866+
2867+
size_t numTrailingObjects(OverloadToken<MangledContextName>) const {
2868+
return this->hasMangledNam() ? 1 : 0;
2869+
}
2870+
2871+
public:
28232872
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
28242873
return cd->getKind() == ContextDescriptorKind::Anonymous;
28252874
}

include/swift/ABI/MetadataValues.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,23 @@ class ProtocolContextDescriptorFlags : public FlagSet<uint16_t> {
13441344
setSpecialProtocol)
13451345
};
13461346

1347+
/// Flags for anonymous type context descriptors. These values are used as the
1348+
/// kindSpecificFlags of the ContextDescriptorFlags for the anonymous context.
1349+
class AnonymousContextDescriptorFlags : public FlagSet<uint16_t> {
1350+
enum {
1351+
/// Whether this anonymous context descriptor is followed by its
1352+
/// mangled name, which can be used to match the descriptor at runtime.
1353+
HasMangledName = 0,
1354+
};
1355+
1356+
public:
1357+
explicit AnonymousContextDescriptorFlags(uint16_t bits) : FlagSet(bits) {}
1358+
constexpr AnonymousContextDescriptorFlags() {}
1359+
1360+
FLAGSET_DEFINE_FLAG_ACCESSORS(HasMangledName, hasMangledName,
1361+
setHasMangledName)
1362+
};
1363+
13471364
enum class GenericParamKind : uint8_t {
13481365
/// A type parameter.
13491366
Type = 0,

include/swift/AST/IRGenOptions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ class IRGenOptions {
165165
/// Emit names of struct stored properties and enum cases.
166166
unsigned EnableReflectionNames : 1;
167167

168+
/// Emit mangled names of anonymous context descriptors.
169+
unsigned EnableAnonymousContextMangledNames : 1;
170+
168171
/// Enables resilient class layout.
169172
unsigned EnableClassResilience : 1;
170173

@@ -224,7 +227,8 @@ class IRGenOptions {
224227
EmitStackPromotionChecks(false), PrintInlineTree(false),
225228
EmbedMode(IRGenEmbedMode::None), HasValueNamesSetting(false),
226229
ValueNames(false), EnableReflectionMetadata(true),
227-
EnableReflectionNames(true), EnableClassResilience(false),
230+
EnableReflectionNames(true), EnableAnonymousContextMangledNames(false),
231+
EnableClassResilience(false),
228232
EnableResilienceBypass(false), LazyInitializeClassMetadata(false),
229233
UseIncrementalLLVMCodeGen(true), UseSwiftCall(false),
230234
GenerateProfile(false), EnableDynamicReplacementChaining(false),

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ def disable_llvm_value_names : Flag<["-"], "disable-llvm-value-names">,
272272
def enable_llvm_value_names : Flag<["-"], "enable-llvm-value-names">,
273273
HelpText<"Add names to local values in LLVM IR">;
274274

275+
def enable_anonymous_context_mangled_names :
276+
Flag<["-"], "enable-anonymous-context-mangled-names">,
277+
HelpText<"Enable emission of mangled names in anonymous context descriptors">;
278+
275279
def disable_reflection_metadata : Flag<["-"], "disable-reflection-metadata">,
276280
HelpText<"Disable emission of reflection metadata for nominal types">;
277281

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,9 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
10471047
Opts.EnableReflectionNames = false;
10481048
}
10491049

1050+
if (Args.hasArg(OPT_enable_anonymous_context_mangled_names))
1051+
Opts.EnableAnonymousContextMangledNames = true;
1052+
10501053
if (Args.hasArg(OPT_disable_reflection_names)) {
10511054
Opts.EnableReflectionNames = false;
10521055
}

lib/IRGen/GenMeta.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ namespace {
511511
void layout() {
512512
super::layout();
513513
asImpl().addGenericSignature();
514+
asImpl().addMangledName();
514515
}
515516

516517
ConstantReference getParent() {
@@ -530,6 +531,26 @@ namespace {
530531
return true;
531532
}
532533

534+
uint16_t getKindSpecificFlags() {
535+
AnonymousContextDescriptorFlags flags{};
536+
flags.setHasMangledName(
537+
IGM.IRGen.Opts.EnableAnonymousContextMangledNames);
538+
539+
return flags.getOpaqueValue();
540+
}
541+
542+
void addMangledName() {
543+
if (!IGM.IRGen.Opts.EnableAnonymousContextMangledNames)
544+
return;
545+
546+
IRGenMangler mangler;
547+
auto mangledName = mangler.mangleContext(DC);
548+
auto mangledNameConstant =
549+
IGM.getAddrOfGlobalString(mangledName,
550+
/*willBeRelativelyAddressed*/ true);
551+
B.addRelativeAddress(mangledNameConstant);
552+
}
553+
533554
void emit() {
534555
asImpl().layout();
535556
auto addr = IGM.getAddrOfAnonymousContextDescriptor(DC,

lib/IRGen/IRGenMangler.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,13 @@ class IRGenMangler : public Mangle::ASTMangler {
153153
appendOperator("MXX");
154154
return finalize();
155155
}
156-
156+
157+
std::string mangleContext(const DeclContext *DC) {
158+
beginMangling();
159+
appendContext(DC);
160+
return finalize();
161+
}
162+
157163
std::string mangleBareProtocol(const ProtocolDecl *Decl) {
158164
beginMangling();
159165
appendProtocolName(Decl, /*allowStandardSubstitution=*/false);

test/IRGen/anonymous_context_descriptors.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s
2+
// RUN: %target-swift-frontend -emit-ir -enable-anonymous-context-mangled-names %s | %FileCheck %s -check-prefix CHECK-MANGLED
23

34
import Builtin
45
import Swift
@@ -9,15 +10,30 @@ class Blah<T: P> {
910
private struct Inner<U: P> { }
1011
}
1112

13+
// Mangled name of the anonymous descriptor
14+
// CHECK-NOT: private constant [84 x i8] c"$s29anonymous_context_descriptors4BlahC5Inner33_4F495173994818481DD703D65EB08308LLV\00"
15+
// CHECK-MANGLED: [[INNER_MANGLED:@[0-9]+]] = private constant [84 x i8] c"$s29anonymous_context_descriptors4BlahC5Inner33_4F495173994818481DD703D65EB08308LLV\00"
16+
1217
// Anonymous descriptor
1318
// CHECK: @"$s29anonymous_context_descriptors4BlahC5Inner33{{.*}}MXX" =
19+
// CHECK-MANGLED: @"$s29anonymous_context_descriptors4BlahC5Inner33{{.*}}MXX" =
1420

1521
// Flags: anonymous (2) + generic (0x80) + unique (0x40)
1622
// CHECK-SAME: i32 194
1723

24+
// Flags: anonymous (2) + generic (0x80) + unique (0x40) + has mangled name (0x10000)
25+
// CHECK-MANGLED-SAME: i32 65730
26+
1827
// Parent
1928
// CHECK-SAME: $s29anonymous_context_descriptors4BlahCMn
29+
// CHECK-MANGLED-SAME: $s29anonymous_context_descriptors4BlahCMn
2030

2131
// # generic header
2232
// CHECK-SAME: i16 2, i16 2
2333
// CHECK-SAME: i16 4, i16 0
34+
35+
// CHECK-MANGLED-SAME: i16 2, i16 2
36+
// CHECK-MANGLED-SAME: i16 4, i16 0
37+
38+
// # mangled name
39+
// CHECK-MANGLED-SAME: [[INNER_MANGLED]]

0 commit comments

Comments
 (0)