Skip to content

Commit 7e8ed50

Browse files
committed
ASTMangler: use specified module names from @_originalDefinedIn to mangle symbols names
When an original module name is specified via @_originalDefinedIn attribute, we need to use the original module name for all related runtime symbol names instead of the current module names. rdar://55268186
1 parent 9ff7485 commit 7e8ed50

File tree

7 files changed

+133
-36
lines changed

7 files changed

+133
-36
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,9 @@ class ASTMangler : public Mangler {
253253

254254
void appendContextOf(const ValueDecl *decl);
255255

256-
void appendContext(const DeclContext *ctx);
256+
void appendContext(const DeclContext *ctx, StringRef useModuleName);
257257

258-
void appendModule(const ModuleDecl *module);
258+
void appendModule(const ModuleDecl *module, StringRef useModuleName);
259259

260260
void appendProtocolName(const ProtocolDecl *protocol,
261261
bool allowStandardSubstitution = true);

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,10 @@ class alignas(1 << DeclAlignInBits) Decl {
897897
/// If this returns true, the decl can be safely casted to ValueDecl.
898898
bool isPotentiallyOverridable() const;
899899

900+
/// If an alternative module name is specified for this decl, e.g. using
901+
/// @_originalDefinedIn attribute, this function returns this module name.
902+
StringRef getAlternateModuleName() const;
903+
900904
/// Emit a diagnostic tied to this declaration.
901905
template<typename ...ArgTypes>
902906
InFlightDiagnostic diagnose(

lib/AST/ASTMangler.cpp

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ std::string ASTMangler::mangleIVarInitDestroyEntity(const ClassDecl *decl,
113113
bool isDestroyer,
114114
SymbolKind SKind) {
115115
beginMangling();
116-
appendContext(decl);
116+
appendContext(decl, decl->getAlternateModuleName());
117117
appendOperator(isDestroyer ? "fE" : "fe");
118118
appendSymbolKind(SKind);
119119
return finalize();
@@ -436,7 +436,7 @@ std::string ASTMangler::mangleObjCRuntimeName(const NominalTypeDecl *Nominal) {
436436
assert(isa<ProtocolDecl>(Nominal));
437437
Buffer << 'P';
438438
}
439-
appendModule(Ctx->getParentModule());
439+
appendModule(Ctx->getParentModule(), StringRef());
440440
appendIdentifier(Nominal->getName().str());
441441
if (isProto)
442442
Buffer << '_';
@@ -479,7 +479,7 @@ std::string ASTMangler::mangleObjCRuntimeName(const NominalTypeDecl *Nominal) {
479479
std::string ASTMangler::mangleTypeAsContextUSR(const NominalTypeDecl *type) {
480480
beginManglingWithoutPrefix();
481481
llvm::SaveAndRestore<bool> allowUnnamedRAII(AllowNamelessEntities, true);
482-
appendContext(type);
482+
appendContext(type, type->getAlternateModuleName());
483483
return finalize();
484484
}
485485

@@ -1561,7 +1561,7 @@ void ASTMangler::appendContextOf(const ValueDecl *decl) {
15611561
}
15621562

15631563
// Just mangle the decl's DC.
1564-
appendContext(decl->getDeclContext());
1564+
appendContext(decl->getDeclContext(), decl->getAlternateModuleName());
15651565
}
15661566

15671567
namespace {
@@ -1617,14 +1617,14 @@ static Optional<VarDecl*> findFirstVariable(PatternBindingDecl *binding) {
16171617
return None;
16181618
}
16191619

1620-
void ASTMangler::appendContext(const DeclContext *ctx) {
1620+
void ASTMangler::appendContext(const DeclContext *ctx, StringRef useModuleName) {
16211621
switch (ctx->getContextKind()) {
16221622
case DeclContextKind::Module:
1623-
return appendModule(cast<ModuleDecl>(ctx));
1623+
return appendModule(cast<ModuleDecl>(ctx), useModuleName);
16241624

16251625
case DeclContextKind::FileUnit:
16261626
assert(!isa<BuiltinUnit>(ctx) && "mangling member of builtin module!");
1627-
appendContext(ctx->getParent());
1627+
appendContext(ctx->getParent(), useModuleName);
16281628
return;
16291629

16301630
case DeclContextKind::SerializedLocal: {
@@ -1645,12 +1645,12 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
16451645
} else {
16461646
// This is incorrect in that it does not produce a /unique/ mangling,
16471647
// but it will at least produce a /valid/ mangling.
1648-
appendContext(ctx->getParent());
1648+
appendContext(ctx->getParent(), useModuleName);
16491649
}
16501650
return;
16511651
}
16521652
case LocalDeclContextKind::TopLevelCodeDecl:
1653-
return appendContext(local->getParent());
1653+
return appendContext(local->getParent(), useModuleName);
16541654
}
16551655
}
16561656

@@ -1663,7 +1663,7 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
16631663
auto decl = ExtD->getExtendedNominal();
16641664
// Recover from erroneous extension.
16651665
if (!decl)
1666-
return appendContext(ExtD->getDeclContext());
1666+
return appendContext(ExtD->getDeclContext(), useModuleName);
16671667

16681668
if (!ExtD->isEquivalentToExtendedContext()) {
16691669
// Mangle the extension if:
@@ -1679,7 +1679,7 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
16791679
// If the extension is constrained, mangle the generic signature that
16801680
// constrains it.
16811681
appendAnyGenericType(decl);
1682-
appendModule(ExtD->getParentModule());
1682+
appendModule(ExtD->getParentModule(), useModuleName);
16831683
if (sig && ExtD->isConstrainedExtension()) {
16841684
Mod = ExtD->getModuleContext();
16851685
auto nominalSig = ExtD->getSelfNominalTypeDecl()
@@ -1733,7 +1733,7 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
17331733
} else {
17341734
// This is incorrect in that it does not produce a /unique/ mangling,
17351735
// but it will at least produce a /valid/ mangling.
1736-
appendContext(ctx->getParent());
1736+
appendContext(ctx->getParent(), useModuleName);
17371737
}
17381738
return;
17391739
}
@@ -1742,26 +1742,35 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
17421742

17431743
case DeclContextKind::TopLevelCodeDecl:
17441744
// Mangle the containing module context.
1745-
return appendContext(ctx->getParent());
1745+
return appendContext(ctx->getParent(), useModuleName);
17461746
}
17471747

17481748
llvm_unreachable("bad decl context");
17491749
}
17501750

1751-
void ASTMangler::appendModule(const ModuleDecl *module) {
1751+
void ASTMangler::appendModule(const ModuleDecl *module,
1752+
StringRef useModuleName) {
17521753
assert(!module->getParent() && "cannot mangle nested modules!");
17531754

17541755
// Try the special 'swift' substitution.
1755-
if (module->isStdlibModule())
1756+
if (module->isStdlibModule()) {
1757+
assert(useModuleName.empty());
17561758
return appendOperator("s");
1759+
}
17571760

17581761
StringRef ModName = module->getName().str();
1759-
if (ModName == MANGLING_MODULE_OBJC)
1762+
if (ModName == MANGLING_MODULE_OBJC) {
1763+
assert(useModuleName.empty());
17601764
return appendOperator("So");
1761-
if (ModName == MANGLING_MODULE_CLANG_IMPORTER)
1765+
}
1766+
if (ModName == MANGLING_MODULE_CLANG_IMPORTER) {
1767+
assert(useModuleName.empty());
17621768
return appendOperator("SC");
1763-
1764-
appendIdentifier(ModName);
1769+
}
1770+
if (!useModuleName.empty())
1771+
appendIdentifier(useModuleName);
1772+
else
1773+
appendIdentifier(ModName);
17651774
}
17661775

17671776
/// Mangle the name of a protocol as a substitution candidate.
@@ -2327,7 +2336,7 @@ void ASTMangler::appendClosureComponents(Type Ty, unsigned discriminator,
23272336
assert(discriminator != AbstractClosureExpr::InvalidDiscriminator
23282337
&& "closure must be marked correctly with discriminator");
23292338

2330-
appendContext(parentContext);
2339+
appendContext(parentContext, StringRef());
23312340

23322341
if (!Ty)
23332342
Ty = ErrorType::get(parentContext->getASTContext());
@@ -2339,7 +2348,7 @@ void ASTMangler::appendClosureComponents(Type Ty, unsigned discriminator,
23392348

23402349
void ASTMangler::appendDefaultArgumentEntity(const DeclContext *func,
23412350
unsigned index) {
2342-
appendContext(func);
2351+
appendContext(func, StringRef());
23432352
appendOperator("fA", Index(index));
23442353
}
23452354

@@ -2542,8 +2551,11 @@ ASTMangler::appendProtocolConformance(const ProtocolConformance *conformance) {
25422551
needsModule = false;
25432552
}
25442553
}
2545-
if (needsModule)
2546-
appendModule(Mod);
2554+
if (needsModule) {
2555+
auto *DC = conformance->getDeclContext();
2556+
assert(DC->getAsDecl());
2557+
appendModule(Mod, DC->getAsDecl()->getAlternateModuleName());
2558+
}
25472559

25482560
contextSig =
25492561
conformingType->getAnyNominal()->getGenericSignatureOfContext();
@@ -2565,7 +2577,10 @@ void ASTMangler::appendProtocolConformanceRef(
25652577
// Same as "conformance module matches type", below.
25662578
appendOperator("HP");
25672579
} else if (isRetroactiveConformance(conformance)) {
2568-
appendModule(conformance->getDeclContext()->getParentModule());
2580+
auto *DC = conformance->getDeclContext();
2581+
assert(DC->getAsDecl());
2582+
appendModule(conformance->getDeclContext()->getParentModule(),
2583+
DC->getAsDecl()->getAlternateModuleName());
25692584
} else if (conformance->getDeclContext()->getParentModule() ==
25702585
conformance->getType()->getAnyNominal()->getParentModule()) {
25712586
appendOperator("HP");

lib/AST/Decl.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,22 @@ Result->X = SM.getLocFromExternalSource(Locs->SourceFilePath, Locs->X.Line, \
576576
return Result;
577577
}
578578

579+
StringRef Decl::getAlternateModuleName() const {
580+
if (auto *OD = Attrs.getAttribute(DeclAttrKind::DAK_OriginallyDefinedIn)) {
581+
return static_cast<const OriginallyDefinedInAttr*>(OD)->OriginalModuleName;
582+
}
583+
for (auto *DC = getDeclContext(); DC; DC = DC->getParent()) {
584+
if (auto decl = DC->getAsDecl()) {
585+
if (decl == this)
586+
continue;
587+
auto AM = decl->getAlternateModuleName();
588+
if (!AM.empty())
589+
return AM;
590+
}
591+
}
592+
return StringRef();
593+
}
594+
579595
SourceLoc Decl::getLoc(bool SerializedOK) const {
580596
#define DECL(ID, X) \
581597
static_assert(sizeof(checkSourceLocType(&ID##Decl::getLoc)) == 2, \

lib/IRGen/IRGenMangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ mangleSymbolNameForSymbolicMangling(const SymbolicMangling &mangling,
267267
= '_';
268268
Buffer << ' ';
269269
if (auto ty = referent.dyn_cast<const NominalTypeDecl*>())
270-
appendContext(ty);
270+
appendContext(ty, ty->getAlternateModuleName());
271271
else if (auto opaque = referent.dyn_cast<const OpaqueTypeDecl*>())
272272
appendOpaqueDeclName(opaque);
273273
else

lib/IRGen/IRGenMangler.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,21 +191,21 @@ class IRGenMangler : public Mangle::ASTMangler {
191191

192192
std::string mangleModuleDescriptor(const ModuleDecl *Decl) {
193193
beginMangling();
194-
appendContext(Decl);
194+
appendContext(Decl, Decl->getAlternateModuleName());
195195
appendOperator("MXM");
196196
return finalize();
197197
}
198198

199199
std::string mangleExtensionDescriptor(const ExtensionDecl *Decl) {
200200
beginMangling();
201-
appendContext(Decl);
201+
appendContext(Decl, Decl->getAlternateModuleName());
202202
appendOperator("MXE");
203203
return finalize();
204204
}
205205

206206
void appendAnonymousDescriptorName(PointerUnion<DeclContext*, VarDecl*> Name){
207207
if (auto DC = Name.dyn_cast<DeclContext *>()) {
208-
return appendContext(DC);
208+
return appendContext(DC, StringRef());
209209
}
210210
if (auto VD = Name.dyn_cast<VarDecl *>()) {
211211
return appendEntity(VD);
@@ -228,12 +228,6 @@ class IRGenMangler : public Mangle::ASTMangler {
228228
return finalize();
229229
}
230230

231-
std::string mangleContext(const DeclContext *DC) {
232-
beginMangling();
233-
appendContext(DC);
234-
return finalize();
235-
}
236-
237231
std::string mangleBareProtocol(const ProtocolDecl *Decl) {
238232
beginMangling();
239233
appendAnyGenericType(Decl);
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// RUN: %target-swift-frontend -swift-version 4 -enforce-exclusivity=checked %s -emit-ir -module-name CurrentModule -D CURRENT_MODULE | %FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-CURRENT
2+
// RUN: %target-swift-frontend -swift-version 4 -enforce-exclusivity=checked %s -emit-ir -module-name OriginalModule | %FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-ORIGINAL
3+
4+
#if CURRENT_MODULE
5+
6+
@_originallyDefinedIn(module: "OriginalModule", macOS 10.15)
7+
public struct Entity {
8+
public func addEntity(_ e: Entity) {}
9+
public func removeEntity(_ e: Entity) {}
10+
}
11+
12+
@_originallyDefinedIn(module: "OriginalModule", macOS 10.15)
13+
public protocol Movable {
14+
func MovableFuncFoo()
15+
}
16+
17+
public protocol Unmoveable {}
18+
19+
@_originallyDefinedIn(module: "OriginalModule", macOS 10.15)
20+
public class MovedClass: Movable, Unmoveable {
21+
public func MovableFuncFoo() {}
22+
}
23+
24+
public class UnmovableClass {}
25+
26+
#else
27+
28+
public struct Entity {
29+
public func addEntity(_ e: Entity) {}
30+
public func removeEntity(_ e: Entity) {}
31+
}
32+
33+
public protocol Movable {
34+
func MovableFuncFoo()
35+
}
36+
37+
public protocol Unmoveable {}
38+
39+
public class MovedClass: Movable, Unmoveable {
40+
public func MovableFuncFoo() {}
41+
}
42+
43+
public class UnmovableClass {}
44+
45+
#endif
46+
47+
48+
func entityClient() {
49+
let root = Entity()
50+
// CHECK-COMMON: call swiftcc void @"$s14OriginalModule6EntityVACycfC"()
51+
let leaf = Entity()
52+
// CHECK-COMMON: call swiftcc void @"$s14OriginalModule6EntityVACycfC"()
53+
root.addEntity(leaf)
54+
// CHECK-COMMON: call swiftcc void @"$s14OriginalModule6EntityV03addC0yyACF"()
55+
let moved = MovedClass()
56+
// CHECK-COMMON: call swiftcc %T14OriginalModule10MovedClassC* @"$s14OriginalModule10MovedClassCACycfC"
57+
moved.MovableFuncFoo()
58+
// CHECK-COMMON: call swiftcc void @"$s14OriginalModule10MovedClassC14MovableFuncFooyyF"
59+
}
60+
61+
public func unmovableClient() {
62+
let unmovable = UnmovableClass()
63+
// CHECK-CURRENT: call swiftcc %swift.metadata_response @"$s13CurrentModule14UnmovableClassCMa"(i64 0)
64+
// CHECK-ORIGINAL: call swiftcc %swift.metadata_response @"$s14OriginalModule14UnmovableClassCMa"(i64 0)
65+
}
66+
67+
entityClient()
68+
unmovableClient()

0 commit comments

Comments
 (0)