]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Symbol/OCamlASTContext.cpp
MFC r345805: Unify SCSI_STATUS_BUSY retry handling with other cases.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Symbol / OCamlASTContext.cpp
1 //===-- OCamlASTContext.cpp ----------------------------------------*- C++
2 //-*-===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #include "lldb/Symbol/OCamlASTContext.h"
12 #include "lldb/Core/DumpDataExtractor.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/PluginManager.h"
15 #include "lldb/Core/StreamFile.h"
16 #include "lldb/Core/ValueObject.h"
17 #include "lldb/Symbol/ObjectFile.h"
18 #include "lldb/Symbol/SymbolFile.h"
19 #include "lldb/Symbol/Type.h"
20 #include "lldb/Target/ExecutionContext.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Utility/Log.h"
23
24 #include "Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h"
25
26 using namespace lldb;
27 using namespace lldb_private;
28
29 namespace lldb_private {
30 class OCamlASTContext::OCamlType {
31 public:
32   enum LLVMCastKind {
33     eKindPrimitive,
34     eKindObject,
35     eKindReference,
36     eKindArray,
37     kNumKinds
38   };
39
40   OCamlType(LLVMCastKind kind) : m_kind(kind) {}
41
42   virtual ~OCamlType() = default;
43
44   virtual ConstString GetName() = 0;
45
46   virtual void Dump(Stream *s) = 0;
47
48   virtual bool IsCompleteType() = 0;
49
50   LLVMCastKind getKind() const { return m_kind; }
51
52 private:
53   LLVMCastKind m_kind;
54 };
55
56 } // end of namespace lldb_private
57
58 namespace {
59
60 class OCamlPrimitiveType : public OCamlASTContext::OCamlType {
61 public:
62   enum TypeKind {
63     eTypeInt,
64   };
65
66   OCamlPrimitiveType(TypeKind type_kind, uint32_t byte_size)
67       : OCamlType(OCamlType::eKindPrimitive), m_type_kind(type_kind),
68         m_type(ConstString()), m_byte_size(byte_size) {}
69
70   OCamlPrimitiveType(TypeKind type_kind, ConstString s, uint32_t byte_size)
71       : OCamlType(OCamlType::eKindPrimitive), m_type_kind(type_kind), m_type(s),
72         m_byte_size(byte_size) {}
73
74   ConstString GetName() override {
75     switch (m_type_kind) {
76     case eTypeInt:
77       return m_type;
78     }
79     return ConstString();
80   }
81
82   TypeKind GetTypeKind() { return m_type_kind; }
83
84   void Dump(Stream *s) override { s->Printf("%s\n", GetName().GetCString()); }
85
86   bool IsCompleteType() override { return true; }
87
88   static bool classof(const OCamlType *ot) {
89     return ot->getKind() == OCamlType::eKindPrimitive;
90   }
91
92   uint64_t GetByteSize() const { return m_byte_size; }
93
94 private:
95   const TypeKind m_type_kind;
96   const ConstString m_type;
97   uint64_t m_byte_size;
98 };
99 }
100
101 OCamlASTContext::OCamlASTContext()
102     : TypeSystem(eKindOCaml), m_pointer_byte_size(0) {}
103
104 OCamlASTContext::~OCamlASTContext() {}
105
106 ConstString OCamlASTContext::GetPluginNameStatic() {
107   return ConstString("ocaml");
108 }
109
110 ConstString OCamlASTContext::GetPluginName() {
111   return OCamlASTContext::GetPluginNameStatic();
112 }
113
114 uint32_t OCamlASTContext::GetPluginVersion() { return 1; }
115
116 lldb::TypeSystemSP OCamlASTContext::CreateInstance(lldb::LanguageType language,
117                                                    Module *module,
118                                                    Target *target) {
119   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
120
121   if (language == lldb::eLanguageTypeOCaml) {
122     std::shared_ptr<OCamlASTContext> ocaml_ast_sp;
123     ArchSpec arch;
124
125     if (module) {
126       arch = module->GetArchitecture();
127
128       ObjectFile *objfile = module->GetObjectFile();
129       ArchSpec object_arch;
130
131       if (!objfile || !objfile->GetArchitecture(object_arch))
132         return lldb::TypeSystemSP();
133
134       ocaml_ast_sp = std::shared_ptr<OCamlASTContext>(new OCamlASTContext);
135
136       if (log) {
137         log->Printf(
138             "((Module*)%p) [%s]->GetOCamlASTContext() = %p", (void *)module,
139             module->GetFileSpec().GetFilename().AsCString("<anonymous>"),
140             (void *)ocaml_ast_sp.get());
141       }
142
143     } else if (target) {
144       arch = target->GetArchitecture();
145       ocaml_ast_sp = std::shared_ptr<OCamlASTContextForExpr>(
146           new OCamlASTContextForExpr(target->shared_from_this()));
147
148       if (log) {
149         log->Printf("((Target*)%p)->GetOCamlASTContext() = %p", (void *)target,
150                     (void *)ocaml_ast_sp.get());
151       }
152     }
153
154     if (arch.IsValid()) {
155       ocaml_ast_sp->SetAddressByteSize(arch.GetAddressByteSize());
156       return ocaml_ast_sp;
157     }
158   }
159
160   return lldb::TypeSystemSP();
161 }
162
163 void OCamlASTContext::EnumerateSupportedLanguages(
164     std::set<lldb::LanguageType> &languages_for_types,
165     std::set<lldb::LanguageType> &languages_for_expressions) {
166   static std::vector<lldb::LanguageType> s_supported_languages_for_types(
167       {lldb::eLanguageTypeOCaml});
168   static std::vector<lldb::LanguageType> s_supported_languages_for_expressions(
169       {});
170
171   languages_for_types.insert(s_supported_languages_for_types.begin(),
172                              s_supported_languages_for_types.end());
173   languages_for_expressions.insert(
174       s_supported_languages_for_expressions.begin(),
175       s_supported_languages_for_expressions.end());
176 }
177
178 void OCamlASTContext::Initialize() {
179   PluginManager::RegisterPlugin(GetPluginNameStatic(),
180                                 "OCaml AST context plug-in", CreateInstance,
181                                 EnumerateSupportedLanguages);
182 }
183
184 void OCamlASTContext::Terminate() {
185   PluginManager::UnregisterPlugin(CreateInstance);
186 }
187
188 DWARFASTParser *OCamlASTContext::GetDWARFParser() {
189   if (!m_dwarf_ast_parser_ap) {
190     m_dwarf_ast_parser_ap.reset(new DWARFASTParserOCaml(*this));
191   }
192
193   return m_dwarf_ast_parser_ap.get();
194 }
195
196 bool OCamlASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
197                                   CompilerType *element_type, uint64_t *size,
198                                   bool *is_incomplete) {
199   return false;
200 }
201
202 bool OCamlASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
203                                    CompilerType *element_type, uint64_t *size) {
204   return false;
205 }
206
207 bool OCamlASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
208   return false;
209 }
210
211 bool OCamlASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
212   return false;
213 }
214
215 bool OCamlASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
216   return false;
217 }
218
219 bool OCamlASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
220   return static_cast<OCamlPrimitiveType *>(type)->IsCompleteType();
221 }
222
223 bool OCamlASTContext::IsConst(lldb::opaque_compiler_type_t type) {
224   return false;
225 }
226
227 bool OCamlASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
228                                     uint32_t &length) {
229   return false;
230 }
231
232 bool OCamlASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
233   return type != nullptr;
234 }
235
236 bool OCamlASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
237                                           uint32_t &count, bool &is_complex) {
238   return false;
239 }
240
241 bool OCamlASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
242                                      bool *is_variadic_ptr) {
243   return false;
244 }
245
246 uint32_t
247 OCamlASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
248                                         CompilerType *base_type_ptr) {
249   return false;
250 }
251
252 size_t OCamlASTContext::GetNumberOfFunctionArguments(
253     lldb::opaque_compiler_type_t type) {
254   return 0;
255 }
256
257 CompilerType
258 OCamlASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
259                                             const size_t index) {
260   return CompilerType();
261 }
262
263 bool OCamlASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
264   return IsFunctionType(type);
265 }
266
267 bool OCamlASTContext::IsBlockPointerType(
268     lldb::opaque_compiler_type_t type,
269     CompilerType *function_pointer_type_ptr) {
270   return false;
271 }
272
273 bool OCamlASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
274                                     bool &is_signed) {
275   if (OCamlPrimitiveType *ptype =
276           llvm::dyn_cast<OCamlPrimitiveType>(static_cast<OCamlType *>(type))) {
277     switch (ptype->GetTypeKind()) {
278     case OCamlPrimitiveType::eTypeInt:
279       is_signed = true;
280       return true;
281     }
282   }
283
284   is_signed = false;
285   return false;
286 }
287
288 bool OCamlASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
289   return false;
290 }
291
292 bool OCamlASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
293                                             CompilerType *target_type,
294                                             bool check_cplusplus,
295                                             bool check_objc) {
296   return false;
297 }
298
299 bool OCamlASTContext::IsRuntimeGeneratedType(
300     lldb::opaque_compiler_type_t type) {
301   return false;
302 }
303
304 bool OCamlASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
305                                     CompilerType *pointee_type) {
306   if (pointee_type)
307     pointee_type->Clear();
308   return false;
309 }
310
311 bool OCamlASTContext::IsPointerOrReferenceType(
312     lldb::opaque_compiler_type_t type, CompilerType *pointee_type) {
313   return IsPointerType(type, pointee_type);
314 }
315
316 bool OCamlASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
317                                       CompilerType *pointee_type,
318                                       bool *is_rvalue) {
319   return false;
320 }
321
322 bool OCamlASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
323   return llvm::isa<OCamlPrimitiveType>(static_cast<OCamlType *>(type));
324 }
325
326 bool OCamlASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
327   return false;
328 }
329
330 bool OCamlASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
331   return false;
332 }
333
334 bool OCamlASTContext::SupportsLanguage(lldb::LanguageType language) {
335   return language == lldb::eLanguageTypeOCaml;
336 }
337
338 bool OCamlASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
339   if (IsCompleteType(type))
340     return true;
341
342   return false;
343 }
344
345 uint32_t OCamlASTContext::GetPointerByteSize() { return m_pointer_byte_size; }
346
347 ConstString OCamlASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
348   if (type)
349     return static_cast<OCamlPrimitiveType *>(type)->GetName();
350
351   return ConstString();
352 }
353
354 uint32_t
355 OCamlASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
356                              CompilerType *pointee_or_element_compiler_type) {
357   if (pointee_or_element_compiler_type)
358     pointee_or_element_compiler_type->Clear();
359   if (!type)
360     return 0;
361
362   if (OCamlPrimitiveType *ptype =
363           llvm::dyn_cast<OCamlPrimitiveType>(static_cast<OCamlType *>(type))) {
364     switch (ptype->GetTypeKind()) {
365     case OCamlPrimitiveType::eTypeInt:
366       return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsInteger |
367              eTypeIsSigned;
368     }
369   }
370
371   return 0;
372 }
373
374 lldb::TypeClass
375 OCamlASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
376   if (llvm::isa<OCamlPrimitiveType>(static_cast<OCamlType *>(type)))
377     return eTypeClassBuiltin;
378
379   return lldb::eTypeClassInvalid;
380 }
381
382 lldb::BasicType
383 OCamlASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
384   return lldb::eBasicTypeInvalid;
385 }
386
387 lldb::LanguageType
388 OCamlASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
389   return lldb::eLanguageTypeOCaml;
390 }
391
392 unsigned OCamlASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
393   return 0;
394 }
395
396 //----------------------------------------------------------------------
397 // Creating related types
398 //----------------------------------------------------------------------
399
400 CompilerType
401 OCamlASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
402                                      uint64_t *stride) {
403   return CompilerType();
404 }
405
406 CompilerType
407 OCamlASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
408   return CompilerType(this, type);
409 }
410
411 CompilerType
412 OCamlASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
413   return CompilerType(this, type);
414 }
415
416 int OCamlASTContext::GetFunctionArgumentCount(
417     lldb::opaque_compiler_type_t type) {
418   return GetNumberOfFunctionArguments(type);
419 }
420
421 CompilerType OCamlASTContext::GetFunctionArgumentTypeAtIndex(
422     lldb::opaque_compiler_type_t type, size_t idx) {
423   return GetFunctionArgumentAtIndex(type, idx);
424 }
425
426 CompilerType
427 OCamlASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
428   return CompilerType();
429 }
430
431 size_t
432 OCamlASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
433   return 0;
434 }
435
436 TypeMemberFunctionImpl
437 OCamlASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
438                                           size_t idx) {
439   return TypeMemberFunctionImpl();
440 }
441
442 CompilerType
443 OCamlASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
444   return CompilerType(this, type);
445 }
446
447 CompilerType
448 OCamlASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
449   return CompilerType();
450 }
451
452 CompilerType
453 OCamlASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
454   return CompilerType();
455 }
456
457 CompilerType
458 OCamlASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
459   return CompilerType();
460 }
461
462 CompilerType OCamlASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
463   return CompilerType();
464 }
465
466 CompilerType
467 OCamlASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
468                                                      size_t bit_size) {
469   return CompilerType();
470 }
471
472 uint64_t OCamlASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
473                                      ExecutionContextScope *exe_scope) {
474   if (OCamlPrimitiveType *ptype =
475           llvm::dyn_cast<OCamlPrimitiveType>(static_cast<OCamlType *>(type))) {
476     switch (ptype->GetTypeKind()) {
477     case OCamlPrimitiveType::eTypeInt:
478       return ptype->GetByteSize() * 8;
479     }
480   }
481   return 0;
482 }
483
484 lldb::Encoding OCamlASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
485                                             uint64_t &count) {
486   count = 1;
487   bool is_signed;
488   if (IsIntegerType(type, is_signed))
489     return is_signed ? lldb::eEncodingSint : lldb::eEncodingUint;
490   bool is_complex;
491   uint32_t complex_count;
492   if (IsFloatingPointType(type, complex_count, is_complex)) {
493     count = complex_count;
494     return lldb::eEncodingIEEE754;
495   }
496   if (IsPointerType(type))
497     return lldb::eEncodingUint;
498   return lldb::eEncodingInvalid;
499 }
500
501 lldb::Format OCamlASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
502   if (!type)
503     return lldb::eFormatDefault;
504   return lldb::eFormatBytes;
505 }
506
507 size_t OCamlASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) {
508   return 0;
509 }
510
511 uint32_t OCamlASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
512                                          bool omit_empty_base_classes) {
513   if (!type || !GetCompleteType(type))
514     return 0;
515
516   return GetNumFields(type);
517 }
518
519 uint32_t OCamlASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
520   if (!type || !GetCompleteType(type))
521     return 0;
522   return 0;
523 }
524
525 CompilerType OCamlASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
526                                               size_t idx, std::string &name,
527                                               uint64_t *bit_offset_ptr,
528                                               uint32_t *bitfield_bit_size_ptr,
529                                               bool *is_bitfield_ptr) {
530   if (bit_offset_ptr)
531     *bit_offset_ptr = 0;
532   if (bitfield_bit_size_ptr)
533     *bitfield_bit_size_ptr = 0;
534   if (is_bitfield_ptr)
535     *is_bitfield_ptr = false;
536
537   if (!type || !GetCompleteType(type))
538     return CompilerType();
539
540   return CompilerType();
541 }
542
543 CompilerType OCamlASTContext::GetChildCompilerTypeAtIndex(
544     lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
545     bool transparent_pointers, bool omit_empty_base_classes,
546     bool ignore_array_bounds, std::string &child_name,
547     uint32_t &child_byte_size, int32_t &child_byte_offset,
548     uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
549     bool &child_is_base_class, bool &child_is_deref_of_parent,
550     ValueObject *valobj, uint64_t &language_flags) {
551   child_name.clear();
552   child_byte_size = 0;
553   child_byte_offset = 0;
554   child_bitfield_bit_size = 0;
555   child_bitfield_bit_offset = 0;
556   child_is_base_class = false;
557   child_is_deref_of_parent = false;
558   language_flags = 0;
559
560   if (!type || !GetCompleteType(type))
561     return CompilerType();
562
563   return CompilerType();
564 }
565
566 uint32_t
567 OCamlASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
568                                          const char *name,
569                                          bool omit_empty_base_classes) {
570   if (!type || !GetCompleteType(type))
571     return UINT_MAX;
572
573   return UINT_MAX;
574 }
575
576 size_t OCamlASTContext::GetIndexOfChildMemberWithName(
577     lldb::opaque_compiler_type_t type, const char *name,
578     bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
579   uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes);
580   if (index == UINT_MAX)
581     return 0;
582   child_indexes.push_back(index);
583   return 1;
584 }
585
586 size_t
587 OCamlASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
588                                            const char *s, uint8_t *dst,
589                                            size_t dst_size) {
590   assert(false);
591   return 0;
592 }
593 //----------------------------------------------------------------------
594 // Dumping types
595 //----------------------------------------------------------------------
596
597 void OCamlASTContext::DumpValue(
598     lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
599     lldb::Format format, const DataExtractor &data,
600     lldb::offset_t data_byte_offset, size_t data_byte_size,
601     uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types,
602     bool show_summary, bool verbose, uint32_t depth) {
603   if (!type) {
604     s->Printf("no type\n");
605     return;
606   }
607
608   s->Printf("no value\n");
609
610   if (show_summary)
611     DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
612 }
613
614 bool OCamlASTContext::DumpTypeValue(
615     lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
616     const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size,
617     uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
618     ExecutionContextScope *exe_scope) {
619   if (!type) {
620     s->Printf("no type value\n");
621     return false;
622   }
623
624   if (IsScalarType(type)) {
625     return DumpDataExtractor(data, s, byte_offset, format, byte_size, 1,
626                              SIZE_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
627                              bitfield_bit_offset, exe_scope);
628   }
629
630   return false;
631 }
632
633 void OCamlASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
634                                   ExecutionContext *exe_ctx, Stream *s,
635                                   const DataExtractor &data,
636                                   lldb::offset_t data_offset,
637                                   size_t data_byte_size) {
638   s->Printf("no summary\n");
639 }
640
641 void OCamlASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) {
642   StreamFile s(stdout, false);
643   DumpTypeDescription(type, &s);
644 }
645
646 void OCamlASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
647                                           Stream *s) {
648   static_cast<OCamlType *>(type)->Dump(s);
649 }
650
651 CompilerType OCamlASTContext::CreateBaseType(const ConstString &name,
652                                              uint64_t byte_size) {
653   if (m_base_type_map.empty()) {
654     OCamlPrimitiveType *type = new OCamlPrimitiveType(
655         OCamlPrimitiveType::eTypeInt, ConstString("ocaml_int"), byte_size);
656     m_base_type_map.emplace(type->GetName(),
657                             std::unique_ptr<OCamlASTContext::OCamlType>(type));
658   }
659
660   auto it = m_base_type_map.find(name);
661   if (it == m_base_type_map.end()) {
662     OCamlPrimitiveType *type =
663         new OCamlPrimitiveType(OCamlPrimitiveType::eTypeInt, name, byte_size);
664     it = m_base_type_map
665              .emplace(name, std::unique_ptr<OCamlASTContext::OCamlType>(type))
666              .first;
667   }
668
669   return CompilerType(this, it->second.get());
670 }