Skip to content

Commit c2b8950

Browse files
authored
Merge pull request #77210 from slavapestov/fix-rdar135445004
Parse: Save and restore InFreestandingMacroArgument when delayed parsing
2 parents c854fa2 + 9d85221 commit c2b8950

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed

include/swift/AST/DeclContext.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,10 @@ class IterableDeclContext {
798798
/// while skipping the body of this context.
799799
unsigned HasNestedClassDeclarations : 1;
800800

801+
/// Whether we were inside a freestanding macro argument when we were parsed.
802+
/// We must restore this when delayed parsing the body.
803+
unsigned InFreestandingMacroArgument : 1;
804+
801805
template<class A, class B, class C>
802806
friend struct ::llvm::CastInfo;
803807

@@ -814,6 +818,7 @@ class IterableDeclContext {
814818
AddedParsedMembers = 0;
815819
HasOperatorDeclarations = 0;
816820
HasNestedClassDeclarations = 0;
821+
InFreestandingMacroArgument = 0;
817822
}
818823

819824
/// Determine the kind of iterable context we have.
@@ -841,6 +846,15 @@ class IterableDeclContext {
841846
HasNestedClassDeclarations = 1;
842847
}
843848

849+
bool inFreestandingMacroArgument() const {
850+
return InFreestandingMacroArgument;
851+
}
852+
853+
void setInFreestandingMacroArgument() {
854+
assert(hasUnparsedMembers());
855+
InFreestandingMacroArgument = 1;
856+
}
857+
844858
/// Retrieve the current set of members in this context.
845859
///
846860
/// NOTE: This operation is an alias of \c getCurrentMembers() that is considered

lib/Parse/ParseDecl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7031,15 +7031,17 @@ bool Parser::parseMemberDeclList(SourceLoc &LBLoc, SourceLoc &RBLoc,
70317031
llvm::SaveAndRestore<std::optional<StableHasher>> T(CurrentTokenHash,
70327032
std::nullopt);
70337033

7034-
bool HasOperatorDeclarations;
7035-
bool HasNestedClassDeclarations;
7034+
bool HasOperatorDeclarations = false;
7035+
bool HasNestedClassDeclarations = false;
70367036

70377037
if (canDelayMemberDeclParsing(HasOperatorDeclarations,
70387038
HasNestedClassDeclarations)) {
70397039
if (HasOperatorDeclarations)
70407040
IDC->setMaybeHasOperatorDeclarations();
70417041
if (HasNestedClassDeclarations)
70427042
IDC->setMaybeHasNestedClassDeclarations();
7043+
if (InFreestandingMacroArgument)
7044+
IDC->setInFreestandingMacroArgument();
70437045

70447046
if (delayParsingDeclList(LBLoc, RBLoc, IDC))
70457047
return true;

lib/Parse/ParseRequests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ ParseMembersRequest::evaluate(Evaluator &evaluator,
7575
// Lexer diagnostics have been emitted during skipping, so we disable lexer's
7676
// diagnostic engine here.
7777
Parser parser(bufferID, *sf, /*No Lexer Diags*/nullptr, nullptr, nullptr);
78+
parser.InFreestandingMacroArgument = idc->inFreestandingMacroArgument();
79+
7880
auto declsAndHash = parser.parseDeclListDelayed(idc);
7981
FingerprintAndMembers fingerprintAndMembers = {declsAndHash.second,
8082
declsAndHash.first};

test/Macros/delayed_parsing.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// REQUIRES: swift_swift_parser
2+
//
3+
// RUN: %empty-directory(%t)
4+
// RUN: %host-build-swift -swift-version 5 -parse-as-library -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath
5+
6+
// Type check testing
7+
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/delayed_parsing.swiftmodule -experimental-skip-non-inlinable-function-bodies-without-types -swift-version 5 -parse-as-library -load-plugin-library %t/%target-library-name(MacroDefinition) %s
8+
9+
@freestanding(declaration)
10+
macro freestandingWithClosure<T>(_ value: T, body: (T) -> T) = #externalMacro(module: "MacroDefinition", type: "EmptyDeclarationMacro")
11+
12+
#freestandingWithClosure(0) { (x: Int) in
13+
struct LocalStruct {
14+
func opaqueReturn() -> some Any {
15+
return 3
16+
}
17+
}
18+
19+
return x
20+
}

0 commit comments

Comments
 (0)