Skip to content

Commit d6b6dc4

Browse files
authored
Merge pull request #62606 from DougGregor/astgen-round-trip
[New parser] Move round-trip checking logic into ASTGen
2 parents d6aa544 + 7dd6af7 commit d6b6dc4

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,5 +2019,8 @@ ERROR(macro_expansion_expr_expected_macro_identifier,none,
20192019
ERROR(macro_expansion_decl_expected_macro_identifier,none,
20202020
"expected a macro identifier for a pound literal declaration", ())
20212021

2022+
ERROR(parser_round_trip_error,none,
2023+
"source file did not round-trip through the Swift Swift parser", ())
2024+
20222025
#define UNDEFINE_DIAGNOSTIC_MACROS
20232026
#include "DefineDiagnosticMacros.h"

lib/ASTGen/Sources/ASTGen/SourceFile.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,14 @@ public func destroySourceFile(
4848
sourceFile.deallocate()
4949
}
5050
}
51+
52+
/// Check for whether the given source file round-trips
53+
@_cdecl("swift_ASTGen_roundTripCheck")
54+
public func roundTripCheck(
55+
sourceFilePtr: UnsafeMutablePointer<UInt8>
56+
) -> CInt {
57+
sourceFilePtr.withMemoryRebound(to: ExportedSourceFile.self, capacity: 1) { sourceFile in
58+
let sf = sourceFile.pointee
59+
return sf.syntax.syntaxTextBytes.elementsEqual(sf.buffer) ? 0 : 1
60+
}
61+
}

lib/Parse/ParseDecl.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ extern "C" void *swift_ASTGen_parseSourceFile(const char *buffer,
178178
/// Destroy a source file parsed with swift_ASTGen_parseSourceFile.
179179
extern "C" void swift_ASTGen_destroySourceFile(void *sourceFile);
180180

181+
/// Check whether the given source file round-trips correctly. Returns 0 if
182+
/// round-trip succeeded, non-zero otherwise.
183+
extern "C" int swift_ASTGen_roundTripCheck(void *sourceFile);
184+
185+
181186
// Build AST nodes for the top-level entities in the syntax.
182187
extern "C" void swift_ASTGen_buildTopLevelASTNodes(void *sourceFile,
183188
void *declContext,
@@ -197,6 +202,7 @@ void Parser::parseTopLevelItems(SmallVectorImpl<ASTNode> &items) {
197202
#if SWIFT_SWIFT_PARSER
198203
if ((Context.LangOpts.hasFeature(Feature::Macros) ||
199204
Context.LangOpts.hasFeature(Feature::BuiltinMacros) ||
205+
Context.LangOpts.hasFeature(Feature::ParserRoundTrip) ||
200206
Context.LangOpts.hasFeature(Feature::ParserASTGen)) &&
201207
!SourceMgr.hasIDEInspectionTargetBuffer() &&
202208
SF.Kind != SourceFileKind::SIL) {
@@ -273,6 +279,20 @@ void Parser::parseTopLevelItems(SmallVectorImpl<ASTNode> &items) {
273279
consumeToken();
274280
}
275281
}
282+
283+
#if SWIFT_SWIFT_PARSER
284+
// Perform round-trip checking.
285+
if (Context.LangOpts.hasFeature(Feature::ParserRoundTrip) &&
286+
SF.exportedSourceFile &&
287+
!L->lexingCutOffOffset() &&
288+
swift_ASTGen_roundTripCheck(SF.exportedSourceFile)) {
289+
SourceLoc loc;
290+
if (auto bufferID = SF.getBufferID()) {
291+
loc = Context.SourceMgr.getLocForBufferStart(*bufferID);
292+
}
293+
diagnose(loc, diag::parser_round_trip_error);
294+
}
295+
#endif
276296
}
277297

278298
bool Parser::parseTopLevelSIL() {

lib/Parse/ParseRequests.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,12 @@ SourceFileParsingResult ParseSourceFileRequest::evaluate(Evaluator &evaluator,
176176
tokensRef = ctx.AllocateCopy(*tokens);
177177

178178
#if SWIFT_SWIFT_PARSER
179-
if ((ctx.LangOpts.hasFeature(Feature::ParserRoundTrip) ||
180-
ctx.LangOpts.hasFeature(Feature::ParserValidation)) &&
179+
if (ctx.LangOpts.hasFeature(Feature::ParserValidation) &&
181180
ctx.SourceMgr.getIDEInspectionTargetBufferID() != bufferID &&
182181
SF->Kind != SourceFileKind::SIL) {
183182
auto bufferRange = ctx.SourceMgr.getRangeForBuffer(*bufferID);
184183
unsigned int flags = 0;
185184

186-
if (ctx.LangOpts.hasFeature(Feature::ParserRoundTrip) &&
187-
!parser.L->lexingCutOffOffset()) {
188-
flags |= SCC_RoundTrip;
189-
}
190-
191185
if (!ctx.Diags.hadAnyError() &&
192186
ctx.LangOpts.hasFeature(Feature::ParserValidation))
193187
flags |= SCC_ParseDiagnostics;

0 commit comments

Comments
 (0)