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