1 //===-- LanguageCategory.cpp ---------------------------------------*- C++
2 //-*-===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/DataFormatters/LanguageCategory.h"
11 
12 #include "lldb/DataFormatters/FormatManager.h"
13 #include "lldb/DataFormatters/TypeCategory.h"
14 #include "lldb/DataFormatters/TypeFormat.h"
15 #include "lldb/DataFormatters/TypeSummary.h"
16 #include "lldb/DataFormatters/TypeSynthetic.h"
17 #include "lldb/DataFormatters/TypeValidator.h"
18 #include "lldb/Target/Language.h"
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 LanguageCategory::LanguageCategory(lldb::LanguageType lang_type)
24     : m_category_sp(), m_hardcoded_formats(), m_hardcoded_summaries(),
25       m_hardcoded_synthetics(), m_hardcoded_validators(), m_format_cache(),
26       m_enabled(false) {
27   if (Language *language_plugin = Language::FindPlugin(lang_type)) {
28     m_category_sp = language_plugin->GetFormatters();
29     m_hardcoded_formats = language_plugin->GetHardcodedFormats();
30     m_hardcoded_summaries = language_plugin->GetHardcodedSummaries();
31     m_hardcoded_synthetics = language_plugin->GetHardcodedSynthetics();
32     m_hardcoded_validators = language_plugin->GetHardcodedValidators();
33   }
34   Enable();
35 }
36 
37 template<typename ImplSP>
38 bool LanguageCategory::Get(FormattersMatchData &match_data,
39                            ImplSP &retval_sp) {
40   if (!m_category_sp)
41     return false;
42 
43   if (!IsEnabled())
44     return false;
45 
46   if (match_data.GetTypeForCache()) {
47     if (m_format_cache.Get(match_data.GetTypeForCache(), retval_sp))
48       return (bool)retval_sp;
49   }
50 
51   ValueObject &valobj(match_data.GetValueObject());
52   bool result = m_category_sp->Get(valobj.GetObjectRuntimeLanguage(),
53                                    match_data.GetMatchesVector(), retval_sp);
54   if (match_data.GetTypeForCache() &&
55       (!retval_sp || !retval_sp->NonCacheable())) {
56     m_format_cache.Set(match_data.GetTypeForCache(), retval_sp);
57   }
58   return result;
59 }
60 
61 /// Explicit instantiations for the four types.
62 /// \{
63 template bool
64 LanguageCategory::Get<lldb::TypeValidatorImplSP>(FormattersMatchData &,
65                                                  lldb::TypeValidatorImplSP &);
66 template bool
67 LanguageCategory::Get<lldb::TypeFormatImplSP>(FormattersMatchData &,
68                                               lldb::TypeFormatImplSP &);
69 template bool
70 LanguageCategory::Get<lldb::TypeSummaryImplSP>(FormattersMatchData &,
71                                                lldb::TypeSummaryImplSP &);
72 template bool
73 LanguageCategory::Get<lldb::SyntheticChildrenSP>(FormattersMatchData &,
74                                                  lldb::SyntheticChildrenSP &);
75 /// \}
76 
77 template <>
78 auto &LanguageCategory::GetHardcodedFinder<lldb::TypeFormatImplSP>() {
79   return m_hardcoded_formats;
80 }
81 
82 template <>
83 auto &LanguageCategory::GetHardcodedFinder<lldb::TypeSummaryImplSP>() {
84   return m_hardcoded_summaries;
85 }
86 
87 template <>
88 auto &LanguageCategory::GetHardcodedFinder<lldb::SyntheticChildrenSP>() {
89   return m_hardcoded_synthetics;
90 }
91 
92 template <>
93 auto &LanguageCategory::GetHardcodedFinder<lldb::TypeValidatorImplSP>() {
94   return m_hardcoded_validators;
95 }
96 
97 template <typename ImplSP>
98 bool LanguageCategory::GetHardcoded(FormatManager &fmt_mgr,
99                                     FormattersMatchData &match_data,
100                                     ImplSP &retval_sp) {
101   if (!IsEnabled())
102     return false;
103 
104   ValueObject &valobj(match_data.GetValueObject());
105   lldb::DynamicValueType use_dynamic(match_data.GetDynamicValueType());
106 
107   for (auto &candidate : GetHardcodedFinder<ImplSP>()) {
108     if (auto result = candidate(valobj, use_dynamic, fmt_mgr)) {
109       retval_sp = result;
110       break;
111     }
112   }
113   return (bool)retval_sp;
114 }
115 
116 /// Explicit instantiations for the four types.
117 /// \{
118 template bool LanguageCategory::GetHardcoded<lldb::TypeValidatorImplSP>(
119     FormatManager &, FormattersMatchData &, lldb::TypeValidatorImplSP &);
120 template bool LanguageCategory::GetHardcoded<lldb::TypeFormatImplSP>(
121     FormatManager &, FormattersMatchData &, lldb::TypeFormatImplSP &);
122 template bool LanguageCategory::GetHardcoded<lldb::TypeSummaryImplSP>(
123     FormatManager &, FormattersMatchData &, lldb::TypeSummaryImplSP &);
124 template bool LanguageCategory::GetHardcoded<lldb::SyntheticChildrenSP>(
125     FormatManager &, FormattersMatchData &, lldb::SyntheticChildrenSP &);
126 /// \}
127 
128 lldb::TypeCategoryImplSP LanguageCategory::GetCategory() const {
129   return m_category_sp;
130 }
131 
132 FormatCache &LanguageCategory::GetFormatCache() { return m_format_cache; }
133 
134 void LanguageCategory::Enable() {
135   if (m_category_sp)
136     m_category_sp->Enable(true, TypeCategoryMap::Default);
137   m_enabled = true;
138 }
139 
140 void LanguageCategory::Disable() {
141   if (m_category_sp)
142     m_category_sp->Disable();
143   m_enabled = false;
144 }
145 
146 bool LanguageCategory::IsEnabled() { return m_enabled; }
147