Skip to content

Commit d33f2c4

Browse files
committed
[IRGen] Fetch the correct IGM for synthesized files
rdar://128870792 Synthesized files are treated as not having a parent source file, but that can cause issues for macro code. The declarations will have the source file of their use site declared as parent source file, which means they should be emitted into the same IGM. If we don't use the correct IGM, we can get inconsistencies when referencing the generated code, which will cause linking issues.
1 parent 11696cd commit d33f2c4

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

lib/IRGen/IRGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1440,7 +1440,7 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
14401440
}
14411441

14421442
if (auto *synthSFU = File->getSynthesizedFile()) {
1443-
CurrentIGMPtr IGM = irgen.getGenModule(synthSFU);
1443+
CurrentIGMPtr IGM = irgen.getGenModule(&synthSFU->getFileUnit());
14441444
IGM->emitSynthesizedFileUnit(*synthSFU);
14451445
}
14461446
} else {

test/Macros/extension_emission.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// REQUIRES: swift_swift_parser
2+
3+
// This test ensures that code generated by extension macros gets emitted into the correct LLVM module
4+
// rdar://128870792
5+
6+
// RUN: %empty-directory(%t)
7+
// RUN: split-file %s %t
8+
9+
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -parse-as-library -module-name=MacroDefinition %t/macro.swift -g -no-toolchain-stdlib-rpath
10+
11+
// RUN: %target-swift-frontend -num-threads 1 -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -enable-library-evolution %t/b.swift %t/a.swift -emit-ir -o %t/b.ll -o %t/a.ll
12+
13+
// RUN: %FileCheck -check-prefix=CHECK-A %s < %t/a.ll
14+
15+
// RUN: %FileCheck -check-prefix=CHECK-B %s < %t/b.ll
16+
17+
//--- macro.swift
18+
19+
import SwiftSyntax
20+
import SwiftSyntaxBuilder
21+
@_spi(ExperimentalLanguageFeature) import SwiftSyntaxMacros
22+
23+
public struct SomeExtensionMacro: ExtensionMacro {
24+
public static func expansion(of node: AttributeSyntax, attachedTo declaration: some DeclGroupSyntax, providingExtensionsOf type: some TypeSyntaxProtocol, conformingTo protocols: [TypeSyntax], in context: some MacroExpansionContext) throws -> [ExtensionDeclSyntax] {
25+
let decl: DeclSyntax =
26+
"""
27+
extension \(type.trimmed) {
28+
struct Storage {
29+
let x: Int
30+
}
31+
32+
func alsoUseStorage(_ x: Storage?) {
33+
print(type(of: x))
34+
}
35+
}
36+
"""
37+
guard let extensionDecl = decl.as(ExtensionDeclSyntax.self) else {
38+
return []
39+
}
40+
41+
return [extensionDecl]
42+
}
43+
}
44+
45+
//--- a.swift
46+
47+
@attached(
48+
extension,
49+
names: named(Storage), named(alsoUseStorage)
50+
)
51+
macro someExtension() = #externalMacro(module: "MacroDefinition", type: "SomeExtensionMacro")
52+
53+
// CHECK-A: @"$s1b1SV7StorageVMn" = {{.*}}constant
54+
@someExtension
55+
struct S {}
56+
57+
//--- b.swift
58+
59+
// This file needs no content, it just needs to exist
60+
61+
// CHECK-B-NOT: @"$s1b1SV7StorageVMn"

0 commit comments

Comments
 (0)