Skip to content

Commit 1390576

Browse files
authored
Merge pull request swiftlang#28528 from nkcsgexi/use-alternate-module-name
ASTMangler: use specified module names from @_originalDefinedIn to mangle symbols names
2 parents 835c701 + 7e8ed50 commit 1390576

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
@@ -254,9 +254,9 @@ class ASTMangler : public Mangler {
254254

255255
void appendContextOf(const ValueDecl *decl);
256256

257-
void appendContext(const DeclContext *ctx);
257+
void appendContext(const DeclContext *ctx, StringRef useModuleName);
258258

259-
void appendModule(const ModuleDecl *module);
259+
void appendModule(const ModuleDecl *module, StringRef useModuleName);
260260

261261
void appendProtocolName(const ProtocolDecl *protocol,
262262
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

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

15641564
// Just mangle the decl's DC.
1565-
appendContext(decl->getDeclContext());
1565+
appendContext(decl->getDeclContext(), decl->getAlternateModuleName());
15661566
}
15671567

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

1621-
void ASTMangler::appendContext(const DeclContext *ctx) {
1621+
void ASTMangler::appendContext(const DeclContext *ctx, StringRef useModuleName) {
16221622
switch (ctx->getContextKind()) {
16231623
case DeclContextKind::Module:
1624-
return appendModule(cast<ModuleDecl>(ctx));
1624+
return appendModule(cast<ModuleDecl>(ctx), useModuleName);
16251625

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

16311631
case DeclContextKind::SerializedLocal: {
@@ -1646,12 +1646,12 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
16461646
} else {
16471647
// This is incorrect in that it does not produce a /unique/ mangling,
16481648
// but it will at least produce a /valid/ mangling.
1649-
appendContext(ctx->getParent());
1649+
appendContext(ctx->getParent(), useModuleName);
16501650
}
16511651
return;
16521652
}
16531653
case LocalDeclContextKind::TopLevelCodeDecl:
1654-
return appendContext(local->getParent());
1654+
return appendContext(local->getParent(), useModuleName);
16551655
}
16561656
}
16571657

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

16691669
if (!ExtD->isEquivalentToExtendedContext()) {
16701670
// Mangle the extension if:
@@ -1680,7 +1680,7 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
16801680
// If the extension is constrained, mangle the generic signature that
16811681
// constrains it.
16821682
appendAnyGenericType(decl);
1683-
appendModule(ExtD->getParentModule());
1683+
appendModule(ExtD->getParentModule(), useModuleName);
16841684
if (sig && ExtD->isConstrainedExtension()) {
16851685
Mod = ExtD->getModuleContext();
16861686
auto nominalSig = ExtD->getSelfNominalTypeDecl()
@@ -1734,7 +1734,7 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
17341734
} else {
17351735
// This is incorrect in that it does not produce a /unique/ mangling,
17361736
// but it will at least produce a /valid/ mangling.
1737-
appendContext(ctx->getParent());
1737+
appendContext(ctx->getParent(), useModuleName);
17381738
}
17391739
return;
17401740
}
@@ -1743,26 +1743,35 @@ void ASTMangler::appendContext(const DeclContext *ctx) {
17431743

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

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

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

17551756
// Try the special 'swift' substitution.
1756-
if (module->isStdlibModule())
1757+
if (module->isStdlibModule()) {
1758+
assert(useModuleName.empty());
17571759
return appendOperator("s");
1760+
}
17581761

17591762
StringRef ModName = module->getName().str();
1760-
if (ModName == MANGLING_MODULE_OBJC)
1763+
if (ModName == MANGLING_MODULE_OBJC) {
1764+
assert(useModuleName.empty());
17611765
return appendOperator("So");
1762-
if (ModName == MANGLING_MODULE_CLANG_IMPORTER)
1766+
}
1767+
if (ModName == MANGLING_MODULE_CLANG_IMPORTER) {
1768+
assert(useModuleName.empty());
17631769
return appendOperator("SC");
1764-
1765-
appendIdentifier(ModName);
1770+
}
1771+
if (!useModuleName.empty())
1772+
appendIdentifier(useModuleName);
1773+
else
1774+
appendIdentifier(ModName);
17661775
}
17671776

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

2331-
appendContext(parentContext);
2340+
appendContext(parentContext, StringRef());
23322341

23332342
if (!Ty)
23342343
Ty = ErrorType::get(parentContext->getASTContext());
@@ -2340,7 +2349,7 @@ void ASTMangler::appendClosureComponents(Type Ty, unsigned discriminator,
23402349

23412350
void ASTMangler::appendDefaultArgumentEntity(const DeclContext *func,
23422351
unsigned index) {
2343-
appendContext(func);
2352+
appendContext(func, StringRef());
23442353
appendOperator("fA", Index(index));
23452354
}
23462355

@@ -2543,8 +2552,11 @@ ASTMangler::appendProtocolConformance(const ProtocolConformance *conformance) {
25432552
needsModule = false;
25442553
}
25452554
}
2546-
if (needsModule)
2547-
appendModule(Mod);
2555+
if (needsModule) {
2556+
auto *DC = conformance->getDeclContext();
2557+
assert(DC->getAsDecl());
2558+
appendModule(Mod, DC->getAsDecl()->getAlternateModuleName());
2559+
}
25482560

25492561
contextSig =
25502562
conformingType->getAnyNominal()->getGenericSignatureOfContext();
@@ -2566,7 +2578,10 @@ void ASTMangler::appendProtocolConformanceRef(
25662578
// Same as "conformance module matches type", below.
25672579
appendOperator("HP");
25682580
} else if (isRetroactiveConformance(conformance)) {
2569-
appendModule(conformance->getDeclContext()->getParentModule());
2581+
auto *DC = conformance->getDeclContext();
2582+
assert(DC->getAsDecl());
2583+
appendModule(conformance->getDeclContext()->getParentModule(),
2584+
DC->getAsDecl()->getAlternateModuleName());
25702585
} else if (conformance->getDeclContext()->getParentModule() ==
25712586
conformance->getType()->getAnyNominal()->getParentModule()) {
25722587
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)