Skip to content

Commit 8dd64be

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/. (cherry picked from commit 0c88b88)
1 parent dfdb6b4 commit 8dd64be

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
@@ -2807,18 +2807,67 @@ struct TargetExtensionContextDescriptor final
28072807

28082808
using ExtensionContextDescriptor = TargetExtensionContextDescriptor<InProcess>;
28092809

2810+
template<typename Runtime>
2811+
struct TargetMangledContextName {
2812+
/// The mangled name of the context.
2813+
TargetRelativeDirectPointer<Runtime, const char, /*nullable*/ false> name;
2814+
};
2815+
28102816
template<typename Runtime>
28112817
struct TargetAnonymousContextDescriptor final
28122818
: TargetContextDescriptor<Runtime>,
2813-
TrailingGenericContextObjects<TargetAnonymousContextDescriptor<Runtime>>
2819+
TrailingGenericContextObjects<TargetAnonymousContextDescriptor<Runtime>,
2820+
TargetGenericContextDescriptorHeader,
2821+
TargetMangledContextName<Runtime>>
28142822
{
28152823
private:
28162824
using TrailingGenericContextObjects
2817-
= TrailingGenericContextObjects<TargetAnonymousContextDescriptor<Runtime>>;
2825+
= TrailingGenericContextObjects<TargetAnonymousContextDescriptor<Runtime>,
2826+
TargetGenericContextDescriptorHeader,
2827+
TargetMangledContextName<Runtime>>;
2828+
using TrailingObjects =
2829+
typename TrailingGenericContextObjects::TrailingObjects;
2830+
friend TrailingObjects;
28182831

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

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

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
@@ -1041,6 +1041,9 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
10411041
Opts.EnableReflectionNames = false;
10421042
}
10431043

1044+
if (Args.hasArg(OPT_enable_anonymous_context_mangled_names))
1045+
Opts.EnableAnonymousContextMangledNames = true;
1046+
10441047
if (Args.hasArg(OPT_disable_reflection_names)) {
10451048
Opts.EnableReflectionNames = false;
10461049
}

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)