Coverage Report

Created: 2022-01-15 10:30

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- CxxStringTypes.cpp ------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "CxxStringTypes.h"
10
11
#include "llvm/Support/ConvertUTF.h"
12
13
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
14
#include "lldb/Core/ValueObject.h"
15
#include "lldb/Core/ValueObjectConstResult.h"
16
#include "lldb/DataFormatters/FormattersHelpers.h"
17
#include "lldb/DataFormatters/StringPrinter.h"
18
#include "lldb/DataFormatters/TypeSummary.h"
19
#include "lldb/Host/Time.h"
20
#include "lldb/Target/ProcessStructReader.h"
21
#include "lldb/Target/SectionLoadList.h"
22
#include "lldb/Target/Target.h"
23
#include "lldb/Target/Thread.h"
24
#include "lldb/Utility/DataBufferHeap.h"
25
#include "lldb/Utility/Endian.h"
26
#include "lldb/Utility/Status.h"
27
#include "lldb/Utility/Stream.h"
28
29
#include <algorithm>
30
31
using namespace lldb;
32
using namespace lldb_private;
33
using namespace lldb_private::formatters;
34
35
using StringElementType = StringPrinter::StringElementType;
36
37
static constexpr std::pair<const char *, Format>
38
90
getElementTraits(StringElementType ElemType) {
39
90
  switch (ElemType) {
40
33
  case StringElementType::UTF8:
41
33
    return std::make_pair("u8", lldb::eFormatUnicode8);
42
27
  case StringElementType::UTF16:
43
27
    return std::make_pair("u", lldb::eFormatUnicode16);
44
30
  case StringElementType::UTF32:
45
30
    return std::make_pair("U", lldb::eFormatUnicode32);
46
0
  default:
47
0
    return std::make_pair(nullptr, lldb::eFormatInvalid);
48
90
  }
49
90
}
50
51
template <StringElementType ElemType>
52
93
static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
53
93
  Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
54
93
  if (!valobj_addr.IsValid())
55
3
    return false;
56
57
90
  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
58
90
  options.SetLocation(valobj_addr);
59
90
  options.SetTargetSP(valobj.GetTargetSP());
60
90
  options.SetStream(&stream);
61
90
  options.SetPrefixToken(getElementTraits(ElemType).first);
62
63
90
  if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options))
64
3
    stream.Printf("Summary Unavailable");
65
66
90
  return true;
67
93
}
CxxStringTypes.cpp:bool CharStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)1>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
52
36
static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
53
36
  Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
54
36
  if (!valobj_addr.IsValid())
55
3
    return false;
56
57
33
  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
58
33
  options.SetLocation(valobj_addr);
59
33
  options.SetTargetSP(valobj.GetTargetSP());
60
33
  options.SetStream(&stream);
61
33
  options.SetPrefixToken(getElementTraits(ElemType).first);
62
63
33
  if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options))
64
0
    stream.Printf("Summary Unavailable");
65
66
33
  return true;
67
36
}
CxxStringTypes.cpp:bool CharStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)2>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
52
27
static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
53
27
  Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
54
27
  if (!valobj_addr.IsValid())
55
0
    return false;
56
57
27
  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
58
27
  options.SetLocation(valobj_addr);
59
27
  options.SetTargetSP(valobj.GetTargetSP());
60
27
  options.SetStream(&stream);
61
27
  options.SetPrefixToken(getElementTraits(ElemType).first);
62
63
27
  if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options))
64
0
    stream.Printf("Summary Unavailable");
65
66
27
  return true;
67
27
}
CxxStringTypes.cpp:bool CharStringSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)3>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
52
30
static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) {
53
30
  Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
54
30
  if (!valobj_addr.IsValid())
55
0
    return false;
56
57
30
  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
58
30
  options.SetLocation(valobj_addr);
59
30
  options.SetTargetSP(valobj.GetTargetSP());
60
30
  options.SetStream(&stream);
61
30
  options.SetPrefixToken(getElementTraits(ElemType).first);
62
63
30
  if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options))
