Skip to content

Commit 0155b41

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 37d867f commit 0155b41

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
@@ -5214,7 +5214,8 @@ class PrintAttribute : public AttributeVisitor<PrintAttribute, void, Label>,
52145214
void visitOriginallyDefinedInAttr(OriginallyDefinedInAttr *Attr,
52155215
Label label) {
52165216
printCommon(Attr, "originally_defined_in_attr", label);
5217-
printField(Attr->OriginalModuleName, Label::always("original_module"));
5217+
printField(Attr->ManglingModuleName, Label::always("mangling_module"));
5218+
printField(Attr->LinkerModuleName, Label::always("linker_module"));
52185219
printField(Attr->Platform, Label::always("platform"));
52195220
printFieldRaw([&](auto &out) { out << Attr->MovedVersion.getAsString(); },
52205221
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
@@ -1101,7 +1101,7 @@ StringRef Decl::getAlternateModuleName() const {
11011101
for (auto *Att: Attrs) {
11021102
if (auto *OD = dyn_cast<OriginallyDefinedInAttr>(Att)) {
11031103
if (!OD->isInvalid() && OD->isActivePlatform(getASTContext())) {
1104-
return OD->OriginalModuleName;
1104+
return OD->ManglingModuleName;
11051105
}
11061106
}
11071107
}

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2541,10 +2541,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
25412541
if (auto Attribute =
25422542
ND->getAttrs().getAttribute<OriginallyDefinedInAttr>()) {
25432543
auto Identifier = IGM.getSILModule().getASTContext().getIdentifier(
2544-
Attribute->OriginalModuleName);
2544+
Attribute->ManglingModuleName);
25452545
void *Key = (void *)Identifier.get();
25462546
Scope =
2547-
getOrCreateModule(Key, TheCU, Attribute->OriginalModuleName, {});
2547+
getOrCreateModule(Key, TheCU, Attribute->ManglingModuleName, {});
25482548
} else {
25492549
Context = ND->getParent();
25502550
}

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
@@ -6043,11 +6043,23 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() {
60436043
Platform);
60446044
llvm::VersionTuple MovedVer;
60456045
DECODE_VER_TUPLE(MovedVer)
6046-
auto ModuleNameEnd = blobData.find('\0');
6047-
assert(ModuleNameEnd != StringRef::npos);
6048-
auto ModuleName = blobData.slice(0, ModuleNameEnd);
6046+
6047+
auto ManglingModuleNameEnd = blobData.find('\0');
6048+
assert(ManglingModuleNameEnd != StringRef::npos);
6049+
auto ManglingModuleName = blobData.slice(0, ManglingModuleNameEnd);
6050+
6051+
blobData = blobData.slice(ManglingModuleNameEnd + 1, blobData.size());
6052+
6053+
auto LinkerModuleNameEnd = blobData.find('\0');
6054+
assert(LinkerModuleNameEnd != StringRef::npos);
6055+
auto LinkerModuleName = blobData.slice(0, LinkerModuleNameEnd);
6056+
6057+
ASSERT(!ManglingModuleName.empty());
6058+
ASSERT(!LinkerModuleName.empty());
6059+
60496060
Attr = new (ctx) OriginallyDefinedInAttr(SourceLoc(), SourceRange(),
6050-
ModuleName,
6061+
ManglingModuleName,
6062+
LinkerModuleName,
60516063
(PlatformKind)Platform,
60526064
MovedVer,
60536065
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 = 928; // abstract conforming type
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 929; // 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
@@ -3094,7 +3094,9 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
30943094
Moved, std::optional<llvm::VersionTuple>(theAttr->MovedVersion));
30953095
auto abbrCode = S.DeclTypeAbbrCodes[OriginallyDefinedInDeclAttrLayout::Code];
30963096
llvm::SmallString<32> blob;
3097-
blob.append(theAttr->OriginalModuleName.str());
3097+
blob.append(theAttr->ManglingModuleName.str());
3098+
blob.push_back('\0');
3099+
blob.append(theAttr->LinkerModuleName.str());
30983100
blob.push_back('\0');
30993101
OriginallyDefinedInDeclAttrLayout::emitRecord(
31003102
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)