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
26namespace lldb_private {
27
28class HardcodedFormatters {
29public:
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
45class FormattersMatchCandidate {
46public:
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 Flags WithStrippedPointer() {
57 Flags result(*this);
58 result.stripped_pointer = true;
59 return result;
60 }
61
62 // Returns a copy of this with the "stripped reference" flag set.
63 Flags WithStrippedReference() {
64 Flags result(*this);
65 result.stripped_reference = true;
66 return result;
67 }
68
69 // Returns a copy of this with the "stripped typedef" flag set.
70 Flags WithStrippedTypedef() {
71 Flags result(*this);
72 result.stripped_typedef = true;
73 return result;
74 }
75 };
76
77 FormattersMatchCandidate(ConstString name,
78 ScriptInterpreter *script_interpreter, TypeImpl type,
79 Flags flags)
80 : m_type_name(name), m_script_interpreter(script_interpreter),
81 m_type(type), m_flags(flags) {}
82
83 ~FormattersMatchCandidate() = default;
84
85 ConstString GetTypeName() const { return m_type_name; }
86
87 TypeImpl GetType() const { return m_type; }
88
89 ScriptInterpreter *GetScriptInterpreter() const {
90 return m_script_interpreter;
91 }
92
93 bool DidStripPointer() const { return m_flags.stripped_pointer; }
94
95 bool DidStripReference() const { return m_flags.stripped_reference; }
96
97 bool DidStripTypedef() const { return m_flags.stripped_typedef; }
98
99 template <class Formatter>
100 bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const {
101 if (!formatter_sp)
102 return false;
103 if (formatter_sp->Cascades() == false && DidStripTypedef())
104 return false;
105 if (formatter_sp->SkipsPointers() && DidStripPointer())
106 return false;
107 if (formatter_sp->SkipsReferences() && DidStripReference())
108 return false;
109 return true;
110 }
111
112private:
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
121typedef std::vector<FormattersMatchCandidate> FormattersMatchVector;
122typedef std::vector<lldb::LanguageType> CandidateLanguagesVector;
123
124class FormattersMatchData {
125public:
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
138private:
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
146class TypeNameSpecifierImpl {
147public:
148 TypeNameSpecifierImpl() = default;
149
150 TypeNameSpecifierImpl(llvm::StringRef name,
151 lldb::FormatterMatchType match_type)
152 : m_match_type(match_type) {
153 m_type.m_type_name = std::string(name);
154 }
155
156 // if constructing with a given type, we consider that a case of exact match.
157 TypeNameSpecifierImpl(lldb::TypeSP type)
158 : m_match_type(lldb::eFormatterMatchExact) {
159 if (type) {
160 m_type.m_type_name = std::string(type->GetName().GetStringRef());
161 m_type.m_compiler_type = type->GetForwardCompilerType();
162 }
163 }
164
165 TypeNameSpecifierImpl(CompilerType type)
166 : m_match_type(lldb::eFormatterMatchExact) {
167 if (type.IsValid()) {
168 m_type.m_type_name.assign(s: type.GetTypeName().GetCString());
169 m_type.m_compiler_type = type;
170 }
171 }
172
173 const char *GetName() {
174 if (m_type.m_type_name.size())
175 return m_type.m_type_name.c_str();
176 return nullptr;
177 }
178
179 CompilerType GetCompilerType() {
180 if (m_type.m_compiler_type.IsValid())
181 return m_type.m_compiler_type;
182 return CompilerType();
183 }
184
185 lldb::FormatterMatchType GetMatchType() { return m_match_type; }
186
187 bool IsRegex() { return m_match_type == lldb::eFormatterMatchRegex; }
188
189private:
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
206

source code of lldb/include/lldb/DataFormatters/FormatClasses.h