]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/ConstString.cpp
Add the llvm-cov and llvm-profdata tools, when WITH_CLANG_EXTRAS is
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / ConstString.cpp
1 //===-- ConstString.cpp -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include "lldb/Core/ConstString.h"
10 #include "lldb/Core/Stream.h"
11 #include "lldb/Host/Mutex.h"
12 #include "llvm/ADT/StringMap.h"
13
14 #include <mutex>
15
16 using namespace lldb_private;
17
18
19 class Pool
20 {
21 public:
22     typedef const char * StringPoolValueType;
23     typedef llvm::StringMap<StringPoolValueType, llvm::BumpPtrAllocator> StringPool;
24     typedef llvm::StringMapEntry<StringPoolValueType> StringPoolEntryType;
25     
26     //------------------------------------------------------------------
27     // Default constructor
28     //
29     // Initialize the member variables and create the empty string.
30     //------------------------------------------------------------------
31     Pool () :
32         m_mutex (Mutex::eMutexTypeRecursive),
33         m_string_map ()
34     {
35     }
36
37     //------------------------------------------------------------------
38     // Destructor
39     //------------------------------------------------------------------
40     ~Pool ()
41     {
42     }
43
44
45     static StringPoolEntryType &
46     GetStringMapEntryFromKeyData (const char *keyData)
47     {
48         char *ptr = const_cast<char*>(keyData) - sizeof (StringPoolEntryType);
49         return *reinterpret_cast<StringPoolEntryType*>(ptr);
50     }
51
52     size_t
53     GetConstCStringLength (const char *ccstr) const
54     {
55         if (ccstr)
56         {
57             const StringPoolEntryType&entry = GetStringMapEntryFromKeyData (ccstr);
58             return entry.getKey().size();
59         }
60         return 0;
61     }
62
63     StringPoolValueType
64     GetMangledCounterpart (const char *ccstr) const
65     {
66         if (ccstr)
67             return GetStringMapEntryFromKeyData (ccstr).getValue();
68         return 0;
69     }
70
71     bool
72     SetMangledCounterparts (const char *key_ccstr, const char *value_ccstr)
73     {
74         if (key_ccstr && value_ccstr)
75         {
76             GetStringMapEntryFromKeyData (key_ccstr).setValue(value_ccstr);
77             GetStringMapEntryFromKeyData (value_ccstr).setValue(key_ccstr);
78             return true;
79         }
80         return false;
81     }
82
83     const char *
84     GetConstCString (const char *cstr)
85     {
86         if (cstr)
87             return GetConstCStringWithLength (cstr, strlen (cstr));
88         return NULL;
89     }
90
91     const char *
92     GetConstCStringWithLength (const char *cstr, size_t cstr_len)
93     {
94         if (cstr)
95         {
96             Mutex::Locker locker (m_mutex);
97             llvm::StringRef string_ref (cstr, cstr_len);
98             StringPoolEntryType& entry = *m_string_map.insert (std::make_pair (string_ref, (StringPoolValueType)NULL)).first;
99             return entry.getKeyData();
100         }
101         return NULL;
102     }
103
104     const char *
105     GetConstCStringWithStringRef (const llvm::StringRef &string_ref)
106     {
107         if (string_ref.data())
108         {
109             Mutex::Locker locker (m_mutex);
110             StringPoolEntryType& entry = *m_string_map.insert (std::make_pair (string_ref, (StringPoolValueType)NULL)).first;
111             return entry.getKeyData();
112         }
113         return NULL;
114     }
115
116     const char *
117     GetConstCStringAndSetMangledCounterPart (const char *demangled_cstr, const char *mangled_ccstr)
118     {
119         if (demangled_cstr)
120         {
121             Mutex::Locker locker (m_mutex);
122             // Make string pool entry with the mangled counterpart already set
123             StringPoolEntryType& entry = *m_string_map.insert (std::make_pair (llvm::StringRef (demangled_cstr), mangled_ccstr)).first;
124
125             // Extract the const version of the demangled_cstr
126             const char *demangled_ccstr = entry.getKeyData();
127             // Now assign the demangled const string as the counterpart of the
128             // mangled const string...
129             GetStringMapEntryFromKeyData (mangled_ccstr).setValue(demangled_ccstr);
130             // Return the constant demangled C string
131             return demangled_ccstr;
132         }
133         return NULL;
134     }
135
136     const char *
137     GetConstTrimmedCStringWithLength (const char *cstr, size_t cstr_len)
138     {
139         if (cstr)
140         {
141             const size_t trimmed_len = std::min<size_t> (strlen (cstr), cstr_len);
142             return GetConstCStringWithLength (cstr, trimmed_len);
143         }
144         return NULL;
145     }
146
147     //------------------------------------------------------------------
148     // Return the size in bytes that this object and any items in its
149     // collection of uniqued strings + data count values takes in
150     // memory.
151     //------------------------------------------------------------------
152     size_t
153     MemorySize() const
154     {
155         Mutex::Locker locker (m_mutex);
156         size_t mem_size = sizeof(Pool);
157         const_iterator end = m_string_map.end();
158         for (const_iterator pos = m_string_map.begin(); pos != end; ++pos)
159         {
160             mem_size += sizeof(StringPoolEntryType) + pos->getKey().size();
161         }
162         return mem_size;
163     }
164
165 protected:
166     //------------------------------------------------------------------
167     // Typedefs
168     //------------------------------------------------------------------
169     typedef StringPool::iterator iterator;
170     typedef StringPool::const_iterator const_iterator;
171
172     //------------------------------------------------------------------
173     // Member variables
174     //------------------------------------------------------------------
175     mutable Mutex m_mutex;
176     StringPool m_string_map;
177 };
178
179 //----------------------------------------------------------------------
180 // Frameworks and dylibs aren't supposed to have global C++
181 // initializers so we hide the string pool in a static function so
182 // that it will get initialized on the first call to this static
183 // function.
184 //
185 // Note, for now we make the string pool a pointer to the pool, because
186 // we can't guarantee that some objects won't get destroyed after the
187 // global destructor chain is run, and trying to make sure no destructors
188 // touch ConstStrings is difficult.  So we leak the pool instead.
189 //----------------------------------------------------------------------
190 static Pool &
191 StringPool()
192 {
193     static std::once_flag g_pool_initialization_flag;
194     static Pool *g_string_pool = NULL;
195
196     std::call_once(g_pool_initialization_flag, [] () {
197         g_string_pool = new Pool();
198     });
199     
200     return *g_string_pool;
201 }
202
203 ConstString::ConstString (const char *cstr) :
204     m_string (StringPool().GetConstCString (cstr))
205 {
206 }
207
208 ConstString::ConstString (const char *cstr, size_t cstr_len) :
209     m_string (StringPool().GetConstCStringWithLength (cstr, cstr_len))
210 {
211 }
212
213 ConstString::ConstString (const llvm::StringRef &s) :
214     m_string (StringPool().GetConstCStringWithLength (s.data(), s.size()))
215 {
216 }
217
218 bool
219 ConstString::operator < (const ConstString& rhs) const
220 {
221     if (m_string == rhs.m_string)
222         return false;
223
224     llvm::StringRef lhs_string_ref (m_string, StringPool().GetConstCStringLength (m_string));
225     llvm::StringRef rhs_string_ref (rhs.m_string, StringPool().GetConstCStringLength (rhs.m_string));
226
227     // If both have valid C strings, then return the comparison
228     if (lhs_string_ref.data() && rhs_string_ref.data())
229         return lhs_string_ref < rhs_string_ref;
230
231     // Else one of them was NULL, so if LHS is NULL then it is less than
232     return lhs_string_ref.data() == NULL;
233 }
234
235 Stream&
236 lldb_private::operator << (Stream& s, const ConstString& str)
237 {
238     const char *cstr = str.GetCString();
239     if (cstr)
240         s << cstr;
241
242     return s;
243 }
244
245 size_t
246 ConstString::GetLength () const
247 {
248     return StringPool().GetConstCStringLength (m_string);
249 }
250
251 int
252 ConstString::Compare (const ConstString& lhs, const ConstString& rhs)
253 {
254     // If the iterators are the same, this is the same string
255     const char *lhs_cstr = lhs.m_string;
256     const char *rhs_cstr = rhs.m_string;
257     if (lhs_cstr == rhs_cstr)
258         return 0;
259     if (lhs_cstr && rhs_cstr)
260     {
261         llvm::StringRef lhs_string_ref (lhs_cstr, StringPool().GetConstCStringLength (lhs_cstr));
262         llvm::StringRef rhs_string_ref (rhs_cstr, StringPool().GetConstCStringLength (rhs_cstr));
263         return lhs_string_ref.compare(rhs_string_ref);
264     }
265
266     if (lhs_cstr)
267         return +1;  // LHS isn't NULL but RHS is
268     else
269         return -1;  // LHS is NULL but RHS isn't
270 }
271
272 void
273 ConstString::Dump(Stream *s, const char *fail_value) const
274 {
275     if (s)
276     {
277         const char *cstr = AsCString (fail_value);
278         if (cstr)
279             s->PutCString (cstr);
280     }
281 }
282
283 void
284 ConstString::DumpDebug(Stream *s) const
285 {
286     const char *cstr = GetCString ();
287     size_t cstr_len = GetLength();
288     // Only print the parens if we have a non-NULL string
289     const char *parens = cstr ? "\"" : "";
290     s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64,
291               static_cast<int>(sizeof(void*) * 2),
292               static_cast<const void*>(this), parens, cstr, parens,
293               static_cast<uint64_t>(cstr_len));
294 }
295
296 void
297 ConstString::SetCString (const char *cstr)
298 {
299     m_string = StringPool().GetConstCString (cstr);
300 }
301
302 void
303 ConstString::SetString (const llvm::StringRef &s)
304 {
305     m_string = StringPool().GetConstCStringWithLength (s.data(), s.size());
306 }
307
308 void
309 ConstString::SetCStringWithMangledCounterpart (const char *demangled, const ConstString &mangled)
310 {
311     m_string = StringPool().GetConstCStringAndSetMangledCounterPart (demangled, mangled.m_string);
312 }
313
314 bool
315 ConstString::GetMangledCounterpart (ConstString &counterpart) const
316 {
317     counterpart.m_string = StringPool().GetMangledCounterpart(m_string);
318     return (bool)counterpart;
319 }
320
321 void
322 ConstString::SetCStringWithLength (const char *cstr, size_t cstr_len)
323 {
324     m_string = StringPool().GetConstCStringWithLength(cstr, cstr_len);
325 }
326
327 void
328 ConstString::SetTrimmedCStringWithLength (const char *cstr, size_t cstr_len)
329 {
330     m_string = StringPool().GetConstTrimmedCStringWithLength (cstr, cstr_len);
331 }
332
333 size_t
334 ConstString::StaticMemorySize()
335 {
336     // Get the size of the static string pool
337     return StringPool().MemorySize();
338 }