Skip to content

Commit 5f49ba1

Browse files
authored
Merge pull request #60888 from DougGregor/round-trip-new-swift-parser
Optional support for round-trip testing the new Swift parser.
2 parents 8674724 + 9e38714 commit 5f49ba1

File tree

8 files changed

+104
-2
lines changed

8 files changed

+104
-2
lines changed

CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,23 @@ if(XCODE)
868868
set(SWIFT_SDKS "OSX")
869869
endif()
870870

871+
# When we have the early SwiftSyntax build, we can include its parser.
872+
if(SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR)
873+
# An option that specifies how the SwiftSyntax-based Swift parser is
874+
# integrated.
875+
option(SWIFT_SWIFT_PARSER_MODE [=[
876+
How to use the SwiftSyntax-based Swift parser. Possible values are
877+
OFF: do not use this parser at all
878+
ROUNDTRIP: ensure that the SwiftSyntax-based Swift parser round-trips
879+
]=] OFF)
880+
881+
if(SWIFT_SWIFT_PARSER_MODE)
882+
set(SWIFT_SWIFT_PARSER TRUE)
883+
include(${SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR}/cmake/SwiftSyntaxTargets.cmake)
884+
endif()
885+
endif()
886+
887+
871888
# FIXME: the parameters we specify in SWIFT_SDKS are lacking architecture specifics,
872889
# so we need to hard-code it. For example, the SDK for Android is just 'ANDROID',
873890
# and we have to specify SWIFT_SDK_ANDROID_ARCHITECTURES separately.

cmake/modules/AddSwift.cmake

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ function(_add_swift_runtime_link_flags target relpath_to_lib_dir bootstrapping)
504504
505505
# Workaround to make lldb happy: we have to explicitly add all swift compiler modules
506506
# to the linker command line.
507-
set(swift_ast_path_flags "-Wl")
507+
set(swift_ast_path_flags " -Wl")
508508
get_property(modules GLOBAL PROPERTY swift_compiler_modules)
509509
foreach(module ${modules})
510510
get_target_property(module_file "SwiftModule${module}" "module_file")
@@ -608,6 +608,11 @@ function(add_swift_host_library name)
608608
609609
translate_flags(ASHL "${options}")
610610
611+
# Once the new Swift parser is linked, everything has Swift modules.
612+
if (SWIFT_SWIFT_PARSER AND ASHL_SHARED)
613+
set(ASHL_HAS_SWIFT_MODULES ON)
614+
endif()
615+
611616
if(NOT ASHL_SHARED AND NOT ASHL_STATIC AND NOT ASHL_OBJECT)
612617
message(FATAL_ERROR "One of SHARED/STATIC/OBJECT must be specified")
613618
endif()
@@ -834,6 +839,11 @@ function(add_swift_host_tool executable)
834839
JOB_POOL_LINK swift_link_job_pool)
835840
endif()
836841
842+
# Once the new Swift parser is linked in, every host tool has Swift modules.
843+
if (SWIFT_SWIFT_PARSER)
844+
set(ASHT_HAS_SWIFT_MODULES ON)
845+
endif()
846+
837847
if (ASHT_HAS_SWIFT_MODULES)
838848
_add_swift_runtime_link_flags(${executable} "../lib" "${ASHT_BOOTSTRAPPING}")
839849
endif()

cmake/modules/AddSwiftUnittests.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,9 @@ function(add_swift_unittest test_dirname)
7878
LINK_FLAGS " -fsanitize=thread")
7979
endif()
8080
endif()
81+
82+
if (SWIFT_SWIFT_PARSER)
83+
_add_swift_runtime_link_flags(${test_dirname} "../../lib" "")
84+
endif()
8185
endfunction()
8286

lib/Parse/CMakeLists.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,34 @@ target_link_libraries(swiftParse PRIVATE
3535
swiftSyntaxParse
3636
)
3737

38+
if (SWIFT_SWIFT_PARSER)
39+
# Link against the SwiftSyntax parser and libraries it depends on. The actual
40+
# formulation of this is a hack to work around a CMake bug in Ninja file
41+
# generation that results in multiple Ninja targets producing the same file in
42+
# a downstream SourceKit target. This should be expressed as:
43+
#
44+
# target_link_libraries(swiftParse
45+
# PRIVATE
46+
# SwiftSyntax::SwiftParser
47+
# )
48+
target_link_libraries(swiftParse
49+
PRIVATE
50+
$<TARGET_OBJECTS:SwiftSyntax::SwiftParser>
51+
$<TARGET_OBJECTS:SwiftSyntax::SwiftDiagnostics>
52+
$<TARGET_OBJECTS:SwiftSyntax::SwiftSyntax>
53+
)
54+
55+
target_include_directories(swiftParse
56+
PRIVATE
57+
${CMAKE_CURRENT_SOURCE_DIR}/../../../swift-syntax/Sources/SwiftParser
58+
)
59+
60+
target_compile_definitions(swiftParse
61+
PRIVATE
62+
SWIFT_SWIFT_PARSER_ROUNDTRIP
63+
)
64+
endif()
65+
3866
add_dependencies(swiftParse swift-parse-syntax-generated-headers)
3967

