blob: 0393691f45c0459b3f7c46506b6ef2a6d414bcca [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"
Kate Stoneb9c1b512016-09-06 20:57:50 +000021#include "lldb/Symbol/GoASTContext.h"
Greg Clayton56939cb2015-09-17 22:23:34 +000022#include "lldb/Symbol/ObjectFile.h"
Ryan Brown57bee1e2015-09-14 22:45:11 +000023#include "lldb/Symbol/SymbolFile.h"
Ryan Brown57bee1e2015-09-14 22:45:11 +000024#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
Kate Stoneb9c1b512016-09-06 20:57:50 +000033namespace lldb_private {
Ryan Brown57bee1e2015-09-14 22:45:11 +000034class GoArray;
35class GoFunction;
36class GoStruct;
37
Kate Stoneb9c1b512016-09-06 20:57:50 +000038class GoType {
39public:
40 enum {
41 KIND_BOOL = 1,
42 KIND_INT = 2,
43 KIND_INT8 = 3,
44 KIND_INT16 = 4,
45 KIND_INT32 = 5,
46 KIND_INT64 = 6,
47 KIND_UINT = 7,
48 KIND_UINT8 = 8,
49 KIND_UINT16 = 9,
50 KIND_UINT32 = 10,
51 KIND_UINT64 = 11,
52 KIND_UINTPTR = 12,
53 KIND_FLOAT32 = 13,
54 KIND_FLOAT64 = 14,
55 KIND_COMPLEX64 = 15,
56 KIND_COMPLEX128 = 16,
57 KIND_ARRAY = 17,
58 KIND_CHAN = 18,
59 KIND_FUNC = 19,
60 KIND_INTERFACE = 20,
61 KIND_MAP = 21,
62 KIND_PTR = 22,
63 KIND_SLICE = 23,
64 KIND_STRING = 24,
65 KIND_STRUCT = 25,
66 KIND_UNSAFEPOINTER = 26,
67 KIND_LLDB_VOID, // Extension for LLDB, not used by go runtime.
68 KIND_MASK = (1 << 5) - 1,
69 KIND_DIRECT_IFACE = 1 << 5
70 };
71 GoType(int kind, const ConstString &name)
72 : m_kind(kind & KIND_MASK), m_name(name) {
Ryan Brown57bee1e2015-09-14 22:45:11 +000073 if (m_kind == KIND_FUNC)
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 m_kind = KIND_FUNC;
75 }
76 virtual ~GoType() {}
77
78 int GetGoKind() const { return m_kind; }
79 const ConstString &GetName() const { return m_name; }
80 virtual CompilerType GetElementType() const { return CompilerType(); }
81
82 bool IsTypedef() const {
83 switch (m_kind) {
84 case KIND_CHAN:
85 case KIND_MAP:
86 case KIND_INTERFACE:
87 return true;
88 default:
89 return false;
Ryan Brown57bee1e2015-09-14 22:45:11 +000090 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 }
92
93 GoArray *GetArray();
94 GoFunction *GetFunction();
95 GoStruct *GetStruct();
96
97private:
98 int m_kind;
99 ConstString m_name;
100 GoType(const GoType &) = delete;
101 const GoType &operator=(const GoType &) = delete;
102};
103
104class GoElem : public GoType {
105public:
106 GoElem(int kind, const ConstString &name, const CompilerType &elem)
107 : GoType(kind, name), m_elem(elem) {}
108 virtual CompilerType GetElementType() const { return m_elem; }
109
110private:
111 // TODO: should we store this differently?
112 CompilerType m_elem;
113
114 GoElem(const GoElem &) = delete;
115 const GoElem &operator=(const GoElem &) = delete;
116};
117
118class GoArray : public GoElem {
119public:
120 GoArray(const ConstString &name, uint64_t length, const CompilerType &elem)
121 : GoElem(KIND_ARRAY, name, elem), m_length(length) {}
122
123 uint64_t GetLength() const { return m_length; }
124
125private:
126 uint64_t m_length;
127 GoArray(const GoArray &) = delete;
128 const GoArray &operator=(const GoArray &) = delete;
129};
130
131class GoFunction : public GoType {
132public:
133 GoFunction(const ConstString &name, bool is_variadic)
134 : GoType(KIND_FUNC, name), m_is_variadic(is_variadic) {}
135
136 bool IsVariadic() const { return m_is_variadic; }
137
138private:
139 bool m_is_variadic;
140 GoFunction(const GoFunction &) = delete;
141 const GoFunction &operator=(const GoFunction &) = delete;
142};
143
144class GoStruct : public GoType {
145public:
146 struct Field {
147 Field(const ConstString &name, const CompilerType &type, uint64_t offset)
148 : m_name(name), m_type(type), m_byte_offset(offset) {}
149 ConstString m_name;
150 CompilerType m_type;
151 uint64_t m_byte_offset;
152 };
153
154 GoStruct(int kind, const ConstString &name, int64_t byte_size)
155 : GoType(kind == 0 ? KIND_STRUCT : kind, name), m_is_complete(false),
156 m_byte_size(byte_size) {}
157
158 uint32_t GetNumFields() const { return m_fields.size(); }
159
160 const Field *GetField(uint32_t i) const {
161 if (i < m_fields.size())
162 return &m_fields[i];
Ryan Brown57bee1e2015-09-14 22:45:11 +0000163 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 }
165
166 void AddField(const ConstString &name, const CompilerType &type,
167 uint64_t offset) {
168 m_fields.push_back(Field(name, type, offset));
169 }
170
171 bool IsComplete() const { return m_is_complete; }
172
173 void SetComplete() { m_is_complete = true; }
174
175 int64_t GetByteSize() const { return m_byte_size; }
176
177private:
178 bool m_is_complete;
179 int64_t m_byte_size;
180 std::vector<Field> m_fields;
181
182 GoStruct(const GoStruct &) = delete;
183 const GoStruct &operator=(const GoStruct &) = delete;
184};
185
186GoArray *GoType::GetArray() {
187 if (m_kind == KIND_ARRAY) {
188 return static_cast<GoArray *>(this);
189 }
190 return nullptr;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000191}
192
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193GoFunction *GoType::GetFunction() {
194 if (m_kind == KIND_FUNC) {
195 return static_cast<GoFunction *>(this);
196 }
197 return nullptr;
198}
199
200GoStruct *GoType::GetStruct() {
201 switch (m_kind) {
202 case KIND_STRING:
203 case KIND_STRUCT:
204 case KIND_SLICE:
205 return static_cast<GoStruct *>(this);
206 }
207 return nullptr;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000208}
209} // namespace lldb_private
210using namespace lldb_private;
211
212GoASTContext::GoASTContext()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213 : TypeSystem(eKindGo), m_pointer_byte_size(0), m_int_byte_size(0),
214 m_types(new TypeMap) {}
215GoASTContext::~GoASTContext() {}
Ryan Brown57bee1e2015-09-14 22:45:11 +0000216
Greg Clayton56939cb2015-09-17 22:23:34 +0000217//------------------------------------------------------------------
218// PluginInterface functions
219//------------------------------------------------------------------
220
Kate Stoneb9c1b512016-09-06 20:57:50 +0000221ConstString GoASTContext::GetPluginNameStatic() { return ConstString("go"); }
222
223ConstString GoASTContext::GetPluginName() {
224 return GoASTContext::GetPluginNameStatic();
Greg Clayton56939cb2015-09-17 22:23:34 +0000225}
226
Kate Stoneb9c1b512016-09-06 20:57:50 +0000227uint32_t GoASTContext::GetPluginVersion() { return 1; }
Greg Clayton56939cb2015-09-17 22:23:34 +0000228
Kate Stoneb9c1b512016-09-06 20:57:50 +0000229lldb::TypeSystemSP GoASTContext::CreateInstance(lldb::LanguageType language,
230 Module *module,
231 Target *target) {
232 if (language == eLanguageTypeGo) {
233 ArchSpec arch;
234 std::shared_ptr<GoASTContext> go_ast_sp;
235 if (module) {
236 arch = module->GetArchitecture();
237 go_ast_sp = std::shared_ptr<GoASTContext>(new GoASTContext);
238 } else if (target) {
239 arch = target->GetArchitecture();
240 go_ast_sp = std::shared_ptr<GoASTContextForExpr>(
241 new GoASTContextForExpr(target->shared_from_this()));
Greg Clayton56939cb2015-09-17 22:23:34 +0000242 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000243
244 if (arch.IsValid()) {
245 go_ast_sp->SetAddressByteSize(arch.GetAddressByteSize());
246 return go_ast_sp;
247 }
248 }
249 return lldb::TypeSystemSP();
Greg Clayton56939cb2015-09-17 22:23:34 +0000250}
251
Kate Stoneb9c1b512016-09-06 20:57:50 +0000252void GoASTContext::EnumerateSupportedLanguages(
253 std::set<lldb::LanguageType> &languages_for_types,
254 std::set<lldb::LanguageType> &languages_for_expressions) {
255 static std::vector<lldb::LanguageType> s_supported_languages_for_types(
256 {lldb::eLanguageTypeGo});
257
258 static std::vector<lldb::LanguageType> s_supported_languages_for_expressions(
259 {});
260
261 languages_for_types.insert(s_supported_languages_for_types.begin(),
262 s_supported_languages_for_types.end());
263 languages_for_expressions.insert(
264 s_supported_languages_for_expressions.begin(),
265 s_supported_languages_for_expressions.end());
Sean Callananfe38c852015-10-08 23:07:53 +0000266}
267
Kate Stoneb9c1b512016-09-06 20:57:50 +0000268void GoASTContext::Initialize() {
269 PluginManager::RegisterPlugin(GetPluginNameStatic(), "AST context plug-in",
270 CreateInstance, EnumerateSupportedLanguages);
Greg Clayton56939cb2015-09-17 22:23:34 +0000271}
272
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273void GoASTContext::Terminate() {
274 PluginManager::UnregisterPlugin(CreateInstance);
Greg Clayton56939cb2015-09-17 22:23:34 +0000275}
276
Ryan Brown57bee1e2015-09-14 22:45:11 +0000277//----------------------------------------------------------------------
278// Tests
279//----------------------------------------------------------------------
280
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281bool GoASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
282 CompilerType *element_type, uint64_t *size,
283 bool *is_incomplete) {
284 if (element_type)
285 element_type->Clear();
286 if (size)
287 *size = 0;
288 if (is_incomplete)
289 *is_incomplete = false;
290 GoArray *array = static_cast<GoType *>(type)->GetArray();
291 if (array) {
Ryan Brown57bee1e2015-09-14 22:45:11 +0000292 if (size)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000293 *size = array->GetLength();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000294 if (element_type)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295 *element_type = array->GetElementType();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000296 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000297 }
298 return false;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000299}
300
Kate Stoneb9c1b512016-09-06 20:57:50 +0000301bool GoASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
302 CompilerType *element_type, uint64_t *size) {
303 if (element_type)
304 element_type->Clear();
305 if (size)
306 *size = 0;
307 return false;
308}
309
310bool GoASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
311 int kind = static_cast<GoType *>(type)->GetGoKind();
312 if (kind < GoType::KIND_ARRAY)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000313 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000314 if (kind == GoType::KIND_PTR)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000315 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000316 if (kind == GoType::KIND_CHAN)
317 return false;
318 if (kind == GoType::KIND_MAP)
319 return false;
320 if (kind == GoType::KIND_STRING)
321 return false;
322 if (kind == GoType::KIND_UNSAFEPOINTER)
323 return false;
324 return true;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000325}
326
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327bool GoASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
328 return false;
329}
330
331bool GoASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
332 // Go's DWARF doesn't distinguish between rune and int32.
333 return false;
334}
335
336bool GoASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
337 if (!type)
338 return false;
339 GoType *t = static_cast<GoType *>(type);
340 if (GoStruct *s = t->GetStruct())
341 return s->IsComplete();
342 if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR)
343 return t->GetElementType().IsCompleteType();
344 return true;
345}
346
347bool GoASTContext::IsConst(lldb::opaque_compiler_type_t type) { return false; }
348
349bool GoASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
350 uint32_t &length) {
351 return false;
352}
353
354bool GoASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
355 return type != nullptr;
356}
357
358bool GoASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
359 uint32_t &count, bool &is_complex) {
360 int kind = static_cast<GoType *>(type)->GetGoKind();
361 if (kind >= GoType::KIND_FLOAT32 && kind <= GoType::KIND_COMPLEX128) {
362 if (kind >= GoType::KIND_COMPLEX64) {
363 is_complex = true;
364 count = 2;
365 } else {
366 is_complex = false;
367 count = 1;
368 }
Ryan Brown57bee1e2015-09-14 22:45:11 +0000369 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000370 }
371 count = 0;
372 is_complex = false;
373 return false;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000374}
375
Kate Stoneb9c1b512016-09-06 20:57:50 +0000376bool GoASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
377 bool *is_variadic_ptr) {
378 GoFunction *func = static_cast<GoType *>(type)->GetFunction();
379 if (func) {
Ryan Brown57bee1e2015-09-14 22:45:11 +0000380 if (is_variadic_ptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000381 *is_variadic_ptr = func->IsVariadic();
382 return true;
383 }
384 if (is_variadic_ptr)
385 *is_variadic_ptr = false;
386 return false;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000387}
388
Kate Stoneb9c1b512016-09-06 20:57:50 +0000389uint32_t GoASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
390 CompilerType *base_type_ptr) {
391 return false;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000392}
393
394size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395GoASTContext::GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) {
396 return 0;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000397}
398
399CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400GoASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
401 const size_t index) {
402 return CompilerType();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000403}
404
Kate Stoneb9c1b512016-09-06 20:57:50 +0000405bool GoASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
406 return IsFunctionType(type);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000407}
408
Kate Stoneb9c1b512016-09-06 20:57:50 +0000409bool GoASTContext::IsBlockPointerType(lldb::opaque_compiler_type_t type,
410 CompilerType *function_pointer_type_ptr) {
411 return false;
Sean Callananc530ba92016-05-02 21:15:31 +0000412}
413
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414bool GoASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
415 bool &is_signed) {
416 is_signed = false;
417 // TODO: Is bool an integer?
418 if (type) {
419 int kind = static_cast<GoType *>(type)->GetGoKind();
420 if (kind <= GoType::KIND_UINTPTR) {
421 is_signed = (kind != GoType::KIND_BOOL) & (kind <= GoType::KIND_INT64);
422 return true;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000423 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000424 }
425 return false;
426}
427
428bool GoASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
429 return false;
430}
431
432bool GoASTContext::IsPossibleDynamicType(
433 lldb::opaque_compiler_type_t type,
434 CompilerType *target_type, // Can pass NULL
435 bool check_cplusplus, bool check_objc) {
436 if (target_type)
437 target_type->Clear();
438 if (type)
439 return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_INTERFACE;
440 return false;
441}
442
443bool GoASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) {
444 return false;
445}
446
447bool GoASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
448 CompilerType *pointee_type) {
449 if (!type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000450 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451 GoType *t = static_cast<GoType *>(type);
452 if (pointee_type) {
453 *pointee_type = t->GetElementType();
454 }
455 switch (t->GetGoKind()) {
456 case GoType::KIND_PTR:
457 case GoType::KIND_UNSAFEPOINTER:
458 case GoType::KIND_CHAN:
459 case GoType::KIND_MAP:
460 // TODO: is function a pointer?
461 return true;
462 default:
Ryan Brown57bee1e2015-09-14 22:45:11 +0000463 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464 }
Ryan Brown57bee1e2015-09-14 22:45:11 +0000465}
466
Kate Stoneb9c1b512016-09-06 20:57:50 +0000467bool GoASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
468 CompilerType *pointee_type) {
469 return IsPointerType(type, pointee_type);
470}
471
472bool GoASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
473 CompilerType *pointee_type,
474 bool *is_rvalue) {
475 return false;
476}
477
478bool GoASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
479 return !IsAggregateType(type);
480}
481
482bool GoASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
483 if (type)
484 return static_cast<GoType *>(type)->IsTypedef();
485 return false;
486}
487
488bool GoASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
489 if (!type)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000490 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000491 return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_LLDB_VOID;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000492}
493
Kate Stoneb9c1b512016-09-06 20:57:50 +0000494bool GoASTContext::SupportsLanguage(lldb::LanguageType language) {
495 return language == eLanguageTypeGo;
Greg Clayton56939cb2015-09-17 22:23:34 +0000496}
497
Ryan Brown57bee1e2015-09-14 22:45:11 +0000498//----------------------------------------------------------------------
499// Type Completion
500//----------------------------------------------------------------------
501
Kate Stoneb9c1b512016-09-06 20:57:50 +0000502bool GoASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
503 if (!type)
504 return false;
505 GoType *t = static_cast<GoType *>(type);
506 if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR || t->GetArray())
507 return t->GetElementType().GetCompleteType();
508 if (GoStruct *s = t->GetStruct()) {
509 if (s->IsComplete())
510 return true;
511 CompilerType compiler_type(this, s);
512 SymbolFile *symbols = GetSymbolFile();
513 return symbols && symbols->CompleteType(compiler_type);
514 }
515 return true;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000516}
517
518//----------------------------------------------------------------------
519// AST related queries
520//----------------------------------------------------------------------
521
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522uint32_t GoASTContext::GetPointerByteSize() { return m_pointer_byte_size; }
Ryan Brown57bee1e2015-09-14 22:45:11 +0000523
524//----------------------------------------------------------------------
525// Accessors
526//----------------------------------------------------------------------
527
Kate Stoneb9c1b512016-09-06 20:57:50 +0000528ConstString GoASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
529 if (type)
530 return static_cast<GoType *>(type)->GetName();
531 return ConstString();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000532}
533
534uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535GoASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
536 CompilerType *pointee_or_element_compiler_type) {
537 if (pointee_or_element_compiler_type)
538 pointee_or_element_compiler_type->Clear();
539 if (!type)
540 return 0;
541 GoType *t = static_cast<GoType *>(type);
542 if (pointee_or_element_compiler_type)
543 *pointee_or_element_compiler_type = t->GetElementType();
544 int kind = t->GetGoKind();
545 if (kind == GoType::KIND_ARRAY)
546 return eTypeHasChildren | eTypeIsArray;
547 if (kind < GoType::KIND_ARRAY) {
548 uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
549 if (kind < GoType::KIND_FLOAT32) {
550 builtin_type_flags |= eTypeIsInteger | eTypeIsScalar;
551 if (kind >= GoType::KIND_INT && kind <= GoType::KIND_INT64)
552 builtin_type_flags |= eTypeIsSigned;
553 } else {
554 builtin_type_flags |= eTypeIsFloat;
555 if (kind < GoType::KIND_COMPLEX64)
556 builtin_type_flags |= eTypeIsComplex;
557 else
558 builtin_type_flags |= eTypeIsScalar;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000559 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560 return builtin_type_flags;
561 }
562 if (kind == GoType::KIND_STRING)
563 return eTypeHasValue | eTypeIsBuiltIn;
564 if (kind == GoType::KIND_FUNC)
565 return eTypeIsFuncPrototype | eTypeHasValue;
566 if (IsPointerType(type))
567 return eTypeIsPointer | eTypeHasValue | eTypeHasChildren;
568 if (kind == GoType::KIND_LLDB_VOID)
569 return 0;
570 return eTypeHasChildren | eTypeIsStructUnion;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000571}
572
Kate Stoneb9c1b512016-09-06 20:57:50 +0000573lldb::TypeClass GoASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
574 if (!type)
575 return eTypeClassInvalid;
576 int kind = static_cast<GoType *>(type)->GetGoKind();
577 if (kind == GoType::KIND_FUNC)
578 return eTypeClassFunction;
579 if (IsPointerType(type))
580 return eTypeClassPointer;
581 if (kind < GoType::KIND_COMPLEX64)
582 return eTypeClassBuiltin;
583 if (kind <= GoType::KIND_COMPLEX128)
584 return eTypeClassComplexFloat;
585 if (kind == GoType::KIND_LLDB_VOID)
586 return eTypeClassInvalid;
587 return eTypeClassStruct;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000588}
589
590lldb::BasicType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000591GoASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
592 ConstString name = GetTypeName(type);
593 if (name) {
594 typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
595 static TypeNameToBasicTypeMap g_type_map;
596 static std::once_flag g_once_flag;
597 std::call_once(g_once_flag, []() {
598 // "void"
Zachary Turner4fa098a2016-10-06 21:22:44 +0000599 g_type_map.Append(ConstString("void").GetStringRef(), eBasicTypeVoid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000600 // "int"
Zachary Turner4fa098a2016-10-06 21:22:44 +0000601 g_type_map.Append(ConstString("int").GetStringRef(), eBasicTypeInt);
602 g_type_map.Append(ConstString("uint").GetStringRef(),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000603 eBasicTypeUnsignedInt);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000604
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605 // Miscellaneous
Zachary Turner4fa098a2016-10-06 21:22:44 +0000606 g_type_map.Append(ConstString("bool").GetStringRef(), eBasicTypeBool);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000607
Kate Stoneb9c1b512016-09-06 20:57:50 +0000608 // Others. Should these map to C types?
Zachary Turner4fa098a2016-10-06 21:22:44 +0000609 g_type_map.Append(ConstString("byte").GetStringRef(), eBasicTypeOther);
610 g_type_map.Append(ConstString("uint8").GetStringRef(), eBasicTypeOther);
611 g_type_map.Append(ConstString("uint16").GetStringRef(), eBasicTypeOther);
612 g_type_map.Append(ConstString("uint32").GetStringRef(), eBasicTypeOther);
613 g_type_map.Append(ConstString("uint64").GetStringRef(), eBasicTypeOther);
614 g_type_map.Append(ConstString("int8").GetStringRef(), eBasicTypeOther);
615 g_type_map.Append(ConstString("int16").GetStringRef(), eBasicTypeOther);
616 g_type_map.Append(ConstString("int32").GetStringRef(), eBasicTypeOther);
617 g_type_map.Append(ConstString("int64").GetStringRef(), eBasicTypeOther);
618 g_type_map.Append(ConstString("float32").GetStringRef(), eBasicTypeOther);
619 g_type_map.Append(ConstString("float64").GetStringRef(), eBasicTypeOther);
620 g_type_map.Append(ConstString("uintptr").GetStringRef(), eBasicTypeOther);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000621
622 g_type_map.Sort();
623 });
624
Zachary Turner4fa098a2016-10-06 21:22:44 +0000625 return g_type_map.Find(name.GetStringRef(), eBasicTypeInvalid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000626 }
627 return eBasicTypeInvalid;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000628}
629
630lldb::LanguageType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000631GoASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
632 return lldb::eLanguageTypeGo;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000633}
634
Kate Stoneb9c1b512016-09-06 20:57:50 +0000635unsigned GoASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
636 return 0;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000637}
638
639//----------------------------------------------------------------------
640// Creating related types
641//----------------------------------------------------------------------
642
643CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000644GoASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
645 uint64_t *stride) {
646 GoArray *array = static_cast<GoType *>(type)->GetArray();
647 if (array) {
648 if (stride) {
649 *stride = array->GetElementType().GetByteSize(nullptr);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000650 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651 return array->GetElementType();
652 }
653 return CompilerType();
654}
655
656CompilerType GoASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
657 GoType *t = static_cast<GoType *>(type);
658 if (t->IsTypedef())
659 return t->GetElementType();
660 return CompilerType(this, type);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000661}
662
663CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000664GoASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
665 return CompilerType(this, type);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000666}
667
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668// Returns -1 if this isn't a function of if the function doesn't have a
669// prototype
Ryan Brown57bee1e2015-09-14 22:45:11 +0000670// Returns a value >= 0 if there is a prototype.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000671int GoASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) {
672 return GetNumberOfFunctionArguments(type);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000673}
674
675CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000676GoASTContext::GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type,
677 size_t idx) {
678 return GetFunctionArgumentAtIndex(type, idx);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000679}
680
681CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000682GoASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
683 CompilerType result;
684 if (type) {
685 GoType *t = static_cast<GoType *>(type);
686 if (t->GetGoKind() == GoType::KIND_FUNC)
687 result = t->GetElementType();
688 }
689 return result;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000690}
691
Kate Stoneb9c1b512016-09-06 20:57:50 +0000692size_t GoASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
693 return 0;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000694}
695
696TypeMemberFunctionImpl
Kate Stoneb9c1b512016-09-06 20:57:50 +0000697GoASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
698 size_t idx) {
699 return TypeMemberFunctionImpl();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000700}
701
702CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000703GoASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
704 return CompilerType(this, type);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000705}
706
Kate Stoneb9c1b512016-09-06 20:57:50 +0000707CompilerType GoASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
708 if (!type)
709 return CompilerType();
710 return static_cast<GoType *>(type)->GetElementType();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000711}
712
Kate Stoneb9c1b512016-09-06 20:57:50 +0000713CompilerType GoASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
714 if (!type)
715 return CompilerType();
716 ConstString type_name = GetTypeName(type);
717 ConstString pointer_name(std::string("*") + type_name.GetCString());
718 GoType *pointer = (*m_types)[pointer_name].get();
719 if (pointer == nullptr) {
720 pointer =
721 new GoElem(GoType::KIND_PTR, pointer_name, CompilerType(this, type));
722 (*m_types)[pointer_name].reset(pointer);
723 }
724 return CompilerType(this, pointer);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000725}
726
727// If the current object represents a typedef type, get the underlying type
Kate Stoneb9c1b512016-09-06 20:57:50 +0000728CompilerType GoASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
729 if (IsTypedefType(type))
730 return static_cast<GoType *>(type)->GetElementType();
731 return CompilerType();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000732}
733
734//----------------------------------------------------------------------
735// Create related types using the current type's AST
736//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000737CompilerType GoASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
738 return CompilerType();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000739}
740
Greg Clayton56939cb2015-09-17 22:23:34 +0000741CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000742GoASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
743 size_t bit_size) {
744 return CompilerType();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000745}
746
Ryan Brown57bee1e2015-09-14 22:45:11 +0000747//----------------------------------------------------------------------
748// Exploring the type
749//----------------------------------------------------------------------
750
Kate Stoneb9c1b512016-09-06 20:57:50 +0000751uint64_t GoASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
752 ExecutionContextScope *exe_scope) {
753 if (!type)
Ryan Brownd03c2e02015-09-15 00:50:43 +0000754 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000755 if (!GetCompleteType(type))
Ryan Brown57bee1e2015-09-14 22:45:11 +0000756 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000757 GoType *t = static_cast<GoType *>(type);
758 GoArray *array = nullptr;
759 switch (t->GetGoKind()) {
760 case GoType::KIND_BOOL:
761 case GoType::KIND_INT8:
762 case GoType::KIND_UINT8:
763 return 8;
764 case GoType::KIND_INT16:
765 case GoType::KIND_UINT16:
766 return 16;
767 case GoType::KIND_INT32:
768 case GoType::KIND_UINT32:
769 case GoType::KIND_FLOAT32:
770 return 32;
771 case GoType::KIND_INT64:
772 case GoType::KIND_UINT64:
773 case GoType::KIND_FLOAT64:
774 case GoType::KIND_COMPLEX64:
775 return 64;
776 case GoType::KIND_COMPLEX128:
777 return 128;
778 case GoType::KIND_INT:
779 case GoType::KIND_UINT:
780 return m_int_byte_size * 8;
781 case GoType::KIND_UINTPTR:
782 case GoType::KIND_FUNC: // I assume this is a pointer?
783 case GoType::KIND_CHAN:
784 case GoType::KIND_PTR:
785 case GoType::KIND_UNSAFEPOINTER:
786 case GoType::KIND_MAP:
787 return m_pointer_byte_size * 8;
788 case GoType::KIND_ARRAY:
789 array = t->GetArray();
790 return array->GetLength() * array->GetElementType().GetBitSize(exe_scope);
791 case GoType::KIND_INTERFACE:
792 return t->GetElementType().GetBitSize(exe_scope);
793 case GoType::KIND_SLICE:
794 case GoType::KIND_STRING:
795 case GoType::KIND_STRUCT:
796 return t->GetStruct()->GetByteSize() * 8;
797 default:
798 assert(false);
799 }
800 return 0;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000801}
802
Kate Stoneb9c1b512016-09-06 20:57:50 +0000803lldb::Encoding GoASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
804 uint64_t &count) {
805 count = 1;
806 bool is_signed;
807 if (IsIntegerType(type, is_signed))
808 return is_signed ? lldb::eEncodingSint : eEncodingUint;
809 bool is_complex;
810 uint32_t complex_count;
811 if (IsFloatingPointType(type, complex_count, is_complex)) {
812 count = complex_count;
813 return eEncodingIEEE754;
814 }
815 if (IsPointerType(type))
816 return eEncodingUint;
817 return eEncodingInvalid;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000818}
819
Kate Stoneb9c1b512016-09-06 20:57:50 +0000820lldb::Format GoASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
821 if (!type)
822 return eFormatDefault;
823 switch (static_cast<GoType *>(type)->GetGoKind()) {
824 case GoType::KIND_BOOL:
825 return eFormatBoolean;
826 case GoType::KIND_INT:
827 case GoType::KIND_INT8:
828 case GoType::KIND_INT16:
829 case GoType::KIND_INT32:
830 case GoType::KIND_INT64:
831 return eFormatDecimal;
832 case GoType::KIND_UINT:
833 case GoType::KIND_UINT8:
834 case GoType::KIND_UINT16:
835 case GoType::KIND_UINT32:
836 case GoType::KIND_UINT64:
837 return eFormatUnsigned;
838 case GoType::KIND_FLOAT32:
839 case GoType::KIND_FLOAT64:
840 return eFormatFloat;
841 case GoType::KIND_COMPLEX64:
842 case GoType::KIND_COMPLEX128:
843 return eFormatComplexFloat;
844 case GoType::KIND_UINTPTR:
845 case GoType::KIND_CHAN:
846 case GoType::KIND_PTR:
847 case GoType::KIND_MAP:
848 case GoType::KIND_UNSAFEPOINTER:
849 return eFormatHex;
850 case GoType::KIND_STRING:
851 return eFormatCString;
852 case GoType::KIND_ARRAY:
853 case GoType::KIND_INTERFACE:
854 case GoType::KIND_SLICE:
855 case GoType::KIND_STRUCT:
856 default:
857 // Don't know how to display this.
858 return eFormatBytes;
859 }
860}
861
862size_t GoASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) {
863 return 0;
864}
865
866uint32_t GoASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
867 bool omit_empty_base_classes) {
868 if (!type || !GetCompleteType(type))
Ryan Brown57bee1e2015-09-14 22:45:11 +0000869 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870 GoType *t = static_cast<GoType *>(type);
871 if (t->GetGoKind() == GoType::KIND_PTR) {
872 CompilerType elem = t->GetElementType();
873 if (elem.IsAggregateType())
874 return elem.GetNumChildren(omit_empty_base_classes);
875 return 1;
876 } else if (GoArray *array = t->GetArray()) {
877 return array->GetLength();
878 } else if (t->IsTypedef()) {
879 return t->GetElementType().GetNumChildren(omit_empty_base_classes);
880 }
881
882 return GetNumFields(type);
Ryan Brown57bee1e2015-09-14 22:45:11 +0000883}
884
Kate Stoneb9c1b512016-09-06 20:57:50 +0000885uint32_t GoASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
886 if (!type || !GetCompleteType(type))
887 return 0;
888 GoType *t = static_cast<GoType *>(type);
889 if (t->IsTypedef())
890 return t->GetElementType().GetNumFields();
891 GoStruct *s = t->GetStruct();
892 if (s)
893 return s->GetNumFields();
894 return 0;
895}
Ryan Brown57bee1e2015-09-14 22:45:11 +0000896
Kate Stoneb9c1b512016-09-06 20:57:50 +0000897CompilerType GoASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
898 size_t idx, std::string &name,
899 uint64_t *bit_offset_ptr,
900 uint32_t *bitfield_bit_size_ptr,
901 bool *is_bitfield_ptr) {
902 if (bit_offset_ptr)
903 *bit_offset_ptr = 0;
904 if (bitfield_bit_size_ptr)
905 *bitfield_bit_size_ptr = 0;
906 if (is_bitfield_ptr)
907 *is_bitfield_ptr = false;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000908
Kate Stoneb9c1b512016-09-06 20:57:50 +0000909 if (!type || !GetCompleteType(type))
Ryan Brown57bee1e2015-09-14 22:45:11 +0000910 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000911
912 GoType *t = static_cast<GoType *>(type);
913 if (t->IsTypedef())
914 return t->GetElementType().GetFieldAtIndex(
915 idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
916
917 GoStruct *s = t->GetStruct();
918 if (s) {
919 const auto *field = s->GetField(idx);
920 if (field) {
921 name = field->m_name.GetStringRef();
922 if (bit_offset_ptr)
923 *bit_offset_ptr = field->m_byte_offset * 8;
924 return field->m_type;
925 }
926 }
927 return CompilerType();
Ryan Brown57bee1e2015-09-14 22:45:11 +0000928}
929
Kate Stoneb9c1b512016-09-06 20:57:50 +0000930CompilerType GoASTContext::GetChildCompilerTypeAtIndex(
931 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
932 bool transparent_pointers, bool omit_empty_base_classes,
933 bool ignore_array_bounds, std::string &child_name,
934 uint32_t &child_byte_size, int32_t &child_byte_offset,
935 uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
936 bool &child_is_base_class, bool &child_is_deref_of_parent,
937 ValueObject *valobj, uint64_t &language_flags) {
938 child_name.clear();
939 child_byte_size = 0;
940 child_byte_offset = 0;
941 child_bitfield_bit_size = 0;
942 child_bitfield_bit_offset = 0;
943 child_is_base_class = false;
944 child_is_deref_of_parent = false;
945 language_flags = 0;
Ryan Brown57bee1e2015-09-14 22:45:11 +0000946
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947 if (!type || !GetCompleteType(type))
Ryan Brown57bee1e2015-09-14 22:45:11 +0000948 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000949
950 GoType *t = static_cast<GoType *>(type);
951 if (t->GetStruct()) {
952 uint64_t bit_offset;
953 CompilerType ret =
954 GetFieldAtIndex(type, idx, child_name, &bit_offset, nullptr, nullptr);
955 child_byte_size = ret.GetByteSize(
956 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
957 child_byte_offset = bit_offset / 8;
958 return ret;
959 } else if (t->GetGoKind() == GoType::KIND_PTR) {
960 CompilerType pointee = t->GetElementType();
961 if (!pointee.IsValid() || pointee.IsVoidType())
962 return CompilerType();
963 if (transparent_pointers && pointee.IsAggregateType()) {
964 bool tmp_child_is_deref_of_parent = false;
965 return pointee.GetChildCompilerTypeAtIndex(
966 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
967 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
968 child_bitfield_bit_size, child_bitfield_bit_offset,
969 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
970 language_flags);
971 } else {
972 child_is_deref_of_parent = true;
973 const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
974 if (parent_name) {
975 child_name.assign(1, '*');
976 child_name += parent_name;
977 }
978
979 // We have a pointer to an simple type
980 if (idx == 0 && pointee.GetCompleteType()) {
981 child_byte_size = pointee.GetByteSize(
982 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
983 child_byte_offset = 0;
984 return pointee;
985 }
986 }
987 } else if (GoArray *a = t->GetArray()) {
988 if (ignore_array_bounds || idx < a->GetLength()) {
989 CompilerType element_type = a->GetElementType();
990 if (element_type.GetCompleteType()) {
991 char element_name[64];
992 ::snprintf(element_name, sizeof(element_name), "[%zu]", idx);
993 child_name.assign(element_name);
994 child_byte_size = element_type.GetByteSize(
995 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
996 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
997 return element_type;
998 }
999 }
1000 } else if (t->IsTypedef()) {
1001 return t->GetElementType().GetChildCompilerTypeAtIndex(
1002 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
1003 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
1004 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
1005 child_is_deref_of_parent, valobj, language_flags);
1006 }
1007 return CompilerType();
Ryan Brown57bee1e2015-09-14 22:45:11 +00001008}
1009
1010// Lookup a child given a name. This function will match base class names
1011// and member member names in "clang_type" only, not descendants.
1012uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001013GoASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
1014 const char *name,
1015 bool omit_empty_base_classes) {
1016 if (!type || !GetCompleteType(type))
Ryan Brown57bee1e2015-09-14 22:45:11 +00001017 return UINT_MAX;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018
1019 GoType *t = static_cast<GoType *>(type);
1020 GoStruct *s = t->GetStruct();
1021 if (s) {
1022 for (uint32_t i = 0; i < s->GetNumFields(); ++i) {
1023 const GoStruct::Field *f = s->GetField(i);
1024 if (f->m_name.GetStringRef() == name)
1025 return i;
1026 }
1027 } else if (t->GetGoKind() == GoType::KIND_PTR || t->IsTypedef()) {
1028 return t->GetElementType().GetIndexOfChildWithName(name,
1029 omit_empty_base_classes);
1030 }
1031 return UINT_MAX;
Ryan Brown57bee1e2015-09-14 22:45:11 +00001032}
1033
1034// Lookup a child member given a name. This function will match member names
1035// only and will descend into "clang_type" children in search for the first
1036// member in this class, or any base class that matches "name".
Kate Stoneb9c1b512016-09-06 20:57:50 +00001037// TODO: Return all matches for a given name by returning a
1038// vector<vector<uint32_t>>
Ryan Brown57bee1e2015-09-14 22:45:11 +00001039// so we catch all names that match a given child name, not just the first.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001040size_t GoASTContext::GetIndexOfChildMemberWithName(
1041 lldb::opaque_compiler_type_t type, const char *name,
1042 bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
1043 uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes);
1044 if (index == UINT_MAX)
1045 return 0;
1046 child_indexes.push_back(index);
1047 return 1;
Ryan Brown57bee1e2015-09-14 22:45:11 +00001048}
1049
1050// Converts "s" to a floating point value and place resulting floating
1051// point bytes in the "dst" buffer.
1052size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001053GoASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
1054 const char *s, uint8_t *dst,
1055 size_t dst_size) {
1056 assert(false);
1057 return 0;
Ryan Brown57bee1e2015-09-14 22:45:11 +00001058}
1059//----------------------------------------------------------------------
1060// Dumping types
1061//----------------------------------------------------------------------
Ryan Brown47d072ca2016-01-15 19:35:48 +00001062#define DEPTH_INCREMENT 2
1063
Kate Stoneb9c1b512016-09-06 20:57:50 +00001064void GoASTContext::DumpValue(lldb::opaque_compiler_type_t type,
1065 ExecutionContext *exe_ctx, Stream *s,
1066 lldb::Format format, const DataExtractor &data,
1067 lldb::offset_t data_byte_offset,
1068 size_t data_byte_size, uint32_t bitfield_bit_size,
1069 uint32_t bitfield_bit_offset, bool show_types,
1070 bool show_summary, bool verbose, uint32_t depth) {
1071 if (IsTypedefType(type))
1072 type = GetTypedefedType(type).GetOpaqueQualType();
1073 if (!type)
1074 return;
1075 GoType *t = static_cast<GoType *>(type);
1076
1077 if (GoStruct *st = t->GetStruct()) {
1078 if (GetCompleteType(type)) {
1079 uint32_t field_idx = 0;
1080 for (auto *field = st->GetField(field_idx); field != nullptr;
1081 field_idx++) {
1082 // Print the starting squiggly bracket (if this is the
1083 // first member) or comma (for member 2 and beyond) for
1084 // the struct/union/class member.
1085 if (field_idx == 0)
1086 s->PutChar('{');
1087 else
1088 s->PutChar(',');
1089
1090 // Indent
1091 s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
1092
1093 // Print the member type if requested
1094 if (show_types) {
1095 ConstString field_type_name = field->m_type.GetTypeName();
1096 s->Printf("(%s) ", field_type_name.AsCString());
1097 }
1098 // Print the member name and equal sign
1099 s->Printf("%s = ", field->m_name.AsCString());
1100
1101 // Dump the value of the member
1102 CompilerType field_type = field->m_type;
1103 field_type.DumpValue(
1104 exe_ctx,
1105 s, // Stream to dump to
1106 field_type
1107 .GetFormat(), // The format with which to display the member
1108 data, // Data buffer containing all bytes for this type
1109 data_byte_offset + field->m_byte_offset, // Offset into "data" where
1110 // to grab value from
1111 field->m_type.GetByteSize(
1112 exe_ctx->GetBestExecutionContextScope()), // Size of this type
1113 // in bytes
1114 0, // Bitfield bit size
1115 0, // Bitfield bit offset
1116 show_types, // Boolean indicating if we should show the variable
1117 // types
1118 show_summary, // Boolean indicating if we should show a summary for
1119 // the current type
1120 verbose, // Verbose output?
1121 depth + DEPTH_INCREMENT); // Scope depth for any types that have
1122 // children
1123 }
1124
1125 // Indent the trailing squiggly bracket
1126 if (field_idx > 0)
1127 s->Printf("\n%*s}", depth, "");
1128 }
1129 }
1130
1131 if (GoArray *a = t->GetArray()) {
1132 CompilerType element_clang_type = a->GetElementType();
1133 lldb::Format element_format = element_clang_type.GetFormat();
1134 uint32_t element_byte_size =
1135 element_clang_type.GetByteSize(exe_ctx->GetBestExecutionContextScope());
1136
1137 uint64_t element_idx;
1138 for (element_idx = 0; element_idx < a->GetLength(); ++element_idx) {
1139 // Print the starting squiggly bracket (if this is the
1140 // first member) or comman (for member 2 and beyong) for
1141 // the struct/union/class member.
1142 if (element_idx == 0)
1143 s->PutChar('{');
1144 else
1145 s->PutChar(',');
1146
1147 // Indent and print the index
1148 s->Printf("\n%*s[%" PRIu64 "] ", depth + DEPTH_INCREMENT, "",
1149 element_idx);
1150
1151 // Figure out the field offset within the current struct/union/class type
1152 uint64_t element_offset = element_idx * element_byte_size;
1153
1154 // Dump the value of the member
1155 element_clang_type.DumpValue(
1156 exe_ctx,
1157 s, // Stream to dump to
1158 element_format, // The format with which to display the element
1159 data, // Data buffer containing all bytes for this type
1160 data_byte_offset +
1161 element_offset, // Offset into "data" where to grab value from
1162 element_byte_size, // Size of this type in bytes
1163 0, // Bitfield bit size
1164 0, // Bitfield bit offset
1165 show_types, // Boolean indicating if we should show the variable types
1166 show_summary, // Boolean indicating if we should show a summary for
1167 // the current type
1168 verbose, // Verbose output?
1169 depth +
1170 DEPTH_INCREMENT); // Scope depth for any types that have children
1171 }
1172
1173 // Indent the trailing squiggly bracket
1174 if (element_idx > 0)
1175 s->Printf("\n%*s}", depth, "");
1176 }
1177
1178 if (show_summary)
1179 DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
1180}
1181
1182bool GoASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s,
1183 lldb::Format format, const DataExtractor &data,
1184 lldb::offset_t byte_offset, size_t byte_size,
1185 uint32_t bitfield_bit_size,
1186 uint32_t bitfield_bit_offset,
1187 ExecutionContextScope *exe_scope) {
1188 if (!type)
1189 return false;
1190 if (IsAggregateType(type)) {
1191 return false;
1192 } else {
Ryan Brown47d072ca2016-01-15 19:35:48 +00001193 GoType *t = static_cast<GoType *>(type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001194 if (t->IsTypedef()) {
1195 CompilerType typedef_compiler_type = t->GetElementType();
1196 if (format == eFormatDefault)
1197 format = typedef_compiler_type.GetFormat();
1198 uint64_t typedef_byte_size = typedef_compiler_type.GetByteSize(exe_scope);
Ryan Brown47d072ca2016-01-15 19:35:48 +00001199
Kate Stoneb9c1b512016-09-06 20:57:50 +00001200 return typedef_compiler_type.DumpTypeValue(
1201 s,
1202 format, // The format with which to display the element
1203 data, // Data buffer containing all bytes for this type
1204 byte_offset, // Offset into "data" where to grab value from
1205 typedef_byte_size, // Size of this type in bytes
1206 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't
1207 // treat as a bitfield
1208 bitfield_bit_offset, // Offset in bits of a bitfield value if
1209 // bitfield_bit_size != 0
1210 exe_scope);
Ryan Brown47d072ca2016-01-15 19:35:48 +00001211 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001212
1213 uint32_t item_count = 1;
1214 // A few formats, we might need to modify our size and count for depending
1215 // on how we are trying to display the value...
1216 switch (format) {
1217 default:
1218 case eFormatBoolean:
1219 case eFormatBinary:
1220 case eFormatComplex:
1221 case eFormatCString: // NULL terminated C strings
1222 case eFormatDecimal:
1223 case eFormatEnum:
1224 case eFormatHex:
1225 case eFormatHexUppercase:
1226 case eFormatFloat:
1227 case eFormatOctal:
1228 case eFormatOSType:
1229 case eFormatUnsigned:
1230 case eFormatPointer:
1231 case eFormatVectorOfChar:
1232 case eFormatVectorOfSInt8:
1233 case eFormatVectorOfUInt8:
1234 case eFormatVectorOfSInt16:
1235 case eFormatVectorOfUInt16:
1236 case eFormatVectorOfSInt32:
1237 case eFormatVectorOfUInt32:
1238 case eFormatVectorOfSInt64:
1239 case eFormatVectorOfUInt64:
1240 case eFormatVectorOfFloat32:
1241 case eFormatVectorOfFloat64:
1242 case eFormatVectorOfUInt128:
1243 break;
1244
1245 case eFormatChar:
1246 case eFormatCharPrintable:
1247 case eFormatCharArray:
1248 case eFormatBytes:
1249 case eFormatBytesWithASCII:
1250 item_count = byte_size;
1251 byte_size = 1;
1252 break;
1253
1254 case eFormatUnicode16:
1255 item_count = byte_size / 2;
1256 byte_size = 2;
1257 break;
1258
1259 case eFormatUnicode32:
1260 item_count = byte_size / 4;
1261 byte_size = 4;
1262 break;
Ryan Brown47d072ca2016-01-15 19:35:48 +00001263 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001264 return data.Dump(s, byte_offset, format, byte_size, item_count, UINT32_MAX,
1265 LLDB_INVALID_ADDRESS, bitfield_bit_size,
1266 bitfield_bit_offset, exe_scope);
1267 }
1268 return 0;
Ryan Brown57bee1e2015-09-14 22:45:11 +00001269}
1270
Kate Stoneb9c1b512016-09-06 20:57:50 +00001271void GoASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
1272 ExecutionContext *exe_ctx, Stream *s,
1273 const DataExtractor &data,
1274 lldb::offset_t data_offset,
1275 size_t data_byte_size) {
1276 if (type && GoType::KIND_STRING == static_cast<GoType *>(type)->GetGoKind()) {
1277 // TODO(ribrdb): read length and data
1278 }
Ryan Brown57bee1e2015-09-14 22:45:11 +00001279}
1280
Kate Stoneb9c1b512016-09-06 20:57:50 +00001281void GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) {
1282 // Dump to stdout
1283 StreamFile s(stdout, false);
1284 DumpTypeDescription(type, &s);
Ryan Brown57bee1e2015-09-14 22:45:11 +00001285}
1286
Kate Stoneb9c1b512016-09-06 20:57:50 +00001287void GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
1288 Stream *s) {
1289 if (!type)
1290 return;
1291 ConstString name = GetTypeName(type);
1292 GoType *t = static_cast<GoType *>(type);
Ryan Brown57bee1e2015-09-14 22:45:11 +00001293
Kate Stoneb9c1b512016-09-06 20:57:50 +00001294 if (GoStruct *st = t->GetStruct()) {
1295 if (GetCompleteType(type)) {
1296 if (NULL == strchr(name.AsCString(), '{'))
1297 s->Printf("type %s ", name.AsCString());
1298 s->PutCString("struct {");
1299 if (st->GetNumFields() == 0) {
1300 s->PutChar('}');
Ryan Brown47d072ca2016-01-15 19:35:48 +00001301 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001302 }
1303 s->IndentMore();
1304 uint32_t field_idx = 0;
1305 for (auto *field = st->GetField(field_idx); field != nullptr;
1306 field_idx++) {
1307 s->PutChar('\n');
1308 s->Indent();
1309 s->Printf("%s %s", field->m_name.AsCString(),
1310 field->m_type.GetTypeName().AsCString());
1311 }
1312 s->IndentLess();
1313 s->PutChar('\n');
1314 s->Indent("}");
1315 return;
Ryan Brown47d072ca2016-01-15 19:35:48 +00001316 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001317 }
Ryan Brown47d072ca2016-01-15 19:35:48 +00001318
Kate Stoneb9c1b512016-09-06 20:57:50 +00001319 s->PutCString(name.AsCString());
1320}
1321
1322CompilerType GoASTContext::CreateArrayType(const ConstString &name,
1323 const CompilerType &element_type,
1324 uint64_t length) {
1325 GoType *type = new GoArray(name, length, element_type);
1326 (*m_types)[name].reset(type);
1327 return CompilerType(this, type);
1328}
1329
1330CompilerType GoASTContext::CreateBaseType(int go_kind,
1331 const lldb_private::ConstString &name,
1332 uint64_t byte_size) {
1333 if (go_kind == GoType::KIND_UINT || go_kind == GoType::KIND_INT)
1334 m_int_byte_size = byte_size;
1335 GoType *type = new GoType(go_kind, name);
1336 (*m_types)[name].reset(type);
1337 return CompilerType(this, type);
1338}
1339
1340CompilerType GoASTContext::CreateTypedefType(int kind, const ConstString &name,
1341 CompilerType impl) {
1342 GoType *type = new GoElem(kind, name, impl);
1343 (*m_types)[name].reset(type);
1344 return CompilerType(this, type);
Ryan Brown57bee1e2015-09-14 22:45:11 +00001345}
1346
1347CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00001348GoASTContext::CreateVoidType(const lldb_private::ConstString &name) {
1349 GoType *type = new GoType(GoType::KIND_LLDB_VOID, name);
1350 (*m_types)[name].reset(type);
1351 return CompilerType(this, type);
Ryan Brown57bee1e2015-09-14 22:45:11 +00001352}
1353
1354CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00001355GoASTContext::CreateStructType(int kind, const lldb_private::ConstString &name,
1356 uint32_t byte_size) {
1357 GoType *type = new GoStruct(kind, name, byte_size);
1358 (*m_types)[name].reset(type);
1359 return CompilerType(this, type);
1360}
1361
1362void GoASTContext::AddFieldToStruct(
1363 const lldb_private::CompilerType &struct_type,
1364 const lldb_private::ConstString &name,
1365 const lldb_private::CompilerType &field_type, uint32_t byte_offset) {
1366 if (!struct_type)
1367 return;
1368 GoASTContext *ast =
1369 llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem());
1370 if (!ast)
1371 return;
1372 GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType());
1373 if (GoStruct *s = type->GetStruct())
1374 s->AddField(name, field_type, byte_offset);
1375}
1376
1377void GoASTContext::CompleteStructType(
1378 const lldb_private::CompilerType &struct_type) {
1379 if (!struct_type)
1380 return;
1381 GoASTContext *ast =
1382 llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem());
1383 if (!ast)
1384 return;
1385 GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType());
1386 if (GoStruct *s = type->GetStruct())
1387 s->SetComplete();
Ryan Brown57bee1e2015-09-14 22:45:11 +00001388}
1389
1390CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00001391GoASTContext::CreateFunctionType(const lldb_private::ConstString &name,
1392 CompilerType *params, size_t params_count,
1393 bool is_variadic) {
1394 GoType *type = new GoFunction(name, is_variadic);
1395 (*m_types)[name].reset(type);
1396 return CompilerType(this, type);
Ryan Brown57bee1e2015-09-14 22:45:11 +00001397}
1398
Kate Stoneb9c1b512016-09-06 20:57:50 +00001399bool GoASTContext::IsGoString(const lldb_private::CompilerType &type) {
1400 if (!type.IsValid() ||
1401 !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1402 return false;
1403 return GoType::KIND_STRING ==
1404 static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
Ryan Brown57bee1e2015-09-14 22:45:11 +00001405}
1406
Kate Stoneb9c1b512016-09-06 20:57:50 +00001407bool GoASTContext::IsGoSlice(const lldb_private::CompilerType &type) {
1408 if (!type.IsValid() ||
1409 !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1410 return false;
1411 return GoType::KIND_SLICE ==
1412 static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
Ryan Brown57bee1e2015-09-14 22:45:11 +00001413}
1414
Kate Stoneb9c1b512016-09-06 20:57:50 +00001415bool GoASTContext::IsGoInterface(const lldb_private::CompilerType &type) {
1416 if (!type.IsValid() ||
1417 !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1418 return false;
1419 return GoType::KIND_INTERFACE ==
1420 static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
Ryan Brown57bee1e2015-09-14 22:45:11 +00001421}
1422
Kate Stoneb9c1b512016-09-06 20:57:50 +00001423bool GoASTContext::IsPointerKind(uint8_t kind) {
1424 return (kind & GoType::KIND_MASK) == GoType::KIND_PTR;
Ryan Brown57bee1e2015-09-14 22:45:11 +00001425}
1426
Kate Stoneb9c1b512016-09-06 20:57:50 +00001427bool GoASTContext::IsDirectIface(uint8_t kind) {
1428 return (kind & GoType::KIND_DIRECT_IFACE) == GoType::KIND_DIRECT_IFACE;
Ryan Brown57bee1e2015-09-14 22:45:11 +00001429}
1430
Kate Stoneb9c1b512016-09-06 20:57:50 +00001431DWARFASTParser *GoASTContext::GetDWARFParser() {
1432 if (!m_dwarf_ast_parser_ap)
1433 m_dwarf_ast_parser_ap.reset(new DWARFASTParserGo(*this));
1434 return m_dwarf_ast_parser_ap.get();
Ryan Brown57bee1e2015-09-14 22:45:11 +00001435}
1436
Kate Stoneb9c1b512016-09-06 20:57:50 +00001437UserExpression *GoASTContextForExpr::GetUserExpression(
1438 const char *expr, const char *expr_prefix, lldb::LanguageType language,
1439 Expression::ResultType desired_type,
1440 const EvaluateExpressionOptions &options) {
1441 TargetSP target = m_target_wp.lock();
1442 if (target)
1443 return new GoUserExpression(*target, expr, expr_prefix, language,
1444 desired_type, options);
1445 return nullptr;
Ryan Brown998c8a1c12015-11-02 19:30:40 +00001446}