64
3
    stream.Printf("Summary Unavailable");
65
66
30
  return true;
67
30
}
68
69
template <StringElementType ElemType>
70
444
static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
71
444
  DataExtractor data;
72
444
  Status error;
73
444
  valobj.GetData(data, error);
74
75
444
  if (error.Fail())
76
0
    return false;
77
78
444
  std::string value;
79
444
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
80
81
444
  constexpr auto ElemTraits = getElementTraits(ElemType);
82
444
  valobj.GetValueAsCString(ElemTraits.second, value);
83
84
444
  if (!value.empty())
85
444
    stream.Printf("%s ", value.c_str());
86
87
444
  options.SetData(std::move(data));
88
444
  options.SetStream(&stream);
89
444
  options.SetPrefixToken(ElemTraits.first);
90
444
  options.SetQuote('\'');
91
444
  options.SetSourceSize(1);
92
444
  options.SetBinaryZeroIsTerminator(false);
93
94
444
  return StringPrinter::ReadBufferAndDumpToStream<ElemType>(options);
95
444
}
CxxStringTypes.cpp:bool CharSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)1>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
70
48
static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
71
48
  DataExtractor data;
72
48
  Status error;
73
48
  valobj.GetData(data, error);
74
75
48
  if (error.Fail())
76
0
    return false;
77
78
48
  std::string value;
79
48
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
80
81
48
  constexpr auto ElemTraits = getElementTraits(ElemType);
82
48
  valobj.GetValueAsCString(ElemTraits.second, value);
83
84
48
  if (!value.empty())
85
48
    stream.Printf("%s ", value.c_str());
86
87
48
  options.SetData(std::move(data));
88
48
  options.SetStream(&stream);
89
48
  options.SetPrefixToken(ElemTraits.first);
90
48
  options.SetQuote('\'');
91
48
  options.SetSourceSize(1);
92
48
  options.SetBinaryZeroIsTerminator(false);
93
94
48
  return StringPrinter::ReadBufferAndDumpToStream<ElemType>(options);
95
48
}
CxxStringTypes.cpp:bool CharSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)2>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
70
375
static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
71
375
  DataExtractor data;
72
375
  Status error;
73
375
  valobj.GetData(data, error);
74
75
375
  if (error.Fail())
76
0
    return false;
77
78
375
  std::string value;
79
375
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
80
81
375
  constexpr auto ElemTraits = getElementTraits(ElemType);
82
375
  valobj.GetValueAsCString(ElemTraits.second, value);
83
84
375
  if (!value.empty())
85
375
    stream.Printf("%s ", value.c_str());
86
87
375
  options.SetData(std::move(data));
88
375
  options.SetStream(&stream);
89
375
  options.SetPrefixToken(ElemTraits.first);
90
375
  options.SetQuote('\'');
91
375
  options.SetSourceSize(1);
92
375
  options.SetBinaryZeroIsTerminator(false);
93
94
375
  return StringPrinter::ReadBufferAndDumpToStream<ElemType>(options);
