Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 6 additions & 1 deletion lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2297,7 +2297,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();
Expand All @@ -2315,6 +2316,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));

Expand Down
13 changes: 7 additions & 6 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -498,12 +499,12 @@ class TypeSystemClang : public TypeSystem {
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

Expand Down
33 changes: 33 additions & 0 deletions lldb/test/Shell/Expr/TestEnumExtensibility.m
Original file line number Diff line number Diff line change
@@ -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'