diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 60f32f76109e9..ff27690d47b08 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2995,20 +2995,21 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, if (!ID) return nullptr; + auto RuntimeLang = + static_cast(TheCU->getSourceLanguage()); + // Return a forward declaration if this type was imported from a clang module, // and this is not the compile unit with the implementation of the type (which // may contain hidden ivars). if (DebugTypeExtRefs && ID->isFromASTFile() && ID->getDefinition() && !ID->getImplementation()) - return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, - ID->getName(), - getDeclContextDescriptor(ID), Unit, 0); + return DBuilder.createForwardDecl( + llvm::dwarf::DW_TAG_structure_type, ID->getName(), + getDeclContextDescriptor(ID), Unit, 0, RuntimeLang); // Get overall information about the record type for the debug info. llvm::DIFile *DefUnit = getOrCreateFile(ID->getLocation()); unsigned Line = getLineNumber(ID->getLocation()); - auto RuntimeLang = - static_cast(TheCU->getSourceLanguage()); // If this is just a forward declaration return a special forward-declaration // debug type since we won't be able to lay out the entire type. diff --git a/clang/test/Modules/ExtDebugInfo.m b/clang/test/Modules/ExtDebugInfo.m index b6a8b2676e5ba..e2611ae530063 100644 --- a/clang/test/Modules/ExtDebugInfo.m +++ b/clang/test/Modules/ExtDebugInfo.m @@ -75,7 +75,8 @@ int foo(ObjCClass *c) { // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClass", // CHECK-SAME: scope: ![[MOD]], -// CHECK-SAME: flags: DIFlagFwdDecl) +// CHECK-SAME: flags: DIFlagFwdDecl, +// CHECK-SAME: runtimeLang: DW_LANG_ObjC) // CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, diff --git a/clang/test/Modules/ModuleDebugInfo.m b/clang/test/Modules/ModuleDebugInfo.m index 62c6fd68dd854..c527c43a0f4a2 100644 --- a/clang/test/Modules/ModuleDebugInfo.m +++ b/clang/test/Modules/ModuleDebugInfo.m @@ -39,6 +39,7 @@ // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "FwdDecl", // CHECK-SAME: scope: ![[MODULE]], +// CHECK-SAME: runtimeLang: DW_LANG_ObjC // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClass", // CHECK-SAME: scope: ![[MODULE]], diff --git a/lldb/test/Shell/SymbolFile/DWARF/objc-gmodules-class-extension.test b/lldb/test/Shell/SymbolFile/DWARF/objc-gmodules-class-extension.test new file mode 100644 index 0000000000000..b829039501072 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/objc-gmodules-class-extension.test @@ -0,0 +1,29 @@ +# REQUIRES: system-darwin + +# Test that we can set a breakpoint in a method of a class extension. +# This requires us to parse the method into an AST type, and the context +# too (which in DWARF is just a forward declaration). +# +# RUN: split-file %s %t +# RUN: %clangxx_host %t/lib.m -c -g -gmodules -fmodules -o %t/lib.o +# RUN: %clangxx_host %t/main.m -g -gmodules -fmodules %t/lib.o -o %t/a.out -framework Foundation +# +# RUN: %lldb %t/a.out -o "breakpoint set -f lib.m -l 6" -o exit | FileCheck %s + +# CHECK: (lldb) breakpoint set -f lib.m -l 6 +# CHECK: Breakpoint 1: where = a.out`-[NSObject(Foo) func] + +#--- main.m +int main() { + return 0; +} + +#--- lib.m +#import + +@implementation NSObject (Foo) +- (NSError *)func { + NSLog(@"Hello, World!"); + return 0; +} +@end