Author: Adrian Prantl Date: 2026-10-21T15:03:58-07:00 New Revision: ed07c22327fdc4ccddac4e44c32bc69c796be782
URL: https://github.com/llvm/llvm-project/commit/ed07c22327fdc4ccddac4e44c32bc69c796be782 DIFF: https://github.com/llvm/llvm-project/commit/ed07c22327fdc4ccddac4e44c32bc69c796be782.diff LOG: [clang][DebugInfo] Record objc_runtime_name of ObjC interfaces (#233647) An Objective-C class with a custom objc_runtime_name exports its class, metaclass, and ivar offset symbols under the runtime name, but the debug info only records the source name. This causes problems in LLDB's expression evaluator since it will use the name recorded in the debug info for any ObjC metadata symbols. This patch uses DW_TAG_LLVM_annotation to record the runtime name in the interface. rdar://187396633 Assisted-by: Claude Added: clang/test/DebugInfo/ObjC/objc-runtime-name.m Modified: clang/lib/CodeGen/CGDebugInfo.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index da62fbbec20590..96cda4555e49db 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -3710,10 +3710,22 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, if (ID->getImplementation()) Flags |= llvm::DINode::FlagObjcClassComplete; + llvm::DINodeArray Annotations; + const auto *RuntimeName = ID->getAttr<ObjCRuntimeNameAttr>(); + if (RuntimeName && RuntimeName->getMetadataName() != ID->getName()) { + llvm::LLVMContext &Ctx = CGM.getLLVMContext(); + llvm::Metadata *Ops[2] = { + llvm::MDString::get(Ctx, "objc_runtime_name"), + llvm::MDString::get(Ctx, RuntimeName->getMetadataName())}; + Annotations = DBuilder.getOrCreateArray({llvm::MDNode::get(Ctx, Ops)}); + } + llvm::DIScope *Mod = getParentModuleOrNull(ID); llvm::DICompositeType *RealDecl = DBuilder.createStructType( Mod ? Mod : Unit, ID->getName(), DefUnit, Line, Size, Align, Flags, - nullptr, llvm::DINodeArray(), RuntimeLang); + nullptr, llvm::DINodeArray(), RuntimeLang, /*VTableHolder=*/nullptr, + /*UniqueIdentifier=*/"", /*Specification=*/nullptr, + /*NumExtraInhabitants=*/0, Annotations); QualType QTy(Ty, 0); TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl); diff --git a/clang/test/DebugInfo/ObjC/objc-runtime-name.m b/clang/test/DebugInfo/ObjC/objc-runtime-name.m new file mode 100644 index 00000000000000..1102969e757992 --- /dev/null +++ b/clang/test/DebugInfo/ObjC/objc-runtime-name.m @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o %t.ll +// RUN: FileCheck %s < %t.ll +// RUN: FileCheck %s --check-prefix=ROOT < %t.ll +// RUN: FileCheck %s --check-prefix=SAME < %t.ll + +// The Objective-C runtime name of a class is recorded in the debug info when +// it diff ers from the source name. + +__attribute__((objc_root_class)) +@interface Root +@end + +@implementation Root +@end + +__attribute__((objc_runtime_name("_$s4main7DefinedC"))) +@interface Defined : Root +@end + +@implementation Defined +@end + +// A class implemented in another TU, such as a Swift class declared in a +// generated header, is completed at the end of the TU and must carry the +// runtime name as well. +__attribute__((objc_runtime_name("_$s4main8DeclaredC"))) +@interface Declared : Root +@end + +Declared *d; + +__attribute__((objc_runtime_name("Same"))) +@interface Same : Root +@end + +@implementation Same +@end + +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Defined",{{.*}}annotations: ![[DEFINED:[0-9]+]] +// CHECK-DAG: ![[DEFINED]] = !{![[DEFINED_NAME:[0-9]+]]} +// CHECK-DAG: ![[DEFINED_NAME]] = !{!"objc_runtime_name", !"_$s4main7DefinedC"} +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Declared",{{.*}}annotations: ![[DECLARED:[0-9]+]] +// CHECK-DAG: ![[DECLARED]] = !{![[DECLARED_NAME:[0-9]+]]} +// CHECK-DAG: ![[DECLARED_NAME]] = !{!"objc_runtime_name", !"_$s4main8DeclaredC"} + +// ROOT: !DICompositeType(tag: DW_TAG_structure_type, name: "Root", +// ROOT-NOT: annotations: +// ROOT-SAME: {{$}} + +// SAME: !DICompositeType(tag: DW_TAG_structure_type, name: "Same", +// SAME-NOT: annotations: +// SAME-SAME: {{$}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
