LLDB mainline
Symbol/Type.cpp
Go to the documentation of this file.
1//===-- Type.cpp ----------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <algorithm>
10#include <cstdio>
11#include <iterator>
12#include <memory>
13#include <optional>
14
15#include "lldb/Core/Module.h"
19#include "lldb/Utility/Log.h"
20#include "lldb/Utility/Scalar.h"
22
28#include "lldb/Symbol/Type.h"
31
33#include "lldb/Target/Process.h"
34#include "lldb/Target/Target.h"
37
38#include "llvm/ADT/StringRef.h"
39#include "llvm/Support/SaveAndRestore.h"
40
41using namespace lldb;
42using namespace lldb_private;
43
44llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &os,
45 const CompilerContext &rhs) {
46 StreamString lldb_stream;
47 rhs.Dump(lldb_stream);
48 return os << lldb_stream.GetString();
49}
50
51static CompilerContextKind ConvertTypeClass(lldb::TypeClass type_class) {
52 if (type_class == eTypeClassAny)
54 CompilerContextKind result = {};
55 if (type_class & (lldb::eTypeClassClass | lldb::eTypeClassStruct))
57 if (type_class & lldb::eTypeClassUnion)
59 if (type_class & lldb::eTypeClassEnumeration)
61 if (type_class & lldb::eTypeClassFunction)
63 if (type_class & lldb::eTypeClassTypedef)
65 return result;
66}
67
68TypeQuery::TypeQuery(llvm::StringRef name, TypeQueryOptions options)
69 : m_options(options) {
70 if (std::optional<Type::ParsedName> parsed_name =
72 llvm::ArrayRef scope = parsed_name->scope;
73 if (!scope.empty()) {
74 if (scope[0] == "::") {
75 m_options |= e_exact_match;
76 scope = scope.drop_front();
77 }
78 for (llvm::StringRef s : scope) {
79 m_context.push_back(
81 }
82 }
83 m_context.push_back({ConvertTypeClass(parsed_name->type_class),
84 ConstString(parsed_name->basename)});
85 } else {
87 }
88}
89
91 ConstString type_basename, TypeQueryOptions options)
92 : m_options(options) {
93 // Always use an exact match if we are looking for a type in compiler context.
94 m_options |= e_exact_match;
95 m_context = decl_ctx.GetCompilerContext();
96 m_context.push_back({CompilerContextKind::AnyType, type_basename});
97}
98
100 const llvm::ArrayRef<lldb_private::CompilerContext> &context,
101 TypeQueryOptions options)
102 : m_context(context), m_options(options) {
103 // Always use an exact match if we are looking for a type in compiler context.
104 m_options |= e_exact_match;
105}
106
107TypeQuery::TypeQuery(const CompilerDecl &decl, TypeQueryOptions options)
108 : m_options(options) {
109 // Always for an exact match if we are looking for a type using a declaration.
110 m_options |= e_exact_match;
112}
113
115 if (m_context.empty())
116 return ConstString();
117 return m_context.back().name;
118}
119
121 if (!m_languages)
123 m_languages->Insert(language);
124}
125
127 m_languages = std::move(languages);
128}
129
131 llvm::ArrayRef<CompilerContext> context_chain) const {
132 auto ctx = context_chain.rbegin(), ctx_end = context_chain.rend();
133 for (auto pat = m_context.rbegin(), pat_end = m_context.rend();
134 pat != pat_end;) {
135
136 if (ctx == ctx_end)
137 return false; // Pattern too long.
138
139 if (ctx->kind == CompilerContextKind::Namespace && ctx->name.IsEmpty()) {
140 // We're matching an anonymous namespace. These are optional, so we check
141 // if the pattern expects an anonymous namespace.
142 if (pat->name.IsEmpty() && (pat->kind & CompilerContextKind::Namespace) ==
144 // Match, advance both iterators.
145 ++pat;
146 }
147 // Otherwise, only advance the context to skip over the anonymous
148 // namespace, and try matching again.
149 ++ctx;
150 continue;
151 }
152
153 // See if there is a kind mismatch; they should have 1 bit in common.
154 if ((ctx->kind & pat->kind) == CompilerContextKind())
155 return false;
156
157 if (ctx->name != pat->name)
158 return false;
159
160 ++ctx;
161 ++pat;
162 }
163
164 // Skip over any remaining module and anonymous namespace entries if we were
165 // asked to do that.
166 auto should_skip = [this](const CompilerContext &ctx) {
167 if (ctx.kind == CompilerContextKind::Module)
168 return GetIgnoreModules();
169 if (ctx.kind == CompilerContextKind::Namespace && ctx.name.IsEmpty())
170 return !GetStrictNamespaces();
171 return false;
172 };
173 ctx = std::find_if_not(ctx, ctx_end, should_skip);
174
175 // At this point, we have exhausted the pattern and we have a partial match at
176 // least. If that's all we're looking for, we're done.
177 if (!GetExactMatch())
178 return true;
179
180 // We have an exact match if we've exhausted the target context as well.
181 return ctx == ctx_end;
182}
183
185 // If we have no language filterm language always matches.
186 if (!m_languages.has_value())
187 return true;
188 return (*m_languages)[language];
189}
190
192 return !m_searched_symbol_files.insert(sym_file).second;
193}
194
196 if (type_sp)
197 return m_type_map.InsertUnique(type_sp);
198 return false;
199}
200
201bool TypeResults::Done(const TypeQuery &query) const {
202 if (query.GetFindOne())
203 return !m_type_map.Empty();
204 return false;
205}
206
208 switch (kind) {
209 default:
210 s << "Invalid";
211 break;
213 s << "TranslationUnit";
214 break;
216 s << "Module";
217 break;
219 s << "Namespace";
220 break;
222 s << "ClassOrStruct";
223 break;
225 s << "Union";
226 break;
228 s << "Function";
229 break;
231 s << "Variable";
232 break;
234 s << "Enumeration";
235 break;
237 s << "Typedef";
238 break;
240 s << "AnyType";
241 break;
242 }
243 s << "(" << name << ")";
244}
245
247public:
248 TypeAppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {}
249
250 bool operator()(const lldb::TypeSP &type) {
251 m_type_list.Append(std::make_shared<TypeImpl>(type));
252 return true;
253 }
254
255private:
257};
258
260 TypeAppendVisitor cb(*this);
261 type_list.ForEach(cb);
262}
263
265 const lldb::TypeSP &type_sp)
266 : UserID(type_sp ? type_sp->GetID() : LLDB_INVALID_UID),
267 m_symbol_file(symbol_file), m_type_sp(type_sp) {}
268
270 if (!m_type_sp) {
271 Type *resolved_type = m_symbol_file.ResolveTypeUID(GetID());
272 if (resolved_type)
273 m_type_sp = resolved_type->shared_from_this();
274 }
275 return m_type_sp.get();
276}
277
279 std::optional<uint64_t> byte_size, SymbolContextScope *context,
280 user_id_t encoding_uid, EncodingDataType encoding_uid_type,
281 const Declaration &decl, const CompilerType &compiler_type,
282 ResolveState compiler_type_resolve_state, uint32_t opaque_payload)
283 : std::enable_shared_from_this<Type>(), UserID(uid), m_name(name),
284 m_symbol_file(symbol_file), m_context(context),
285 m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type),
286 m_decl(decl), m_compiler_type(compiler_type),
287 m_compiler_type_resolve_state(compiler_type ? compiler_type_resolve_state
289 m_payload(opaque_payload) {
290 if (byte_size) {
291 m_byte_size = *byte_size;
293 } else {
294 m_byte_size = 0;
295 m_byte_size_has_value = false;
296 }
297}
298
300 : std::enable_shared_from_this<Type>(), UserID(0), m_name("<INVALID TYPE>"),
301 m_payload(0) {
302 m_byte_size = 0;
303 m_byte_size_has_value = false;
304}
305
307 bool show_name, ExecutionContextScope *exe_scope) {
308 *s << "id = " << (const UserID &)*this;
309
310 // Call the name accessor to make sure we resolve the type name
311 if (show_name) {
312 ConstString type_name = GetName();
313 if (type_name) {
314 *s << ", name = \"" << type_name << '"';
315 ConstString qualified_type_name(GetQualifiedName());
316 if (qualified_type_name != type_name) {
317 *s << ", qualified = \"" << qualified_type_name << '"';
318 }
319 }
320 }
321
322 // Call the get byte size accessor so we resolve our byte size
323 if (GetByteSize(exe_scope))
324 s->Printf(", byte-size = %" PRIu64, m_byte_size);
325 bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
326 m_decl.Dump(s, show_fullpaths);
327
328 if (m_compiler_type.IsValid()) {
329 *s << ", compiler_type = \"";
331 *s << '"';
332 } else if (m_encoding_uid != LLDB_INVALID_UID) {
333 s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid);
334 switch (m_encoding_uid_type) {
335 case eEncodingInvalid:
336 break;
337 case eEncodingIsUID:
338 s->PutCString(" (unresolved type)");
339 break;
341 s->PutCString(" (unresolved const type)");
342 break;
344 s->PutCString(" (unresolved restrict type)");
345 break;
347 s->PutCString(" (unresolved volatile type)");
348 break;
350 s->PutCString(" (unresolved atomic type)");
351 break;
353 s->PutCString(" (unresolved typedef)");
354 break;
356 s->PutCString(" (unresolved pointer)");
357 break;
359 s->PutCString(" (unresolved L value reference)");
360 break;
362 s->PutCString(" (unresolved R value reference)");
363 break;
365 s->PutCString(" (synthetic type)");
366 break;
368 s->PutCString(" (ptrauth type)");
369 break;
370 }
371 }
372}
373
374void Type::Dump(Stream *s, bool show_context, lldb::DescriptionLevel level) {
375 s->Printf("%p: ", static_cast<void *>(this));
376 s->Indent();
377 *s << "Type" << static_cast<const UserID &>(*this) << ' ';
378 if (m_name)
379 *s << ", name = \"" << m_name << "\"";
380
382 s->Printf(", size = %" PRIu64, m_byte_size);
383
384 if (show_context && m_context != nullptr) {
385 s->PutCString(", context = ( ");
386 m_context->DumpSymbolContext(s);
387 s->PutCString(" )");
388 }
389
390 bool show_fullpaths = false;
391 m_decl.Dump(s, show_fullpaths);
392
393 if (m_compiler_type.IsValid()) {
394 *s << ", compiler_type = " << m_compiler_type.GetOpaqueQualType() << ' ';
396 } else if (m_encoding_uid != LLDB_INVALID_UID) {
397 s->Format(", type_data = {0:x-16}", m_encoding_uid);
398 switch (m_encoding_uid_type) {
399 case eEncodingInvalid:
400 break;
401 case eEncodingIsUID:
402 s->PutCString(" (unresolved type)");
403 break;
405 s->PutCString(" (unresolved const type)");
406 break;
408 s->PutCString(" (unresolved restrict type)");
409 break;
411 s->PutCString(" (unresolved volatile type)");
412 break;
414 s->PutCString(" (unresolved atomic type)");
415 break;
417 s->PutCString(" (unresolved typedef)");
418 break;
420 s->PutCString(" (unresolved pointer)");
421 break;
423 s->PutCString(" (unresolved L value reference)");
424 break;
426 s->PutCString(" (unresolved R value reference)");
427 break;
429 s->PutCString(" (synthetic type)");
430 break;
432 s->PutCString(" (ptrauth type)");
433 }
434 }
435
436 //
437 // if (m_access)
438 // s->Printf(", access = %u", m_access);
439 s->EOL();
440}
441
447
449 return GetForwardCompilerType().GetTypeName(/*BaseOnly*/ true);
450}
451
452void Type::DumpTypeName(Stream *s) { GetName().Dump(s, "<invalid-type-name>"); }
453
459
460llvm::Expected<uint64_t> Type::GetByteSize(ExecutionContextScope *exe_scope) {
462 return static_cast<uint64_t>(m_byte_size);
463
464 switch (m_encoding_uid_type) {
465 case eEncodingInvalid:
466 return llvm::createStringError("could not get type size: invalid encoding");
467
469 return llvm::createStringError(
470 "could not get type size: synthetic encoding");
471
472 case eEncodingIsUID:
478 Type *encoding_type = GetEncodingType();
479 if (encoding_type)
480 if (std::optional<uint64_t> size =
481 llvm::expectedToOptional(encoding_type->GetByteSize(exe_scope))) {
482 m_byte_size = *size;
484 return static_cast<uint64_t>(m_byte_size);
485 }
486
487 auto size_or_err = GetLayoutCompilerType().GetByteSize(exe_scope);
488 if (!size_or_err)
489 return size_or_err.takeError();
490 m_byte_size = *size_or_err;
492 return static_cast<uint64_t>(m_byte_size);
493 } break;
494
495 // If we are a pointer or reference, then this is just a pointer size;
500 if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) {
501 m_byte_size = arch.GetAddressByteSize();
503 return static_cast<uint64_t>(m_byte_size);
504 }
505 } break;
506 }
507 return llvm::createStringError(
508 "could not get type size: unexpected encoding");
509}
510
511llvm::Expected<uint32_t> Type::GetNumChildren(bool omit_empty_base_classes) {
512 return GetForwardCompilerType().GetNumChildren(omit_empty_base_classes, nullptr);
513}
514
518
522
524 lldb::TypeSP type_sp;
525 if (IsTypedef()) {
526 Type *typedef_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
527 if (typedef_type)
528 type_sp = typedef_type->shared_from_this();
529 }
530 return type_sp;
531}
532
534
536 // Make sure we resolve our type if it already hasn't been.
538}
539
541 AddressType address_type, DataExtractor &data) {
542 if (address_type == eAddressTypeFile) {
543 // Can't convert a file address to anything valid without more context
544 // (which Module it came from)
545 return false;
546 }
547
548 const uint64_t byte_size =
549 llvm::expectedToOptional(
550 GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope()
551 : nullptr))
552 .value_or(0);
553 if (data.GetByteSize() < byte_size) {
554 lldb::DataBufferSP data_sp(new DataBufferHeap(byte_size, '\0'));
555 data.SetData(data_sp);
556 }
557
558 uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));
559 if (dst != nullptr) {
560 if (address_type == eAddressTypeHost) {
561 // The address is an address in this process, so just copy it
562 if (addr == 0)
563 return false;
564 memcpy(dst, reinterpret_cast<uint8_t *>(addr), byte_size);
565 return true;
566 } else {
567 if (exe_ctx) {
568 Process *process = exe_ctx->GetProcessPtr();
569 if (process) {
571 return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size,
572 error) == byte_size;
573 }
574 }
575 }
576 }
577 return false;
578}
579
581 AddressType address_type, DataExtractor &data) {
582 return false;
583}
584
585const Declaration &Type::GetDeclaration() const { return m_decl; }
586
587bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {
590 "Cycle detected while resolving type {0:x} ({1})", GetID(),
591 m_name.AsCString("<anonymous>"));
592 return false;
593 }
594 llvm::SaveAndRestore<bool> guard(m_resolving_compiler_type, true);
595
596 // TODO: This needs to consider the correct type system to use.
597 Type *encoding_type = nullptr;
598 if (!m_compiler_type.IsValid()) {
599 encoding_type = GetEncodingType();
600 if (encoding_type) {
601 switch (m_encoding_uid_type) {
602 case eEncodingIsUID: {
603 CompilerType encoding_compiler_type =
604 encoding_type->GetForwardCompilerType();
605 if (encoding_compiler_type.IsValid()) {
606 m_compiler_type = encoding_compiler_type;
608 encoding_type->m_compiler_type_resolve_state;
609 }
610 } break;
611
614 encoding_type->GetForwardCompilerType().AddConstModifier();
615 break;
616
620 break;
621
625 break;
626
629 encoding_type->GetForwardCompilerType().GetAtomicType();
630 break;
631
634 m_name.AsCString("__lldb_invalid_typedef_name"),
635 GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload);
636 m_name.Clear();
637 break;
638
641 encoding_type->GetForwardCompilerType().GetPointerType();
642 break;
643
647 break;
648
652 break;
653
657 m_payload);
658 break;
659
660 default:
661 llvm_unreachable("Unhandled encoding_data_type.");
662 }
663 } else {
664 // We have no encoding type, return void?
665 auto type_system_or_err =
666 m_symbol_file->GetTypeSystemForLanguage(eLanguageTypeC);
667 if (auto err = type_system_or_err.takeError()) {
669 GetLog(LLDBLog::Symbols), std::move(err),
670 "Unable to construct void type from TypeSystemClang: {0}");
671 } else {
672 CompilerType void_compiler_type;
673 auto ts = *type_system_or_err;
674 if (ts)
675 void_compiler_type = ts->GetBasicTypeFromAST(eBasicTypeVoid);
676 switch (m_encoding_uid_type) {
677 case eEncodingIsUID:
678 m_compiler_type = void_compiler_type;
679 break;
680
682 m_compiler_type = void_compiler_type.AddConstModifier();
683 break;
684
686 m_compiler_type = void_compiler_type.AddRestrictModifier();
687 break;
688
690 m_compiler_type = void_compiler_type.AddVolatileModifier();
691 break;
692
694 m_compiler_type = void_compiler_type.GetAtomicType();
695 break;
696
698 m_compiler_type = void_compiler_type.CreateTypedef(
699 m_name.AsCString("__lldb_invalid_typedef_name"),
700 GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload);
701 break;
702
704 m_compiler_type = void_compiler_type.GetPointerType();
705 break;
706
708 m_compiler_type = void_compiler_type.GetLValueReferenceType();
709 break;
710
712 m_compiler_type = void_compiler_type.GetRValueReferenceType();
713 break;
714
716 llvm_unreachable("Cannot handle eEncodingIsLLVMPtrAuthUID without "
717 "valid encoding_type");
718
719 default:
720 llvm_unreachable("Unhandled encoding_data_type.");
721 }
722 }
723 }
724
725 // When we have a EncodingUID, our "m_flags.compiler_type_resolve_state" is
726 // set to eResolveStateUnresolved so we need to update it to say that we
727 // now have a forward declaration since that is what we created above.
728 if (m_compiler_type.IsValid())
730 }
731
732 // Check if we have a forward reference to a class/struct/union/enum?
733 if (compiler_type_resolve_state == ResolveState::Layout ||
734 compiler_type_resolve_state == ResolveState::Full) {
735 // Check if we have a forward reference to a class/struct/union/enum?
736 if (m_compiler_type.IsValid() &&
737 m_compiler_type_resolve_state < compiler_type_resolve_state) {
739 if (!m_compiler_type.IsDefined()) {
740 // We have a forward declaration, we need to resolve it to a complete
741 // definition.
742 m_symbol_file->CompleteType(m_compiler_type);
743 }
744 }
745 }
746
747 // If we have an encoding type, then we need to make sure it is resolved
748 // appropriately.
750 if (encoding_type == nullptr)
751 encoding_type = GetEncodingType();
752 if (encoding_type) {
753 ResolveState encoding_compiler_type_resolve_state =
754 compiler_type_resolve_state;
755
756 if (compiler_type_resolve_state == ResolveState::Layout) {
757 switch (m_encoding_uid_type) {
761 encoding_compiler_type_resolve_state = ResolveState::Forward;
762 break;
763 default:
764 break;
765 }
766 }
767 encoding_type->ResolveCompilerType(encoding_compiler_type_resolve_state);
768 }
769 }
770 return m_compiler_type.IsValid();
771}
773 uint32_t encoding_mask = 1u << m_encoding_uid_type;
774 Type *encoding_type = GetEncodingType();
775 assert(encoding_type != this);
776 if (encoding_type)
777 encoding_mask |= encoding_type->GetEncodingMask();
778 return encoding_mask;
779}
780
785
790
795
799
800std::optional<Type::ParsedName>
801Type::GetTypeScopeAndBasename(llvm::StringRef name) {
802 ParsedName result;
803
804 if (name.empty())
805 return std::nullopt;
806
807 if (name.consume_front("struct "))
808 result.type_class = eTypeClassStruct;
809 else if (name.consume_front("class "))
810 result.type_class = eTypeClassClass;
811 else if (name.consume_front("union "))
812 result.type_class = eTypeClassUnion;
813 else if (name.consume_front("enum "))
814 result.type_class = eTypeClassEnumeration;
815 else if (name.consume_front("typedef "))
816 result.type_class = eTypeClassTypedef;
817
818 if (name.consume_front("::"))
819 result.scope.push_back("::");
820
821 bool prev_is_colon = false;
822 size_t template_depth = 0;
823 size_t name_begin = 0;
824 for (const auto &pos : llvm::enumerate(name)) {
825 switch (pos.value()) {
826 case ':':
827 if (prev_is_colon && template_depth == 0) {
828 llvm::StringRef scope_name = name.slice(name_begin, pos.index() - 1);
829 // The demanglers use these strings to represent anonymous
830 // namespaces. Convert it to a more language-agnostic form (which is
831 // also used in DWARF).
832 if (scope_name == "(anonymous namespace)" ||
833 scope_name == "`anonymous namespace'" ||
834 scope_name == "`anonymous-namespace'")
835 scope_name = "";
836 result.scope.push_back(scope_name);
837 name_begin = pos.index() + 1;
838 }
839 break;
840 case '<':
841 ++template_depth;
842 break;
843 case '>':
844 if (template_depth == 0)
845 return std::nullopt; // Invalid name.
846 --template_depth;
847 break;
848 }
849 prev_is_colon = pos.value() == ':';
850 }
851
852 if (name_begin < name.size() && template_depth == 0)
853 result.basename = name.substr(name_begin);
854 else
855 return std::nullopt;
856
857 return result;
858}
859
861 if (m_symbol_file)
862 return m_symbol_file->GetObjectFile()->GetModule();
863 return ModuleSP();
864}
865
867 if (m_compiler_type) {
868 auto ts = m_compiler_type.GetTypeSystem();
869 if (!ts)
870 return {};
871 SymbolFile *symbol_file = ts->GetSymbolFile();
872 if (symbol_file)
873 return symbol_file->GetObjectFile()->GetModule();
874 }
875 return {};
876}
877
879 if (in_type_sp) {
880 m_compiler_type = in_type_sp->GetForwardCompilerType();
881 m_type_name = in_type_sp->GetName();
882 }
883}
884
885TypeAndOrName::TypeAndOrName(const char *in_type_str)
886 : m_type_name(in_type_str) {}
887
889 : m_type_name(in_type_const_string) {}
890
891bool TypeAndOrName::operator==(const TypeAndOrName &other) const {
892 if (m_compiler_type != other.m_compiler_type)
893 return false;
894 if (m_type_name != other.m_type_name)
895 return false;
896 return true;
897}
898
899bool TypeAndOrName::operator!=(const TypeAndOrName &other) const {
900 return !(*this == other);
901}
902
904 if (m_type_name)
905 return m_type_name;
906 if (m_compiler_type)
907 return m_compiler_type.GetTypeName();
908 return ConstString("<invalid>");
909}
910
912 m_type_name = type_name;
913}
914
915void TypeAndOrName::SetName(const char *type_name_cstr) {
916 m_type_name.SetCString(type_name_cstr);
917}
918
919void TypeAndOrName::SetName(llvm::StringRef type_name) {
920 m_type_name.SetString(type_name);
921}
922
924 if (type_sp) {
925 m_compiler_type = type_sp->GetForwardCompilerType();
926 m_type_name = type_sp->GetName();
927 } else
928 Clear();
929}
930
932 m_compiler_type = compiler_type;
933 if (m_compiler_type)
934 m_type_name = m_compiler_type.GetTypeName();
935}
936
938 return !((bool)m_type_name || (bool)m_compiler_type);
939}
940
942 m_type_name.Clear();
943 m_compiler_type.Clear();
944}
945
946bool TypeAndOrName::HasName() const { return (bool)m_type_name; }
947
949 return m_compiler_type.IsValid();
950}
951
954 SetType(type_sp);
955}
956
957TypeImpl::TypeImpl(const CompilerType &compiler_type)
959 SetType(compiler_type);
960}
961
962TypeImpl::TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic)
963 : m_module_wp(), m_static_type(), m_dynamic_type(dynamic) {
964 SetType(type_sp, dynamic);
965}
966
968 const CompilerType &dynamic_type)
970 SetType(static_type, dynamic_type);
971}
972
973void TypeImpl::SetType(const lldb::TypeSP &type_sp) {
974 if (type_sp) {
975 m_static_type = type_sp->GetForwardCompilerType();
976 m_exe_module_wp = type_sp->GetExeModule();
977 m_module_wp = type_sp->GetModule();
978 } else {
979 m_static_type.Clear();
981 }
982}
983
984void TypeImpl::SetType(const CompilerType &compiler_type) {
986 m_static_type = compiler_type;
987}
988
989void TypeImpl::SetType(const lldb::TypeSP &type_sp,
990 const CompilerType &dynamic) {
991 SetType(type_sp);
992 m_dynamic_type = dynamic;
993}
994
995void TypeImpl::SetType(const CompilerType &compiler_type,
996 const CompilerType &dynamic) {
998 m_static_type = compiler_type;
999 m_dynamic_type = dynamic;
1000}
1001
1003 return CheckModuleCommon(m_module_wp, module_sp);
1004}
1005
1007 return CheckModuleCommon(m_exe_module_wp, module_sp);
1008}
1009
1011 lldb::ModuleSP &module_sp) const {
1012 // Check if we have a module for this type. If we do and the shared pointer
1013 // is can be successfully initialized with m_module_wp, return true. Else
1014 // return false if we didn't have a module, or if we had a module and it has
1015 // been deleted. Any functions doing anything with a TypeSP in this TypeImpl
1016 // class should call this function and only do anything with the ivars if
1017 // this function returns true. If we have a module, the "module_sp" will be
1018 // filled in with a strong reference to the module so that the module will at
1019 // least stay around long enough for the type query to succeed.
1020 module_sp = input_module_wp.lock();
1021 if (!module_sp) {
1022 lldb::ModuleWP empty_module_wp;
1023 // If either call to "std::weak_ptr::owner_before(...) value returns true,
1024 // this indicates that m_module_wp once contained (possibly still does) a
1025 // reference to a valid shared pointer. This helps us know if we had a
1026 // valid reference to a section which is now invalid because the module it
1027 // was in was deleted
1028 if (empty_module_wp.owner_before(input_module_wp) ||
1029 input_module_wp.owner_before(empty_module_wp)) {
1030 // input_module_wp had a valid reference to a module, but all strong
1031 // references have been released and the module has been deleted
1032 return false;
1033 }
1034 }
1035 // We either successfully locked the module, or didn't have one to begin with
1036 return true;
1037}
1038
1039bool TypeImpl::operator==(const TypeImpl &rhs) const {
1040 return m_static_type == rhs.m_static_type &&
1042}
1043
1044bool TypeImpl::operator!=(const TypeImpl &rhs) const {
1045 return !(*this == rhs);
1046}
1047
1048bool TypeImpl::IsValid() const {
1049 // just a name is not valid
1050 ModuleSP module_sp;
1051 if (CheckModule(module_sp))
1052 return m_static_type.IsValid() || m_dynamic_type.IsValid();
1053 return false;
1054}
1055
1056TypeImpl::operator bool() const { return IsValid(); }
1057
1060 m_static_type.Clear();
1061 m_dynamic_type.Clear();
1062}
1063
1065 lldb::ModuleSP module_sp;
1066 if (CheckExeModule(module_sp))
1067 return module_sp;
1068 return nullptr;
1069}
1070
1072 ModuleSP module_sp;
1073 if (CheckModule(module_sp)) {
1074 if (m_dynamic_type)
1075 return m_dynamic_type.GetTypeName();
1076 return m_static_type.GetTypeName();
1077 }
1078 return ConstString();
1079}
1080
1082 ModuleSP module_sp;
1083 if (CheckModule(module_sp)) {
1084 if (m_dynamic_type)
1085 return m_dynamic_type.GetDisplayTypeName();
1086 return m_static_type.GetDisplayTypeName();
1087 }
1088 return ConstString();
1089}
1090
1092 ModuleSP module_sp;
1093 if (CheckModule(module_sp)) {
1094 if (m_dynamic_type.IsValid()) {
1095 return TypeImpl(m_static_type.GetPointerType(),
1096 m_dynamic_type.GetPointerType());
1097 }
1098 return TypeImpl(m_static_type.GetPointerType());
1099 }
1100 return TypeImpl();
1101}
1102
1104 ModuleSP module_sp;
1105 if (CheckModule(module_sp)) {
1106 if (m_dynamic_type.IsValid()) {
1107 return TypeImpl(m_static_type.GetPointeeType(),
1108 m_dynamic_type.GetPointeeType());
1109 }
1110 return TypeImpl(m_static_type.GetPointeeType());
1111 }
1112 return TypeImpl();
1113}
1114
1116 ModuleSP module_sp;
1117 if (CheckModule(module_sp)) {
1118 if (m_dynamic_type.IsValid()) {
1119 return TypeImpl(m_static_type.GetLValueReferenceType(),
1120 m_dynamic_type.GetLValueReferenceType());
1121 }
1122 return TypeImpl(m_static_type.GetLValueReferenceType());
1123 }
1124 return TypeImpl();
1125}
1126
1128 ModuleSP module_sp;
1129 if (CheckModule(module_sp)) {
1130 if (m_dynamic_type.IsValid()) {
1131 return TypeImpl(m_static_type.GetTypedefedType(),
1132 m_dynamic_type.GetTypedefedType());
1133 }
1134 return TypeImpl(m_static_type.GetTypedefedType());
1135 }
1136 return TypeImpl();
1137}
1138
1140 ModuleSP module_sp;
1141 if (CheckModule(module_sp)) {
1142 if (m_dynamic_type.IsValid()) {
1143 return TypeImpl(m_static_type.GetNonReferenceType(),
1144 m_dynamic_type.GetNonReferenceType());
1145 }
1146 return TypeImpl(m_static_type.GetNonReferenceType());
1147 }
1148 return TypeImpl();
1149}
1150
1152 ModuleSP module_sp;
1153 if (CheckModule(module_sp)) {
1154 if (m_dynamic_type.IsValid()) {
1155 return TypeImpl(m_static_type.GetFullyUnqualifiedType(),
1156 m_dynamic_type.GetFullyUnqualifiedType());
1157 }
1158 return TypeImpl(m_static_type.GetFullyUnqualifiedType());
1159 }
1160 return TypeImpl();
1161}
1162
1164 ModuleSP module_sp;
1165 if (CheckModule(module_sp)) {
1166 if (m_dynamic_type.IsValid()) {
1167 return TypeImpl(m_static_type.GetCanonicalType(),
1168 m_dynamic_type.GetCanonicalType());
1169 }
1170 return TypeImpl(m_static_type.GetCanonicalType());
1171 }
1172 return TypeImpl();
1173}
1174
1176 ModuleSP module_sp;
1177 if (CheckModule(module_sp)) {
1178 if (prefer_dynamic) {
1179 if (m_dynamic_type.IsValid())
1180 return m_dynamic_type;
1181 }
1182 return m_static_type;
1183 }
1184 return CompilerType();
1185}
1186
1188 ModuleSP module_sp;
1189 if (CheckModule(module_sp)) {
1190 if (prefer_dynamic) {
1191 if (m_dynamic_type.IsValid())
1192 return m_dynamic_type.GetTypeSystem();
1193 }
1194 return m_static_type.GetTypeSystem();
1195 }
1196 return {};
1197}
1198
1200 lldb::DescriptionLevel description_level) {
1201 ModuleSP module_sp;
1202 if (CheckModule(module_sp)) {
1203 if (m_dynamic_type.IsValid()) {
1204 strm.PutCString("Dynamic:\n");
1205 m_dynamic_type.DumpTypeDescription(&strm);
1206 strm.PutCString("\nStatic:\n");
1207 }
1208 m_static_type.DumpTypeDescription(&strm);
1209 } else {
1210 strm.PutCString("Invalid TypeImpl module for type has been deleted\n");
1211 }
1212 return true;
1213}
1214
1216 if (name.empty())
1217 return CompilerType();
1218 return GetCompilerType(/*prefer_dynamic=*/true)
1220}
1221
1225
1227
1229 return m_decl.GetMangledName();
1230}
1231
1233
1237
1239 switch (m_kind) {
1241 return false;
1243 stream.Printf("constructor for %s",
1244 m_type.GetTypeName().AsCString("<unknown>"));
1245 break;
1247 stream.Printf("destructor for %s",
1248 m_type.GetTypeName().AsCString("<unknown>"));
1249 break;
1251 stream.Format("instance method {0} of type {1}", m_name,
1252 m_decl.GetDeclContext().GetName());
1253 break;
1255 stream.Format("static method {0} of type {1}", m_name,
1256 m_decl.GetDeclContext().GetName());
1257 break;
1258 }
1259 return true;
1260}
1261
1263 if (m_type)
1264 return m_type.GetFunctionReturnType();
1265 return m_decl.GetFunctionReturnType();
1266}
1267
1269 if (m_type)
1270 return m_type.GetNumberOfFunctionArguments();
1271 else
1272 return m_decl.GetNumFunctionArguments();
1273}
1274
1276 if (m_type)
1277 return m_type.GetFunctionArgumentAtIndex(idx);
1278 else
1279 return m_decl.GetFunctionArgumentType(idx);
1280}
1281
1283 ConstString name,
1284 const llvm::APSInt &value)
1285 : m_integer_type_sp(integer_type_sp), m_name(name), m_value(value),
1286 m_valid((bool)name && (bool)integer_type_sp)
1287
1288{}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
static CompilerContextKind ConvertTypeClass(lldb::TypeClass type_class)
bool operator()(const lldb::TypeSP &type)
TypeListImpl & m_type_list
TypeAppendVisitor(TypeListImpl &type_list)
An architecture specification class.
Definition ArchSpec.h:32
Represents a generic declaration context in a program.
std::vector< lldb_private::CompilerContext > GetCompilerContext() const
Populate a valid compiler context from the current decl context.
Represents a generic declaration such as a function declaration.
std::vector< lldb_private::CompilerContext > GetCompilerContext() const
Populate a valid compiler context from the current declaration.
This is a minimal wrapper of a TypeSystem shared pointer as returned by CompilerType which conventien...
Generic representation of a type in a programming language.
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const
Create related types using the current type's AST.
CompilerType AddConstModifier() const
Return a new CompilerType adds a const modifier to this type if this type is valid and the type syste...
CompilerType GetRValueReferenceType() const
Return a new CompilerType that is a R value reference to this type if this type is valid and the type...
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
CompilerType AddVolatileModifier() const
Return a new CompilerType adds a volatile modifier to this type if this type is valid and the type sy...
CompilerType AddRestrictModifier() const
Return a new CompilerType adds a restrict modifier to this type if this type is valid and the type sy...
CompilerType GetDirectNestedTypeWithName(llvm::StringRef name) const
lldb::Encoding GetEncoding() const
CompilerType GetLValueReferenceType() const
Return a new CompilerType that is a L value reference to this type if this type is valid and the type...
ConstString GetTypeName(bool BaseOnly=false) const
lldb::Format GetFormat() const
llvm::Expected< uint32_t > GetNumChildren(bool omit_empty_base_classes, const ExecutionContext *exe_ctx) const
CompilerType CreateTypedef(const char *name, const CompilerDeclContext &decl_ctx, uint32_t payload) const
Create a typedef to this type using "name" as the name of the typedef this type is valid and the type...
CompilerType GetAtomicType() const
Return a new CompilerType that is the atomic type of this type.
void DumpTypeDescription(lldb::DescriptionLevel level=lldb::eDescriptionLevelFull) const
Dump to stdout.
CompilerType AddPtrAuthModifier(uint32_t payload) const
Return a new CompilerType adds a ptrauth modifier from the given 32-bit opaque payload to this type i...
A uniqued constant string class.
Definition ConstString.h:40
void Dump(Stream *s, const char *value_if_empty=nullptr) const
Dump the object description to a stream.
A subclass of DataBuffer that stores a data buffer on the heap.
An data extractor class.
virtual const uint8_t * PeekData(lldb::offset_t offset, lldb::offset_t length) const
Peek at a bytes at offset.
virtual uint64_t GetByteSize() const
Get the number of bytes contained in this object.
virtual lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
A class that describes the declaration location of a lldb object.
Definition Declaration.h:24
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
ExecutionContextScope * GetBestExecutionContextScope() const
Process * GetProcessPtr() const
Returns a pointer to the process object.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A plug-in interface definition class for debugging a process.
Definition Process.h:369
virtual size_t ReadMemory(const ProcessAddress &process_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition Process.cpp:2114
An error handling class.
Definition Status.h:118
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition Stream.cpp:157
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
SymbolFileType(SymbolFile &symbol_file, lldb::user_id_t uid)
Provides public interface for all SymbolFiles.
Definition SymbolFile.h:51
virtual ObjectFile * GetObjectFile()=0
void SetName(ConstString type_name)
bool operator!=(const TypeAndOrName &other) const
bool operator==(const TypeAndOrName &other) const
ConstString GetName() const
void SetCompilerType(CompilerType compiler_type)
void SetTypeSP(lldb::TypeSP type_sp)
CompilerType GetCompilerType(bool prefer_dynamic)
bool operator!=(const TypeImpl &rhs) const
bool CheckExeModule(lldb::ModuleSP &module_sp) const
bool GetDescription(lldb_private::Stream &strm, lldb::DescriptionLevel description_level)
bool operator==(const TypeImpl &rhs) const
bool CheckModuleCommon(const lldb::ModuleWP &input_module_wp, lldb::ModuleSP &module_sp) const
TypeImpl GetCanonicalType() const
void SetType(const lldb::TypeSP &type_sp)
TypeImpl GetUnqualifiedType() const
TypeImpl GetPointeeType() const
CompilerType::TypeSystemSPWrapper GetTypeSystem(bool prefer_dynamic)
bool CheckModule(lldb::ModuleSP &module_sp) const
lldb::ModuleSP GetModule() const
TypeImpl GetDereferencedType() const
TypeImpl GetPointerType() const
TypeImpl GetReferenceType() const
TypeImpl GetTypedefedType() const
ConstString GetName() const
CompilerType FindDirectNestedType(llvm::StringRef name)
ConstString GetDisplayTypeName() const
void Append(const lldb::TypeImplSP &type)
void ForEach(std::function< bool(const lldb::TypeSP &type_sp)> const &callback) const
Definition TypeList.cpp:50
CompilerType GetArgumentAtIndex(size_t idx) const
lldb::MemberFunctionKind GetKind() const
A class that contains all state required for type lookups.
std::vector< lldb_private::CompilerContext > m_context
A full or partial compiler context array where the parent declaration contexts appear at the top of t...
void AddLanguage(lldb::LanguageType language)
Add a language family to the list of languages that should produce a match.
TypeQueryOptions m_options
An options bitmask that contains enabled options for the type query.
bool LanguageMatches(lldb::LanguageType language) const
Check if the language matches any languages that have been added to this match object.
void SetLanguages(LanguageSet languages)
Set the list of languages that should produce a match to only the ones specified in languages.
std::optional< LanguageSet > m_languages
If this variable has a value, then the language family must match at least one of the specified langu...
ConstString GetTypeBasename() const
Get the type basename to use when searching the type indexes in each SymbolFile object.
bool ContextMatches(llvm::ArrayRef< lldb_private::CompilerContext > context) const
Check of a CompilerContext array from matching type from a symbol file matches the m_context.
bool GetFindOne() const
Returns true if the type query is supposed to find only a single matching type.
bool InsertUnique(const lldb::TypeSP &type_sp)
When types that match a TypeQuery are found, this API is used to insert the matching types.
llvm::DenseSet< lldb_private::SymbolFile * > m_searched_symbol_files
This set is used to track and make sure we only perform lookups in a symbol file one time.
bool Done(const TypeQuery &query) const
Check if the type matching has found all of the matches that it needs.
bool AlreadySearched(lldb_private::SymbolFile *sym_file)
Check if a SymbolFile object has already been searched by this type match object.
TypeMap m_type_map
Matching types get added to this map as type search continues.
CompilerType GetForwardCompilerType()
lldb::Format GetFormat()
ConstString GetName()
const lldb_private::Declaration & GetDeclaration() const
ResolveState m_compiler_type_resolve_state
uint32_t GetEncodingMask()
void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name, ExecutionContextScope *exe_scope)
llvm::Expected< uint32_t > GetNumChildren(bool omit_empty_base_classes)
SymbolContextScope * m_context
The symbol context in which this type is defined.
lldb::Encoding GetEncoding()
@ eEncodingIsRestrictUID
This type is the type whose UID is m_encoding_uid with the restrict qualifier added.
@ eEncodingIsConstUID
This type is the type whose UID is m_encoding_uid with the const qualifier added.
@ eEncodingIsVolatileUID
This type is the type whose UID is m_encoding_uid with the volatile qualifier added.
@ eEncodingIsAtomicUID
This type is the type whose UID is m_encoding_uid as an atomic type.
@ eEncodingIsLLVMPtrAuthUID
This type is a signed pointer.
@ eEncodingIsSyntheticUID
This type is the synthetic type whose UID is m_encoding_uid.
@ eEncodingInvalid
Invalid encoding.
@ eEncodingIsTypedefUID
This type is alias to a type whose UID is m_encoding_uid.
@ eEncodingIsPointerUID
This type is pointer to a type whose UID is m_encoding_uid.
@ eEncodingIsLValueReferenceUID
This type is L value reference to a type whose UID is m_encoding_uid.
@ eEncodingIsRValueReferenceUID
This type is R value reference to a type whose UID is m_encoding_uid.
@ eEncodingIsUID
This type is the type whose UID is m_encoding_uid.
Payload m_payload
Language-specific flags.
void Dump(Stream *s, bool show_context, lldb::DescriptionLevel level=lldb::eDescriptionLevelFull)
CompilerType GetLayoutCompilerType()
lldb::ModuleSP GetExeModule()
GetModule may return module for compile unit's object file.
void DumpTypeName(Stream *s)
static std::optional< ParsedName > GetTypeScopeAndBasename(llvm::StringRef name)
lldb::TypeSP GetTypedefType()
bool ResolveCompilerType(ResolveState compiler_type_resolve_state)
EncodingDataType m_encoding_uid_type
bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t address, AddressType address_type, DataExtractor &data)
ConstString GetBaseName()
Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name, std::optional< uint64_t > byte_size, SymbolContextScope *context, lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type, const Declaration &decl, const CompilerType &compiler_qual_type, ResolveState compiler_type_resolve_state, uint32_t opaque_payload=0)
ConstString GetQualifiedName()
CompilerType GetFullCompilerType()
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope)
lldb::ModuleSP GetModule()
Since Type instances only keep a "SymbolFile *" internally, other classes like TypeImpl need make sur...
bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t address, AddressType address_type, DataExtractor &data)
#define LLDB_INVALID_UID
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
@ AnyDeclContext
Math any declaration context.
Stream & operator<<(Stream &s, const Mangled &obj)
@ eAddressTypeFile
Address is an address as found in an object or symbol file.
@ eAddressTypeHost
Address is an address in the process that is running this code.
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
@ eDescriptionLevelVerbose
std::weak_ptr< lldb_private::Module > ModuleWP
Format
Display format definitions.
LanguageType
Programming language type.
@ eLanguageTypeC
Non-standardized C, such as K&R.
std::shared_ptr< lldb_private::Type > TypeSP
Encoding
Register encoding definitions.
MemberFunctionKind
Kind of member function.
@ eMemberFunctionKindInstanceMethod
A function that applies to a specific instance.
@ eMemberFunctionKindConstructor
A function used to create instances.
@ eMemberFunctionKindUnknown
Not sure what the type of this is.
@ eMemberFunctionKindDestructor
A function used to tear down existing instances.
@ eMemberFunctionKindStaticMethod
A function that applies to a type rather than any instance.
uint64_t user_id_t
Definition lldb-types.h:83
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::TypeImpl > TypeImplSP
std::shared_ptr< lldb_private::Module > ModuleSP
CompilerContext allows an array of these items to be passed to perform detailed lookups in SymbolVend...
void Dump(Stream &s) const
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
llvm::SmallVector< llvm::StringRef > scope
UserID(lldb::user_id_t uid=LLDB_INVALID_UID)
Construct with optional user ID.
Definition UserID.h:33
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition UserID.h:47