AST: Introduce EnumDecl::isCDeclEnum and isCCompatibleEnum

This commit is contained in:
Alexis Laferrière
2025-08-18 15:49:53 -07:00
parent 09edc47db5
commit b624ee96fe
4 changed files with 13 additions and 4 deletions

View File

@@ -4874,6 +4874,16 @@ public:
return getAttrs().hasAttribute<IndirectAttr>();
}
/// True if the enum is marked with `@cdecl`.
bool isCDeclEnum() const {
return getAttrs().hasAttribute<CDeclAttr>();
}
/// True if the enum is marked with `@cdecl` or `@objc`.
bool isCCompatibleEnum() const {
return isCDeclEnum() || isObjC();
}
/// True if the enum can be exhaustively switched within \p useDC.
///
/// Note that this property is \e not necessarily true for all children of

View File

@@ -654,7 +654,7 @@ clang::QualType ClangTypeConverter::visitEnumType(EnumType *type) {
return convert(Context.TheEmptyTupleType);
auto ED = type->getDecl();
if (!ED->isObjC() && !ED->getAttrs().hasAttribute<CDeclAttr>())
if (!ED->isCCompatibleEnum())
// Can't translate something not marked with @objc or @cdecl.
return clang::QualType();

View File

@@ -2408,7 +2408,7 @@ private:
void maybePrintTagKeyword(const TypeDecl *NTD) {
auto *ED = dyn_cast<EnumDecl>(NTD);
if (ED && !NTD->hasClangNode()) {
if (ED->getAttrs().hasAttribute<CDeclAttr>()) {
if (ED->isCDeclEnum()) {
// We should be able to use the tag macro for all printed enums but
// for now restrict it to @cdecl to guard it behind the feature flag.
os << "SWIFT_ENUM_TAG ";

View File

@@ -538,8 +538,7 @@ public:
}
void forwardDeclare(const EnumDecl *ED) {
assert(ED->isObjC() || ED->getAttrs().getAttribute<CDeclAttr>() ||
ED->hasClangNode());
assert(ED->isCCompatibleEnum() || ED->hasClangNode());
forwardDeclare(ED, [&]{
if (ED->getASTContext().LangOpts.hasFeature(Feature::CDecl)) {