Avoid #include AST headers in Basic headers

Resolve a layering violation. `DiagnosticBehavior` was used in
`LangOptions`. Introduce a dedicated 'enum' for the possible values.
This commit is contained in:
Rintaro Ishizaki
2024-09-24 13:14:57 -07:00
parent 6e055d3b8f
commit c57025af67
5 changed files with 36 additions and 10 deletions

View File

@@ -13,6 +13,10 @@
#ifndef SWIFT_BASIC_CXX_STDLIB_KIND_H
#define SWIFT_BASIC_CXX_STDLIB_KIND_H
#include "llvm/Support/ErrorHandling.h"
#include <stdint.h>
#include <string>
namespace swift {
enum class CXXStdlibKind : uint8_t {

View File

@@ -18,7 +18,6 @@
#ifndef SWIFT_BASIC_LANGOPTIONS_H
#define SWIFT_BASIC_LANGOPTIONS_H
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/Basic/CXXStdlibKind.h"
#include "swift/Basic/Feature.h"
#include "swift/Basic/FixedBitSet.h"
@@ -46,6 +45,7 @@
namespace swift {
struct DiagnosticBehavior;
class DiagnosticEngine;
/// Kind of implicit platform conditions.
enum class PlatformConditionKind {
@@ -217,8 +217,14 @@ namespace swift {
/// Diagnostic level to report when a public declarations doesn't declare
/// an introduction OS version.
std::optional<DiagnosticBehavior> RequireExplicitAvailability =
std::nullopt;
enum class RequireExplicitAvailabilityDiagnosticBehavior : uint8_t {
Ignore,
Warning,
Error,
};
RequireExplicitAvailabilityDiagnosticBehavior
RequireExplicitAvailabilityBehavior =
RequireExplicitAvailabilityDiagnosticBehavior::Ignore;
/// Introduction platform and version to suggest as fix-it
/// when using RequireExplicitAvailability.

View File

@@ -16,6 +16,7 @@
//===----------------------------------------------------------------------===//
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTPrinter.h"
#include "swift/AST/Decl.h"

View File

@@ -1167,11 +1167,14 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
if (const Arg *A = Args.getLastArg(OPT_require_explicit_availability_EQ)) {
StringRef diagLevel = A->getValue();
if (diagLevel == "warn") {
Opts.RequireExplicitAvailability = DiagnosticBehavior::Warning;
Opts.RequireExplicitAvailabilityBehavior =
LangOptions::RequireExplicitAvailabilityDiagnosticBehavior::Warning;
} else if (diagLevel == "error") {
Opts.RequireExplicitAvailability = DiagnosticBehavior::Error;
Opts.RequireExplicitAvailabilityBehavior =
LangOptions::RequireExplicitAvailabilityDiagnosticBehavior::Error;
} else if (diagLevel == "ignore") {
Opts.RequireExplicitAvailability = std::nullopt;
Opts.RequireExplicitAvailabilityBehavior =
LangOptions::RequireExplicitAvailabilityDiagnosticBehavior::Ignore;
} else {
Diags.diagnose(SourceLoc(),
diag::error_unknown_require_explicit_availability,
@@ -1180,7 +1183,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
} else if (Args.getLastArg(OPT_require_explicit_availability,
OPT_require_explicit_availability_target) ||
Opts.LibraryLevel == LibraryLevel::API) {
Opts.RequireExplicitAvailability = DiagnosticBehavior::Warning;
Opts.RequireExplicitAvailabilityBehavior =
LangOptions::RequireExplicitAvailabilityDiagnosticBehavior::Warning;
}
if (const Arg *A = Args.getLastArg(OPT_require_explicit_availability_target)) {

View File

@@ -4651,10 +4651,21 @@ void swift::checkExplicitAvailability(Decl *decl) {
// Skip if the command line option was not set and
// accessors as we check the pattern binding decl instead.
auto &ctx = decl->getASTContext();
auto DiagLevel = ctx.LangOpts.RequireExplicitAvailability;
if (!DiagLevel || isa<AccessorDecl>(decl))
if (isa<AccessorDecl>(decl))
return;
DiagnosticBehavior DiagLevel;
switch (ctx.LangOpts.RequireExplicitAvailabilityBehavior) {
case LangOptions::RequireExplicitAvailabilityDiagnosticBehavior::Ignore:
return;
case LangOptions::RequireExplicitAvailabilityDiagnosticBehavior::Warning:
DiagLevel = DiagnosticBehavior::Warning;
break;
case LangOptions::RequireExplicitAvailabilityDiagnosticBehavior::Error:
DiagLevel = DiagnosticBehavior::Error;
break;
}
// Only look at decls at module level or in extensions.
// This could be changed to force having attributes on all decls.
if (!decl->getDeclContext()->isModuleScopeContext() &&
@@ -4695,7 +4706,7 @@ void swift::checkExplicitAvailability(Decl *decl) {
if (declNeedsExplicitAvailability(decl)) {
auto diag = decl->diagnose(diag::public_decl_needs_availability);
diag.limitBehavior(*DiagLevel);
diag.limitBehavior(DiagLevel);
auto suggestPlatform = ctx.LangOpts.RequireExplicitAvailabilityTarget;
if (!suggestPlatform.empty()) {