1 //===-- Type.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 
10 // Other libraries and framework includes
11 
12 #include "lldb/Core/DataExtractor.h"
13 #include "lldb/Core/DataBufferHeap.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/Scalar.h"
16 #include "lldb/Core/StreamString.h"
17 
18 #include "lldb/Symbol/ClangASTType.h"
19 #include "lldb/Symbol/ClangASTContext.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Symbol/SymbolContextScope.h"
22 #include "lldb/Symbol/SymbolFile.h"
23 #include "lldb/Symbol/Type.h"
24 #include "lldb/Symbol/TypeList.h"
25 
26 #include "lldb/Target/ExecutionContext.h"
27 #include "lldb/Target/Process.h"
28 
29 using namespace lldb;
30 
31 lldb_private::Type::Type
32 (
33     lldb::user_id_t uid,
34     SymbolFile* symbol_file,
35     const ConstString &name,
36     uint32_t byte_size,
37     SymbolContextScope *context,
38     uintptr_t encoding_data,
39     EncodingDataType encoding_data_type,
40     const Declaration& decl,
41     clang_type_t clang_type,
42     ResolveState clang_type_resolve_state
43 ) :
44     UserID (uid),
45     m_name (name),
46     m_symbol_file (symbol_file),
47     m_context (context),
48     m_encoding_type (NULL),
49     m_encoding_uid_type (encoding_data_type),
50     m_encoding_uid (encoding_data),
51     m_byte_size (byte_size),
52     m_decl (decl),
53     m_clang_type (clang_type),
54     m_clang_type_resolve_state (clang_type ? clang_type_resolve_state : eResolveStateUnresolved)
55 {
56 }
57 
58 lldb_private::Type::Type () :
59     UserID (0),
60     m_name ("<INVALID TYPE>"),
61     m_symbol_file (NULL),
62     m_context (NULL),
63     m_encoding_type (NULL),
64     m_encoding_uid_type (eEncodingInvalid),
65     m_encoding_uid (0),
66     m_byte_size (0),
67     m_decl (),
68     m_clang_type (NULL),
69     m_clang_type_resolve_state (eResolveStateUnresolved)
70 {
71 }
72 
73 
74 const lldb_private::Type&
75 lldb_private::Type::operator= (const Type& rhs)
76 {
77     if (this != &rhs)
78     {
79         UserID::operator= (rhs);
80         m_name = rhs.m_name;
81         m_symbol_file = rhs.m_symbol_file;
82         m_context = rhs.m_context;
83         m_encoding_type = rhs.m_encoding_type;
84         m_encoding_uid_type = rhs.m_encoding_uid_type;
85         m_encoding_uid = rhs.m_encoding_uid;
86         m_byte_size = rhs.m_byte_size;
87         m_decl = rhs.m_decl;
88         m_clang_type = rhs.m_clang_type;
89         m_clang_type_resolve_state = rhs.m_clang_type_resolve_state;
90     }
91     return *this;
92 }
93 
94 
95 void
96 lldb_private::Type::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name)
97 {
98     *s << "id = " << (const UserID&)*this;
99 
100     // Call the name accessor to make sure we resolve the type name
101     if (show_name && GetName())
102         *s << ", name = \"" << m_name << '"';
103 
104     // Call the get byte size accesor so we resolve our byte size
105     if (GetByteSize())
106         s->Printf(", byte-size = %zu", m_byte_size);
107     bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
108     m_decl.Dump(s, show_fullpaths);
109 
110     if (m_clang_type)
111     {
112         *s << ", clang_type = \"";
113         ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_type, s);
114         *s << '"';
115     }
116     else if (m_encoding_uid != LLDB_INVALID_UID)
117     {
118         s->Printf(", type_uid = 0x%8.8x", m_encoding_uid);
119         switch (m_encoding_uid_type)
120         {
121         case eEncodingIsUID: s->PutCString(" (unresolved type)"); break;
122         case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break;
123         case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break;
124         case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break;
125         case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break;
126         case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break;
127         case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break;
128         case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break;
129         case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break;
130         }
131     }
132 }
133 
134 
135 void
136 lldb_private::Type::Dump (Stream *s, bool show_context)
137 {
138     s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
139     s->Indent();
140     *s << "Type" << (const UserID&)*this << ' ';
141     if (m_name)
142         *s << ", name = \"" << m_name << "\"";
143 
144     if (m_byte_size != 0)
145         s->Printf(", size = %zu", m_byte_size);
146 
147     if (show_context && m_context != NULL)
148     {
149         s->PutCString(", context = ( ");
150         m_context->DumpSymbolContext(s);
151         s->PutCString(" )");
152     }
153 
154     bool show_fullpaths = false;
155     m_decl.Dump (s,show_fullpaths);
156 
157     if (m_clang_type)
158     {
159         *s << ", clang_type = " << m_clang_type << ' ';
160 
161         ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_type, s);
162     }
163     else if (m_encoding_uid != LLDB_INVALID_UID)
164     {
165         *s << ", type_data = " << (uint64_t)m_encoding_uid;
166         switch (m_encoding_uid_type)
167         {
168         case eEncodingIsUID: s->PutCString(" (unresolved type)"); break;
169         case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break;
170         case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break;
171         case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break;
172         case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break;
173         case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break;
174         case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break;
175         case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break;
176         case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break;
177         }
178     }
179 
180 //
181 //  if (m_access)
182 //      s->Printf(", access = %u", m_access);
183     s->EOL();
184 }
185 
186 const lldb_private::ConstString &
187 lldb_private::Type::GetName()
188 {
189     if (!(m_name))
190     {
191         if (ResolveClangType(eResolveStateForward))
192         {
193             std::string type_name = ClangASTContext::GetTypeName (m_clang_type);
194             if (!type_name.empty())
195                 m_name.SetCString (type_name.c_str());
196         }
197     }
198     return m_name;
199 }
200 
201 void
202 lldb_private::Type::DumpTypeName(Stream *s)
203 {
204     GetName().Dump(s, "<invalid-type-name>");
205 }
206 
207 
208 void
209 lldb_private::Type::DumpValue
210 (
211     lldb_private::ExecutionContext *exe_ctx,
212     lldb_private::Stream *s,
213     const lldb_private::DataExtractor &data,
214     uint32_t data_byte_offset,
215     bool show_types,
216     bool show_summary,
217     bool verbose,
218     lldb::Format format
219 )
220 {
221     if (ResolveClangType(eResolveStateForward))
222     {
223         if (show_types)
224         {
225             s->PutChar('(');
226             if (verbose)
227                 s->Printf("Type{0x%8.8x} ", GetID());
228             DumpTypeName (s);
229             s->PutCString(") ");
230         }
231 
232         lldb_private::ClangASTType::DumpValue (GetClangAST (),
233                                                m_clang_type,
234                                                exe_ctx,
235                                                s,
236                                                format == lldb::eFormatDefault ? GetFormat() : format,
237                                                data,
238                                                data_byte_offset,
239                                                GetByteSize(),
240                                                0, // Bitfield bit size
241                                                0, // Bitfield bit offset
242                                                show_types,
243                                                show_summary,
244                                                verbose,
245                                                0);
246     }
247 }
248 
249 lldb_private::Type *
250 lldb_private::Type::GetEncodingType ()
251 {
252     if (m_encoding_type == NULL && m_encoding_uid != LLDB_INVALID_UID)
253         m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
254     return m_encoding_type;
255 }
256 
257 
258 
259 uint64_t
260 lldb_private::Type::GetByteSize()
261 {
262     if (m_byte_size == 0)
263     {
264         switch (m_encoding_uid_type)
265         {
266         case eEncodingIsUID:
267         case eEncodingIsConstUID:
268         case eEncodingIsRestrictUID:
269         case eEncodingIsVolatileUID:
270         case eEncodingIsTypedefUID:
271             {
272                 Type *encoding_type = GetEncodingType ();
273                 if (encoding_type)
274                     m_byte_size = encoding_type->GetByteSize();
275                 if (m_byte_size == 0)
276                 {
277                     uint64_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetClangLayoutType());
278                     m_byte_size = (bit_width + 7 ) / 8;
279                 }
280             }
281             break;
282 
283         // If we are a pointer or reference, then this is just a pointer size;
284         case eEncodingIsPointerUID:
285         case eEncodingIsLValueReferenceUID:
286         case eEncodingIsRValueReferenceUID:
287             m_byte_size = GetTypeList()->GetClangASTContext().GetPointerBitSize() / 8;
288             break;
289         }
290     }
291     return m_byte_size;
292 }
293 
294 
295 uint32_t
296 lldb_private::Type::GetNumChildren (bool omit_empty_base_classes)
297 {
298     if (!ResolveClangType(eResolveStateFull))
299         return 0;
300     return ClangASTContext::GetNumChildren (m_clang_type, omit_empty_base_classes);
301 
302 }
303 
304 bool
305 lldb_private::Type::IsAggregateType ()
306 {
307     if (ResolveClangType(eResolveStateForward))
308         return ClangASTContext::IsAggregateType (m_clang_type);
309     return false;
310 }
311 
312 lldb::Format
313 lldb_private::Type::GetFormat ()
314 {
315     // Make sure we resolve our type if it already hasn't been.
316     if (!ResolveClangType(eResolveStateForward))
317         return lldb::eFormatInvalid;
318     return lldb_private::ClangASTType::GetFormat (m_clang_type);
319 }
320 
321 
322 
323 lldb::Encoding
324 lldb_private::Type::GetEncoding (uint32_t &count)
325 {
326     // Make sure we resolve our type if it already hasn't been.
327     if (!ResolveClangType(eResolveStateForward))
328         return lldb::eEncodingInvalid;
329 
330     return lldb_private::ClangASTType::GetEncoding (m_clang_type, count);
331 }
332 
333 
334 
335 bool
336 lldb_private::Type::DumpValueInMemory
337 (
338     lldb_private::ExecutionContext *exe_ctx,
339     lldb_private::Stream *s,
340     lldb::addr_t address,
341     lldb::AddressType address_type,
342     bool show_types,
343     bool show_summary,
344     bool verbose
345 )
346 {
347     if (address != LLDB_INVALID_ADDRESS)
348     {
349         lldb_private::DataExtractor data;
350         data.SetByteOrder (exe_ctx->process->GetByteOrder());
351         if (ReadFromMemory (exe_ctx, address, address_type, data))
352         {
353             DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose);
354             return true;
355         }
356     }
357     return false;
358 }
359 
360 
361 bool
362 lldb_private::Type::ReadFromMemory (lldb_private::ExecutionContext *exe_ctx, lldb::addr_t addr, lldb::AddressType address_type, lldb_private::DataExtractor &data)
363 {
364     if (address_type == lldb::eAddressTypeFile)
365     {
366         // Can't convert a file address to anything valid without more
367         // context (which Module it came from)
368         return false;
369     }
370 
371     const uint32_t byte_size = GetByteSize();
372     if (data.GetByteSize() < byte_size)
373     {
374         lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
375         data.SetData(data_sp);
376     }
377 
378     uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
379     if (dst != NULL)
380     {
381         if (address_type == lldb::eAddressTypeHost)
382         {
383             // The address is an address in this process, so just copy it
384             memcpy (dst, (uint8_t*)NULL + addr, byte_size);
385             return true;
386         }
387         else
388         {
389             if (exe_ctx && exe_ctx->process)
390             {
391                 Error error;
392                 return exe_ctx->process->ReadMemory(addr, dst, byte_size, error) == byte_size;
393             }
394         }
395     }
396     return false;
397 }
398 
399 
400 bool
401 lldb_private::Type::WriteToMemory (lldb_private::ExecutionContext *exe_ctx, lldb::addr_t addr, lldb::AddressType address_type, lldb_private::DataExtractor &data)
402 {
403     return false;
404 }
405 
406 
407 lldb_private::TypeList*
408 lldb_private::Type::GetTypeList()
409 {
410     return GetSymbolFile()->GetTypeList();
411 }
412 
413 const lldb_private::Declaration &
414 lldb_private::Type::GetDeclaration () const
415 {
416     return m_decl;
417 }
418 
419 bool
420 lldb_private::Type::ResolveClangType (ResolveState clang_type_resolve_state)
421 {
422     Type *encoding_type = NULL;
423     if (m_clang_type == NULL)
424     {
425         TypeList *type_list = GetTypeList();
426         encoding_type = GetEncodingType();
427         if (encoding_type)
428         {
429             switch (m_encoding_uid_type)
430             {
431             case eEncodingIsUID:
432                 if (encoding_type->ResolveClangType(clang_type_resolve_state))
433                 {
434                     m_clang_type = encoding_type->m_clang_type;
435                     m_clang_type_resolve_state = encoding_type->m_clang_type_resolve_state;
436                 }
437                 break;
438 
439             case eEncodingIsConstUID:
440                 m_clang_type = ClangASTContext::AddConstModifier (encoding_type->GetClangForwardType());
441                 break;
442 
443             case eEncodingIsRestrictUID:
444                 m_clang_type = ClangASTContext::AddRestrictModifier (encoding_type->GetClangForwardType());
445                 break;
446 
447             case eEncodingIsVolatileUID:
448                 m_clang_type = ClangASTContext::AddVolatileModifier (encoding_type->GetClangForwardType());
449                 break;
450 
451             case eEncodingIsTypedefUID:
452                 m_clang_type = type_list->CreateClangTypedefType (this, encoding_type);
453                 // Clear the name so it can get fully qualified in case the
454                 // typedef is in a namespace.
455                 m_name.Clear();
456                 break;
457 
458             case eEncodingIsPointerUID:
459                 m_clang_type = type_list->CreateClangPointerType (encoding_type);
460                 break;
461 
462             case eEncodingIsLValueReferenceUID:
463                 m_clang_type = type_list->CreateClangLValueReferenceType (encoding_type);
464                 break;
465 
466             case eEncodingIsRValueReferenceUID:
467                 m_clang_type = type_list->CreateClangRValueReferenceType (encoding_type);
468                 break;
469 
470             default:
471                 assert(!"Unhandled encoding_data_type.");
472                 break;
473             }
474         }
475         else
476         {
477             // We have no encoding type, return void?
478             clang_type_t void_clang_type = type_list->GetClangASTContext().GetBuiltInType_void();
479             switch (m_encoding_uid_type)
480             {
481             case eEncodingIsUID:
482                 m_clang_type = void_clang_type;
483                 break;
484 
485             case eEncodingIsConstUID:
486                 m_clang_type = ClangASTContext::AddConstModifier (void_clang_type);
487                 break;
488 
489             case eEncodingIsRestrictUID:
490                 m_clang_type = ClangASTContext::AddRestrictModifier (void_clang_type);
491                 break;
492 
493             case eEncodingIsVolatileUID:
494                 m_clang_type = ClangASTContext::AddVolatileModifier (void_clang_type);
495                 break;
496 
497             case eEncodingIsTypedefUID:
498                 m_clang_type = type_list->GetClangASTContext().CreateTypedefType (m_name.AsCString(), void_clang_type, NULL);
499                 break;
500 
501             case eEncodingIsPointerUID:
502                 m_clang_type = type_list->GetClangASTContext().CreatePointerType (void_clang_type);
503                 break;
504 
505             case eEncodingIsLValueReferenceUID:
506                 m_clang_type = type_list->GetClangASTContext().CreateLValueReferenceType (void_clang_type);
507                 break;
508 
509             case eEncodingIsRValueReferenceUID:
510                 m_clang_type = type_list->GetClangASTContext().CreateRValueReferenceType (void_clang_type);
511                 break;
512 
513             default:
514                 assert(!"Unhandled encoding_data_type.");
515                 break;
516             }
517         }
518     }
519 
520     // Check if we have a forward reference to a class/struct/union/enum?
521     if (m_clang_type && m_clang_type_resolve_state < clang_type_resolve_state)
522     {
523         m_clang_type_resolve_state = eResolveStateFull;
524         if (!ClangASTType::IsDefined (m_clang_type))
525         {
526             // We have a forward declaration, we need to resolve it to a complete
527             // definition.
528             m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type);
529         }
530     }
531 
532     // If we have an encoding type, then we need to make sure it is
533     // resolved appropriately.
534     if (m_encoding_uid != LLDB_INVALID_UID)
535     {
536         if (encoding_type == NULL)
537             encoding_type = GetEncodingType();
538         if (encoding_type)
539         {
540             ResolveState encoding_clang_type_resolve_state = clang_type_resolve_state;
541 
542             if (clang_type_resolve_state == eResolveStateLayout)
543             {
544                 switch (m_encoding_uid_type)
545                 {
546                 case eEncodingIsPointerUID:
547                 case eEncodingIsLValueReferenceUID:
548                 case eEncodingIsRValueReferenceUID:
549                     encoding_clang_type_resolve_state = eResolveStateForward;
550                     break;
551                 default:
552                     break;
553                 }
554             }
555             encoding_type->ResolveClangType (encoding_clang_type_resolve_state);
556         }
557     }
558     return m_clang_type != NULL;
559 }
560 
561 clang_type_t
562 lldb_private::Type::GetChildClangTypeAtIndex
563 (
564     const char *parent_name,
565     uint32_t idx,
566     bool transparent_pointers,
567     bool omit_empty_base_classes,
568     ConstString& name,
569     uint32_t &child_byte_size,
570     int32_t &child_byte_offset,
571     uint32_t &child_bitfield_bit_size,
572     uint32_t &child_bitfield_bit_offset,
573     bool &child_is_base_class
574 )
575 {
576     clang_type_t child_qual_type = NULL;
577 
578     if (GetClangType())
579     {
580         std::string name_str;
581         child_qual_type = GetClangASTContext().GetChildClangTypeAtIndex (parent_name,
582                                                                          m_clang_type,
583                                                                          idx,
584                                                                          transparent_pointers,
585                                                                          omit_empty_base_classes,
586                                                                          name_str,
587                                                                          child_byte_size,
588                                                                          child_byte_offset,
589                                                                          child_bitfield_bit_size,
590                                                                          child_bitfield_bit_offset,
591                                                                          child_is_base_class);
592 
593         if (child_qual_type)
594         {
595             if (!name_str.empty())
596                 name.SetCString(name_str.c_str());
597             else
598                 name.Clear();
599         }
600     }
601     return child_qual_type;
602 }
603 
604 uint32_t
605 lldb_private::Type::GetEncodingMask ()
606 {
607     uint32_t encoding_mask = 1u << m_encoding_uid_type;
608     Type *encoding_type = GetEncodingType();
609     assert (encoding_type != this);
610     if (encoding_type)
611         encoding_mask |= encoding_type->GetEncodingMask ();
612     return encoding_mask;
613 }
614 
615 clang_type_t
616 lldb_private::Type::GetClangType ()
617 {
618     ResolveClangType(eResolveStateFull);
619     return m_clang_type;
620 }
621 
622 clang_type_t
623 lldb_private::Type::GetClangLayoutType ()
624 {
625     ResolveClangType(eResolveStateLayout);
626     return m_clang_type;
627 }
628 
629 clang_type_t
630 lldb_private::Type::GetClangForwardType ()
631 {
632     ResolveClangType (eResolveStateForward);
633     return m_clang_type;
634 }
635 
636 clang::ASTContext *
637 lldb_private::Type::GetClangAST ()
638 {
639     TypeList *type_list = GetTypeList();
640     if (type_list)
641         return type_list->GetClangASTContext().getASTContext();
642     return NULL;
643 }
644 
645 lldb_private::ClangASTContext &
646 lldb_private::Type::GetClangASTContext ()
647 {
648     return GetTypeList()->GetClangASTContext();
649 }
650 
651 int
652 lldb_private::Type::Compare(const Type &a, const Type &b)
653 {
654     // Just compare the UID values for now...
655     lldb::user_id_t a_uid = a.GetID();
656     lldb::user_id_t b_uid = b.GetID();
657     if (a_uid < b_uid)
658         return -1;
659     if (a_uid > b_uid)
660         return 1;
661     return 0;
662 //  if (a.getQualType() == b.getQualType())
663 //      return 0;
664 }
665 
666