Skip to content

Commit 16753ee

Browse files
authored
Merge pull request #10313 from swiftlang/lldb/mixed-objcxx-decls-to-20240723
[lldb][DWARFASTParserClang] Don't complete conflicting Objective-C++ types
2 parents e5e1999 + cfc8aab commit 16753ee

File tree

2 files changed

+87
-3
lines changed

2 files changed

+87
-3
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "lldb/Utility/LLDBAssert.h"
4141
#include "lldb/Utility/Log.h"
4242
#include "lldb/Utility/StreamString.h"
43+
#include "lldb/lldb-enumerations.h"
4344

4445
#include "clang/AST/CXXInheritance.h"
4546
#include "clang/AST/Decl.h"
@@ -2204,6 +2205,22 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
22042205
if (attrs.is_forward_declaration)
22052206
return true;
22062207

2208+
const bool type_is_objc_object_or_interface =
2209+
TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type);
2210+
if (!type_is_objc_object_or_interface &&
2211+
Language::LanguageIsObjC(
2212+
static_cast<LanguageType>(die.GetAttributeValueAsUnsigned(
2213+
DW_AT_APPLE_runtime_class, eLanguageTypeUnknown)))) {
2214+
// The forward declaration was C++ but the definition is Objective-C.
2215+
// We currently don't handle such situations. Keep the forward declaration
2216+
// without a definition.
2217+
LLDB_LOG(GetLog(LLDBLog::Expressions),
2218+
"WARNING: Type completion aborted because forward declaration for "
2219+
"'{0}' is C++ while definition is Objective-C.",
2220+
attrs.name.AsCString(""));
2221+
return false;
2222+
}
2223+
22072224
clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE(die, nullptr);
22082225

22092226
// Start the definition if the type is not being defined already. This can
@@ -2231,9 +2248,6 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
22312248
default_accessibility, layout_info);
22322249

22332250
// Now parse any methods if there were any...
2234-
const bool type_is_objc_object_or_interface =
2235-
TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type);
2236-
// Now parse any methods if there were any...
22372251
for (const DWARFDIE &mem : member_function_dies)
22382252
dwarf->ResolveType(mem);
22392253

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# REQUIRES: system-darwin
2+
3+
# In this test we have two CUs with conflicting forward declaration
4+
# depending on the CU language (one is C++ and the other is Objective-C++).
5+
# We are then stopped in the C++ CU and try to print the type, at which
6+
# point LLDB will try to make it into an Clang AST node. If LLDB were to
7+
# interpret the type as C++ instead of Objective-C, we'd violate Clang
8+
# invariants and crash.
9+
#
10+
# RUN: split-file %s %t
11+
# RUN: %clangxx_host -c -g -x objective-c++ %t/request.m -o %t/request_objc.o
12+
# RUN: %clangxx_host -c -g %t/main.cpp -o %t/main.o
13+
# RUN: %clangxx_host %t/main.o %t/request_objc.o -framework Foundation -o %t/a.out
14+
#
15+
# RUN: %lldb %t/a.out \
16+
# RUN: -o "breakpoint set -p return -X main" \
17+
# RUN: -o run \
18+
# RUN: -o "frame variable r" \
19+
# RUN: -o exit | FileCheck %s
20+
#
21+
# RUN: dsymutil %t/a.out
22+
#
23+
# RUN: %lldb %t/a.out \
24+
# RUN: -o "breakpoint set -p return -X main" \
25+
# RUN: -o run \
26+
# RUN: -o "frame variable r" \
27+
# RUN: -o exit | FileCheck %s --check-prefix=CHECK-DSYM
28+
29+
# CHECK: (lldb) frame variable r
30+
# CHECK-NEXT: (Request) ::r = (m_request = "Hello, World!")
31+
32+
# CHECK-DSYM: (lldb) frame variable r
33+
# CHECK-DSYM-NEXT: (Request) ::r = (m_request = "Hello, World!")
34+
35+
#--- lib.h
36+
#ifndef LIB_H_IN
37+
#define LIB_H_IN
38+
39+
#ifdef __OBJC__
40+
@class NSString;
41+
#else
42+
class NSString;
43+
#endif
44+
45+
struct Request {
46+
NSString * m_request = nullptr;
47+
};
48+
49+
#endif // _H_IN
50+
51+
#--- main.cpp
52+
#include "lib.h"
53+
54+
void process(Request *);
55+
56+
Request r;
57+
58+
int main() {
59+
process(&r);
60+
return 0;
61+
}
62+
63+
#--- request.m
64+
#import <Foundation/Foundation.h>
65+
66+
#include "lib.h"
67+
68+
void process(Request * r) {
69+
r->m_request = @"Hello, World!";
70+
}

0 commit comments

Comments
 (0)