95
375
}
CxxStringTypes.cpp:bool CharSummaryProvider<(lldb_private::formatters::StringPrinter::StringElementType)3>(lldb_private::ValueObject&, lldb_private::Stream&)
Line
Count
Source
70
21
static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) {
71
21
  DataExtractor data;
72
21
  Status error;
73
21
  valobj.GetData(data, error);
74
75
21
  if (error.Fail())
76
0
    return false;
77
78
21
  std::string value;
79
21
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
80
81
21
  constexpr auto ElemTraits = getElementTraits(ElemType);
82
21
  valobj.GetValueAsCString(ElemTraits.second, value);
83
84
21
  if (!value.empty())
85
21
    stream.Printf("%s ", value.c_str());
86
87
21
  options.SetData(std::move(data));
88
21
  options.SetStream(&stream);
89
21
  options.SetPrefixToken(ElemTraits.first);
90
21
  options.SetQuote('\'');
91
21
  options.SetSourceSize(1);
92
21
  options.SetBinaryZeroIsTerminator(false);
93
94
21
  return StringPrinter::ReadBufferAndDumpToStream<ElemType>(options);
95
21
}
96
97
bool lldb_private::formatters::Char8StringSummaryProvider(
98
36
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
99
36
  return CharStringSummaryProvider<StringElementType::UTF8>(valobj, stream);
100
36
}
101
102
bool lldb_private::formatters::Char16StringSummaryProvider(
103
27
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
104
27
  return CharStringSummaryProvider<StringElementType::UTF16>(valobj, stream);
105
27
}
106
107
bool lldb_private::formatters::Char32StringSummaryProvider(
108
30
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
109
30
  return CharStringSummaryProvider<StringElementType::UTF32>(valobj, stream);
110
30
}
111
112
bool lldb_private::formatters::WCharStringSummaryProvider(
113
23
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
114
23
  Address valobj_addr = GetArrayAddressOrPointerValue(valobj);
115
23
  if (!valobj_addr.IsValid())
116
0
    return false;
117
118
  // Get a wchar_t basic type from the current type system
119
23
  CompilerType wchar_compiler_type =
120
23
      valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
121
122
23
  if (!wchar_compiler_type)
123
0
    return false;
124
125
  // Safe to pass nullptr for exe_scope here.
126
23
  llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
127
23
  if (!size)
128
0
    return false;
129
23
  const uint32_t wchar_size = *size;
130
131
23
  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
132
23
  options.SetLocation(valobj_addr);
133
23
  options.SetTargetSP(valobj.GetTargetSP());
134
23
  options.SetStream(&stream);
135
23
  options.SetPrefixToken("L");
136
137
23
  switch (wchar_size) {
138
0
  case 8:
139
0
    return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF8>(
140
0
        options);
141
0
  case 16:
142
0
    return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF16>(
143
0
        options);
144
23
  case 32:
145
23
    return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF32>(
146
23
        options);
147
0
  default:
148
0
    stream.Printf("size for wchar_t is not valid");
149
0
    return true;
150
23
  }
151
0
  return true;
152
23
}
153
154
bool lldb_private::formatters::Char8SummaryProvider(
155
48
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
156
48
  return CharSummaryProvider<StringElementType::UTF8>(valobj, stream);
157
48
}
158
159
bool lldb_private::formatters::Char16SummaryProvider(
160
375
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
161
375
  return CharSummaryProvider<StringElementType::UTF16>(valobj, stream);
162
375
}
163
164
bool lldb_private::formatters::Char32SummaryProvider(
165
21
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
166
21
  return CharSummaryProvider<StringElementType::UTF32>(valobj, stream);
167
21
}
168
169
bool lldb_private::formatters::WCharSummaryProvider(
170
21
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
171
21
  DataExtractor data;
172
21
  Status error;
173
21
  valobj.GetData(data, error);
174
175
21
  if (error.Fail())
176
0
    return false;
177
178
  // Get a wchar_t basic type from the current type system
179
21
  CompilerType wchar_compiler_type =
180
21
      valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
181
182
21
  if (!wchar_compiler_type)
183
0
    return false;
184
185
    // Safe to pass nullptr for exe_scope here.
186
21
  llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
187
21
  if (!size)
188
0
    return false;
189
21
  const uint32_t wchar_size = *size;
190
191
21
  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
192
21
  options.SetData(std::move(data));
193
21
  options.SetStream(&stream);
194
21
  options.SetPrefixToken("L");
195
21
  options.SetQuote('\'');
196
21
  options.SetSourceSize(1);
197
21
  options.SetBinaryZeroIsTerminator(false);
198
199
21
  switch (wchar_size) {
200
0
  case 8:
201
0
    return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF8>(
202
0
        options);
203
0
  case 16:
204
0
    return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF16>(
205
0
        options);
206
21
  case 32:
207
21
    return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF32>(
208
21
        options);
209
0
  default:
210
0
    stream.Printf("size for wchar_t is not valid");
211
0
    return true;
212
21
  }
213
0
  return true;
214
21
}