Skip to content

Commit c302e79

Browse files
committed
[ASTGen] Fix expanded macro buffer parsing and AST generation
Parse expanded buffer into dedicated syntax. Also rename `BridgedGeneratedSourceFileKindAttribute` to `BridgedGeneratedSourceFileKindAttributeFromClang` because C++ decl (i.e. `GeneratedSourceInfo::Kind::AttributeFromClang`) was renamed a while ago.
1 parent 6e4f711 commit c302e79

File tree

11 files changed

+153
-24
lines changed

11 files changed

+153
-24
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,12 @@ enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedOperatorFixity {
15111511
BridgedOperatorFixityPostfix,
15121512
};
15131513

1514+
SWIFT_NAME("BridgedMissingDecl.createParsed(_:declContext:loc:)")
1515+
BridgedMissingDecl
1516+
BridgedMissingDecl_createParsed(BridgedASTContext cContext,
1517+
BridgedDeclContext cDeclContext,
1518+
BridgedSourceLoc cLoc);
1519+
15141520
SWIFT_NAME("BridgedOperatorDecl.createParsed(_:declContext:fixity:"
15151521
"operatorKeywordLoc:name:nameLoc:colonLoc:precedenceGroupName:"
15161522
"precedenceGroupLoc:)")

include/swift/Basic/BasicBridging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedGeneratedSourceFileKind {
457457
BridgedGeneratedSourceFileKindReplacedFunctionBody,
458458
BridgedGeneratedSourceFileKindPrettyPrinted,
459459
BridgedGeneratedSourceFileKindDefaultArgument,
460-
BridgedGeneratedSourceFileKindAttribute,
460+
BridgedGeneratedSourceFileKindAttributeFromClang,
461461

462462
BridgedGeneratedSourceFileKindNone,
463463
};

include/swift/Bridging/ASTGen.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ int swift_ASTGen_emitParserDiagnostics(
5757
// Build AST nodes for the top-level entities in the syntax.
5858
void swift_ASTGen_buildTopLevelASTNodes(
5959
BridgedDiagnosticEngine diagEngine, void *_Nonnull sourceFile,
60-
BridgedDeclContext declContext, BridgedASTContext astContext,
61-
void *_Nonnull outputContext,
60+
BridgedDeclContext declContext, BridgedNullableDecl attachedDecl,
61+
BridgedASTContext astContext, void *_Nonnull outputContext,
6262
void (*_Nonnull)(BridgedASTNode, void *_Nonnull));
6363

6464
BridgedFingerprint

lib/AST/Bridging/DeclBridging.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,14 @@ BridgedMacroExpansionDecl BridgedMacroExpansionDecl_createParsed(
564564
cRightAngleLoc.unbridged(), cArgList.unbridged());
565565
}
566566

