mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add _compiler_version build configuration
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
This commit is contained in:
@@ -14,10 +14,14 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "swift/Basic/Version.h"
|
||||
|
||||
#include "swift/AST/DiagnosticsParse.h"
|
||||
#include "swift/Basic/LLVM.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
|
||||
#define TOSTR2(X) #X
|
||||
#define TOSTR(X) TOSTR2(X)
|
||||
@@ -42,6 +46,82 @@
|
||||
namespace swift {
|
||||
namespace version {
|
||||
|
||||
void parseVersionString(StringRef VersionString,
|
||||
SmallVectorImpl<unsigned> &Components,
|
||||
SourceLoc Loc,
|
||||
DiagnosticEngine *Diags) {
|
||||
StringRef SwiftTagPrefix("swiftlang-");
|
||||
if (VersionString.startswith_lower(SwiftTagPrefix))
|
||||
VersionString = VersionString.substr(SwiftTagPrefix.size());
|
||||
SmallString<16> digits;
|
||||
llvm::raw_svector_ostream OS(digits);
|
||||
for (auto c : VersionString) {
|
||||
if (Loc.isValid())
|
||||
Loc = Loc.getAdvancedLoc(1);
|
||||
if (isdigit(c)) {
|
||||
OS << c;
|
||||
} else if (c == '.' && digits.str().size()) {
|
||||
Components.push_back(std::atoi(OS.str().str().data()));
|
||||
digits.clear();
|
||||
} else {
|
||||
Components.clear();
|
||||
if (Diags)
|
||||
Diags->diagnose(Loc, diag::invalid_character_in_compiler_version);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (digits.str().size())
|
||||
Components.push_back(std::atoi(OS.str().data()));
|
||||
}
|
||||
|
||||
CompilerVersion::CompilerVersion(const StringRef VersionString,
|
||||
SourceLoc Loc, DiagnosticEngine *Diags) {
|
||||
parseVersionString(VersionString, Components, Loc, Diags);
|
||||
}
|
||||
|
||||
#ifdef SWIFT_COMPILER_VERSION
|
||||
|
||||
CompilerVersion::CompilerVersion() {
|
||||
parseVersionString(TOSTR(SWIFT_COMPILER_VERSION), Components, SourceLoc(),
|
||||
nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string CompilerVersion::str() const {
|
||||
std::string VersionString;
|
||||
llvm::raw_string_ostream OS(VersionString);
|
||||
for (auto i = Components.begin(); i != Components.end(); i++) {
|
||||
OS << *i;
|
||||
if (i != Components.end() - 1)
|
||||
OS << '.';
|
||||
}
|
||||
return OS.str();
|
||||
}
|
||||
|
||||
bool operator>=(const class CompilerVersion &lhs,
|
||||
const class CompilerVersion &rhs) {
|
||||
|
||||
// The empty compiler version represents the latest possible version,
|
||||
// usually built from the source repository.
|
||||
if (lhs.empty())
|
||||
return true;
|
||||
|
||||
auto n = std::min(lhs.size(), rhs.size());
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
// Skip the second component for comparison - this is just an internal
|
||||
// compiler variant.
|
||||
if (i == 1)
|
||||
continue;
|
||||
|
||||
if (lhs[i] < rhs[i])
|
||||
return false;
|
||||
else if (lhs[i] > rhs[i])
|
||||
return true;
|
||||
}
|
||||
return lhs.size() >= rhs.size();
|
||||
}
|
||||
|
||||
std::pair<unsigned, unsigned> getSwiftNumericVersion() {
|
||||
return { SWIFT_VERSION_MAJOR, SWIFT_VERSION_MINOR };
|
||||
}
|
||||
@@ -53,8 +133,8 @@ std::string getSwiftFullVersion() {
|
||||
OS << SWIFT_VENDOR " ";
|
||||
#endif
|
||||
OS << "Swift version " SWIFT_VERSION_STRING;
|
||||
#ifdef SWIFT_REPOSITORY_STRING
|
||||
OS << " (" SWIFT_REPOSITORY_STRING ")";
|
||||
#ifdef SWIFT_COMPILER_VERSION
|
||||
OS << " (" TOSTR(SWIFT_COMPILER_VERSION) ")";
|
||||
#endif
|
||||
return OS.str();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user