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/Target/Language.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 LanguageCategory::LanguageCategory(lldb::LanguageType lang_type)
23     : m_category_sp(), m_hardcoded_formats(), m_hardcoded_summaries(),
24       m_hardcoded_synthetics(), m_format_cache(), m_enabled(false) {
25   if (Language *language_plugin = Language::FindPlugin(lang_type)) {
26     m_category_sp = language_plugin->GetFormatters();
27     m_hardcoded_formats = language_plugin->GetHardcodedFormats();
28     m_hardcoded_summaries = language_plugin->GetHardcodedSummaries();
29     m_hardcoded_synthetics = language_plugin->GetHardcodedSynthetics();
30   }
31   Enable();
32 }
33 
34 template<typename ImplSP>
35 bool LanguageCategory::Get(FormattersMatchData &match_data,
36                            ImplSP &retval_sp) {
37   if (!m_category_sp)
38     return false;
39 
40   if (!IsEnabled())
41     return false;
42 
43   if (match_data.GetTypeForCache()) {
44     if (m_format_cache.Get(match_data.GetTypeForCache(), retval_sp))
45       return (bool)retval_sp;
46   }
47 
48   ValueObject &valobj(match_data.GetValueObject());
49   bool result = m_category_sp->Get(valobj.GetObjectRuntimeLanguage(),
50                                    match_data.GetMatchesVector(), retval_sp);
51   if (match_data.GetTypeForCache() &&
52       (!retval_sp || !retval_sp->NonCacheable())) {
53     m_format_cache.Set(match_data.GetTypeForCache(), retval_sp);
54   }
55   return result;
56 }
57 
58 namespace lldb_private {
59 
60 /// Explicit instantiations for the three types.
61 /// \{
62 template bool
63 LanguageCategory::Get<lldb::TypeFormatImplSP>(FormattersMatchData &,
64                                               lldb::TypeFormatImplSP &);
65 template bool
66 LanguageCategory::Get<lldb::TypeSummaryImplSP>(FormattersMatchData &,
67                                                lldb::TypeSummaryImplSP &);
68 template bool
69 LanguageCategory::Get<lldb::SyntheticChildrenSP>(FormattersMatchData &,
70                                                  lldb::SyntheticChildrenSP &);
71 /// \}
72 
73 template <>
74 auto &LanguageCategory::GetHardcodedFinder<lldb::TypeFormatImplSP>() {
75   return m_hardcoded_formats;
76 }
77 
78 template <>
79 auto &LanguageCategory::GetHardcodedFinder<lldb::TypeSummaryImplSP>() {
80   return m_hardcoded_summaries;
81 }
82 
83 template <>
84 auto &LanguageCategory::GetHardcodedFinder<lldb::SyntheticChildrenSP>() {
85   return m_hardcoded_synthetics;
86 }
87 
88 } // namespace lldb_private
89 
90 template <typename ImplSP>
91 bool LanguageCategory::GetHardcoded(FormatManager &fmt_mgr,
92                                     FormattersMatchData &match_data,
93                                     ImplSP &retval_sp) {
94   if (!IsEnabled())
95     return false;
96 
97   ValueObject &valobj(match_data.GetValueObject());
98   lldb::DynamicValueType use_dynamic(match_data.GetDynamicValueType());
99 
100   for (auto &candidate : GetHardcodedFinder<ImplSP>()) {
101     if (auto result = candidate(valobj, use_dynamic, fmt_mgr)) {
102       retval_sp = result;
103       break;
104     }
105   }
106   return (bool)retval_sp;
107 }
108 
109 /// Explicit instantiations for the three types.
110 /// \{
111 template bool LanguageCategory::GetHardcoded<lldb::TypeFormatImplSP>(
112     FormatManager &, FormattersMatchData &, lldb::TypeFormatImplSP &);
113 template bool LanguageCategory::GetHardcoded<lldb::TypeSummaryImplSP>(
114     FormatManager &, FormattersMatchData &, lldb::TypeSummaryImplSP &);
115 template bool LanguageCategory::GetHardcoded<lldb::SyntheticChildrenSP>(
116     FormatManager &, FormattersMatchData &, lldb::SyntheticChildrenSP &);
117 /// \}
118 
119 lldb::TypeCategoryImplSP LanguageCategory::GetCategory() const {
120   return m_category_sp;
121 }
122 
123 FormatCache &LanguageCategory::GetFormatCache() { return m_format_cache; }
124 
125 void LanguageCategory::Enable() {
126   if (m_category_sp)
127     m_category_sp->Enable(true, TypeCategoryMap::Default);
128   m_enabled = true;
129 }
130 
131 void LanguageCategory::Disable() {
132   if (m_category_sp)
133     m_category_sp->Disable();
134   m_enabled = false;
135 }
136 
137 bool LanguageCategory::IsEnabled() { return m_enabled; }
138