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/Symbol/CompilerType.h"
21 #include "lldb/Symbol/Type.h"
22 #include "lldb/lldb-enumerations.h"
23 #include "lldb/lldb-public.h"
24 
25 namespace lldb_private {
26 
27 class HardcodedFormatters {
28 public:
29   template <typename FormatterType>
30   using HardcodedFormatterFinder =
31       std::function<typename FormatterType::SharedPointer(
32           lldb_private::ValueObject &, lldb::DynamicValueType,
33           FormatManager &)>;
34 
35   template <typename FormatterType>
36   using HardcodedFormatterFinders =
37       std::vector<HardcodedFormatterFinder<FormatterType>>;
38 
39   typedef HardcodedFormatterFinders<TypeFormatImpl> HardcodedFormatFinder;
40   typedef HardcodedFormatterFinders<TypeSummaryImpl> HardcodedSummaryFinder;
41   typedef HardcodedFormatterFinders<SyntheticChildren> HardcodedSyntheticFinder;
42 };
43 
44 class FormattersMatchCandidate {
45 public:
46   FormattersMatchCandidate(ConstString name, bool strip_ptr,
47                            bool strip_ref, bool strip_tydef)
48       : m_type_name(name), m_stripped_pointer(strip_ptr),
49         m_stripped_reference(strip_ref), m_stripped_typedef(strip_tydef) {}
50 
51   ~FormattersMatchCandidate() = default;
52 
53   ConstString GetTypeName() const { return m_type_name; }
54 
55   bool DidStripPointer() const { return m_stripped_pointer; }
56 
57   bool DidStripReference() const { return m_stripped_reference; }
58 
59   bool DidStripTypedef() const { return m_stripped_typedef; }
60 
61   template <class Formatter>
62   bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const {
63     if (!formatter_sp)
64       return false;
65     if (formatter_sp->Cascades() == false && DidStripTypedef())
66       return false;
67     if (formatter_sp->SkipsPointers() && DidStripPointer())
68       return false;
69     if (formatter_sp->SkipsReferences() && DidStripReference())
70       return false;
71     return true;
72   }
73 
74 private:
75   ConstString m_type_name;
76   bool m_stripped_pointer;
77   bool m_stripped_reference;
78   bool m_stripped_typedef;
79 };
80 
81 typedef std::vector<FormattersMatchCandidate> FormattersMatchVector;
82 typedef std::vector<lldb::LanguageType> CandidateLanguagesVector;
83 
84 class FormattersMatchData {
85 public:
86   FormattersMatchData(ValueObject &, lldb::DynamicValueType);
87 
88   FormattersMatchVector GetMatchesVector();
89 
90   ConstString GetTypeForCache();
91 
92   CandidateLanguagesVector GetCandidateLanguages();
93 
94   ValueObject &GetValueObject();
95 
96   lldb::DynamicValueType GetDynamicValueType();
97 
98 private:
99   ValueObject &m_valobj;
100   lldb::DynamicValueType m_dynamic_value_type;
101   std::pair<FormattersMatchVector, bool> m_formatters_match_vector;
102   ConstString m_type_for_cache;
103   CandidateLanguagesVector m_candidate_languages;
104 };
105 
106 class TypeNameSpecifierImpl {
107 public:
108   TypeNameSpecifierImpl() : m_is_regex(false), m_type() {}
109 
110   TypeNameSpecifierImpl(llvm::StringRef name, bool is_regex)
111       : m_is_regex(is_regex), m_type() {
112     m_type.m_type_name = std::string(name);
113   }
114 
115   // if constructing with a given type, is_regex cannot be true since we are
116   // giving an exact type to match
117   TypeNameSpecifierImpl(lldb::TypeSP type) : m_is_regex(false), m_type() {
118     if (type) {
119       m_type.m_type_name = std::string(type->GetName().GetStringRef());
120       m_type.m_compiler_type = type->GetForwardCompilerType();
121     }
122   }
123 
124   TypeNameSpecifierImpl(CompilerType type) : m_is_regex(false), m_type() {
125     if (type.IsValid()) {
126       m_type.m_type_name.assign(type.GetTypeName().GetCString());
127       m_type.m_compiler_type = type;
128     }
129   }
130 
131   const char *GetName() {
132     if (m_type.m_type_name.size())
133       return m_type.m_type_name.c_str();
134     return nullptr;
135   }
136 
137   CompilerType GetCompilerType() {
138     if (m_type.m_compiler_type.IsValid())
139       return m_type.m_compiler_type;
140     return CompilerType();
141   }
142 
143   bool IsRegex() { return m_is_regex; }
144 
145 private:
146   bool m_is_regex;
147   // TODO: Replace this with TypeAndOrName.
148   struct TypeOrName {
149     std::string m_type_name;
150     CompilerType m_compiler_type;
151   };
152   TypeOrName m_type;
153 
154   TypeNameSpecifierImpl(const TypeNameSpecifierImpl &) = delete;
155   const TypeNameSpecifierImpl &
156   operator=(const TypeNameSpecifierImpl &) = delete;
157 };
158 
159 } // namespace lldb_private
160 
161 #endif // LLDB_DATAFORMATTERS_FORMATCLASSES_H
162