Skip to content

Commit 8b75460

Browse files
committed
AST: Extend @_originallyDefinedIn to allow specifying module name for linker directive purposes
The module name changes the symbol mangling, and also causes TBDGen to emit linker directives. To separate out these two behaviors, introduce a terrible hack. If the module name contains a semicolon (`;`), the part before the semicolon is the module name for mangling, and the part after the semicolon is the module name for linker directives. If there is no semicolon, both module names are identical, and the behavior is the same as before.
1 parent d02bb32 commit 8b75460

File tree

12 files changed

+118
-25
lines changed

12 files changed

+118
-25
lines changed

include/swift/AST/Attr.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,17 +2050,29 @@ class ProjectedValuePropertyAttr : public DeclAttribute {
20502050
class OriginallyDefinedInAttr: public DeclAttribute {
20512051
public:
20522052
OriginallyDefinedInAttr(SourceLoc AtLoc, SourceRange Range,
2053-
StringRef OriginalModuleName, PlatformKind Platform,
2053+
StringRef OriginalModuleName,
2054+
PlatformKind Platform,
2055+
const llvm::VersionTuple MovedVersion, bool Implicit);
2056+
2057+
OriginallyDefinedInAttr(SourceLoc AtLoc, SourceRange Range,
2058+
StringRef ManglingModuleName,
2059+
StringRef LinkerModuleName,
2060+
PlatformKind Platform,
20542061
const llvm::VersionTuple MovedVersion, bool Implicit)
20552062
: DeclAttribute(DeclAttrKind::OriginallyDefinedIn, AtLoc, Range,
20562063
Implicit),
2057-
OriginalModuleName(OriginalModuleName), Platform(Platform),
2064+
ManglingModuleName(ManglingModuleName),
2065+
LinkerModuleName(LinkerModuleName),
2066+
Platform(Platform),
20582067
MovedVersion(MovedVersion) {}
20592068

20602069
OriginallyDefinedInAttr *clone(ASTContext &C, bool implicit) const;
20612070

2062-
// The original module name.
2063-
const StringRef OriginalModuleName;
2071+
// The original module name for mangling.
2072+
const StringRef ManglingModuleName;
2073+
2074+
// The original module name for linker directives.
2075+
const StringRef LinkerModuleName;
20642076

20652077
/// The platform of the symbol.
20662078
const PlatformKind Platform;
@@ -2069,7 +2081,8 @@ class OriginallyDefinedInAttr: public DeclAttribute {
20692081
const llvm::VersionTuple MovedVersion;
20702082

20712083
struct ActiveVersion {
2072-
StringRef ModuleName;
2084+
StringRef ManglingModuleName;
2085+
StringRef LinkerModuleName;
20732086
PlatformKind Platform;
20742087
llvm::VersionTuple Version;
20752088
bool ForTargetVariant = false;
@@ -2085,7 +2098,8 @@ class OriginallyDefinedInAttr: public DeclAttribute {
20852098
/// Create a copy of this attribute.
20862099
OriginallyDefinedInAttr *clone(ASTContext &ctx) const {
20872100
return new (ctx) OriginallyDefinedInAttr(
2088-
AtLoc, Range, OriginalModuleName, Platform, MovedVersion, isImplicit());
2101+
AtLoc, Range, ManglingModuleName, LinkerModuleName,
2102+
Platform, MovedVersion, isImplicit());
20892103
}
20902104
};
20912105

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5207,7 +5207,8 @@ class PrintAttribute : public AttributeVisitor<PrintAttribute, void, Label>,
52075207
void visitOriginallyDefinedInAttr(OriginallyDefinedInAttr *Attr,
52085208
Label label) {
52095209
printCommon(Attr, "originally_defined_in_attr", label);
5210-
printField(Attr->OriginalModuleName, Label::always("original_module"));
5210+
printField(Attr->ManglingModuleName, Label::always("mangling_module"));
5211+
printField(Attr->LinkerModuleName, Label::always("linker_module"));
52115212
printField(Attr->Platform, Label::always("platform"));
52125213
printFieldRaw([&](auto &out) { out << Attr->MovedVersion.getAsString(); },
52135214
Label::always("moved_version"));

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5986,7 +5986,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
59865986
for (auto attr: D->getAttrs().getAttributes<OriginallyDefinedInAttr>()) {
59875987
Name = Mod->getASTContext()
59885988
.getIdentifier(const_cast<OriginallyDefinedInAttr*>(attr)
5989-
->OriginalModuleName);
5989+
->ManglingModuleName);
59905990
break;
59915991
}
59925992
}

lib/AST/Attr.cpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,8 +1175,12 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
11751175
Printer.printAttrName("@_originallyDefinedIn");
11761176
Printer << "(module: ";
11771177
auto Attr = cast<OriginallyDefinedInAttr>(this);
1178-
Printer << "\"" << Attr->OriginalModuleName << "\", ";
1179-
Printer << platformString(Attr->Platform) << " " <<
1178+
Printer << "\"" << Attr->ManglingModuleName;
1179+
ASSERT(!Attr->ManglingModuleName.empty());
1180+
ASSERT(!Attr->LinkerModuleName.empty());
1181+
if (Attr->LinkerModuleName != Attr->ManglingModuleName)
1182+
Printer << ";" << Attr->LinkerModuleName;
1183+
Printer << "\", " << platformString(Attr->Platform) << " " <<
11801184
Attr->MovedVersion.getAsString();
11811185
Printer << ")";
11821186
break;
@@ -2235,12 +2239,39 @@ AvailableAttr *AvailableAttr::clone(ASTContext &C, bool implicit) const {
22352239
implicit ? SourceRange() : ObsoletedRange, implicit, isSPI());
22362240
}
22372241

2242+
static StringRef getManglingModuleName(StringRef OriginalModuleName) {
2243+
auto index = OriginalModuleName.find(";");
2244+
return index == StringRef::npos
2245+
? OriginalModuleName
2246+
: OriginalModuleName.slice(0, index);
2247+
}
2248+
2249+
static StringRef getLinkerModuleName(StringRef OriginalModuleName) {
2250+
auto index = OriginalModuleName.find(";");
2251+
return index == StringRef::npos
2252+
? OriginalModuleName
2253+
: OriginalModuleName.slice(index + 1, OriginalModuleName.size());
2254+
}
2255+
2256+
OriginallyDefinedInAttr::OriginallyDefinedInAttr(
2257+
SourceLoc AtLoc, SourceRange Range,
2258+
StringRef OriginalModuleName,
2259+
PlatformKind Platform,
2260+
const llvm::VersionTuple MovedVersion, bool Implicit)
2261+
: DeclAttribute(DeclAttrKind::OriginallyDefinedIn, AtLoc, Range,
2262+
Implicit),
2263+
ManglingModuleName(getManglingModuleName(OriginalModuleName)),
2264+
LinkerModuleName(getLinkerModuleName(OriginalModuleName)),
2265+
Platform(Platform),
2266+
MovedVersion(MovedVersion) {}
2267+
22382268
std::optional<OriginallyDefinedInAttr::ActiveVersion>
22392269
OriginallyDefinedInAttr::isActivePlatform(const ASTContext &ctx) const {
22402270
OriginallyDefinedInAttr::ActiveVersion Result;
22412271
Result.Platform = Platform;
22422272
Result.Version = MovedVersion;
2243-
Result.ModuleName = OriginalModuleName;
2273+
Result.ManglingModuleName = ManglingModuleName;
2274+
Result.LinkerModuleName = LinkerModuleName;
22442275
if (isPlatformActive(Platform, ctx.LangOpts, /*TargetVariant*/false)) {
22452276
return Result;
22462277
}
@@ -2260,7 +2291,7 @@ OriginallyDefinedInAttr *OriginallyDefinedInAttr::clone(ASTContext &C,
22602291
bool implicit) const {
22612292
return new (C) OriginallyDefinedInAttr(
22622293
implicit ? SourceLoc() : AtLoc, implicit ? SourceRange() : getRange(),
2263-
OriginalModuleName, Platform, MovedVersion, implicit);
2294+
ManglingModuleName, LinkerModuleName, Platform, MovedVersion, implicit);
22642295
}
22652296

22662297
bool AvailableAttr::isUnconditionallyUnavailable() const {

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,7 @@ StringRef Decl::getAlternateModuleName() const {
10841084
for (auto *Att: Attrs) {
10851085
if (auto *OD = dyn_cast<OriginallyDefinedInAttr>(Att)) {
10861086
if (!OD->isInvalid() && OD->isActivePlatform(getASTContext())) {
1087-
return OD->OriginalModuleName;
1087+
return OD->ManglingModuleName;
10881088
}
10891089
}
10901090
}

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,10 +2512,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
25122512
if (auto Attribute =
25132513
ND->getAttrs().getAttribute<OriginallyDefinedInAttr>()) {
25142514
auto Identifier = IGM.getSILModule().getASTContext().getIdentifier(
2515-
Attribute->OriginalModuleName);
2515+
Attribute->ManglingModuleName);
25162516
void *Key = (void *)Identifier.get();
25172517
Scope =
2518-
getOrCreateModule(Key, TheCU, Attribute->OriginalModuleName, {});
2518+
getOrCreateModule(Key, TheCU, Attribute->ManglingModuleName, {});
25192519
} else {
25202520
Context = ND->getParent();
25212521
}

lib/IRGen/TBDGen.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,18 @@ void TBDGenVisitor::addSymbolInternal(StringRef name, EncodeKind kind,
8888

8989
static std::vector<OriginallyDefinedInAttr::ActiveVersion>
9090
getAllMovedPlatformVersions(Decl *D) {
91+
StringRef Name = D->getDeclContext()->getParentModule()->getName().str();
92+
9193
std::vector<OriginallyDefinedInAttr::ActiveVersion> Results;
9294
for (auto *attr: D->getAttrs()) {
9395
if (auto *ODA = dyn_cast<OriginallyDefinedInAttr>(attr)) {
9496
auto Active = ODA->isActivePlatform(D->getASTContext());
95-
if (Active.has_value()) {
97+
if (Active.has_value() && Active->LinkerModuleName != Name) {
9698
Results.push_back(*Active);
9799
}
98100
}
99101
}
102+
100103
return Results;
101104
}
102105

@@ -324,16 +327,16 @@ void TBDGenVisitor::addLinkerDirectiveSymbolsLdPrevious(
324327
if (*IntroVer >= Ver.Version)
325328
continue;
326329
auto PlatformNumber = getLinkerPlatformId(Ver, Ctx);
327-
auto It = previousInstallNameMap->find(Ver.ModuleName.str());
330+
auto It = previousInstallNameMap->find(Ver.LinkerModuleName.str());
328331
if (It == previousInstallNameMap->end()) {
329332
Ctx.Diags.diagnose(SourceLoc(), diag::cannot_find_install_name,
330-
Ver.ModuleName, getLinkerPlatformName(Ver, Ctx));
333+
Ver.LinkerModuleName, getLinkerPlatformName(Ver, Ctx));
331334
continue;
332335
}
333336
auto InstallName = It->second.getInstallName(PlatformNumber);
334337
if (InstallName.empty()) {
335338
Ctx.Diags.diagnose(SourceLoc(), diag::cannot_find_install_name,
336-
Ver.ModuleName, getLinkerPlatformName(Ver, Ctx));
339+
Ver.LinkerModuleName, getLinkerPlatformName(Ver, Ctx));
337340
continue;
338341
}
339342
llvm::SmallString<64> Buffer;

lib/Serialization/Deserialization.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5974,11 +5974,23 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() {
59745974
Platform);
59755975
llvm::VersionTuple MovedVer;
59765976
DECODE_VER_TUPLE(MovedVer)
5977-
auto ModuleNameEnd = blobData.find('\0');
5978-
assert(ModuleNameEnd != StringRef::npos);
5979-
auto ModuleName = blobData.slice(0, ModuleNameEnd);
5977+
5978+
auto ManglingModuleNameEnd = blobData.find('\0');
5979+
assert(ManglingModuleNameEnd != StringRef::npos);
5980+
auto ManglingModuleName = blobData.slice(0, ManglingModuleNameEnd);
5981+
5982+
blobData = blobData.slice(ManglingModuleNameEnd + 1, blobData.size());
5983+
5984+
auto LinkerModuleNameEnd = blobData.find('\0');
5985+
assert(LinkerModuleNameEnd != StringRef::npos);
5986+
auto LinkerModuleName = blobData.slice(0, LinkerModuleNameEnd);
5987+
5988+
ASSERT(!ManglingModuleName.empty());
5989+
ASSERT(!LinkerModuleName.empty());
5990+
59805991
Attr = new (ctx) OriginallyDefinedInAttr(SourceLoc(), SourceRange(),
5981-
ModuleName,
5992+
ManglingModuleName,
5993+
LinkerModuleName,
59825994
(PlatformKind)Platform,
59835995
MovedVer,
59845996
isImplicit);

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 926; // abstract conformances
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 927; // OriginallyDefinedInAttr::LinkerModuleName
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///

lib/Serialization/Serialization.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3080,7 +3080,9 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
30803080
Moved, std::optional<llvm::VersionTuple>(theAttr->MovedVersion));
30813081
auto abbrCode = S.DeclTypeAbbrCodes[OriginallyDefinedInDeclAttrLayout::Code];
30823082
llvm::SmallString<32> blob;
3083-
blob.append(theAttr->OriginalModuleName.str());
3083+
blob.append(theAttr->ManglingModuleName.str());
3084+
blob.push_back('\0');
3085+
blob.append(theAttr->LinkerModuleName.str());
30843086
blob.push_back('\0');
30853087
OriginallyDefinedInDeclAttrLayout::emitRecord(
30863088
S.Out, S.ScratchRecord, abbrCode,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"module": "Compatibility59",
4+
"install_name": "libswiftCompatibility59.dylib"
5+
}
6+
]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %target-swift-frontend -emit-ir -parse-as-library -parse-stdlib %s -module-name Swift -previous-module-installname-map-file %S/Inputs/backward_deploy_nominal.json | %FileCheck %s
2+
// RUN: %target-swift-frontend -emit-ir -parse-as-library -parse-stdlib %s -module-name Swift -previous-module-installname-map-file %S/Inputs/backward_deploy_nominal.json | %FileCheck %s --check-prefix=ALSO
3+
4+
// RUN: %target-swift-frontend -emit-ir -parse-as-library -parse-stdlib %s -module-name Compatibility59 -module-abi-name Swift | %FileCheck %s --check-prefix=CHECK-SHIM
5+
// RUN: %target-swift-frontend -emit-ir -parse-as-library -parse-stdlib %s -module-name Compatibility59 -module-abi-name Swift | %FileCheck %s --check-prefix=ALSO-SHIM
6+
7+
// REQUIRES: OS=macosx
8+
9+
// Let's just pretend...
10+
@available(macOS 13, *)
11+
@_originallyDefinedIn(module: "Swift;Compatibility59", macOS 14)
12+
public struct Fridge<Contents> {}
13+
14+
// Ultimately, both modules must export the same nominal type descriptor.
15+
// CHECK-DAG: @"$ss6FridgeVMn" =
16+
// CHECK-SHIM-DAG: @"$ss6FridgeVMn" =
17+
18+
// The home module also has linker directives.
19+
// CHECK-DAG: @"\01$ld$previous$libswiftCompatibility59.dylib$$1$13.0$14.0$_$ss6FridgeVMn$" =
20+
// ALSO-NOT: $ld$hide$
21+
22+
// The compatibility shim does not have any linker directives.
23+
// ALSO-SHIM-NOT: $ld$hide$
24+
// ALSO-SHIM-NOT: $ld$previous$

0 commit comments

Comments
 (0)