1717
1818#include " swift/Basic/LangOptions.h"
1919#include " swift/AST/DiagnosticEngine.h"
20+ #include " swift/Basic/Assertions.h"
2021#include " swift/Basic/Feature.h"
2122#include " swift/Basic/FileTypes.h"
2223#include " swift/Basic/Platform.h"
@@ -35,7 +36,7 @@ using namespace swift;
3536LangOptions::LangOptions () {
3637 // Add all promoted language features
3738#define LANGUAGE_FEATURE (FeatureName, IsAdoptable, SENumber, Description ) \
38- Features. insert (Feature::FeatureName);
39+ this -> enableFeature (Feature::FeatureName);
3940#define UPCOMING_FEATURE (FeatureName, SENumber, Version )
4041#define EXPERIMENTAL_FEATURE (FeatureName, AvailableInProd )
4142#define OPTIONAL_LANGUAGE_FEATURE (FeatureName, SENumber, Description )
@@ -44,14 +45,16 @@ LangOptions::LangOptions() {
4445 // Special case: remove macro support if the compiler wasn't built with a
4546 // host Swift.
4647#if !SWIFT_BUILD_SWIFT_SYNTAX
47- Features.removeAll ({Feature::Macros, Feature::FreestandingExpressionMacros,
48- Feature::AttachedMacros, Feature::ExtensionMacros});
48+ this ->disableFeature (Feature::Macros);
49+ this ->disableFeature (Feature::FreestandingExpressionMacros);
50+ this ->disableFeature (Feature::AttachedMacros);
51+ this ->disableFeature (Feature::ExtensionMacros);
4952#endif
5053
5154 // Note: Introduce default-on language options here.
52- Features. insert (Feature::NoncopyableGenerics);
53- Features. insert (Feature::BorrowingSwitch);
54- Features. insert (Feature::MoveOnlyPartialConsumption);
55+ this -> enableFeature (Feature::NoncopyableGenerics);
56+ this -> enableFeature (Feature::BorrowingSwitch);
57+ this -> enableFeature (Feature::MoveOnlyPartialConsumption);
5558
5659 // Enable any playground options that are enabled by default.
5760#define PLAYGROUND_OPTION (OptionName, Description, DefaultOn, HighPerfOn ) \
@@ -291,8 +294,50 @@ bool LangOptions::isCustomConditionalCompilationFlagSet(StringRef Name) const {
291294 != CustomConditionalCompilationFlags.end ();
292295}
293296
297+ bool LangOptions::FeatureState::isEnabled () const {
298+ return this ->state != FeatureState::Off;
299+ }
300+
301+ bool LangOptions::FeatureState::isEnabledForAdoption () const {
302+ ASSERT (isFeatureAdoptable (this ->feature ) &&
303+ " You forgot to make the feature adoptable!" );
304+
305+ return this ->state == FeatureState::EnabledForAdoption;
306+ }
307+
308+ LangOptions::FeatureStateStorage::FeatureStateStorage ()
309+ : states(numFeatures(), FeatureState::Off) {}
310+
311+ void LangOptions::FeatureStateStorage::setState (Feature feature,
312+ FeatureState::Kind state) {
313+ auto index = size_t (feature);
314+
315+ this ->states [index] = state;
316+ }
317+
318+ LangOptions::FeatureState
319+ LangOptions::FeatureStateStorage::getState (Feature feature) const {
320+ auto index = size_t (feature);
321+
322+ return FeatureState (feature, this ->states [index]);
323+ }
324+
325+ LangOptions::FeatureState LangOptions::getFeatureState (Feature feature) const {
326+ auto state = this ->featureStates .getState (feature);
327+ if (state.isEnabled ())
328+ return state;
329+
330+ if (auto version = getFeatureLanguageVersion (feature)) {
331+ if (this ->isSwiftVersionAtLeast (*version)) {
332+ return FeatureState (feature, FeatureState::Enabled);
333+ }
334+ }
335+
336+ return state;
337+ }
338+
294339bool LangOptions::hasFeature (Feature feature) const {
295- if (Features. contains (feature))
340+ if (this -> featureStates . getState (feature). isEnabled ( ))
296341 return true ;
297342
298343 if (auto version = getFeatureLanguageVersion (feature))
@@ -313,6 +358,19 @@ bool LangOptions::hasFeature(llvm::StringRef featureName) const {
313358 return false ;
314359}
315360
361+ void LangOptions::enableFeature (Feature feature, bool forAdoption) {
362+ if (forAdoption) {
363+ ASSERT (isFeatureAdoptable (feature));
364+ this ->featureStates .setState (feature, FeatureState::EnabledForAdoption);
365+ } else {
366+ this ->featureStates .setState (feature, FeatureState::Enabled);
367+ }
368+ }
369+
370+ void LangOptions::disableFeature (Feature feature) {
371+ this ->featureStates .setState (feature, FeatureState::Off);
372+ }
373+
316374void LangOptions::setHasAtomicBitWidth (llvm::Triple triple) {
317375 // We really want to use Clang's getMaxAtomicInlineWidth(), but that requires
318376 // a Clang::TargetInfo and we're setting up lang opts very early in the
0 commit comments