blob: 1993f23310584a37d849ae21214596b3b245c7bb [file] [log] [blame]
Ryan Brown57bee1e2015-09-14 22:45:11 +00001//===-- GoASTContext.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#include <mutex>
11#include <utility>
12#include <vector>
13
Greg Clayton56939cb2015-09-17 22:23:34 +000014#include "lldb/Core/Module.h"
15#include "lldb/Core/PluginManager.h"
Ryan Brown47d072ca2016-01-15 19:35:48 +000016#include "lldb/Core/StreamFile.h"
Ryan Brown57bee1e2015-09-14 22:45:11 +000017#include "lldb/Core/UniqueCStringMap.h"
18#include "lldb/Core/ValueObject.h"
19#include "lldb/DataFormatters/StringPrinter.h"
20#include "lldb/Symbol/CompilerType.h"
Greg Clayton56939cb2015-09-17 22:23:34 +000021#include "lldb/Symbol/ObjectFile.h"
Ryan Brown57bee1e2015-09-14 22:45:11 +000022#include "lldb/Symbol/SymbolFile.h"
23#include "lldb/Symbol/GoASTContext.h"
24#include "lldb/Symbol/Type.h"
25#include "lldb/Target/ExecutionContext.h"
Greg Clayton5beec212015-10-08 21:04:34 +000026#include "lldb/Target/Target.h"
Ryan Brown57bee1e2015-09-14 22:45:11 +000027
Ryan Brown998c8a1c12015-11-02 19:30:40 +000028#include "Plugins/ExpressionParser/Go/GoUserExpression.h"
Ryan Brown57bee1e2015-09-14 22:45:11 +000029#include "Plugins/SymbolFile/DWARF/DWARFASTParserGo.h"
30
31using namespace lldb;
32
33namespace lldb_private
34{
35class GoArray;
36class GoFunction;
37class GoStruct;
38
39class GoType
40{
41 public:
42 enum
43 {
44 KIND_BOOL = 1,
45 KIND_INT = 2,
46 KIND_INT8 = 3,
47 KIND_INT16 = 4,
48 KIND_INT32 = 5,
49 KIND_INT64 = 6,
50 KIND_UINT = 7,
51 KIND_UINT8 = 8,
52 KIND_UINT16 = 9,
53 KIND_UINT32 = 10,
54 KIND_UINT64 = 11,
55 KIND_UINTPTR = 12,
56 KIND_FLOAT32 = 13,
57 KIND_FLOAT64 = 14,
58 KIND_COMPLEX64 = 15,
59 KIND_COMPLEX128 = 16,
60 KIND_ARRAY = 17,
61 KIND_CHAN = 18,
62 KIND_FUNC = 19,
63 KIND_INTERFACE = 20,
64 KIND_MAP = 21,
65 KIND_PTR = 22,
66 KIND_SLICE = 23,
67 KIND_STRING = 24,
68 KIND_STRUCT = 25,
69 KIND_UNSAFEPOINTER = 26,
70 KIND_LLDB_VOID, // Extension for LLDB, not used by go runtime.
71 KIND_MASK = (1 << 5) - 1,
72 KIND_DIRECT_IFACE = 1 << 5
73 };
74 GoType(int kind, const ConstString &name)
75 : m_kind(kind & KIND_MASK)
76 , m_name(name)
77 {
78 if (m_kind == KIND_FUNC)
79 m_kind = KIND_FUNC;
80 }
81 virtual ~GoType() {}
82
83 int
84 GetGoKind() const
85 {
86 return m_kind;
87 }
88 const ConstString &
89 GetName() const
90 {
91 return m_name;
92 }
93 virtual CompilerType
94 GetElementType() const
95 {
96 return CompilerType();
97 }
98
99 bool
100 IsTypedef() const
101 {
102 switch (m_kind)
103 {
104 case KIND_CHAN:
105 case KIND_MAP:
106 case KIND_INTERFACE:
107 return true;
108 default:
109 return false;
110 }
111 }
112
113 GoArray *GetArray();
114 GoFunction *GetFunction();
115 GoStruct *GetStruct();
116
117 private:
118 int m_kind;
119 ConstString m_name;
120 GoType(const GoType &) = delete;
121 const GoType &operator=(const GoType &) = delete;
122};
123
124class GoElem : public GoType
125{
126 public:
127 GoElem(int kind, const ConstString &name, const CompilerType &elem)
128 : GoType(kind, name)
129 , m_elem(elem)
130 {
131 }
132 virtual CompilerType
133 GetElementType() const
134 {
135 return m_elem;
136 }
137
138 private:
139 // TODO: should we store this differently?
140 CompilerType m_elem;
141
142 GoElem(const GoElem &) = delete;
143 const GoElem &operator=(const GoElem &) = delete;
144};
145
146class GoArray : public GoElem
147{
148 public:
Bruce Mitchener500737e2015-09-15 04:33:48 +0000149 GoArray(const ConstString &name, uint64_t length, const CompilerType &elem)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000150 : GoElem(KIND_ARRAY, name, elem)
151 , m_length(length)
152 {
153 }
154
Bruce Mitchener500737e2015-09-15 04:33:48 +0000155 uint64_t
Ryan Brown57bee1e2015-09-14 22:45:11 +0000156 GetLength() const
157 {
158 return m_length;
159 }
160
161 private:
Bruce Mitchener500737e2015-09-15 04:33:48 +0000162 uint64_t m_length;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000163 GoArray(const GoArray &) = delete;
164 const GoArray &operator=(const GoArray &) = delete;
165};
166
167class GoFunction : public GoType
168{
169 public:
170 GoFunction(const ConstString &name, bool is_variadic)
171 : GoType(KIND_FUNC, name)
172 , m_is_variadic(is_variadic)
173 {
174 }
175
176 bool
177 IsVariadic() const
178 {
179 return m_is_variadic;
180 }
181
182 private:
183 bool m_is_variadic;
184 GoFunction(const GoFunction &) = delete;
185 const GoFunction &operator=(const GoFunction &) = delete;
186};
187
188class GoStruct : public GoType
189{
190 public:
191 struct Field
192 {
193 Field(const ConstString &name, const CompilerType &type, uint64_t offset)
194 : m_name(name)
195 , m_type(type)
196 , m_byte_offset(offset)
197 {
198 }
199 ConstString m_name;
200 CompilerType m_type;
201 uint64_t m_byte_offset;
202 };
203
204 GoStruct(int kind, const ConstString &name, int64_t byte_size)
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000205 : GoType(kind == 0 ? KIND_STRUCT : kind, name), m_is_complete(false), m_byte_size(byte_size)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000206 {
207 }
208
209 uint32_t
210 GetNumFields() const
211 {
212 return m_fields.size();
213 }
214
215 const Field *
216 GetField(uint32_t i) const
217 {
218 if (i < m_fields.size())
219 return &m_fields[i];
220 return nullptr;
221 }
222
223 void
224 AddField(const ConstString &name, const CompilerType &type, uint64_t offset)
225 {
226 m_fields.push_back(Field(name, type, offset));
227 }
228
229 bool
230 IsComplete() const
231 {
232 return m_is_complete;
233 }
234
235 void
236 SetComplete()
237 {
238 m_is_complete = true;
239 }
240
241 int64_t
242 GetByteSize() const
243 {
244 return m_byte_size;
245 }
246
247 private:
248 bool m_is_complete;
249 int64_t m_byte_size;
250 std::vector<Field> m_fields;
251
252 GoStruct(const GoStruct &) = delete;
253 const GoStruct &operator=(const GoStruct &) = delete;
254};
255
256GoArray *
257GoType::GetArray()
258{
259 if (m_kind == KIND_ARRAY)
260 {
261 return static_cast<GoArray *>(this);
262 }
263 return nullptr;
264}
265
266GoFunction *
267GoType::GetFunction()
268{
269 if (m_kind == KIND_FUNC)
270 {
271 return static_cast<GoFunction *>(this);
272 }
273 return nullptr;
274}
275
276GoStruct *
277GoType::GetStruct()
278{
279 switch (m_kind)
280 {
281 case KIND_STRING:
282 case KIND_STRUCT:
283 case KIND_SLICE:
284 return static_cast<GoStruct *>(this);
285 }
286 return nullptr;
287}
288} // namespace lldb_private
289using namespace lldb_private;
290
291GoASTContext::GoASTContext()
292 : TypeSystem(eKindGo)
293 , m_pointer_byte_size(0)
294 , m_int_byte_size(0)
295 , m_types(new TypeMap)
296{
297}
298GoASTContext::~GoASTContext()
299{
300}
301
Greg Clayton56939cb2015-09-17 22:23:34 +0000302//------------------------------------------------------------------
303// PluginInterface functions
304//------------------------------------------------------------------
305
306ConstString
307GoASTContext::GetPluginNameStatic()
308{
309 return ConstString("go");
310}
311
312ConstString
313GoASTContext::GetPluginName()
314{
315 return GoASTContext::GetPluginNameStatic();
316}
317
318uint32_t
319GoASTContext::GetPluginVersion()
320{
321 return 1;
322}
323
324lldb::TypeSystemSP
Greg Clayton5beec212015-10-08 21:04:34 +0000325GoASTContext::CreateInstance (lldb::LanguageType language, Module *module, Target *target)
Greg Clayton56939cb2015-09-17 22:23:34 +0000326{
327 if (language == eLanguageTypeGo)
328 {
Greg Clayton5beec212015-10-08 21:04:34 +0000329 ArchSpec arch;
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000330 std::shared_ptr<GoASTContext> go_ast_sp;
Greg Clayton5beec212015-10-08 21:04:34 +0000331 if (module)
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000332 {
Greg Clayton5beec212015-10-08 21:04:34 +0000333 arch = module->GetArchitecture();
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000334 go_ast_sp = std::shared_ptr<GoASTContext>(new GoASTContext);
335 }
Greg Clayton5beec212015-10-08 21:04:34 +0000336 else if (target)
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000337 {
Greg Clayton5beec212015-10-08 21:04:34 +0000338 arch = target->GetArchitecture();
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000339 go_ast_sp = std::shared_ptr<GoASTContextForExpr>(new GoASTContextForExpr(target->shared_from_this()));
340 }
Greg Clayton5beec212015-10-08 21:04:34 +0000341
Greg Clayton56939cb2015-09-17 22:23:34 +0000342 if (arch.IsValid())
343 {
Greg Clayton56939cb2015-09-17 22:23:34 +0000344 go_ast_sp->SetAddressByteSize(arch.GetAddressByteSize());
345 return go_ast_sp;
346 }
347 }
348 return lldb::TypeSystemSP();
349}
350
Sean Callananfe38c852015-10-08 23:07:53 +0000351void
352GoASTContext::EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types, std::set<lldb::LanguageType> &languages_for_expressions)
353{
354 static std::vector<lldb::LanguageType> s_supported_languages_for_types({
355 lldb::eLanguageTypeGo});
356
357 static std::vector<lldb::LanguageType> s_supported_languages_for_expressions({});
358
359 languages_for_types.insert(s_supported_languages_for_types.begin(), s_supported_languages_for_types.end());
360 languages_for_expressions.insert(s_supported_languages_for_expressions.begin(), s_supported_languages_for_expressions.end());
361}
362
Greg Clayton56939cb2015-09-17 22:23:34 +0000363
364void
365GoASTContext::Initialize()
366{
367 PluginManager::RegisterPlugin (GetPluginNameStatic(),
368 "AST context plug-in",
Sean Callananfe38c852015-10-08 23:07:53 +0000369 CreateInstance,
370 EnumerateSupportedLanguages);
Greg Clayton56939cb2015-09-17 22:23:34 +0000371}
372
373void
374GoASTContext::Terminate()
375{
376 PluginManager::UnregisterPlugin (CreateInstance);
377}
378
379
Ryan Brown57bee1e2015-09-14 22:45:11 +0000380//----------------------------------------------------------------------
381// Tests
382//----------------------------------------------------------------------
383
384bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000385GoASTContext::IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size, bool *is_incomplete)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000386{
387 if (element_type)
388 element_type->Clear();
389 if (size)
390 *size = 0;
391 if (is_incomplete)
392 *is_incomplete = false;
393 GoArray *array = static_cast<GoType *>(type)->GetArray();
394 if (array)
395 {
Bruce Mitchener500737e2015-09-15 04:33:48 +0000396 if (size)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000397 *size = array->GetLength();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000398 if (element_type)
399 *element_type = array->GetElementType();
400 return true;
401 }
402 return false;
403}
404
405bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000406GoASTContext::IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000407{
408 if (element_type)
409 element_type->Clear();
410 if (size)
411 *size = 0;
412 return false;
413}
414
415bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000416GoASTContext::IsAggregateType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000417{
418 int kind = static_cast<GoType *>(type)->GetGoKind();
419 if (kind < GoType::KIND_ARRAY)
420 return false;
421 if (kind == GoType::KIND_PTR)
422 return false;
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000423 if (kind == GoType::KIND_CHAN)
424 return false;
425 if (kind == GoType::KIND_MAP)
426 return false;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000427 if (kind == GoType::KIND_STRING)
428 return false;
429 if (kind == GoType::KIND_UNSAFEPOINTER)
430 return false;
431 return true;
432}
433
434bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000435GoASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000436{
437 return false;
438}
439
440bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000441GoASTContext::IsCharType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000442{
443 // Go's DWARF doesn't distinguish between rune and int32.
444 return false;
445}
446
447bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000448GoASTContext::IsCompleteType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000449{
450 if (!type)
451 return false;
452 GoType *t = static_cast<GoType *>(type);
453 if (GoStruct *s = t->GetStruct())
454 return s->IsComplete();
455 if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR)
456 return t->GetElementType().IsCompleteType();
457 return true;
458}
459
460bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000461GoASTContext::IsConst(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000462{
463 return false;
464}
465
466bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000467GoASTContext::IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000468{
469 return false;
470}
471
472bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000473GoASTContext::IsDefined(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000474{
475 return type != nullptr;
476}
477
478bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000479GoASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000480{
481 int kind = static_cast<GoType *>(type)->GetGoKind();
482 if (kind >= GoType::KIND_FLOAT32 && kind <= GoType::KIND_COMPLEX128)
483 {
484 if (kind >= GoType::KIND_COMPLEX64)
485 {
486 is_complex = true;
487 count = 2;
488 }
489 else
490 {
491 is_complex = false;
492 count = 1;
493 }
494 return true;
495 }
496 count = 0;
497 is_complex = false;
498 return false;
499}
500
501bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000502GoASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000503{
504 GoFunction *func = static_cast<GoType *>(type)->GetFunction();
505 if (func)
506 {
507 if (is_variadic_ptr)
508 *is_variadic_ptr = func->IsVariadic();
509 return true;
510 }
511 if (is_variadic_ptr)
512 *is_variadic_ptr = false;
513 return false;
514}
515
516uint32_t
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000517GoASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000518{
519 return false;
520}
521
522size_t
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000523GoASTContext::GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000524{
525 return 0;
526}
527
528CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000529GoASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000530{
531 return CompilerType();
532}
533
534bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000535GoASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000536{
537 return IsFunctionType(type);
538}
539
540bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000541GoASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000542{
543 is_signed = false;
544 // TODO: Is bool an integer?
545 if (type)
546 {
547 int kind = static_cast<GoType *>(type)->GetGoKind();
548 if (kind <= GoType::KIND_UINTPTR)
549 {
550 is_signed = (kind != GoType::KIND_BOOL) & (kind <= GoType::KIND_INT64);
551 return true;
552 }
553 }
554 return false;
555}
556
557bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000558GoASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000559{
560 return false;
561}
562
563bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000564GoASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
Ryan Brown57bee1e2015-09-14 22:45:11 +0000565 CompilerType *target_type, // Can pass NULL
566 bool check_cplusplus, bool check_objc)
567{
568 if (target_type)
569 target_type->Clear();
570 if (type)
571 return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_INTERFACE;
572 return false;
573}
574
575bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000576GoASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000577{
578 return false;
579}
580
581bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000582GoASTContext::IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000583{
584 if (!type)
585 return false;
586 GoType *t = static_cast<GoType *>(type);
587 if (pointee_type)
588 {
589 *pointee_type = t->GetElementType();
590 }
591 switch (t->GetGoKind())
592 {
593 case GoType::KIND_PTR:
594 case GoType::KIND_UNSAFEPOINTER:
595 case GoType::KIND_CHAN:
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000596 case GoType::KIND_MAP:
597 // TODO: is function a pointer?
Ryan Brown57bee1e2015-09-14 22:45:11 +0000598 return true;
599 default:
600 return false;
601 }
602}
603
604bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000605GoASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000606{
607 return IsPointerType(type, pointee_type);
608}
609
610bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000611GoASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000612{
613 return false;
614}
615
616bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000617GoASTContext::IsScalarType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000618{
619 return !IsAggregateType(type);
620}
621
622bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000623GoASTContext::IsTypedefType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000624{
625 if (type)
626 return static_cast<GoType *>(type)->IsTypedef();
627 return false;
628}
629
630bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000631GoASTContext::IsVoidType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000632{
633 if (!type)
634 return false;
635 return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_LLDB_VOID;
636}
637
Greg Clayton56939cb2015-09-17 22:23:34 +0000638bool
639GoASTContext::SupportsLanguage (lldb::LanguageType language)
640{
641 return language == eLanguageTypeGo;
642}
643
Ryan Brown57bee1e2015-09-14 22:45:11 +0000644//----------------------------------------------------------------------
645// Type Completion
646//----------------------------------------------------------------------
647
648bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000649GoASTContext::GetCompleteType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000650{
651 if (!type)
652 return false;
653 GoType *t = static_cast<GoType *>(type);
654 if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR || t->GetArray())
655 return t->GetElementType().GetCompleteType();
656 if (GoStruct *s = t->GetStruct())
657 {
658 if (s->IsComplete())
659 return true;
660 CompilerType compiler_type(this, s);
661 SymbolFile *symbols = GetSymbolFile();
662 return symbols && symbols->CompleteType(compiler_type);
663 }
664 return true;
665}
666
667//----------------------------------------------------------------------
668// AST related queries
669//----------------------------------------------------------------------
670
671uint32_t
672GoASTContext::GetPointerByteSize()
673{
674 return m_pointer_byte_size;
675}
676
677//----------------------------------------------------------------------
678// Accessors
679//----------------------------------------------------------------------
680
681ConstString
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000682GoASTContext::GetTypeName(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000683{
684 if (type)
685 return static_cast<GoType *>(type)->GetName();
686 return ConstString();
687}
688
689uint32_t
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000690GoASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000691{
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000692 if (pointee_or_element_compiler_type)
693 pointee_or_element_compiler_type->Clear();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000694 if (!type)
695 return 0;
696 GoType *t = static_cast<GoType *>(type);
Bruce Mitchener3ad353f2015-09-24 03:54:50 +0000697 if (pointee_or_element_compiler_type)
698 *pointee_or_element_compiler_type = t->GetElementType();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000699 int kind = t->GetGoKind();
700 if (kind == GoType::KIND_ARRAY)
701 return eTypeHasChildren | eTypeIsArray;
702 if (kind < GoType::KIND_ARRAY)
703 {
704 uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
705 if (kind < GoType::KIND_FLOAT32)
706 {
707 builtin_type_flags |= eTypeIsInteger | eTypeIsScalar;
708 if (kind >= GoType::KIND_INT && kind <= GoType::KIND_INT64)
709 builtin_type_flags |= eTypeIsSigned;
710 }
711 else
712 {
713 builtin_type_flags |= eTypeIsFloat;
714 if (kind < GoType::KIND_COMPLEX64)
715 builtin_type_flags |= eTypeIsComplex;
716 else
717 builtin_type_flags |= eTypeIsScalar;
718 }
719 return builtin_type_flags;
720 }
721 if (kind == GoType::KIND_STRING)
722 return eTypeHasValue | eTypeIsBuiltIn;
723 if (kind == GoType::KIND_FUNC)
724 return eTypeIsFuncPrototype | eTypeHasValue;
725 if (IsPointerType(type))
726 return eTypeIsPointer | eTypeHasValue | eTypeHasChildren;
727 if (kind == GoType::KIND_LLDB_VOID)
728 return 0;
729 return eTypeHasChildren | eTypeIsStructUnion;
730}
731
732lldb::TypeClass
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000733GoASTContext::GetTypeClass(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000734{
735 if (!type)
736 return eTypeClassInvalid;
737 int kind = static_cast<GoType *>(type)->GetGoKind();
738 if (kind == GoType::KIND_FUNC)
739 return eTypeClassFunction;
740 if (IsPointerType(type))
741 return eTypeClassPointer;
742 if (kind < GoType::KIND_COMPLEX64)
743 return eTypeClassBuiltin;
744 if (kind <= GoType::KIND_COMPLEX128)
745 return eTypeClassComplexFloat;
746 if (kind == GoType::KIND_LLDB_VOID)
747 return eTypeClassInvalid;
748 return eTypeClassStruct;
749}
750
751lldb::BasicType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000752GoASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000753{
754 ConstString name = GetTypeName(type);
755 if (name)
756 {
757 typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
758 static TypeNameToBasicTypeMap g_type_map;
759 static std::once_flag g_once_flag;
760 std::call_once(g_once_flag, [](){
761 // "void"
762 g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
763 // "int"
764 g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
765 g_type_map.Append(ConstString("uint").GetCString(), eBasicTypeUnsignedInt);
766
767 // Miscellaneous
768 g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
769
770 // Others. Should these map to C types?
771 g_type_map.Append(ConstString("byte").GetCString(), eBasicTypeOther);
772 g_type_map.Append(ConstString("uint8").GetCString(), eBasicTypeOther);
773 g_type_map.Append(ConstString("uint16").GetCString(), eBasicTypeOther);
774 g_type_map.Append(ConstString("uint32").GetCString(), eBasicTypeOther);
775 g_type_map.Append(ConstString("uint64").GetCString(), eBasicTypeOther);
776 g_type_map.Append(ConstString("int8").GetCString(), eBasicTypeOther);
777 g_type_map.Append(ConstString("int16").GetCString(), eBasicTypeOther);
778 g_type_map.Append(ConstString("int32").GetCString(), eBasicTypeOther);
779 g_type_map.Append(ConstString("int64").GetCString(), eBasicTypeOther);
780 g_type_map.Append(ConstString("float32").GetCString(), eBasicTypeOther);
781 g_type_map.Append(ConstString("float64").GetCString(), eBasicTypeOther);
782 g_type_map.Append(ConstString("uintptr").GetCString(), eBasicTypeOther);
783
784 g_type_map.Sort();
785 });
786
787 return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
788 }
789 return eBasicTypeInvalid;
790}
791
792lldb::LanguageType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000793GoASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000794{
795 return lldb::eLanguageTypeGo;
796}
797
798unsigned
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000799GoASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000800{
801 return 0;
802}
803
804//----------------------------------------------------------------------
805// Creating related types
806//----------------------------------------------------------------------
807
808CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000809GoASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000810{
811 GoArray *array = static_cast<GoType *>(type)->GetArray();
812 if (array)
813 {
814 if (stride)
815 {
816 *stride = array->GetElementType().GetByteSize(nullptr);
817 }
818 return array->GetElementType();
819 }
820 return CompilerType();
821}
822
823CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000824GoASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000825{
826 GoType *t = static_cast<GoType *>(type);
827 if (t->IsTypedef())
828 return t->GetElementType();
829 return CompilerType(this, type);
830}
831
832CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000833GoASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000834{
835 return CompilerType(this, type);
836}
837
838// Returns -1 if this isn't a function of if the function doesn't have a prototype
839// Returns a value >= 0 if there is a prototype.
840int
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000841GoASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000842{
843 return GetNumberOfFunctionArguments(type);
844}
845
846CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000847GoASTContext::GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000848{
849 return GetFunctionArgumentAtIndex(type, idx);
850}
851
852CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000853GoASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000854{
855 CompilerType result;
856 if (type)
857 {
858 GoType *t = static_cast<GoType *>(type);
859 if (t->GetGoKind() == GoType::KIND_FUNC)
860 result = t->GetElementType();
861 }
862 return result;
863}
864
865size_t
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000866GoASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000867{
868 return 0;
869}
870
871TypeMemberFunctionImpl
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000872GoASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000873{
874 return TypeMemberFunctionImpl();
875}
876
877CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000878GoASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000879{
880 return CompilerType(this, type);
881}
882
883CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000884GoASTContext::GetPointeeType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000885{
886 if (!type)
887 return CompilerType();
888 return static_cast<GoType *>(type)->GetElementType();
889}
890
891CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000892GoASTContext::GetPointerType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000893{
894 if (!type)
895 return CompilerType();
896 ConstString type_name = GetTypeName(type);
897 ConstString pointer_name(std::string("*") + type_name.GetCString());
898 GoType *pointer = (*m_types)[pointer_name].get();
899 if (pointer == nullptr)
900 {
901 pointer = new GoElem(GoType::KIND_PTR, pointer_name, CompilerType(this, type));
902 (*m_types)[pointer_name].reset(pointer);
903 }
904 return CompilerType(this, pointer);
905}
906
907// If the current object represents a typedef type, get the underlying type
908CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000909GoASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000910{
911 if (IsTypedefType(type))
912 return static_cast<GoType *>(type)->GetElementType();
913 return CompilerType();
914}
915
916//----------------------------------------------------------------------
917// Create related types using the current type's AST
918//----------------------------------------------------------------------
919CompilerType
920GoASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type)
921{
922 return CompilerType();
923}
924
Greg Clayton56939cb2015-09-17 22:23:34 +0000925CompilerType
926GoASTContext::GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding,
927 size_t bit_size)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000928{
929 return CompilerType();
930}
931
932
933//----------------------------------------------------------------------
934// Exploring the type
935//----------------------------------------------------------------------
936
937uint64_t
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000938GoASTContext::GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000939{
940 if (!type)
941 return 0;
942 if (!GetCompleteType(type))
943 return 0;
944 GoType *t = static_cast<GoType *>(type);
945 GoArray *array = nullptr;
946 switch (t->GetGoKind())
947 {
948 case GoType::KIND_BOOL:
949 case GoType::KIND_INT8:
950 case GoType::KIND_UINT8:
951 return 8;
952 case GoType::KIND_INT16:
953 case GoType::KIND_UINT16:
954 return 16;
955 case GoType::KIND_INT32:
956 case GoType::KIND_UINT32:
957 case GoType::KIND_FLOAT32:
958 return 32;
959 case GoType::KIND_INT64:
960 case GoType::KIND_UINT64:
961 case GoType::KIND_FLOAT64:
962 case GoType::KIND_COMPLEX64:
963 return 64;
964 case GoType::KIND_COMPLEX128:
965 return 128;
966 case GoType::KIND_INT:
967 case GoType::KIND_UINT:
968 return m_int_byte_size * 8;
969 case GoType::KIND_UINTPTR:
970 case GoType::KIND_FUNC: // I assume this is a pointer?
971 case GoType::KIND_CHAN:
972 case GoType::KIND_PTR:
973 case GoType::KIND_UNSAFEPOINTER:
974 case GoType::KIND_MAP:
975 return m_pointer_byte_size * 8;
976 case GoType::KIND_ARRAY:
977 array = t->GetArray();
978 return array->GetLength() * array->GetElementType().GetBitSize(exe_scope);
979 case GoType::KIND_INTERFACE:
980 return t->GetElementType().GetBitSize(exe_scope);
981 case GoType::KIND_SLICE:
982 case GoType::KIND_STRING:
983 case GoType::KIND_STRUCT:
984 return t->GetStruct()->GetByteSize() * 8;
985 default:
986 assert(false);
987 }
Ryan Brownd03c2e02015-09-15 00:50:43 +0000988 return 0;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000989}
990
991lldb::Encoding
Bruce Mitchener48ea9002015-09-23 00:18:24 +0000992GoASTContext::GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000993{
994 count = 1;
995 bool is_signed;
996 if (IsIntegerType(type, is_signed))
997 return is_signed ? lldb::eEncodingSint : eEncodingUint;
998 bool is_complex;
999 uint32_t complex_count;
1000 if (IsFloatingPointType(type, complex_count, is_complex))
1001 {
1002 count = complex_count;
1003 return eEncodingIEEE754;
1004 }
1005 if (IsPointerType(type))
1006 return eEncodingUint;
1007 return eEncodingInvalid;
1008}
1009
1010lldb::Format
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001011GoASTContext::GetFormat(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001012{
1013 if (!type)
1014 return eFormatDefault;
1015 switch (static_cast<GoType *>(type)->GetGoKind())
1016 {
1017 case GoType::KIND_BOOL:
1018 return eFormatBoolean;
1019 case GoType::KIND_INT:
1020 case GoType::KIND_INT8:
1021 case GoType::KIND_INT16:
1022 case GoType::KIND_INT32:
1023 case GoType::KIND_INT64:
1024 return eFormatDecimal;
1025 case GoType::KIND_UINT:
1026 case GoType::KIND_UINT8:
1027 case GoType::KIND_UINT16:
1028 case GoType::KIND_UINT32:
1029 case GoType::KIND_UINT64:
1030 return eFormatUnsigned;
1031 case GoType::KIND_FLOAT32:
1032 case GoType::KIND_FLOAT64:
1033 return eFormatFloat;
1034 case GoType::KIND_COMPLEX64:
1035 case GoType::KIND_COMPLEX128:
1036 return eFormatComplexFloat;
1037 case GoType::KIND_UINTPTR:
1038 case GoType::KIND_CHAN:
1039 case GoType::KIND_PTR:
1040 case GoType::KIND_MAP:
1041 case GoType::KIND_UNSAFEPOINTER:
1042 return eFormatHex;
1043 case GoType::KIND_STRING:
1044 return eFormatCString;
1045 case GoType::KIND_ARRAY:
1046 case GoType::KIND_INTERFACE:
1047 case GoType::KIND_SLICE:
1048 case GoType::KIND_STRUCT:
1049 default:
1050 // Don't know how to display this.
1051 return eFormatBytes;
1052 }
1053}
1054
1055size_t
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001056GoASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001057{
1058 return 0;
1059}
1060
1061uint32_t
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001062GoASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001063{
1064 if (!type || !GetCompleteType(type))
1065 return 0;
1066 GoType *t = static_cast<GoType *>(type);
1067 if (t->GetGoKind() == GoType::KIND_PTR)
1068 {
1069 CompilerType elem = t->GetElementType();
1070 if (elem.IsAggregateType())
1071 return elem.GetNumChildren(omit_empty_base_classes);
1072 return 1;
1073 }
1074 else if (GoArray *array = t->GetArray())
1075 {
1076 return array->GetLength();
1077 }
Ryan Brown998c8a1c12015-11-02 19:30:40 +00001078 else if (t->IsTypedef())
1079 {
1080 return t->GetElementType().GetNumChildren(omit_empty_base_classes);
1081 }
1082
Ryan Brown57bee1e2015-09-14 22:45:11 +00001083 return GetNumFields(type);
1084}
1085
1086uint32_t
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001087GoASTContext::GetNumFields(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001088{
1089 if (!type || !GetCompleteType(type))
1090 return 0;
1091 GoType *t = static_cast<GoType *>(type);
1092 if (t->IsTypedef())
1093 return t->GetElementType().GetNumFields();
1094 GoStruct *s = t->GetStruct();
1095 if (s)
1096 return s->GetNumFields();
1097 return 0;
1098}
1099
1100CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001101GoASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, std::string &name, uint64_t *bit_offset_ptr,
Ryan Brown57bee1e2015-09-14 22:45:11 +00001102 uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr)
1103{
1104 if (bit_offset_ptr)
1105 *bit_offset_ptr = 0;
1106 if (bitfield_bit_size_ptr)
1107 *bitfield_bit_size_ptr = 0;
1108 if (is_bitfield_ptr)
1109 *is_bitfield_ptr = false;
1110
1111 if (!type || !GetCompleteType(type))
1112 return CompilerType();
1113
1114 GoType *t = static_cast<GoType *>(type);
1115 if (t->IsTypedef())
1116 return t->GetElementType().GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
1117
1118 GoStruct *s = t->GetStruct();
1119 if (s)
1120 {
1121 const auto *field = s->GetField(idx);
1122 if (field)
1123 {
1124 name = field->m_name.GetStringRef();
1125 if (bit_offset_ptr)
1126 *bit_offset_ptr = field->m_byte_offset * 8;
1127 return field->m_type;
1128 }
1129 }
1130 return CompilerType();
1131}
1132
1133CompilerType
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001134GoASTContext::GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
Bruce Mitchener4ad83342015-09-21 16:48:48 +00001135 bool omit_empty_base_classes, bool ignore_array_bounds, std::string &child_name,
1136 uint32_t &child_byte_size, int32_t &child_byte_offset,
1137 uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
Enrico Granatadc62ffd2015-11-09 19:27:34 +00001138 bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj, uint64_t &language_flags)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001139{
1140 child_name.clear();
1141 child_byte_size = 0;
1142 child_byte_offset = 0;
1143 child_bitfield_bit_size = 0;
1144 child_bitfield_bit_offset = 0;
1145 child_is_base_class = false;
1146 child_is_deref_of_parent = false;
Enrico Granatadc62ffd2015-11-09 19:27:34 +00001147 language_flags = 0;
Ryan Brown57bee1e2015-09-14 22:45:11 +00001148
1149 if (!type || !GetCompleteType(type))
1150 return CompilerType();
1151
1152 GoType *t = static_cast<GoType *>(type);
1153 if (t->GetStruct())
1154 {
1155 uint64_t bit_offset;
1156 CompilerType ret = GetFieldAtIndex(type, idx, child_name, &bit_offset, nullptr, nullptr);
1157 child_byte_size = ret.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
1158 child_byte_offset = bit_offset / 8;
1159 return ret;
1160 }
1161 else if (t->GetGoKind() == GoType::KIND_PTR)
1162 {
1163 CompilerType pointee = t->GetElementType();
1164 if (!pointee.IsValid() || pointee.IsVoidType())
1165 return CompilerType();
1166 if (transparent_pointers && pointee.IsAggregateType())
1167 {
1168 bool tmp_child_is_deref_of_parent = false;
Bruce Mitchener4ad83342015-09-21 16:48:48 +00001169 return pointee.GetChildCompilerTypeAtIndex(exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
Ryan Brown57bee1e2015-09-14 22:45:11 +00001170 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
1171 child_bitfield_bit_size, child_bitfield_bit_offset,
Enrico Granatadc62ffd2015-11-09 19:27:34 +00001172 child_is_base_class, tmp_child_is_deref_of_parent, valobj, language_flags);
Ryan Brown57bee1e2015-09-14 22:45:11 +00001173 }
1174 else
1175 {
1176 child_is_deref_of_parent = true;
1177 const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
1178 if (parent_name)
1179 {
1180 child_name.assign(1, '*');
1181 child_name += parent_name;
1182 }
1183
1184 // We have a pointer to an simple type
1185 if (idx == 0 && pointee.GetCompleteType())
1186 {
1187 child_byte_size = pointee.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
1188 child_byte_offset = 0;
1189 return pointee;
1190 }
1191 }
1192 }
1193 else if (GoArray *a = t->GetArray())
1194 {
1195 if (ignore_array_bounds || idx < a->GetLength())
1196 {
1197 CompilerType element_type = a->GetElementType();
1198 if (element_type.GetCompleteType())
1199 {
1200 char element_name[64];
1201 ::snprintf(element_name, sizeof(element_name), "[%zu]", idx);
1202 child_name.assign(element_name);
1203 child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
1204 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
1205 return element_type;
1206 }
1207 }
1208 }
1209 else if (t->IsTypedef())
1210 {
Bruce Mitchener4ad83342015-09-21 16:48:48 +00001211 return t->GetElementType().GetChildCompilerTypeAtIndex(
Ryan Brown57bee1e2015-09-14 22:45:11 +00001212 exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name,
1213 child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
Enrico Granatadc62ffd2015-11-09 19:27:34 +00001214 child_is_deref_of_parent, valobj, language_flags);
Ryan Brown57bee1e2015-09-14 22:45:11 +00001215 }
1216 return CompilerType();
1217}
1218
1219// Lookup a child given a name. This function will match base class names
1220// and member member names in "clang_type" only, not descendants.
1221uint32_t
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001222GoASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001223{
Ryan Brown07a1c452015-10-06 20:29:31 +00001224 if (!type || !GetCompleteType(type))
1225 return UINT_MAX;
1226
Ryan Brown57bee1e2015-09-14 22:45:11 +00001227 GoType *t = static_cast<GoType *>(type);
1228 GoStruct *s = t->GetStruct();
1229 if (s)
1230 {
1231 for (uint32_t i = 0; i < s->GetNumFields(); ++i)
1232 {
1233 const GoStruct::Field *f = s->GetField(i);
1234 if (f->m_name.GetStringRef() == name)
1235 return i;
1236 }
1237 }
1238 else if (t->GetGoKind() == GoType::KIND_PTR || t->IsTypedef())
1239 {
1240 return t->GetElementType().GetIndexOfChildWithName(name, omit_empty_base_classes);
1241 }
1242 return UINT_MAX;
1243}
1244
1245// Lookup a child member given a name. This function will match member names
1246// only and will descend into "clang_type" children in search for the first
1247// member in this class, or any base class that matches "name".
1248// TODO: Return all matches for a given name by returning a vector<vector<uint32_t>>
1249// so we catch all names that match a given child name, not just the first.
1250size_t
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001251GoASTContext::GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes,
Ryan Brown57bee1e2015-09-14 22:45:11 +00001252 std::vector<uint32_t> &child_indexes)
1253{
1254 uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes);
1255 if (index == UINT_MAX)
1256 return 0;
1257 child_indexes.push_back(index);
1258 return 1;
1259}
1260
1261// Converts "s" to a floating point value and place resulting floating
1262// point bytes in the "dst" buffer.
1263size_t
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001264GoASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst, size_t dst_size)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001265{
1266 assert(false);
Ryan Brownd03c2e02015-09-15 00:50:43 +00001267 return 0;
Ryan Brown57bee1e2015-09-14 22:45:11 +00001268}
1269//----------------------------------------------------------------------
1270// Dumping types
1271//----------------------------------------------------------------------
Ryan Brown47d072ca2016-01-15 19:35:48 +00001272#define DEPTH_INCREMENT 2
1273
Ryan Brown57bee1e2015-09-14 22:45:11 +00001274void
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001275GoASTContext::DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format,
Ryan Brown47d072ca2016-01-15 19:35:48 +00001276 const DataExtractor &data, lldb::offset_t data_byte_offset, size_t data_byte_size,
Ryan Brown57bee1e2015-09-14 22:45:11 +00001277 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary,
1278 bool verbose, uint32_t depth)
1279{
Ryan Brown47d072ca2016-01-15 19:35:48 +00001280 if (IsTypedefType(type))
1281 type = GetTypedefedType(type).GetOpaqueQualType();
1282 if (!type)
1283 return;
1284 GoType *t = static_cast<GoType *>(type);
1285
1286 if (GoStruct *st = t->GetStruct())
1287 {
1288 if (GetCompleteType(type))
1289 {
1290 uint32_t field_idx = 0;
1291 for (auto* field = st->GetField(field_idx); field != nullptr; field_idx++)
1292 {
1293 // Print the starting squiggly bracket (if this is the
1294 // first member) or comma (for member 2 and beyond) for
1295 // the struct/union/class member.
1296 if (field_idx == 0)
1297 s->PutChar('{');
1298 else
1299 s->PutChar(',');
1300
1301 // Indent
1302 s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
1303
1304 // Print the member type if requested
1305 if (show_types)
1306 {
1307 ConstString field_type_name = field->m_type.GetTypeName();
1308 s->Printf("(%s) ", field_type_name.AsCString());
1309 }
1310 // Print the member name and equal sign
1311 s->Printf("%s = ", field->m_name.AsCString());
1312
1313
1314 // Dump the value of the member
1315 CompilerType field_type = field->m_type;
1316 field_type.DumpValue (exe_ctx,
1317 s, // Stream to dump to
1318 field_type.GetFormat(), // The format with which to display the member
1319 data, // Data buffer containing all bytes for this type
1320 data_byte_offset + field->m_byte_offset,// Offset into "data" where to grab value from
1321 field->m_type.GetByteSize(exe_ctx->GetBestExecutionContextScope()), // Size of this type in bytes
1322 0, // Bitfield bit size
1323 0, // Bitfield bit offset
1324 show_types, // Boolean indicating if we should show the variable types
1325 show_summary, // Boolean indicating if we should show a summary for the current type
1326 verbose, // Verbose output?
1327 depth + DEPTH_INCREMENT); // Scope depth for any types that have children
1328 }
1329
1330 // Indent the trailing squiggly bracket
1331 if (field_idx > 0)
1332 s->Printf("\n%*s}", depth, "");
1333
1334 }
1335 }
1336
1337 if (GoArray *a = t->GetArray()) {
1338 CompilerType element_clang_type = a->GetElementType();
1339 lldb::Format element_format = element_clang_type.GetFormat();
1340 uint32_t element_byte_size = element_clang_type.GetByteSize(exe_ctx->GetBestExecutionContextScope());
1341
1342 uint64_t element_idx;
1343 for (element_idx = 0; element_idx < a->GetLength(); ++element_idx)
1344 {
1345 // Print the starting squiggly bracket (if this is the
1346 // first member) or comman (for member 2 and beyong) for
1347 // the struct/union/class member.
1348 if (element_idx == 0)
1349 s->PutChar('{');
1350 else
1351 s->PutChar(',');
1352
1353 // Indent and print the index
1354 s->Printf("\n%*s[%" PRIu64 "] ", depth + DEPTH_INCREMENT, "", element_idx);
1355
1356 // Figure out the field offset within the current struct/union/class type
1357 uint64_t element_offset = element_idx * element_byte_size;
1358
1359 // Dump the value of the member
1360 element_clang_type.DumpValue (exe_ctx,
1361 s, // Stream to dump to
1362 element_format, // The format with which to display the element
1363 data, // Data buffer containing all bytes for this type
1364 data_byte_offset + element_offset,// Offset into "data" where to grab value from
1365 element_byte_size, // Size of this type in bytes
1366 0, // Bitfield bit size
1367 0, // Bitfield bit offset
1368 show_types, // Boolean indicating if we should show the variable types
1369 show_summary, // Boolean indicating if we should show a summary for the current type
1370 verbose, // Verbose output?
1371 depth + DEPTH_INCREMENT); // Scope depth for any types that have children
1372 }
1373
1374 // Indent the trailing squiggly bracket
1375 if (element_idx > 0)
1376 s->Printf("\n%*s}", depth, "");
1377 }
1378
1379 if (show_summary)
1380 DumpSummary (type, exe_ctx, s, data, data_byte_offset, data_byte_size);
Ryan Brown57bee1e2015-09-14 22:45:11 +00001381}
1382
1383bool
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001384GoASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, const DataExtractor &data,
Ryan Brown57bee1e2015-09-14 22:45:11 +00001385 lldb::offset_t byte_offset, size_t byte_size, uint32_t bitfield_bit_size,
1386 uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope)
1387{
1388 if (!type)
1389 return false;
1390 if (IsAggregateType(type))
1391 {
1392 return false;
1393 }
1394 else
1395 {
1396 GoType *t = static_cast<GoType *>(type);
1397 if (t->IsTypedef())
1398 {
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001399 CompilerType typedef_compiler_type = t->GetElementType();
Ryan Brown57bee1e2015-09-14 22:45:11 +00001400 if (format == eFormatDefault)
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001401 format = typedef_compiler_type.GetFormat();
1402 uint64_t typedef_byte_size = typedef_compiler_type.GetByteSize(exe_scope);
Ryan Brown57bee1e2015-09-14 22:45:11 +00001403
Bruce Mitchener3ad353f2015-09-24 03:54:50 +00001404 return typedef_compiler_type.DumpTypeValue(
Ryan Brown57bee1e2015-09-14 22:45:11 +00001405 s,
1406 format, // The format with which to display the element
1407 data, // Data buffer containing all bytes for this type
1408 byte_offset, // Offset into "data" where to grab value from
1409 typedef_byte_size, // Size of this type in bytes
1410 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't treat as a bitfield
1411 bitfield_bit_offset, // Offset in bits of a bitfield value if bitfield_bit_size != 0
1412 exe_scope);
1413 }
1414
1415 uint32_t item_count = 1;
1416 // A few formats, we might need to modify our size and count for depending
1417 // on how we are trying to display the value...
1418 switch (format)
1419 {
1420 default:
1421 case eFormatBoolean:
1422 case eFormatBinary:
1423 case eFormatComplex:
1424 case eFormatCString: // NULL terminated C strings
1425 case eFormatDecimal:
1426 case eFormatEnum:
1427 case eFormatHex:
1428 case eFormatHexUppercase:
1429 case eFormatFloat:
1430 case eFormatOctal:
1431 case eFormatOSType:
1432 case eFormatUnsigned:
1433 case eFormatPointer:
1434 case eFormatVectorOfChar:
1435 case eFormatVectorOfSInt8:
1436 case eFormatVectorOfUInt8:
1437 case eFormatVectorOfSInt16:
1438 case eFormatVectorOfUInt16:
1439 case eFormatVectorOfSInt32:
1440 case eFormatVectorOfUInt32:
1441 case eFormatVectorOfSInt64:
1442 case eFormatVectorOfUInt64:
1443 case eFormatVectorOfFloat32:
1444 case eFormatVectorOfFloat64:
1445 case eFormatVectorOfUInt128:
1446 break;
1447
1448 case eFormatChar:
1449 case eFormatCharPrintable:
1450 case eFormatCharArray:
1451 case eFormatBytes:
1452 case eFormatBytesWithASCII:
1453 item_count = byte_size;
1454 byte_size = 1;
1455 break;
1456
1457 case eFormatUnicode16:
1458 item_count = byte_size / 2;
1459 byte_size = 2;
1460 break;
1461
1462 case eFormatUnicode32:
1463 item_count = byte_size / 4;
1464 byte_size = 4;
1465 break;
1466 }
1467 return data.Dump(s, byte_offset, format, byte_size, item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
1468 bitfield_bit_size, bitfield_bit_offset, exe_scope);
1469 }
1470 return 0;
1471}
1472
1473void
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001474GoASTContext::DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data,
Ryan Brown57bee1e2015-09-14 22:45:11 +00001475 lldb::offset_t data_offset, size_t data_byte_size)
1476{
Ryan Brown47d072ca2016-01-15 19:35:48 +00001477 if (type && GoType::KIND_STRING == static_cast<GoType *>(type)->GetGoKind())
1478 {
1479 // TODO(ribrdb): read length and data
1480 }
Ryan Brown57bee1e2015-09-14 22:45:11 +00001481}
1482
1483void
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001484GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001485{
Ryan Brown47d072ca2016-01-15 19:35:48 +00001486 // Dump to stdout
1487 StreamFile s (stdout, false);
1488 DumpTypeDescription (type, &s);
1489}
Ryan Brown57bee1e2015-09-14 22:45:11 +00001490
1491void
Bruce Mitchener48ea9002015-09-23 00:18:24 +00001492GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001493{
Ryan Brown47d072ca2016-01-15 19:35:48 +00001494 if (!type)
1495 return;
1496 ConstString name = GetTypeName(type);
1497 GoType *t = static_cast<GoType *>(type);
1498
1499 if (GoStruct *st = t->GetStruct())
1500 {
1501 if (GetCompleteType(type))
1502 {
1503 if (NULL == strchr(name.AsCString(), '{'))
1504 s->Printf("type %s ", name.AsCString());
1505 s->PutCString("struct {");
1506 if (st->GetNumFields() == 0) {
1507 s->PutChar('}');
1508 return;
1509 }
1510 s->IndentMore();
1511 uint32_t field_idx = 0;
1512 for (auto* field = st->GetField(field_idx); field != nullptr; field_idx++)
1513 {
1514 s->PutChar('\n');
1515 s->Indent();
1516 s->Printf("%s %s", field->m_name.AsCString(), field->m_type.GetTypeName().AsCString());
1517 }
1518 s->IndentLess();
1519 s->PutChar('\n');
1520 s->Indent("}");
1521 return;
1522 }
1523 }
1524
1525 s->PutCString(name.AsCString());
Ryan Brown57bee1e2015-09-14 22:45:11 +00001526}
1527
1528CompilerType
Bruce Mitchener500737e2015-09-15 04:33:48 +00001529GoASTContext::CreateArrayType(const ConstString &name, const CompilerType &element_type, uint64_t length)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001530{
1531 GoType *type = new GoArray(name, length, element_type);
1532 (*m_types)[name].reset(type);
1533 return CompilerType(this, type);
1534}
1535
1536CompilerType
1537GoASTContext::CreateBaseType(int go_kind, const lldb_private::ConstString &name, uint64_t byte_size)
1538{
1539 if (go_kind == GoType::KIND_UINT || go_kind == GoType::KIND_INT)
1540 m_int_byte_size = byte_size;
1541 GoType *type = new GoType(go_kind, name);
1542 (*m_types)[name].reset(type);
1543 return CompilerType(this, type);
1544}
1545
1546CompilerType
Greg Clayton56939cb2015-09-17 22:23:34 +00001547GoASTContext::CreateTypedefType(int kind, const ConstString &name, CompilerType impl)
Ryan Brown57bee1e2015-09-14 22:45:11 +00001548{
1549 GoType *type = new GoElem(kind, name, impl);
1550 (*m_types)[name].reset(type);
1551 return CompilerType(this, type);
1552}
1553
1554CompilerType
1555GoASTContext::CreateVoidType(const lldb_private::ConstString &name)
1556{
1557 GoType *type = new GoType(GoType::KIND_LLDB_VOID, name);
1558 (*m_types)[name].reset(type);
1559 return CompilerType(this, type);
1560}
1561
1562CompilerType
1563GoASTContext::CreateStructType(int kind, const lldb_private::ConstString &name, uint32_t byte_size)
1564{
1565 GoType *type = new GoStruct(kind, name, byte_size);
1566 (*m_types)[name].reset(type);
1567 return CompilerType(this, type);
1568}
1569
1570void
1571GoASTContext::AddFieldToStruct(const lldb_private::CompilerType &struct_type, const lldb_private::ConstString &name,
1572 const lldb_private::CompilerType &field_type, uint32_t byte_offset)
1573{
1574 if (!struct_type)
1575 return;
1576 GoASTContext *ast = llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem());
1577 if (!ast)
1578 return;
1579 GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType());
1580 if (GoStruct *s = type->GetStruct())
1581 s->AddField(name, field_type, byte_offset);
1582}
1583
1584void
1585GoASTContext::CompleteStructType(const lldb_private::CompilerType &struct_type)
1586{
1587 if (!struct_type)
1588 return;
1589 GoASTContext *ast = llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem());
1590 if (!ast)
1591 return;
1592 GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType());
1593 if (GoStruct *s = type->GetStruct())
1594 s->SetComplete();
1595}
1596
1597CompilerType
1598GoASTContext::CreateFunctionType(const lldb_private::ConstString &name, CompilerType *params, size_t params_count,
1599 bool is_variadic)
1600{
1601 GoType *type = new GoFunction(name, is_variadic);
1602 (*m_types)[name].reset(type);
1603 return CompilerType(this, type);
1604}
1605
1606bool
1607GoASTContext::IsGoString(const lldb_private::CompilerType &type)
1608{
1609 if (!type.IsValid() || !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1610 return false;
1611 return GoType::KIND_STRING == static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
1612}
1613
1614bool
1615GoASTContext::IsGoSlice(const lldb_private::CompilerType &type)
1616{
1617 if (!type.IsValid() || !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1618 return false;
1619 return GoType::KIND_SLICE == static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
1620}
1621
1622bool
1623GoASTContext::IsGoInterface(const lldb_private::CompilerType &type)
1624{
1625 if (!type.IsValid() || !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1626 return false;
1627 return GoType::KIND_INTERFACE == static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
1628}
1629
1630bool
1631GoASTContext::IsPointerKind(uint8_t kind)
1632{
1633 return (kind & GoType::KIND_MASK) == GoType::KIND_PTR;
1634}
1635
1636bool
1637GoASTContext::IsDirectIface(uint8_t kind)
1638{
1639 return (kind & GoType::KIND_DIRECT_IFACE) == GoType::KIND_DIRECT_IFACE;
1640}
1641
1642DWARFASTParser *
1643GoASTContext::GetDWARFParser()
1644{
1645 if (!m_dwarf_ast_parser_ap)
1646 m_dwarf_ast_parser_ap.reset(new DWARFASTParserGo(*this));
1647 return m_dwarf_ast_parser_ap.get();
1648}
Ryan Brown998c8a1c12015-11-02 19:30:40 +00001649
1650UserExpression *
1651GoASTContextForExpr::GetUserExpression(const char *expr, const char *expr_prefix, lldb::LanguageType language,
Jim Ingham19a63fc2015-11-03 02:11:24 +00001652 Expression::ResultType desired_type, const EvaluateExpressionOptions &options)
Ryan Brown998c8a1c12015-11-02 19:30:40 +00001653{
1654 TargetSP target = m_target_wp.lock();
1655 if (target)
Jim Ingham19a63fc2015-11-03 02:11:24 +00001656 return new GoUserExpression(*target, expr, expr_prefix, language, desired_type, options);
Ryan Brown998c8a1c12015-11-02 19:30:40 +00001657 return nullptr;
1658}