4068
set_swift_llvm_is_available(swiftParse)

lib/Parse/ParseRequests.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
#include "swift/Syntax/SyntaxNodes.h"
2727
#include "swift/SyntaxParse/SyntaxTreeCreator.h"
2828

29+
#ifdef SWIFT_SWIFT_PARSER_ROUNDTRIP
30+
#include "SwiftParserCompilerSupport.h"
31+
#endif
32+
2933
using namespace swift;
3034

3135
namespace swift {
@@ -189,6 +193,22 @@ SourceFileParsingResult ParseSourceFileRequest::evaluate(Evaluator &evaluator,
189193
if (auto tokens = parser.takeTokenReceiver()->finalize())
190194
tokensRef = ctx.AllocateCopy(*tokens);
191195

196+
#ifdef SWIFT_SWIFT_PARSER_ROUNDTRIP
197+
if (ctx.SourceMgr.getCodeCompletionBufferID() != bufferID) {
198+
auto bufferRange = ctx.SourceMgr.getRangeForBuffer(*bufferID);
199+
unsigned int flags = SPCC_RoundTrip;
200+
201+
int roundTripResult =
202+
swift_parser_consistencyCheck(
203+
bufferRange.str().data(), bufferRange.getByteLength(),
204+
SF->getFilename().str().c_str(), flags);
205+
206+
// FIXME: Produce an error on round-trip failure.
207+
if (roundTripResult)
208+
abort();
209+
}
210+
#endif
211+
192212
return SourceFileParsingResult{ctx.AllocateCopy(decls), tokensRef,
193213
parser.CurrentTokenHash, syntaxRoot};
194214
}

utils/swift_build_support/swift_build_support/products/earlyswiftdriver.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import os
1414

15+
from . import earlyswiftsyntax
1516
from . import product
1617
from .. import shell
1718
from .. import toolchain
@@ -57,7 +58,11 @@ def should_build(self, host_target):
5758

5859
@classmethod
5960
def get_dependencies(cls):
60-
return []
61+
# FIXME: This isn't a real dependency, but is necessary to linearize the
62+
# dependency graph from Swift to EarlySwiftSyntax. If we properly
63+
# express the dependency from Swift -> EarlySwiftSyntax, build_graph.py
64+
# asserts that there are multiple roots to the graph.
65+
return [earlyswiftsyntax.EarlySwiftSyntax]
6166

6267
def should_clean(self, host_target):
6368
return self.args.clean_early_swift_driver

utils/swift_build_support/swift_build_support/products/swift.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#
1111
# ----------------------------------------------------------------------------
1212

13+
import os
14+
1315
from . import cmark
1416
from . import earlyswiftdriver
1517
from . import libcxx
@@ -55,6 +57,9 @@ def __init__(self, args, toolchain, source_dir, build_dir):
5557
# Add experimental distributed flag.
5658
self.cmake_options.extend(self._enable_experimental_distributed)
5759

60+
# Add path for the early SwiftSyntax build.
61+
self.cmake_options.extend(self._early_swiftsyntax_flags)
62+
5863
# Add static vprintf flag
5964
self.cmake_options.extend(self._enable_stdlib_static_vprintf)
6065

@@ -167,6 +172,18 @@ def _enable_experimental_distributed(self):
167172
return [('SWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED:BOOL',
168173
self.args.enable_experimental_distributed)]
169174

175+
@property
176+
def _early_swiftsyntax_flags(self):
177+
result = []
178+
if self.args.build_early_swiftsyntax:
179+
build_root = os.path.dirname(self.build_dir)
180+
early_swiftsyntax_build_dir = os.path.join(
181+
'..', build_root, '%s-%s' % ('earlyswiftsyntax',
182+
self.args.host_target))
183+
result.append(('SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR:PATH',
184+
early_swiftsyntax_build_dir))
185+
return result
186+
170187
@property
171188
def _enable_stdlib_static_vprintf(self):
172189
return [('SWIFT_STDLIB_STATIC_PRINT',

utils/swift_build_support/tests/products/test_swift.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def setUp(self):
5656
enable_experimental_differentiable_programming=False,
5757
enable_experimental_concurrency=False,
5858
enable_experimental_distributed=False,
59+
build_early_swiftsyntax=False,
5960
build_swift_stdlib_static_print=False,
6061
build_swift_stdlib_unicode_data=True,
6162
swift_freestanding_is_darwin=False,

0 commit comments

Comments
 (0)