Files
swift-mirror/include/swift/Basic/Feature.h
John McCall 1437acdf22 Implement conditional feature suppression.
Our standard conception of suppressible features assumes we should
always suppress the feature if the compiler doesn't support it.
This presumes that there's no harm in suppressing the feature, and
that's a fine assumption for features that are just adding information
or suppressing new diagnostics.  Features that are semantically
relevant, maybe even ABI-breaking, are not a good fit for this,
and so instead of reprinting the decl with the feature suppressed,
we just have to hide the decl entirely.  The missing middle here
is that it's sometimes useful to be able to adopt a type change
to an existing declaration, and we'd like older compilers to be
able to use the older version of the declaration.  Making a type
change this way is, of course, only really acceptable for
@_alwaysEmitIntoClient declarations; but those represent quite a
few declarations that we'd like to be able to refine the types of.

Rather than trying to come up with heuristics based on
@_alwaysEmitIntoClient or other sources of information, this design
just requires the declaration to opt in with a new attribute,
@_allowFeatureSuppress.  When a declaration opts in to suppression
for a conditionally-suppressible feature, the printer uses the
suppression serially-print-with-downgraded-options approach;
otherwise it uses the print-only-if-feature-is-available approach.
2024-03-01 22:10:14 -05:00

71 lines
2.3 KiB
C++

//===--- Feature.h - Helpers related to Swift features ----------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_BASIC_FEATURES_H
#define SWIFT_BASIC_FEATURES_H
#include "llvm/ADT/StringRef.h"
#include <optional>
namespace swift {
class LangOptions;
/// Enumeration describing all of the named features.
enum class Feature {
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) FeatureName,
#include "swift/Basic/Features.def"
};
constexpr unsigned numFeatures() {
enum Features {
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) FeatureName,
#include "swift/Basic/Features.def"
NumFeatures
};
return NumFeatures;
}
/// Check whether the given feature is available in production compilers.
bool isFeatureAvailableInProduction(Feature feature);
/// Determine the in-source name of the given feature.
llvm::StringRef getFeatureName(Feature feature);
/// Determine whether the first feature is more recent (and thus implies
/// the existence of) the second feature. Only meaningful for suppressible
/// features.
inline bool featureImpliesFeature(Feature feature, Feature implied) {
// Suppressible features are expected to be listed in order of
// addition in Features.def.
return (unsigned) feature < (unsigned) implied;
}
/// Get the feature corresponding to this "future" feature, if there is one.
std::optional<Feature> getUpcomingFeature(llvm::StringRef name);
/// Get the feature corresponding to this "experimental" feature, if there is
/// one.
std::optional<Feature> getExperimentalFeature(llvm::StringRef name);
/// Get the major language version in which this feature was introduced, or
/// \c None if it does not have such a version.
std::optional<unsigned> getFeatureLanguageVersion(Feature feature);
/// Determine whether this feature should be included in the
/// module interface
bool includeInModuleInterface(Feature feature);
}
#endif // SWIFT_BASIC_FEATURES_H