Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bec3af6

Browse files
authored
Merge pull request swiftlang#2240 from apple/🍒/bastille/406ad187486b
[lldb/DataFormatters] Display null C++ pointers as nullptr
2 parents 8711013 + 5098f0e commit bec3af6

File tree

14 files changed

+61
-23
lines changed

14 files changed

+61
-23
lines changed

lldb/include/lldb/Target/Language.h

+4
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ class Language : public PluginInterface {
211211
// nil/null object, this method returns true
212212
virtual bool IsNilReference(ValueObject &valobj);
213213

214+
/// Returns the summary string for ValueObjects for which IsNilReference() is
215+
/// true.
216+
virtual llvm::StringRef GetNilReferenceSummaryString() { return {}; }
217+
214218
// for a ValueObject of some "reference type", if the language provides a
215219
// technique to decide whether the reference has ever been assigned to some
216220
// object, this method will return true if such detection is possible, and if

lldb/source/DataFormatters/ValueObjectPrinter.cpp

+30-17
Original file line numberDiff line numberDiff line change
@@ -355,22 +355,33 @@ void ValueObjectPrinter::GetValueSummaryError(std::string &value,
355355
if (err_cstr)
356356
error.assign(err_cstr);
357357

358-
if (ShouldPrintValueObject()) {
359-
if (IsNil())
360-
summary.assign("nil");
361-
else if (IsUninitialized())
362-
summary.assign("<uninitialized>");
363-
else if (m_options.m_omit_summary_depth == 0) {
364-
TypeSummaryImpl *entry = GetSummaryFormatter();
365-
if (entry)
366-
m_valobj->GetSummaryAsCString(entry, summary,
367-
m_options.m_varformat_language);
368-
else {
369-
const char *sum_cstr =
370-
m_valobj->GetSummaryAsCString(m_options.m_varformat_language);
371-
if (sum_cstr)
372-
summary.assign(sum_cstr);
373-
}
358+
if (!ShouldPrintValueObject())
359+
return;
360+
361+
if (IsNil()) {
362+
lldb::LanguageType lang_type =
363+
(m_options.m_varformat_language == lldb::eLanguageTypeUnknown)
364+
? m_valobj->GetPreferredDisplayLanguage()
365+
: m_options.m_varformat_language;
366+
if (Language *lang_plugin = Language::FindPlugin(lang_type)) {
367+
summary.assign(lang_plugin->GetNilReferenceSummaryString().str());
368+
} else {
369+
// We treat C as the fallback language rather than as a separate Language
370+
// plugin.
371+
summary.assign("NULL");
372+
}
373+
} else if (IsUninitialized()) {
374+
summary.assign("<uninitialized>");
375+
} else if (m_options.m_omit_summary_depth == 0) {
376+
TypeSummaryImpl *entry = GetSummaryFormatter();
377+
if (entry) {
378+
m_valobj->GetSummaryAsCString(entry, summary,
379+
m_options.m_varformat_language);
380+
} else {
381+
const char *sum_cstr =
382+
m_valobj->GetSummaryAsCString(m_options.m_varformat_language);
383+
if (sum_cstr)
384+
summary.assign(sum_cstr);
374385
}
375386
}
376387
}
@@ -403,7 +414,9 @@ bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool &value_printed,
403414
// this thing is nil (but show the value if the user passes a format
404415
// explicitly)
405416
TypeSummaryImpl *entry = GetSummaryFormatter();
406-
if (!IsNil() && !IsUninitialized() && !m_value.empty() &&
417+
const bool has_nil_or_uninitialized_summary =
418+
(IsNil() || IsUninitialized()) && !m_summary.empty();
419+
if (!has_nil_or_uninitialized_summary && !m_value.empty() &&
407420
(entry == nullptr ||
408421
(entry->DoesPrintValue(m_valobj) ||
409422
m_options.m_format != eFormatDefault) ||

lldb/source/Expression/UserExpression.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
358358
} else {
359359
if (expr_result) {
360360
result_valobj_sp = expr_result->GetValueObject();
361+
result_valobj_sp->SetPreferredDisplayLanguage(language);
361362

362363
LLDB_LOG(log,
363364
"== [UserExpression::Evaluate] Execution completed "

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,15 @@ CPlusPlusLanguage::GetHardcodedSynthetics() {
11351135
return g_formatters;
11361136
}
11371137

1138+
bool CPlusPlusLanguage::IsNilReference(ValueObject &valobj) {
1139+
if (!Language::LanguageIsCPlusPlus(valobj.GetObjectRuntimeLanguage()) ||
1140+
!valobj.IsPointerType())
1141+
return false;
1142+
bool canReadValue = true;
1143+
bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
1144+
return canReadValue && isZero;
1145+
}
1146+
11381147
bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
11391148
const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c",
11401149
".h", ".hh", ".hpp", ".hxx", ".h++"};

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h

+4
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ class CPlusPlusLanguage : public Language {
8888
HardcodedFormatters::HardcodedSyntheticFinder
8989
GetHardcodedSynthetics() override;
9090

91+
bool IsNilReference(ValueObject &valobj) override;
92+
93+
llvm::StringRef GetNilReferenceSummaryString() override { return "nullptr"; }
94+
9195
bool IsSourceFile(llvm::StringRef file_path) const override;
9296

9397
const Highlighter *GetHighlighter() const override { return &m_highlighter; }

lldb/source/Plugins/Language/ObjC/ObjCLanguage.h

+2
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ class ObjCLanguage : public Language {
119119

120120
bool IsNilReference(ValueObject &valobj) override;
121121

122+
llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
123+
122124
bool IsSourceFile(llvm::StringRef file_path) const override;
123125

124126
const Highlighter *GetHighlighter() const override { return &m_highlighter; }

lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class ObjCPlusPlusLanguage : public Language {
2727
return lldb::eLanguageTypeObjC_plus_plus;
2828
}
2929

30+
llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
31+
3032
bool IsSourceFile(llvm::StringRef file_path) const override;
3133

3234
const Highlighter *GetHighlighter() const override { return &m_highlighter; }

lldb/test/API/commands/expression/import-std-module/forward_decl_from_module/TestForwardDeclFromStdModule.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ def test(self):
3939
# Both `std::vector` and the type of the member have forward
4040
# declarations before their definitions.
4141
self.expect("expr --raw -- v",
42-
substrs=['(std::__1::vector<int>) $0 = {', 'f = 0x', '}'])
42+
substrs=['(std::__1::vector<int>) $0 = {', 'f = nullptr', '}'])

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py

+2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def cleanup():
7777
'(%s::u32string) u32_empty = ""'%ns,
7878
'(%s::basic_string<unsigned char, %s::char_traits<unsigned char>, '
7979
'%s::allocator<unsigned char> >) uchar = "aaaaa"'%(ns,ns,ns),
80+
'(%s::string *) null_str = nullptr'%ns,
8081
])
8182

8283
self.runCmd("n")
@@ -114,6 +115,7 @@ def cleanup():
114115
'(%s::u32string) u32_empty = ""'%ns,
115116
'(%s::basic_string<unsigned char, %s::char_traits<unsigned char>, '
116117
'%s::allocator<unsigned char> >) uchar = "aaaaa"'%(ns,ns,ns),
118+
'(%s::string *) null_str = nullptr'%ns,
117119
])
118120

119121
# The test assumes that std::string is in its cap-size-data layout.

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ int main()
7474
std::u32string u32_string(U"🍄🍅🍆🍌");
7575
std::u32string u32_empty(U"");
7676
std::basic_string<unsigned char> uchar(5, 'a');
77+
std::string *null_str = nullptr;
7778

7879
#if _LIBCPP_ABI_VERSION == 1
7980
std::string garbage1, garbage2, garbage3, garbage4, garbage5;

lldb/test/API/lang/c/anonymous/TestAnonymous.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def test_expr_parent(self):
6262

6363
# These should display correctly.
6464
self.expect("expression pz", VARIABLES_DISPLAYED_CORRECTLY,
65-
substrs=["(type_z *) $", " = 0x0000"])
65+
substrs=["(type_z *) $", " = NULL"])
6666

6767
self.expect("expression z.y", VARIABLES_DISPLAYED_CORRECTLY,
6868
substrs=["(type_y) $", "dummy = 2"])

lldb/test/API/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py renamed to lldb/test/API/lang/objcxx/objc-builtin-types/TestObjCBuiltinTypes.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
"""Test that the expression parser doesn't get confused by 'id' and 'Class'"""
22

3-
4-
53
import lldb
64
from lldbsuite.test.decorators import *
75
from lldbsuite.test.lldbtest import *
@@ -22,7 +20,6 @@ def setUp(self):
2220

2321
@skipUnlessDarwin
2422
@add_test_categories(['pyapi'])
25-
#<rdar://problem/10591460> [regression] Can't print ivar value: error: reference to 'id' is ambiguous
2623
def test_with_python_api(self):
2724
"""Test expression parser respect for ObjC built-in types."""
2825
self.build()
@@ -58,4 +55,7 @@ def test_with_python_api(self):
5855

5956
self.expect("expr (foo)", patterns=["\(ns::id\) \$.* = 0"])
6057

61-
self.expect("expr id my_id = 0; my_id", patterns=["\(id\) \$.* = nil"])
58+
self.expect("expr --language Objective-C++ -- id my_id = 0; my_id",
59+
patterns=["\(id\) \$.* = nil"])
60+
self.expect("expr --language C++ -- id my_id = 0; my_id",
61+
patterns=["\(id\) \$.* = nullptr"])

0 commit comments

Comments
 (0)