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