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