[lldb][TypeSystemClang] Create EnumExtensibilityAttr from DW_AT_APPLE_enum_kind (#126221)

This patch consumes the `DW_AT_APPLE_enum_kind` attribute added in
https://github.com/llvm/llvm-project/pull/124752 and turns it into a
Clang attribute in the AST. This will currently be used by the Swift
language plugin when it creates `EnumDecl`s from debug-info and passes
it to Swift compiler, which expects these attributes
This commit is contained in:
Michael Buch 2025-02-08 11:39:11 +00:00 committed by GitHub
parent 16df836a52
commit 0cdb467c7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 57 additions and 9 deletions

View File

@ -492,6 +492,10 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
case DW_AT_reference:
ref_qual = clang::RQ_LValue;
break;
case DW_AT_APPLE_enum_kind:
enum_kind = static_cast<clang::EnumExtensibilityAttr::Kind>(
form_value.Unsigned());
break;
}
}
}
@ -1001,9 +1005,10 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
}
CompilerType clang_type = m_ast.CreateEnumerationType(
attrs.name.GetStringRef(), GetClangDeclContextContainingDIE(def_die, nullptr),
attrs.name.GetStringRef(),
GetClangDeclContextContainingDIE(def_die, nullptr),
GetOwningClangModule(def_die), attrs.decl, enumerator_clang_type,
attrs.is_scoped_enum);
attrs.is_scoped_enum, attrs.enum_kind);
TypeSP type_sp =
dwarf->MakeType(def_die.GetID(), attrs.name, attrs.byte_size, nullptr,
attrs.type.Reference().GetID(), Type::eEncodingIsUID,

View File

@ -568,6 +568,10 @@ struct ParsedDWARFTypeAttributes {
///< Indicates ref-qualifier of C++ member function if present.
///< Is RQ_None otherwise.
clang::RefQualifierKind ref_qual = clang::RQ_None;
///< Has a value if this DIE represents an enum that was declared
///< with enum_extensibility.
std::optional<clang::EnumExtensibilityAttr::Kind> enum_kind;
};
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H

View File

@ -2303,7 +2303,8 @@ CompilerType TypeSystemClang::GetOrCreateStructForIdentifier(
CompilerType TypeSystemClang::CreateEnumerationType(
llvm::StringRef name, clang::DeclContext *decl_ctx,
OptionalClangModuleID owning_module, const Declaration &decl,
const CompilerType &integer_clang_type, bool is_scoped) {
const CompilerType &integer_clang_type, bool is_scoped,
std::optional<clang::EnumExtensibilityAttr::Kind> enum_kind) {
// TODO: Do something intelligent with the Declaration object passed in
// like maybe filling in the SourceLocation with it...
ASTContext &ast = getASTContext();
@ -2321,6 +2322,10 @@ CompilerType TypeSystemClang::CreateEnumerationType(
if (decl_ctx)
decl_ctx->addDecl(enum_decl);
if (enum_kind)
enum_decl->addAttr(
clang::EnumExtensibilityAttr::CreateImplicit(ast, *enum_kind));
// TODO: check if we should be setting the promotion type too?
enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));

View File

@ -22,6 +22,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
@ -498,12 +499,12 @@ public:
bool is_vector);
// Enumeration Types
CompilerType CreateEnumerationType(llvm::StringRef name,
clang::DeclContext *decl_ctx,
OptionalClangModuleID owning_module,
const Declaration &decl,
const CompilerType &integer_qual_type,
bool is_scoped);
CompilerType CreateEnumerationType(
llvm::StringRef name, clang::DeclContext *decl_ctx,
OptionalClangModuleID owning_module, const Declaration &decl,
const CompilerType &integer_qual_type, bool is_scoped,
std::optional<clang::EnumExtensibilityAttr::Kind> enum_kind =
std::nullopt);
// Integer type functions

View File

@ -0,0 +1,33 @@
// UNSUPPORTED: system-linux, system-windows
// RUN: %clangxx_host %s -c -g -o %t
// RUN: %lldb %t \
// RUN: -o "target var gClosed gOpen gNS gNSOpts" \
// RUN: -o "image dump ast" \
// RUN: 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
enum __attribute__((enum_extensibility(closed))) Closed { C1 } gClosed;
enum __attribute__((enum_extensibility(open))) Open { O1 } gOpen;
typedef NS_ENUM(int, NS) { N1 } gNS;
typedef NS_OPTIONS(int, NSO) { OPT1 } gNSOpts;
// CHECK: EnumDecl {{.*}} Closed
// CHECK-NEXT: |-EnumExtensibilityAttr {{.*}} Closed
// CHECK-NEXT: `-EnumConstantDecl {{.*}} C1 'Closed'
// CHECK: EnumDecl {{.*}} Open
// CHECK-NEXT: |-EnumExtensibilityAttr {{.*}} Open
// CHECK-NEXT: `-EnumConstantDecl {{.*}} O1 'Open'
// CHECK: EnumDecl {{.*}} NS
// CHECK-NEXT: |-EnumExtensibilityAttr {{.*}} Open
// CHECK-NEXT: `-EnumConstantDecl {{.*}} N1 'NS'
// CHECK: EnumDecl {{.*}} NSO
// CHECK-NEXT: |-EnumExtensibilityAttr {{.*}} Open
// CHECK-NEXT: `-EnumConstantDecl {{.*}} OPT1 'NSO'