Use the std-equivalent names as the LLVM ones are now deprecated
(eventually `llvm::Optional` will disappear):
- `getValue` -> `value`
- `getValueOr` -> `value_or`
- `hasValue` -> `has_value`
Follow up from ab1b343dad and
7d8bf37e5e with some missing cases.
Basic should not be allowed to link Parse, yet it was doing so
to allow Version to provide a constructor that would conveniently
parse a StringRef. This entrypoint also emitted diagnostics, so it
pulled in libAST.
Sink the version parser entrypoint down into Parse where it belongs
and point all the clients to the right place.
The `SWIFT_COMPILER_VERSION` define is used to stamp a vendor’s version number into a Swift compiler binary. It can be queried from Swift code using `#if _compiler_version` and from Clang by using a preprocessor definition called `__SWIFT_COMPILER_VERSION`. These are unsupported compiler-internal features used primarily by Apple Swift.
In Swift 1.0 through 5.5, Apple Swift used a scheme for `SWIFT_COMPILER_VERSION` where the major version matched the embedded clang (e.g. 1300 for Apple Clang 13.0.0) and the minor version was ignored. Starting in Swift 5.6, Apple Swift started using major and minor version numbers that matched the Swift.org version number. This makes them easier to understand, but it means that version 1300.0.x was followed by version 5.6.x. Not only did version numbers go backwards, but also the old logic to ignore minor versions was now a liability, because it meant you would not be able to target a change to 5.7.x compilers but not 5.6.x compilers.
This commit addresses the problem by:
* Modifying the existing `#if _compiler_version(string-literal)` feature so it transforms the major version into a major and minor that will compare correctly to new version numbers. For instance, “1300.*” is transformed into “1.300”, which will compare correctly to a “5.6” or “5.7” version even if it doesn’t really capture the fact that “1300” was a Swift 5.5 compiler. As a bonus, this allows you to use the feature to backwards-compatibly test new compilers using the existing feature: “5007.*” will be seen by compilers before 5.7 as an unknown future version, but will be seen by 5.7 compilers as targeting them.
* Modifying the `__SWIFT_COMPILER_VERSION` clang define similarly so that, to preprocessor conditions written for the old scheme, a 5.7 compiler will appear to have major version 5007.
* Adding a new variant of `#if _compiler_version` with the same syntax as `#if swift` and `#if compiler`—that is, taking a comparison operator and a bare set of dotted version numbers, rather than a string literal. Going forward, this will be how version checks are written once compatibility with compilers before this change is no longer a concern.
These changes are only lightly tested because tests have to work without any compiler version defined (the default in most configurations), but I’ve tested what I can.
Fixes rdar://89841295.
Fixes:
https://bugs.swift.org/browse/SR-3455https://bugs.swift.org/browse/SR-3663https://bugs.swift.org/browse/SR-4032https://bugs.swift.org/browse/SR-4031
Now, compilation conditions are validated at first, then evaluated. Also,
in non-Swift3 mode, '&&' now has higher precedence than '||'.
'A || B && C || D' are evaluated as 'A || (B && C) || D'.
Swift3 source breaking changes:
* [SR-3663] This used to be accepted and evaluate to 'true' because of short
circuit without any validation.
#if true || true * 12 = try Anything is OK?
print("foo")
#endif
In this change, remaining expressions are properly validated and
diagnosed if it's invalid.
* [SR-4031] Compound name references are now diagnosed as errors.
e.g. `#if os(foo:bar:)(macOS)` or `#if FLAG(x:y:)`
Swift3 compatibility:
* [SR-3663] The precedence of '||' and '&&' are still the same and the
following code evaluates to 'true'.
#if false || true && false
print("foo")
#endif
Introduce a new "swift" build configuration that guards declarations
and statements with a language version - if the current language version
of the compiler is at least that version, the block will parse as normal.
For inactive blocks, the code will not be parsed an no diagnostics will
be emitted there.
Example:
#if swift(>=2.2)
print("Active")
#else
this code will not parse or emit diagnostics
#endif
https://github.com/apple/swift-evolution/blob/master/proposals/0020-if-swift-version.md
rdar://problem/19823607
This is a WIP to make CompilerVersion more general.
- Rename CompilerVersion to just "Version"
- Make version comparison general and put _compiler_version special logic
with its second version component in a specialized parsing function
- Add a generic version parsing function
Swift SVN r32726
This configuration clause will suppress lex diagnostics and skip parsing
altogether if the code under the clause isn't active - the compiler must
have a repository version greater than or equal to the version given to
_compiler_version.
This option is only meant to be used sparingly and not to track the
Swift *language* version.
Example, if using a compiler versioned 700.0.28:
#if _compiler_version("700.0.23")
print("This code will compile for versions 700.0.23 and later.")
#else
This + code + will + not + be + parsed
#endif
Included are new diagnostics for checking that the version is formatted
correctly and isn't empty.
New tests:
- Compiler version comparison unit tests
- Build configuration diagnostics
- Skipping parsing of code under inactive clauses
rdar://problem/22730282
Swift SVN r32195