Tie attributes to language features

The new `DECL_ATTR_FEATURE_REQUIREMENT` macro in DeclAttr.def can be used to declare that an attribute should only be available when a related language feature is enabled.

Effects:

• `#if hasAttribute(someAttr)` will return `false` unless the required feature is enabled.
• Code completion will not include the attribute unless the required feature is enabled.
• `TypeChecker::checkDeclAttributes()` diagnoses non-implicit uses of the attribute.

Add this mechanism and use it to tie @abi to the ABIAttribute feature. Also design tests for it.
This commit is contained in:
Becca Royal-Gordon
2024-10-08 14:35:50 -07:00
parent 94ff062edd
commit 01b8bbea89
11 changed files with 236 additions and 14 deletions

View File

@@ -686,7 +686,7 @@ static void addKeyword(CodeCompletionResultSink &Sink, StringRef Name,
}
static void addDeclKeywords(CodeCompletionResultSink &Sink, DeclContext *DC,
bool IsConcurrencyEnabled) {
const LangOptions &langOpts) {
auto isTypeDeclIntroducer = [](CodeCompletionKeywordKind Kind,
std::optional<DeclAttrKind> DAK) -> bool {
switch (Kind) {
@@ -799,10 +799,16 @@ static void addDeclKeywords(CodeCompletionResultSink &Sink, DeclContext *DC,
return;
// Remove keywords only available when concurrency is enabled.
if (DAK.has_value() && !IsConcurrencyEnabled &&
if (DAK.has_value() && !langOpts.EnableExperimentalConcurrency &&
DeclAttribute::isConcurrencyOnly(*DAK))
return;
// Remove experimental keywords.
if (DAK.has_value())
if (auto feature = DeclAttribute::getRequiredFeature(*DAK))
if (!langOpts.hasFeature(*feature))
return;
CodeCompletionFlair flair = getFlair(Kind, DAK);
// Special case for 'actor'. Get the same flair with 'kw_class'.
@@ -1019,8 +1025,7 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
LLVM_FALLTHROUGH;
}
case CompletionKind::StmtOrExpr:
addDeclKeywords(Sink, CurDeclContext,
Context.LangOpts.EnableExperimentalConcurrency);
addDeclKeywords(Sink, CurDeclContext, Context.LangOpts);
addStmtKeywords(Sink, CurDeclContext, MaybeFuncBody);
addClosureSignatureKeywordsIfApplicable(Sink, CurDeclContext);
@@ -1122,8 +1127,7 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
.Default(false);
}) != ParsedKeywords.end();
if (!HasDeclIntroducer) {
addDeclKeywords(Sink, CurDeclContext,
Context.LangOpts.EnableExperimentalConcurrency);
addDeclKeywords(Sink, CurDeclContext, Context.LangOpts);
addLetVarKeywords(Sink);
}
break;