567+
BridgedMissingDecl
568+
BridgedMissingDecl_createParsed(BridgedASTContext cContext,
569+
BridgedDeclContext cDeclContext,
570+
BridgedSourceLoc cLoc) {
571+
return MissingDecl::create(cContext.unbridged(), cDeclContext.unbridged(),
572+
cLoc.unbridged());
573+
}
574+
567575
BridgedOperatorDecl BridgedOperatorDecl_createParsed(
568576
BridgedASTContext cContext, BridgedDeclContext cDeclContext,
569577
BridgedOperatorFixity cFixity, BridgedSourceLoc cOperatorKeywordLoc,

lib/ASTGen/Sources/ASTGen/ASTGen.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import ASTBridging
1414
import BasicBridging
1515
import SwiftIfConfig
1616
// Needed to use BumpPtrAllocator
17-
@_spi(BumpPtrAllocator) @_spi(RawSyntax) import SwiftSyntax
17+
@_spi(BumpPtrAllocator) @_spi(RawSyntax) @_spi(Compiler) import SwiftSyntax
1818

1919
import struct SwiftDiagnostics.Diagnostic
2020

@@ -422,6 +422,7 @@ public func buildTopLevelASTNodes(
422422
diagEngine: BridgedDiagnosticEngine,
423423
sourceFilePtr: UnsafeMutableRawPointer,
424424
dc: BridgedDeclContext,
425+
attachedDecl: BridgedNullableDecl,
425426
ctx: BridgedASTContext,
426427
outputContext: UnsafeMutableRawPointer,
427428
callback: @convention(c) (BridgedASTNode, UnsafeMutableRawPointer) -> Void
@@ -440,10 +441,28 @@ public func buildTopLevelASTNodes(
440441
for elem in visitor.generate(sourceFile: node) {
441442
callback(elem, outputContext)
442443
}
443-
case .memberBlockItemList(let node):
444-
for elem in visitor.generate(memberBlockItemList: node) {
444+
445+
case .memberBlockItemListFile(let node):
446+
for elem in visitor.generate(memberBlockItemList: node.members) {
445447
callback(.decl(elem), outputContext)
446448
}
449+
450+
case .codeBlockFile(let node):
451+
let block = visitor.generate(codeBlock: node.body)
452+
callback(.stmt(block.asStmt), outputContext)
453+
454+
case .attributeClauseFile(let node):
455+
let decl = visitor.generate(generatedAttributeClauseFile: node)
456+
callback(.decl(decl), outputContext)
457+
458+
case .accessorBlockFile(let node):
459+
// For 'accessor' macro, 'attachedDecl' must be a 'AbstractStorageDecl'.
460+
let storage = BridgedAbstractStorageDecl(raw: attachedDecl.raw!)
461+
462+
for elem in visitor.generate(accessorBlockFile: node, for: storage) {
463+
callback(.decl(elem.asDecl), outputContext)
464+
}
465+
447466
default:
448467
fatalError("invalid syntax for a source file")
449468
}

lib/ASTGen/Sources/ASTGen/Availability.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ extension ASTGenVisitor {
254254
return map.has(name: name.bridged)
255255
}
256256

257-
func generate(availabilityMacroDefinition node: AvailabilityMacroDefinitionSyntax) -> BridgedAvailabilityMacroDefinition {
257+
func generate(availabilityMacroDefinition node: AvailabilityMacroDefinitionFileSyntax) -> BridgedAvailabilityMacroDefinition {
258258

259259
let name = allocateBridgedString(node.platformVersion.platform.text)
260260
let version = self.generate(versionTuple: node.platformVersion.version)
@@ -446,7 +446,7 @@ func parseAvailabilityMacroDefinition(
446446

447447
// Parse.
448448
var parser = Parser(buffer)
449-
let parsed = AvailabilityMacroDefinitionSyntax.parse(from: &parser)
449+
let parsed = AvailabilityMacroDefinitionFileSyntax.parse(from: &parser)
450450

451451
// Emit diagnostics.
452452
let diagnostics = ParseDiagnosticsGenerator.diagnostics(for: parsed)

lib/ASTGen/Sources/ASTGen/DeclAttrs.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import BasicBridging
1515
import SwiftDiagnostics
1616
import SwiftIfConfig
1717

18-
@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) import SwiftSyntax
18+
@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) @_spi(Compiler) import SwiftSyntax
1919

2020
extension ASTGenVisitor {
2121
struct DeclAttributesResult {
@@ -2077,6 +2077,21 @@ extension ASTGenVisitor {
20772077
}
20782078
}
20792079

2080+
extension ASTGenVisitor {
2081+
func generate(generatedAttributeClauseFile node: AttributeClauseFileSyntax) -> BridgedDecl {
2082+
let attrs = self.generateDeclAttributes(node, allowStatic: false)
2083+
2084+
// Attach the attribute list to a implicit 'MissingDecl' as the placeholder.
2085+
let decl = BridgedMissingDecl.createParsed(
2086+
self.ctx,
2087+
declContext: self.declContext,
2088+
loc: self.generateSourceLoc(node.endOfFileToken)
2089+
).asDecl
2090+
decl.attachParsedAttrs(attrs.attributes)
2091+
return decl
2092+
}
2093+
}
2094+
20802095
/// Simpler helper for handling attribute arguments in "generate" functions.
20812096
struct AttrArgumentState<Flag: RawRepresentable, SeenStorage: FixedWidthInteger> where Flag.RawValue: FixedWidthInteger {
20822097
private var seen: SeenStorage = 0

lib/ASTGen/Sources/ASTGen/Decls.swift

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import ASTBridging
1414
import BasicBridging
1515
import SwiftDiagnostics
16-
@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) import SwiftSyntax
16+
@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) @_spi(Compiler) import SwiftSyntax
1717

1818
// MARK: - TypeDecl
1919

@@ -50,8 +50,8 @@ extension ASTGenVisitor {
5050
return self.generate(macroDecl: node)?.asDecl
5151
case .macroExpansionDecl(let node):
5252
return self.generate(macroExpansionDecl: node).asDecl
53-
case .missingDecl:
54-
fatalError("unimplemented")
53+
case .missingDecl(let node):
54+
return self.generate(missingDecl: node)?.asDecl
5555
case .operatorDecl(let node):
5656
return self.generate(operatorDecl: node)?.asDecl
5757
case .poundSourceLocation:
@@ -640,6 +640,24 @@ extension ASTGenVisitor {
640640
}
641641
return subscriptDecl
642642
}
643+
644+
func generate(accessorBlockFile node: AccessorBlockFileSyntax, for storage: BridgedAbstractStorageDecl) -> [BridgedAccessorDecl] {
645+
var accessors: [BridgedAccessorDecl] = []
646+
for elem in node.accessors {
647+
if let accessor = self.generate(accessorDecl: elem, for: storage) {
648+
accessors.append(accessor)
649+
}
650+
}
651+
// NOTE: Do not set brace locations even if exist. AST doesn't expect that.
652+
let record = BridgedAccessorRecord(
653+
lBraceLoc: nil,
654+
accessors: accessors.lazy.bridgedArray(in: self),
655+
rBraceLoc: nil
656+
)
657+
// FIXME: The caller should setAccessors() after ASTGen just return parsed accessors.
658+
storage.setAccessors(record)
659+
return accessors
660+
}
643661
}
644662

645663
// MARK: - AbstractFunctionDecl
@@ -780,6 +798,14 @@ extension ASTGenVisitor {
780798

781799
return decl
782800
}
801+
802+
func generate(missingDecl node: MissingDeclSyntax) -> BridgedMissingDecl? {
803+
// Generate the attributes for diagnostics, but discard the result.
804+
// There's no use of the attributes in AST at this point.
805+
// FIXME: We probably should place 'swift::MissingDecl' with the attributes attached in AST for better IDE experience in custom attributes.
806+
_ = self.generateDeclAttributes(node, allowStatic: true)
807+
return nil
808+
}
783809
}
784810

785811
extension ASTGenVisitor {

lib/ASTGen/Sources/ASTGen/SourceFile.swift

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,24 +131,31 @@ public func parseSourceFile(
131131
.codeItemMacroExpansion,
132132
.peerMacroExpansion:
133133
if let dc, dc.isTypeContext {
134-
parsed = Syntax(MemberBlockItemListSyntax.parse(from: &parser))
134+
parsed = Syntax(MemberBlockItemListFileSyntax.parse(from: &parser))
135135
} else {
136136
parsed = Syntax(SourceFileSyntax.parse(from: &parser))
137137
}
138138

139139
case .memberMacroExpansion:
140-
parsed = Syntax(MemberBlockItemListSyntax.parse(from: &parser))
140+
parsed = Syntax(MemberBlockItemListFileSyntax.parse(from: &parser))
141141

142142
case .accessorMacroExpansion:
143-
// FIXME: Implement specialized parsing.
144-
parsed = Syntax(SourceFileSyntax.parse(from: &parser))
145-
case .memberAttributeMacroExpansion,
146-
.attribute:
147-
// FIXME: Implement specialized parsing.
148-
parsed = Syntax(SourceFileSyntax.parse(from: &parser))
143+
parsed = Syntax(AccessorBlockFileSyntax.parse(from: &parser))
144+
145+
case .memberAttributeMacroExpansion:
146+
var attrs = AttributeClauseFileSyntax.parse(from: &parser)
147+
if !attrs.modifiers.isEmpty {
148+
// 'memberAttribute' macro doesn't allow modifiers. Move to "unexpected" if any.
149+
attrs.unexpectedBetweenAttributesAndModifiers = [Syntax(attrs.modifiers)]
150+
attrs.modifiers = []
151+
}
152+
parsed = Syntax(attrs)
153+
154+
case .attributeFromClang:
155+
parsed = Syntax(AttributeClauseFileSyntax.parse(from: &parser))
156+
149157
case .bodyMacroExpansion:
150-
// FIXME: Implement specialized parsing.
151-
parsed = Syntax(SourceFileSyntax.parse(from: &parser))
158+
parsed = Syntax(CodeBlockFileSyntax.parse(from: &parser))
152159
}
153160

154161
let exportedPtr = UnsafeMutablePointer<ExportedSourceFile>.allocate(capacity: 1)

lib/Parse/ParseRequests.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ getBridgedGeneratedSourceFileKind(const GeneratedSourceInfo *genInfo) {
248248
case GeneratedSourceInfo::Kind::DefaultArgument:
249249
return BridgedGeneratedSourceFileKindDefaultArgument;
250250
case GeneratedSourceInfo::AttributeFromClang:
251-
return BridgedGeneratedSourceFileKindAttribute;
251+
return BridgedGeneratedSourceFileKindAttributeFromClang;
252252
}
253253
}
254254

@@ -353,6 +353,11 @@ SourceFileParsingResult parseSourceFileViaASTGen(SourceFile &SF) {
353353
if (genInfo && genInfo->declContext) {
354354
declContext = genInfo->declContext;
355355
}
356+
Decl *attachedDecl = nullptr;
357+
if (genInfo && genInfo->astNode) {
358+
attachedDecl =
359+
ASTNode::getFromOpaqueValue(genInfo->astNode).dyn_cast<Decl *>();
360+
}
356361

357362
// Parse the file.
358363
auto *exportedSourceFile = SF.getExportedSourceFile();
@@ -385,7 +390,7 @@ SourceFileParsingResult parseSourceFileViaASTGen(SourceFile &SF) {
385390
// Generate AST nodes.
386391
SmallVector<ASTNode, 128> items;
387392
swift_ASTGen_buildTopLevelASTNodes(
388-
&Diags, exportedSourceFile, declContext, Ctx,
393+
&Diags, exportedSourceFile, declContext, attachedDecl, Ctx,
389394
static_cast<SmallVectorImpl<ASTNode> *>(&items),
390395
appendToVector<BridgedASTNode, ASTNode>);
391396

test/ASTGen/macros.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,46 @@ class D: C { }
6767

6868
@DefaultInit
6969
struct E { }
70+
71+
72+
@attached(memberAttribute)
73+
@attached(member, names: named(_storage))
74+
macro myTypeWrapper() = #externalMacro(module: "MacroDefinition", type: "TypeWrapperMacro")
75+
@attached(accessor)
76+
macro accessViaStorage() = #externalMacro(module: "MacroDefinition", type: "AccessViaStorageMacro")
77+
78+
struct _Storage {
79+
var x: Int = 0 {
80+
willSet { print("setting \(newValue)") }
81+
}
82+
var y: Int = 0 {
83+
willSet { print("setting \(newValue)") }
84+
}
85+
}
86+
87+
@myTypeWrapper
88+
struct S {
89+
var x: Int
90+
var y: Int
91+
}
92+
93+
94+
@attached(body)
95+
macro Remote() = #externalMacro(module: "MacroDefinition", type: "RemoteBodyMacro")
96+
97+
protocol ConjureRemoteValue {
98+
static func conjureValue() -> Self
99+
}
100+
extension String: ConjureRemoteValue {
101+
static func conjureValue() -> String { "" }
102+
}
103+
func remoteCall<Result: ConjureRemoteValue>(function: String, arguments: [String: Any]) async throws -> Result {
104+
let printedArgs = arguments.keys.sorted().map { key in
105+
"\(key): \(arguments[key]!)"
106+
}.joined(separator: ", ")
107+
print("Remote call \(function)(\(printedArgs))")
108+
return Result.conjureValue()
109+
}
110+
111+
@Remote
112+
func f(a: Int, b: String) async throws -> String

0 commit comments

Comments
 (0)