Skip to content

Commit e5a75fc

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 149fc5c commit e5a75fc

File tree

12 files changed

+112
-24
lines changed

12 files changed

+112
-24
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: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,9 @@ 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 << "\", ";
1178+
Printer << "\"" << Attr->ManglingModuleName;
1179+
if (Attr->LinkerModuleName != Attr->ManglingModuleName)
1180+
Printer << ";" << Attr->LinkerModuleName << "\", ";
11791181
Printer << platformString(Attr->Platform) << " " <<
11801182
Attr->MovedVersion.getAsString();
11811183
Printer << ")";
@@ -2235,12 +2237,39 @@ AvailableAttr *AvailableAttr::clone(ASTContext &C, bool implicit) const {
22352237
implicit ? SourceRange() : ObsoletedRange, implicit, isSPI());
22362238
}
22372239

2240+
static StringRef getManglingModuleName(StringRef OriginalModuleName) {
2241+
auto index = OriginalModuleName.find(";");
2242+
return index == StringRef::npos
2243+
? OriginalModuleName
2244+
: OriginalModuleName.slice(0, index);
2245+
}
2246+
2247+
static StringRef getLinkerModuleName(StringRef OriginalModuleName) {
2248+
auto index = OriginalModuleName.find(";");
2249+
return index == StringRef::npos
2250+
? OriginalModuleName
2251+
: OriginalModuleName.slice(index + 1, OriginalModuleName.size());
2252+
}
2253+
2254+
OriginallyDefinedInAttr::OriginallyDefinedInAttr(
2255+
SourceLoc AtLoc, SourceRange Range,
2256+
StringRef OriginalModuleName,
2257+
PlatformKind Platform,
2258+
const llvm::VersionTuple MovedVersion, bool Implicit)
2259+
: DeclAttribute(DeclAttrKind::OriginallyDefinedIn, AtLoc, Range,
2260+
Implicit),
2261+
ManglingModuleName(getManglingModuleName(OriginalModuleName)),
2262+
LinkerModuleName(getLinkerModuleName(OriginalModuleName)),
2263+
Platform(Platform),
2264+
MovedVersion(MovedVersion) {}
2265+
22382266
std::optional<OriginallyDefinedInAttr::ActiveVersion>
22392267
OriginallyDefinedInAttr::isActivePlatform(const ASTContext &ctx) const {
22402268
OriginallyDefinedInAttr::ActiveVersion Result;
22412269
Result.Platform = Platform;
22422270
Result.Version = MovedVersion;
2243-
Result.ModuleName = OriginalModuleName;
2271+
Result.ManglingModuleName = ManglingModuleName;
2272+
Result.LinkerModuleName = LinkerModuleName;
22442273
if (isPlatformActive(Platform, ctx.LangOpts, /*TargetVariant*/false)) {
22452274
return Result;
22462275
}
@@ -2260,7 +2289,7 @@ OriginallyDefinedInAttr *OriginallyDefinedInAttr::clone(ASTContext &C,
22602289
bool implicit) const {
22612290
return new (C) OriginallyDefinedInAttr(
22622291
implicit ? SourceLoc() : AtLoc, implicit ? SourceRange() : getRange(),
2263-
OriginalModuleName, Platform, MovedVersion, implicit);
2292+
ManglingModuleName, LinkerModuleName, Platform, MovedVersion, implicit);
22642293
}
22652294

22662295
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: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5974,11 +5974,20 @@ 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, blobData.size());
5983+
5984+
auto LinkerModuleNameEnd = blobData.find('\0');
5985+
assert(LinkerModuleNameEnd != StringRef::npos);
5986+
auto LinkerModuleName = blobData.slice(0, LinkerModuleNameEnd);
5987+
59805988
Attr = new (ctx) OriginallyDefinedInAttr(SourceLoc(), SourceRange(),
5981-
ModuleName,
5989+
ManglingModuleName,
5990+
LinkerModuleName,
59825991
(PlatformKind)Platform,
59835992
MovedVer,
59845993
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)