Skip to content

Commit 6a3ef05

Browse files
committed
[ClangImporter] Augment has*Attr methods to find attributes in type positions
`SwiftAttr` can now appear in type positions and `has*Attr` methods have to account for that when the given declaration is `ParmVarDecl`.
1 parent 8f8e856 commit 6a3ef05

File tree

3 files changed

+57
-39
lines changed

3 files changed

+57
-39
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7196,36 +7196,40 @@ static bool isForeignReferenceType(const clang::QualType type) {
71967196
return hasImportAsRefAttr(pointeeType->getDecl());
71977197
}
71987198

7199+
static bool hasSwiftAttribute(const clang::Decl *decl, StringRef attr) {
7200+
if (decl->hasAttrs() && llvm::any_of(decl->getAttrs(), [&](auto *A) {
7201+
if (auto swiftAttr = dyn_cast<clang::SwiftAttrAttr>(A))
7202+
return swiftAttr->getAttribute() == attr;
7203+
return false;
7204+
}))
7205+
return true;
7206+
7207+
if (auto *P = dyn_cast<clang::ParmVarDecl>(decl)) {
7208+
bool found = false;
7209+
findSwiftAttributes(P->getOriginalType(),
7210+
[&](const clang::SwiftAttrAttr *swiftAttr) {
7211+
found |= swiftAttr->getAttribute() == attr;
7212+
});
7213+
return found;
7214+
}
7215+
7216+
return false;
7217+
}
7218+
71997219
static bool hasOwnedValueAttr(const clang::RecordDecl *decl) {
7200-
return decl->hasAttrs() && llvm::any_of(decl->getAttrs(), [](auto *attr) {
7201-
if (auto swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr))
7202-
return swiftAttr->getAttribute() == "import_owned";
7203-
return false;
7204-
});
7220+
return hasSwiftAttribute(decl, "import_owned");
72057221
}
72067222

72077223
bool importer::hasUnsafeAPIAttr(const clang::Decl *decl) {
7208-
return decl->hasAttrs() && llvm::any_of(decl->getAttrs(), [](auto *attr) {
7209-
if (auto swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr))
7210-
return swiftAttr->getAttribute() == "import_unsafe";
7211-
return false;
7212-
});
7224+
return hasSwiftAttribute(decl, "import_unsafe");
72137225
}
72147226

72157227
static bool hasIteratorAPIAttr(const clang::Decl *decl) {
7216-
return decl->hasAttrs() && llvm::any_of(decl->getAttrs(), [](auto *attr) {
7217-
if (auto swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr))
7218-
return swiftAttr->getAttribute() == "import_iterator";
7219-
return false;
7220-
});
7228+
return hasSwiftAttribute(decl, "import_iterator");
72217229
}
72227230

72237231
static bool hasNonCopyableAttr(const clang::RecordDecl *decl) {
7224-
return decl->hasAttrs() && llvm::any_of(decl->getAttrs(), [](auto *attr) {
7225-
if (auto swiftAttr = dyn_cast<clang::SwiftAttrAttr>(attr))
7226-
return swiftAttr->getAttribute() == "~Copyable";
7227-
return false;
7228-
});
7232+
return hasSwiftAttribute(decl, "~Copyable");
72297233
}
72307234

72317235
/// Recursively checks that there are no pointers in any fields or base classes.

lib/ClangImporter/ImportType.cpp

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,15 +1633,9 @@ static ImportedType adjustTypeForConcreteImport(
16331633
return {importedType, isIUO};
16341634
}
16351635

1636-
void swift::getConcurrencyAttrs(ASTContext &SwiftContext,
1637-
ImportTypeKind importKind,
1638-
ImportTypeAttrs &attrs, clang::QualType type) {
1639-
bool isMainActor = false;
1640-
bool isSendable =
1641-
SwiftContext.LangOpts.hasFeature(Feature::SendableCompletionHandlers) &&
1642-
importKind == ImportTypeKind::CompletionHandlerParameter;
1643-
bool isNonSendable = false;
1644-
1636+
void swift::findSwiftAttributes(
1637+
clang::QualType type,
1638+
llvm::function_ref<void(const clang::SwiftAttrAttr *)> callback) {
16451639
std::function<clang::QualType(clang::QualType)> skipUnrelatedSugar =
16461640
[&](clang::QualType type) -> clang::QualType {
16471641
if (auto *MQT = dyn_cast<clang::MacroQualifiedType>(type))
@@ -1660,19 +1654,33 @@ void swift::getConcurrencyAttrs(ASTContext &SwiftContext,
16601654
while (const auto *AT = dyn_cast<clang::AttributedType>(type)) {
16611655
if (auto swiftAttr =
16621656
dyn_cast_or_null<clang::SwiftAttrAttr>(AT->getAttr())) {
1663-
if (isMainActorAttr(swiftAttr)) {
1664-
isMainActor = true;
1665-
isNonSendable =
1666-
importKind == ImportTypeKind::Parameter ||
1667-
importKind == ImportTypeKind::CompletionHandlerParameter;
1668-
} else if (swiftAttr->getAttribute() == "@Sendable")
1669-
isSendable = true;
1670-
else if (swiftAttr->getAttribute() == "@_nonSendable")
1671-
isNonSendable = true;
1657+
callback(swiftAttr);
16721658
}
1673-
16741659
type = skipUnrelatedSugar(AT->getEquivalentType());
16751660
}
1661+
}
1662+
1663+
void swift::getConcurrencyAttrs(ASTContext &SwiftContext,
1664+
ImportTypeKind importKind,
1665+
ImportTypeAttrs &attrs, clang::QualType type) {
1666+
bool isMainActor = false;
1667+
bool isSendable =
1668+
SwiftContext.LangOpts.hasFeature(Feature::SendableCompletionHandlers) &&
1669+
importKind == ImportTypeKind::CompletionHandlerParameter;
1670+
bool isNonSendable = false;
1671+
1672+
// Consider only immediate attributes, don't look through the typerefs
1673+
// because they are imported separately.
1674+
findSwiftAttributes(type, [&](const clang::SwiftAttrAttr *attr) {
1675+
if (isMainActorAttr(attr)) {
1676+
isMainActor = true;
1677+
isNonSendable = importKind == ImportTypeKind::Parameter ||
1678+
importKind == ImportTypeKind::CompletionHandlerParameter;
1679+
} else if (attr->getAttribute() == "@Sendable")
1680+
isSendable = true;
1681+
else if (attr->getAttribute() == "@_nonSendable")
1682+
isNonSendable = true;
1683+
});
16761684

16771685
if (isMainActor)
16781686
attrs |= ImportTypeAttr::MainActor;

lib/ClangImporter/ImporterImpl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,12 @@ enum class ImportTypeAttr : uint8_t {
216216
CFUnretainedOutParameter = 1 << 5,
217217
};
218218

219+
/// Find and iterate over swift attributes embedded in the type
220+
/// without looking through typealiases.
221+
void findSwiftAttributes(
222+
clang::QualType type,
223+
llvm::function_ref<void(const clang::SwiftAttrAttr *)> callback);
224+
219225
/// Attributes which were set on the declaration and affect how its type is
220226
/// imported.
221227
///

0 commit comments

Comments
 (0)