Skip to content

Commit b4c56cb

Browse files
committed
[clang][DebugInfo][gmodules] Set runtimeLang on ObjC forward declarations
In Objective-C, forward declarations are currently represented as: ``` DW_TAG_structure_type DW_AT_name ("Foo") DW_AT_declaration (true) DW_AT_APPLE_runtime_class (DW_LANG_ObjC) ``` However, when compiling with `-gmodules`, when a class definition is turned into a forward declaration within a `DW_TAG_module`, the DIE for the forward declaration looks as follows: ``` DW_TAG_structure_type DW_AT_name ("Foo") DW_AT_declaration (true) ``` Note the absence of `DW_AT_APPLE_runtime_class`. With recent changes in LLDB, not being able to differentiate between C++ and Objective-C forward declarations has become problematic (see attached test-case and explanation in #119860).
1 parent fbbf1be commit b4c56cb

File tree

4 files changed

+43
-6
lines changed

4 files changed

+43
-6
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -2995,20 +2995,21 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
29952995
if (!ID)
29962996
return nullptr;
29972997

2998+
auto RuntimeLang =
2999+
static_cast<llvm::dwarf::SourceLanguage>(TheCU->getSourceLanguage());
3000+
29983001
// Return a forward declaration if this type was imported from a clang module,
29993002
// and this is not the compile unit with the implementation of the type (which
30003003
// may contain hidden ivars).
30013004
if (DebugTypeExtRefs && ID->isFromASTFile() && ID->getDefinition() &&
30023005
!ID->getImplementation())
3003-
return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
3004-
ID->getName(),
3005-
getDeclContextDescriptor(ID), Unit, 0);
3006+
return DBuilder.createForwardDecl(
3007+
llvm::dwarf::DW_TAG_structure_type, ID->getName(),
3008+
getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
30063009

30073010
// Get overall information about the record type for the debug info.
30083011
llvm::DIFile *DefUnit = getOrCreateFile(ID->getLocation());
30093012
unsigned Line = getLineNumber(ID->getLocation());
3010-
auto RuntimeLang =
3011-
static_cast<llvm::dwarf::SourceLanguage>(TheCU->getSourceLanguage());
30123013

30133014
// If this is just a forward declaration return a special forward-declaration
30143015
// debug type since we won't be able to lay out the entire type.

clang/test/Modules/ExtDebugInfo.m

+2-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ int foo(ObjCClass *c) {
7575

7676
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClass",
7777
// CHECK-SAME: scope: ![[MOD]],
78-
// CHECK-SAME: flags: DIFlagFwdDecl)
78+
// CHECK-SAME: flags: DIFlagFwdDecl,
79+
// CHECK-SAME: runtimeLang: DW_LANG_ObjC)
7980

8081
// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type,
8182
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,

clang/test/Modules/ModuleDebugInfo.m

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "FwdDecl",
4141
// CHECK-SAME: scope: ![[MODULE]],
42+
// CHECK-SAME: runtimeLang: DW_LANG_ObjC
4243

4344
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClass",
4445
// CHECK-SAME: scope: ![[MODULE]],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# REQUIRES: system-darwin
2+
3+
# Test that we can set a breakpoint in a method of a class extension.
4+
# This requires us to parse the method into an AST type, and the context
5+
# too (which in DWARF is just a forward declaration).
6+
#
7+
# RUN: split-file %s %t
8+
# RUN: %clangxx_host %t/lib.m -c -g -gmodules -fmodules -o %t/lib.o
9+
# RUN: %clangxx_host %t/main.m -g -gmodules -fmodules %t/lib.o -o %t/a.out -framework Foundation
10+
#
11+
# RUN: %lldb %t/a.out -o "breakpoint set -f lib.m -l 6" -o exit | FileCheck %s
12+
13+
# CHECK: (lldb) breakpoint set -f lib.m -l 6
14+
# CHECK: Breakpoint 1: where = a.out`-[NSObject(Foo) func]
15+
16+
#--- main.m
17+
int main() {
18+
return 0;
19+
}
20+
21+
#--- lib.m
22+
#import <Foundation/Foundation.h>
23+
24+
@implementation NSObject (Foo)
25+
- (NSError *)func {
26+
NSLog(@"Hello, World!");
27+
return 0;
28+
}
29+
@end
30+
31+
NSObject * func() {
32+
return 0;
33+
}
34+

0 commit comments

Comments
 (0)