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
640 m_compiler_type = encoding_type->GetForwardCompilerType()
643 break;
644
648 break;
649
653 break;
654
658 m_payload);
659 break;
660
661 default:
662 llvm_unreachable("Unhandled encoding_data_type.");
663 }
664 } else {
665 // We have no encoding type, return void?
666 auto type_system_or_err =
667 m_symbol_file->GetTypeSystemForLanguage(eLanguageTypeC);
668 if (auto err = type_system_or_err.takeError()) {
670 GetLog(LLDBLog::Symbols), std::move(err),
671 "Unable to construct void type from TypeSystemClang: {0}");
672 } else {
673 CompilerType void_compiler_type;
674 auto ts = *type_system_or_err;
675 if (ts)
676 void_compiler_type = ts->GetBasicTypeFromAST(eBasicTypeVoid);
677 switch (m_encoding_uid_type) {
678 case eEncodingIsUID:
679 m_compiler_type = void_compiler_type;
680 break;
681
683 m_compiler_type = void_compiler_type.AddConstModifier();
684 break;
685
687 m_compiler_type = void_compiler_type.AddRestrictModifier();
688 break;
689
691 m_compiler_type = void_compiler_type.AddVolatileModifier();
692 break;
693
695 m_compiler_type = void_compiler_type.GetAtomicType();
696 break;
697
699 m_compiler_type = void_compiler_type.CreateTypedef(
700 m_name.AsCString("__lldb_invalid_typedef_name"),
701 GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload);
702 break;
703
706 void_compiler_type.AddAddressSpaceModifier(m_payload)
708 break;
709
711 m_compiler_type = void_compiler_type.GetLValueReferenceType();
712 break;
713
715 m_compiler_type = void_compiler_type.GetRValueReferenceType();
716 break;
717
719 llvm_unreachable("Cannot handle eEncodingIsLLVMPtrAuthUID without "
720 "valid encoding_type");
721
722 default:
723 llvm_unreachable("Unhandled encoding_data_type.");
724 }
725 }
726 }
727
728 // When we have a EncodingUID, our "m_flags.compiler_type_resolve_state" is
729 // set to eResolveStateUnresolved so we need to update it to say that we
730 // now have a forward declaration since that is what we created above.
731 if (m_compiler_type.IsValid())
733 }
734
735 // Check if we have a forward reference to a class/struct/union/enum?
736 if (compiler_type_resolve_state == ResolveState::Layout ||
737 compiler_type_resolve_state == ResolveState::Full) {
738 // Check if we have a forward reference to a class/struct/union/enum?
739 if (m_compiler_type.IsValid() &&
740 m_compiler_type_resolve_state < compiler_type_resolve_state) {
742 if (!m_compiler_type.IsDefined()) {
743 // We have a forward declaration, we need to resolve it to a complete
744 // definition.
745 m_symbol_file->CompleteType(m_compiler_type);
746 }
747 }
748 }
749
750 // If we have an encoding type, then we need to make sure it is resolved
751 // appropriately.
753 if (encoding_type == nullptr)
754 encoding_type = GetEncodingType();
755 if (encoding_type) {
756 ResolveState encoding_compiler_type_resolve_state =
757 compiler_type_resolve_state;
758
759 if (compiler_type_resolve_state == ResolveState::Layout) {
760 switch (m_encoding_uid_type) {
764 encoding_compiler_type_resolve_state = ResolveState::Forward;
765 break;
766 default:
767 break;
768 }
769 }
770 encoding_type->ResolveCompilerType(encoding_compiler_type_resolve_state);
771 }
772 }
773 return m_compiler_type.IsValid();
774}
776 uint32_t encoding_mask = 1u << m_encoding_uid_type;
777 Type *encoding_type = GetEncodingType();
778 assert(encoding_type != this);
779 if (encoding_type)
780 encoding_mask |= encoding_type->GetEncodingMask();
781 return encoding_mask;
782}
783
788
793
798
802
803std::optional<Type::ParsedName>
804Type::GetTypeScopeAndBasename(llvm::StringRef name) {
805 ParsedName result;
806
807 if (name.empty())
808 return std::nullopt;
809
810 if (name.consume_front("struct "))
811 result.type_class = eTypeClassStruct;
812 else if (name.consume_front("class "))
813 result.type_class = eTypeClassClass;
814 else if (name.consume_front("union "))
815 result.type_class = eTypeClassUnion;
816 else if (name.consume_front("enum "))
817 result.type_class = eTypeClassEnumeration;
818 else if (name.consume_front("typedef "))
819 result.type_class = eTypeClassTypedef;
820
821 if (name.consume_front("::"))
822 result.scope.push_back("::");
823
824 bool prev_is_colon = false;
825 size_t template_depth = 0;
826 size_t name_begin = 0;
827 for (const auto &pos : llvm::enumerate(name)) {
828 switch (pos.value()) {
829 case ':':
830 if (prev_is_colon && template_depth == 0) {
831 llvm::StringRef scope_name = name.slice(name_begin, pos.index() - 1);
832 // The demanglers use these strings to represent anonymous
833 // namespaces. Convert it to a more language-agnostic form (which is
834 // also used in DWARF).
835 if (scope_name == "(anonymous namespace)" ||
836 scope_name == "`anonymous namespace'" ||
837 scope_name == "`anonymous-namespace'")
838 scope_name = "";
839 result.scope.push_back(scope_name);
840 name_begin = pos.index() + 1;
841 }
842 break;
843 case '<':
844 ++template_depth;
845 break;
846 case '>':
847 if (template_depth == 0)
848 return std::nullopt; // Invalid name.
849 --template_depth;
850 break;
851 }
852 prev_is_colon = pos.value() == ':';
853 }
854
855 if (name_begin < name.size() && template_depth == 0)
856 result.basename = name.substr(name_begin);
857 else
858 return std::nullopt;
859
860 return result;
861}
862
864 if (m_symbol_file)
865 return m_symbol_file->GetObjectFile()->GetModule();
866 return ModuleSP();
867}
868
870 if (m_compiler_type) {
871 auto ts = m_compiler_type.GetTypeSystem();
872 if (!ts)
873 return {};
874 SymbolFile *symbol_file = ts->GetSymbolFile();
875 if (symbol_file)
876 return symbol_file->GetObjectFile()->GetModule();
877 }
878 return {};
879}
880
882 if (in_type_sp) {
883 m_compiler_type = in_type_sp->GetForwardCompilerType();
884 m_type_name = in_type_sp->GetName();
885 }
886}
887
888TypeAndOrName::TypeAndOrName(const char *in_type_str)
889 : m_type_name(in_type_str) {}
890
892 : m_type_name(in_type_const_string) {}
893
894bool TypeAndOrName::operator==(const TypeAndOrName &other) const {
895 if (m_compiler_type != other.m_compiler_type)
896 return false;
897 if (m_type_name != other.m_type_name)
898 return false;
899 return true;
900}
901
902bool TypeAndOrName::operator!=(const TypeAndOrName &other) const {
903 return !(*this == other);
904}
905
907 if (m_type_name)
908 return m_type_name;
909 if (m_compiler_type)
910 return m_compiler_type.GetTypeName();
911 return ConstString("<invalid>");
912}
913
915 m_type_name = type_name;
916}
917
918void TypeAndOrName::SetName(const char *type_name_cstr) {
919 m_type_name.SetCString(type_name_cstr);
920}
921
922void TypeAndOrName::SetName(llvm::StringRef type_name) {
923 m_type_name.SetString(type_name);
924}
925
927 if (type_sp) {
928 m_compiler_type = type_sp->GetForwardCompilerType();
929 m_type_name = type_sp->GetName();
930 } else
931 Clear();
932}
933
935 m_compiler_type = compiler_type;
936 if (m_compiler_type)
937 m_type_name = m_compiler_type.GetTypeName();
938}
939
941 return !((bool)m_type_name || (bool)m_compiler_type);
942}
943
945 m_type_name.Clear();
946 m_compiler_type.Clear();
947}
948
949bool TypeAndOrName::HasName() const { return (bool)m_type_name; }
950
952 return m_compiler_type.IsValid();
953}
954
957 SetType(type_sp);
958}
959
960TypeImpl::TypeImpl(const CompilerType &compiler_type)
962 SetType(compiler_type);
963}
964
965TypeImpl::TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic)
966 : m_module_wp(), m_static_type(), m_dynamic_type(dynamic) {
967 SetType(type_sp, dynamic);
968}
969
971 const CompilerType &dynamic_type)
973 SetType(static_type, dynamic_type);
974}
975
976void TypeImpl::SetType(const lldb::TypeSP &type_sp) {
977 if (type_sp) {
978 m_static_type = type_sp->GetForwardCompilerType();
979 m_exe_module_wp = type_sp->GetExeModule();
980 m_module_wp = type_sp->GetModule();
981 } else {
982 m_static_type.Clear();
984 }
985}
986
987void TypeImpl::SetType(const CompilerType &compiler_type) {
989 m_static_type = compiler_type;
990}
991
992void TypeImpl::SetType(const lldb::TypeSP &type_sp,
993 const CompilerType &dynamic) {
994 SetType(type_sp);
995 m_dynamic_type = dynamic;
996}
997
998void TypeImpl::SetType(const CompilerType &compiler_type,
999 const CompilerType &dynamic) {
1001 m_static_type = compiler_type;
1002 m_dynamic_type = dynamic;
1003}
1004
1006 return CheckModuleCommon(m_module_wp, module_sp);
1007}
1008
1010 return CheckModuleCommon(m_exe_module_wp, module_sp);
1011}
1012
1014 lldb::ModuleSP &module_sp) const {
1015 // Check if we have a module for this type. If we do and the shared pointer
1016 // is can be successfully initialized with m_module_wp, return true. Else
1017 // return false if we didn't have a module, or if we had a module and it has
1018 // been deleted. Any functions doing anything with a TypeSP in this TypeImpl
1019 // class should call this function and only do anything with the ivars if
1020 // this function returns true. If we have a module, the "module_sp" will be
1021 // filled in with a strong reference to the module so that the module will at
1022 // least stay around long enough for the type query to succeed.
1023 module_sp = input_module_wp.lock();
1024 if (!module_sp) {
1025 lldb::ModuleWP empty_module_wp;
1026 // If either call to "std::weak_ptr::owner_before(...) value returns true,
1027 // this indicates that m_module_wp once contained (possibly still does) a
1028 // reference to a valid shared pointer. This helps us know if we had a
1029 // valid reference to a section which is now invalid because the module it
1030 // was in was deleted
1031 if (empty_module_wp.owner_before(input_module_wp) ||
1032 input_module_wp.owner_before(empty_module_wp)) {
1033 // input_module_wp had a valid reference to a module, but all strong
1034 // references have been released and the module has been deleted
1035 return false;
1036 }
1037 }
1038 // We either successfully locked the module, or didn't have one to begin with
1039 return true;
1040}
1041
1042bool TypeImpl::operator==(const TypeImpl &rhs) const {
1043 return m_static_type == rhs.m_static_type &&
1045}
1046
1047bool TypeImpl::operator!=(const TypeImpl &rhs) const {
1048 return !(*this == rhs);
1049}
1050
1051bool TypeImpl::IsValid() const {
1052 // just a name is not valid
1053 ModuleSP module_sp;
1054 if (CheckModule(module_sp))
1055 return m_static_type.IsValid() || m_dynamic_type.IsValid();
1056 return false;
1057}
1058
1059TypeImpl::operator bool() const { return IsValid(); }
1060
1063 m_static_type.Clear();
1064 m_dynamic_type.Clear();
1065}
1066
1068 lldb::ModuleSP module_sp;
1069 if (CheckExeModule(module_sp))
1070 return module_sp;
1071 return nullptr;
1072}
1073
1075 ModuleSP module_sp;
1076 if (CheckModule(module_sp)) {
1077 if (m_dynamic_type)
1078 return m_dynamic_type.GetTypeName();
1079 return m_static_type.GetTypeName();
1080 }
1081 return ConstString();
1082}
1083
1085 ModuleSP module_sp;
1086 if (CheckModule(module_sp)) {
1087 if (m_dynamic_type)
1088 return m_dynamic_type.GetDisplayTypeName();
1089 return m_static_type.GetDisplayTypeName();
1090 }
1091 return ConstString();
1092}
1093
1095 ModuleSP module_sp;
1096 if (CheckModule(module_sp)) {
1097 if (m_dynamic_type.IsValid()) {
1098 return TypeImpl(m_static_type.GetPointerType(),
1099 m_dynamic_type.GetPointerType());
1100 }
1101 return TypeImpl(m_static_type.GetPointerType());
1102 }
1103 return TypeImpl();
1104}
1105
1107 ModuleSP module_sp;
1108 if (CheckModule(module_sp)) {
1109 if (m_dynamic_type.IsValid()) {
1110 return TypeImpl(m_static_type.GetPointeeType(),
1111 m_dynamic_type.GetPointeeType());
1112 }
1113 return TypeImpl(m_static_type.GetPointeeType());
1114 }
1115 return TypeImpl();
1116}
1117
1119 ModuleSP module_sp;
1120 if (CheckModule(module_sp)) {
1121 if (m_dynamic_type.IsValid()) {
1122 return TypeImpl(m_static_type.GetLValueReferenceType(),
1123 m_dynamic_type.GetLValueReferenceType());
1124 }
1125 return TypeImpl(m_static_type.GetLValueReferenceType());
1126 }
1127 return TypeImpl();
1128}
1129
1131 ModuleSP module_sp;
1132 if (CheckModule(module_sp)) {
1133 if (m_dynamic_type.IsValid()) {
1134 return TypeImpl(m_static_type.GetTypedefedType(),
1135 m_dynamic_type.GetTypedefedType());
1136 }
1137 return TypeImpl(m_static_type.GetTypedefedType());
1138 }
1139 return TypeImpl();
1140}
1141
1143 ModuleSP module_sp;
1144 if (CheckModule(module_sp)) {
1145 if (m_dynamic_type.IsValid()) {
1146 return TypeImpl(m_static_type.GetNonReferenceType(),
1147 m_dynamic_type.GetNonReferenceType());
1148 }
1149 return TypeImpl(m_static_type.GetNonReferenceType());
1150 }
1151 return TypeImpl();
1152}
1153
1155 ModuleSP module_sp;
1156 if (CheckModule(module_sp)) {
1157 if (m_dynamic_type.IsValid()) {
1158 return TypeImpl(m_static_type.GetFullyUnqualifiedType(),
1159 m_dynamic_type.GetFullyUnqualifiedType());
1160 }
1161 return TypeImpl(m_static_type.GetFullyUnqualifiedType());
1162 }
1163 return TypeImpl();
1164}
1165
1167 ModuleSP module_sp;
1168 if (CheckModule(module_sp)) {
1169 if (m_dynamic_type.IsValid()) {
1170 return TypeImpl(m_static_type.GetCanonicalType(),
1171 m_dynamic_type.GetCanonicalType());
1172 }
1173 return TypeImpl(m_static_type.GetCanonicalType());
1174 }
1175 return TypeImpl();
1176}
1177
1179 ModuleSP module_sp;
1180 if (CheckModule(module_sp)) {
1181 if (prefer_dynamic) {
1182 if (m_dynamic_type.IsValid())
1183 return m_dynamic_type;
1184 }
1185 return m_static_type;
1186 }
1187 return CompilerType();
1188}
1189
1191 ModuleSP module_sp;
1192 if (CheckModule(module_sp)) {
1193 if (prefer_dynamic) {
1194 if (m_dynamic_type.IsValid())
1195 return m_dynamic_type.GetTypeSystem();
1196 }
1197 return m_static_type.GetTypeSystem();
1198 }
1199 return {};
1200}
1201
1203 lldb::DescriptionLevel description_level) {
1204 ModuleSP module_sp;
1205 if (CheckModule(module_sp)) {
1206 if (m_dynamic_type.IsValid()) {
1207 strm.PutCString("Dynamic:\n");
1208 m_dynamic_type.DumpTypeDescription(&strm);
1209 strm.PutCString("\nStatic:\n");
1210 }
1211 m_static_type.DumpTypeDescription(&strm);
1212 } else {
1213 strm.PutCString("Invalid TypeImpl module for type has been deleted\n");
1214 }
1215 return true;
1216}
1217
1219 if (name.empty())
1220 return CompilerType();
1221 return GetCompilerType(/*prefer_dynamic=*/true)
1223}
1224
1228
1230
1232 return m_decl.GetMangledName();
1233}
1234
1236
1240
1242 switch (m_kind) {
1244 return false;
1246 stream.Printf("constructor for %s",
1247 m_type.GetTypeName().AsCString("<unknown>"));
1248 break;
1250 stream.Printf("destructor for %s",
1251 m_type.GetTypeName().AsCString("<unknown>"));
1252 break;
1254 stream.Format("instance method {0} of type {1}", m_name,
1255 m_decl.GetDeclContext().GetName());
1256 break;
1258 stream.Format("static method {0} of type {1}", m_name,
1259 m_decl.GetDeclContext().GetName());
1260 break;
1261 }
1262 return true;
1263}
1264
1266 if (m_type)
1267 return m_type.GetFunctionReturnType();
1268 return m_decl.GetFunctionReturnType();
1269}
1270
1272 if (m_type)
1273 return m_type.GetNumberOfFunctionArguments();
1274 else
1275 return m_decl.GetNumFunctionArguments();
1276}
1277
1279 if (m_type)
1280 return m_type.GetFunctionArgumentAtIndex(idx);
1281 else
1282 return m_decl.GetFunctionArgumentType(idx);
1283}
1284
1286 ConstString name,
1287 const llvm::APSInt &value)
1288 : m_integer_type_sp(integer_type_sp), m_name(name), m_value(value),
1289 m_valid((bool)name && (bool)integer_type_sp)
1290
1291{}
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
CompilerType AddAddressSpaceModifier(uint32_t address_space) const
Return a new CompilerType that qualifies this type with the given target address space if this type i...
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
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