/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/DataFormatters/FormatClasses.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- FormatClasses.h -----------------------------------------*- C++ -*-===// |
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 | | #ifndef LLDB_DATAFORMATTERS_FORMATCLASSES_H |
10 | | #define LLDB_DATAFORMATTERS_FORMATCLASSES_H |
11 | | |
12 | | #include <functional> |
13 | | #include <memory> |
14 | | #include <string> |
15 | | #include <vector> |
16 | | |
17 | | #include "lldb/DataFormatters/TypeFormat.h" |
18 | | #include "lldb/DataFormatters/TypeSummary.h" |
19 | | #include "lldb/DataFormatters/TypeSynthetic.h" |
20 | | #include "lldb/Interpreter/ScriptInterpreter.h" |
21 | | #include "lldb/Symbol/CompilerType.h" |
22 | | #include "lldb/Symbol/Type.h" |
23 | | #include "lldb/lldb-enumerations.h" |
24 | | #include "lldb/lldb-public.h" |
25 | | |
26 | | namespace lldb_private { |
27 | | |
28 | | class HardcodedFormatters { |
29 | | public: |
30 | | template <typename FormatterType> |
31 | | using HardcodedFormatterFinder = |
32 | | std::function<typename FormatterType::SharedPointer( |
33 | | lldb_private::ValueObject &, lldb::DynamicValueType, |
34 | | FormatManager &)>; |
35 | | |
36 | | template <typename FormatterType> |
37 | | using HardcodedFormatterFinders = |
38 | | std::vector<HardcodedFormatterFinder<FormatterType>>; |
39 | | |
40 | | typedef HardcodedFormatterFinders<TypeFormatImpl> HardcodedFormatFinder; |
41 | | typedef HardcodedFormatterFinders<TypeSummaryImpl> HardcodedSummaryFinder; |
42 | | typedef HardcodedFormatterFinders<SyntheticChildren> HardcodedSyntheticFinder; |
43 | | }; |
44 | | |
45 | | class FormattersMatchCandidate { |
46 | | public: |
47 | | // Contains flags to indicate how this candidate was generated (e.g. if |
48 | | // typedefs were stripped, or pointers were skipped). These are later compared |
49 | | // to flags in formatters to confirm a string match. |
50 | | struct Flags { |
51 | | bool stripped_pointer = false; |
52 | | bool stripped_reference = false; |
53 | | bool stripped_typedef = false; |
54 | | |
55 | | // Returns a copy of this with the "stripped pointer" flag set. |
56 | 8.81k | Flags WithStrippedPointer() { |
57 | 8.81k | Flags result(*this); |
58 | 8.81k | result.stripped_pointer = true; |
59 | 8.81k | return result; |
60 | 8.81k | } |
61 | | |
62 | | // Returns a copy of this with the "stripped reference" flag set. |
63 | 584 | Flags WithStrippedReference() { |
64 | 584 | Flags result(*this); |
65 | 584 | result.stripped_reference = true; |
66 | 584 | return result; |
67 | 584 | } |
68 | | |
69 | | // Returns a copy of this with the "stripped typedef" flag set. |
70 | 4.12k | Flags WithStrippedTypedef() { |
71 | 4.12k | Flags result(*this); |
72 | 4.12k | result.stripped_typedef = true; |
73 | 4.12k | return result; |
74 | 4.12k | } |
75 | | }; |
76 | | |
77 | | FormattersMatchCandidate(ConstString name, |
78 | | ScriptInterpreter *script_interpreter, TypeImpl type, |
79 | | Flags flags) |
80 | 37.1k | : m_type_name(name), m_script_interpreter(script_interpreter), |
81 | 37.1k | m_type(type), m_flags(flags) {} |
82 | | |
83 | 3.62M | ~FormattersMatchCandidate() = default; |
84 | | |
85 | 2.67M | ConstString GetTypeName() const { return m_type_name; } |
86 | | |
87 | 44 | TypeImpl GetType() const { return m_type; } |
88 | | |
89 | 88 | ScriptInterpreter *GetScriptInterpreter() const { |
90 | 88 | return m_script_interpreter; |
91 | 88 | } |
92 | | |
93 | 556 | bool DidStripPointer() const { return m_flags.stripped_pointer; } |
94 | | |
95 | 51 | bool DidStripReference() const { return m_flags.stripped_reference; } |
96 | | |
97 | 97 | bool DidStripTypedef() const { return m_flags.stripped_typedef; } |
98 | | |
99 | | template <class Formatter> |
100 | 2.32k | bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const { |
101 | 2.32k | if (!formatter_sp) |
102 | 0 | return false; |
103 | 2.32k | if (formatter_sp->Cascades() == false && DidStripTypedef()97 ) |
104 | 6 | return false; |
105 | 2.32k | if (formatter_sp->SkipsPointers() && DidStripPointer()556 ) |
106 | 272 | return false; |
107 | 2.04k | if (formatter_sp->SkipsReferences() && DidStripReference()51 ) |
108 | 0 | return false; |
109 | 2.04k | return true; |
110 | 2.04k | } bool lldb_private::FormattersMatchCandidate::IsMatch<lldb_private::TypeFormatImpl>(std::__1::shared_ptr<lldb_private::TypeFormatImpl> const&) const Line | Count | Source | 100 | 57 | bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const { | 101 | 57 | if (!formatter_sp) | 102 | 0 | return false; | 103 | 57 | if (formatter_sp->Cascades() == false && DidStripTypedef()15 ) | 104 | 6 | return false; | 105 | 51 | if (formatter_sp->SkipsPointers() && DidStripPointer()2 ) | 106 | 0 | return false; | 107 | 51 | if (formatter_sp->SkipsReferences() && DidStripReference()2 ) | 108 | 0 | return false; | 109 | 51 | return true; | 110 | 51 | } |
bool lldb_private::FormattersMatchCandidate::IsMatch<lldb_private::TypeSummaryImpl>(std::__1::shared_ptr<lldb_private::TypeSummaryImpl> const&) const Line | Count | Source | 100 | 1.72k | bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const { | 101 | 1.72k | if (!formatter_sp) | 102 | 0 | return false; | 103 | 1.72k | if (formatter_sp->Cascades() == false && DidStripTypedef()64 ) | 104 | 0 | return false; | 105 | 1.72k | if (formatter_sp->SkipsPointers() && DidStripPointer()550 ) | 106 | 270 | return false; | 107 | 1.45k | if (formatter_sp->SkipsReferences() && DidStripReference()49 ) | 108 | 0 | return false; | 109 | 1.45k | return true; | 110 | 1.45k | } |
bool lldb_private::FormattersMatchCandidate::IsMatch<lldb_private::TypeFilterImpl>(std::__1::shared_ptr<lldb_private::TypeFilterImpl> const&) const Line | Count | Source | 100 | 62 | bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const { | 101 | 62 | if (!formatter_sp) | 102 | 0 | return false; | 103 | 62 | if (formatter_sp->Cascades() == false && DidStripTypedef()12 ) | 104 | 0 | return false; | 105 | 62 | if (formatter_sp->SkipsPointers() && DidStripPointer()4 ) | 106 | 2 | return false; | 107 | 60 | if (formatter_sp->SkipsReferences() && DidStripReference()0 ) | 108 | 0 | return false; | 109 | 60 | return true; | 110 | 60 | } |
bool lldb_private::FormattersMatchCandidate::IsMatch<lldb_private::SyntheticChildren>(std::__1::shared_ptr<lldb_private::SyntheticChildren> const&) const Line | Count | Source | 100 | 482 | bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const { | 101 | 482 | if (!formatter_sp) | 102 | 0 | return false; | 103 | 482 | if (formatter_sp->Cascades() == false && DidStripTypedef()6 ) | 104 | 0 | return false; | 105 | 482 | if (formatter_sp->SkipsPointers() && DidStripPointer()0 ) | 106 | 0 | return false; | 107 | 482 | if (formatter_sp->SkipsReferences() && DidStripReference()0 ) | 108 | 0 | return false; | 109 | 482 | return true; | 110 | 482 | } |
|
111 | | |
112 | | private: |
113 | | ConstString m_type_name; |
114 | | // If a formatter provides a matching callback function, we need the script |
115 | | // interpreter and the type object (as an argument to the callback). |
116 | | ScriptInterpreter *m_script_interpreter; |
117 | | TypeImpl m_type; |
118 | | Flags m_flags; |
119 | | }; |
120 | | |
121 | | typedef std::vector<FormattersMatchCandidate> FormattersMatchVector; |
122 | | typedef std::vector<lldb::LanguageType> CandidateLanguagesVector; |
123 | | |
124 | | class FormattersMatchData { |
125 | | public: |
126 | | FormattersMatchData(ValueObject &, lldb::DynamicValueType); |
127 | | |
128 | | FormattersMatchVector GetMatchesVector(); |
129 | | |
130 | | ConstString GetTypeForCache(); |
131 | | |
132 | | CandidateLanguagesVector GetCandidateLanguages(); |
133 | | |
134 | | ValueObject &GetValueObject(); |
135 | | |
136 | | lldb::DynamicValueType GetDynamicValueType(); |
137 | | |
138 | | private: |
139 | | ValueObject &m_valobj; |
140 | | lldb::DynamicValueType m_dynamic_value_type; |
141 | | std::pair<FormattersMatchVector, bool> m_formatters_match_vector; |
142 | | ConstString m_type_for_cache; |
143 | | CandidateLanguagesVector m_candidate_languages; |
144 | | }; |
145 | | |
146 | | class TypeNameSpecifierImpl { |
147 | | public: |
148 | | TypeNameSpecifierImpl() = default; |
149 | | |
150 | | TypeNameSpecifierImpl(llvm::StringRef name, |
151 | | lldb::FormatterMatchType match_type) |
152 | 206k | : m_match_type(match_type) { |
153 | 206k | m_type.m_type_name = std::string(name); |
154 | 206k | } |
155 | | |
156 | | // if constructing with a given type, we consider that a case of exact match. |
157 | | TypeNameSpecifierImpl(lldb::TypeSP type) |
158 | 0 | : m_match_type(lldb::eFormatterMatchExact) { |
159 | 0 | if (type) { |
160 | 0 | m_type.m_type_name = std::string(type->GetName().GetStringRef()); |
161 | 0 | m_type.m_compiler_type = type->GetForwardCompilerType(); |
162 | 0 | } |
163 | 0 | } |
164 | | |
165 | | TypeNameSpecifierImpl(CompilerType type) |
166 | 0 | : m_match_type(lldb::eFormatterMatchExact) { |
167 | 0 | if (type.IsValid()) { |
168 | 0 | m_type.m_type_name.assign(type.GetTypeName().GetCString()); |
169 | 0 | m_type.m_compiler_type = type; |
170 | 0 | } |
171 | 0 | } |
172 | | |
173 | 274k | const char *GetName() { |
174 | 274k | if (m_type.m_type_name.size()) |
175 | 274k | return m_type.m_type_name.c_str(); |
176 | 0 | return nullptr; |
177 | 274k | } |
178 | | |
179 | 0 | CompilerType GetCompilerType() { |
180 | 0 | if (m_type.m_compiler_type.IsValid()) |
181 | 0 | return m_type.m_compiler_type; |
182 | 0 | return CompilerType(); |
183 | 0 | } |
184 | | |
185 | 413k | lldb::FormatterMatchType GetMatchType() { return m_match_type; } |
186 | | |
187 | 0 | bool IsRegex() { return m_match_type == lldb::eFormatterMatchRegex; } |
188 | | |
189 | | private: |
190 | | lldb::FormatterMatchType m_match_type = lldb::eFormatterMatchExact; |
191 | | // TODO: Replace this with TypeAndOrName. |
192 | | struct TypeOrName { |
193 | | std::string m_type_name; |
194 | | CompilerType m_compiler_type; |
195 | | }; |
196 | | TypeOrName m_type; |
197 | | |
198 | | TypeNameSpecifierImpl(const TypeNameSpecifierImpl &) = delete; |
199 | | const TypeNameSpecifierImpl & |
200 | | operator=(const TypeNameSpecifierImpl &) = delete; |
201 | | }; |
202 | | |
203 | | } // namespace lldb_private |
204 | | |
205 | | #endif // LLDB_DATAFORMATTERS_FORMATCLASSES_H |