Skip to content

Commit a281feb

Browse files
committed
[NFC] Factor out ImportTypeAttrs
Preparation for integrating the logic remaining in `applyParamAttributes()` into `importType()`.
1 parent 6f71581 commit a281feb

File tree

3 files changed

+102
-31
lines changed

3 files changed

+102
-31
lines changed

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ WARNING(clang_error_code_must_be_sendable,none,
8989
"cannot make error code type '%0' non-sendable because Swift errors "
9090
"are always sendable", (StringRef))
9191

92-
WARNING(clang_param_ignored_sendable_attr,none,
93-
"cannot make parameter '%0' sendable type %1 cannot be made sendable "
94-
"by adding '@Sendable' or '& Sendable'",
95-
(StringRef, Type))
92+
WARNING(clang_ignored_sendable_attr,none,
93+
"cannot make type %0 sendable because '@Sendable' and '& Sendable' "
94+
"cannot be added to it",
95+
(Type))
9696
NOTE(clang_param_should_be_implicitly_sendable,none,
9797
"parameter should be implicitly 'Sendable' because it is a completion "
9898
"handler", ())

lib/ClangImporter/ImportType.cpp

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,19 +1948,21 @@ class GetSendableType :
19481948

19491949
} // anonymous namespace
19501950

1951-
Type ClangImporter::Implementation::applyParamAttributes(
1952-
const clang::ParmVarDecl *param, Type type, bool sendableByDefault) {
1951+
ImportTypeAttrs swift::getImportTypeAttrs(const clang::Decl *D, bool isParam,
1952+
bool sendableByDefault) {
1953+
ImportTypeAttrs attrs;
1954+
1955+
if (sendableByDefault)
1956+
attrs |= ImportTypeAttr::DefaultsToSendable;
1957+
19531958
bool sendableRequested = sendableByDefault;
19541959
bool sendableDisqualified = false;
19551960

1956-
if (param->hasAttrs()) {
1957-
for (auto attr : param->getAttrs()) {
1961+
if (D->hasAttrs()) {
1962+
for (auto attr : D->getAttrs()) {
19581963
// Map __attribute__((noescape)) to @noescape.
1959-
if (isa<clang::NoEscapeAttr>(attr)) {
1960-
type = applyToFunctionType(type, [](ASTExtInfo extInfo) {
1961-
return extInfo.withNoEscape();
1962-
});
1963-
1964+
if (isParam && isa<clang::NoEscapeAttr>(attr)) {
1965+
attrs |= ImportTypeAttr::NoEscape;
19641966
continue;
19651967
}
19661968

@@ -1969,14 +1971,9 @@ Type ClangImporter::Implementation::applyParamAttributes(
19691971
continue;
19701972

19711973
// Map the main-actor attribute.
1972-
if (isMainActorAttr(swiftAttr)) {
1973-
if (Type mainActor = SwiftContext.getMainActorType()) {
1974-
type = applyToFunctionType(type, [&](ASTExtInfo extInfo) {
1975-
return extInfo.withGlobalActor(mainActor);
1976-
});
1977-
sendableDisqualified = true;
1978-
}
1979-
1974+
if (isParam && isMainActorAttr(swiftAttr)) {
1975+
attrs |= ImportTypeAttr::MainActor;
1976+
sendableDisqualified = true;
19801977
continue;
19811978
}
19821979

@@ -1995,22 +1992,51 @@ Type ClangImporter::Implementation::applyParamAttributes(
19951992
}
19961993

19971994
if (!sendableDisqualified && sendableRequested) {
1995+
attrs |= ImportTypeAttr::Sendable;
1996+
}
1997+
1998+
return attrs;
1999+
}
2000+
2001+
Type ClangImporter::Implementation::applyParamAttributes(
2002+
const clang::ParmVarDecl *param, Type type, bool sendableByDefault) {
2003+
auto parentDecl = cast<clang::Decl>(param->getDeclContext());
2004+
ImportDiagnosticAdder addDiag(*this, parentDecl, param->getLocation());
2005+
2006+
auto attrs = getImportTypeAttrs(param, /*isParam=*/true, sendableByDefault);
2007+
return applyImportTypeAttrs(attrs, type, addDiag);
2008+
}
2009+
2010+
Type ClangImporter::Implementation::
2011+
applyImportTypeAttrs(ImportTypeAttrs attrs, Type type,
2012+
llvm::function_ref<void(Diagnostic &&)> addDiag) {
2013+
if (attrs.contains(ImportTypeAttr::NoEscape)) {
2014+
type = applyToFunctionType(type, [](ASTExtInfo extInfo) {
2015+
return extInfo.withNoEscape();
2016+
});
2017+
}
2018+
2019+
if (attrs.contains(ImportTypeAttr::MainActor)) {
2020+
if (Type mainActor = SwiftContext.getMainActorType()) {
2021+
type = applyToFunctionType(type, [&](ASTExtInfo extInfo) {
2022+
return extInfo.withGlobalActor(mainActor);
2023+
});
2024+
} else {
2025+
// If we can't use @MainActor, fall back to at least using @Sendable.
2026+
attrs |= ImportTypeAttr::Sendable;
2027+
}
2028+
}
2029+
2030+
if (attrs.contains(ImportTypeAttr::Sendable)) {
19982031
bool changed;
19992032
std::tie(type, changed) = GetSendableType(SwiftContext).convert(type);
20002033

20012034
// Diagnose if we couldn't find a place to add `Sendable` to the type.
20022035
if (!changed) {
2003-
auto parentDecl = cast<clang::Decl>(param->getDeclContext());
2004-
2005-
addImportDiagnostic(parentDecl,
2006-
Diagnostic(diag::clang_param_ignored_sendable_attr,
2007-
param->getName(), type),
2008-
param->getLocation());
2036+
addDiag(Diagnostic(diag::clang_ignored_sendable_attr, type));
20092037

2010-
if (sendableByDefault)
2011-
addImportDiagnostic(parentDecl,
2012-
Diagnostic(diag::clang_param_should_be_implicitly_sendable),
2013-
param->getLocation());
2038+
if (attrs.contains(ImportTypeAttr::DefaultsToSendable))
2039+
addDiag(Diagnostic(diag::clang_param_should_be_implicitly_sendable));
20142040
}
20152041
}
20162042

lib/ClangImporter/ImporterImpl.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,48 @@ enum class ImportTypeKind {
187187
Enum
188188
};
189189

190+
/// Flags which are extracted from an imported declaration to influence how its
191+
/// type is imported. Typically used via \c ImportTypeAttrs to form an option
192+
/// set.
193+
///
194+
/// \warning Do not use this as a random grab bag of flags to \c importType() .
195+
/// This information is intended to be extracted and applied all at once.
196+
enum class ImportTypeAttr : uint8_t {
197+
/// Type should be imported as though declaration was marked with
198+
/// \c __attribute__((noescape)) .
199+
NoEscape = 1 << 0,
200+
201+
/// Type should be imported as though declaration was marked with
202+
/// \c __attribute__((swift_attr("@MainActor"))) .
203+
MainActor = 1 << 1,
204+
205+
/// Type should be imported as though declaration was marked with
206+
/// \c __attribute__((swift_attr("@Sendable"))) .
207+
Sendable = 1 << 2,
208+
209+
/// Type is in a declaration where it would be imported as Sendable by
210+
/// default. This comes directly from the parameters to
211+
/// \c getImportTypeAttrs() and merely affects diagnostics.
212+
DefaultsToSendable = 1 << 3
213+
};
214+
215+
/// Attributes which were set on the declaration and affect how its type is
216+
/// imported.
217+
///
218+
/// \seeAlso ImportTypeAttr
219+
using ImportTypeAttrs = OptionSet<ImportTypeAttr>;
220+
221+
/// Extracts the \c ImportTypeAttrs from a declaration.
222+
///
223+
/// \param D The declaration to extract attributes from.
224+
/// \param isParam Is the declaration a function parameter? If so, additional
225+
/// attributes will be imported.
226+
/// \param sendableByDefault If the sendability of the declaration is not
227+
/// specified, should the \c \@Sendable attribute be added implicitly?
228+
/// Used for e.g. completion handlers.
229+
ImportTypeAttrs getImportTypeAttrs(const clang::Decl *D, bool isParam = false,
230+
bool sendableByDefault = false);
231+
190232
struct ImportDiagnostic {
191233
ImportDiagnosticTarget target;
192234
Diagnostic diag;
@@ -956,6 +998,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
956998
Type applyParamAttributes(const clang::ParmVarDecl *param, Type type,
957999
bool sendableByDefault);
9581000

1001+
Type applyImportTypeAttrs(ImportTypeAttrs attrs, Type type,
1002+
llvm::function_ref<void(Diagnostic &&)> addImportDiagnosticFn);
1003+
9591004
/// If we already imported a given decl, return the corresponding Swift decl.
9601005
/// Otherwise, return nullptr.
9611006
Optional<Decl *> importDeclCached(const clang::NamedDecl *ClangDecl,

0 commit comments

Comments
 (0)