1//===-- TypeSystemClang.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 "TypeSystemClang.h"
10
11#include "clang/AST/DeclBase.h"
12#include "clang/AST/ExprCXX.h"
13#include "clang/Frontend/ASTConsumers.h"
14#include "llvm/Support/Casting.h"
15#include "llvm/Support/FormatAdapters.h"
16#include "llvm/Support/FormatVariadic.h"
17
18#include <mutex>
19#include <memory>
20#include <string>
21#include <vector>
22
23#include "clang/AST/ASTContext.h"
24#include "clang/AST/ASTImporter.h"
25#include "clang/AST/Attr.h"
26#include "clang/AST/CXXInheritance.h"
27#include "clang/AST/DeclObjC.h"
28#include "clang/AST/DeclTemplate.h"
29#include "clang/AST/Mangle.h"
30#include "clang/AST/RecordLayout.h"
31#include "clang/AST/Type.h"
32#include "clang/AST/VTableBuilder.h"
33#include "clang/Basic/Builtins.h"
34#include "clang/Basic/Diagnostic.h"
35#include "clang/Basic/FileManager.h"
36#include "clang/Basic/FileSystemOptions.h"
37#include "clang/Basic/LangStandard.h"
38#include "clang/Basic/SourceManager.h"
39#include "clang/Basic/TargetInfo.h"
40#include "clang/Basic/TargetOptions.h"
41#include "clang/Frontend/FrontendOptions.h"
42#include "clang/Lex/HeaderSearch.h"
43#include "clang/Lex/HeaderSearchOptions.h"
44#include "clang/Lex/ModuleMap.h"
45#include "clang/Sema/Sema.h"
46
47#include "llvm/Support/Signals.h"
48#include "llvm/Support/Threading.h"
49
50#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
51#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
52#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h"
53#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
54#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
55#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
56#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
57#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
58#include "lldb/Core/Debugger.h"
59#include "lldb/Core/DumpDataExtractor.h"
60#include "lldb/Core/Module.h"
61#include "lldb/Core/PluginManager.h"
62#include "lldb/Core/UniqueCStringMap.h"
63#include "lldb/Host/StreamFile.h"
64#include "lldb/Symbol/ObjectFile.h"
65#include "lldb/Symbol/SymbolFile.h"
66#include "lldb/Target/ExecutionContext.h"
67#include "lldb/Target/Language.h"
68#include "lldb/Target/Process.h"
69#include "lldb/Target/Target.h"
70#include "lldb/Utility/ArchSpec.h"
71#include "lldb/Utility/DataExtractor.h"
72#include "lldb/Utility/Flags.h"
73#include "lldb/Utility/LLDBAssert.h"
74#include "lldb/Utility/LLDBLog.h"
75#include "lldb/Utility/RegularExpression.h"
76#include "lldb/Utility/Scalar.h"
77#include "lldb/Utility/ThreadSafeDenseMap.h"
78
79#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
80#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
81#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
82#include "Plugins/SymbolFile/NativePDB/PdbAstBuilder.h"
83
84#include <cstdio>
85
86#include <optional>
87
88using namespace lldb;
89using namespace lldb_private;
90using namespace lldb_private::dwarf;
91using namespace lldb_private::plugin::dwarf;
92using namespace clang;
93using llvm::StringSwitch;
94
95LLDB_PLUGIN_DEFINE(TypeSystemClang)
96
97namespace {
98static void VerifyDecl(clang::Decl *decl) {
99 assert(decl && "VerifyDecl called with nullptr?");
100#ifndef NDEBUG
101 // We don't care about the actual access value here but only want to trigger
102 // that Clang calls its internal Decl::AccessDeclContextCheck validation.
103 decl->getAccess();
104#endif
105}
106
107static inline bool
108TypeSystemClangSupportsLanguage(lldb::LanguageType language) {
109 return language == eLanguageTypeUnknown || // Clang is the default type system
110 lldb_private::Language::LanguageIsC(language) ||
111 lldb_private::Language::LanguageIsCPlusPlus(language) ||
112 lldb_private::Language::LanguageIsObjC(language) ||
113 lldb_private::Language::LanguageIsPascal(language) ||
114 // Use Clang for Rust until there is a proper language plugin for it
115 language == eLanguageTypeRust ||
116 // Use Clang for D until there is a proper language plugin for it
117 language == eLanguageTypeD ||
118 // Open Dylan compiler debug info is designed to be Clang-compatible
119 language == eLanguageTypeDylan;
120}
121
122// Checks whether m1 is an overload of m2 (as opposed to an override). This is
123// called by addOverridesForMethod to distinguish overrides (which share a
124// vtable entry) from overloads (which require distinct entries).
125bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) {
126 // FIXME: This should detect covariant return types, but currently doesn't.
127 lldbassert(&m1->getASTContext() == &m2->getASTContext() &&
128 "Methods should have the same AST context");
129 clang::ASTContext &context = m1->getASTContext();
130
131 const auto *m1Type = llvm::cast<clang::FunctionProtoType>(
132 Val: context.getCanonicalType(T: m1->getType()));
133
134 const auto *m2Type = llvm::cast<clang::FunctionProtoType>(
135 Val: context.getCanonicalType(T: m2->getType()));
136
137 auto compareArgTypes = [&context](const clang::QualType &m1p,
138 const clang::QualType &m2p) {
139 return context.hasSameType(T1: m1p.getUnqualifiedType(),
140 T2: m2p.getUnqualifiedType());
141 };
142
143 // FIXME: In C++14 and later, we can just pass m2Type->param_type_end()
144 // as a fourth parameter to std::equal().
145 return (m1->getNumParams() != m2->getNumParams()) ||
146 !std::equal(first1: m1Type->param_type_begin(), last1: m1Type->param_type_end(),
147 first2: m2Type->param_type_begin(), binary_pred: compareArgTypes);
148}
149
150// If decl is a virtual method, walk the base classes looking for methods that
151// decl overrides. This table of overridden methods is used by IRGen to
152// determine the vtable layout for decl's parent class.
153void addOverridesForMethod(clang::CXXMethodDecl *decl) {
154 if (!decl->isVirtual())
155 return;
156
157 clang::CXXBasePaths paths;
158 llvm::SmallVector<clang::NamedDecl *, 4> decls;
159
160 auto find_overridden_methods =
161 [&decls, decl](const clang::CXXBaseSpecifier *specifier,
162 clang::CXXBasePath &path) {
163 if (auto *base_record = llvm::dyn_cast<clang::CXXRecordDecl>(
164 Val: specifier->getType()->castAs<clang::RecordType>()->getDecl())) {
165
166 clang::DeclarationName name = decl->getDeclName();
167
168 // If this is a destructor, check whether the base class destructor is
169 // virtual.
170 if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
171 if (auto *baseDtorDecl = base_record->getDestructor()) {
172 if (baseDtorDecl->isVirtual()) {
173 decls.push_back(Elt: baseDtorDecl);
174 return true;
175 } else
176 return false;
177 }
178
179 // Otherwise, search for name in the base class.
180 for (path.Decls = base_record->lookup(Name: name).begin();
181 path.Decls != path.Decls.end(); ++path.Decls) {
182 if (auto *method_decl =
183 llvm::dyn_cast<clang::CXXMethodDecl>(Val: *path.Decls))
184 if (method_decl->isVirtual() && !isOverload(m1: decl, m2: method_decl)) {
185 decls.push_back(Elt: method_decl);
186 return true;
187 }
188 }
189 }
190
191 return false;
192 };
193
194 if (decl->getParent()->lookupInBases(BaseMatches: find_overridden_methods, Paths&: paths)) {
195 for (auto *overridden_decl : decls)
196 decl->addOverriddenMethod(
197 MD: llvm::cast<clang::CXXMethodDecl>(Val: overridden_decl));
198 }
199}
200}
201
202static lldb::addr_t GetVTableAddress(Process &process,
203 VTableContextBase &vtable_ctx,
204 ValueObject &valobj,
205 const ASTRecordLayout &record_layout) {
206 // Retrieve type info
207 CompilerType pointee_type;
208 CompilerType this_type(valobj.GetCompilerType());
209 uint32_t type_info = this_type.GetTypeInfo(pointee_or_element_compiler_type: &pointee_type);
210 if (!type_info)
211 return LLDB_INVALID_ADDRESS;
212
213 // Check if it's a pointer or reference
214 bool ptr_or_ref = false;
215 if (type_info & (eTypeIsPointer | eTypeIsReference)) {
216 ptr_or_ref = true;
217 type_info = pointee_type.GetTypeInfo();
218 }
219
220 // We process only C++ classes
221 const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus;
222 if ((type_info & cpp_class) != cpp_class)
223 return LLDB_INVALID_ADDRESS;
224
225 // Calculate offset to VTable pointer
226 lldb::offset_t vbtable_ptr_offset =
227 vtable_ctx.isMicrosoft() ? record_layout.getVBPtrOffset().getQuantity()
228 : 0;
229
230 if (ptr_or_ref) {
231 // We have a pointer / ref to object, so read
232 // VTable pointer from process memory
233
234 if (valobj.GetAddressTypeOfChildren() != eAddressTypeLoad)
235 return LLDB_INVALID_ADDRESS;
236
237 auto vbtable_ptr_addr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
238 if (vbtable_ptr_addr == LLDB_INVALID_ADDRESS)
239 return LLDB_INVALID_ADDRESS;
240
241 vbtable_ptr_addr += vbtable_ptr_offset;
242
243 Status err;
244 return process.ReadPointerFromMemory(vm_addr: vbtable_ptr_addr, error&: err);
245 }
246
247 // We have an object already read from process memory,
248 // so just extract VTable pointer from it
249
250 DataExtractor data;
251 Status err;
252 auto size = valobj.GetData(data, error&: err);
253 if (err.Fail() || vbtable_ptr_offset + data.GetAddressByteSize() > size)
254 return LLDB_INVALID_ADDRESS;
255
256 return data.GetAddress(offset_ptr: &vbtable_ptr_offset);
257}
258
259static int64_t ReadVBaseOffsetFromVTable(Process &process,
260 VTableContextBase &vtable_ctx,
261 lldb::addr_t vtable_ptr,
262 const CXXRecordDecl *cxx_record_decl,
263 const CXXRecordDecl *base_class_decl) {
264 if (vtable_ctx.isMicrosoft()) {
265 clang::MicrosoftVTableContext &msoft_vtable_ctx =
266 static_cast<clang::MicrosoftVTableContext &>(vtable_ctx);
267
268 // Get the index into the virtual base table. The
269 // index is the index in uint32_t from vbtable_ptr
270 const unsigned vbtable_index =
271 msoft_vtable_ctx.getVBTableIndex(Derived: cxx_record_decl, VBase: base_class_decl);
272 const lldb::addr_t base_offset_addr = vtable_ptr + vbtable_index * 4;
273 Status err;
274 return process.ReadSignedIntegerFromMemory(load_addr: base_offset_addr, byte_size: 4, INT64_MAX,
275 error&: err);
276 }
277
278 clang::ItaniumVTableContext &itanium_vtable_ctx =
279 static_cast<clang::ItaniumVTableContext &>(vtable_ctx);
280
281 clang::CharUnits base_offset_offset =
282 itanium_vtable_ctx.getVirtualBaseOffsetOffset(RD: cxx_record_decl,
283 VBase: base_class_decl);
284 const lldb::addr_t base_offset_addr =
285 vtable_ptr + base_offset_offset.getQuantity();
286 const uint32_t base_offset_size = process.GetAddressByteSize();
287 Status err;
288 return process.ReadSignedIntegerFromMemory(load_addr: base_offset_addr, byte_size: base_offset_size,
289 INT64_MAX, error&: err);
290}
291
292static bool GetVBaseBitOffset(VTableContextBase &vtable_ctx,
293 ValueObject &valobj,
294 const ASTRecordLayout &record_layout,
295 const CXXRecordDecl *cxx_record_decl,
296 const CXXRecordDecl *base_class_decl,
297 int32_t &bit_offset) {
298 ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
299 Process *process = exe_ctx.GetProcessPtr();
300 if (!process)
301 return false;
302
303 lldb::addr_t vtable_ptr =
304 GetVTableAddress(process&: *process, vtable_ctx, valobj, record_layout);
305 if (vtable_ptr == LLDB_INVALID_ADDRESS)
306 return false;
307
308 auto base_offset = ReadVBaseOffsetFromVTable(
309 process&: *process, vtable_ctx, vtable_ptr, cxx_record_decl, base_class_decl);
310 if (base_offset == INT64_MAX)
311 return false;
312
313 bit_offset = base_offset * 8;
314
315 return true;
316}
317
318typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, TypeSystemClang *>
319 ClangASTMap;
320
321static ClangASTMap &GetASTMap() {
322 static ClangASTMap *g_map_ptr = nullptr;
323 static llvm::once_flag g_once_flag;
324 llvm::call_once(flag&: g_once_flag, F: []() {
325 g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins
326 });
327 return *g_map_ptr;
328}
329
330TypePayloadClang::TypePayloadClang(OptionalClangModuleID owning_module,
331 bool is_complete_objc_class)
332 : m_payload(owning_module.GetValue()) {
333 SetIsCompleteObjCClass(is_complete_objc_class);
334}
335
336void TypePayloadClang::SetOwningModule(OptionalClangModuleID id) {
337 assert(id.GetValue() < ObjCClassBit);
338 bool is_complete = IsCompleteObjCClass();
339 m_payload = id.GetValue();
340 SetIsCompleteObjCClass(is_complete);
341}
342
343static void SetMemberOwningModule(clang::Decl *member,
344 const clang::Decl *parent) {
345 if (!member || !parent)
346 return;
347
348 OptionalClangModuleID id(parent->getOwningModuleID());
349 if (!id.HasValue())
350 return;
351
352 member->setFromASTFile();
353 member->setOwningModuleID(id.GetValue());
354 member->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
355 if (llvm::isa<clang::NamedDecl>(Val: member))
356 if (auto *dc = llvm::dyn_cast<clang::DeclContext>(Val: parent)) {
357 dc->setHasExternalVisibleStorage(true);
358 // This triggers ExternalASTSource::FindExternalVisibleDeclsByName() to be
359 // called when searching for members.
360 dc->setHasExternalLexicalStorage(true);
361 }
362}
363
364char TypeSystemClang::ID;
365
366bool TypeSystemClang::IsOperator(llvm::StringRef name,
367 clang::OverloadedOperatorKind &op_kind) {
368 // All operators have to start with "operator".
369 if (!name.consume_front(Prefix: "operator"))
370 return false;
371
372 // Remember if there was a space after "operator". This is necessary to
373 // check for collisions with strangely named functions like "operatorint()".
374 bool space_after_operator = name.consume_front(Prefix: " ");
375
376 op_kind = StringSwitch<clang::OverloadedOperatorKind>(name)
377 .Case(S: "+", Value: clang::OO_Plus)
378 .Case(S: "+=", Value: clang::OO_PlusEqual)
379 .Case(S: "++", Value: clang::OO_PlusPlus)
380 .Case(S: "-", Value: clang::OO_Minus)
381 .Case(S: "-=", Value: clang::OO_MinusEqual)
382 .Case(S: "--", Value: clang::OO_MinusMinus)
383 .Case(S: "->", Value: clang::OO_Arrow)
384 .Case(S: "->*", Value: clang::OO_ArrowStar)
385 .Case(S: "*", Value: clang::OO_Star)
386 .Case(S: "*=", Value: clang::OO_StarEqual)
387 .Case(S: "/", Value: clang::OO_Slash)
388 .Case(S: "/=", Value: clang::OO_SlashEqual)
389 .Case(S: "%", Value: clang::OO_Percent)
390 .Case(S: "%=", Value: clang::OO_PercentEqual)
391 .Case(S: "^", Value: clang::OO_Caret)
392 .Case(S: "^=", Value: clang::OO_CaretEqual)
393 .Case(S: "&", Value: clang::OO_Amp)
394 .Case(S: "&=", Value: clang::OO_AmpEqual)
395 .Case(S: "&&", Value: clang::OO_AmpAmp)
396 .Case(S: "|", Value: clang::OO_Pipe)
397 .Case(S: "|=", Value: clang::OO_PipeEqual)
398 .Case(S: "||", Value: clang::OO_PipePipe)
399 .Case(S: "~", Value: clang::OO_Tilde)
400 .Case(S: "!", Value: clang::OO_Exclaim)
401 .Case(S: "!=", Value: clang::OO_ExclaimEqual)
402 .Case(S: "=", Value: clang::OO_Equal)
403 .Case(S: "==", Value: clang::OO_EqualEqual)
404 .Case(S: "<", Value: clang::OO_Less)
405 .Case(S: "<=>", Value: clang::OO_Spaceship)
406 .Case(S: "<<", Value: clang::OO_LessLess)
407 .Case(S: "<<=", Value: clang::OO_LessLessEqual)
408 .Case(S: "<=", Value: clang::OO_LessEqual)
409 .Case(S: ">", Value: clang::OO_Greater)
410 .Case(S: ">>", Value: clang::OO_GreaterGreater)
411 .Case(S: ">>=", Value: clang::OO_GreaterGreaterEqual)
412 .Case(S: ">=", Value: clang::OO_GreaterEqual)
413 .Case(S: "()", Value: clang::OO_Call)
414 .Case(S: "[]", Value: clang::OO_Subscript)
415 .Case(S: ",", Value: clang::OO_Comma)
416 .Default(Value: clang::NUM_OVERLOADED_OPERATORS);
417
418 // We found a fitting operator, so we can exit now.
419 if (op_kind != clang::NUM_OVERLOADED_OPERATORS)
420 return true;
421
422 // After the "operator " or "operator" part is something unknown. This means
423 // it's either one of the named operators (new/delete), a conversion operator
424 // (e.g. operator bool) or a function which name starts with "operator"
425 // (e.g. void operatorbool).
426
427 // If it's a function that starts with operator it can't have a space after
428 // "operator" because identifiers can't contain spaces.
429 // E.g. "operator int" (conversion operator)
430 // vs. "operatorint" (function with colliding name).
431 if (!space_after_operator)
432 return false; // not an operator.
433
434 // Now the operator is either one of the named operators or a conversion
435 // operator.
436 op_kind = StringSwitch<clang::OverloadedOperatorKind>(name)
437 .Case(S: "new", Value: clang::OO_New)
438 .Case(S: "new[]", Value: clang::OO_Array_New)
439 .Case(S: "delete", Value: clang::OO_Delete)
440 .Case(S: "delete[]", Value: clang::OO_Array_Delete)
441 // conversion operators hit this case.
442 .Default(Value: clang::NUM_OVERLOADED_OPERATORS);
443
444 return true;
445}
446
447clang::AccessSpecifier
448TypeSystemClang::ConvertAccessTypeToAccessSpecifier(AccessType access) {
449 switch (access) {
450 default:
451 break;
452 case eAccessNone:
453 return AS_none;
454 case eAccessPublic:
455 return AS_public;
456 case eAccessPrivate:
457 return AS_private;
458 case eAccessProtected:
459 return AS_protected;
460 }
461 return AS_none;
462}
463
464static void ParseLangArgs(LangOptions &Opts, ArchSpec arch) {
465 // FIXME: Cleanup per-file based stuff.
466
467 std::vector<std::string> Includes;
468 LangOptions::setLangDefaults(Opts, Lang: clang::Language::ObjCXX, T: arch.GetTriple(),
469 Includes, LangStd: clang::LangStandard::lang_gnucxx98);
470
471 Opts.setValueVisibilityMode(DefaultVisibility);
472
473 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs is
474 // specified, or -std is set to a conforming mode.
475 Opts.Trigraphs = !Opts.GNUMode;
476 Opts.CharIsSigned = arch.CharIsSignedByDefault();
477 Opts.OptimizeSize = 0;
478
479 // FIXME: Eliminate this dependency.
480 // unsigned Opt =
481 // Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
482 // Opts.Optimize = Opt != 0;
483 unsigned Opt = 0;
484
485 // This is the __NO_INLINE__ define, which just depends on things like the
486 // optimization level and -fno-inline, not actually whether the backend has
487 // inlining enabled.
488 //
489 // FIXME: This is affected by other options (-fno-inline).
490 Opts.NoInlineDefine = !Opt;
491
492 // This is needed to allocate the extra space for the owning module
493 // on each decl.
494 Opts.ModulesLocalVisibility = 1;
495}
496
497TypeSystemClang::TypeSystemClang(llvm::StringRef name,
498 llvm::Triple target_triple) {
499 m_display_name = name.str();
500 if (!target_triple.str().empty())
501 SetTargetTriple(target_triple.str());
502 // The caller didn't pass an ASTContext so create a new one for this
503 // TypeSystemClang.
504 CreateASTContext();
505
506 LogCreation();
507}
508
509TypeSystemClang::TypeSystemClang(llvm::StringRef name,
510 ASTContext &existing_ctxt) {
511 m_display_name = name.str();
512 SetTargetTriple(existing_ctxt.getTargetInfo().getTriple().str());
513
514 m_ast_up.reset(p: &existing_ctxt);
515 GetASTMap().Insert(k: &existing_ctxt, v: this);
516
517 LogCreation();
518}
519
520// Destructor
521TypeSystemClang::~TypeSystemClang() { Finalize(); }
522
523lldb::TypeSystemSP TypeSystemClang::CreateInstance(lldb::LanguageType language,
524 lldb_private::Module *module,
525 Target *target) {
526 if (!TypeSystemClangSupportsLanguage(language))
527 return lldb::TypeSystemSP();
528 ArchSpec arch;
529 if (module)
530 arch = module->GetArchitecture();
531 else if (target)
532 arch = target->GetArchitecture();
533
534 if (!arch.IsValid())
535 return lldb::TypeSystemSP();
536
537 llvm::Triple triple = arch.GetTriple();
538 // LLVM wants this to be set to iOS or MacOSX; if we're working on
539 // a bare-boards type image, change the triple for llvm's benefit.
540 if (triple.getVendor() == llvm::Triple::Apple &&
541 triple.getOS() == llvm::Triple::UnknownOS) {
542 if (triple.getArch() == llvm::Triple::arm ||
543 triple.getArch() == llvm::Triple::aarch64 ||
544 triple.getArch() == llvm::Triple::aarch64_32 ||
545 triple.getArch() == llvm::Triple::thumb) {
546 triple.setOS(llvm::Triple::IOS);
547 } else {
548 triple.setOS(llvm::Triple::MacOSX);
549 }
550 }
551
552 if (module) {
553 std::string ast_name =
554 "ASTContext for '" + module->GetFileSpec().GetPath() + "'";
555 return std::make_shared<TypeSystemClang>(args&: ast_name, args&: triple);
556 } else if (target && target->IsValid())
557 return std::make_shared<ScratchTypeSystemClang>(args&: *target, args&: triple);
558 return lldb::TypeSystemSP();
559}
560
561LanguageSet TypeSystemClang::GetSupportedLanguagesForTypes() {
562 LanguageSet languages;
563 languages.Insert(language: lldb::eLanguageTypeC89);
564 languages.Insert(language: lldb::eLanguageTypeC);
565 languages.Insert(language: lldb::eLanguageTypeC11);
566 languages.Insert(language: lldb::eLanguageTypeC_plus_plus);
567 languages.Insert(language: lldb::eLanguageTypeC99);
568 languages.Insert(language: lldb::eLanguageTypeObjC);
569 languages.Insert(language: lldb::eLanguageTypeObjC_plus_plus);
570 languages.Insert(language: lldb::eLanguageTypeC_plus_plus_03);
571 languages.Insert(language: lldb::eLanguageTypeC_plus_plus_11);
572 languages.Insert(language: lldb::eLanguageTypeC11);
573 languages.Insert(language: lldb::eLanguageTypeC_plus_plus_14);
574 languages.Insert(language: lldb::eLanguageTypeC_plus_plus_17);
575 languages.Insert(language: lldb::eLanguageTypeC_plus_plus_20);
576 return languages;
577}
578
579LanguageSet TypeSystemClang::GetSupportedLanguagesForExpressions() {
580 LanguageSet languages;
581 languages.Insert(language: lldb::eLanguageTypeC_plus_plus);
582 languages.Insert(language: lldb::eLanguageTypeObjC_plus_plus);
583 languages.Insert(language: lldb::eLanguageTypeC_plus_plus_03);
584 languages.Insert(language: lldb::eLanguageTypeC_plus_plus_11);
585 languages.Insert(language: lldb::eLanguageTypeC_plus_plus_14);
586 languages.Insert(language: lldb::eLanguageTypeC_plus_plus_17);
587 languages.Insert(language: lldb::eLanguageTypeC_plus_plus_20);
588 return languages;
589}
590
591void TypeSystemClang::Initialize() {
592 PluginManager::RegisterPlugin(
593 name: GetPluginNameStatic(), description: "clang base AST context plug-in", create_callback: CreateInstance,
594 supported_languages_for_types: GetSupportedLanguagesForTypes(), supported_languages_for_expressions: GetSupportedLanguagesForExpressions());
595}
596
597void TypeSystemClang::Terminate() {
598 PluginManager::UnregisterPlugin(create_callback: CreateInstance);
599}
600
601void TypeSystemClang::Finalize() {
602 assert(m_ast_up);
603 GetASTMap().Erase(k: m_ast_up.get());
604 if (!m_ast_owned)
605 m_ast_up.release();
606
607 m_builtins_up.reset();
608 m_selector_table_up.reset();
609 m_identifier_table_up.reset();
610 m_target_info_up.reset();
611 m_target_options_rp.reset();
612 m_diagnostics_engine_up.reset();
613 m_source_manager_up.reset();
614 m_language_options_up.reset();
615}
616
617void TypeSystemClang::setSema(Sema *s) {
618 // Ensure that the new sema actually belongs to our ASTContext.
619 assert(s == nullptr || &s->getASTContext() == m_ast_up.get());
620 m_sema = s;
621}
622
623const char *TypeSystemClang::GetTargetTriple() {
624 return m_target_triple.c_str();
625}
626
627void TypeSystemClang::SetTargetTriple(llvm::StringRef target_triple) {
628 m_target_triple = target_triple.str();
629}
630
631void TypeSystemClang::SetExternalSource(
632 llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) {
633 ASTContext &ast = getASTContext();
634 ast.getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
635 ast.setExternalSource(ast_source_up);
636}
637
638ASTContext &TypeSystemClang::getASTContext() const {
639 assert(m_ast_up);
640 return *m_ast_up;
641}
642
643class NullDiagnosticConsumer : public DiagnosticConsumer {
644public:
645 NullDiagnosticConsumer() { m_log = GetLog(mask: LLDBLog::Expressions); }
646
647 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
648 const clang::Diagnostic &info) override {
649 if (m_log) {
650 llvm::SmallVector<char, 32> diag_str(10);
651 info.FormatDiagnostic(OutStr&: diag_str);
652 diag_str.push_back(Elt: '\0');
653 LLDB_LOGF(m_log, "Compiler diagnostic: %s\n", diag_str.data());
654 }
655 }
656
657 DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
658 return new NullDiagnosticConsumer();
659 }
660
661private:
662 Log *m_log;
663};
664
665void TypeSystemClang::CreateASTContext() {
666 assert(!m_ast_up);
667 m_ast_owned = true;
668
669 m_language_options_up = std::make_unique<LangOptions>();
670 ParseLangArgs(Opts&: *m_language_options_up, arch: ArchSpec(GetTargetTriple()));
671
672 m_identifier_table_up =
673 std::make_unique<IdentifierTable>(args&: *m_language_options_up, args: nullptr);
674 m_builtins_up = std::make_unique<Builtin::Context>();
675
676 m_selector_table_up = std::make_unique<SelectorTable>();
677
678 clang::FileSystemOptions file_system_options;
679 m_file_manager_up = std::make_unique<clang::FileManager>(
680 args&: file_system_options, args: FileSystem::Instance().GetVirtualFileSystem());
681
682 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
683 m_diagnostic_options_up = std::make_unique<DiagnosticOptions>();
684 m_diagnostics_engine_up =
685 std::make_unique<DiagnosticsEngine>(args&: diag_id_sp, args&: *m_diagnostic_options_up);
686
687 m_source_manager_up = std::make_unique<clang::SourceManager>(
688 args&: *m_diagnostics_engine_up, args&: *m_file_manager_up);
689 m_ast_up = std::make_unique<ASTContext>(
690 args&: *m_language_options_up, args&: *m_source_manager_up, args&: *m_identifier_table_up,
691 args&: *m_selector_table_up, args&: *m_builtins_up, args: TU_Complete);
692
693 m_diagnostic_consumer_up = std::make_unique<NullDiagnosticConsumer>();
694 m_ast_up->getDiagnostics().setClient(client: m_diagnostic_consumer_up.get(), ShouldOwnClient: false);
695
696 // This can be NULL if we don't know anything about the architecture or if
697 // the target for an architecture isn't enabled in the llvm/clang that we
698 // built
699 TargetInfo *target_info = getTargetInfo();
700 if (target_info)
701 m_ast_up->InitBuiltinTypes(Target: *target_info);
702 else {
703 std::string err =
704 llvm::formatv(
705 Fmt: "Failed to initialize builtin ASTContext types for target '{0}'. "
706 "Printing variables may behave unexpectedly.",
707 Vals&: m_target_triple)
708 .str();
709
710 LLDB_LOG(GetLog(LLDBLog::Expressions), err.c_str());
711
712 static std::once_flag s_uninitialized_target_warning;
713 Debugger::ReportWarning(message: std::move(err), /*debugger_id=*/std::nullopt,
714 once: &s_uninitialized_target_warning);
715 }
716
717 GetASTMap().Insert(k: m_ast_up.get(), v: this);
718
719 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_up(
720 new ClangExternalASTSourceCallbacks(*this));
721 SetExternalSource(ast_source_up);
722}
723
724TypeSystemClang *TypeSystemClang::GetASTContext(clang::ASTContext *ast) {
725 TypeSystemClang *clang_ast = GetASTMap().Lookup(k: ast);
726 return clang_ast;
727}
728
729clang::MangleContext *TypeSystemClang::getMangleContext() {
730 if (m_mangle_ctx_up == nullptr)
731 m_mangle_ctx_up.reset(p: getASTContext().createMangleContext());
732 return m_mangle_ctx_up.get();
733}
734
735std::shared_ptr<clang::TargetOptions> &TypeSystemClang::getTargetOptions() {
736 if (m_target_options_rp == nullptr && !m_target_triple.empty()) {
737 m_target_options_rp = std::make_shared<clang::TargetOptions>();
738 if (m_target_options_rp != nullptr)
739 m_target_options_rp->Triple = m_target_triple;
740 }
741 return m_target_options_rp;
742}
743
744TargetInfo *TypeSystemClang::getTargetInfo() {
745 // target_triple should be something like "x86_64-apple-macosx"
746 if (m_target_info_up == nullptr && !m_target_triple.empty())
747 m_target_info_up.reset(p: TargetInfo::CreateTargetInfo(
748 Diags&: getASTContext().getDiagnostics(), Opts&: *getTargetOptions()));
749 return m_target_info_up.get();
750}
751
752#pragma mark Basic Types
753
754static inline bool QualTypeMatchesBitSize(const uint64_t bit_size,
755 ASTContext &ast, QualType qual_type) {
756 uint64_t qual_type_bit_size = ast.getTypeSize(T: qual_type);
757 return qual_type_bit_size == bit_size;
758}
759
760CompilerType
761TypeSystemClang::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
762 size_t bit_size) {
763 ASTContext &ast = getASTContext();
764
765 if (!ast.VoidPtrTy)
766 return {};
767
768 switch (encoding) {
769 case eEncodingInvalid:
770 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.VoidPtrTy))
771 return GetType(qt: ast.VoidPtrTy);
772 break;
773
774 case eEncodingUint:
775 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedCharTy))
776 return GetType(qt: ast.UnsignedCharTy);
777 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedShortTy))
778 return GetType(qt: ast.UnsignedShortTy);
779 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedIntTy))
780 return GetType(qt: ast.UnsignedIntTy);
781 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedLongTy))
782 return GetType(qt: ast.UnsignedLongTy);
783 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedLongLongTy))
784 return GetType(qt: ast.UnsignedLongLongTy);
785 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedInt128Ty))
786 return GetType(qt: ast.UnsignedInt128Ty);
787 break;
788
789 case eEncodingSint:
790 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.SignedCharTy))
791 return GetType(qt: ast.SignedCharTy);
792 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.ShortTy))
793 return GetType(qt: ast.ShortTy);
794 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.IntTy))
795 return GetType(qt: ast.IntTy);
796 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.LongTy))
797 return GetType(qt: ast.LongTy);
798 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.LongLongTy))
799 return GetType(qt: ast.LongLongTy);
800 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.Int128Ty))
801 return GetType(qt: ast.Int128Ty);
802 break;
803
804 case eEncodingIEEE754:
805 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.FloatTy))
806 return GetType(qt: ast.FloatTy);
807 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.DoubleTy))
808 return GetType(qt: ast.DoubleTy);
809 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.LongDoubleTy))
810 return GetType(qt: ast.LongDoubleTy);
811 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.HalfTy))
812 return GetType(qt: ast.HalfTy);
813 break;
814
815 case eEncodingVector:
816 // Sanity check that bit_size is a multiple of 8's.
817 if (bit_size && !(bit_size & 0x7u))
818 return GetType(qt: ast.getExtVectorType(VectorType: ast.UnsignedCharTy, NumElts: bit_size / 8));
819 break;
820 }
821
822 return CompilerType();
823}
824
825lldb::BasicType TypeSystemClang::GetBasicTypeEnumeration(llvm::StringRef name) {
826 static const llvm::StringMap<lldb::BasicType> g_type_map = {
827 // "void"
828 {"void", eBasicTypeVoid},
829
830 // "char"
831 {"char", eBasicTypeChar},
832 {"signed char", eBasicTypeSignedChar},
833 {"unsigned char", eBasicTypeUnsignedChar},
834 {"wchar_t", eBasicTypeWChar},
835 {"signed wchar_t", eBasicTypeSignedWChar},
836 {"unsigned wchar_t", eBasicTypeUnsignedWChar},
837
838 // "short"
839 {"short", eBasicTypeShort},
840 {"short int", eBasicTypeShort},
841 {"unsigned short", eBasicTypeUnsignedShort},
842 {"unsigned short int", eBasicTypeUnsignedShort},
843
844 // "int"
845 {"int", eBasicTypeInt},
846 {"signed int", eBasicTypeInt},
847 {"unsigned int", eBasicTypeUnsignedInt},
848 {"unsigned", eBasicTypeUnsignedInt},
849
850 // "long"
851 {"long", eBasicTypeLong},
852 {"long int", eBasicTypeLong},
853 {"unsigned long", eBasicTypeUnsignedLong},
854 {"unsigned long int", eBasicTypeUnsignedLong},
855
856 // "long long"
857 {"long long", eBasicTypeLongLong},
858 {"long long int", eBasicTypeLongLong},
859 {"unsigned long long", eBasicTypeUnsignedLongLong},
860 {"unsigned long long int", eBasicTypeUnsignedLongLong},
861
862 // "int128"
863 {"__int128_t", eBasicTypeInt128},
864 {"__uint128_t", eBasicTypeUnsignedInt128},
865
866 // "bool"
867 {"bool", eBasicTypeBool},
868 {"_Bool", eBasicTypeBool},
869
870 // Miscellaneous
871 {"float", eBasicTypeFloat},
872 {"double", eBasicTypeDouble},
873 {"long double", eBasicTypeLongDouble},
874 {"id", eBasicTypeObjCID},
875 {"SEL", eBasicTypeObjCSel},
876 {"nullptr", eBasicTypeNullPtr},
877 };
878
879 auto iter = g_type_map.find(Key: name);
880 if (iter == g_type_map.end())
881 return eBasicTypeInvalid;
882
883 return iter->second;
884}
885
886uint32_t TypeSystemClang::GetPointerByteSize() {
887 if (m_pointer_byte_size == 0)
888 if (auto size = GetBasicType(type: lldb::eBasicTypeVoid)
889 .GetPointerType()
890 .GetByteSize(exe_scope: nullptr))
891 m_pointer_byte_size = *size;
892 return m_pointer_byte_size;
893}
894
895CompilerType TypeSystemClang::GetBasicType(lldb::BasicType basic_type) {
896 clang::ASTContext &ast = getASTContext();
897
898 lldb::opaque_compiler_type_t clang_type =
899 GetOpaqueCompilerType(ast: &ast, basic_type);
900
901 if (clang_type)
902 return CompilerType(weak_from_this(), clang_type);
903 return CompilerType();
904}
905
906CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize(
907 llvm::StringRef type_name, uint32_t dw_ate, uint32_t bit_size) {
908 ASTContext &ast = getASTContext();
909
910 if (!ast.VoidPtrTy)
911 return {};
912
913 switch (dw_ate) {
914 default:
915 break;
916
917 case DW_ATE_address:
918 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.VoidPtrTy))
919 return GetType(qt: ast.VoidPtrTy);
920 break;
921
922 case DW_ATE_boolean:
923 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.BoolTy))
924 return GetType(qt: ast.BoolTy);
925 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedCharTy))
926 return GetType(qt: ast.UnsignedCharTy);
927 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedShortTy))
928 return GetType(qt: ast.UnsignedShortTy);
929 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedIntTy))
930 return GetType(qt: ast.UnsignedIntTy);
931 break;
932
933 case DW_ATE_lo_user:
934 // This has been seen to mean DW_AT_complex_integer
935 if (type_name.contains(Other: "complex")) {
936 CompilerType complex_int_clang_type =
937 GetBuiltinTypeForDWARFEncodingAndBitSize(type_name: "int", dw_ate: DW_ATE_signed,
938 bit_size: bit_size / 2);
939 return GetType(
940 qt: ast.getComplexType(T: ClangUtil::GetQualType(ct: complex_int_clang_type)));
941 }
942 break;
943
944 case DW_ATE_complex_float: {
945 CanQualType FloatComplexTy = ast.getComplexType(T: ast.FloatTy);
946 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: FloatComplexTy))
947 return GetType(qt: FloatComplexTy);
948
949 CanQualType DoubleComplexTy = ast.getComplexType(T: ast.DoubleTy);
950 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: DoubleComplexTy))
951 return GetType(qt: DoubleComplexTy);
952
953 CanQualType LongDoubleComplexTy = ast.getComplexType(T: ast.LongDoubleTy);
954 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: LongDoubleComplexTy))
955 return GetType(qt: LongDoubleComplexTy);
956
957 CompilerType complex_float_clang_type =
958 GetBuiltinTypeForDWARFEncodingAndBitSize(type_name: "float", dw_ate: DW_ATE_float,
959 bit_size: bit_size / 2);
960 return GetType(
961 qt: ast.getComplexType(T: ClangUtil::GetQualType(ct: complex_float_clang_type)));
962 }
963
964 case DW_ATE_float:
965 if (type_name == "float" &&
966 QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.FloatTy))
967 return GetType(qt: ast.FloatTy);
968 if (type_name == "double" &&
969 QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.DoubleTy))
970 return GetType(qt: ast.DoubleTy);
971 if (type_name == "long double" &&
972 QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.LongDoubleTy))
973 return GetType(qt: ast.LongDoubleTy);
974 // Fall back to not requiring a name match
975 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.FloatTy))
976 return GetType(qt: ast.FloatTy);
977 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.DoubleTy))
978 return GetType(qt: ast.DoubleTy);
979 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.LongDoubleTy))
980 return GetType(qt: ast.LongDoubleTy);
981 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.HalfTy))
982 return GetType(qt: ast.HalfTy);
983 break;
984
985 case DW_ATE_signed:
986 if (!type_name.empty()) {
987 if (type_name == "wchar_t" &&
988 QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.WCharTy) &&
989 (getTargetInfo() &&
990 TargetInfo::isTypeSigned(T: getTargetInfo()->getWCharType())))
991 return GetType(qt: ast.WCharTy);
992 if (type_name == "void" &&
993 QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.VoidTy))
994 return GetType(qt: ast.VoidTy);
995 if (type_name.contains(Other: "long long") &&
996 QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.LongLongTy))
997 return GetType(qt: ast.LongLongTy);
998 if (type_name.contains(Other: "long") &&
999 QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.LongTy))
1000 return GetType(qt: ast.LongTy);
1001 if (type_name.contains(Other: "short") &&
1002 QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.ShortTy))
1003 return GetType(qt: ast.ShortTy);
1004 if (type_name.contains(Other: "char")) {
1005 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.CharTy))
1006 return GetType(qt: ast.CharTy);
1007 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.SignedCharTy))
1008 return GetType(qt: ast.SignedCharTy);
1009 }
1010 if (type_name.contains(Other: "int")) {
1011 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.IntTy))
1012 return GetType(qt: ast.IntTy);
1013 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.Int128Ty))
1014 return GetType(qt: ast.Int128Ty);
1015 }
1016 }
1017 // We weren't able to match up a type name, just search by size
1018 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.CharTy))
1019 return GetType(qt: ast.CharTy);
1020 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.ShortTy))
1021 return GetType(qt: ast.ShortTy);
1022 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.IntTy))
1023 return GetType(qt: ast.IntTy);
1024 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.LongTy))
1025 return GetType(qt: ast.LongTy);
1026 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.LongLongTy))
1027 return GetType(qt: ast.LongLongTy);
1028 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.Int128Ty))
1029 return GetType(qt: ast.Int128Ty);
1030 break;
1031
1032 case DW_ATE_signed_char:
1033 if (type_name == "char") {
1034 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.CharTy))
1035 return GetType(qt: ast.CharTy);
1036 }
1037 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.SignedCharTy))
1038 return GetType(qt: ast.SignedCharTy);
1039 break;
1040
1041 case DW_ATE_unsigned:
1042 if (!type_name.empty()) {
1043 if (type_name == "wchar_t") {
1044 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.WCharTy)) {
1045 if (!(getTargetInfo() &&
1046 TargetInfo::isTypeSigned(T: getTargetInfo()->getWCharType())))
1047 return GetType(qt: ast.WCharTy);
1048 }
1049 }
1050 if (type_name.contains(Other: "long long")) {
1051 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedLongLongTy))
1052 return GetType(qt: ast.UnsignedLongLongTy);
1053 } else if (type_name.contains(Other: "long")) {
1054 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedLongTy))
1055 return GetType(qt: ast.UnsignedLongTy);
1056 } else if (type_name.contains(Other: "short")) {
1057 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedShortTy))
1058 return GetType(qt: ast.UnsignedShortTy);
1059 } else if (type_name.contains(Other: "char")) {
1060 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedCharTy))
1061 return GetType(qt: ast.UnsignedCharTy);
1062 } else if (type_name.contains(Other: "int")) {
1063 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedIntTy))
1064 return GetType(qt: ast.UnsignedIntTy);
1065 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedInt128Ty))
1066 return GetType(qt: ast.UnsignedInt128Ty);
1067 }
1068 }
1069 // We weren't able to match up a type name, just search by size
1070 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedCharTy))
1071 return GetType(qt: ast.UnsignedCharTy);
1072 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedShortTy))
1073 return GetType(qt: ast.UnsignedShortTy);
1074 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedIntTy))
1075 return GetType(qt: ast.UnsignedIntTy);
1076 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedLongTy))
1077 return GetType(qt: ast.UnsignedLongTy);
1078 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedLongLongTy))
1079 return GetType(qt: ast.UnsignedLongLongTy);
1080 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedInt128Ty))
1081 return GetType(qt: ast.UnsignedInt128Ty);
1082 break;
1083
1084 case DW_ATE_unsigned_char:
1085 if (type_name == "char") {
1086 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.CharTy))
1087 return GetType(qt: ast.CharTy);
1088 }
1089 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedCharTy))
1090 return GetType(qt: ast.UnsignedCharTy);
1091 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: ast.UnsignedShortTy))
1092 return GetType(qt: ast.UnsignedShortTy);
1093 break;
1094
1095 case DW_ATE_imaginary_float:
1096 break;
1097
1098 case DW_ATE_UTF:
1099 switch (bit_size) {
1100 case 8:
1101 return GetType(qt: ast.Char8Ty);
1102 case 16:
1103 return GetType(qt: ast.Char16Ty);
1104 case 32:
1105 return GetType(qt: ast.Char32Ty);
1106 default:
1107 if (!type_name.empty()) {
1108 if (type_name == "char16_t")
1109 return GetType(qt: ast.Char16Ty);
1110 if (type_name == "char32_t")
1111 return GetType(qt: ast.Char32Ty);
1112 if (type_name == "char8_t")
1113 return GetType(qt: ast.Char8Ty);
1114 }
1115 }
1116 break;
1117 }
1118
1119 Log *log = GetLog(mask: LLDBLog::Types);
1120 LLDB_LOG(log,
1121 "error: need to add support for DW_TAG_base_type '{0}' "
1122 "encoded with DW_ATE = {1:x}, bit_size = {2}",
1123 type_name, dw_ate, bit_size);
1124 return CompilerType();
1125}
1126
1127CompilerType TypeSystemClang::GetCStringType(bool is_const) {
1128 ASTContext &ast = getASTContext();
1129 QualType char_type(ast.CharTy);
1130
1131 if (is_const)
1132 char_type.addConst();
1133
1134 return GetType(qt: ast.getPointerType(T: char_type));
1135}
1136
1137bool TypeSystemClang::AreTypesSame(CompilerType type1, CompilerType type2,
1138 bool ignore_qualifiers) {
1139 auto ast = type1.GetTypeSystem<TypeSystemClang>();
1140 if (!ast || type1.GetTypeSystem() != type2.GetTypeSystem())
1141 return false;
1142
1143 if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
1144 return true;
1145
1146 QualType type1_qual = ClangUtil::GetQualType(ct: type1);
1147 QualType type2_qual = ClangUtil::GetQualType(ct: type2);
1148
1149 if (ignore_qualifiers) {
1150 type1_qual = type1_qual.getUnqualifiedType();
1151 type2_qual = type2_qual.getUnqualifiedType();
1152 }
1153
1154 return ast->getASTContext().hasSameType(T1: type1_qual, T2: type2_qual);
1155}
1156
1157CompilerType TypeSystemClang::GetTypeForDecl(void *opaque_decl) {
1158 if (!opaque_decl)
1159 return CompilerType();
1160
1161 clang::Decl *decl = static_cast<clang::Decl *>(opaque_decl);
1162 if (auto *named_decl = llvm::dyn_cast<clang::NamedDecl>(Val: decl))
1163 return GetTypeForDecl(decl: named_decl);
1164 return CompilerType();
1165}
1166
1167CompilerDeclContext TypeSystemClang::CreateDeclContext(DeclContext *ctx) {
1168 // Check that the DeclContext actually belongs to this ASTContext.
1169 assert(&ctx->getParentASTContext() == &getASTContext());
1170 return CompilerDeclContext(this, ctx);
1171}
1172
1173CompilerType TypeSystemClang::GetTypeForDecl(clang::NamedDecl *decl) {
1174 if (clang::ObjCInterfaceDecl *interface_decl =
1175 llvm::dyn_cast<clang::ObjCInterfaceDecl>(Val: decl))
1176 return GetTypeForDecl(objc_decl: interface_decl);
1177 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(Val: decl))
1178 return GetTypeForDecl(decl: tag_decl);
1179 if (clang::ValueDecl *value_decl = llvm::dyn_cast<clang::ValueDecl>(Val: decl))
1180 return GetTypeForDecl(value_decl);
1181 return CompilerType();
1182}
1183
1184CompilerType TypeSystemClang::GetTypeForDecl(TagDecl *decl) {
1185 return GetType(qt: getASTContext().getTagDeclType(Decl: decl));
1186}
1187
1188CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) {
1189 return GetType(qt: getASTContext().getObjCInterfaceType(Decl: decl));
1190}
1191
1192CompilerType TypeSystemClang::GetTypeForDecl(clang::ValueDecl *value_decl) {
1193 return GetType(qt: value_decl->getType());
1194}
1195
1196#pragma mark Structure, Unions, Classes
1197
1198void TypeSystemClang::SetOwningModule(clang::Decl *decl,
1199 OptionalClangModuleID owning_module) {
1200 if (!decl || !owning_module.HasValue())
1201 return;
1202
1203 decl->setFromASTFile();
1204 decl->setOwningModuleID(owning_module.GetValue());
1205 decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
1206}
1207
1208OptionalClangModuleID
1209TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name,
1210 OptionalClangModuleID parent,
1211 bool is_framework, bool is_explicit) {
1212 // Get the external AST source which holds the modules.
1213 auto *ast_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
1214 Val: getASTContext().getExternalSource());
1215 assert(ast_source && "external ast source was lost");
1216 if (!ast_source)
1217 return {};
1218
1219 // Lazily initialize the module map.
1220 if (!m_header_search_up) {
1221 m_header_search_opts_up = std::make_unique<clang::HeaderSearchOptions>();
1222 m_header_search_up = std::make_unique<clang::HeaderSearch>(
1223 args&: *m_header_search_opts_up, args&: *m_source_manager_up,
1224 args&: *m_diagnostics_engine_up, args&: *m_language_options_up,
1225 args: m_target_info_up.get());
1226 m_module_map_up = std::make_unique<clang::ModuleMap>(
1227 args&: *m_source_manager_up, args&: *m_diagnostics_engine_up, args&: *m_language_options_up,
1228 args: m_target_info_up.get(), args&: *m_header_search_up);
1229 }
1230
1231 // Get or create the module context.
1232 bool created;
1233 clang::Module *module;
1234 auto parent_desc = ast_source->getSourceDescriptor(ID: parent.GetValue());
1235 std::tie(args&: module, args&: created) = m_module_map_up->findOrCreateModule(
1236 Name: name, Parent: parent_desc ? parent_desc->getModuleOrNull() : nullptr,
1237 IsFramework: is_framework, IsExplicit: is_explicit);
1238 if (!created)
1239 return ast_source->GetIDForModule(module);
1240
1241 return ast_source->RegisterModule(module);
1242}
1243
1244CompilerType TypeSystemClang::CreateRecordType(
1245 clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
1246 AccessType access_type, llvm::StringRef name, int kind,
1247 LanguageType language, std::optional<ClangASTMetadata> metadata,
1248 bool exports_symbols) {
1249 ASTContext &ast = getASTContext();
1250
1251 if (decl_ctx == nullptr)
1252 decl_ctx = ast.getTranslationUnitDecl();
1253
1254 if (language == eLanguageTypeObjC ||
1255 language == eLanguageTypeObjC_plus_plus) {
1256 bool isInternal = false;
1257 return CreateObjCClass(name, decl_ctx, owning_module, isInternal, metadata);
1258 }
1259
1260 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1261 // we will need to update this code. I was told to currently always use the
1262 // CXXRecordDecl class since we often don't know from debug information if
1263 // something is struct or a class, so we default to always use the more
1264 // complete definition just in case.
1265
1266 bool has_name = !name.empty();
1267 CXXRecordDecl *decl = CXXRecordDecl::CreateDeserialized(C: ast, ID: GlobalDeclID());
1268 decl->setTagKind(static_cast<TagDecl::TagKind>(kind));
1269 decl->setDeclContext(decl_ctx);
1270 if (has_name)
1271 decl->setDeclName(&ast.Idents.get(Name: name));
1272 SetOwningModule(decl, owning_module);
1273
1274 if (!has_name) {
1275 // In C++ a lambda is also represented as an unnamed class. This is
1276 // different from an *anonymous class* that the user wrote:
1277 //
1278 // struct A {
1279 // // anonymous class (GNU/MSVC extension)
1280 // struct {
1281 // int x;
1282 // };
1283 // // unnamed class within a class
1284 // struct {
1285 // int y;
1286 // } B;
1287 // };
1288 //
1289 // void f() {
1290 // // unammed class outside of a class
1291 // struct {
1292 // int z;
1293 // } C;
1294 // }
1295 //
1296 // Anonymous classes is a GNU/MSVC extension that clang supports. It
1297 // requires the anonymous class be embedded within a class. So the new
1298 // heuristic verifies this condition.
1299 if (isa<CXXRecordDecl>(Val: decl_ctx) && exports_symbols)
1300 decl->setAnonymousStructOrUnion(true);
1301 }
1302
1303 if (metadata)
1304 SetMetadata(object: decl, meta_data: *metadata);
1305
1306 if (access_type != eAccessNone)
1307 decl->setAccess(ConvertAccessTypeToAccessSpecifier(access: access_type));
1308
1309 if (decl_ctx)
1310 decl_ctx->addDecl(D: decl);
1311
1312 return GetType(qt: ast.getTagDeclType(Decl: decl));
1313}
1314
1315namespace {
1316/// Returns the type of the template argument iff the given TemplateArgument
1317/// should be represented as an NonTypeTemplateParmDecl in the AST. Returns
1318/// a null QualType otherwise.
1319QualType GetValueParamType(const clang::TemplateArgument &argument) {
1320 switch (argument.getKind()) {
1321 case TemplateArgument::Integral:
1322 return argument.getIntegralType();
1323 case TemplateArgument::StructuralValue:
1324 return argument.getStructuralValueType();
1325 default:
1326 return {};
1327 }
1328}
1329
1330void AddAccessSpecifierDecl(clang::CXXRecordDecl *cxx_record_decl,
1331 ASTContext &ct,
1332 clang::AccessSpecifier previous_access,
1333 clang::AccessSpecifier access_specifier) {
1334 if (!cxx_record_decl->isClass() && !cxx_record_decl->isStruct())
1335 return;
1336 if (previous_access != access_specifier) {
1337 // For struct, don't add AS_public if it's the first AccessSpecDecl.
1338 // For class, don't add AS_private if it's the first AccessSpecDecl.
1339 if ((cxx_record_decl->isStruct() &&
1340 previous_access == clang::AccessSpecifier::AS_none &&
1341 access_specifier == clang::AccessSpecifier::AS_public) ||
1342 (cxx_record_decl->isClass() &&
1343 previous_access == clang::AccessSpecifier::AS_none &&
1344 access_specifier == clang::AccessSpecifier::AS_private)) {
1345 return;
1346 }
1347 cxx_record_decl->addDecl(
1348 D: AccessSpecDecl::Create(C&: ct, AS: access_specifier, DC: cxx_record_decl,
1349 ASLoc: SourceLocation(), ColonLoc: SourceLocation()));
1350 }
1351}
1352} // namespace
1353
1354static TemplateParameterList *CreateTemplateParameterList(
1355 ASTContext &ast,
1356 const TypeSystemClang::TemplateParameterInfos &template_param_infos,
1357 llvm::SmallVector<NamedDecl *, 8> &template_param_decls) {
1358 const bool parameter_pack = false;
1359 const bool is_typename = false;
1360 const unsigned depth = 0;
1361 const size_t num_template_params = template_param_infos.Size();
1362 DeclContext *const decl_context =
1363 ast.getTranslationUnitDecl(); // Is this the right decl context?,
1364
1365 auto const &args = template_param_infos.GetArgs();
1366 auto const &names = template_param_infos.GetNames();
1367 for (size_t i = 0; i < num_template_params; ++i) {
1368 const char *name = names[i];
1369
1370 IdentifierInfo *identifier_info = nullptr;
1371 if (name && name[0])
1372 identifier_info = &ast.Idents.get(Name: name);
1373 TemplateArgument const &targ = args[i];
1374 QualType template_param_type = GetValueParamType(argument: targ);
1375 if (!template_param_type.isNull()) {
1376 template_param_decls.push_back(Elt: NonTypeTemplateParmDecl::Create(
1377 C: ast, DC: decl_context, StartLoc: SourceLocation(), IdLoc: SourceLocation(), D: depth, P: i,
1378 Id: identifier_info, T: template_param_type, ParameterPack: parameter_pack,
1379 TInfo: ast.getTrivialTypeSourceInfo(T: template_param_type)));
1380 } else {
1381 template_param_decls.push_back(Elt: TemplateTypeParmDecl::Create(
1382 C: ast, DC: decl_context, KeyLoc: SourceLocation(), NameLoc: SourceLocation(), D: depth, P: i,
1383 Id: identifier_info, Typename: is_typename, ParameterPack: parameter_pack));
1384 }
1385 }
1386
1387 if (template_param_infos.hasParameterPack()) {
1388 IdentifierInfo *identifier_info = nullptr;
1389 if (template_param_infos.HasPackName())
1390 identifier_info = &ast.Idents.get(Name: template_param_infos.GetPackName());
1391 const bool parameter_pack_true = true;
1392
1393 QualType template_param_type =
1394 !template_param_infos.GetParameterPack().IsEmpty()
1395 ? GetValueParamType(argument: template_param_infos.GetParameterPack().Front())
1396 : QualType();
1397 if (!template_param_type.isNull()) {
1398 template_param_decls.push_back(Elt: NonTypeTemplateParmDecl::Create(
1399 C: ast, DC: decl_context, StartLoc: SourceLocation(), IdLoc: SourceLocation(), D: depth,
1400 P: num_template_params, Id: identifier_info, T: template_param_type,
1401 ParameterPack: parameter_pack_true,
1402 TInfo: ast.getTrivialTypeSourceInfo(T: template_param_type)));
1403 } else {
1404 template_param_decls.push_back(Elt: TemplateTypeParmDecl::Create(
1405 C: ast, DC: decl_context, KeyLoc: SourceLocation(), NameLoc: SourceLocation(), D: depth,
1406 P: num_template_params, Id: identifier_info, Typename: is_typename,
1407 ParameterPack: parameter_pack_true));
1408 }
1409 }
1410 clang::Expr *const requires_clause = nullptr; // TODO: Concepts
1411 TemplateParameterList *template_param_list = TemplateParameterList::Create(
1412 C: ast, TemplateLoc: SourceLocation(), LAngleLoc: SourceLocation(), Params: template_param_decls,
1413 RAngleLoc: SourceLocation(), RequiresClause: requires_clause);
1414 return template_param_list;
1415}
1416
1417clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
1418 clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
1419 clang::FunctionDecl *func_decl,
1420 const TemplateParameterInfos &template_param_infos) {
1421 // /// Create a function template node.
1422 ASTContext &ast = getASTContext();
1423
1424 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
1425 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1426 ast, template_param_infos, template_param_decls);
1427 FunctionTemplateDecl *func_tmpl_decl =
1428 FunctionTemplateDecl::CreateDeserialized(C&: ast, ID: GlobalDeclID());
1429 func_tmpl_decl->setDeclContext(decl_ctx);
1430 func_tmpl_decl->setLocation(func_decl->getLocation());
1431 func_tmpl_decl->setDeclName(func_decl->getDeclName());
1432 func_tmpl_decl->setTemplateParameters(template_param_list);
1433 func_tmpl_decl->init(NewTemplatedDecl: func_decl);
1434 SetOwningModule(decl: func_tmpl_decl, owning_module);
1435
1436 for (size_t i = 0, template_param_decl_count = template_param_decls.size();
1437 i < template_param_decl_count; ++i) {
1438 // TODO: verify which decl context we should put template_param_decls into..
1439 template_param_decls[i]->setDeclContext(func_decl);
1440 }
1441 // Function templates inside a record need to have an access specifier.
1442 // It doesn't matter what access specifier we give the template as LLDB
1443 // anyway allows accessing everything inside a record.
1444 if (decl_ctx->isRecord())
1445 func_tmpl_decl->setAccess(clang::AccessSpecifier::AS_public);
1446
1447 return func_tmpl_decl;
1448}
1449
1450void TypeSystemClang::CreateFunctionTemplateSpecializationInfo(
1451 FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl,
1452 const TemplateParameterInfos &infos) {
1453 TemplateArgumentList *template_args_ptr = TemplateArgumentList::CreateCopy(
1454 Context&: func_decl->getASTContext(), Args: infos.GetArgs());
1455
1456 func_decl->setFunctionTemplateSpecialization(Template: func_tmpl_decl,
1457 TemplateArgs: template_args_ptr, InsertPos: nullptr);
1458}
1459
1460/// Returns true if the given template parameter can represent the given value.
1461/// For example, `typename T` can represent `int` but not integral values such
1462/// as `int I = 3`.
1463static bool TemplateParameterAllowsValue(NamedDecl *param,
1464 const TemplateArgument &value) {
1465 if (llvm::isa<TemplateTypeParmDecl>(Val: param)) {
1466 // Compare the argument kind, i.e. ensure that <typename> != <int>.
1467 if (value.getKind() != TemplateArgument::Type)
1468 return false;
1469 } else if (auto *type_param =
1470 llvm::dyn_cast<NonTypeTemplateParmDecl>(Val: param)) {
1471 // Compare the argument kind, i.e. ensure that <typename> != <int>.
1472 QualType value_param_type = GetValueParamType(argument: value);
1473 if (value_param_type.isNull())
1474 return false;
1475
1476 // Compare the integral type, i.e. ensure that <int> != <char>.
1477 if (type_param->getType() != value_param_type)
1478 return false;
1479 } else {
1480 // There is no way to create other parameter decls at the moment, so we
1481 // can't reach this case during normal LLDB usage. Log that this happened
1482 // and assert.
1483 Log *log = GetLog(mask: LLDBLog::Expressions);
1484 LLDB_LOG(log,
1485 "Don't know how to compare template parameter to passed"
1486 " value. Decl kind of parameter is: {0}",
1487 param->getDeclKindName());
1488 lldbassert(false && "Can't compare this TemplateParmDecl subclass");
1489 // In release builds just fall back to marking the parameter as not
1490 // accepting the value so that we don't try to fit an instantiation to a
1491 // template that doesn't fit. E.g., avoid that `S<1>` is being connected to
1492 // `template<typename T> struct S;`.
1493 return false;
1494 }
1495 return true;
1496}
1497
1498/// Returns true if the given class template declaration could produce an
1499/// instantiation with the specified values.
1500/// For example, `<typename T>` allows the arguments `float`, but not for
1501/// example `bool, float` or `3` (as an integer parameter value).
1502static bool ClassTemplateAllowsToInstantiationArgs(
1503 ClassTemplateDecl *class_template_decl,
1504 const TypeSystemClang::TemplateParameterInfos &instantiation_values) {
1505
1506 TemplateParameterList &params = *class_template_decl->getTemplateParameters();
1507
1508 // Save some work by iterating only once over the found parameters and
1509 // calculate the information related to parameter packs.
1510
1511 // Contains the first pack parameter (or non if there are none).
1512 std::optional<NamedDecl *> pack_parameter;
1513 // Contains the number of non-pack parameters.
1514 size_t non_pack_params = params.size();
1515 for (size_t i = 0; i < params.size(); ++i) {
1516 NamedDecl *param = params.getParam(Idx: i);
1517 if (param->isParameterPack()) {
1518 pack_parameter = param;
1519 non_pack_params = i;
1520 break;
1521 }
1522 }
1523
1524 // The found template needs to have compatible non-pack template arguments.
1525 // E.g., ensure that <typename, typename> != <typename>.
1526 // The pack parameters are compared later.
1527 if (non_pack_params != instantiation_values.Size())
1528 return false;
1529
1530 // Ensure that <typename...> != <typename>.
1531 if (pack_parameter.has_value() != instantiation_values.hasParameterPack())
1532 return false;
1533
1534 // Compare the first pack parameter that was found with the first pack
1535 // parameter value. The special case of having an empty parameter pack value
1536 // always fits to a pack parameter.
1537 // E.g., ensure that <int...> != <typename...>.
1538 if (pack_parameter && !instantiation_values.GetParameterPack().IsEmpty() &&
1539 !TemplateParameterAllowsValue(
1540 param: *pack_parameter, value: instantiation_values.GetParameterPack().Front()))
1541 return false;
1542
1543 // Compare all the non-pack parameters now.
1544 // E.g., ensure that <int> != <long>.
1545 for (const auto pair :
1546 llvm::zip_first(t: instantiation_values.GetArgs(), u&: params)) {
1547 const TemplateArgument &passed_arg = std::get<0>(t: pair);
1548 NamedDecl *found_param = std::get<1>(t: pair);
1549 if (!TemplateParameterAllowsValue(param: found_param, value: passed_arg))
1550 return false;
1551 }
1552
1553 return class_template_decl;
1554}
1555
1556ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
1557 DeclContext *decl_ctx, OptionalClangModuleID owning_module,
1558 lldb::AccessType access_type, llvm::StringRef class_name, int kind,
1559 const TemplateParameterInfos &template_param_infos) {
1560 ASTContext &ast = getASTContext();
1561
1562 ClassTemplateDecl *class_template_decl = nullptr;
1563 if (decl_ctx == nullptr)
1564 decl_ctx = ast.getTranslationUnitDecl();
1565
1566 IdentifierInfo &identifier_info = ast.Idents.get(Name: class_name);
1567 DeclarationName decl_name(&identifier_info);
1568
1569 // Search the AST for an existing ClassTemplateDecl that could be reused.
1570 clang::DeclContext::lookup_result result = decl_ctx->lookup(Name: decl_name);
1571 for (NamedDecl *decl : result) {
1572 class_template_decl = dyn_cast<clang::ClassTemplateDecl>(Val: decl);
1573 if (!class_template_decl)
1574 continue;
1575 // The class template has to be able to represents the instantiation
1576 // values we received. Without this we might end up putting an instantiation
1577 // with arguments such as <int, int> to a template such as:
1578 // template<typename T> struct S;
1579 // Connecting the instantiation to an incompatible template could cause
1580 // problems later on.
1581 if (!ClassTemplateAllowsToInstantiationArgs(class_template_decl,
1582 instantiation_values: template_param_infos))
1583 continue;
1584 return class_template_decl;
1585 }
1586
1587 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
1588
1589 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1590 ast, template_param_infos, template_param_decls);
1591
1592 CXXRecordDecl *template_cxx_decl =
1593 CXXRecordDecl::CreateDeserialized(C: ast, ID: GlobalDeclID());
1594 template_cxx_decl->setTagKind(static_cast<TagDecl::TagKind>(kind));
1595 // What decl context do we use here? TU? The actual decl context?
1596 template_cxx_decl->setDeclContext(decl_ctx);
1597 template_cxx_decl->setDeclName(decl_name);
1598 SetOwningModule(decl: template_cxx_decl, owning_module);
1599
1600 for (size_t i = 0, template_param_decl_count = template_param_decls.size();
1601 i < template_param_decl_count; ++i) {
1602 template_param_decls[i]->setDeclContext(template_cxx_decl);
1603 }
1604
1605 // With templated classes, we say that a class is templated with
1606 // specializations, but that the bare class has no functions.
1607 // template_cxx_decl->startDefinition();
1608 // template_cxx_decl->completeDefinition();
1609
1610 class_template_decl =
1611 ClassTemplateDecl::CreateDeserialized(C&: ast, ID: GlobalDeclID());
1612 // What decl context do we use here? TU? The actual decl context?
1613 class_template_decl->setDeclContext(decl_ctx);
1614 class_template_decl->setDeclName(decl_name);
1615 class_template_decl->setTemplateParameters(template_param_list);
1616 class_template_decl->init(NewTemplatedDecl: template_cxx_decl);
1617 template_cxx_decl->setDescribedClassTemplate(class_template_decl);
1618 SetOwningModule(decl: class_template_decl, owning_module);
1619
1620 if (access_type != eAccessNone)
1621 class_template_decl->setAccess(
1622 ConvertAccessTypeToAccessSpecifier(access: access_type));
1623
1624 decl_ctx->addDecl(D: class_template_decl);
1625
1626 VerifyDecl(decl: class_template_decl);
1627
1628 return class_template_decl;
1629}
1630
1631TemplateTemplateParmDecl *
1632TypeSystemClang::CreateTemplateTemplateParmDecl(const char *template_name) {
1633 ASTContext &ast = getASTContext();
1634
1635 auto *decl_ctx = ast.getTranslationUnitDecl();
1636
1637 IdentifierInfo &identifier_info = ast.Idents.get(Name: template_name);
1638 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
1639
1640 TypeSystemClang::TemplateParameterInfos template_param_infos;
1641 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1642 ast, template_param_infos, template_param_decls);
1643
1644 // LLDB needs to create those decls only to be able to display a
1645 // type that includes a template template argument. Only the name matters for
1646 // this purpose, so we use dummy values for the other characteristics of the
1647 // type.
1648 return TemplateTemplateParmDecl::Create(C: ast, DC: decl_ctx, L: SourceLocation(),
1649 /*Depth=*/D: 0, /*Position=*/P: 0,
1650 /*IsParameterPack=*/ParameterPack: false,
1651 Id: &identifier_info, /*Typename=*/false,
1652 Params: template_param_list);
1653}
1654
1655ClassTemplateSpecializationDecl *
1656TypeSystemClang::CreateClassTemplateSpecializationDecl(
1657 DeclContext *decl_ctx, OptionalClangModuleID owning_module,
1658 ClassTemplateDecl *class_template_decl, int kind,
1659 const TemplateParameterInfos &template_param_infos) {
1660 ASTContext &ast = getASTContext();
1661 llvm::SmallVector<clang::TemplateArgument, 2> args(
1662 template_param_infos.Size() +
1663 (template_param_infos.hasParameterPack() ? 1 : 0));
1664
1665 auto const &orig_args = template_param_infos.GetArgs();
1666 std::copy(first: orig_args.begin(), last: orig_args.end(), result: args.begin());
1667 if (template_param_infos.hasParameterPack()) {
1668 args[args.size() - 1] = TemplateArgument::CreatePackCopy(
1669 Context&: ast, Args: template_param_infos.GetParameterPackArgs());
1670 }
1671 ClassTemplateSpecializationDecl *class_template_specialization_decl =
1672 ClassTemplateSpecializationDecl::CreateDeserialized(C&: ast, ID: GlobalDeclID());
1673 class_template_specialization_decl->setTagKind(
1674 static_cast<TagDecl::TagKind>(kind));
1675 class_template_specialization_decl->setDeclContext(decl_ctx);
1676 class_template_specialization_decl->setInstantiationOf(class_template_decl);
1677 class_template_specialization_decl->setTemplateArgs(
1678 TemplateArgumentList::CreateCopy(Context&: ast, Args: args));
1679 ast.getTypeDeclType(Decl: class_template_specialization_decl, PrevDecl: nullptr);
1680 class_template_specialization_decl->setDeclName(
1681 class_template_decl->getDeclName());
1682
1683 // FIXME: set to fixed value for now so it's not uninitialized.
1684 // One way to determine StrictPackMatch would be
1685 // Sema::CheckTemplateTemplateArgument.
1686 class_template_specialization_decl->setStrictPackMatch(false);
1687
1688 SetOwningModule(decl: class_template_specialization_decl, owning_module);
1689 decl_ctx->addDecl(D: class_template_specialization_decl);
1690
1691 class_template_specialization_decl->setSpecializationKind(
1692 TSK_ExplicitSpecialization);
1693
1694 return class_template_specialization_decl;
1695}
1696
1697CompilerType TypeSystemClang::CreateClassTemplateSpecializationType(
1698 ClassTemplateSpecializationDecl *class_template_specialization_decl) {
1699 if (class_template_specialization_decl) {
1700 ASTContext &ast = getASTContext();
1701 return GetType(qt: ast.getTagDeclType(Decl: class_template_specialization_decl));
1702 }
1703 return CompilerType();
1704}
1705
1706static inline bool check_op_param(bool is_method,
1707 clang::OverloadedOperatorKind op_kind,
1708 bool unary, bool binary,
1709 uint32_t num_params) {
1710 // Special-case call since it can take any number of operands
1711 if (op_kind == OO_Call)
1712 return true;
1713
1714 // The parameter count doesn't include "this"
1715 if (is_method)
1716 ++num_params;
1717 if (num_params == 1)
1718 return unary;
1719 if (num_params == 2)
1720 return binary;
1721 else
1722 return false;
1723}
1724
1725bool TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
1726 bool is_method, clang::OverloadedOperatorKind op_kind,
1727 uint32_t num_params) {
1728 switch (op_kind) {
1729 default:
1730 break;
1731 // C++ standard allows any number of arguments to new/delete
1732 case OO_New:
1733 case OO_Array_New:
1734 case OO_Delete:
1735 case OO_Array_Delete:
1736 return true;
1737 }
1738
1739#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
1740 case OO_##Name: \
1741 return check_op_param(is_method, op_kind, Unary, Binary, num_params);
1742 switch (op_kind) {
1743#include "clang/Basic/OperatorKinds.def"
1744 default:
1745 break;
1746 }
1747 return false;
1748}
1749
1750clang::AccessSpecifier
1751TypeSystemClang::UnifyAccessSpecifiers(clang::AccessSpecifier lhs,
1752 clang::AccessSpecifier rhs) {
1753 // Make the access equal to the stricter of the field and the nested field's
1754 // access
1755 if (lhs == AS_none || rhs == AS_none)
1756 return AS_none;
1757 if (lhs == AS_private || rhs == AS_private)
1758 return AS_private;
1759 if (lhs == AS_protected || rhs == AS_protected)
1760 return AS_protected;
1761 return AS_public;
1762}
1763
1764bool TypeSystemClang::FieldIsBitfield(FieldDecl *field,
1765 uint32_t &bitfield_bit_size) {
1766 ASTContext &ast = getASTContext();
1767 if (field == nullptr)
1768 return false;
1769
1770 if (field->isBitField()) {
1771 Expr *bit_width_expr = field->getBitWidth();
1772 if (bit_width_expr) {
1773 if (std::optional<llvm::APSInt> bit_width_apsint =
1774 bit_width_expr->getIntegerConstantExpr(Ctx: ast)) {
1775 bitfield_bit_size = bit_width_apsint->getLimitedValue(UINT32_MAX);
1776 return true;
1777 }
1778 }
1779 }
1780 return false;
1781}
1782
1783bool TypeSystemClang::RecordHasFields(const RecordDecl *record_decl) {
1784 if (record_decl == nullptr)
1785 return false;
1786
1787 if (!record_decl->field_empty())
1788 return true;
1789
1790 // No fields, lets check this is a CXX record and check the base classes
1791 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(Val: record_decl);
1792 if (cxx_record_decl) {
1793 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1794 for (base_class = cxx_record_decl->bases_begin(),
1795 base_class_end = cxx_record_decl->bases_end();
1796 base_class != base_class_end; ++base_class) {
1797 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(
1798 Val: base_class->getType()->getAs<RecordType>()->getDecl());
1799 if (RecordHasFields(record_decl: base_class_decl))
1800 return true;
1801 }
1802 }
1803
1804 // We always want forcefully completed types to show up so we can print a
1805 // message in the summary that indicates that the type is incomplete.
1806 // This will help users know when they are running into issues with
1807 // -flimit-debug-info instead of just seeing nothing if this is a base class
1808 // (since we were hiding empty base classes), or nothing when you turn open
1809 // an valiable whose type was incomplete.
1810 if (std::optional<ClangASTMetadata> meta_data = GetMetadata(object: record_decl);
1811 meta_data && meta_data->IsForcefullyCompleted())
1812 return true;
1813
1814 return false;
1815}
1816
1817#pragma mark Objective-C Classes
1818
1819CompilerType TypeSystemClang::CreateObjCClass(
1820 llvm::StringRef name, clang::DeclContext *decl_ctx,
1821 OptionalClangModuleID owning_module, bool isInternal,
1822 std::optional<ClangASTMetadata> metadata) {
1823 ASTContext &ast = getASTContext();
1824 assert(!name.empty());
1825 if (!decl_ctx)
1826 decl_ctx = ast.getTranslationUnitDecl();
1827
1828 ObjCInterfaceDecl *decl =
1829 ObjCInterfaceDecl::CreateDeserialized(C: ast, ID: GlobalDeclID());
1830 decl->setDeclContext(decl_ctx);
1831 decl->setDeclName(&ast.Idents.get(Name: name));
1832 decl->setImplicit(isInternal);
1833 SetOwningModule(decl, owning_module);
1834
1835 if (metadata)
1836 SetMetadata(object: decl, meta_data: *metadata);
1837
1838 return GetType(qt: ast.getObjCInterfaceType(Decl: decl));
1839}
1840
1841bool TypeSystemClang::BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) {
1842 return !TypeSystemClang::RecordHasFields(record_decl: b->getType()->getAsCXXRecordDecl());
1843}
1844
1845uint32_t
1846TypeSystemClang::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl,
1847 bool omit_empty_base_classes) {
1848 uint32_t num_bases = 0;
1849 if (cxx_record_decl) {
1850 if (omit_empty_base_classes) {
1851 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1852 for (base_class = cxx_record_decl->bases_begin(),
1853 base_class_end = cxx_record_decl->bases_end();
1854 base_class != base_class_end; ++base_class) {
1855 // Skip empty base classes
1856 if (BaseSpecifierIsEmpty(b: base_class))
1857 continue;
1858 ++num_bases;
1859 }
1860 } else
1861 num_bases = cxx_record_decl->getNumBases();
1862 }
1863 return num_bases;
1864}
1865
1866#pragma mark Namespace Declarations
1867
1868NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration(
1869 const char *name, clang::DeclContext *decl_ctx,
1870 OptionalClangModuleID owning_module, bool is_inline) {
1871 NamespaceDecl *namespace_decl = nullptr;
1872 ASTContext &ast = getASTContext();
1873 TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl();
1874 if (!decl_ctx)
1875 decl_ctx = translation_unit_decl;
1876
1877 if (name) {
1878 IdentifierInfo &identifier_info = ast.Idents.get(Name: name);
1879 DeclarationName decl_name(&identifier_info);
1880 clang::DeclContext::lookup_result result = decl_ctx->lookup(Name: decl_name);
1881 for (NamedDecl *decl : result) {
1882 namespace_decl = dyn_cast<clang::NamespaceDecl>(Val: decl);
1883 if (namespace_decl)
1884 return namespace_decl;
1885 }
1886
1887 namespace_decl = NamespaceDecl::Create(C&: ast, DC: decl_ctx, Inline: is_inline,
1888 StartLoc: SourceLocation(), IdLoc: SourceLocation(),
1889 Id: &identifier_info, PrevDecl: nullptr, Nested: false);
1890
1891 decl_ctx->addDecl(D: namespace_decl);
1892 } else {
1893 if (decl_ctx == translation_unit_decl) {
1894 namespace_decl = translation_unit_decl->getAnonymousNamespace();
1895 if (namespace_decl)
1896 return namespace_decl;
1897
1898 namespace_decl =
1899 NamespaceDecl::Create(C&: ast, DC: decl_ctx, Inline: false, StartLoc: SourceLocation(),
1900 IdLoc: SourceLocation(), Id: nullptr, PrevDecl: nullptr, Nested: false);
1901 translation_unit_decl->setAnonymousNamespace(namespace_decl);
1902 translation_unit_decl->addDecl(D: namespace_decl);
1903 assert(namespace_decl == translation_unit_decl->getAnonymousNamespace());
1904 } else {
1905 NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(Val: decl_ctx);
1906 if (parent_namespace_decl) {
1907 namespace_decl = parent_namespace_decl->getAnonymousNamespace();
1908 if (namespace_decl)
1909 return namespace_decl;
1910 namespace_decl =
1911 NamespaceDecl::Create(C&: ast, DC: decl_ctx, Inline: false, StartLoc: SourceLocation(),
1912 IdLoc: SourceLocation(), Id: nullptr, PrevDecl: nullptr, Nested: false);
1913 parent_namespace_decl->setAnonymousNamespace(namespace_decl);
1914 parent_namespace_decl->addDecl(D: namespace_decl);
1915 assert(namespace_decl ==
1916 parent_namespace_decl->getAnonymousNamespace());
1917 } else {
1918 assert(false && "GetUniqueNamespaceDeclaration called with no name and "
1919 "no namespace as decl_ctx");
1920 }
1921 }
1922 }
1923 // Note: namespaces can span multiple modules, so perhaps this isn't a good
1924 // idea.
1925 SetOwningModule(decl: namespace_decl, owning_module);
1926
1927 VerifyDecl(decl: namespace_decl);
1928 return namespace_decl;
1929}
1930
1931clang::BlockDecl *
1932TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx,
1933 OptionalClangModuleID owning_module) {
1934 if (ctx) {
1935 clang::BlockDecl *decl =
1936 clang::BlockDecl::CreateDeserialized(C&: getASTContext(), ID: GlobalDeclID());
1937 decl->setDeclContext(ctx);
1938 ctx->addDecl(D: decl);
1939 SetOwningModule(decl, owning_module);
1940 return decl;
1941 }
1942 return nullptr;
1943}
1944
1945clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left,
1946 clang::DeclContext *right,
1947 clang::DeclContext *root) {
1948 if (root == nullptr)
1949 return nullptr;
1950
1951 std::set<clang::DeclContext *> path_left;
1952 for (clang::DeclContext *d = left; d != nullptr; d = d->getParent())
1953 path_left.insert(x: d);
1954
1955 for (clang::DeclContext *d = right; d != nullptr; d = d->getParent())
1956 if (path_left.find(x: d) != path_left.end())
1957 return d;
1958
1959 return nullptr;
1960}
1961
1962clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration(
1963 clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
1964 clang::NamespaceDecl *ns_decl) {
1965 if (decl_ctx && ns_decl) {
1966 auto *translation_unit = getASTContext().getTranslationUnitDecl();
1967 clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
1968 C&: getASTContext(), DC: decl_ctx, UsingLoc: clang::SourceLocation(),
1969 NamespaceLoc: clang::SourceLocation(), QualifierLoc: clang::NestedNameSpecifierLoc(),
1970 IdentLoc: clang::SourceLocation(), Nominated: ns_decl,
1971 CommonAncestor: FindLCABetweenDecls(left: decl_ctx, right: ns_decl,
1972 root: translation_unit));
1973 decl_ctx->addDecl(D: using_decl);
1974 SetOwningModule(decl: using_decl, owning_module);
1975 return using_decl;
1976 }
1977 return nullptr;
1978}
1979
1980clang::UsingDecl *
1981TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
1982 OptionalClangModuleID owning_module,
1983 clang::NamedDecl *target) {
1984 if (current_decl_ctx && target) {
1985 clang::UsingDecl *using_decl = clang::UsingDecl::Create(
1986 C&: getASTContext(), DC: current_decl_ctx, UsingL: clang::SourceLocation(),
1987 QualifierLoc: clang::NestedNameSpecifierLoc(), NameInfo: clang::DeclarationNameInfo(), HasTypenameKeyword: false);
1988 SetOwningModule(decl: using_decl, owning_module);
1989 clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
1990 C&: getASTContext(), DC: current_decl_ctx, Loc: clang::SourceLocation(),
1991 Name: target->getDeclName(), Introducer: using_decl, Target: target);
1992 SetOwningModule(decl: shadow_decl, owning_module);
1993 using_decl->addShadowDecl(S: shadow_decl);
1994 current_decl_ctx->addDecl(D: using_decl);
1995 return using_decl;
1996 }
1997 return nullptr;
1998}
1999
2000clang::VarDecl *TypeSystemClang::CreateVariableDeclaration(
2001 clang::DeclContext *decl_context, OptionalClangModuleID owning_module,
2002 const char *name, clang::QualType type) {
2003 if (decl_context) {
2004 clang::VarDecl *var_decl =
2005 clang::VarDecl::CreateDeserialized(C&: getASTContext(), ID: GlobalDeclID());
2006 var_decl->setDeclContext(decl_context);
2007 if (name && name[0])
2008 var_decl->setDeclName(&getASTContext().Idents.getOwn(Name: name));
2009 var_decl->setType(type);
2010 SetOwningModule(decl: var_decl, owning_module);
2011 var_decl->setAccess(clang::AS_public);
2012 decl_context->addDecl(D: var_decl);
2013 return var_decl;
2014 }
2015 return nullptr;
2016}
2017
2018lldb::opaque_compiler_type_t
2019TypeSystemClang::GetOpaqueCompilerType(clang::ASTContext *ast,
2020 lldb::BasicType basic_type) {
2021 switch (basic_type) {
2022 case eBasicTypeVoid:
2023 return ast->VoidTy.getAsOpaquePtr();
2024 case eBasicTypeChar:
2025 return ast->CharTy.getAsOpaquePtr();
2026 case eBasicTypeSignedChar:
2027 return ast->SignedCharTy.getAsOpaquePtr();
2028 case eBasicTypeUnsignedChar:
2029 return ast->UnsignedCharTy.getAsOpaquePtr();
2030 case eBasicTypeWChar:
2031 return ast->getWCharType().getAsOpaquePtr();
2032 case eBasicTypeSignedWChar:
2033 return ast->getSignedWCharType().getAsOpaquePtr();
2034 case eBasicTypeUnsignedWChar:
2035 return ast->getUnsignedWCharType().getAsOpaquePtr();
2036 case eBasicTypeChar8:
2037 return ast->Char8Ty.getAsOpaquePtr();
2038 case eBasicTypeChar16:
2039 return ast->Char16Ty.getAsOpaquePtr();
2040 case eBasicTypeChar32:
2041 return ast->Char32Ty.getAsOpaquePtr();
2042 case eBasicTypeShort:
2043 return ast->ShortTy.getAsOpaquePtr();
2044 case eBasicTypeUnsignedShort:
2045 return ast->UnsignedShortTy.getAsOpaquePtr();
2046 case eBasicTypeInt:
2047 return ast->IntTy.getAsOpaquePtr();
2048 case eBasicTypeUnsignedInt:
2049 return ast->UnsignedIntTy.getAsOpaquePtr();
2050 case eBasicTypeLong:
2051 return ast->LongTy.getAsOpaquePtr();
2052 case eBasicTypeUnsignedLong:
2053 return ast->UnsignedLongTy.getAsOpaquePtr();
2054 case eBasicTypeLongLong:
2055 return ast->LongLongTy.getAsOpaquePtr();
2056 case eBasicTypeUnsignedLongLong:
2057 return ast->UnsignedLongLongTy.getAsOpaquePtr();
2058 case eBasicTypeInt128:
2059 return ast->Int128Ty.getAsOpaquePtr();
2060 case eBasicTypeUnsignedInt128:
2061 return ast->UnsignedInt128Ty.getAsOpaquePtr();
2062 case eBasicTypeBool:
2063 return ast->BoolTy.getAsOpaquePtr();
2064 case eBasicTypeHalf:
2065 return ast->HalfTy.getAsOpaquePtr();
2066 case eBasicTypeFloat:
2067 return ast->FloatTy.getAsOpaquePtr();
2068 case eBasicTypeDouble:
2069 return ast->DoubleTy.getAsOpaquePtr();
2070 case eBasicTypeLongDouble:
2071 return ast->LongDoubleTy.getAsOpaquePtr();
2072 case eBasicTypeFloatComplex:
2073 return ast->getComplexType(T: ast->FloatTy).getAsOpaquePtr();
2074 case eBasicTypeDoubleComplex:
2075 return ast->getComplexType(T: ast->DoubleTy).getAsOpaquePtr();
2076 case eBasicTypeLongDoubleComplex:
2077 return ast->getComplexType(T: ast->LongDoubleTy).getAsOpaquePtr();
2078 case eBasicTypeObjCID:
2079 return ast->getObjCIdType().getAsOpaquePtr();
2080 case eBasicTypeObjCClass:
2081 return ast->getObjCClassType().getAsOpaquePtr();
2082 case eBasicTypeObjCSel:
2083 return ast->getObjCSelType().getAsOpaquePtr();
2084 case eBasicTypeNullPtr:
2085 return ast->NullPtrTy.getAsOpaquePtr();
2086 default:
2087 return nullptr;
2088 }
2089}
2090
2091#pragma mark Function Types
2092
2093clang::DeclarationName
2094TypeSystemClang::GetDeclarationName(llvm::StringRef name,
2095 const CompilerType &function_clang_type) {
2096 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
2097 if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS)
2098 return DeclarationName(&getASTContext().Idents.get(
2099 Name: name)); // Not operator, but a regular function.
2100
2101 // Check the number of operator parameters. Sometimes we have seen bad DWARF
2102 // that doesn't correctly describe operators and if we try to create a method
2103 // and add it to the class, clang will assert and crash, so we need to make
2104 // sure things are acceptable.
2105 clang::QualType method_qual_type(ClangUtil::GetQualType(ct: function_clang_type));
2106 const clang::FunctionProtoType *function_type =
2107 llvm::dyn_cast<clang::FunctionProtoType>(Val: method_qual_type.getTypePtr());
2108 if (function_type == nullptr)
2109 return clang::DeclarationName();
2110
2111 const bool is_method = false;
2112 const unsigned int num_params = function_type->getNumParams();
2113 if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
2114 is_method, op_kind, num_params))
2115 return clang::DeclarationName();
2116
2117 return getASTContext().DeclarationNames.getCXXOperatorName(Op: op_kind);
2118}
2119
2120PrintingPolicy TypeSystemClang::GetTypePrintingPolicy() {
2121 clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy());
2122 printing_policy.SuppressTagKeyword = true;
2123 // Inline namespaces are important for some type formatters (e.g., libc++
2124 // and libstdc++ are differentiated by their inline namespaces).
2125 printing_policy.SuppressInlineNamespace = false;
2126 printing_policy.SuppressUnwrittenScope = false;
2127 // Default arguments are also always important for type formatters. Otherwise
2128 // we would need to always specify two type names for the setups where we do
2129 // know the default arguments and where we don't know default arguments.
2130 //
2131 // For example, without this we would need to have formatters for both:
2132 // std::basic_string<char>
2133 // and
2134 // std::basic_string<char, std::char_traits<char>, std::allocator<char> >
2135 // to support setups where LLDB was able to reconstruct default arguments
2136 // (and we then would have suppressed them from the type name) and also setups
2137 // where LLDB wasn't able to reconstruct the default arguments.
2138 printing_policy.SuppressDefaultTemplateArgs = false;
2139 return printing_policy;
2140}
2141
2142std::string TypeSystemClang::GetTypeNameForDecl(const NamedDecl *named_decl,
2143 bool qualified) {
2144 clang::PrintingPolicy printing_policy = GetTypePrintingPolicy();
2145 std::string result;
2146 llvm::raw_string_ostream os(result);
2147 named_decl->getNameForDiagnostic(OS&: os, Policy: printing_policy, Qualified: qualified);
2148 return result;
2149}
2150
2151FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
2152 clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
2153 llvm::StringRef name, const CompilerType &function_clang_type,
2154 clang::StorageClass storage, bool is_inline) {
2155 FunctionDecl *func_decl = nullptr;
2156 ASTContext &ast = getASTContext();
2157 if (!decl_ctx)
2158 decl_ctx = ast.getTranslationUnitDecl();
2159
2160 const bool hasWrittenPrototype = true;
2161 const bool isConstexprSpecified = false;
2162
2163 clang::DeclarationName declarationName =
2164 GetDeclarationName(name, function_clang_type);
2165 func_decl = FunctionDecl::CreateDeserialized(C&: ast, ID: GlobalDeclID());
2166 func_decl->setDeclContext(decl_ctx);
2167 func_decl->setDeclName(declarationName);
2168 func_decl->setType(ClangUtil::GetQualType(ct: function_clang_type));
2169 func_decl->setStorageClass(storage);
2170 func_decl->setInlineSpecified(is_inline);
2171 func_decl->setHasWrittenPrototype(hasWrittenPrototype);
2172 func_decl->setConstexprKind(isConstexprSpecified
2173 ? ConstexprSpecKind::Constexpr
2174 : ConstexprSpecKind::Unspecified);
2175 SetOwningModule(decl: func_decl, owning_module);
2176 decl_ctx->addDecl(D: func_decl);
2177
2178 VerifyDecl(decl: func_decl);
2179
2180 return func_decl;
2181}
2182
2183CompilerType TypeSystemClang::CreateFunctionType(
2184 const CompilerType &result_type, llvm::ArrayRef<CompilerType> args,
2185 bool is_variadic, unsigned type_quals, clang::CallingConv cc,
2186 clang::RefQualifierKind ref_qual) {
2187 if (!result_type || !ClangUtil::IsClangType(ct: result_type))
2188 return CompilerType(); // invalid return type
2189
2190 std::vector<QualType> qual_type_args;
2191 // Verify that all arguments are valid and the right type
2192 for (const auto &arg : args) {
2193 if (arg) {
2194 // Make sure we have a clang type in args[i] and not a type from another
2195 // language whose name might match
2196 const bool is_clang_type = ClangUtil::IsClangType(ct: arg);
2197 lldbassert(is_clang_type);
2198 if (is_clang_type)
2199 qual_type_args.push_back(x: ClangUtil::GetQualType(ct: arg));
2200 else
2201 return CompilerType(); // invalid argument type (must be a clang type)
2202 } else
2203 return CompilerType(); // invalid argument type (empty)
2204 }
2205
2206 // TODO: Detect calling convention in DWARF?
2207 FunctionProtoType::ExtProtoInfo proto_info;
2208 proto_info.ExtInfo = cc;
2209 proto_info.Variadic = is_variadic;
2210 proto_info.ExceptionSpec = EST_None;
2211 proto_info.TypeQuals = clang::Qualifiers::fromFastMask(Mask: type_quals);
2212 proto_info.RefQualifier = ref_qual;
2213
2214 return GetType(qt: getASTContext().getFunctionType(
2215 ResultTy: ClangUtil::GetQualType(ct: result_type), Args: qual_type_args, EPI: proto_info));
2216}
2217
2218ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
2219 clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
2220 const char *name, const CompilerType &param_type, int storage,
2221 bool add_decl) {
2222 ASTContext &ast = getASTContext();
2223 auto *decl = ParmVarDecl::CreateDeserialized(C&: ast, ID: GlobalDeclID());
2224 decl->setDeclContext(decl_ctx);
2225 if (name && name[0])
2226 decl->setDeclName(&ast.Idents.get(Name: name));
2227 decl->setType(ClangUtil::GetQualType(ct: param_type));
2228 decl->setStorageClass(static_cast<clang::StorageClass>(storage));
2229 SetOwningModule(decl, owning_module);
2230 if (add_decl)
2231 decl_ctx->addDecl(D: decl);
2232
2233 return decl;
2234}
2235
2236CompilerType
2237TypeSystemClang::CreateBlockPointerType(const CompilerType &function_type) {
2238 QualType block_type = m_ast_up->getBlockPointerType(
2239 T: clang::QualType::getFromOpaquePtr(Ptr: function_type.GetOpaqueQualType()));
2240
2241 return GetType(qt: block_type);
2242}
2243
2244#pragma mark Array Types
2245
2246CompilerType
2247TypeSystemClang::CreateArrayType(const CompilerType &element_type,
2248 std::optional<size_t> element_count,
2249 bool is_vector) {
2250 if (!element_type.IsValid())
2251 return {};
2252
2253 ASTContext &ast = getASTContext();
2254
2255 // Unknown number of elements; this is an incomplete array
2256 // (e.g., variable length array with non-constant bounds, or
2257 // a flexible array member).
2258 if (!element_count)
2259 return GetType(
2260 qt: ast.getIncompleteArrayType(EltTy: ClangUtil::GetQualType(ct: element_type),
2261 ASM: clang::ArraySizeModifier::Normal, IndexTypeQuals: 0));
2262
2263 if (is_vector)
2264 return GetType(qt: ast.getExtVectorType(VectorType: ClangUtil::GetQualType(ct: element_type),
2265 NumElts: *element_count));
2266
2267 llvm::APInt ap_element_count(64, *element_count);
2268 return GetType(qt: ast.getConstantArrayType(EltTy: ClangUtil::GetQualType(ct: element_type),
2269 ArySize: ap_element_count, SizeExpr: nullptr,
2270 ASM: clang::ArraySizeModifier::Normal, IndexTypeQuals: 0));
2271}
2272
2273CompilerType TypeSystemClang::CreateStructForIdentifier(
2274 llvm::StringRef type_name,
2275 const std::initializer_list<std::pair<const char *, CompilerType>>
2276 &type_fields,
2277 bool packed) {
2278 CompilerType type;
2279 if (!type_name.empty() &&
2280 (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name))
2281 .IsValid()) {
2282 lldbassert(0 && "Trying to create a type for an existing name");
2283 return type;
2284 }
2285
2286 type = CreateRecordType(
2287 decl_ctx: nullptr, owning_module: OptionalClangModuleID(), access_type: lldb::eAccessPublic, name: type_name,
2288 kind: llvm::to_underlying(E: clang::TagTypeKind::Struct), language: lldb::eLanguageTypeC);
2289 StartTagDeclarationDefinition(type);
2290 for (const auto &field : type_fields)
2291 AddFieldToRecordType(type, name: field.first, field_type: field.second, access: lldb::eAccessPublic,
2292 bitfield_bit_size: 0);
2293 if (packed)
2294 SetIsPacked(type);
2295 CompleteTagDeclarationDefinition(type);
2296 return type;
2297}
2298
2299CompilerType TypeSystemClang::GetOrCreateStructForIdentifier(
2300 llvm::StringRef type_name,
2301 const std::initializer_list<std::pair<const char *, CompilerType>>
2302 &type_fields,
2303 bool packed) {
2304 CompilerType type;
2305 if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
2306 return type;
2307
2308 return CreateStructForIdentifier(type_name, type_fields, packed);
2309}
2310
2311#pragma mark Enumeration Types
2312
2313CompilerType TypeSystemClang::CreateEnumerationType(
2314 llvm::StringRef name, clang::DeclContext *decl_ctx,
2315 OptionalClangModuleID owning_module, const Declaration &decl,
2316 const CompilerType &integer_clang_type, bool is_scoped,
2317 std::optional<clang::EnumExtensibilityAttr::Kind> enum_kind) {
2318 // TODO: Do something intelligent with the Declaration object passed in
2319 // like maybe filling in the SourceLocation with it...
2320 ASTContext &ast = getASTContext();
2321
2322 // TODO: ask about these...
2323 // const bool IsFixed = false;
2324 EnumDecl *enum_decl = EnumDecl::CreateDeserialized(C&: ast, ID: GlobalDeclID());
2325 enum_decl->setDeclContext(decl_ctx);
2326 if (!name.empty())
2327 enum_decl->setDeclName(&ast.Idents.get(Name: name));
2328 enum_decl->setScoped(is_scoped);
2329 enum_decl->setScopedUsingClassTag(is_scoped);
2330 enum_decl->setFixed(false);
2331 SetOwningModule(decl: enum_decl, owning_module);
2332 if (decl_ctx)
2333 decl_ctx->addDecl(D: enum_decl);
2334
2335 if (enum_kind)
2336 enum_decl->addAttr(
2337 A: clang::EnumExtensibilityAttr::CreateImplicit(Ctx&: ast, Extensibility: *enum_kind));
2338
2339 // TODO: check if we should be setting the promotion type too?
2340 enum_decl->setIntegerType(ClangUtil::GetQualType(ct: integer_clang_type));
2341
2342 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
2343
2344 return GetType(qt: ast.getTagDeclType(Decl: enum_decl));
2345}
2346
2347CompilerType TypeSystemClang::GetIntTypeFromBitSize(size_t bit_size,
2348 bool is_signed) {
2349 clang::ASTContext &ast = getASTContext();
2350
2351 if (!ast.VoidPtrTy)
2352 return {};
2353
2354 if (is_signed) {
2355 if (bit_size == ast.getTypeSize(T: ast.SignedCharTy))
2356 return GetType(qt: ast.SignedCharTy);
2357
2358 if (bit_size == ast.getTypeSize(T: ast.ShortTy))
2359 return GetType(qt: ast.ShortTy);
2360
2361 if (bit_size == ast.getTypeSize(T: ast.IntTy))
2362 return GetType(qt: ast.IntTy);
2363
2364 if (bit_size == ast.getTypeSize(T: ast.LongTy))
2365 return GetType(qt: ast.LongTy);
2366
2367 if (bit_size == ast.getTypeSize(T: ast.LongLongTy))
2368 return GetType(qt: ast.LongLongTy);
2369
2370 if (bit_size == ast.getTypeSize(T: ast.Int128Ty))
2371 return GetType(qt: ast.Int128Ty);
2372 } else {
2373 if (bit_size == ast.getTypeSize(T: ast.UnsignedCharTy))
2374 return GetType(qt: ast.UnsignedCharTy);
2375
2376 if (bit_size == ast.getTypeSize(T: ast.UnsignedShortTy))
2377 return GetType(qt: ast.UnsignedShortTy);
2378
2379 if (bit_size == ast.getTypeSize(T: ast.UnsignedIntTy))
2380 return GetType(qt: ast.UnsignedIntTy);
2381
2382 if (bit_size == ast.getTypeSize(T: ast.UnsignedLongTy))
2383 return GetType(qt: ast.UnsignedLongTy);
2384
2385 if (bit_size == ast.getTypeSize(T: ast.UnsignedLongLongTy))
2386 return GetType(qt: ast.UnsignedLongLongTy);
2387
2388 if (bit_size == ast.getTypeSize(T: ast.UnsignedInt128Ty))
2389 return GetType(qt: ast.UnsignedInt128Ty);
2390 }
2391 return CompilerType();
2392}
2393
2394CompilerType TypeSystemClang::GetPointerSizedIntType(bool is_signed) {
2395 if (!getASTContext().VoidPtrTy)
2396 return {};
2397
2398 return GetIntTypeFromBitSize(
2399 bit_size: getASTContext().getTypeSize(T: getASTContext().VoidPtrTy), is_signed);
2400}
2401
2402void TypeSystemClang::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) {
2403 if (decl_ctx) {
2404 DumpDeclContextHiearchy(decl_ctx: decl_ctx->getParent());
2405
2406 clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(Val: decl_ctx);
2407 if (named_decl) {
2408 printf(format: "%20s: %s\n", decl_ctx->getDeclKindName(),
2409 named_decl->getDeclName().getAsString().c_str());
2410 } else {
2411 printf(format: "%20s\n", decl_ctx->getDeclKindName());
2412 }
2413 }
2414}
2415
2416void TypeSystemClang::DumpDeclHiearchy(clang::Decl *decl) {
2417 if (decl == nullptr)
2418 return;
2419 DumpDeclContextHiearchy(decl_ctx: decl->getDeclContext());
2420
2421 clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(Val: decl);
2422 if (record_decl) {
2423 bool is_injected_class_name =
2424 llvm::isa<clang::CXXRecordDecl>(Val: record_decl) &&
2425 llvm::cast<CXXRecordDecl>(Val: record_decl)->isInjectedClassName();
2426 printf(format: "%20s: %s%s\n", decl->getDeclKindName(),
2427 record_decl->getDeclName().getAsString().c_str(),
2428 is_injected_class_name ? " (injected class name)" : "");
2429
2430 } else {
2431 clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(Val: decl);
2432 if (named_decl) {
2433 printf(format: "%20s: %s\n", decl->getDeclKindName(),
2434 named_decl->getDeclName().getAsString().c_str());
2435 } else {
2436 printf(format: "%20s\n", decl->getDeclKindName());
2437 }
2438 }
2439}
2440
2441bool TypeSystemClang::GetCompleteDecl(clang::ASTContext *ast,
2442 clang::Decl *decl) {
2443 if (!decl)
2444 return false;
2445
2446 ExternalASTSource *ast_source = ast->getExternalSource();
2447
2448 if (!ast_source)
2449 return false;
2450
2451 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(Val: decl)) {
2452 if (tag_decl->isCompleteDefinition())
2453 return true;
2454
2455 if (!tag_decl->hasExternalLexicalStorage())
2456 return false;
2457
2458 ast_source->CompleteType(Tag: tag_decl);
2459
2460 return !tag_decl->getTypeForDecl()->isIncompleteType();
2461 } else if (clang::ObjCInterfaceDecl *objc_interface_decl =
2462 llvm::dyn_cast<clang::ObjCInterfaceDecl>(Val: decl)) {
2463 if (objc_interface_decl->getDefinition())
2464 return true;
2465
2466 if (!objc_interface_decl->hasExternalLexicalStorage())
2467 return false;
2468
2469 ast_source->CompleteType(Class: objc_interface_decl);
2470
2471 return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
2472 } else {
2473 return false;
2474 }
2475}
2476
2477void TypeSystemClang::SetMetadataAsUserID(const clang::Decl *decl,
2478 user_id_t user_id) {
2479 ClangASTMetadata meta_data;
2480 meta_data.SetUserID(user_id);
2481 SetMetadata(object: decl, meta_data);
2482}
2483
2484void TypeSystemClang::SetMetadataAsUserID(const clang::Type *type,
2485 user_id_t user_id) {
2486 ClangASTMetadata meta_data;
2487 meta_data.SetUserID(user_id);
2488 SetMetadata(object: type, meta_data);
2489}
2490
2491void TypeSystemClang::SetMetadata(const clang::Decl *object,
2492 ClangASTMetadata metadata) {
2493 m_decl_metadata[object] = metadata;
2494}
2495
2496void TypeSystemClang::SetMetadata(const clang::Type *object,
2497 ClangASTMetadata metadata) {
2498 m_type_metadata[object] = metadata;
2499}
2500
2501std::optional<ClangASTMetadata>
2502TypeSystemClang::GetMetadata(const clang::Decl *object) {
2503 auto It = m_decl_metadata.find(Val: object);
2504 if (It != m_decl_metadata.end())
2505 return It->second;
2506
2507 return std::nullopt;
2508}
2509
2510std::optional<ClangASTMetadata>
2511TypeSystemClang::GetMetadata(const clang::Type *object) {
2512 auto It = m_type_metadata.find(Val: object);
2513 if (It != m_type_metadata.end())
2514 return It->second;
2515
2516 return std::nullopt;
2517}
2518
2519void TypeSystemClang::SetCXXRecordDeclAccess(const clang::CXXRecordDecl *object,
2520 clang::AccessSpecifier access) {
2521 if (access == clang::AccessSpecifier::AS_none)
2522 m_cxx_record_decl_access.erase(Val: object);
2523 else
2524 m_cxx_record_decl_access[object] = access;
2525}
2526
2527clang::AccessSpecifier
2528TypeSystemClang::GetCXXRecordDeclAccess(const clang::CXXRecordDecl *object) {
2529 auto It = m_cxx_record_decl_access.find(Val: object);
2530 if (It != m_cxx_record_decl_access.end())
2531 return It->second;
2532 return clang::AccessSpecifier::AS_none;
2533}
2534
2535clang::DeclContext *
2536TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
2537 return GetDeclContextForType(type: ClangUtil::GetQualType(ct: type));
2538}
2539
2540CompilerDeclContext
2541TypeSystemClang::GetCompilerDeclContextForType(const CompilerType &type) {
2542 if (auto *decl_context = GetDeclContextForType(type))
2543 return CreateDeclContext(ctx: decl_context);
2544 return CompilerDeclContext();
2545}
2546
2547/// Aggressively desugar the provided type, skipping past various kinds of
2548/// syntactic sugar and other constructs one typically wants to ignore.
2549/// The \p mask argument allows one to skip certain kinds of simplifications,
2550/// when one wishes to handle a certain kind of type directly.
2551static QualType
2552RemoveWrappingTypes(QualType type, ArrayRef<clang::Type::TypeClass> mask = {}) {
2553 while (true) {
2554 if (find(Range&: mask, Val: type->getTypeClass()) != mask.end())
2555 return type;
2556 switch (type->getTypeClass()) {
2557 // This is not fully correct as _Atomic is more than sugar, but it is
2558 // sufficient for the purposes we care about.
2559 case clang::Type::Atomic:
2560 type = cast<clang::AtomicType>(Val&: type)->getValueType();
2561 break;
2562 case clang::Type::Auto:
2563 case clang::Type::Decltype:
2564 case clang::Type::Elaborated:
2565 case clang::Type::Paren:
2566 case clang::Type::SubstTemplateTypeParm:
2567 case clang::Type::TemplateSpecialization:
2568 case clang::Type::Typedef:
2569 case clang::Type::TypeOf:
2570 case clang::Type::TypeOfExpr:
2571 case clang::Type::Using:
2572 type = type->getLocallyUnqualifiedSingleStepDesugaredType();
2573 break;
2574 default:
2575 return type;
2576 }
2577 }
2578}
2579
2580clang::DeclContext *
2581TypeSystemClang::GetDeclContextForType(clang::QualType type) {
2582 if (type.isNull())
2583 return nullptr;
2584
2585 clang::QualType qual_type = RemoveWrappingTypes(type: type.getCanonicalType());
2586 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2587 switch (type_class) {
2588 case clang::Type::ObjCInterface:
2589 return llvm::cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr())
2590 ->getInterface();
2591 case clang::Type::ObjCObjectPointer:
2592 return GetDeclContextForType(
2593 type: llvm::cast<clang::ObjCObjectPointerType>(Val: qual_type.getTypePtr())
2594 ->getPointeeType());
2595 case clang::Type::Record:
2596 return llvm::cast<clang::RecordType>(Val&: qual_type)->getDecl();
2597 case clang::Type::Enum:
2598 return llvm::cast<clang::EnumType>(Val&: qual_type)->getDecl();
2599 default:
2600 break;
2601 }
2602 // No DeclContext in this type...
2603 return nullptr;
2604}
2605
2606/// Returns the clang::RecordType of the specified \ref qual_type. This
2607/// function will try to complete the type if necessary (and allowed
2608/// by the specified \ref allow_completion). If we fail to return a *complete*
2609/// type, returns nullptr.
2610static const clang::RecordType *GetCompleteRecordType(clang::ASTContext *ast,
2611 clang::QualType qual_type,
2612 bool allow_completion) {
2613 assert(qual_type->isRecordType());
2614
2615 const auto *tag_type = llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
2616
2617 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2618
2619 // RecordType with no way of completing it, return the plain
2620 // TagType.
2621 if (!cxx_record_decl || !cxx_record_decl->hasExternalLexicalStorage())
2622 return tag_type;
2623
2624 const bool is_complete = cxx_record_decl->isCompleteDefinition();
2625 const bool fields_loaded =
2626 cxx_record_decl->hasLoadedFieldsFromExternalStorage();
2627
2628 // Already completed this type, nothing to be done.
2629 if (is_complete && fields_loaded)
2630 return tag_type;
2631
2632 if (!allow_completion)
2633 return nullptr;
2634
2635 // Call the field_begin() accessor to for it to use the external source
2636 // to load the fields...
2637 //
2638 // TODO: if we need to complete the type but have no external source,
2639 // shouldn't we error out instead?
2640 clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2641 if (external_ast_source) {
2642 external_ast_source->CompleteType(Tag: cxx_record_decl);
2643 if (cxx_record_decl->isCompleteDefinition()) {
2644 cxx_record_decl->field_begin();
2645 cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
2646 }
2647 }
2648
2649 return tag_type;
2650}
2651
2652/// Returns the clang::EnumType of the specified \ref qual_type. This
2653/// function will try to complete the type if necessary (and allowed
2654/// by the specified \ref allow_completion). If we fail to return a *complete*
2655/// type, returns nullptr.
2656static const clang::EnumType *GetCompleteEnumType(clang::ASTContext *ast,
2657 clang::QualType qual_type,
2658 bool allow_completion) {
2659 assert(qual_type->isEnumeralType());
2660 assert(ast);
2661
2662 const clang::EnumType *enum_type =
2663 llvm::cast<clang::EnumType>(Val: qual_type.getTypePtr());
2664
2665 auto *tag_decl = enum_type->getAsTagDecl();
2666 assert(tag_decl);
2667
2668 // Already completed, nothing to be done.
2669 if (tag_decl->getDefinition())
2670 return enum_type;
2671
2672 if (!allow_completion)
2673 return nullptr;
2674
2675 // No definition but can't complete it, error out.
2676 if (!tag_decl->hasExternalLexicalStorage())
2677 return nullptr;
2678
2679 // We can't complete the type without an external source.
2680 clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2681 if (!external_ast_source)
2682 return nullptr;
2683
2684 external_ast_source->CompleteType(Tag: tag_decl);
2685 return enum_type;
2686}
2687
2688/// Returns the clang::ObjCObjectType of the specified \ref qual_type. This
2689/// function will try to complete the type if necessary (and allowed
2690/// by the specified \ref allow_completion). If we fail to return a *complete*
2691/// type, returns nullptr.
2692static const clang::ObjCObjectType *
2693GetCompleteObjCObjectType(clang::ASTContext *ast, QualType qual_type,
2694 bool allow_completion) {
2695 assert(qual_type->isObjCObjectType());
2696 assert(ast);
2697
2698 const clang::ObjCObjectType *objc_class_type =
2699 llvm::cast<clang::ObjCObjectType>(Val&: qual_type);
2700
2701 clang::ObjCInterfaceDecl *class_interface_decl =
2702 objc_class_type->getInterface();
2703 // We currently can't complete objective C types through the newly added
2704 // ASTContext because it only supports TagDecl objects right now...
2705 if (!class_interface_decl)
2706 return objc_class_type;
2707
2708 // Already complete, nothing to be done.
2709 if (class_interface_decl->getDefinition())
2710 return objc_class_type;
2711
2712 if (!allow_completion)
2713 return nullptr;
2714
2715 // No definition but can't complete it, error out.
2716 if (!class_interface_decl->hasExternalLexicalStorage())
2717 return nullptr;
2718
2719 // We can't complete the type without an external source.
2720 clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2721 if (!external_ast_source)
2722 return nullptr;
2723
2724 external_ast_source->CompleteType(Class: class_interface_decl);
2725 return objc_class_type;
2726}
2727
2728static bool GetCompleteQualType(clang::ASTContext *ast,
2729 clang::QualType qual_type,
2730 bool allow_completion = true) {
2731 qual_type = RemoveWrappingTypes(type: qual_type);
2732 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2733 switch (type_class) {
2734 case clang::Type::ConstantArray:
2735 case clang::Type::IncompleteArray:
2736 case clang::Type::VariableArray: {
2737 const clang::ArrayType *array_type =
2738 llvm::dyn_cast<clang::ArrayType>(Val: qual_type.getTypePtr());
2739
2740 if (array_type)
2741 return GetCompleteQualType(ast, qual_type: array_type->getElementType(),
2742 allow_completion);
2743 } break;
2744 case clang::Type::Record: {
2745 if (const auto *RT =
2746 GetCompleteRecordType(ast, qual_type, allow_completion))
2747 return !RT->isIncompleteType();
2748
2749 return false;
2750 } break;
2751
2752 case clang::Type::Enum: {
2753 if (const auto *ET = GetCompleteEnumType(ast, qual_type, allow_completion))
2754 return !ET->isIncompleteType();
2755
2756 return false;
2757 } break;
2758 case clang::Type::ObjCObject:
2759 case clang::Type::ObjCInterface: {
2760 if (const auto *OT =
2761 GetCompleteObjCObjectType(ast, qual_type, allow_completion))
2762 return !OT->isIncompleteType();
2763
2764 return false;
2765 } break;
2766
2767 case clang::Type::Attributed:
2768 return GetCompleteQualType(
2769 ast, qual_type: llvm::cast<clang::AttributedType>(Val&: qual_type)->getModifiedType(),
2770 allow_completion);
2771
2772 case clang::Type::MemberPointer:
2773 // MS C++ ABI requires type of the class to be complete of which the pointee
2774 // is a member.
2775 if (ast->getTargetInfo().getCXXABI().isMicrosoft()) {
2776 auto *MPT = qual_type.getTypePtr()->castAs<clang::MemberPointerType>();
2777 if (auto *RD = MPT->getMostRecentCXXRecordDecl())
2778 GetCompleteRecordType(ast, qual_type: QualType(RD->getTypeForDecl(), 0),
2779 allow_completion);
2780
2781 return !qual_type.getTypePtr()->isIncompleteType();
2782 }
2783 break;
2784
2785 default:
2786 break;
2787 }
2788
2789 return true;
2790}
2791
2792static clang::ObjCIvarDecl::AccessControl
2793ConvertAccessTypeToObjCIvarAccessControl(AccessType access) {
2794 switch (access) {
2795 case eAccessNone:
2796 return clang::ObjCIvarDecl::None;
2797 case eAccessPublic:
2798 return clang::ObjCIvarDecl::Public;
2799 case eAccessPrivate:
2800 return clang::ObjCIvarDecl::Private;
2801 case eAccessProtected:
2802 return clang::ObjCIvarDecl::Protected;
2803 case eAccessPackage:
2804 return clang::ObjCIvarDecl::Package;
2805 }
2806 return clang::ObjCIvarDecl::None;
2807}
2808
2809// Tests
2810
2811#ifndef NDEBUG
2812bool TypeSystemClang::Verify(lldb::opaque_compiler_type_t type) {
2813 return !type || llvm::isa<clang::Type>(GetQualType(type).getTypePtr());
2814}
2815#endif
2816
2817bool TypeSystemClang::IsAggregateType(lldb::opaque_compiler_type_t type) {
2818 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
2819
2820 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2821 switch (type_class) {
2822 case clang::Type::IncompleteArray:
2823 case clang::Type::VariableArray:
2824 case clang::Type::ConstantArray:
2825 case clang::Type::ExtVector:
2826 case clang::Type::Vector:
2827 case clang::Type::Record:
2828 case clang::Type::ObjCObject:
2829 case clang::Type::ObjCInterface:
2830 return true;
2831 default:
2832 break;
2833 }
2834 // The clang type does have a value
2835 return false;
2836}
2837
2838bool TypeSystemClang::IsAnonymousType(lldb::opaque_compiler_type_t type) {
2839 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
2840
2841 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2842 switch (type_class) {
2843 case clang::Type::Record: {
2844 if (const clang::RecordType *record_type =
2845 llvm::dyn_cast_or_null<clang::RecordType>(
2846 Val: qual_type.getTypePtrOrNull())) {
2847 if (const clang::RecordDecl *record_decl = record_type->getDecl()) {
2848 return record_decl->isAnonymousStructOrUnion();
2849 }
2850 }
2851 break;
2852 }
2853 default:
2854 break;
2855 }
2856 // The clang type does have a value
2857 return false;
2858}
2859
2860bool TypeSystemClang::IsArrayType(lldb::opaque_compiler_type_t type,
2861 CompilerType *element_type_ptr,
2862 uint64_t *size, bool *is_incomplete) {
2863 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
2864
2865 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2866 switch (type_class) {
2867 default:
2868 break;
2869
2870 case clang::Type::ConstantArray:
2871 if (element_type_ptr)
2872 element_type_ptr->SetCompilerType(
2873 type_system: weak_from_this(), type: llvm::cast<clang::ConstantArrayType>(Val&: qual_type)
2874 ->getElementType()
2875 .getAsOpaquePtr());
2876 if (size)
2877 *size = llvm::cast<clang::ConstantArrayType>(Val&: qual_type)
2878 ->getSize()
2879 .getLimitedValue(ULLONG_MAX);
2880 if (is_incomplete)
2881 *is_incomplete = false;
2882 return true;
2883
2884 case clang::Type::IncompleteArray:
2885 if (element_type_ptr)
2886 element_type_ptr->SetCompilerType(
2887 type_system: weak_from_this(), type: llvm::cast<clang::IncompleteArrayType>(Val&: qual_type)
2888 ->getElementType()
2889 .getAsOpaquePtr());
2890 if (size)
2891 *size = 0;
2892 if (is_incomplete)
2893 *is_incomplete = true;
2894 return true;
2895
2896 case clang::Type::VariableArray:
2897 if (element_type_ptr)
2898 element_type_ptr->SetCompilerType(
2899 type_system: weak_from_this(), type: llvm::cast<clang::VariableArrayType>(Val&: qual_type)
2900 ->getElementType()
2901 .getAsOpaquePtr());
2902 if (size)
2903 *size = 0;
2904 if (is_incomplete)
2905 *is_incomplete = false;
2906 return true;
2907
2908 case clang::Type::DependentSizedArray:
2909 if (element_type_ptr)
2910 element_type_ptr->SetCompilerType(
2911 type_system: weak_from_this(),
2912 type: llvm::cast<clang::DependentSizedArrayType>(Val&: qual_type)
2913 ->getElementType()
2914 .getAsOpaquePtr());
2915 if (size)
2916 *size = 0;
2917 if (is_incomplete)
2918 *is_incomplete = false;
2919 return true;
2920 }
2921 if (element_type_ptr)
2922 element_type_ptr->Clear();
2923 if (size)
2924 *size = 0;
2925 if (is_incomplete)
2926 *is_incomplete = false;
2927 return false;
2928}
2929
2930bool TypeSystemClang::IsVectorType(lldb::opaque_compiler_type_t type,
2931 CompilerType *element_type, uint64_t *size) {
2932 clang::QualType qual_type(GetCanonicalQualType(type));
2933
2934 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2935 switch (type_class) {
2936 case clang::Type::Vector: {
2937 const clang::VectorType *vector_type =
2938 qual_type->getAs<clang::VectorType>();
2939 if (vector_type) {
2940 if (size)
2941 *size = vector_type->getNumElements();
2942 if (element_type)
2943 *element_type = GetType(qt: vector_type->getElementType());
2944 }
2945 return true;
2946 } break;
2947 case clang::Type::ExtVector: {
2948 const clang::ExtVectorType *ext_vector_type =
2949 qual_type->getAs<clang::ExtVectorType>();
2950 if (ext_vector_type) {
2951 if (size)
2952 *size = ext_vector_type->getNumElements();
2953 if (element_type)
2954 *element_type =
2955 CompilerType(weak_from_this(),
2956 ext_vector_type->getElementType().getAsOpaquePtr());
2957 }
2958 return true;
2959 }
2960 default:
2961 break;
2962 }
2963 return false;
2964}
2965
2966bool TypeSystemClang::IsRuntimeGeneratedType(
2967 lldb::opaque_compiler_type_t type) {
2968 clang::DeclContext *decl_ctx = GetDeclContextForType(type: GetQualType(type));
2969 if (!decl_ctx)
2970 return false;
2971
2972 if (!llvm::isa<clang::ObjCInterfaceDecl>(Val: decl_ctx))
2973 return false;
2974
2975 clang::ObjCInterfaceDecl *result_iface_decl =
2976 llvm::dyn_cast<clang::ObjCInterfaceDecl>(Val: decl_ctx);
2977
2978 std::optional<ClangASTMetadata> ast_metadata = GetMetadata(object: result_iface_decl);
2979 if (!ast_metadata)
2980 return false;
2981
2982 return (ast_metadata->GetISAPtr() != 0);
2983}
2984
2985bool TypeSystemClang::IsCharType(lldb::opaque_compiler_type_t type) {
2986 return GetQualType(type).getUnqualifiedType()->isCharType();
2987}
2988
2989bool TypeSystemClang::IsCompleteType(lldb::opaque_compiler_type_t type) {
2990 // If the type hasn't been lazily completed yet, complete it now so that we
2991 // can give the caller an accurate answer whether the type actually has a
2992 // definition. Without completing the type now we would just tell the user
2993 // the current (internal) completeness state of the type and most users don't
2994 // care (or even know) about this behavior.
2995 const bool allow_completion = true;
2996 return GetCompleteQualType(ast: &getASTContext(), qual_type: GetQualType(type),
2997 allow_completion);
2998}
2999
3000bool TypeSystemClang::IsConst(lldb::opaque_compiler_type_t type) {
3001 return GetQualType(type).isConstQualified();
3002}
3003
3004bool TypeSystemClang::IsCStringType(lldb::opaque_compiler_type_t type,
3005 uint32_t &length) {
3006 CompilerType pointee_or_element_clang_type;
3007 length = 0;
3008 Flags type_flags(GetTypeInfo(type, pointee_or_element_compiler_type: &pointee_or_element_clang_type));
3009
3010 if (!pointee_or_element_clang_type.IsValid())
3011 return false;
3012
3013 if (type_flags.AnySet(mask: eTypeIsArray | eTypeIsPointer)) {
3014 if (pointee_or_element_clang_type.IsCharType()) {
3015 if (type_flags.Test(bit: eTypeIsArray)) {
3016 // We know the size of the array and it could be a C string since it is
3017 // an array of characters
3018 length = llvm::cast<clang::ConstantArrayType>(
3019 Val: GetCanonicalQualType(type).getTypePtr())
3020 ->getSize()
3021 .getLimitedValue();
3022 }
3023 return true;
3024 }
3025 }
3026 return false;
3027}
3028
3029unsigned TypeSystemClang::GetPtrAuthKey(lldb::opaque_compiler_type_t type) {
3030 if (type) {
3031 clang::QualType qual_type(GetCanonicalQualType(type));
3032 if (auto pointer_auth = qual_type.getPointerAuth())
3033 return pointer_auth.getKey();
3034 }
3035 return 0;
3036}
3037
3038unsigned
3039TypeSystemClang::GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) {
3040 if (type) {
3041 clang::QualType qual_type(GetCanonicalQualType(type));
3042 if (auto pointer_auth = qual_type.getPointerAuth())
3043 return pointer_auth.getExtraDiscriminator();
3044 }
3045 return 0;
3046}
3047
3048bool TypeSystemClang::GetPtrAuthAddressDiversity(
3049 lldb::opaque_compiler_type_t type) {
3050 if (type) {
3051 clang::QualType qual_type(GetCanonicalQualType(type));
3052 if (auto pointer_auth = qual_type.getPointerAuth())
3053 return pointer_auth.isAddressDiscriminated();
3054 }
3055 return false;
3056}
3057
3058bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type) {
3059 auto isFunctionType = [&](clang::QualType qual_type) {
3060 return qual_type->isFunctionType();
3061 };
3062
3063 return IsTypeImpl(type, predicate: isFunctionType);
3064}
3065
3066// Used to detect "Homogeneous Floating-point Aggregates"
3067uint32_t
3068TypeSystemClang::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
3069 CompilerType *base_type_ptr) {
3070 if (!type)
3071 return 0;
3072
3073 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
3074 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3075 switch (type_class) {
3076 case clang::Type::Record:
3077 if (GetCompleteType(type)) {
3078 const clang::CXXRecordDecl *cxx_record_decl =
3079 qual_type->getAsCXXRecordDecl();
3080 if (cxx_record_decl) {
3081 if (cxx_record_decl->getNumBases() || cxx_record_decl->isDynamicClass())
3082 return 0;
3083 }
3084 const clang::RecordType *record_type =
3085 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
3086 if (record_type) {
3087 const clang::RecordDecl *record_decl = record_type->getDecl();
3088 if (record_decl) {
3089 // We are looking for a structure that contains only floating point
3090 // types
3091 clang::RecordDecl::field_iterator field_pos,
3092 field_end = record_decl->field_end();
3093 uint32_t num_fields = 0;
3094 bool is_hva = false;
3095 bool is_hfa = false;
3096 clang::QualType base_qual_type;
3097 uint64_t base_bitwidth = 0;
3098 for (field_pos = record_decl->field_begin(); field_pos != field_end;
3099 ++field_pos) {
3100 clang::QualType field_qual_type = field_pos->getType();
3101 uint64_t field_bitwidth = getASTContext().getTypeSize(T: qual_type);
3102 if (field_qual_type->isFloatingType()) {
3103 if (field_qual_type->isComplexType())
3104 return 0;
3105 else {
3106 if (num_fields == 0)
3107 base_qual_type = field_qual_type;
3108 else {
3109 if (is_hva)
3110 return 0;
3111 is_hfa = true;
3112 if (field_qual_type.getTypePtr() !=
3113 base_qual_type.getTypePtr())
3114 return 0;
3115 }
3116 }
3117 } else if (field_qual_type->isVectorType() ||
3118 field_qual_type->isExtVectorType()) {
3119 if (num_fields == 0) {
3120 base_qual_type = field_qual_type;
3121 base_bitwidth = field_bitwidth;
3122 } else {
3123 if (is_hfa)
3124 return 0;
3125 is_hva = true;
3126 if (base_bitwidth != field_bitwidth)
3127 return 0;
3128 if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
3129 return 0;
3130 }
3131 } else
3132 return 0;
3133 ++num_fields;
3134 }
3135 if (base_type_ptr)
3136 *base_type_ptr =
3137 CompilerType(weak_from_this(), base_qual_type.getAsOpaquePtr());
3138 return num_fields;
3139 }
3140 }
3141 }
3142 break;
3143
3144 default:
3145 break;
3146 }
3147 return 0;
3148}
3149
3150size_t TypeSystemClang::GetNumberOfFunctionArguments(
3151 lldb::opaque_compiler_type_t type) {
3152 if (type) {
3153 clang::QualType qual_type(GetCanonicalQualType(type));
3154 const clang::FunctionProtoType *func =
3155 llvm::dyn_cast<clang::FunctionProtoType>(Val: qual_type.getTypePtr());
3156 if (func)
3157 return func->getNumParams();
3158 }
3159 return 0;
3160}
3161
3162CompilerType
3163TypeSystemClang::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
3164 const size_t index) {
3165 if (type) {
3166 clang::QualType qual_type(GetQualType(type));
3167 const clang::FunctionProtoType *func =
3168 llvm::dyn_cast<clang::FunctionProtoType>(Val: qual_type.getTypePtr());
3169 if (func) {
3170 if (index < func->getNumParams())
3171 return CompilerType(weak_from_this(), func->getParamType(i: index).getAsOpaquePtr());
3172 }
3173 }
3174 return CompilerType();
3175}
3176
3177bool TypeSystemClang::IsTypeImpl(
3178 lldb::opaque_compiler_type_t type,
3179 llvm::function_ref<bool(clang::QualType)> predicate) const {
3180 if (type) {
3181 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
3182
3183 if (predicate(qual_type))
3184 return true;
3185
3186 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3187 switch (type_class) {
3188 default:
3189 break;
3190
3191 case clang::Type::LValueReference:
3192 case clang::Type::RValueReference: {
3193 const clang::ReferenceType *reference_type =
3194 llvm::cast<clang::ReferenceType>(Val: qual_type.getTypePtr());
3195 if (reference_type)
3196 return IsTypeImpl(type: reference_type->getPointeeType().getAsOpaquePtr(), predicate);
3197 } break;
3198 }
3199 }
3200 return false;
3201}
3202
3203bool TypeSystemClang::IsMemberFunctionPointerType(
3204 lldb::opaque_compiler_type_t type) {
3205 auto isMemberFunctionPointerType = [](clang::QualType qual_type) {
3206 return qual_type->isMemberFunctionPointerType();
3207 };
3208
3209 return IsTypeImpl(type, predicate: isMemberFunctionPointerType);
3210}
3211
3212bool TypeSystemClang::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
3213 auto isFunctionPointerType = [](clang::QualType qual_type) {
3214 return qual_type->isFunctionPointerType();
3215 };
3216
3217 return IsTypeImpl(type, predicate: isFunctionPointerType);
3218}
3219
3220bool TypeSystemClang::IsBlockPointerType(
3221 lldb::opaque_compiler_type_t type,
3222 CompilerType *function_pointer_type_ptr) {
3223 auto isBlockPointerType = [&](clang::QualType qual_type) {
3224 if (qual_type->isBlockPointerType()) {
3225 if (function_pointer_type_ptr) {
3226 const clang::BlockPointerType *block_pointer_type =
3227 qual_type->castAs<clang::BlockPointerType>();
3228 QualType pointee_type = block_pointer_type->getPointeeType();
3229 QualType function_pointer_type = m_ast_up->getPointerType(T: pointee_type);
3230 *function_pointer_type_ptr = CompilerType(
3231 weak_from_this(), function_pointer_type.getAsOpaquePtr());
3232 }
3233 return true;
3234 }
3235
3236 return false;
3237 };
3238
3239 return IsTypeImpl(type, predicate: isBlockPointerType);
3240}
3241
3242bool TypeSystemClang::IsIntegerType(lldb::opaque_compiler_type_t type,
3243 bool &is_signed) {
3244 if (!type)
3245 return false;
3246
3247 clang::QualType qual_type(GetCanonicalQualType(type));
3248 const clang::BuiltinType *builtin_type =
3249 llvm::dyn_cast<clang::BuiltinType>(Val: qual_type->getCanonicalTypeInternal());
3250
3251 if (builtin_type) {
3252 if (builtin_type->isInteger()) {
3253 is_signed = builtin_type->isSignedInteger();
3254 return true;
3255 }
3256 }
3257
3258 return false;
3259}
3260
3261bool TypeSystemClang::IsEnumerationType(lldb::opaque_compiler_type_t type,
3262 bool &is_signed) {
3263 if (type) {
3264 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
3265 Val: GetCanonicalQualType(type)->getCanonicalTypeInternal());
3266
3267 if (enum_type) {
3268 IsIntegerType(type: enum_type->getDecl()->getIntegerType().getAsOpaquePtr(),
3269 is_signed);
3270 return true;
3271 }
3272 }
3273
3274 return false;
3275}
3276
3277bool TypeSystemClang::IsScopedEnumerationType(
3278 lldb::opaque_compiler_type_t type) {
3279 if (type) {
3280 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
3281 Val: GetCanonicalQualType(type)->getCanonicalTypeInternal());
3282
3283 if (enum_type) {
3284 return enum_type->isScopedEnumeralType();
3285 }
3286 }
3287
3288 return false;
3289}
3290
3291bool TypeSystemClang::IsPointerType(lldb::opaque_compiler_type_t type,
3292 CompilerType *pointee_type) {
3293 if (type) {
3294 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
3295 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3296 switch (type_class) {
3297 case clang::Type::Builtin:
3298 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
3299 default:
3300 break;
3301 case clang::BuiltinType::ObjCId:
3302 case clang::BuiltinType::ObjCClass:
3303 return true;
3304 }
3305 return false;
3306 case clang::Type::ObjCObjectPointer:
3307 if (pointee_type)
3308 pointee_type->SetCompilerType(
3309 type_system: weak_from_this(),
3310 type: llvm::cast<clang::ObjCObjectPointerType>(Val&: qual_type)
3311 ->getPointeeType()
3312 .getAsOpaquePtr());
3313 return true;
3314 case clang::Type::BlockPointer:
3315 if (pointee_type)
3316 pointee_type->SetCompilerType(
3317 type_system: weak_from_this(), type: llvm::cast<clang::BlockPointerType>(Val&: qual_type)
3318 ->getPointeeType()
3319 .getAsOpaquePtr());
3320 return true;
3321 case clang::Type::Pointer:
3322 if (pointee_type)
3323 pointee_type->SetCompilerType(type_system: weak_from_this(),
3324 type: llvm::cast<clang::PointerType>(Val&: qual_type)
3325 ->getPointeeType()
3326 .getAsOpaquePtr());
3327 return true;
3328 case clang::Type::MemberPointer:
3329 if (pointee_type)
3330 pointee_type->SetCompilerType(
3331 type_system: weak_from_this(), type: llvm::cast<clang::MemberPointerType>(Val&: qual_type)
3332 ->getPointeeType()
3333 .getAsOpaquePtr());
3334 return true;
3335 default:
3336 break;
3337 }
3338 }
3339 if (pointee_type)
3340 pointee_type->Clear();
3341 return false;
3342}
3343
3344bool TypeSystemClang::IsPointerOrReferenceType(
3345 lldb::opaque_compiler_type_t type, CompilerType *pointee_type) {
3346 if (type) {
3347 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
3348 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3349 switch (type_class) {
3350 case clang::Type::Builtin:
3351 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
3352 default:
3353 break;
3354 case clang::BuiltinType::ObjCId:
3355 case clang::BuiltinType::ObjCClass:
3356 return true;
3357 }
3358 return false;
3359 case clang::Type::ObjCObjectPointer:
3360 if (pointee_type)
3361 pointee_type->SetCompilerType(
3362 type_system: weak_from_this(),
3363 type: llvm::cast<clang::ObjCObjectPointerType>(Val&: qual_type)
3364 ->getPointeeType()
3365 .getAsOpaquePtr());
3366 return true;
3367 case clang::Type::BlockPointer:
3368 if (pointee_type)
3369 pointee_type->SetCompilerType(
3370 type_system: weak_from_this(), type: llvm::cast<clang::BlockPointerType>(Val&: qual_type)
3371 ->getPointeeType()
3372 .getAsOpaquePtr());
3373 return true;
3374 case clang::Type::Pointer:
3375 if (pointee_type)
3376 pointee_type->SetCompilerType(type_system: weak_from_this(),
3377 type: llvm::cast<clang::PointerType>(Val&: qual_type)
3378 ->getPointeeType()
3379 .getAsOpaquePtr());
3380 return true;
3381 case clang::Type::MemberPointer:
3382 if (pointee_type)
3383 pointee_type->SetCompilerType(
3384 type_system: weak_from_this(), type: llvm::cast<clang::MemberPointerType>(Val&: qual_type)
3385 ->getPointeeType()
3386 .getAsOpaquePtr());
3387 return true;
3388 case clang::Type::LValueReference:
3389 if (pointee_type)
3390 pointee_type->SetCompilerType(
3391 type_system: weak_from_this(), type: llvm::cast<clang::LValueReferenceType>(Val&: qual_type)
3392 ->desugar()
3393 .getAsOpaquePtr());
3394 return true;
3395 case clang::Type::RValueReference:
3396 if (pointee_type)
3397 pointee_type->SetCompilerType(
3398 type_system: weak_from_this(), type: llvm::cast<clang::RValueReferenceType>(Val&: qual_type)
3399 ->desugar()
3400 .getAsOpaquePtr());
3401 return true;
3402 default:
3403 break;
3404 }
3405 }
3406 if (pointee_type)
3407 pointee_type->Clear();
3408 return false;
3409}
3410
3411bool TypeSystemClang::IsReferenceType(lldb::opaque_compiler_type_t type,
3412 CompilerType *pointee_type,
3413 bool *is_rvalue) {
3414 if (type) {
3415 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
3416 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3417
3418 switch (type_class) {
3419 case clang::Type::LValueReference:
3420 if (pointee_type)
3421 pointee_type->SetCompilerType(
3422 type_system: weak_from_this(), type: llvm::cast<clang::LValueReferenceType>(Val&: qual_type)
3423 ->desugar()
3424 .getAsOpaquePtr());
3425 if (is_rvalue)
3426 *is_rvalue = false;
3427 return true;
3428 case clang::Type::RValueReference:
3429 if (pointee_type)
3430 pointee_type->SetCompilerType(
3431 type_system: weak_from_this(), type: llvm::cast<clang::RValueReferenceType>(Val&: qual_type)
3432 ->desugar()
3433 .getAsOpaquePtr());
3434 if (is_rvalue)
3435 *is_rvalue = true;
3436 return true;
3437
3438 default:
3439 break;
3440 }
3441 }
3442 if (pointee_type)
3443 pointee_type->Clear();
3444 return false;
3445}
3446
3447bool TypeSystemClang::IsFloatingPointType(lldb::opaque_compiler_type_t type,
3448 uint32_t &count, bool &is_complex) {
3449 if (type) {
3450 clang::QualType qual_type(GetCanonicalQualType(type));
3451
3452 if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(
3453 Val: qual_type->getCanonicalTypeInternal())) {
3454 clang::BuiltinType::Kind kind = BT->getKind();
3455 if (kind >= clang::BuiltinType::Float &&
3456 kind <= clang::BuiltinType::LongDouble) {
3457 count = 1;
3458 is_complex = false;
3459 return true;
3460 }
3461 } else if (const clang::ComplexType *CT =
3462 llvm::dyn_cast<clang::ComplexType>(
3463 Val: qual_type->getCanonicalTypeInternal())) {
3464 if (IsFloatingPointType(type: CT->getElementType().getAsOpaquePtr(), count,
3465 is_complex)) {
3466 count = 2;
3467 is_complex = true;
3468 return true;
3469 }
3470 } else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(
3471 Val: qual_type->getCanonicalTypeInternal())) {
3472 if (IsFloatingPointType(type: VT->getElementType().getAsOpaquePtr(), count,
3473 is_complex)) {
3474 count = VT->getNumElements();
3475 is_complex = false;
3476 return true;
3477 }
3478 }
3479 }
3480 count = 0;
3481 is_complex = false;
3482 return false;
3483}
3484
3485bool TypeSystemClang::IsDefined(lldb::opaque_compiler_type_t type) {
3486 if (!type)
3487 return false;
3488
3489 clang::QualType qual_type(GetQualType(type));
3490 const clang::TagType *tag_type =
3491 llvm::dyn_cast<clang::TagType>(Val: qual_type.getTypePtr());
3492 if (tag_type) {
3493 clang::TagDecl *tag_decl = tag_type->getDecl();
3494 if (tag_decl)
3495 return tag_decl->isCompleteDefinition();
3496 return false;
3497 } else {
3498 const clang::ObjCObjectType *objc_class_type =
3499 llvm::dyn_cast<clang::ObjCObjectType>(Val&: qual_type);
3500 if (objc_class_type) {
3501 clang::ObjCInterfaceDecl *class_interface_decl =
3502 objc_class_type->getInterface();
3503 if (class_interface_decl)
3504 return class_interface_decl->getDefinition() != nullptr;
3505 return false;
3506 }
3507 }
3508 return true;
3509}
3510
3511bool TypeSystemClang::IsObjCClassType(const CompilerType &type) {
3512 if (ClangUtil::IsClangType(ct: type)) {
3513 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ct: type));
3514
3515 const clang::ObjCObjectPointerType *obj_pointer_type =
3516 llvm::dyn_cast<clang::ObjCObjectPointerType>(Val&: qual_type);
3517
3518 if (obj_pointer_type)
3519 return obj_pointer_type->isObjCClassType();
3520 }
3521 return false;
3522}
3523
3524bool TypeSystemClang::IsObjCObjectOrInterfaceType(const CompilerType &type) {
3525 if (ClangUtil::IsClangType(ct: type))
3526 return ClangUtil::GetCanonicalQualType(ct: type)->isObjCObjectOrInterfaceType();
3527 return false;
3528}
3529
3530bool TypeSystemClang::IsClassType(lldb::opaque_compiler_type_t type) {
3531 if (!type)
3532 return false;
3533 clang::QualType qual_type(GetCanonicalQualType(type));
3534 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3535 return (type_class == clang::Type::Record);
3536}
3537
3538bool TypeSystemClang::IsEnumType(lldb::opaque_compiler_type_t type) {
3539 if (!type)
3540 return false;
3541 clang::QualType qual_type(GetCanonicalQualType(type));
3542 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3543 return (type_class == clang::Type::Enum);
3544}
3545
3546bool TypeSystemClang::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
3547 if (type) {
3548 clang::QualType qual_type(GetCanonicalQualType(type));
3549 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3550 switch (type_class) {
3551 case clang::Type::Record:
3552 if (GetCompleteType(type)) {
3553 const clang::RecordType *record_type =
3554 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
3555 const clang::RecordDecl *record_decl = record_type->getDecl();
3556 if (record_decl) {
3557 const clang::CXXRecordDecl *cxx_record_decl =
3558 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
3559 if (cxx_record_decl) {
3560 // We can't just call is isPolymorphic() here because that just
3561 // means the current class has virtual functions, it doesn't check
3562 // if any inherited classes have virtual functions. The doc string
3563 // in SBType::IsPolymorphicClass() says it is looking for both
3564 // if the class has virtual methods or if any bases do, so this
3565 // should be more correct.
3566 return cxx_record_decl->isDynamicClass();
3567 }
3568 }
3569 }
3570 break;
3571
3572 default:
3573 break;
3574 }
3575 }
3576 return false;
3577}
3578
3579bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
3580 CompilerType *dynamic_pointee_type,
3581 bool check_cplusplus,
3582 bool check_objc) {
3583 if (dynamic_pointee_type)
3584 dynamic_pointee_type->Clear();
3585 if (!type)
3586 return false;
3587
3588 auto set_dynamic_pointee_type = [&](clang::QualType type) {
3589 if (dynamic_pointee_type)
3590 dynamic_pointee_type->SetCompilerType(type_system: weak_from_this(),
3591 type: type.getAsOpaquePtr());
3592 };
3593
3594 clang::QualType pointee_qual_type;
3595 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
3596 switch (qual_type->getTypeClass()) {
3597 case clang::Type::Builtin:
3598 if (check_objc && llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind() ==
3599 clang::BuiltinType::ObjCId) {
3600 set_dynamic_pointee_type(qual_type);
3601 return true;
3602 }
3603 return false;
3604
3605 case clang::Type::ObjCObjectPointer:
3606 if (!check_objc)
3607 return false;
3608 if (const auto *objc_pointee_type =
3609 qual_type->getPointeeType().getTypePtrOrNull()) {
3610 if (const auto *objc_object_type =
3611 llvm::dyn_cast_or_null<clang::ObjCObjectType>(
3612 Val: objc_pointee_type)) {
3613 if (objc_object_type->isObjCClass())
3614 return false;
3615 }
3616 }
3617 set_dynamic_pointee_type(
3618 llvm::cast<clang::ObjCObjectPointerType>(Val&: qual_type)->getPointeeType());
3619 return true;
3620
3621 case clang::Type::Pointer:
3622 pointee_qual_type =
3623 llvm::cast<clang::PointerType>(Val&: qual_type)->getPointeeType();
3624 break;
3625
3626 case clang::Type::LValueReference:
3627 case clang::Type::RValueReference:
3628 pointee_qual_type =
3629 llvm::cast<clang::ReferenceType>(Val&: qual_type)->getPointeeType();
3630 break;
3631
3632 default:
3633 return false;
3634 }
3635
3636 // Check to make sure what we are pointing to is a possible dynamic C++ type
3637 // We currently accept any "void *" (in case we have a class that has been
3638 // watered down to an opaque pointer) and virtual C++ classes.
3639 switch (pointee_qual_type.getCanonicalType()->getTypeClass()) {
3640 case clang::Type::Builtin:
3641 switch (llvm::cast<clang::BuiltinType>(Val&: pointee_qual_type)->getKind()) {
3642 case clang::BuiltinType::UnknownAny:
3643 case clang::BuiltinType::Void:
3644 set_dynamic_pointee_type(pointee_qual_type);
3645 return true;
3646 default:
3647 return false;
3648 }
3649
3650 case clang::Type::Record: {
3651 if (!check_cplusplus)
3652 return false;
3653 clang::CXXRecordDecl *cxx_record_decl =
3654 pointee_qual_type->getAsCXXRecordDecl();
3655 if (!cxx_record_decl)
3656 return false;
3657
3658 bool success;
3659 if (cxx_record_decl->isCompleteDefinition())
3660 success = cxx_record_decl->isDynamicClass();
3661 else {
3662 std::optional<ClangASTMetadata> metadata = GetMetadata(object: cxx_record_decl);
3663 std::optional<bool> is_dynamic =
3664 metadata ? metadata->GetIsDynamicCXXType() : std::nullopt;
3665 if (is_dynamic)
3666 success = *is_dynamic;
3667 else if (GetType(qt: pointee_qual_type).GetCompleteType())
3668 success = cxx_record_decl->isDynamicClass();
3669 else
3670 success = false;
3671 }
3672
3673 if (success)
3674 set_dynamic_pointee_type(pointee_qual_type);
3675 return success;
3676 }
3677
3678 case clang::Type::ObjCObject:
3679 case clang::Type::ObjCInterface:
3680 if (check_objc) {
3681 set_dynamic_pointee_type(pointee_qual_type);
3682 return true;
3683 }
3684 break;
3685
3686 default:
3687 break;
3688 }
3689 return false;
3690}
3691
3692bool TypeSystemClang::IsScalarType(lldb::opaque_compiler_type_t type) {
3693 if (!type)
3694 return false;
3695
3696 return (GetTypeInfo(type, pointee_or_element_compiler_type: nullptr) & eTypeIsScalar) != 0;
3697}
3698
3699bool TypeSystemClang::IsTypedefType(lldb::opaque_compiler_type_t type) {
3700 if (!type)
3701 return false;
3702 return RemoveWrappingTypes(type: GetQualType(type), mask: {clang::Type::Typedef})
3703 ->getTypeClass() == clang::Type::Typedef;
3704}
3705
3706bool TypeSystemClang::IsVoidType(lldb::opaque_compiler_type_t type) {
3707 if (!type)
3708 return false;
3709 return GetCanonicalQualType(type)->isVoidType();
3710}
3711
3712bool TypeSystemClang::CanPassInRegisters(const CompilerType &type) {
3713 if (auto *record_decl =
3714 TypeSystemClang::GetAsRecordDecl(type)) {
3715 return record_decl->canPassInRegisters();
3716 }
3717 return false;
3718}
3719
3720bool TypeSystemClang::SupportsLanguage(lldb::LanguageType language) {
3721 return TypeSystemClangSupportsLanguage(language);
3722}
3723
3724std::optional<std::string>
3725TypeSystemClang::GetCXXClassName(const CompilerType &type) {
3726 if (!type)
3727 return std::nullopt;
3728
3729 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ct: type));
3730 if (qual_type.isNull())
3731 return std::nullopt;
3732
3733 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3734 if (!cxx_record_decl)
3735 return std::nullopt;
3736
3737 return std::string(cxx_record_decl->getIdentifier()->getNameStart());
3738}
3739
3740bool TypeSystemClang::IsCXXClassType(const CompilerType &type) {
3741 if (!type)
3742 return false;
3743
3744 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ct: type));
3745 return !qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr;
3746}
3747
3748bool TypeSystemClang::IsBeingDefined(lldb::opaque_compiler_type_t type) {
3749 if (!type)
3750 return false;
3751 clang::QualType qual_type(GetCanonicalQualType(type));
3752 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(Val&: qual_type);
3753 if (tag_type)
3754 return tag_type->isBeingDefined();
3755 return false;
3756}
3757
3758bool TypeSystemClang::IsObjCObjectPointerType(const CompilerType &type,
3759 CompilerType *class_type_ptr) {
3760 if (!ClangUtil::IsClangType(ct: type))
3761 return false;
3762
3763 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ct: type));
3764
3765 if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) {
3766 if (class_type_ptr) {
3767 if (!qual_type->isObjCClassType() && !qual_type->isObjCIdType()) {
3768 const clang::ObjCObjectPointerType *obj_pointer_type =
3769 llvm::dyn_cast<clang::ObjCObjectPointerType>(Val&: qual_type);
3770 if (obj_pointer_type == nullptr)
3771 class_type_ptr->Clear();
3772 else
3773 class_type_ptr->SetCompilerType(
3774 type_system: type.GetTypeSystem(),
3775 type: clang::QualType(obj_pointer_type->getInterfaceType(), 0)
3776 .getAsOpaquePtr());
3777 }
3778 }
3779 return true;
3780 }
3781 if (class_type_ptr)
3782 class_type_ptr->Clear();
3783 return false;
3784}
3785
3786// Type Completion
3787
3788bool TypeSystemClang::GetCompleteType(lldb::opaque_compiler_type_t type) {
3789 if (!type)
3790 return false;
3791 const bool allow_completion = true;
3792 return GetCompleteQualType(ast: &getASTContext(), qual_type: GetQualType(type),
3793 allow_completion);
3794}
3795
3796ConstString TypeSystemClang::GetTypeName(lldb::opaque_compiler_type_t type,
3797 bool base_only) {
3798 if (!type)
3799 return ConstString();
3800
3801 clang::QualType qual_type(GetQualType(type));
3802
3803 // Remove certain type sugar from the name. Sugar such as elaborated types
3804 // or template types which only serve to improve diagnostics shouldn't
3805 // act as their own types from the user's perspective (e.g., formatter
3806 // shouldn't format a variable differently depending on how the ser has
3807 // specified the type. '::Type' and 'Type' should behave the same).
3808 // Typedefs and atomic derived types are not removed as they are actually
3809 // useful for identifiying specific types.
3810 qual_type = RemoveWrappingTypes(type: qual_type,
3811 mask: {clang::Type::Typedef, clang::Type::Atomic});
3812
3813 // For a typedef just return the qualified name.
3814 if (const auto *typedef_type = qual_type->getAs<clang::TypedefType>()) {
3815 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
3816 return ConstString(GetTypeNameForDecl(named_decl: typedef_decl));
3817 }
3818
3819 // For consistency, this follows the same code path that clang uses to emit
3820 // debug info. This also handles when we don't want any scopes preceding the
3821 // name.
3822 if (auto *named_decl = qual_type->getAsTagDecl())
3823 return ConstString(GetTypeNameForDecl(named_decl, qualified: !base_only));
3824
3825 return ConstString(qual_type.getAsString(Policy: GetTypePrintingPolicy()));
3826}
3827
3828ConstString
3829TypeSystemClang::GetDisplayTypeName(lldb::opaque_compiler_type_t type) {
3830 if (!type)
3831 return ConstString();
3832
3833 clang::QualType qual_type(GetQualType(type));
3834 clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy());
3835 printing_policy.SuppressTagKeyword = true;
3836 printing_policy.SuppressScope = false;
3837 printing_policy.SuppressUnwrittenScope = true;
3838 printing_policy.SuppressInlineNamespace = true;
3839 return ConstString(qual_type.getAsString(Policy: printing_policy));
3840}
3841
3842uint32_t
3843TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type,
3844 CompilerType *pointee_or_element_clang_type) {
3845 if (!type)
3846 return 0;
3847
3848 if (pointee_or_element_clang_type)
3849 pointee_or_element_clang_type->Clear();
3850
3851 clang::QualType qual_type =
3852 RemoveWrappingTypes(type: GetQualType(type), mask: {clang::Type::Typedef});
3853
3854 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3855 switch (type_class) {
3856 case clang::Type::Attributed:
3857 return GetTypeInfo(type: qual_type->castAs<clang::AttributedType>()
3858 ->getModifiedType()
3859 .getAsOpaquePtr(),
3860 pointee_or_element_clang_type);
3861 case clang::Type::Builtin: {
3862 const clang::BuiltinType *builtin_type =
3863 llvm::cast<clang::BuiltinType>(Val: qual_type->getCanonicalTypeInternal());
3864
3865 uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
3866 switch (builtin_type->getKind()) {
3867 case clang::BuiltinType::ObjCId:
3868 case clang::BuiltinType::ObjCClass:
3869 if (pointee_or_element_clang_type)
3870 pointee_or_element_clang_type->SetCompilerType(
3871 type_system: weak_from_this(),
3872 type: getASTContext().ObjCBuiltinClassTy.getAsOpaquePtr());
3873 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
3874 break;
3875
3876 case clang::BuiltinType::ObjCSel:
3877 if (pointee_or_element_clang_type)
3878 pointee_or_element_clang_type->SetCompilerType(
3879 type_system: weak_from_this(), type: getASTContext().CharTy.getAsOpaquePtr());
3880 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
3881 break;
3882
3883 case clang::BuiltinType::Bool:
3884 case clang::BuiltinType::Char_U:
3885 case clang::BuiltinType::UChar:
3886 case clang::BuiltinType::WChar_U:
3887 case clang::BuiltinType::Char16:
3888 case clang::BuiltinType::Char32:
3889 case clang::BuiltinType::UShort:
3890 case clang::BuiltinType::UInt:
3891 case clang::BuiltinType::ULong:
3892 case clang::BuiltinType::ULongLong:
3893 case clang::BuiltinType::UInt128:
3894 case clang::BuiltinType::Char_S:
3895 case clang::BuiltinType::SChar:
3896 case clang::BuiltinType::WChar_S:
3897 case clang::BuiltinType::Short:
3898 case clang::BuiltinType::Int:
3899 case clang::BuiltinType::Long:
3900 case clang::BuiltinType::LongLong:
3901 case clang::BuiltinType::Int128:
3902 case clang::BuiltinType::Float:
3903 case clang::BuiltinType::Double:
3904 case clang::BuiltinType::LongDouble:
3905 builtin_type_flags |= eTypeIsScalar;
3906 if (builtin_type->isInteger()) {
3907 builtin_type_flags |= eTypeIsInteger;
3908 if (builtin_type->isSignedInteger())
3909 builtin_type_flags |= eTypeIsSigned;
3910 } else if (builtin_type->isFloatingPoint())
3911 builtin_type_flags |= eTypeIsFloat;
3912 break;
3913 default:
3914 break;
3915 }
3916 return builtin_type_flags;
3917 }
3918
3919 case clang::Type::BlockPointer:
3920 if (pointee_or_element_clang_type)
3921 pointee_or_element_clang_type->SetCompilerType(
3922 type_system: weak_from_this(), type: qual_type->getPointeeType().getAsOpaquePtr());
3923 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
3924
3925 case clang::Type::Complex: {
3926 uint32_t complex_type_flags =
3927 eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
3928 const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(
3929 Val: qual_type->getCanonicalTypeInternal());
3930 if (complex_type) {
3931 clang::QualType complex_element_type(complex_type->getElementType());
3932 if (complex_element_type->isIntegerType())
3933 complex_type_flags |= eTypeIsFloat;
3934 else if (complex_element_type->isFloatingType())
3935 complex_type_flags |= eTypeIsInteger;
3936 }
3937 return complex_type_flags;
3938 } break;
3939
3940 case clang::Type::ConstantArray:
3941 case clang::Type::DependentSizedArray:
3942 case clang::Type::IncompleteArray:
3943 case clang::Type::VariableArray:
3944 if (pointee_or_element_clang_type)
3945 pointee_or_element_clang_type->SetCompilerType(
3946 type_system: weak_from_this(), type: llvm::cast<clang::ArrayType>(Val: qual_type.getTypePtr())
3947 ->getElementType()
3948 .getAsOpaquePtr());
3949 return eTypeHasChildren | eTypeIsArray;
3950
3951 case clang::Type::DependentName:
3952 return 0;
3953 case clang::Type::DependentSizedExtVector:
3954 return eTypeHasChildren | eTypeIsVector;
3955 case clang::Type::DependentTemplateSpecialization:
3956 return eTypeIsTemplate;
3957
3958 case clang::Type::Enum:
3959 if (pointee_or_element_clang_type)
3960 pointee_or_element_clang_type->SetCompilerType(
3961 type_system: weak_from_this(), type: llvm::cast<clang::EnumType>(Val&: qual_type)
3962 ->getDecl()
3963 ->getIntegerType()
3964 .getAsOpaquePtr());
3965 return eTypeIsEnumeration | eTypeHasValue;
3966
3967 case clang::Type::FunctionProto:
3968 return eTypeIsFuncPrototype | eTypeHasValue;
3969 case clang::Type::FunctionNoProto:
3970 return eTypeIsFuncPrototype | eTypeHasValue;
3971 case clang::Type::InjectedClassName:
3972 return 0;
3973
3974 case clang::Type::LValueReference:
3975 case clang::Type::RValueReference:
3976 if (pointee_or_element_clang_type)
3977 pointee_or_element_clang_type->SetCompilerType(
3978 type_system: weak_from_this(),
3979 type: llvm::cast<clang::ReferenceType>(Val: qual_type.getTypePtr())
3980 ->getPointeeType()
3981 .getAsOpaquePtr());
3982 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
3983
3984 case clang::Type::MemberPointer:
3985 return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
3986
3987 case clang::Type::ObjCObjectPointer:
3988 if (pointee_or_element_clang_type)
3989 pointee_or_element_clang_type->SetCompilerType(
3990 type_system: weak_from_this(), type: qual_type->getPointeeType().getAsOpaquePtr());
3991 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer |
3992 eTypeHasValue;
3993
3994 case clang::Type::ObjCObject:
3995 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
3996 case clang::Type::ObjCInterface:
3997 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
3998
3999 case clang::Type::Pointer:
4000 if (pointee_or_element_clang_type)
4001 pointee_or_element_clang_type->SetCompilerType(
4002 type_system: weak_from_this(), type: qual_type->getPointeeType().getAsOpaquePtr());
4003 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
4004
4005 case clang::Type::Record:
4006 if (qual_type->getAsCXXRecordDecl())
4007 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
4008 else
4009 return eTypeHasChildren | eTypeIsStructUnion;
4010 break;
4011 case clang::Type::SubstTemplateTypeParm:
4012 return eTypeIsTemplate;
4013 case clang::Type::TemplateTypeParm:
4014 return eTypeIsTemplate;
4015 case clang::Type::TemplateSpecialization:
4016 return eTypeIsTemplate;
4017
4018 case clang::Type::Typedef:
4019 return eTypeIsTypedef | GetType(qt: llvm::cast<clang::TypedefType>(Val&: qual_type)
4020 ->getDecl()
4021 ->getUnderlyingType())
4022 .GetTypeInfo(pointee_or_element_compiler_type: pointee_or_element_clang_type);
4023 case clang::Type::UnresolvedUsing:
4024 return 0;
4025
4026 case clang::Type::ExtVector:
4027 case clang::Type::Vector: {
4028 uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
4029 const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>(
4030 Val: qual_type->getCanonicalTypeInternal());
4031 if (vector_type) {
4032 if (vector_type->isIntegerType())
4033 vector_type_flags |= eTypeIsFloat;
4034 else if (vector_type->isFloatingType())
4035 vector_type_flags |= eTypeIsInteger;
4036 }
4037 return vector_type_flags;
4038 }
4039 default:
4040 return 0;
4041 }
4042 return 0;
4043}
4044
4045lldb::LanguageType
4046TypeSystemClang::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
4047 if (!type)
4048 return lldb::eLanguageTypeC;
4049
4050 // If the type is a reference, then resolve it to what it refers to first:
4051 clang::QualType qual_type(GetCanonicalQualType(type).getNonReferenceType());
4052 if (qual_type->isAnyPointerType()) {
4053 if (qual_type->isObjCObjectPointerType())
4054 return lldb::eLanguageTypeObjC;
4055 if (qual_type->getPointeeCXXRecordDecl())
4056 return lldb::eLanguageTypeC_plus_plus;
4057
4058 clang::QualType pointee_type(qual_type->getPointeeType());
4059 if (pointee_type->getPointeeCXXRecordDecl())
4060 return lldb::eLanguageTypeC_plus_plus;
4061 if (pointee_type->isObjCObjectOrInterfaceType())
4062 return lldb::eLanguageTypeObjC;
4063 if (pointee_type->isObjCClassType())
4064 return lldb::eLanguageTypeObjC;
4065 if (pointee_type.getTypePtr() ==
4066 getASTContext().ObjCBuiltinIdTy.getTypePtr())
4067 return lldb::eLanguageTypeObjC;
4068 } else {
4069 if (qual_type->isObjCObjectOrInterfaceType())
4070 return lldb::eLanguageTypeObjC;
4071 if (qual_type->getAsCXXRecordDecl())
4072 return lldb::eLanguageTypeC_plus_plus;
4073 switch (qual_type->getTypeClass()) {
4074 default:
4075 break;
4076 case clang::Type::Builtin:
4077 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
4078 default:
4079 case clang::BuiltinType::Void:
4080 case clang::BuiltinType::Bool:
4081 case clang::BuiltinType::Char_U:
4082 case clang::BuiltinType::UChar:
4083 case clang::BuiltinType::WChar_U:
4084 case clang::BuiltinType::Char16:
4085 case clang::BuiltinType::Char32:
4086 case clang::BuiltinType::UShort:
4087 case clang::BuiltinType::UInt:
4088 case clang::BuiltinType::ULong:
4089 case clang::BuiltinType::ULongLong:
4090 case clang::BuiltinType::UInt128:
4091 case clang::BuiltinType::Char_S:
4092 case clang::BuiltinType::SChar:
4093 case clang::BuiltinType::WChar_S:
4094 case clang::BuiltinType::Short:
4095 case clang::BuiltinType::Int:
4096 case clang::BuiltinType::Long:
4097 case clang::BuiltinType::LongLong:
4098 case clang::BuiltinType::Int128:
4099 case clang::BuiltinType::Float:
4100 case clang::BuiltinType::Double:
4101 case clang::BuiltinType::LongDouble:
4102 break;
4103
4104 case clang::BuiltinType::NullPtr:
4105 return eLanguageTypeC_plus_plus;
4106
4107 case clang::BuiltinType::ObjCId:
4108 case clang::BuiltinType::ObjCClass:
4109 case clang::BuiltinType::ObjCSel:
4110 return eLanguageTypeObjC;
4111
4112 case clang::BuiltinType::Dependent:
4113 case clang::BuiltinType::Overload:
4114 case clang::BuiltinType::BoundMember:
4115 case clang::BuiltinType::UnknownAny:
4116 break;
4117 }
4118 break;
4119 case clang::Type::Typedef:
4120 return GetType(qt: llvm::cast<clang::TypedefType>(Val&: qual_type)
4121 ->getDecl()
4122 ->getUnderlyingType())
4123 .GetMinimumLanguage();
4124 }
4125 }
4126 return lldb::eLanguageTypeC;
4127}
4128
4129lldb::TypeClass
4130TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) {
4131 if (!type)
4132 return lldb::eTypeClassInvalid;
4133
4134 clang::QualType qual_type =
4135 RemoveWrappingTypes(type: GetQualType(type), mask: {clang::Type::Typedef});
4136
4137 switch (qual_type->getTypeClass()) {
4138 case clang::Type::Atomic:
4139 case clang::Type::Auto:
4140 case clang::Type::CountAttributed:
4141 case clang::Type::Decltype:
4142 case clang::Type::Elaborated:
4143 case clang::Type::Paren:
4144 case clang::Type::TypeOf:
4145 case clang::Type::TypeOfExpr:
4146 case clang::Type::Using:
4147 llvm_unreachable("Handled in RemoveWrappingTypes!");
4148 case clang::Type::UnaryTransform:
4149 break;
4150 case clang::Type::FunctionNoProto:
4151 return lldb::eTypeClassFunction;
4152 case clang::Type::FunctionProto:
4153 return lldb::eTypeClassFunction;
4154 case clang::Type::IncompleteArray:
4155 return lldb::eTypeClassArray;
4156 case clang::Type::VariableArray:
4157 return lldb::eTypeClassArray;
4158 case clang::Type::ConstantArray:
4159 return lldb::eTypeClassArray;
4160 case clang::Type::DependentSizedArray:
4161 return lldb::eTypeClassArray;
4162 case clang::Type::ArrayParameter:
4163 return lldb::eTypeClassArray;
4164 case clang::Type::DependentSizedExtVector:
4165 return lldb::eTypeClassVector;
4166 case clang::Type::DependentVector:
4167 return lldb::eTypeClassVector;
4168 case clang::Type::ExtVector:
4169 return lldb::eTypeClassVector;
4170 case clang::Type::Vector:
4171 return lldb::eTypeClassVector;
4172 case clang::Type::Builtin:
4173 // Ext-Int is just an integer type.
4174 case clang::Type::BitInt:
4175 case clang::Type::DependentBitInt:
4176 return lldb::eTypeClassBuiltin;
4177 case clang::Type::ObjCObjectPointer:
4178 return lldb::eTypeClassObjCObjectPointer;
4179 case clang::Type::BlockPointer:
4180 return lldb::eTypeClassBlockPointer;
4181 case clang::Type::Pointer:
4182 return lldb::eTypeClassPointer;
4183 case clang::Type::LValueReference:
4184 return lldb::eTypeClassReference;
4185 case clang::Type::RValueReference:
4186 return lldb::eTypeClassReference;
4187 case clang::Type::MemberPointer:
4188 return lldb::eTypeClassMemberPointer;
4189 case clang::Type::Complex:
4190 if (qual_type->isComplexType())
4191 return lldb::eTypeClassComplexFloat;
4192 else
4193 return lldb::eTypeClassComplexInteger;
4194 case clang::Type::ObjCObject:
4195 return lldb::eTypeClassObjCObject;
4196 case clang::Type::ObjCInterface:
4197 return lldb::eTypeClassObjCInterface;
4198 case clang::Type::Record: {
4199 const clang::RecordType *record_type =
4200 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
4201 const clang::RecordDecl *record_decl = record_type->getDecl();
4202 if (record_decl->isUnion())
4203 return lldb::eTypeClassUnion;
4204 else if (record_decl->isStruct())
4205 return lldb::eTypeClassStruct;
4206 else
4207 return lldb::eTypeClassClass;
4208 } break;
4209 case clang::Type::Enum:
4210 return lldb::eTypeClassEnumeration;
4211 case clang::Type::Typedef:
4212 return lldb::eTypeClassTypedef;
4213 case clang::Type::UnresolvedUsing:
4214 break;
4215
4216 case clang::Type::Attributed:
4217 case clang::Type::BTFTagAttributed:
4218 break;
4219 case clang::Type::TemplateTypeParm:
4220 break;
4221 case clang::Type::SubstTemplateTypeParm:
4222 break;
4223 case clang::Type::SubstTemplateTypeParmPack:
4224 break;
4225 case clang::Type::InjectedClassName:
4226 break;
4227 case clang::Type::DependentName:
4228 break;
4229 case clang::Type::DependentTemplateSpecialization:
4230 break;
4231 case clang::Type::PackExpansion:
4232 break;
4233
4234 case clang::Type::TemplateSpecialization:
4235 break;
4236 case clang::Type::DeducedTemplateSpecialization:
4237 break;
4238 case clang::Type::Pipe:
4239 break;
4240
4241 // pointer type decayed from an array or function type.
4242 case clang::Type::Decayed:
4243 break;
4244 case clang::Type::Adjusted:
4245 break;
4246 case clang::Type::ObjCTypeParam:
4247 break;
4248
4249 case clang::Type::DependentAddressSpace:
4250 break;
4251 case clang::Type::MacroQualified:
4252 break;
4253
4254 // Matrix types that we're not sure how to display at the moment.
4255 case clang::Type::ConstantMatrix:
4256 case clang::Type::DependentSizedMatrix:
4257 break;
4258
4259 // We don't handle pack indexing yet
4260 case clang::Type::PackIndexing:
4261 break;
4262
4263 case clang::Type::HLSLAttributedResource:
4264 break;
4265 case clang::Type::HLSLInlineSpirv:
4266 break;
4267 }
4268 // We don't know hot to display this type...
4269 return lldb::eTypeClassOther;
4270}
4271
4272unsigned TypeSystemClang::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
4273 if (type)
4274 return GetQualType(type).getQualifiers().getCVRQualifiers();
4275 return 0;
4276}
4277
4278// Creating related types
4279
4280CompilerType
4281TypeSystemClang::GetArrayElementType(lldb::opaque_compiler_type_t type,
4282 ExecutionContextScope *exe_scope) {
4283 if (type) {
4284 clang::QualType qual_type(GetQualType(type));
4285
4286 const clang::Type *array_eletype =
4287 qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
4288
4289 if (!array_eletype)
4290 return CompilerType();
4291
4292 return GetType(qt: clang::QualType(array_eletype, 0));
4293 }
4294 return CompilerType();
4295}
4296
4297CompilerType TypeSystemClang::GetArrayType(lldb::opaque_compiler_type_t type,
4298 uint64_t size) {
4299 if (type) {
4300 clang::QualType qual_type(GetCanonicalQualType(type));
4301 clang::ASTContext &ast_ctx = getASTContext();
4302 if (size != 0)
4303 return GetType(qt: ast_ctx.getConstantArrayType(
4304 EltTy: qual_type, ArySize: llvm::APInt(64, size), SizeExpr: nullptr,
4305 ASM: clang::ArraySizeModifier::Normal, IndexTypeQuals: 0));
4306 else
4307 return GetType(qt: ast_ctx.getIncompleteArrayType(
4308 EltTy: qual_type, ASM: clang::ArraySizeModifier::Normal, IndexTypeQuals: 0));
4309 }
4310
4311 return CompilerType();
4312}
4313
4314CompilerType
4315TypeSystemClang::GetCanonicalType(lldb::opaque_compiler_type_t type) {
4316 if (type)
4317 return GetType(qt: GetCanonicalQualType(type));
4318 return CompilerType();
4319}
4320
4321static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast,
4322 clang::QualType qual_type) {
4323 if (qual_type->isPointerType())
4324 qual_type = ast->getPointerType(
4325 T: GetFullyUnqualifiedType_Impl(ast, qual_type: qual_type->getPointeeType()));
4326 else if (const ConstantArrayType *arr =
4327 ast->getAsConstantArrayType(T: qual_type)) {
4328 qual_type = ast->getConstantArrayType(
4329 EltTy: GetFullyUnqualifiedType_Impl(ast, qual_type: arr->getElementType()),
4330 ArySize: arr->getSize(), SizeExpr: arr->getSizeExpr(), ASM: arr->getSizeModifier(),
4331 IndexTypeQuals: arr->getIndexTypeQualifiers().getAsOpaqueValue());
4332 } else
4333 qual_type = qual_type.getUnqualifiedType();
4334 qual_type.removeLocalConst();
4335 qual_type.removeLocalRestrict();
4336 qual_type.removeLocalVolatile();
4337 return qual_type;
4338}
4339
4340CompilerType
4341TypeSystemClang::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
4342 if (type)
4343 return GetType(
4344 qt: GetFullyUnqualifiedType_Impl(ast: &getASTContext(), qual_type: GetQualType(type)));
4345 return CompilerType();
4346}
4347
4348CompilerType
4349TypeSystemClang::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) {
4350 if (type)
4351 return GetEnumerationIntegerType(type: GetType(qt: GetCanonicalQualType(type)));
4352 return CompilerType();
4353}
4354
4355int TypeSystemClang::GetFunctionArgumentCount(
4356 lldb::opaque_compiler_type_t type) {
4357 if (type) {
4358 const clang::FunctionProtoType *func =
4359 llvm::dyn_cast<clang::FunctionProtoType>(Val: GetCanonicalQualType(type));
4360 if (func)
4361 return func->getNumParams();
4362 }
4363 return -1;
4364}
4365
4366CompilerType TypeSystemClang::GetFunctionArgumentTypeAtIndex(
4367 lldb::opaque_compiler_type_t type, size_t idx) {
4368 if (type) {
4369 const clang::FunctionProtoType *func =
4370 llvm::dyn_cast<clang::FunctionProtoType>(Val: GetQualType(type));
4371 if (func) {
4372 const uint32_t num_args = func->getNumParams();
4373 if (idx < num_args)
4374 return GetType(qt: func->getParamType(i: idx));
4375 }
4376 }
4377 return CompilerType();
4378}
4379
4380CompilerType
4381TypeSystemClang::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
4382 if (type) {
4383 clang::QualType qual_type(GetQualType(type));
4384 const clang::FunctionProtoType *func =
4385 llvm::dyn_cast<clang::FunctionProtoType>(Val: qual_type.getTypePtr());
4386 if (func)
4387 return GetType(qt: func->getReturnType());
4388 }
4389 return CompilerType();
4390}
4391
4392size_t
4393TypeSystemClang::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
4394 size_t num_functions = 0;
4395 if (type) {
4396 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
4397 switch (qual_type->getTypeClass()) {
4398 case clang::Type::Record:
4399 if (GetCompleteQualType(ast: &getASTContext(), qual_type)) {
4400 const clang::RecordType *record_type =
4401 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
4402 const clang::RecordDecl *record_decl = record_type->getDecl();
4403 assert(record_decl);
4404 const clang::CXXRecordDecl *cxx_record_decl =
4405 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
4406 if (cxx_record_decl)
4407 num_functions = std::distance(first: cxx_record_decl->method_begin(),
4408 last: cxx_record_decl->method_end());
4409 }
4410 break;
4411
4412 case clang::Type::ObjCObjectPointer: {
4413 const clang::ObjCObjectPointerType *objc_class_type =
4414 qual_type->castAs<clang::ObjCObjectPointerType>();
4415 const clang::ObjCInterfaceType *objc_interface_type =
4416 objc_class_type->getInterfaceType();
4417 if (objc_interface_type &&
4418 GetCompleteType(type: static_cast<lldb::opaque_compiler_type_t>(
4419 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
4420 clang::ObjCInterfaceDecl *class_interface_decl =
4421 objc_interface_type->getDecl();
4422 if (class_interface_decl) {
4423 num_functions = std::distance(first: class_interface_decl->meth_begin(),
4424 last: class_interface_decl->meth_end());
4425 }
4426 }
4427 break;
4428 }
4429
4430 case clang::Type::ObjCObject:
4431 case clang::Type::ObjCInterface:
4432 if (GetCompleteType(type)) {
4433 const clang::ObjCObjectType *objc_class_type =
4434 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
4435 if (objc_class_type) {
4436 clang::ObjCInterfaceDecl *class_interface_decl =
4437 objc_class_type->getInterface();
4438 if (class_interface_decl)
4439 num_functions = std::distance(first: class_interface_decl->meth_begin(),
4440 last: class_interface_decl->meth_end());
4441 }
4442 }
4443 break;
4444
4445 default:
4446 break;
4447 }
4448 }
4449 return num_functions;
4450}
4451
4452TypeMemberFunctionImpl
4453TypeSystemClang::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
4454 size_t idx) {
4455 std::string name;
4456 MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
4457 CompilerType clang_type;
4458 CompilerDecl clang_decl;
4459 if (type) {
4460 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
4461 switch (qual_type->getTypeClass()) {
4462 case clang::Type::Record:
4463 if (GetCompleteQualType(ast: &getASTContext(), qual_type)) {
4464 const clang::RecordType *record_type =
4465 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
4466 const clang::RecordDecl *record_decl = record_type->getDecl();
4467 assert(record_decl);
4468 const clang::CXXRecordDecl *cxx_record_decl =
4469 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
4470 if (cxx_record_decl) {
4471 auto method_iter = cxx_record_decl->method_begin();
4472 auto method_end = cxx_record_decl->method_end();
4473 if (idx <
4474 static_cast<size_t>(std::distance(first: method_iter, last: method_end))) {
4475 std::advance(i&: method_iter, n: idx);
4476 clang::CXXMethodDecl *cxx_method_decl =
4477 method_iter->getCanonicalDecl();
4478 if (cxx_method_decl) {
4479 name = cxx_method_decl->getDeclName().getAsString();
4480 if (cxx_method_decl->isStatic())
4481 kind = lldb::eMemberFunctionKindStaticMethod;
4482 else if (llvm::isa<clang::CXXConstructorDecl>(Val: cxx_method_decl))
4483 kind = lldb::eMemberFunctionKindConstructor;
4484 else if (llvm::isa<clang::CXXDestructorDecl>(Val: cxx_method_decl))
4485 kind = lldb::eMemberFunctionKindDestructor;
4486 else
4487 kind = lldb::eMemberFunctionKindInstanceMethod;
4488 clang_type = GetType(qt: cxx_method_decl->getType());
4489 clang_decl = GetCompilerDecl(decl: cxx_method_decl);
4490 }
4491 }
4492 }
4493 }
4494 break;
4495
4496 case clang::Type::ObjCObjectPointer: {
4497 const clang::ObjCObjectPointerType *objc_class_type =
4498 qual_type->castAs<clang::ObjCObjectPointerType>();
4499 const clang::ObjCInterfaceType *objc_interface_type =
4500 objc_class_type->getInterfaceType();
4501 if (objc_interface_type &&
4502 GetCompleteType(type: static_cast<lldb::opaque_compiler_type_t>(
4503 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
4504 clang::ObjCInterfaceDecl *class_interface_decl =
4505 objc_interface_type->getDecl();
4506 if (class_interface_decl) {
4507 auto method_iter = class_interface_decl->meth_begin();
4508 auto method_end = class_interface_decl->meth_end();
4509 if (idx <
4510 static_cast<size_t>(std::distance(first: method_iter, last: method_end))) {
4511 std::advance(i&: method_iter, n: idx);
4512 clang::ObjCMethodDecl *objc_method_decl =
4513 method_iter->getCanonicalDecl();
4514 if (objc_method_decl) {
4515 clang_decl = GetCompilerDecl(decl: objc_method_decl);
4516 name = objc_method_decl->getSelector().getAsString();
4517 if (objc_method_decl->isClassMethod())
4518 kind = lldb::eMemberFunctionKindStaticMethod;
4519 else
4520 kind = lldb::eMemberFunctionKindInstanceMethod;
4521 }
4522 }
4523 }
4524 }
4525 break;
4526 }
4527
4528 case clang::Type::ObjCObject:
4529 case clang::Type::ObjCInterface:
4530 if (GetCompleteType(type)) {
4531 const clang::ObjCObjectType *objc_class_type =
4532 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
4533 if (objc_class_type) {
4534 clang::ObjCInterfaceDecl *class_interface_decl =
4535 objc_class_type->getInterface();
4536 if (class_interface_decl) {
4537 auto method_iter = class_interface_decl->meth_begin();
4538 auto method_end = class_interface_decl->meth_end();
4539 if (idx <
4540 static_cast<size_t>(std::distance(first: method_iter, last: method_end))) {
4541 std::advance(i&: method_iter, n: idx);
4542 clang::ObjCMethodDecl *objc_method_decl =
4543 method_iter->getCanonicalDecl();
4544 if (objc_method_decl) {
4545 clang_decl = GetCompilerDecl(decl: objc_method_decl);
4546 name = objc_method_decl->getSelector().getAsString();
4547 if (objc_method_decl->isClassMethod())
4548 kind = lldb::eMemberFunctionKindStaticMethod;
4549 else
4550 kind = lldb::eMemberFunctionKindInstanceMethod;
4551 }
4552 }
4553 }
4554 }
4555 }
4556 break;
4557
4558 default:
4559 break;
4560 }
4561 }
4562
4563 if (kind == eMemberFunctionKindUnknown)
4564 return TypeMemberFunctionImpl();
4565 else
4566 return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
4567}
4568
4569CompilerType
4570TypeSystemClang::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
4571 if (type)
4572 return GetType(qt: GetQualType(type).getNonReferenceType());
4573 return CompilerType();
4574}
4575
4576CompilerType
4577TypeSystemClang::GetPointeeType(lldb::opaque_compiler_type_t type) {
4578 if (type) {
4579 clang::QualType qual_type(GetQualType(type));
4580 return GetType(qt: qual_type.getTypePtr()->getPointeeType());
4581 }
4582 return CompilerType();
4583}
4584
4585CompilerType
4586TypeSystemClang::GetPointerType(lldb::opaque_compiler_type_t type) {
4587 if (type) {
4588 clang::QualType qual_type(GetQualType(type));
4589
4590 switch (qual_type.getDesugaredType(Context: getASTContext())->getTypeClass()) {
4591 case clang::Type::ObjCObject:
4592 case clang::Type::ObjCInterface:
4593 return GetType(qt: getASTContext().getObjCObjectPointerType(OIT: qual_type));
4594
4595 default:
4596 return GetType(qt: getASTContext().getPointerType(T: qual_type));
4597 }
4598 }
4599 return CompilerType();
4600}
4601
4602CompilerType
4603TypeSystemClang::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
4604 if (type)
4605 return GetType(qt: getASTContext().getLValueReferenceType(T: GetQualType(type)));
4606 else
4607 return CompilerType();
4608}
4609
4610CompilerType
4611TypeSystemClang::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
4612 if (type)
4613 return GetType(qt: getASTContext().getRValueReferenceType(T: GetQualType(type)));
4614 else
4615 return CompilerType();
4616}
4617
4618CompilerType TypeSystemClang::GetAtomicType(lldb::opaque_compiler_type_t type) {
4619 if (!type)
4620 return CompilerType();
4621 return GetType(qt: getASTContext().getAtomicType(T: GetQualType(type)));
4622}
4623
4624CompilerType
4625TypeSystemClang::AddConstModifier(lldb::opaque_compiler_type_t type) {
4626 if (type) {
4627 clang::QualType result(GetQualType(type));
4628 result.addConst();
4629 return GetType(qt: result);
4630 }
4631 return CompilerType();
4632}
4633
4634CompilerType
4635TypeSystemClang::AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
4636 uint32_t payload) {
4637 if (type) {
4638 clang::ASTContext &clang_ast = getASTContext();
4639 auto pauth = PointerAuthQualifier::fromOpaqueValue(Opaque: payload);
4640 clang::QualType result =
4641 clang_ast.getPointerAuthType(Ty: GetQualType(type), PointerAuth: pauth);
4642 return GetType(qt: result);
4643 }
4644 return CompilerType();
4645}
4646
4647CompilerType
4648TypeSystemClang::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
4649 if (type) {
4650 clang::QualType result(GetQualType(type));
4651 result.addVolatile();
4652 return GetType(qt: result);
4653 }
4654 return CompilerType();
4655}
4656
4657CompilerType
4658TypeSystemClang::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
4659 if (type) {
4660 clang::QualType result(GetQualType(type));
4661 result.addRestrict();
4662 return GetType(qt: result);
4663 }
4664 return CompilerType();
4665}
4666
4667CompilerType TypeSystemClang::CreateTypedef(
4668 lldb::opaque_compiler_type_t type, const char *typedef_name,
4669 const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) {
4670 if (type && typedef_name && typedef_name[0]) {
4671 clang::ASTContext &clang_ast = getASTContext();
4672 clang::QualType qual_type(GetQualType(type));
4673
4674 clang::DeclContext *decl_ctx =
4675 TypeSystemClang::DeclContextGetAsDeclContext(dc: compiler_decl_ctx);
4676 if (!decl_ctx)
4677 decl_ctx = getASTContext().getTranslationUnitDecl();
4678
4679 clang::TypedefDecl *decl =
4680 clang::TypedefDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
4681 decl->setDeclContext(decl_ctx);
4682 decl->setDeclName(&clang_ast.Idents.get(Name: typedef_name));
4683 decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(T: qual_type));
4684 decl_ctx->addDecl(D: decl);
4685 SetOwningModule(decl, owning_module: TypePayloadClang(payload).GetOwningModule());
4686
4687 clang::TagDecl *tdecl = nullptr;
4688 if (!qual_type.isNull()) {
4689 if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
4690 tdecl = rt->getDecl();
4691 if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
4692 tdecl = et->getDecl();
4693 }
4694
4695 // Check whether this declaration is an anonymous struct, union, or enum,
4696 // hidden behind a typedef. If so, we try to check whether we have a
4697 // typedef tag to attach to the original record declaration
4698 if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
4699 tdecl->setTypedefNameForAnonDecl(decl);
4700
4701 decl->setAccess(clang::AS_public); // TODO respect proper access specifier
4702
4703 // Get a uniqued clang::QualType for the typedef decl type
4704 return GetType(qt: clang_ast.getTypedefType(Decl: decl));
4705 }
4706 return CompilerType();
4707}
4708
4709CompilerType
4710TypeSystemClang::GetTypedefedType(lldb::opaque_compiler_type_t type) {
4711 if (type) {
4712 const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(
4713 Val: RemoveWrappingTypes(type: GetQualType(type), mask: {clang::Type::Typedef}));
4714 if (typedef_type)
4715 return GetType(qt: typedef_type->getDecl()->getUnderlyingType());
4716 }
4717 return CompilerType();
4718}
4719
4720// Create related types using the current type's AST
4721
4722CompilerType TypeSystemClang::GetBasicTypeFromAST(lldb::BasicType basic_type) {
4723 return TypeSystemClang::GetBasicType(basic_type);
4724}
4725
4726CompilerType TypeSystemClang::CreateGenericFunctionPrototype() {
4727 clang::ASTContext &ast = getASTContext();
4728 const FunctionType::ExtInfo generic_ext_info(
4729 /*noReturn=*/false,
4730 /*hasRegParm=*/false,
4731 /*regParm=*/0,
4732 CallingConv::CC_C,
4733 /*producesResult=*/false,
4734 /*noCallerSavedRegs=*/false,
4735 /*NoCfCheck=*/false,
4736 /*cmseNSCall=*/false);
4737 QualType func_type = ast.getFunctionNoProtoType(ResultTy: ast.VoidTy, Info: generic_ext_info);
4738 return GetType(qt: func_type);
4739}
4740// Exploring the type
4741
4742const llvm::fltSemantics &
4743TypeSystemClang::GetFloatTypeSemantics(size_t byte_size) {
4744 clang::ASTContext &ast = getASTContext();
4745 const size_t bit_size = byte_size * 8;
4746 if (bit_size == ast.getTypeSize(T: ast.FloatTy))
4747 return ast.getFloatTypeSemantics(T: ast.FloatTy);
4748 else if (bit_size == ast.getTypeSize(T: ast.DoubleTy))
4749 return ast.getFloatTypeSemantics(T: ast.DoubleTy);
4750 else if (bit_size == ast.getTypeSize(T: ast.LongDoubleTy) ||
4751 bit_size == llvm::APFloat::semanticsSizeInBits(
4752 ast.getFloatTypeSemantics(T: ast.LongDoubleTy)))
4753 return ast.getFloatTypeSemantics(T: ast.LongDoubleTy);
4754 else if (bit_size == ast.getTypeSize(T: ast.HalfTy))
4755 return ast.getFloatTypeSemantics(T: ast.HalfTy);
4756 return llvm::APFloatBase::Bogus();
4757}
4758
4759llvm::Expected<uint64_t>
4760TypeSystemClang::GetObjCBitSize(QualType qual_type,
4761 ExecutionContextScope *exe_scope) {
4762 assert(qual_type->isObjCObjectOrInterfaceType());
4763 ExecutionContext exe_ctx(exe_scope);
4764 if (Process *process = exe_ctx.GetProcessPtr()) {
4765 if (ObjCLanguageRuntime *objc_runtime =
4766 ObjCLanguageRuntime::Get(process&: *process)) {
4767 if (std::optional<uint64_t> bit_size =
4768 objc_runtime->GetTypeBitSize(compiler_type: GetType(qt: qual_type)))
4769 return *bit_size;
4770 }
4771 } else {
4772 static bool g_printed = false;
4773 if (!g_printed) {
4774 StreamString s;
4775 DumpTypeDescription(type: qual_type.getAsOpaquePtr(), s);
4776
4777 llvm::outs() << "warning: trying to determine the size of type ";
4778 llvm::outs() << s.GetString() << "\n";
4779 llvm::outs() << "without a valid ExecutionContext. this is not "
4780 "reliable. please file a bug against LLDB.\n";
4781 llvm::outs() << "backtrace:\n";
4782 llvm::sys::PrintStackTrace(OS&: llvm::outs());
4783 llvm::outs() << "\n";
4784 g_printed = true;
4785 }
4786 }
4787
4788 return getASTContext().getTypeSize(T: qual_type) +
4789 getASTContext().getTypeSize(T: getASTContext().ObjCBuiltinClassTy);
4790}
4791
4792llvm::Expected<uint64_t>
4793TypeSystemClang::GetBitSize(lldb::opaque_compiler_type_t type,
4794 ExecutionContextScope *exe_scope) {
4795 const bool base_name_only = true;
4796 if (!GetCompleteType(type))
4797 return llvm::createStringError(
4798 Fmt: "could not complete type %s",
4799 Vals: GetTypeName(type, base_only: base_name_only).AsCString(value_if_empty: ""));
4800
4801 clang::QualType qual_type(GetCanonicalQualType(type));
4802 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4803 switch (type_class) {
4804 case clang::Type::ConstantArray:
4805 case clang::Type::FunctionProto:
4806 case clang::Type::Record:
4807 return getASTContext().getTypeSize(T: qual_type);
4808 case clang::Type::ObjCInterface:
4809 case clang::Type::ObjCObject:
4810 return GetObjCBitSize(qual_type, exe_scope);
4811 case clang::Type::IncompleteArray: {
4812 const uint64_t bit_size = getASTContext().getTypeSize(T: qual_type);
4813 if (bit_size == 0)
4814 return getASTContext().getTypeSize(
4815 T: qual_type->getArrayElementTypeNoTypeQual()
4816 ->getCanonicalTypeUnqualified());
4817
4818 return bit_size;
4819 }
4820 default:
4821 if (const uint64_t bit_size = getASTContext().getTypeSize(T: qual_type))
4822 return bit_size;
4823 }
4824
4825 return llvm::createStringError(
4826 Fmt: "could not get size of type %s",
4827 Vals: GetTypeName(type, base_only: base_name_only).AsCString(value_if_empty: ""));
4828}
4829
4830std::optional<size_t>
4831TypeSystemClang::GetTypeBitAlign(lldb::opaque_compiler_type_t type,
4832 ExecutionContextScope *exe_scope) {
4833 if (GetCompleteType(type))
4834 return getASTContext().getTypeAlign(T: GetQualType(type));
4835 return {};
4836}
4837
4838lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
4839 uint64_t &count) {
4840 if (!type)
4841 return lldb::eEncodingInvalid;
4842
4843 count = 1;
4844 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
4845
4846 switch (qual_type->getTypeClass()) {
4847 case clang::Type::Atomic:
4848 case clang::Type::Auto:
4849 case clang::Type::CountAttributed:
4850 case clang::Type::Decltype:
4851 case clang::Type::Elaborated:
4852 case clang::Type::Paren:
4853 case clang::Type::Typedef:
4854 case clang::Type::TypeOf:
4855 case clang::Type::TypeOfExpr:
4856 case clang::Type::Using:
4857 llvm_unreachable("Handled in RemoveWrappingTypes!");
4858
4859 case clang::Type::UnaryTransform:
4860 break;
4861
4862 case clang::Type::FunctionNoProto:
4863 case clang::Type::FunctionProto:
4864 return lldb::eEncodingUint;
4865
4866 case clang::Type::IncompleteArray:
4867 case clang::Type::VariableArray:
4868 case clang::Type::ArrayParameter:
4869 break;
4870
4871 case clang::Type::ConstantArray:
4872 break;
4873
4874 case clang::Type::DependentVector:
4875 case clang::Type::ExtVector:
4876 case clang::Type::Vector:
4877 // TODO: Set this to more than one???
4878 break;
4879
4880 case clang::Type::BitInt:
4881 case clang::Type::DependentBitInt:
4882 return qual_type->isUnsignedIntegerType() ? lldb::eEncodingUint
4883 : lldb::eEncodingSint;
4884
4885 case clang::Type::Builtin:
4886 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
4887 case clang::BuiltinType::Void:
4888 break;
4889
4890 case clang::BuiltinType::Char_S:
4891 case clang::BuiltinType::SChar:
4892 case clang::BuiltinType::WChar_S:
4893 case clang::BuiltinType::Short:
4894 case clang::BuiltinType::Int:
4895 case clang::BuiltinType::Long:
4896 case clang::BuiltinType::LongLong:
4897 case clang::BuiltinType::Int128:
4898 return lldb::eEncodingSint;
4899
4900 case clang::BuiltinType::Bool:
4901 case clang::BuiltinType::Char_U:
4902 case clang::BuiltinType::UChar:
4903 case clang::BuiltinType::WChar_U:
4904 case clang::BuiltinType::Char8:
4905 case clang::BuiltinType::Char16:
4906 case clang::BuiltinType::Char32:
4907 case clang::BuiltinType::UShort:
4908 case clang::BuiltinType::UInt:
4909 case clang::BuiltinType::ULong:
4910 case clang::BuiltinType::ULongLong:
4911 case clang::BuiltinType::UInt128:
4912 return lldb::eEncodingUint;
4913
4914 // Fixed point types. Note that they are currently ignored.
4915 case clang::BuiltinType::ShortAccum:
4916 case clang::BuiltinType::Accum:
4917 case clang::BuiltinType::LongAccum:
4918 case clang::BuiltinType::UShortAccum:
4919 case clang::BuiltinType::UAccum:
4920 case clang::BuiltinType::ULongAccum:
4921 case clang::BuiltinType::ShortFract:
4922 case clang::BuiltinType::Fract:
4923 case clang::BuiltinType::LongFract:
4924 case clang::BuiltinType::UShortFract:
4925 case clang::BuiltinType::UFract:
4926 case clang::BuiltinType::ULongFract:
4927 case clang::BuiltinType::SatShortAccum:
4928 case clang::BuiltinType::SatAccum:
4929 case clang::BuiltinType::SatLongAccum:
4930 case clang::BuiltinType::SatUShortAccum:
4931 case clang::BuiltinType::SatUAccum:
4932 case clang::BuiltinType::SatULongAccum:
4933 case clang::BuiltinType::SatShortFract:
4934 case clang::BuiltinType::SatFract:
4935 case clang::BuiltinType::SatLongFract:
4936 case clang::BuiltinType::SatUShortFract:
4937 case clang::BuiltinType::SatUFract:
4938 case clang::BuiltinType::SatULongFract:
4939 break;
4940
4941 case clang::BuiltinType::Half:
4942 case clang::BuiltinType::Float:
4943 case clang::BuiltinType::Float16:
4944 case clang::BuiltinType::Float128:
4945 case clang::BuiltinType::Double:
4946 case clang::BuiltinType::LongDouble:
4947 case clang::BuiltinType::BFloat16:
4948 case clang::BuiltinType::Ibm128:
4949 return lldb::eEncodingIEEE754;
4950
4951 case clang::BuiltinType::ObjCClass:
4952 case clang::BuiltinType::ObjCId:
4953 case clang::BuiltinType::ObjCSel:
4954 return lldb::eEncodingUint;
4955
4956 case clang::BuiltinType::NullPtr:
4957 return lldb::eEncodingUint;
4958
4959 case clang::BuiltinType::Kind::ARCUnbridgedCast:
4960 case clang::BuiltinType::Kind::BoundMember:
4961 case clang::BuiltinType::Kind::BuiltinFn:
4962 case clang::BuiltinType::Kind::Dependent:
4963 case clang::BuiltinType::Kind::OCLClkEvent:
4964 case clang::BuiltinType::Kind::OCLEvent:
4965 case clang::BuiltinType::Kind::OCLImage1dRO:
4966 case clang::BuiltinType::Kind::OCLImage1dWO:
4967 case clang::BuiltinType::Kind::OCLImage1dRW:
4968 case clang::BuiltinType::Kind::OCLImage1dArrayRO:
4969 case clang::BuiltinType::Kind::OCLImage1dArrayWO:
4970 case clang::BuiltinType::Kind::OCLImage1dArrayRW:
4971 case clang::BuiltinType::Kind::OCLImage1dBufferRO:
4972 case clang::BuiltinType::Kind::OCLImage1dBufferWO:
4973 case clang::BuiltinType::Kind::OCLImage1dBufferRW:
4974 case clang::BuiltinType::Kind::OCLImage2dRO:
4975 case clang::BuiltinType::Kind::OCLImage2dWO:
4976 case clang::BuiltinType::Kind::OCLImage2dRW:
4977 case clang::BuiltinType::Kind::OCLImage2dArrayRO:
4978 case clang::BuiltinType::Kind::OCLImage2dArrayWO:
4979 case clang::BuiltinType::Kind::OCLImage2dArrayRW:
4980 case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
4981 case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
4982 case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
4983 case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
4984 case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
4985 case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
4986 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
4987 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
4988 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
4989 case clang::BuiltinType::Kind::OCLImage2dDepthRO:
4990 case clang::BuiltinType::Kind::OCLImage2dDepthWO:
4991 case clang::BuiltinType::Kind::OCLImage2dDepthRW:
4992 case clang::BuiltinType::Kind::OCLImage2dMSAARO:
4993 case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
4994 case clang::BuiltinType::Kind::OCLImage2dMSAARW:
4995 case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
4996 case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
4997 case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
4998 case clang::BuiltinType::Kind::OCLImage3dRO:
4999 case clang::BuiltinType::Kind::OCLImage3dWO:
5000 case clang::BuiltinType::Kind::OCLImage3dRW:
5001 case clang::BuiltinType::Kind::OCLQueue:
5002 case clang::BuiltinType::Kind::OCLReserveID:
5003 case clang::BuiltinType::Kind::OCLSampler:
5004 case clang::BuiltinType::Kind::HLSLResource:
5005 case clang::BuiltinType::Kind::ArraySection:
5006 case clang::BuiltinType::Kind::OMPArrayShaping:
5007 case clang::BuiltinType::Kind::OMPIterator:
5008 case clang::BuiltinType::Kind::Overload:
5009 case clang::BuiltinType::Kind::PseudoObject:
5010 case clang::BuiltinType::Kind::UnknownAny:
5011 break;
5012
5013 case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload:
5014 case clang::BuiltinType::OCLIntelSubgroupAVCImePayload:
5015 case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload:
5016 case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload:
5017 case clang::BuiltinType::OCLIntelSubgroupAVCMceResult:
5018 case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
5019 case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
5020 case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
5021 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleReferenceStreamout:
5022 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualReferenceStreamout:
5023 case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleReferenceStreamin:
5024 case clang::BuiltinType::OCLIntelSubgroupAVCImeDualReferenceStreamin:
5025 break;
5026
5027 // PowerPC -- Matrix Multiply Assist
5028 case clang::BuiltinType::VectorPair:
5029 case clang::BuiltinType::VectorQuad:
5030 case clang::BuiltinType::DMR1024:
5031 break;
5032
5033 // ARM -- Scalable Vector Extension
5034#define SVE_TYPE(Name, Id, SingletonId) case clang::BuiltinType::Id:
5035#include "clang/Basic/AArch64ACLETypes.def"
5036 break;
5037
5038 // RISC-V V builtin types.
5039#define RVV_TYPE(Name, Id, SingletonId) case clang::BuiltinType::Id:
5040#include "clang/Basic/RISCVVTypes.def"
5041 break;
5042
5043 // WebAssembly builtin types.
5044 case clang::BuiltinType::WasmExternRef:
5045 break;
5046
5047 case clang::BuiltinType::IncompleteMatrixIdx:
5048 break;
5049
5050 case clang::BuiltinType::UnresolvedTemplate:
5051 break;
5052
5053 // AMD GPU builtin types.
5054#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) \
5055 case clang::BuiltinType::Id:
5056#include "clang/Basic/AMDGPUTypes.def"
5057 break;
5058 }
5059 break;
5060 // All pointer types are represented as unsigned integer encodings. We may
5061 // nee to add a eEncodingPointer if we ever need to know the difference
5062 case clang::Type::ObjCObjectPointer:
5063 case clang::Type::BlockPointer:
5064 case clang::Type::Pointer:
5065 case clang::Type::LValueReference:
5066 case clang::Type::RValueReference:
5067 case clang::Type::MemberPointer:
5068 return lldb::eEncodingUint;
5069 case clang::Type::Complex: {
5070 lldb::Encoding encoding = lldb::eEncodingIEEE754;
5071 if (qual_type->isComplexType())
5072 encoding = lldb::eEncodingIEEE754;
5073 else {
5074 const clang::ComplexType *complex_type =
5075 qual_type->getAsComplexIntegerType();
5076 if (complex_type)
5077 encoding = GetType(qt: complex_type->getElementType()).GetEncoding(count);
5078 else
5079 encoding = lldb::eEncodingSint;
5080 }
5081 count = 2;
5082 return encoding;
5083 }
5084
5085 case clang::Type::ObjCInterface:
5086 break;
5087 case clang::Type::Record:
5088 break;
5089 case clang::Type::Enum:
5090 return qual_type->isUnsignedIntegerOrEnumerationType()
5091 ? lldb::eEncodingUint
5092 : lldb::eEncodingSint;
5093 case clang::Type::DependentSizedArray:
5094 case clang::Type::DependentSizedExtVector:
5095 case clang::Type::UnresolvedUsing:
5096 case clang::Type::Attributed:
5097 case clang::Type::BTFTagAttributed:
5098 case clang::Type::TemplateTypeParm:
5099 case clang::Type::SubstTemplateTypeParm:
5100 case clang::Type::SubstTemplateTypeParmPack:
5101 case clang::Type::InjectedClassName:
5102 case clang::Type::DependentName:
5103 case clang::Type::DependentTemplateSpecialization:
5104 case clang::Type::PackExpansion:
5105 case clang::Type::ObjCObject:
5106
5107 case clang::Type::TemplateSpecialization:
5108 case clang::Type::DeducedTemplateSpecialization:
5109 case clang::Type::Adjusted:
5110 case clang::Type::Pipe:
5111 break;
5112
5113 // pointer type decayed from an array or function type.
5114 case clang::Type::Decayed:
5115 break;
5116 case clang::Type::ObjCTypeParam:
5117 break;
5118
5119 case clang::Type::DependentAddressSpace:
5120 break;
5121 case clang::Type::MacroQualified:
5122 break;
5123
5124 case clang::Type::ConstantMatrix:
5125 case clang::Type::DependentSizedMatrix:
5126 break;
5127
5128 // We don't handle pack indexing yet
5129 case clang::Type::PackIndexing:
5130 break;
5131
5132 case clang::Type::HLSLAttributedResource:
5133 break;
5134 case clang::Type::HLSLInlineSpirv:
5135 break;
5136 }
5137 count = 0;
5138 return lldb::eEncodingInvalid;
5139}
5140
5141lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
5142 if (!type)
5143 return lldb::eFormatDefault;
5144
5145 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5146
5147 switch (qual_type->getTypeClass()) {
5148 case clang::Type::Atomic:
5149 case clang::Type::Auto:
5150 case clang::Type::CountAttributed:
5151 case clang::Type::Decltype:
5152 case clang::Type::Elaborated:
5153 case clang::Type::Paren:
5154 case clang::Type::Typedef:
5155 case clang::Type::TypeOf:
5156 case clang::Type::TypeOfExpr:
5157 case clang::Type::Using:
5158 llvm_unreachable("Handled in RemoveWrappingTypes!");
5159 case clang::Type::UnaryTransform:
5160 break;
5161
5162 case clang::Type::FunctionNoProto:
5163 case clang::Type::FunctionProto:
5164 break;
5165
5166 case clang::Type::IncompleteArray:
5167 case clang::Type::VariableArray:
5168 case clang::Type::ArrayParameter:
5169 break;
5170
5171 case clang::Type::ConstantArray:
5172 return lldb::eFormatVoid; // no value
5173
5174 case clang::Type::DependentVector:
5175 case clang::Type::ExtVector:
5176 case clang::Type::Vector:
5177 break;
5178
5179 case clang::Type::BitInt:
5180 case clang::Type::DependentBitInt:
5181 return qual_type->isUnsignedIntegerType() ? lldb::eFormatUnsigned
5182 : lldb::eFormatDecimal;
5183
5184 case clang::Type::Builtin:
5185 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
5186 case clang::BuiltinType::UnknownAny:
5187 case clang::BuiltinType::Void:
5188 case clang::BuiltinType::BoundMember:
5189 break;
5190
5191 case clang::BuiltinType::Bool:
5192 return lldb::eFormatBoolean;
5193 case clang::BuiltinType::Char_S:
5194 case clang::BuiltinType::SChar:
5195 case clang::BuiltinType::WChar_S:
5196 case clang::BuiltinType::Char_U:
5197 case clang::BuiltinType::UChar:
5198 case clang::BuiltinType::WChar_U:
5199 return lldb::eFormatChar;
5200 case clang::BuiltinType::Char8:
5201 return lldb::eFormatUnicode8;
5202 case clang::BuiltinType::Char16:
5203 return lldb::eFormatUnicode16;
5204 case clang::BuiltinType::Char32:
5205 return lldb::eFormatUnicode32;
5206 case clang::BuiltinType::UShort:
5207 return lldb::eFormatUnsigned;
5208 case clang::BuiltinType::Short:
5209 return lldb::eFormatDecimal;
5210 case clang::BuiltinType::UInt:
5211 return lldb::eFormatUnsigned;
5212 case clang::BuiltinType::Int:
5213 return lldb::eFormatDecimal;
5214 case clang::BuiltinType::ULong:
5215 return lldb::eFormatUnsigned;
5216 case clang::BuiltinType::Long:
5217 return lldb::eFormatDecimal;
5218 case clang::BuiltinType::ULongLong:
5219 return lldb::eFormatUnsigned;
5220 case clang::BuiltinType::LongLong:
5221 return lldb::eFormatDecimal;
5222 case clang::BuiltinType::UInt128:
5223 return lldb::eFormatUnsigned;
5224 case clang::BuiltinType::Int128:
5225 return lldb::eFormatDecimal;
5226 case clang::BuiltinType::Half:
5227 case clang::BuiltinType::Float:
5228 case clang::BuiltinType::Double:
5229 case clang::BuiltinType::LongDouble:
5230 return lldb::eFormatFloat;
5231 default:
5232 return lldb::eFormatHex;
5233 }
5234 break;
5235 case clang::Type::ObjCObjectPointer:
5236 return lldb::eFormatHex;
5237 case clang::Type::BlockPointer:
5238 return lldb::eFormatHex;
5239 case clang::Type::Pointer:
5240 return lldb::eFormatHex;
5241 case clang::Type::LValueReference:
5242 case clang::Type::RValueReference:
5243 return lldb::eFormatHex;
5244 case clang::Type::MemberPointer:
5245 return lldb::eFormatHex;
5246 case clang::Type::Complex: {
5247 if (qual_type->isComplexType())
5248 return lldb::eFormatComplex;
5249 else
5250 return lldb::eFormatComplexInteger;
5251 }
5252 case clang::Type::ObjCInterface:
5253 break;
5254 case clang::Type::Record:
5255 break;
5256 case clang::Type::Enum:
5257 return lldb::eFormatEnum;
5258 case clang::Type::DependentSizedArray:
5259 case clang::Type::DependentSizedExtVector:
5260 case clang::Type::UnresolvedUsing:
5261 case clang::Type::Attributed:
5262 case clang::Type::BTFTagAttributed:
5263 case clang::Type::TemplateTypeParm:
5264 case clang::Type::SubstTemplateTypeParm:
5265 case clang::Type::SubstTemplateTypeParmPack:
5266 case clang::Type::InjectedClassName:
5267 case clang::Type::DependentName:
5268 case clang::Type::DependentTemplateSpecialization:
5269 case clang::Type::PackExpansion:
5270 case clang::Type::ObjCObject:
5271
5272 case clang::Type::TemplateSpecialization:
5273 case clang::Type::DeducedTemplateSpecialization:
5274 case clang::Type::Adjusted:
5275 case clang::Type::Pipe:
5276 break;
5277
5278 // pointer type decayed from an array or function type.
5279 case clang::Type::Decayed:
5280 break;
5281 case clang::Type::ObjCTypeParam:
5282 break;
5283
5284 case clang::Type::DependentAddressSpace:
5285 break;
5286 case clang::Type::MacroQualified:
5287 break;
5288
5289 // Matrix types we're not sure how to display yet.
5290 case clang::Type::ConstantMatrix:
5291 case clang::Type::DependentSizedMatrix:
5292 break;
5293
5294 // We don't handle pack indexing yet
5295 case clang::Type::PackIndexing:
5296 break;
5297
5298 case clang::Type::HLSLAttributedResource:
5299 break;
5300 case clang::Type::HLSLInlineSpirv:
5301 break;
5302 }
5303 // We don't know hot to display this type...
5304 return lldb::eFormatBytes;
5305}
5306
5307static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl) {
5308 while (class_interface_decl) {
5309 if (class_interface_decl->ivar_size() > 0)
5310 return true;
5311
5312 class_interface_decl = class_interface_decl->getSuperClass();
5313 }
5314 return false;
5315}
5316
5317static std::optional<SymbolFile::ArrayInfo>
5318GetDynamicArrayInfo(TypeSystemClang &ast, SymbolFile *sym_file,
5319 clang::QualType qual_type,
5320 const ExecutionContext *exe_ctx) {
5321 if (qual_type->isIncompleteArrayType())
5322 if (std::optional<ClangASTMetadata> metadata =
5323 ast.GetMetadata(object: qual_type.getTypePtr()))
5324 return sym_file->GetDynamicArrayInfoForUID(type_uid: metadata->GetUserID(),
5325 exe_ctx);
5326 return std::nullopt;
5327}
5328
5329llvm::Expected<uint32_t>
5330TypeSystemClang::GetNumChildren(lldb::opaque_compiler_type_t type,
5331 bool omit_empty_base_classes,
5332 const ExecutionContext *exe_ctx) {
5333 if (!type)
5334 return llvm::createStringError(Fmt: "invalid clang type");
5335
5336 uint32_t num_children = 0;
5337 clang::QualType qual_type(RemoveWrappingTypes(type: GetQualType(type)));
5338 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5339 switch (type_class) {
5340 case clang::Type::Builtin:
5341 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
5342 case clang::BuiltinType::ObjCId: // child is Class
5343 case clang::BuiltinType::ObjCClass: // child is Class
5344 num_children = 1;
5345 break;
5346
5347 default:
5348 break;
5349 }
5350 break;
5351
5352 case clang::Type::Complex:
5353 return 0;
5354 case clang::Type::Record:
5355 if (GetCompleteQualType(ast: &getASTContext(), qual_type)) {
5356 const clang::RecordType *record_type =
5357 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
5358 const clang::RecordDecl *record_decl = record_type->getDecl();
5359 assert(record_decl);
5360 const clang::CXXRecordDecl *cxx_record_decl =
5361 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
5362
5363 num_children +=
5364 GetNumBaseClasses(cxx_record_decl, omit_empty_base_classes);
5365 num_children += std::distance(first: record_decl->field_begin(),
5366 last: record_decl->field_end());
5367 } else
5368 return llvm::createStringError(
5369 S: "incomplete type \"" + GetDisplayTypeName(type).GetString() + "\"");
5370 break;
5371 case clang::Type::ObjCObject:
5372 case clang::Type::ObjCInterface:
5373 if (GetCompleteQualType(ast: &getASTContext(), qual_type)) {
5374 const clang::ObjCObjectType *objc_class_type =
5375 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
5376 assert(objc_class_type);
5377 if (objc_class_type) {
5378 clang::ObjCInterfaceDecl *class_interface_decl =
5379 objc_class_type->getInterface();
5380
5381 if (class_interface_decl) {
5382
5383 clang::ObjCInterfaceDecl *superclass_interface_decl =
5384 class_interface_decl->getSuperClass();
5385 if (superclass_interface_decl) {
5386 if (omit_empty_base_classes) {
5387 if (ObjCDeclHasIVars(class_interface_decl: superclass_interface_decl))
5388 ++num_children;
5389 } else
5390 ++num_children;
5391 }
5392
5393 num_children += class_interface_decl->ivar_size();
5394 }
5395 }
5396 }
5397 break;
5398
5399 case clang::Type::LValueReference:
5400 case clang::Type::RValueReference:
5401 case clang::Type::ObjCObjectPointer: {
5402 CompilerType pointee_clang_type(GetPointeeType(type));
5403
5404 uint32_t num_pointee_children = 0;
5405 if (pointee_clang_type.IsAggregateType()) {
5406 auto num_children_or_err =
5407 pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx);
5408 if (!num_children_or_err)
5409 return num_children_or_err;
5410 num_pointee_children = *num_children_or_err;
5411 }
5412 // If this type points to a simple type, then it has 1 child
5413 if (num_pointee_children == 0)
5414 num_children = 1;
5415 else
5416 num_children = num_pointee_children;
5417 } break;
5418
5419 case clang::Type::Vector:
5420 case clang::Type::ExtVector:
5421 num_children =
5422 llvm::cast<clang::VectorType>(Val: qual_type.getTypePtr())->getNumElements();
5423 break;
5424
5425 case clang::Type::ConstantArray:
5426 num_children = llvm::cast<clang::ConstantArrayType>(Val: qual_type.getTypePtr())
5427 ->getSize()
5428 .getLimitedValue();
5429 break;
5430 case clang::Type::IncompleteArray:
5431 if (auto array_info =
5432 GetDynamicArrayInfo(ast&: *this, sym_file: GetSymbolFile(), qual_type, exe_ctx))
5433 // FIXME: Only 1-dimensional arrays are supported.
5434 num_children = array_info->element_orders.size()
5435 ? array_info->element_orders.back().value_or(u: 0)
5436 : 0;
5437 break;
5438
5439 case clang::Type::Pointer: {
5440 const clang::PointerType *pointer_type =
5441 llvm::cast<clang::PointerType>(Val: qual_type.getTypePtr());
5442 clang::QualType pointee_type(pointer_type->getPointeeType());
5443 CompilerType pointee_clang_type(GetType(qt: pointee_type));
5444 uint32_t num_pointee_children = 0;
5445 if (pointee_clang_type.IsAggregateType()) {
5446 auto num_children_or_err =
5447 pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx);
5448 if (!num_children_or_err)
5449 return num_children_or_err;
5450 num_pointee_children = *num_children_or_err;
5451 }
5452 if (num_pointee_children == 0) {
5453 // We have a pointer to a pointee type that claims it has no children. We
5454 // will want to look at
5455 num_children = GetNumPointeeChildren(type: pointee_type);
5456 } else
5457 num_children = num_pointee_children;
5458 } break;
5459
5460 default:
5461 break;
5462 }
5463 return num_children;
5464}
5465
5466CompilerType TypeSystemClang::GetBuiltinTypeByName(ConstString name) {
5467 return GetBasicType(basic_type: GetBasicTypeEnumeration(name));
5468}
5469
5470lldb::BasicType
5471TypeSystemClang::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
5472 if (type) {
5473 clang::QualType qual_type(GetQualType(type));
5474 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5475 if (type_class == clang::Type::Builtin) {
5476 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
5477 case clang::BuiltinType::Void:
5478 return eBasicTypeVoid;
5479 case clang::BuiltinType::Bool:
5480 return eBasicTypeBool;
5481 case clang::BuiltinType::Char_S:
5482 return eBasicTypeSignedChar;
5483 case clang::BuiltinType::Char_U:
5484 return eBasicTypeUnsignedChar;
5485 case clang::BuiltinType::Char8:
5486 return eBasicTypeChar8;
5487 case clang::BuiltinType::Char16:
5488 return eBasicTypeChar16;
5489 case clang::BuiltinType::Char32:
5490 return eBasicTypeChar32;
5491 case clang::BuiltinType::UChar:
5492 return eBasicTypeUnsignedChar;
5493 case clang::BuiltinType::SChar:
5494 return eBasicTypeSignedChar;
5495 case clang::BuiltinType::WChar_S:
5496 return eBasicTypeSignedWChar;
5497 case clang::BuiltinType::WChar_U:
5498 return eBasicTypeUnsignedWChar;
5499 case clang::BuiltinType::Short:
5500 return eBasicTypeShort;
5501 case clang::BuiltinType::UShort:
5502 return eBasicTypeUnsignedShort;
5503 case clang::BuiltinType::Int:
5504 return eBasicTypeInt;
5505 case clang::BuiltinType::UInt:
5506 return eBasicTypeUnsignedInt;
5507 case clang::BuiltinType::Long:
5508 return eBasicTypeLong;
5509 case clang::BuiltinType::ULong:
5510 return eBasicTypeUnsignedLong;
5511 case clang::BuiltinType::LongLong:
5512 return eBasicTypeLongLong;
5513 case clang::BuiltinType::ULongLong:
5514 return eBasicTypeUnsignedLongLong;
5515 case clang::BuiltinType::Int128:
5516 return eBasicTypeInt128;
5517 case clang::BuiltinType::UInt128:
5518 return eBasicTypeUnsignedInt128;
5519
5520 case clang::BuiltinType::Half:
5521 return eBasicTypeHalf;
5522 case clang::BuiltinType::Float:
5523 return eBasicTypeFloat;
5524 case clang::BuiltinType::Double:
5525 return eBasicTypeDouble;
5526 case clang::BuiltinType::LongDouble:
5527 return eBasicTypeLongDouble;
5528
5529 case clang::BuiltinType::NullPtr:
5530 return eBasicTypeNullPtr;
5531 case clang::BuiltinType::ObjCId:
5532 return eBasicTypeObjCID;
5533 case clang::BuiltinType::ObjCClass:
5534 return eBasicTypeObjCClass;
5535 case clang::BuiltinType::ObjCSel:
5536 return eBasicTypeObjCSel;
5537 default:
5538 return eBasicTypeOther;
5539 }
5540 }
5541 }
5542 return eBasicTypeInvalid;
5543}
5544
5545void TypeSystemClang::ForEachEnumerator(
5546 lldb::opaque_compiler_type_t type,
5547 std::function<bool(const CompilerType &integer_type,
5548 ConstString name,
5549 const llvm::APSInt &value)> const &callback) {
5550 const clang::EnumType *enum_type =
5551 llvm::dyn_cast<clang::EnumType>(Val: GetCanonicalQualType(type));
5552 if (enum_type) {
5553 const clang::EnumDecl *enum_decl = enum_type->getDecl();
5554 if (enum_decl) {
5555 CompilerType integer_type = GetType(qt: enum_decl->getIntegerType());
5556
5557 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
5558 for (enum_pos = enum_decl->enumerator_begin(),
5559 enum_end_pos = enum_decl->enumerator_end();
5560 enum_pos != enum_end_pos; ++enum_pos) {
5561 ConstString name(enum_pos->getNameAsString().c_str());
5562 if (!callback(integer_type, name, enum_pos->getInitVal()))
5563 break;
5564 }
5565 }
5566 }
5567}
5568
5569#pragma mark Aggregate Types
5570
5571uint32_t TypeSystemClang::GetNumFields(lldb::opaque_compiler_type_t type) {
5572 if (!type)
5573 return 0;
5574
5575 uint32_t count = 0;
5576 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
5577 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5578 switch (type_class) {
5579 case clang::Type::Record:
5580 if (GetCompleteType(type)) {
5581 const clang::RecordType *record_type =
5582 llvm::dyn_cast<clang::RecordType>(Val: qual_type.getTypePtr());
5583 if (record_type) {
5584 clang::RecordDecl *record_decl = record_type->getDecl();
5585 if (record_decl) {
5586 count = std::distance(first: record_decl->field_begin(),
5587 last: record_decl->field_end());
5588 }
5589 }
5590 }
5591 break;
5592
5593 case clang::Type::ObjCObjectPointer: {
5594 const clang::ObjCObjectPointerType *objc_class_type =
5595 qual_type->castAs<clang::ObjCObjectPointerType>();
5596 const clang::ObjCInterfaceType *objc_interface_type =
5597 objc_class_type->getInterfaceType();
5598 if (objc_interface_type &&
5599 GetCompleteType(type: static_cast<lldb::opaque_compiler_type_t>(
5600 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
5601 clang::ObjCInterfaceDecl *class_interface_decl =
5602 objc_interface_type->getDecl();
5603 if (class_interface_decl) {
5604 count = class_interface_decl->ivar_size();
5605 }
5606 }
5607 break;
5608 }
5609
5610 case clang::Type::ObjCObject:
5611 case clang::Type::ObjCInterface:
5612 if (GetCompleteType(type)) {
5613 const clang::ObjCObjectType *objc_class_type =
5614 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
5615 if (objc_class_type) {
5616 clang::ObjCInterfaceDecl *class_interface_decl =
5617 objc_class_type->getInterface();
5618
5619 if (class_interface_decl)
5620 count = class_interface_decl->ivar_size();
5621 }
5622 }
5623 break;
5624
5625 default:
5626 break;
5627 }
5628 return count;
5629}
5630
5631static lldb::opaque_compiler_type_t
5632GetObjCFieldAtIndex(clang::ASTContext *ast,
5633 clang::ObjCInterfaceDecl *class_interface_decl, size_t idx,
5634 std::string &name, uint64_t *bit_offset_ptr,
5635 uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) {
5636 if (class_interface_decl) {
5637 if (idx < (class_interface_decl->ivar_size())) {
5638 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
5639 ivar_end = class_interface_decl->ivar_end();
5640 uint32_t ivar_idx = 0;
5641
5642 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end;
5643 ++ivar_pos, ++ivar_idx) {
5644 if (ivar_idx == idx) {
5645 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
5646
5647 clang::QualType ivar_qual_type(ivar_decl->getType());
5648
5649 name.assign(str: ivar_decl->getNameAsString());
5650
5651 if (bit_offset_ptr) {
5652 const clang::ASTRecordLayout &interface_layout =
5653 ast->getASTObjCInterfaceLayout(D: class_interface_decl);
5654 *bit_offset_ptr = interface_layout.getFieldOffset(FieldNo: ivar_idx);
5655 }
5656
5657 const bool is_bitfield = ivar_pos->isBitField();
5658
5659 if (bitfield_bit_size_ptr) {
5660 *bitfield_bit_size_ptr = 0;
5661
5662 if (is_bitfield && ast) {
5663 clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
5664 clang::Expr::EvalResult result;
5665 if (bitfield_bit_size_expr &&
5666 bitfield_bit_size_expr->EvaluateAsInt(Result&: result, Ctx: *ast)) {
5667 llvm::APSInt bitfield_apsint = result.Val.getInt();
5668 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
5669 }
5670 }
5671 }
5672 if (is_bitfield_ptr)
5673 *is_bitfield_ptr = is_bitfield;
5674
5675 return ivar_qual_type.getAsOpaquePtr();
5676 }
5677 }
5678 }
5679 }
5680 return nullptr;
5681}
5682
5683CompilerType TypeSystemClang::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
5684 size_t idx, std::string &name,
5685 uint64_t *bit_offset_ptr,
5686 uint32_t *bitfield_bit_size_ptr,
5687 bool *is_bitfield_ptr) {
5688 if (!type)
5689 return CompilerType();
5690
5691 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
5692 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5693 switch (type_class) {
5694 case clang::Type::Record:
5695 if (GetCompleteType(type)) {
5696 const clang::RecordType *record_type =
5697 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
5698 const clang::RecordDecl *record_decl = record_type->getDecl();
5699 uint32_t field_idx = 0;
5700 clang::RecordDecl::field_iterator field, field_end;
5701 for (field = record_decl->field_begin(),
5702 field_end = record_decl->field_end();
5703 field != field_end; ++field, ++field_idx) {
5704 if (idx == field_idx) {
5705 // Print the member type if requested
5706 // Print the member name and equal sign
5707 name.assign(str: field->getNameAsString());
5708
5709 // Figure out the type byte size (field_type_info.first) and
5710 // alignment (field_type_info.second) from the AST context.
5711 if (bit_offset_ptr) {
5712 const clang::ASTRecordLayout &record_layout =
5713 getASTContext().getASTRecordLayout(D: record_decl);
5714 *bit_offset_ptr = record_layout.getFieldOffset(FieldNo: field_idx);
5715 }
5716
5717 const bool is_bitfield = field->isBitField();
5718
5719 if (bitfield_bit_size_ptr) {
5720 *bitfield_bit_size_ptr = 0;
5721
5722 if (is_bitfield) {
5723 clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
5724 clang::Expr::EvalResult result;
5725 if (bitfield_bit_size_expr &&
5726 bitfield_bit_size_expr->EvaluateAsInt(Result&: result,
5727 Ctx: getASTContext())) {
5728 llvm::APSInt bitfield_apsint = result.Val.getInt();
5729 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
5730 }
5731 }
5732 }
5733 if (is_bitfield_ptr)
5734 *is_bitfield_ptr = is_bitfield;
5735
5736 return GetType(qt: field->getType());
5737 }
5738 }
5739 }
5740 break;
5741
5742 case clang::Type::ObjCObjectPointer: {
5743 const clang::ObjCObjectPointerType *objc_class_type =
5744 qual_type->castAs<clang::ObjCObjectPointerType>();
5745 const clang::ObjCInterfaceType *objc_interface_type =
5746 objc_class_type->getInterfaceType();
5747 if (objc_interface_type &&
5748 GetCompleteType(type: static_cast<lldb::opaque_compiler_type_t>(
5749 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
5750 clang::ObjCInterfaceDecl *class_interface_decl =
5751 objc_interface_type->getDecl();
5752 if (class_interface_decl) {
5753 return CompilerType(
5754 weak_from_this(),
5755 GetObjCFieldAtIndex(ast: &getASTContext(), class_interface_decl, idx,
5756 name, bit_offset_ptr, bitfield_bit_size_ptr,
5757 is_bitfield_ptr));
5758 }
5759 }
5760 break;
5761 }
5762
5763 case clang::Type::ObjCObject:
5764 case clang::Type::ObjCInterface:
5765 if (GetCompleteType(type)) {
5766 const clang::ObjCObjectType *objc_class_type =
5767 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
5768 assert(objc_class_type);
5769 if (objc_class_type) {
5770 clang::ObjCInterfaceDecl *class_interface_decl =
5771 objc_class_type->getInterface();
5772 return CompilerType(
5773 weak_from_this(),
5774 GetObjCFieldAtIndex(ast: &getASTContext(), class_interface_decl, idx,
5775 name, bit_offset_ptr, bitfield_bit_size_ptr,
5776 is_bitfield_ptr));
5777 }
5778 }
5779 break;
5780
5781 default:
5782 break;
5783 }
5784 return CompilerType();
5785}
5786
5787uint32_t
5788TypeSystemClang::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) {
5789 uint32_t count = 0;
5790 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5791 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5792 switch (type_class) {
5793 case clang::Type::Record:
5794 if (GetCompleteType(type)) {
5795 const clang::CXXRecordDecl *cxx_record_decl =
5796 qual_type->getAsCXXRecordDecl();
5797 if (cxx_record_decl)
5798 count = cxx_record_decl->getNumBases();
5799 }
5800 break;
5801
5802 case clang::Type::ObjCObjectPointer:
5803 count = GetPointeeType(type).GetNumDirectBaseClasses();
5804 break;
5805
5806 case clang::Type::ObjCObject:
5807 if (GetCompleteType(type)) {
5808 const clang::ObjCObjectType *objc_class_type =
5809 qual_type->getAsObjCQualifiedInterfaceType();
5810 if (objc_class_type) {
5811 clang::ObjCInterfaceDecl *class_interface_decl =
5812 objc_class_type->getInterface();
5813
5814 if (class_interface_decl && class_interface_decl->getSuperClass())
5815 count = 1;
5816 }
5817 }
5818 break;
5819 case clang::Type::ObjCInterface:
5820 if (GetCompleteType(type)) {
5821 const clang::ObjCInterfaceType *objc_interface_type =
5822 qual_type->getAs<clang::ObjCInterfaceType>();
5823 if (objc_interface_type) {
5824 clang::ObjCInterfaceDecl *class_interface_decl =
5825 objc_interface_type->getInterface();
5826
5827 if (class_interface_decl && class_interface_decl->getSuperClass())
5828 count = 1;
5829 }
5830 }
5831 break;
5832
5833 default:
5834 break;
5835 }
5836 return count;
5837}
5838
5839uint32_t
5840TypeSystemClang::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) {
5841 uint32_t count = 0;
5842 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5843 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5844 switch (type_class) {
5845 case clang::Type::Record:
5846 if (GetCompleteType(type)) {
5847 const clang::CXXRecordDecl *cxx_record_decl =
5848 qual_type->getAsCXXRecordDecl();
5849 if (cxx_record_decl)
5850 count = cxx_record_decl->getNumVBases();
5851 }
5852 break;
5853
5854 default:
5855 break;
5856 }
5857 return count;
5858}
5859
5860CompilerType TypeSystemClang::GetDirectBaseClassAtIndex(
5861 lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
5862 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5863 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5864 switch (type_class) {
5865 case clang::Type::Record:
5866 if (GetCompleteType(type)) {
5867 const clang::CXXRecordDecl *cxx_record_decl =
5868 qual_type->getAsCXXRecordDecl();
5869 if (cxx_record_decl) {
5870 uint32_t curr_idx = 0;
5871 clang::CXXRecordDecl::base_class_const_iterator base_class,
5872 base_class_end;
5873 for (base_class = cxx_record_decl->bases_begin(),
5874 base_class_end = cxx_record_decl->bases_end();
5875 base_class != base_class_end; ++base_class, ++curr_idx) {
5876 if (curr_idx == idx) {
5877 if (bit_offset_ptr) {
5878 const clang::ASTRecordLayout &record_layout =
5879 getASTContext().getASTRecordLayout(D: cxx_record_decl);
5880 const clang::CXXRecordDecl *base_class_decl =
5881 llvm::cast<clang::CXXRecordDecl>(
5882 Val: base_class->getType()
5883 ->castAs<clang::RecordType>()
5884 ->getDecl());
5885 if (base_class->isVirtual())
5886 *bit_offset_ptr =
5887 record_layout.getVBaseClassOffset(VBase: base_class_decl)
5888 .getQuantity() *
5889 8;
5890 else
5891 *bit_offset_ptr =
5892 record_layout.getBaseClassOffset(Base: base_class_decl)
5893 .getQuantity() *
5894 8;
5895 }
5896 return GetType(qt: base_class->getType());
5897 }
5898 }
5899 }
5900 }
5901 break;
5902
5903 case clang::Type::ObjCObjectPointer:
5904 return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr);
5905
5906 case clang::Type::ObjCObject:
5907 if (idx == 0 && GetCompleteType(type)) {
5908 const clang::ObjCObjectType *objc_class_type =
5909 qual_type->getAsObjCQualifiedInterfaceType();
5910 if (objc_class_type) {
5911 clang::ObjCInterfaceDecl *class_interface_decl =
5912 objc_class_type->getInterface();
5913
5914 if (class_interface_decl) {
5915 clang::ObjCInterfaceDecl *superclass_interface_decl =
5916 class_interface_decl->getSuperClass();
5917 if (superclass_interface_decl) {
5918 if (bit_offset_ptr)
5919 *bit_offset_ptr = 0;
5920 return GetType(qt: getASTContext().getObjCInterfaceType(
5921 Decl: superclass_interface_decl));
5922 }
5923 }
5924 }
5925 }
5926 break;
5927 case clang::Type::ObjCInterface:
5928 if (idx == 0 && GetCompleteType(type)) {
5929 const clang::ObjCObjectType *objc_interface_type =
5930 qual_type->getAs<clang::ObjCInterfaceType>();
5931 if (objc_interface_type) {
5932 clang::ObjCInterfaceDecl *class_interface_decl =
5933 objc_interface_type->getInterface();
5934
5935 if (class_interface_decl) {
5936 clang::ObjCInterfaceDecl *superclass_interface_decl =
5937 class_interface_decl->getSuperClass();
5938 if (superclass_interface_decl) {
5939 if (bit_offset_ptr)
5940 *bit_offset_ptr = 0;
5941 return GetType(qt: getASTContext().getObjCInterfaceType(
5942 Decl: superclass_interface_decl));
5943 }
5944 }
5945 }
5946 }
5947 break;
5948
5949 default:
5950 break;
5951 }
5952 return CompilerType();
5953}
5954
5955CompilerType TypeSystemClang::GetVirtualBaseClassAtIndex(
5956 lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
5957 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5958 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5959 switch (type_class) {
5960 case clang::Type::Record:
5961 if (GetCompleteType(type)) {
5962 const clang::CXXRecordDecl *cxx_record_decl =
5963 qual_type->getAsCXXRecordDecl();
5964 if (cxx_record_decl) {
5965 uint32_t curr_idx = 0;
5966 clang::CXXRecordDecl::base_class_const_iterator base_class,
5967 base_class_end;
5968 for (base_class = cxx_record_decl->vbases_begin(),
5969 base_class_end = cxx_record_decl->vbases_end();
5970 base_class != base_class_end; ++base_class, ++curr_idx) {
5971 if (curr_idx == idx) {
5972 if (bit_offset_ptr) {
5973 const clang::ASTRecordLayout &record_layout =
5974 getASTContext().getASTRecordLayout(D: cxx_record_decl);
5975 const clang::CXXRecordDecl *base_class_decl =
5976 llvm::cast<clang::CXXRecordDecl>(
5977 Val: base_class->getType()
5978 ->castAs<clang::RecordType>()
5979 ->getDecl());
5980 *bit_offset_ptr =
5981 record_layout.getVBaseClassOffset(VBase: base_class_decl)
5982 .getQuantity() *
5983 8;
5984 }
5985 return GetType(qt: base_class->getType());
5986 }
5987 }
5988 }
5989 }
5990 break;
5991
5992 default:
5993 break;
5994 }
5995 return CompilerType();
5996}
5997
5998CompilerDecl
5999TypeSystemClang::GetStaticFieldWithName(lldb::opaque_compiler_type_t type,
6000 llvm::StringRef name) {
6001 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
6002 switch (qual_type->getTypeClass()) {
6003 case clang::Type::Record: {
6004 if (!GetCompleteType(type))
6005 return CompilerDecl();
6006
6007 const clang::RecordType *record_type =
6008 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
6009 const clang::RecordDecl *record_decl = record_type->getDecl();
6010
6011 clang::DeclarationName decl_name(&getASTContext().Idents.get(Name: name));
6012 for (NamedDecl *decl : record_decl->lookup(Name: decl_name)) {
6013 auto *var_decl = dyn_cast<clang::VarDecl>(Val: decl);
6014 if (!var_decl || var_decl->getStorageClass() != clang::SC_Static)
6015 continue;
6016
6017 return CompilerDecl(this, var_decl);
6018 }
6019 break;
6020 }
6021
6022 default:
6023 break;
6024 }
6025 return CompilerDecl();
6026}
6027
6028// If a pointer to a pointee type (the clang_type arg) says that it has no
6029// children, then we either need to trust it, or override it and return a
6030// different result. For example, an "int *" has one child that is an integer,
6031// but a function pointer doesn't have any children. Likewise if a Record type
6032// claims it has no children, then there really is nothing to show.
6033uint32_t TypeSystemClang::GetNumPointeeChildren(clang::QualType type) {
6034 if (type.isNull())
6035 return 0;
6036
6037 clang::QualType qual_type = RemoveWrappingTypes(type: type.getCanonicalType());
6038 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6039 switch (type_class) {
6040 case clang::Type::Builtin:
6041 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
6042 case clang::BuiltinType::UnknownAny:
6043 case clang::BuiltinType::Void:
6044 case clang::BuiltinType::NullPtr:
6045 case clang::BuiltinType::OCLEvent:
6046 case clang::BuiltinType::OCLImage1dRO:
6047 case clang::BuiltinType::OCLImage1dWO:
6048 case clang::BuiltinType::OCLImage1dRW:
6049 case clang::BuiltinType::OCLImage1dArrayRO:
6050 case clang::BuiltinType::OCLImage1dArrayWO:
6051 case clang::BuiltinType::OCLImage1dArrayRW:
6052 case clang::BuiltinType::OCLImage1dBufferRO:
6053 case clang::BuiltinType::OCLImage1dBufferWO:
6054 case clang::BuiltinType::OCLImage1dBufferRW:
6055 case clang::BuiltinType::OCLImage2dRO:
6056 case clang::BuiltinType::OCLImage2dWO:
6057 case clang::BuiltinType::OCLImage2dRW:
6058 case clang::BuiltinType::OCLImage2dArrayRO:
6059 case clang::BuiltinType::OCLImage2dArrayWO:
6060 case clang::BuiltinType::OCLImage2dArrayRW:
6061 case clang::BuiltinType::OCLImage3dRO:
6062 case clang::BuiltinType::OCLImage3dWO:
6063 case clang::BuiltinType::OCLImage3dRW:
6064 case clang::BuiltinType::OCLSampler:
6065 case clang::BuiltinType::HLSLResource:
6066 return 0;
6067 case clang::BuiltinType::Bool:
6068 case clang::BuiltinType::Char_U:
6069 case clang::BuiltinType::UChar:
6070 case clang::BuiltinType::WChar_U:
6071 case clang::BuiltinType::Char16:
6072 case clang::BuiltinType::Char32:
6073 case clang::BuiltinType::UShort:
6074 case clang::BuiltinType::UInt:
6075 case clang::BuiltinType::ULong:
6076 case clang::BuiltinType::ULongLong:
6077 case clang::BuiltinType::UInt128:
6078 case clang::BuiltinType::Char_S:
6079 case clang::BuiltinType::SChar:
6080 case clang::BuiltinType::WChar_S:
6081 case clang::BuiltinType::Short:
6082 case clang::BuiltinType::Int:
6083 case clang::BuiltinType::Long:
6084 case clang::BuiltinType::LongLong:
6085 case clang::BuiltinType::Int128:
6086 case clang::BuiltinType::Float:
6087 case clang::BuiltinType::Double:
6088 case clang::BuiltinType::LongDouble:
6089 case clang::BuiltinType::Dependent:
6090 case clang::BuiltinType::Overload:
6091 case clang::BuiltinType::ObjCId:
6092 case clang::BuiltinType::ObjCClass:
6093 case clang::BuiltinType::ObjCSel:
6094 case clang::BuiltinType::BoundMember:
6095 case clang::BuiltinType::Half:
6096 case clang::BuiltinType::ARCUnbridgedCast:
6097 case clang::BuiltinType::PseudoObject:
6098 case clang::BuiltinType::BuiltinFn:
6099 case clang::BuiltinType::ArraySection:
6100 return 1;
6101 default:
6102 return 0;
6103 }
6104 break;
6105
6106 case clang::Type::Complex:
6107 return 1;
6108 case clang::Type::Pointer:
6109 return 1;
6110 case clang::Type::BlockPointer:
6111 return 0; // If block pointers don't have debug info, then no children for
6112 // them
6113 case clang::Type::LValueReference:
6114 return 1;
6115 case clang::Type::RValueReference:
6116 return 1;
6117 case clang::Type::MemberPointer:
6118 return 0;
6119 case clang::Type::ConstantArray:
6120 return 0;
6121 case clang::Type::IncompleteArray:
6122 return 0;
6123 case clang::Type::VariableArray:
6124 return 0;
6125 case clang::Type::DependentSizedArray:
6126 return 0;
6127 case clang::Type::DependentSizedExtVector:
6128 return 0;
6129 case clang::Type::Vector:
6130 return 0;
6131 case clang::Type::ExtVector:
6132 return 0;
6133 case clang::Type::FunctionProto:
6134 return 0; // When we function pointers, they have no children...
6135 case clang::Type::FunctionNoProto:
6136 return 0; // When we function pointers, they have no children...
6137 case clang::Type::UnresolvedUsing:
6138 return 0;
6139 case clang::Type::Record:
6140 return 0;
6141 case clang::Type::Enum:
6142 return 1;
6143 case clang::Type::TemplateTypeParm:
6144 return 1;
6145 case clang::Type::SubstTemplateTypeParm:
6146 return 1;
6147 case clang::Type::TemplateSpecialization:
6148 return 1;
6149 case clang::Type::InjectedClassName:
6150 return 0;
6151 case clang::Type::DependentName:
6152 return 1;
6153 case clang::Type::DependentTemplateSpecialization:
6154 return 1;
6155 case clang::Type::ObjCObject:
6156 return 0;
6157 case clang::Type::ObjCInterface:
6158 return 0;
6159 case clang::Type::ObjCObjectPointer:
6160 return 1;
6161 default:
6162 break;
6163 }
6164 return 0;
6165}
6166
6167llvm::Expected<CompilerType> TypeSystemClang::GetDereferencedType(
6168 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
6169 std::string &deref_name, uint32_t &deref_byte_size,
6170 int32_t &deref_byte_offset, ValueObject *valobj, uint64_t &language_flags) {
6171 bool type_valid = IsPointerOrReferenceType(type, pointee_type: nullptr) ||
6172 IsArrayType(type, element_type_ptr: nullptr, size: nullptr, is_incomplete: nullptr);
6173 if (!type_valid)
6174 return llvm::createStringError(Fmt: "not a pointer, reference or array type");
6175 uint32_t child_bitfield_bit_size = 0;
6176 uint32_t child_bitfield_bit_offset = 0;
6177 bool child_is_base_class;
6178 bool child_is_deref_of_parent;
6179 return GetChildCompilerTypeAtIndex(
6180 type, exe_ctx, idx: 0, transparent_pointers: false, omit_empty_base_classes: true, ignore_array_bounds: false, child_name&: deref_name, child_byte_size&: deref_byte_size,
6181 child_byte_offset&: deref_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
6182 child_is_base_class, child_is_deref_of_parent, valobj, language_flags);
6183}
6184
6185llvm::Expected<CompilerType> TypeSystemClang::GetChildCompilerTypeAtIndex(
6186 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
6187 bool transparent_pointers, bool omit_empty_base_classes,
6188 bool ignore_array_bounds, std::string &child_name,
6189 uint32_t &child_byte_size, int32_t &child_byte_offset,
6190 uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
6191 bool &child_is_base_class, bool &child_is_deref_of_parent,
6192 ValueObject *valobj, uint64_t &language_flags) {
6193 if (!type)
6194 return CompilerType();
6195
6196 auto get_exe_scope = [&exe_ctx]() {
6197 return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
6198 };
6199
6200 clang::QualType parent_qual_type(
6201 RemoveWrappingTypes(type: GetCanonicalQualType(type)));
6202 const clang::Type::TypeClass parent_type_class =
6203 parent_qual_type->getTypeClass();
6204 child_bitfield_bit_size = 0;
6205 child_bitfield_bit_offset = 0;
6206 child_is_base_class = false;
6207 language_flags = 0;
6208
6209 auto num_children_or_err =
6210 GetNumChildren(type, omit_empty_base_classes, exe_ctx);
6211 if (!num_children_or_err)
6212 return num_children_or_err.takeError();
6213
6214 const bool idx_is_valid = idx < *num_children_or_err;
6215 int32_t bit_offset;
6216 switch (parent_type_class) {
6217 case clang::Type::Builtin:
6218 if (idx_is_valid) {
6219 switch (llvm::cast<clang::BuiltinType>(Val&: parent_qual_type)->getKind()) {
6220 case clang::BuiltinType::ObjCId:
6221 case clang::BuiltinType::ObjCClass:
6222 child_name = "isa";
6223 child_byte_size =
6224 getASTContext().getTypeSize(T: getASTContext().ObjCBuiltinClassTy) /
6225 CHAR_BIT;
6226 return GetType(qt: getASTContext().ObjCBuiltinClassTy);
6227
6228 default:
6229 break;
6230 }
6231 }
6232 break;
6233
6234 case clang::Type::Record:
6235 if (idx_is_valid && GetCompleteType(type)) {
6236 const clang::RecordType *record_type =
6237 llvm::cast<clang::RecordType>(Val: parent_qual_type.getTypePtr());
6238 const clang::RecordDecl *record_decl = record_type->getDecl();
6239 assert(record_decl);
6240 const clang::ASTRecordLayout &record_layout =
6241 getASTContext().getASTRecordLayout(D: record_decl);
6242 uint32_t child_idx = 0;
6243
6244 const clang::CXXRecordDecl *cxx_record_decl =
6245 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
6246 if (cxx_record_decl) {
6247 // We might have base classes to print out first
6248 clang::CXXRecordDecl::base_class_const_iterator base_class,
6249 base_class_end;
6250 for (base_class = cxx_record_decl->bases_begin(),
6251 base_class_end = cxx_record_decl->bases_end();
6252 base_class != base_class_end; ++base_class) {
6253 const clang::CXXRecordDecl *base_class_decl = nullptr;
6254
6255 // Skip empty base classes
6256 if (omit_empty_base_classes) {
6257 base_class_decl = llvm::cast<clang::CXXRecordDecl>(
6258 Val: base_class->getType()->getAs<clang::RecordType>()->getDecl());
6259 if (!TypeSystemClang::RecordHasFields(record_decl: base_class_decl))
6260 continue;
6261 }
6262
6263 if (idx == child_idx) {
6264 if (base_class_decl == nullptr)
6265 base_class_decl = llvm::cast<clang::CXXRecordDecl>(
6266 Val: base_class->getType()->getAs<clang::RecordType>()->getDecl());
6267
6268 if (base_class->isVirtual()) {
6269 bool handled = false;
6270 if (valobj) {
6271 clang::VTableContextBase *vtable_ctx =
6272 getASTContext().getVTableContext();
6273 if (vtable_ctx)
6274 handled = GetVBaseBitOffset(vtable_ctx&: *vtable_ctx, valobj&: *valobj,
6275 record_layout, cxx_record_decl,
6276 base_class_decl, bit_offset);
6277 }
6278 if (!handled)
6279 bit_offset = record_layout.getVBaseClassOffset(VBase: base_class_decl)
6280 .getQuantity() *
6281 8;
6282 } else
6283 bit_offset = record_layout.getBaseClassOffset(Base: base_class_decl)
6284 .getQuantity() *
6285 8;
6286
6287 // Base classes should be a multiple of 8 bits in size
6288 child_byte_offset = bit_offset / 8;
6289 CompilerType base_class_clang_type = GetType(qt: base_class->getType());
6290 child_name = base_class_clang_type.GetTypeName().AsCString(value_if_empty: "");
6291 auto size_or_err =
6292 base_class_clang_type.GetBitSize(exe_scope: get_exe_scope());
6293 if (!size_or_err)
6294 return llvm::joinErrors(
6295 E1: llvm::createStringError(Fmt: "no size info for base class"),
6296 E2: size_or_err.takeError());
6297
6298 uint64_t base_class_clang_type_bit_size = *size_or_err;
6299
6300 // Base classes bit sizes should be a multiple of 8 bits in size
6301 assert(base_class_clang_type_bit_size % 8 == 0);
6302 child_byte_size = base_class_clang_type_bit_size / 8;
6303 child_is_base_class = true;
6304 return base_class_clang_type;
6305 }
6306 // We don't increment the child index in the for loop since we might
6307 // be skipping empty base classes
6308 ++child_idx;
6309 }
6310 }
6311 // Make sure index is in range...
6312 uint32_t field_idx = 0;
6313 clang::RecordDecl::field_iterator field, field_end;
6314 for (field = record_decl->field_begin(),
6315 field_end = record_decl->field_end();
6316 field != field_end; ++field, ++field_idx, ++child_idx) {
6317 if (idx == child_idx) {
6318 // Print the member type if requested
6319 // Print the member name and equal sign
6320 child_name.assign(str: field->getNameAsString());
6321
6322 // Figure out the type byte size (field_type_info.first) and
6323 // alignment (field_type_info.second) from the AST context.
6324 CompilerType field_clang_type = GetType(qt: field->getType());
6325 assert(field_idx < record_layout.getFieldCount());
6326 auto size_or_err = field_clang_type.GetByteSize(exe_scope: get_exe_scope());
6327 if (!size_or_err)
6328 return llvm::joinErrors(
6329 E1: llvm::createStringError(Fmt: "no size info for field"),
6330 E2: size_or_err.takeError());
6331
6332 child_byte_size = *size_or_err;
6333 const uint32_t child_bit_size = child_byte_size * 8;
6334
6335 // Figure out the field offset within the current struct/union/class
6336 // type
6337 bit_offset = record_layout.getFieldOffset(FieldNo: field_idx);
6338 if (FieldIsBitfield(field: *field, bitfield_bit_size&: child_bitfield_bit_size)) {
6339 child_bitfield_bit_offset = bit_offset % child_bit_size;
6340 const uint32_t child_bit_offset =
6341 bit_offset - child_bitfield_bit_offset;
6342 child_byte_offset = child_bit_offset / 8;
6343 } else {
6344 child_byte_offset = bit_offset / 8;
6345 }
6346
6347 return field_clang_type;
6348 }
6349 }
6350 }
6351 break;
6352
6353 case clang::Type::ObjCObject:
6354 case clang::Type::ObjCInterface:
6355 if (idx_is_valid && GetCompleteType(type)) {
6356 const clang::ObjCObjectType *objc_class_type =
6357 llvm::dyn_cast<clang::ObjCObjectType>(Val: parent_qual_type.getTypePtr());
6358 assert(objc_class_type);
6359 if (objc_class_type) {
6360 uint32_t child_idx = 0;
6361 clang::ObjCInterfaceDecl *class_interface_decl =
6362 objc_class_type->getInterface();
6363
6364 if (class_interface_decl) {
6365
6366 const clang::ASTRecordLayout &interface_layout =
6367 getASTContext().getASTObjCInterfaceLayout(D: class_interface_decl);
6368 clang::ObjCInterfaceDecl *superclass_interface_decl =
6369 class_interface_decl->getSuperClass();
6370 if (superclass_interface_decl) {
6371 if (omit_empty_base_classes) {
6372 CompilerType base_class_clang_type =
6373 GetType(qt: getASTContext().getObjCInterfaceType(
6374 Decl: superclass_interface_decl));
6375 if (llvm::expectedToStdOptional(
6376 E: base_class_clang_type.GetNumChildren(
6377 omit_empty_base_classes, exe_ctx))
6378 .value_or(u: 0) > 0) {
6379 if (idx == 0) {
6380 clang::QualType ivar_qual_type(
6381 getASTContext().getObjCInterfaceType(
6382 Decl: superclass_interface_decl));
6383
6384 child_name.assign(
6385 str: superclass_interface_decl->getNameAsString());
6386
6387 clang::TypeInfo ivar_type_info =
6388 getASTContext().getTypeInfo(T: ivar_qual_type.getTypePtr());
6389
6390 child_byte_size = ivar_type_info.Width / 8;
6391 child_byte_offset = 0;
6392 child_is_base_class = true;
6393
6394 return GetType(qt: ivar_qual_type);
6395 }
6396
6397 ++child_idx;
6398 }
6399 } else
6400 ++child_idx;
6401 }
6402
6403 const uint32_t superclass_idx = child_idx;
6404
6405 if (idx < (child_idx + class_interface_decl->ivar_size())) {
6406 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
6407 ivar_end = class_interface_decl->ivar_end();
6408
6409 for (ivar_pos = class_interface_decl->ivar_begin();
6410 ivar_pos != ivar_end; ++ivar_pos) {
6411 if (child_idx == idx) {
6412 clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
6413
6414 clang::QualType ivar_qual_type(ivar_decl->getType());
6415
6416 child_name.assign(str: ivar_decl->getNameAsString());
6417
6418 clang::TypeInfo ivar_type_info =
6419 getASTContext().getTypeInfo(T: ivar_qual_type.getTypePtr());
6420
6421 child_byte_size = ivar_type_info.Width / 8;
6422
6423 // Figure out the field offset within the current
6424 // struct/union/class type For ObjC objects, we can't trust the
6425 // bit offset we get from the Clang AST, since that doesn't
6426 // account for the space taken up by unbacked properties, or
6427 // from the changing size of base classes that are newer than
6428 // this class. So if we have a process around that we can ask
6429 // about this object, do so.
6430 child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
6431 Process *process = nullptr;
6432 if (exe_ctx)
6433 process = exe_ctx->GetProcessPtr();
6434 if (process) {
6435 ObjCLanguageRuntime *objc_runtime =
6436 ObjCLanguageRuntime::Get(process&: *process);
6437 if (objc_runtime != nullptr) {
6438 CompilerType parent_ast_type = GetType(qt: parent_qual_type);
6439 child_byte_offset = objc_runtime->GetByteOffsetForIvar(
6440 parent_qual_type&: parent_ast_type, ivar_name: ivar_decl->getNameAsString().c_str());
6441 }
6442 }
6443
6444 // Setting this to INT32_MAX to make sure we don't compute it
6445 // twice...
6446 bit_offset = INT32_MAX;
6447
6448 if (child_byte_offset ==
6449 static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET)) {
6450 bit_offset = interface_layout.getFieldOffset(FieldNo: child_idx -
6451 superclass_idx);
6452 child_byte_offset = bit_offset / 8;
6453 }
6454
6455 // Note, the ObjC Ivar Byte offset is just that, it doesn't
6456 // account for the bit offset of a bitfield within its
6457 // containing object. So regardless of where we get the byte
6458 // offset from, we still need to get the bit offset for
6459 // bitfields from the layout.
6460
6461 if (FieldIsBitfield(field: ivar_decl, bitfield_bit_size&: child_bitfield_bit_size)) {
6462 if (bit_offset == INT32_MAX)
6463 bit_offset = interface_layout.getFieldOffset(
6464 FieldNo: child_idx - superclass_idx);
6465
6466 child_bitfield_bit_offset = bit_offset % 8;
6467 }
6468 return GetType(qt: ivar_qual_type);
6469 }
6470 ++child_idx;
6471 }
6472 }
6473 }
6474 }
6475 }
6476 break;
6477
6478 case clang::Type::ObjCObjectPointer:
6479 if (idx_is_valid) {
6480 CompilerType pointee_clang_type(GetPointeeType(type));
6481
6482 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6483 child_is_deref_of_parent = false;
6484 bool tmp_child_is_deref_of_parent = false;
6485 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6486 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6487 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6488 child_bitfield_bit_size, child_bitfield_bit_offset,
6489 child_is_base_class, child_is_deref_of_parent&: tmp_child_is_deref_of_parent, valobj,
6490 language_flags);
6491 } else {
6492 child_is_deref_of_parent = true;
6493 const char *parent_name =
6494 valobj ? valobj->GetName().GetCString() : nullptr;
6495 if (parent_name) {
6496 child_name.assign(n: 1, c: '*');
6497 child_name += parent_name;
6498 }
6499
6500 // We have a pointer to an simple type
6501 if (idx == 0 && pointee_clang_type.GetCompleteType()) {
6502 auto size_or_err = pointee_clang_type.GetByteSize(exe_scope: get_exe_scope());
6503 if (!size_or_err)
6504 return size_or_err.takeError();
6505 child_byte_size = *size_or_err;
6506 child_byte_offset = 0;
6507 return pointee_clang_type;
6508 }
6509 }
6510 }
6511 break;
6512
6513 case clang::Type::Vector:
6514 case clang::Type::ExtVector:
6515 if (idx_is_valid) {
6516 const clang::VectorType *array =
6517 llvm::cast<clang::VectorType>(Val: parent_qual_type.getTypePtr());
6518 if (array) {
6519 CompilerType element_type = GetType(qt: array->getElementType());
6520 if (element_type.GetCompleteType()) {
6521 char element_name[64];
6522 ::snprintf(s: element_name, maxlen: sizeof(element_name), format: "[%" PRIu64 "]",
6523 static_cast<uint64_t>(idx));
6524 child_name.assign(s: element_name);
6525 auto size_or_err = element_type.GetByteSize(exe_scope: get_exe_scope());
6526 if (!size_or_err)
6527 return size_or_err.takeError();
6528 child_byte_size = *size_or_err;
6529 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
6530 return element_type;
6531 }
6532 }
6533 }
6534 break;
6535
6536 case clang::Type::ConstantArray:
6537 case clang::Type::IncompleteArray:
6538 if (ignore_array_bounds || idx_is_valid) {
6539 const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
6540 if (array) {
6541 CompilerType element_type = GetType(qt: array->getElementType());
6542 if (element_type.GetCompleteType()) {
6543 child_name = std::string(llvm::formatv(Fmt: "[{0}]", Vals&: idx));
6544 auto size_or_err = element_type.GetByteSize(exe_scope: get_exe_scope());
6545 if (!size_or_err)
6546 return size_or_err.takeError();
6547 child_byte_size = *size_or_err;
6548 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
6549 return element_type;
6550 }
6551 }
6552 }
6553 break;
6554
6555 case clang::Type::Pointer: {
6556 CompilerType pointee_clang_type(GetPointeeType(type));
6557
6558 // Don't dereference "void *" pointers
6559 if (pointee_clang_type.IsVoidType())
6560 return CompilerType();
6561
6562 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6563 child_is_deref_of_parent = false;
6564 bool tmp_child_is_deref_of_parent = false;
6565 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6566 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6567 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6568 child_bitfield_bit_size, child_bitfield_bit_offset,
6569 child_is_base_class, child_is_deref_of_parent&: tmp_child_is_deref_of_parent, valobj,
6570 language_flags);
6571 } else {
6572 child_is_deref_of_parent = true;
6573
6574 const char *parent_name =
6575 valobj ? valobj->GetName().GetCString() : nullptr;
6576 if (parent_name) {
6577 child_name.assign(n: 1, c: '*');
6578 child_name += parent_name;
6579 }
6580
6581 // We have a pointer to an simple type
6582 if (idx == 0) {
6583 auto size_or_err = pointee_clang_type.GetByteSize(exe_scope: get_exe_scope());
6584 if (!size_or_err)
6585 return size_or_err.takeError();
6586 child_byte_size = *size_or_err;
6587 child_byte_offset = 0;
6588 return pointee_clang_type;
6589 }
6590 }
6591 break;
6592 }
6593
6594 case clang::Type::LValueReference:
6595 case clang::Type::RValueReference:
6596 if (idx_is_valid) {
6597 const clang::ReferenceType *reference_type =
6598 llvm::cast<clang::ReferenceType>(
6599 Val: RemoveWrappingTypes(type: GetQualType(type)).getTypePtr());
6600 CompilerType pointee_clang_type =
6601 GetType(qt: reference_type->getPointeeType());
6602 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6603 child_is_deref_of_parent = false;
6604 bool tmp_child_is_deref_of_parent = false;
6605 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6606 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6607 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6608 child_bitfield_bit_size, child_bitfield_bit_offset,
6609 child_is_base_class, child_is_deref_of_parent&: tmp_child_is_deref_of_parent, valobj,
6610 language_flags);
6611 } else {
6612 const char *parent_name =
6613 valobj ? valobj->GetName().GetCString() : nullptr;
6614 if (parent_name) {
6615 child_name.assign(n: 1, c: '&');
6616 child_name += parent_name;
6617 }
6618
6619 // We have a pointer to an simple type
6620 if (idx == 0) {
6621 auto size_or_err = pointee_clang_type.GetByteSize(exe_scope: get_exe_scope());
6622 if (!size_or_err)
6623 return size_or_err.takeError();
6624 child_byte_size = *size_or_err;
6625 child_byte_offset = 0;
6626 return pointee_clang_type;
6627 }
6628 }
6629 }
6630 break;
6631
6632 default:
6633 break;
6634 }
6635 return CompilerType();
6636}
6637
6638uint32_t TypeSystemClang::GetIndexForRecordBase(
6639 const clang::RecordDecl *record_decl,
6640 const clang::CXXBaseSpecifier *base_spec,
6641 bool omit_empty_base_classes) {
6642 uint32_t child_idx = 0;
6643
6644 const clang::CXXRecordDecl *cxx_record_decl =
6645 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
6646
6647 if (cxx_record_decl) {
6648 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
6649 for (base_class = cxx_record_decl->bases_begin(),
6650 base_class_end = cxx_record_decl->bases_end();
6651 base_class != base_class_end; ++base_class) {
6652 if (omit_empty_base_classes) {
6653 if (BaseSpecifierIsEmpty(b: base_class))
6654 continue;
6655 }
6656
6657 if (base_class == base_spec)
6658 return child_idx;
6659 ++child_idx;
6660 }
6661 }
6662
6663 return UINT32_MAX;
6664}
6665
6666uint32_t TypeSystemClang::GetIndexForRecordChild(
6667 const clang::RecordDecl *record_decl, clang::NamedDecl *canonical_decl,
6668 bool omit_empty_base_classes) {
6669 uint32_t child_idx = TypeSystemClang::GetNumBaseClasses(
6670 cxx_record_decl: llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl),
6671 omit_empty_base_classes);
6672
6673 clang::RecordDecl::field_iterator field, field_end;
6674 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
6675 field != field_end; ++field, ++child_idx) {
6676 if (field->getCanonicalDecl() == canonical_decl)
6677 return child_idx;
6678 }
6679
6680 return UINT32_MAX;
6681}
6682
6683// Look for a child member (doesn't include base classes, but it does include
6684// their members) in the type hierarchy. Returns an index path into
6685// "clang_type" on how to reach the appropriate member.
6686//
6687// class A
6688// {
6689// public:
6690// int m_a;
6691// int m_b;
6692// };
6693//
6694// class B
6695// {
6696// };
6697//
6698// class C :
6699// public B,
6700// public A
6701// {
6702// };
6703//
6704// If we have a clang type that describes "class C", and we wanted to looked
6705// "m_b" in it:
6706//
6707// With omit_empty_base_classes == false we would get an integer array back
6708// with: { 1, 1 } The first index 1 is the child index for "class A" within
6709// class C The second index 1 is the child index for "m_b" within class A
6710//
6711// With omit_empty_base_classes == true we would get an integer array back
6712// with: { 0, 1 } The first index 0 is the child index for "class A" within
6713// class C (since class B doesn't have any members it doesn't count) The second
6714// index 1 is the child index for "m_b" within class A
6715
6716size_t TypeSystemClang::GetIndexOfChildMemberWithName(
6717 lldb::opaque_compiler_type_t type, llvm::StringRef name,
6718 bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
6719 if (type && !name.empty()) {
6720 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
6721 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6722 switch (type_class) {
6723 case clang::Type::Record:
6724 if (GetCompleteType(type)) {
6725 const clang::RecordType *record_type =
6726 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
6727 const clang::RecordDecl *record_decl = record_type->getDecl();
6728
6729 assert(record_decl);
6730 uint32_t child_idx = 0;
6731
6732 const clang::CXXRecordDecl *cxx_record_decl =
6733 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
6734
6735 // Try and find a field that matches NAME
6736 clang::RecordDecl::field_iterator field, field_end;
6737 for (field = record_decl->field_begin(),
6738 field_end = record_decl->field_end();
6739 field != field_end; ++field, ++child_idx) {
6740 llvm::StringRef field_name = field->getName();
6741 if (field_name.empty()) {
6742 CompilerType field_type = GetType(qt: field->getType());
6743 std::vector<uint32_t> save_indices = child_indexes;
6744 child_indexes.push_back(
6745 x: child_idx + TypeSystemClang::GetNumBaseClasses(
6746 cxx_record_decl, omit_empty_base_classes));
6747 if (field_type.GetIndexOfChildMemberWithName(
6748 name, omit_empty_base_classes, child_indexes))
6749 return child_indexes.size();
6750 child_indexes = std::move(save_indices);
6751 } else if (field_name == name) {
6752 // We have to add on the number of base classes to this index!
6753 child_indexes.push_back(
6754 x: child_idx + TypeSystemClang::GetNumBaseClasses(
6755 cxx_record_decl, omit_empty_base_classes));
6756 return child_indexes.size();
6757 }
6758 }
6759
6760 if (cxx_record_decl) {
6761 const clang::RecordDecl *parent_record_decl = cxx_record_decl;
6762
6763 // Didn't find things easily, lets let clang do its thang...
6764 clang::IdentifierInfo &ident_ref = getASTContext().Idents.get(Name: name);
6765 clang::DeclarationName decl_name(&ident_ref);
6766
6767 clang::CXXBasePaths paths;
6768 if (cxx_record_decl->lookupInBases(
6769 BaseMatches: [decl_name](const clang::CXXBaseSpecifier *specifier,
6770 clang::CXXBasePath &path) {
6771 CXXRecordDecl *record =
6772 specifier->getType()->getAsCXXRecordDecl();
6773 auto r = record->lookup(Name: decl_name);
6774 path.Decls = r.begin();
6775 return !r.empty();
6776 },
6777 Paths&: paths)) {
6778 clang::CXXBasePaths::const_paths_iterator path,
6779 path_end = paths.end();
6780 for (path = paths.begin(); path != path_end; ++path) {
6781 const size_t num_path_elements = path->size();
6782 for (size_t e = 0; e < num_path_elements; ++e) {
6783 clang::CXXBasePathElement elem = (*path)[e];
6784
6785 child_idx = GetIndexForRecordBase(record_decl: parent_record_decl, base_spec: elem.Base,
6786 omit_empty_base_classes);
6787 if (child_idx == UINT32_MAX) {
6788 child_indexes.clear();
6789 return 0;
6790 } else {
6791 child_indexes.push_back(x: child_idx);
6792 parent_record_decl = llvm::cast<clang::RecordDecl>(
6793 Val: elem.Base->getType()
6794 ->castAs<clang::RecordType>()
6795 ->getDecl());
6796 }
6797 }
6798 for (clang::DeclContext::lookup_iterator I = path->Decls, E;
6799 I != E; ++I) {
6800 child_idx = GetIndexForRecordChild(
6801 record_decl: parent_record_decl, canonical_decl: *I, omit_empty_base_classes);
6802 if (child_idx == UINT32_MAX) {
6803 child_indexes.clear();
6804 return 0;
6805 } else {
6806 child_indexes.push_back(x: child_idx);
6807 }
6808 }
6809 }
6810 return child_indexes.size();
6811 }
6812 }
6813 }
6814 break;
6815
6816 case clang::Type::ObjCObject:
6817 case clang::Type::ObjCInterface:
6818 if (GetCompleteType(type)) {
6819 llvm::StringRef name_sref(name);
6820 const clang::ObjCObjectType *objc_class_type =
6821 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
6822 assert(objc_class_type);
6823 if (objc_class_type) {
6824 uint32_t child_idx = 0;
6825 clang::ObjCInterfaceDecl *class_interface_decl =
6826 objc_class_type->getInterface();
6827
6828 if (class_interface_decl) {
6829 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
6830 ivar_end = class_interface_decl->ivar_end();
6831 clang::ObjCInterfaceDecl *superclass_interface_decl =
6832 class_interface_decl->getSuperClass();
6833
6834 for (ivar_pos = class_interface_decl->ivar_begin();
6835 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
6836 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
6837
6838 if (ivar_decl->getName() == name_sref) {
6839 if ((!omit_empty_base_classes && superclass_interface_decl) ||
6840 (omit_empty_base_classes &&
6841 ObjCDeclHasIVars(class_interface_decl: superclass_interface_decl)))
6842 ++child_idx;
6843
6844 child_indexes.push_back(x: child_idx);
6845 return child_indexes.size();
6846 }
6847 }
6848
6849 if (superclass_interface_decl) {
6850 // The super class index is always zero for ObjC classes, so we
6851 // push it onto the child indexes in case we find an ivar in our
6852 // superclass...
6853 child_indexes.push_back(x: 0);
6854
6855 CompilerType superclass_clang_type =
6856 GetType(qt: getASTContext().getObjCInterfaceType(
6857 Decl: superclass_interface_decl));
6858 if (superclass_clang_type.GetIndexOfChildMemberWithName(
6859 name, omit_empty_base_classes, child_indexes)) {
6860 // We did find an ivar in a superclass so just return the
6861 // results!
6862 return child_indexes.size();
6863 }
6864
6865 // We didn't find an ivar matching "name" in our superclass, pop
6866 // the superclass zero index that we pushed on above.
6867 child_indexes.pop_back();
6868 }
6869 }
6870 }
6871 }
6872 break;
6873
6874 case clang::Type::ObjCObjectPointer: {
6875 CompilerType objc_object_clang_type = GetType(
6876 qt: llvm::cast<clang::ObjCObjectPointerType>(Val: qual_type.getTypePtr())
6877 ->getPointeeType());
6878 return objc_object_clang_type.GetIndexOfChildMemberWithName(
6879 name, omit_empty_base_classes, child_indexes);
6880 } break;
6881
6882 case clang::Type::LValueReference:
6883 case clang::Type::RValueReference: {
6884 const clang::ReferenceType *reference_type =
6885 llvm::cast<clang::ReferenceType>(Val: qual_type.getTypePtr());
6886 clang::QualType pointee_type(reference_type->getPointeeType());
6887 CompilerType pointee_clang_type = GetType(qt: pointee_type);
6888
6889 if (pointee_clang_type.IsAggregateType()) {
6890 return pointee_clang_type.GetIndexOfChildMemberWithName(
6891 name, omit_empty_base_classes, child_indexes);
6892 }
6893 } break;
6894
6895 case clang::Type::Pointer: {
6896 CompilerType pointee_clang_type(GetPointeeType(type));
6897
6898 if (pointee_clang_type.IsAggregateType()) {
6899 return pointee_clang_type.GetIndexOfChildMemberWithName(
6900 name, omit_empty_base_classes, child_indexes);
6901 }
6902 } break;
6903
6904 default:
6905 break;
6906 }
6907 }
6908 return 0;
6909}
6910
6911// Get the index of the child of "clang_type" whose name matches. This function
6912// doesn't descend into the children, but only looks one level deep and name
6913// matches can include base class names.
6914
6915llvm::Expected<uint32_t>
6916TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
6917 llvm::StringRef name,
6918 bool omit_empty_base_classes) {
6919 if (type && !name.empty()) {
6920 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
6921
6922 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6923
6924 switch (type_class) {
6925 case clang::Type::Record:
6926 if (GetCompleteType(type)) {
6927 const clang::RecordType *record_type =
6928 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
6929 const clang::RecordDecl *record_decl = record_type->getDecl();
6930
6931 assert(record_decl);
6932 uint32_t child_idx = 0;
6933
6934 const clang::CXXRecordDecl *cxx_record_decl =
6935 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
6936
6937 if (cxx_record_decl) {
6938 clang::CXXRecordDecl::base_class_const_iterator base_class,
6939 base_class_end;
6940 for (base_class = cxx_record_decl->bases_begin(),
6941 base_class_end = cxx_record_decl->bases_end();
6942 base_class != base_class_end; ++base_class) {
6943 // Skip empty base classes
6944 clang::CXXRecordDecl *base_class_decl =
6945 llvm::cast<clang::CXXRecordDecl>(
6946 Val: base_class->getType()
6947 ->castAs<clang::RecordType>()
6948 ->getDecl());
6949 if (omit_empty_base_classes &&
6950 !TypeSystemClang::RecordHasFields(record_decl: base_class_decl))
6951 continue;
6952
6953 CompilerType base_class_clang_type = GetType(qt: base_class->getType());
6954 std::string base_class_type_name(
6955 base_class_clang_type.GetTypeName().AsCString(value_if_empty: ""));
6956 if (base_class_type_name == name)
6957 return child_idx;
6958 ++child_idx;
6959 }
6960 }
6961
6962 // Try and find a field that matches NAME
6963 clang::RecordDecl::field_iterator field, field_end;
6964 for (field = record_decl->field_begin(),
6965 field_end = record_decl->field_end();
6966 field != field_end; ++field, ++child_idx) {
6967 if (field->getName() == name)
6968 return child_idx;
6969 }
6970 }
6971 break;
6972
6973 case clang::Type::ObjCObject:
6974 case clang::Type::ObjCInterface:
6975 if (GetCompleteType(type)) {
6976 const clang::ObjCObjectType *objc_class_type =
6977 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
6978 assert(objc_class_type);
6979 if (objc_class_type) {
6980 uint32_t child_idx = 0;
6981 clang::ObjCInterfaceDecl *class_interface_decl =
6982 objc_class_type->getInterface();
6983
6984 if (class_interface_decl) {
6985 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
6986 ivar_end = class_interface_decl->ivar_end();
6987 clang::ObjCInterfaceDecl *superclass_interface_decl =
6988 class_interface_decl->getSuperClass();
6989
6990 for (ivar_pos = class_interface_decl->ivar_begin();
6991 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
6992 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
6993
6994 if (ivar_decl->getName() == name) {
6995 if ((!omit_empty_base_classes && superclass_interface_decl) ||
6996 (omit_empty_base_classes &&
6997 ObjCDeclHasIVars(class_interface_decl: superclass_interface_decl)))
6998 ++child_idx;
6999
7000 return child_idx;
7001 }
7002 }
7003
7004 if (superclass_interface_decl) {
7005 if (superclass_interface_decl->getName() == name)
7006 return 0;
7007 }
7008 }
7009 }
7010 }
7011 break;
7012
7013 case clang::Type::ObjCObjectPointer: {
7014 CompilerType pointee_clang_type = GetType(
7015 qt: llvm::cast<clang::ObjCObjectPointerType>(Val: qual_type.getTypePtr())
7016 ->getPointeeType());
7017 return pointee_clang_type.GetIndexOfChildWithName(
7018 name, omit_empty_base_classes);
7019 } break;
7020
7021 case clang::Type::LValueReference:
7022 case clang::Type::RValueReference: {
7023 const clang::ReferenceType *reference_type =
7024 llvm::cast<clang::ReferenceType>(Val: qual_type.getTypePtr());
7025 CompilerType pointee_type = GetType(qt: reference_type->getPointeeType());
7026
7027 if (pointee_type.IsAggregateType()) {
7028 return pointee_type.GetIndexOfChildWithName(name,
7029 omit_empty_base_classes);
7030 }
7031 } break;
7032
7033 case clang::Type::Pointer: {
7034 const clang::PointerType *pointer_type =
7035 llvm::cast<clang::PointerType>(Val: qual_type.getTypePtr());
7036 CompilerType pointee_type = GetType(qt: pointer_type->getPointeeType());
7037
7038 if (pointee_type.IsAggregateType()) {
7039 return pointee_type.GetIndexOfChildWithName(name,
7040 omit_empty_base_classes);
7041 }
7042 } break;
7043
7044 default:
7045 break;
7046 }
7047 }
7048 return llvm::createStringError(Fmt: "Type has no child named '%s'",
7049 Vals: name.str().c_str());
7050}
7051
7052CompilerType
7053TypeSystemClang::GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type,
7054 llvm::StringRef name) {
7055 if (!type || name.empty())
7056 return CompilerType();
7057
7058 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
7059 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7060
7061 switch (type_class) {
7062 case clang::Type::Record: {
7063 if (!GetCompleteType(type))
7064 return CompilerType();
7065 const clang::RecordType *record_type =
7066 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
7067 const clang::RecordDecl *record_decl = record_type->getDecl();
7068
7069 clang::DeclarationName decl_name(&getASTContext().Idents.get(Name: name));
7070 for (NamedDecl *decl : record_decl->lookup(Name: decl_name)) {
7071 if (auto *tag_decl = dyn_cast<clang::TagDecl>(Val: decl))
7072 return GetType(qt: getASTContext().getTagDeclType(Decl: tag_decl));
7073 if (auto *typedef_decl = dyn_cast<clang::TypedefNameDecl>(Val: decl))
7074 return GetType(qt: getASTContext().getTypedefType(Decl: typedef_decl));
7075 }
7076 break;
7077 }
7078 default:
7079 break;
7080 }
7081 return CompilerType();
7082}
7083
7084bool TypeSystemClang::IsTemplateType(lldb::opaque_compiler_type_t type) {
7085 if (!type)
7086 return false;
7087 CompilerType ct(weak_from_this(), type);
7088 const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr();
7089 if (auto *cxx_record_decl = dyn_cast<clang::TagType>(Val: clang_type))
7090 return isa<clang::ClassTemplateSpecializationDecl>(
7091 Val: cxx_record_decl->getDecl());
7092 return false;
7093}
7094
7095size_t
7096TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
7097 bool expand_pack) {
7098 if (!type)
7099 return 0;
7100
7101 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
7102 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7103 switch (type_class) {
7104 case clang::Type::Record:
7105 if (GetCompleteType(type)) {
7106 const clang::CXXRecordDecl *cxx_record_decl =
7107 qual_type->getAsCXXRecordDecl();
7108 if (cxx_record_decl) {
7109 const clang::ClassTemplateSpecializationDecl *template_decl =
7110 llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
7111 Val: cxx_record_decl);
7112 if (template_decl) {
7113 const auto &template_arg_list = template_decl->getTemplateArgs();
7114 size_t num_args = template_arg_list.size();
7115 assert(num_args && "template specialization without any args");
7116 if (expand_pack && num_args) {
7117 const auto &pack = template_arg_list[num_args - 1];
7118 if (pack.getKind() == clang::TemplateArgument::Pack)
7119 num_args += pack.pack_size() - 1;
7120 }
7121 return num_args;
7122 }
7123 }
7124 }
7125 break;
7126
7127 default:
7128 break;
7129 }
7130
7131 return 0;
7132}
7133
7134const clang::ClassTemplateSpecializationDecl *
7135TypeSystemClang::GetAsTemplateSpecialization(
7136 lldb::opaque_compiler_type_t type) {
7137 if (!type)
7138 return nullptr;
7139
7140 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
7141 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7142 switch (type_class) {
7143 case clang::Type::Record: {
7144 if (! GetCompleteType(type))
7145 return nullptr;
7146 const clang::CXXRecordDecl *cxx_record_decl =
7147 qual_type->getAsCXXRecordDecl();
7148 if (!cxx_record_decl)
7149 return nullptr;
7150 return llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
7151 Val: cxx_record_decl);
7152 }
7153
7154 default:
7155 return nullptr;
7156 }
7157}
7158
7159const TemplateArgument *
7160GetNthTemplateArgument(const clang::ClassTemplateSpecializationDecl *decl,
7161 size_t idx, bool expand_pack) {
7162 const auto &args = decl->getTemplateArgs();
7163 const size_t args_size = args.size();
7164
7165 assert(args_size && "template specialization without any args");
7166 if (!args_size)
7167 return nullptr;
7168
7169 const size_t last_idx = args_size - 1;
7170
7171 // We're asked for a template argument that can't be a parameter pack, so
7172 // return it without worrying about 'expand_pack'.
7173 if (idx < last_idx)
7174 return &args[idx];
7175
7176 // We're asked for the last template argument but we don't want/need to
7177 // expand it.
7178 if (!expand_pack || args[last_idx].getKind() != clang::TemplateArgument::Pack)
7179 return idx >= args.size() ? nullptr : &args[idx];
7180
7181 // Index into the expanded pack.
7182 // Note that 'idx' counts from the beginning of all template arguments
7183 // (including the ones preceding the parameter pack).
7184 const auto &pack = args[last_idx];
7185 const size_t pack_idx = idx - last_idx;
7186 if (pack_idx >= pack.pack_size())
7187 return nullptr;
7188 return &pack.pack_elements()[pack_idx];
7189}
7190
7191lldb::TemplateArgumentKind
7192TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
7193 size_t arg_idx, bool expand_pack) {
7194 const clang::ClassTemplateSpecializationDecl *template_decl =
7195 GetAsTemplateSpecialization(type);
7196 if (!template_decl)
7197 return eTemplateArgumentKindNull;
7198
7199 const auto *arg = GetNthTemplateArgument(decl: template_decl, idx: arg_idx, expand_pack);
7200 if (!arg)
7201 return eTemplateArgumentKindNull;
7202
7203 switch (arg->getKind()) {
7204 case clang::TemplateArgument::Null:
7205 return eTemplateArgumentKindNull;
7206
7207 case clang::TemplateArgument::NullPtr:
7208 return eTemplateArgumentKindNullPtr;
7209
7210 case clang::TemplateArgument::Type:
7211 return eTemplateArgumentKindType;
7212
7213 case clang::TemplateArgument::Declaration:
7214 return eTemplateArgumentKindDeclaration;
7215
7216 case clang::TemplateArgument::Integral:
7217 return eTemplateArgumentKindIntegral;
7218
7219 case clang::TemplateArgument::Template:
7220 return eTemplateArgumentKindTemplate;
7221
7222 case clang::TemplateArgument::TemplateExpansion:
7223 return eTemplateArgumentKindTemplateExpansion;
7224
7225 case clang::TemplateArgument::Expression:
7226 return eTemplateArgumentKindExpression;
7227
7228 case clang::TemplateArgument::Pack:
7229 return eTemplateArgumentKindPack;
7230
7231 case clang::TemplateArgument::StructuralValue:
7232 return eTemplateArgumentKindStructuralValue;
7233 }
7234 llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind");
7235}
7236
7237CompilerType
7238TypeSystemClang::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
7239 size_t idx, bool expand_pack) {
7240 const clang::ClassTemplateSpecializationDecl *template_decl =
7241 GetAsTemplateSpecialization(type);
7242 if (!template_decl)
7243 return CompilerType();
7244
7245 const auto *arg = GetNthTemplateArgument(decl: template_decl, idx, expand_pack);
7246 if (!arg || arg->getKind() != clang::TemplateArgument::Type)
7247 return CompilerType();
7248
7249 return GetType(qt: arg->getAsType());
7250}
7251
7252std::optional<CompilerType::IntegralTemplateArgument>
7253TypeSystemClang::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
7254 size_t idx, bool expand_pack) {
7255 const clang::ClassTemplateSpecializationDecl *template_decl =
7256 GetAsTemplateSpecialization(type);
7257 if (!template_decl)
7258 return std::nullopt;
7259
7260 const auto *arg = GetNthTemplateArgument(decl: template_decl, idx, expand_pack);
7261 if (!arg)
7262 return std::nullopt;
7263
7264 switch (arg->getKind()) {
7265 case clang::TemplateArgument::Integral:
7266 return {{.value: arg->getAsIntegral(), .type: GetType(qt: arg->getIntegralType())}};
7267 case clang::TemplateArgument::StructuralValue: {
7268 clang::APValue value = arg->getAsStructuralValue();
7269 CompilerType type = GetType(qt: arg->getStructuralValueType());
7270
7271 if (value.isFloat())
7272 return {{.value: value.getFloat(), .type: type}};
7273
7274 if (value.isInt())
7275 return {{.value: value.getInt(), .type: type}};
7276
7277 return std::nullopt;
7278 }
7279 default:
7280 return std::nullopt;
7281 }
7282}
7283
7284CompilerType TypeSystemClang::GetTypeForFormatters(void *type) {
7285 if (type)
7286 return ClangUtil::RemoveFastQualifiers(ct: CompilerType(weak_from_this(), type));
7287 return CompilerType();
7288}
7289
7290clang::EnumDecl *TypeSystemClang::GetAsEnumDecl(const CompilerType &type) {
7291 const clang::EnumType *enutype =
7292 llvm::dyn_cast<clang::EnumType>(Val: ClangUtil::GetCanonicalQualType(ct: type));
7293 if (enutype)
7294 return enutype->getDecl();
7295 return nullptr;
7296}
7297
7298clang::RecordDecl *TypeSystemClang::GetAsRecordDecl(const CompilerType &type) {
7299 const clang::RecordType *record_type =
7300 llvm::dyn_cast<clang::RecordType>(Val: ClangUtil::GetCanonicalQualType(ct: type));
7301 if (record_type)
7302 return record_type->getDecl();
7303 return nullptr;
7304}
7305
7306clang::TagDecl *TypeSystemClang::GetAsTagDecl(const CompilerType &type) {
7307 return ClangUtil::GetAsTagDecl(type);
7308}
7309
7310clang::TypedefNameDecl *
7311TypeSystemClang::GetAsTypedefDecl(const CompilerType &type) {
7312 const clang::TypedefType *typedef_type =
7313 llvm::dyn_cast<clang::TypedefType>(Val: ClangUtil::GetQualType(ct: type));
7314 if (typedef_type)
7315 return typedef_type->getDecl();
7316 return nullptr;
7317}
7318
7319clang::CXXRecordDecl *
7320TypeSystemClang::GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type) {
7321 return GetCanonicalQualType(type)->getAsCXXRecordDecl();
7322}
7323
7324clang::ObjCInterfaceDecl *
7325TypeSystemClang::GetAsObjCInterfaceDecl(const CompilerType &type) {
7326 const clang::ObjCObjectType *objc_class_type =
7327 llvm::dyn_cast<clang::ObjCObjectType>(
7328 Val: ClangUtil::GetCanonicalQualType(ct: type));
7329 if (objc_class_type)
7330 return objc_class_type->getInterface();
7331 return nullptr;
7332}
7333
7334clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
7335 const CompilerType &type, llvm::StringRef name,
7336 const CompilerType &field_clang_type, AccessType access,
7337 uint32_t bitfield_bit_size) {
7338 if (!type.IsValid() || !field_clang_type.IsValid())
7339 return nullptr;
7340 auto ast = type.GetTypeSystem<TypeSystemClang>();
7341 if (!ast)
7342 return nullptr;
7343 clang::ASTContext &clang_ast = ast->getASTContext();
7344 clang::IdentifierInfo *ident = nullptr;
7345 if (!name.empty())
7346 ident = &clang_ast.Idents.get(Name: name);
7347
7348 clang::FieldDecl *field = nullptr;
7349
7350 clang::Expr *bit_width = nullptr;
7351 if (bitfield_bit_size != 0) {
7352 if (clang_ast.IntTy.isNull()) {
7353 LLDB_LOG(
7354 GetLog(LLDBLog::Expressions),
7355 "{0} failed: builtin ASTContext types have not been initialized");
7356 return nullptr;
7357 }
7358
7359 llvm::APInt bitfield_bit_size_apint(clang_ast.getTypeSize(T: clang_ast.IntTy),
7360 bitfield_bit_size);
7361 bit_width = new (clang_ast)
7362 clang::IntegerLiteral(clang_ast, bitfield_bit_size_apint,
7363 clang_ast.IntTy, clang::SourceLocation());
7364 bit_width = clang::ConstantExpr::Create(
7365 Context: clang_ast, E: bit_width, Result: APValue(llvm::APSInt(bitfield_bit_size_apint)));
7366 }
7367
7368 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
7369 if (record_decl) {
7370 field = clang::FieldDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
7371 field->setDeclContext(record_decl);
7372 field->setDeclName(ident);
7373 field->setType(ClangUtil::GetQualType(ct: field_clang_type));
7374 if (bit_width)
7375 field->setBitWidth(bit_width);
7376 SetMemberOwningModule(member: field, parent: record_decl);
7377
7378 if (name.empty()) {
7379 // Determine whether this field corresponds to an anonymous struct or
7380 // union.
7381 if (const clang::TagType *TagT =
7382 field->getType()->getAs<clang::TagType>()) {
7383 if (clang::RecordDecl *Rec =
7384 llvm::dyn_cast<clang::RecordDecl>(Val: TagT->getDecl()))
7385 if (!Rec->getDeclName()) {
7386 Rec->setAnonymousStructOrUnion(true);
7387 field->setImplicit();
7388 }
7389 }
7390 }
7391
7392 if (field) {
7393 clang::AccessSpecifier access_specifier =
7394 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
7395 field->setAccess(access_specifier);
7396
7397 if (clang::CXXRecordDecl *cxx_record_decl =
7398 llvm::dyn_cast<CXXRecordDecl>(Val: record_decl)) {
7399 AddAccessSpecifierDecl(cxx_record_decl, ct&: ast->getASTContext(),
7400 previous_access: ast->GetCXXRecordDeclAccess(object: cxx_record_decl),
7401 access_specifier);
7402 ast->SetCXXRecordDeclAccess(object: cxx_record_decl, access: access_specifier);
7403 }
7404 record_decl->addDecl(D: field);
7405
7406 VerifyDecl(decl: field);
7407 }
7408 } else {
7409 clang::ObjCInterfaceDecl *class_interface_decl =
7410 ast->GetAsObjCInterfaceDecl(type);
7411
7412 if (class_interface_decl) {
7413 const bool is_synthesized = false;
7414
7415 field_clang_type.GetCompleteType();
7416
7417 auto *ivar =
7418 clang::ObjCIvarDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
7419 ivar->setDeclContext(class_interface_decl);
7420 ivar->setDeclName(ident);
7421 ivar->setType(ClangUtil::GetQualType(ct: field_clang_type));
7422 ivar->setAccessControl(ConvertAccessTypeToObjCIvarAccessControl(access));
7423 if (bit_width)
7424 ivar->setBitWidth(bit_width);
7425 ivar->setSynthesize(is_synthesized);
7426 field = ivar;
7427 SetMemberOwningModule(member: field, parent: class_interface_decl);
7428
7429 if (field) {
7430 class_interface_decl->addDecl(D: field);
7431
7432 VerifyDecl(decl: field);
7433 }
7434 }
7435 }
7436 return field;
7437}
7438
7439void TypeSystemClang::BuildIndirectFields(const CompilerType &type) {
7440 if (!type)
7441 return;
7442
7443 auto ast = type.GetTypeSystem<TypeSystemClang>();
7444 if (!ast)
7445 return;
7446
7447 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
7448
7449 if (!record_decl)
7450 return;
7451
7452 typedef llvm::SmallVector<clang::IndirectFieldDecl *, 1> IndirectFieldVector;
7453
7454 IndirectFieldVector indirect_fields;
7455 clang::RecordDecl::field_iterator field_pos;
7456 clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end();
7457 clang::RecordDecl::field_iterator last_field_pos = field_end_pos;
7458 for (field_pos = record_decl->field_begin(); field_pos != field_end_pos;
7459 last_field_pos = field_pos++) {
7460 if (field_pos->isAnonymousStructOrUnion()) {
7461 clang::QualType field_qual_type = field_pos->getType();
7462
7463 const clang::RecordType *field_record_type =
7464 field_qual_type->getAs<clang::RecordType>();
7465
7466 if (!field_record_type)
7467 continue;
7468
7469 clang::RecordDecl *field_record_decl = field_record_type->getDecl();
7470
7471 if (!field_record_decl)
7472 continue;
7473
7474 for (clang::RecordDecl::decl_iterator
7475 di = field_record_decl->decls_begin(),
7476 de = field_record_decl->decls_end();
7477 di != de; ++di) {
7478 if (clang::FieldDecl *nested_field_decl =
7479 llvm::dyn_cast<clang::FieldDecl>(Val: *di)) {
7480 clang::NamedDecl **chain =
7481 new (ast->getASTContext()) clang::NamedDecl *[2];
7482 chain[0] = *field_pos;
7483 chain[1] = nested_field_decl;
7484 clang::IndirectFieldDecl *indirect_field =
7485 clang::IndirectFieldDecl::Create(
7486 C&: ast->getASTContext(), DC: record_decl, L: clang::SourceLocation(),
7487 Id: nested_field_decl->getIdentifier(),
7488 T: nested_field_decl->getType(), CH: {chain, 2});
7489 SetMemberOwningModule(member: indirect_field, parent: record_decl);
7490
7491 indirect_field->setImplicit();
7492
7493 indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers(
7494 lhs: field_pos->getAccess(), rhs: nested_field_decl->getAccess()));
7495
7496 indirect_fields.push_back(Elt: indirect_field);
7497 } else if (clang::IndirectFieldDecl *nested_indirect_field_decl =
7498 llvm::dyn_cast<clang::IndirectFieldDecl>(Val: *di)) {
7499 size_t nested_chain_size =
7500 nested_indirect_field_decl->getChainingSize();
7501 clang::NamedDecl **chain = new (ast->getASTContext())
7502 clang::NamedDecl *[nested_chain_size + 1];
7503 chain[0] = *field_pos;
7504
7505 int chain_index = 1;
7506 for (clang::IndirectFieldDecl::chain_iterator
7507 nci = nested_indirect_field_decl->chain_begin(),
7508 nce = nested_indirect_field_decl->chain_end();
7509 nci < nce; ++nci) {
7510 chain[chain_index] = *nci;
7511 chain_index++;
7512 }
7513
7514 clang::IndirectFieldDecl *indirect_field =
7515 clang::IndirectFieldDecl::Create(
7516 C&: ast->getASTContext(), DC: record_decl, L: clang::SourceLocation(),
7517 Id: nested_indirect_field_decl->getIdentifier(),
7518 T: nested_indirect_field_decl->getType(),
7519 CH: {chain, nested_chain_size + 1});
7520 SetMemberOwningModule(member: indirect_field, parent: record_decl);
7521
7522 indirect_field->setImplicit();
7523
7524 indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers(
7525 lhs: field_pos->getAccess(), rhs: nested_indirect_field_decl->getAccess()));
7526
7527 indirect_fields.push_back(Elt: indirect_field);
7528 }
7529 }
7530 }
7531 }
7532
7533 // Check the last field to see if it has an incomplete array type as its last
7534 // member and if it does, the tell the record decl about it
7535 if (last_field_pos != field_end_pos) {
7536 if (last_field_pos->getType()->isIncompleteArrayType())
7537 record_decl->hasFlexibleArrayMember();
7538 }
7539
7540 for (IndirectFieldVector::iterator ifi = indirect_fields.begin(),
7541 ife = indirect_fields.end();
7542 ifi < ife; ++ifi) {
7543 record_decl->addDecl(D: *ifi);
7544 }
7545}
7546
7547void TypeSystemClang::SetIsPacked(const CompilerType &type) {
7548 if (type) {
7549 auto ast = type.GetTypeSystem<TypeSystemClang>();
7550 if (ast) {
7551 clang::RecordDecl *record_decl = GetAsRecordDecl(type);
7552
7553 if (!record_decl)
7554 return;
7555
7556 record_decl->addAttr(
7557 A: clang::PackedAttr::CreateImplicit(Ctx&: ast->getASTContext()));
7558 }
7559 }
7560}
7561
7562clang::VarDecl *TypeSystemClang::AddVariableToRecordType(
7563 const CompilerType &type, llvm::StringRef name,
7564 const CompilerType &var_type, AccessType access) {
7565 if (!type.IsValid() || !var_type.IsValid())
7566 return nullptr;
7567
7568 auto ast = type.GetTypeSystem<TypeSystemClang>();
7569 if (!ast)
7570 return nullptr;
7571
7572 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
7573 if (!record_decl)
7574 return nullptr;
7575
7576 clang::VarDecl *var_decl = nullptr;
7577 clang::IdentifierInfo *ident = nullptr;
7578 if (!name.empty())
7579 ident = &ast->getASTContext().Idents.get(Name: name);
7580
7581 var_decl =
7582 clang::VarDecl::CreateDeserialized(C&: ast->getASTContext(), ID: GlobalDeclID());
7583 var_decl->setDeclContext(record_decl);
7584 var_decl->setDeclName(ident);
7585 var_decl->setType(ClangUtil::GetQualType(ct: var_type));
7586 var_decl->setStorageClass(clang::SC_Static);
7587 SetMemberOwningModule(member: var_decl, parent: record_decl);
7588 if (!var_decl)
7589 return nullptr;
7590
7591 var_decl->setAccess(
7592 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access));
7593 record_decl->addDecl(D: var_decl);
7594
7595 VerifyDecl(decl: var_decl);
7596
7597 return var_decl;
7598}
7599
7600void TypeSystemClang::SetIntegerInitializerForVariable(
7601 VarDecl *var, const llvm::APInt &init_value) {
7602 assert(!var->hasInit() && "variable already initialized");
7603
7604 clang::ASTContext &ast = var->getASTContext();
7605 QualType qt = var->getType();
7606 assert(qt->isIntegralOrEnumerationType() &&
7607 "only integer or enum types supported");
7608 // If the variable is an enum type, take the underlying integer type as
7609 // the type of the integer literal.
7610 if (const EnumType *enum_type = qt->getAs<EnumType>()) {
7611 const EnumDecl *enum_decl = enum_type->getDecl();
7612 qt = enum_decl->getIntegerType();
7613 }
7614 // Bools are handled separately because the clang AST printer handles bools
7615 // separately from other integral types.
7616 if (qt->isSpecificBuiltinType(K: BuiltinType::Bool)) {
7617 var->setInit(CXXBoolLiteralExpr::Create(
7618 C: ast, Val: !init_value.isZero(), Ty: qt.getUnqualifiedType(), Loc: SourceLocation()));
7619 } else {
7620 var->setInit(IntegerLiteral::Create(
7621 C: ast, V: init_value, type: qt.getUnqualifiedType(), l: SourceLocation()));
7622 }
7623}
7624
7625void TypeSystemClang::SetFloatingInitializerForVariable(
7626 clang::VarDecl *var, const llvm::APFloat &init_value) {
7627 assert(!var->hasInit() && "variable already initialized");
7628
7629 clang::ASTContext &ast = var->getASTContext();
7630 QualType qt = var->getType();
7631 assert(qt->isFloatingType() && "only floating point types supported");
7632 var->setInit(FloatingLiteral::Create(
7633 C: ast, V: init_value, isexact: true, Type: qt.getUnqualifiedType(), L: SourceLocation()));
7634}
7635
7636llvm::SmallVector<clang::ParmVarDecl *>
7637TypeSystemClang::CreateParameterDeclarations(
7638 clang::FunctionDecl *func, const clang::FunctionProtoType &prototype,
7639 const llvm::SmallVector<llvm::StringRef> &parameter_names) {
7640 assert(func);
7641 assert(parameter_names.empty() ||
7642 parameter_names.size() == prototype.getNumParams());
7643
7644 llvm::SmallVector<clang::ParmVarDecl *> params;
7645 for (unsigned param_index = 0; param_index < prototype.getNumParams();
7646 ++param_index) {
7647 llvm::StringRef name =
7648 !parameter_names.empty() ? parameter_names[param_index] : "";
7649
7650 auto *param =
7651 CreateParameterDeclaration(decl_ctx: func, /*owning_module=*/{}, name: name.data(),
7652 param_type: GetType(qt: prototype.getParamType(i: param_index)),
7653 storage: clang::SC_None, /*add_decl=*/false);
7654 assert(param);
7655
7656 params.push_back(Elt: param);
7657 }
7658
7659 return params;
7660}
7661
7662clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
7663 lldb::opaque_compiler_type_t type, llvm::StringRef name,
7664 const char *mangled_name, const CompilerType &method_clang_type,
7665 lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline,
7666 bool is_explicit, bool is_attr_used, bool is_artificial) {
7667 if (!type || !method_clang_type.IsValid() || name.empty())
7668 return nullptr;
7669
7670 clang::QualType record_qual_type(GetCanonicalQualType(type));
7671
7672 clang::CXXRecordDecl *cxx_record_decl =
7673 record_qual_type->getAsCXXRecordDecl();
7674
7675 if (cxx_record_decl == nullptr)
7676 return nullptr;
7677
7678 clang::QualType method_qual_type(ClangUtil::GetQualType(ct: method_clang_type));
7679
7680 clang::CXXMethodDecl *cxx_method_decl = nullptr;
7681
7682 clang::DeclarationName decl_name(&getASTContext().Idents.get(Name: name));
7683
7684 const clang::FunctionType *function_type =
7685 llvm::dyn_cast<clang::FunctionType>(Val: method_qual_type.getTypePtr());
7686
7687 if (function_type == nullptr)
7688 return nullptr;
7689
7690 const clang::FunctionProtoType *method_function_prototype(
7691 llvm::dyn_cast<clang::FunctionProtoType>(Val: function_type));
7692
7693 if (!method_function_prototype)
7694 return nullptr;
7695
7696 unsigned int num_params = method_function_prototype->getNumParams();
7697
7698 clang::CXXDestructorDecl *cxx_dtor_decl(nullptr);
7699 clang::CXXConstructorDecl *cxx_ctor_decl(nullptr);
7700
7701 if (is_artificial)
7702 return nullptr; // skip everything artificial
7703
7704 const clang::ExplicitSpecifier explicit_spec(
7705 nullptr /*expr*/, is_explicit ? clang::ExplicitSpecKind::ResolvedTrue
7706 : clang::ExplicitSpecKind::ResolvedFalse);
7707
7708 if (name.starts_with(Prefix: "~")) {
7709 cxx_dtor_decl = clang::CXXDestructorDecl::CreateDeserialized(
7710 C&: getASTContext(), ID: GlobalDeclID());
7711 cxx_dtor_decl->setDeclContext(cxx_record_decl);
7712 cxx_dtor_decl->setDeclName(
7713 getASTContext().DeclarationNames.getCXXDestructorName(
7714 Ty: getASTContext().getCanonicalType(T: record_qual_type)));
7715 cxx_dtor_decl->setType(method_qual_type);
7716 cxx_dtor_decl->setImplicit(is_artificial);
7717 cxx_dtor_decl->setInlineSpecified(is_inline);
7718 cxx_dtor_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
7719 cxx_method_decl = cxx_dtor_decl;
7720 } else if (decl_name == cxx_record_decl->getDeclName()) {
7721 cxx_ctor_decl = clang::CXXConstructorDecl::CreateDeserialized(
7722 C&: getASTContext(), ID: GlobalDeclID(), AllocKind: 0);
7723 cxx_ctor_decl->setDeclContext(cxx_record_decl);
7724 cxx_ctor_decl->setDeclName(
7725 getASTContext().DeclarationNames.getCXXConstructorName(
7726 Ty: getASTContext().getCanonicalType(T: record_qual_type)));
7727 cxx_ctor_decl->setType(method_qual_type);
7728 cxx_ctor_decl->setImplicit(is_artificial);
7729 cxx_ctor_decl->setInlineSpecified(is_inline);
7730 cxx_ctor_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
7731 cxx_ctor_decl->setNumCtorInitializers(0);
7732 cxx_ctor_decl->setExplicitSpecifier(explicit_spec);
7733 cxx_method_decl = cxx_ctor_decl;
7734 } else {
7735 clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
7736 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
7737
7738 if (IsOperator(name, op_kind)) {
7739 if (op_kind != clang::NUM_OVERLOADED_OPERATORS) {
7740 // Check the number of operator parameters. Sometimes we have seen bad
7741 // DWARF that doesn't correctly describe operators and if we try to
7742 // create a method and add it to the class, clang will assert and
7743 // crash, so we need to make sure things are acceptable.
7744 const bool is_method = true;
7745 if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
7746 is_method, op_kind, num_params))
7747 return nullptr;
7748 cxx_method_decl = clang::CXXMethodDecl::CreateDeserialized(
7749 C&: getASTContext(), ID: GlobalDeclID());
7750 cxx_method_decl->setDeclContext(cxx_record_decl);
7751 cxx_method_decl->setDeclName(
7752 getASTContext().DeclarationNames.getCXXOperatorName(Op: op_kind));
7753 cxx_method_decl->setType(method_qual_type);
7754 cxx_method_decl->setStorageClass(SC);
7755 cxx_method_decl->setInlineSpecified(is_inline);
7756 cxx_method_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
7757 } else if (num_params == 0) {
7758 // Conversion operators don't take params...
7759 auto *cxx_conversion_decl =
7760 clang::CXXConversionDecl::CreateDeserialized(C&: getASTContext(),
7761 ID: GlobalDeclID());
7762 cxx_conversion_decl->setDeclContext(cxx_record_decl);
7763 cxx_conversion_decl->setDeclName(
7764 getASTContext().DeclarationNames.getCXXConversionFunctionName(
7765 Ty: getASTContext().getCanonicalType(
7766 T: function_type->getReturnType())));
7767 cxx_conversion_decl->setType(method_qual_type);
7768 cxx_conversion_decl->setInlineSpecified(is_inline);
7769 cxx_conversion_decl->setExplicitSpecifier(explicit_spec);
7770 cxx_conversion_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
7771 cxx_method_decl = cxx_conversion_decl;
7772 }
7773 }
7774
7775 if (cxx_method_decl == nullptr) {
7776 cxx_method_decl = clang::CXXMethodDecl::CreateDeserialized(
7777 C&: getASTContext(), ID: GlobalDeclID());
7778 cxx_method_decl->setDeclContext(cxx_record_decl);
7779 cxx_method_decl->setDeclName(decl_name);
7780 cxx_method_decl->setType(method_qual_type);
7781 cxx_method_decl->setInlineSpecified(is_inline);
7782 cxx_method_decl->setStorageClass(SC);
7783 cxx_method_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
7784 }
7785 }
7786 SetMemberOwningModule(member: cxx_method_decl, parent: cxx_record_decl);
7787
7788 clang::AccessSpecifier access_specifier =
7789 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
7790
7791 cxx_method_decl->setAccess(access_specifier);
7792 cxx_method_decl->setVirtualAsWritten(is_virtual);
7793
7794 if (is_attr_used)
7795 cxx_method_decl->addAttr(A: clang::UsedAttr::CreateImplicit(Ctx&: getASTContext()));
7796
7797 if (mangled_name != nullptr) {
7798 cxx_method_decl->addAttr(A: clang::AsmLabelAttr::CreateImplicit(
7799 Ctx&: getASTContext(), Label: mangled_name, /*literal=*/IsLiteralLabel: false));
7800 }
7801
7802 // Parameters on member function declarations in DWARF generally don't
7803 // have names, so we omit them when creating the ParmVarDecls.
7804 cxx_method_decl->setParams(CreateParameterDeclarations(
7805 func: cxx_method_decl, prototype: *method_function_prototype, /*parameter_names=*/{}));
7806
7807 AddAccessSpecifierDecl(cxx_record_decl, ct&: getASTContext(),
7808 previous_access: GetCXXRecordDeclAccess(object: cxx_record_decl),
7809 access_specifier);
7810 SetCXXRecordDeclAccess(object: cxx_record_decl, access: access_specifier);
7811
7812 cxx_record_decl->addDecl(D: cxx_method_decl);
7813
7814 // Sometimes the debug info will mention a constructor (default/copy/move),
7815 // destructor, or assignment operator (copy/move) but there won't be any
7816 // version of this in the code. So we check if the function was artificially
7817 // generated and if it is trivial and this lets the compiler/backend know
7818 // that it can inline the IR for these when it needs to and we can avoid a
7819 // "missing function" error when running expressions.
7820
7821 if (is_artificial) {
7822 if (cxx_ctor_decl && ((cxx_ctor_decl->isDefaultConstructor() &&
7823 cxx_record_decl->hasTrivialDefaultConstructor()) ||
7824 (cxx_ctor_decl->isCopyConstructor() &&
7825 cxx_record_decl->hasTrivialCopyConstructor()) ||
7826 (cxx_ctor_decl->isMoveConstructor() &&
7827 cxx_record_decl->hasTrivialMoveConstructor()))) {
7828 cxx_ctor_decl->setDefaulted();
7829 cxx_ctor_decl->setTrivial(true);
7830 } else if (cxx_dtor_decl) {
7831 if (cxx_record_decl->hasTrivialDestructor()) {
7832 cxx_dtor_decl->setDefaulted();
7833 cxx_dtor_decl->setTrivial(true);
7834 }
7835 } else if ((cxx_method_decl->isCopyAssignmentOperator() &&
7836 cxx_record_decl->hasTrivialCopyAssignment()) ||
7837 (cxx_method_decl->isMoveAssignmentOperator() &&
7838 cxx_record_decl->hasTrivialMoveAssignment())) {
7839 cxx_method_decl->setDefaulted();
7840 cxx_method_decl->setTrivial(true);
7841 }
7842 }
7843
7844 VerifyDecl(decl: cxx_method_decl);
7845
7846 return cxx_method_decl;
7847}
7848
7849void TypeSystemClang::AddMethodOverridesForCXXRecordType(
7850 lldb::opaque_compiler_type_t type) {
7851 if (auto *record = GetAsCXXRecordDecl(type))
7852 for (auto *method : record->methods())
7853 addOverridesForMethod(decl: method);
7854}
7855
7856#pragma mark C++ Base Classes
7857
7858std::unique_ptr<clang::CXXBaseSpecifier>
7859TypeSystemClang::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
7860 AccessType access, bool is_virtual,
7861 bool base_of_class) {
7862 if (!type)
7863 return nullptr;
7864
7865 return std::make_unique<clang::CXXBaseSpecifier>(
7866 args: clang::SourceRange(), args&: is_virtual, args&: base_of_class,
7867 args: TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access),
7868 args: getASTContext().getTrivialTypeSourceInfo(T: GetQualType(type)),
7869 args: clang::SourceLocation());
7870}
7871
7872bool TypeSystemClang::TransferBaseClasses(
7873 lldb::opaque_compiler_type_t type,
7874 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases) {
7875 if (!type)
7876 return false;
7877 clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type);
7878 if (!cxx_record_decl)
7879 return false;
7880 std::vector<clang::CXXBaseSpecifier *> raw_bases;
7881 raw_bases.reserve(n: bases.size());
7882
7883 // Clang will make a copy of them, so it's ok that we pass pointers that we're
7884 // about to destroy.
7885 for (auto &b : bases)
7886 raw_bases.push_back(x: b.get());
7887 cxx_record_decl->setBases(Bases: raw_bases.data(), NumBases: raw_bases.size());
7888 return true;
7889}
7890
7891bool TypeSystemClang::SetObjCSuperClass(
7892 const CompilerType &type, const CompilerType &superclass_clang_type) {
7893 auto ast = type.GetTypeSystem<TypeSystemClang>();
7894 if (!ast)
7895 return false;
7896 clang::ASTContext &clang_ast = ast->getASTContext();
7897
7898 if (type && superclass_clang_type.IsValid() &&
7899 superclass_clang_type.GetTypeSystem() == type.GetTypeSystem()) {
7900 clang::ObjCInterfaceDecl *class_interface_decl =
7901 GetAsObjCInterfaceDecl(type);
7902 clang::ObjCInterfaceDecl *super_interface_decl =
7903 GetAsObjCInterfaceDecl(type: superclass_clang_type);
7904 if (class_interface_decl && super_interface_decl) {
7905 class_interface_decl->setSuperClass(clang_ast.getTrivialTypeSourceInfo(
7906 T: clang_ast.getObjCInterfaceType(Decl: super_interface_decl)));
7907 return true;
7908 }
7909 }
7910 return false;
7911}
7912
7913bool TypeSystemClang::AddObjCClassProperty(
7914 const CompilerType &type, const char *property_name,
7915 const CompilerType &property_clang_type, clang::ObjCIvarDecl *ivar_decl,
7916 const char *property_setter_name, const char *property_getter_name,
7917 uint32_t property_attributes, ClangASTMetadata metadata) {
7918 if (!type || !property_clang_type.IsValid() || property_name == nullptr ||
7919 property_name[0] == '\0')
7920 return false;
7921 auto ast = type.GetTypeSystem<TypeSystemClang>();
7922 if (!ast)
7923 return false;
7924 clang::ASTContext &clang_ast = ast->getASTContext();
7925
7926 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
7927 if (!class_interface_decl)
7928 return false;
7929
7930 CompilerType property_clang_type_to_access;
7931
7932 if (property_clang_type.IsValid())
7933 property_clang_type_to_access = property_clang_type;
7934 else if (ivar_decl)
7935 property_clang_type_to_access = ast->GetType(qt: ivar_decl->getType());
7936
7937 if (!class_interface_decl || !property_clang_type_to_access.IsValid())
7938 return false;
7939
7940 clang::TypeSourceInfo *prop_type_source;
7941 if (ivar_decl)
7942 prop_type_source = clang_ast.getTrivialTypeSourceInfo(T: ivar_decl->getType());
7943 else
7944 prop_type_source = clang_ast.getTrivialTypeSourceInfo(
7945 T: ClangUtil::GetQualType(ct: property_clang_type));
7946
7947 clang::ObjCPropertyDecl *property_decl =
7948 clang::ObjCPropertyDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
7949 property_decl->setDeclContext(class_interface_decl);
7950 property_decl->setDeclName(&clang_ast.Idents.get(Name: property_name));
7951 property_decl->setType(T: ivar_decl
7952 ? ivar_decl->getType()
7953 : ClangUtil::GetQualType(ct: property_clang_type),
7954 TSI: prop_type_source);
7955 SetMemberOwningModule(member: property_decl, parent: class_interface_decl);
7956
7957 if (!property_decl)
7958 return false;
7959
7960 ast->SetMetadata(object: property_decl, metadata);
7961
7962 class_interface_decl->addDecl(D: property_decl);
7963
7964 clang::Selector setter_sel, getter_sel;
7965
7966 if (property_setter_name) {
7967 std::string property_setter_no_colon(property_setter_name,
7968 strlen(s: property_setter_name) - 1);
7969 const clang::IdentifierInfo *setter_ident =
7970 &clang_ast.Idents.get(Name: property_setter_no_colon);
7971 setter_sel = clang_ast.Selectors.getSelector(NumArgs: 1, IIV: &setter_ident);
7972 } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) {
7973 std::string setter_sel_string("set");
7974 setter_sel_string.push_back(c: ::toupper(c: property_name[0]));
7975 setter_sel_string.append(s: &property_name[1]);
7976 const clang::IdentifierInfo *setter_ident =
7977 &clang_ast.Idents.get(Name: setter_sel_string);
7978 setter_sel = clang_ast.Selectors.getSelector(NumArgs: 1, IIV: &setter_ident);
7979 }
7980 property_decl->setSetterName(Sel: setter_sel);
7981 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_setter);
7982
7983 if (property_getter_name != nullptr) {
7984 const clang::IdentifierInfo *getter_ident =
7985 &clang_ast.Idents.get(Name: property_getter_name);
7986 getter_sel = clang_ast.Selectors.getSelector(NumArgs: 0, IIV: &getter_ident);
7987 } else {
7988 const clang::IdentifierInfo *getter_ident =
7989 &clang_ast.Idents.get(Name: property_name);
7990 getter_sel = clang_ast.Selectors.getSelector(NumArgs: 0, IIV: &getter_ident);
7991 }
7992 property_decl->setGetterName(Sel: getter_sel);
7993 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_getter);
7994
7995 if (ivar_decl)
7996 property_decl->setPropertyIvarDecl(ivar_decl);
7997
7998 if (property_attributes & DW_APPLE_PROPERTY_readonly)
7999 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readonly);
8000 if (property_attributes & DW_APPLE_PROPERTY_readwrite)
8001 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readwrite);
8002 if (property_attributes & DW_APPLE_PROPERTY_assign)
8003 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_assign);
8004 if (property_attributes & DW_APPLE_PROPERTY_retain)
8005 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_retain);
8006 if (property_attributes & DW_APPLE_PROPERTY_copy)
8007 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_copy);
8008 if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
8009 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_nonatomic);
8010 if (property_attributes & ObjCPropertyAttribute::kind_nullability)
8011 property_decl->setPropertyAttributes(
8012 ObjCPropertyAttribute::kind_nullability);
8013 if (property_attributes & ObjCPropertyAttribute::kind_null_resettable)
8014 property_decl->setPropertyAttributes(
8015 ObjCPropertyAttribute::kind_null_resettable);
8016 if (property_attributes & ObjCPropertyAttribute::kind_class)
8017 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_class);
8018
8019 const bool isInstance =
8020 (property_attributes & ObjCPropertyAttribute::kind_class) == 0;
8021
8022 clang::ObjCMethodDecl *getter = nullptr;
8023 if (!getter_sel.isNull())
8024 getter = isInstance ? class_interface_decl->lookupInstanceMethod(Sel: getter_sel)
8025 : class_interface_decl->lookupClassMethod(Sel: getter_sel);
8026 if (!getter_sel.isNull() && !getter) {
8027 const bool isVariadic = false;
8028 const bool isPropertyAccessor = true;
8029 const bool isSynthesizedAccessorStub = false;
8030 const bool isImplicitlyDeclared = true;
8031 const bool isDefined = false;
8032 const clang::ObjCImplementationControl impControl =
8033 clang::ObjCImplementationControl::None;
8034 const bool HasRelatedResultType = false;
8035
8036 getter =
8037 clang::ObjCMethodDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
8038 getter->setDeclName(getter_sel);
8039 getter->setReturnType(ClangUtil::GetQualType(ct: property_clang_type_to_access));
8040 getter->setDeclContext(class_interface_decl);
8041 getter->setInstanceMethod(isInstance);
8042 getter->setVariadic(isVariadic);
8043 getter->setPropertyAccessor(isPropertyAccessor);
8044 getter->setSynthesizedAccessorStub(isSynthesizedAccessorStub);
8045 getter->setImplicit(isImplicitlyDeclared);
8046 getter->setDefined(isDefined);
8047 getter->setDeclImplementation(impControl);
8048 getter->setRelatedResultType(HasRelatedResultType);
8049 SetMemberOwningModule(member: getter, parent: class_interface_decl);
8050
8051 if (getter) {
8052 ast->SetMetadata(object: getter, metadata);
8053
8054 getter->setMethodParams(C&: clang_ast, Params: llvm::ArrayRef<clang::ParmVarDecl *>(),
8055 SelLocs: llvm::ArrayRef<clang::SourceLocation>());
8056 class_interface_decl->addDecl(D: getter);
8057 }
8058 }
8059 if (getter) {
8060 getter->setPropertyAccessor(true);
8061 property_decl->setGetterMethodDecl(getter);
8062 }
8063
8064 clang::ObjCMethodDecl *setter = nullptr;
8065 setter = isInstance ? class_interface_decl->lookupInstanceMethod(Sel: setter_sel)
8066 : class_interface_decl->lookupClassMethod(Sel: setter_sel);
8067 if (!setter_sel.isNull() && !setter) {
8068 clang::QualType result_type = clang_ast.VoidTy;
8069 const bool isVariadic = false;
8070 const bool isPropertyAccessor = true;
8071 const bool isSynthesizedAccessorStub = false;
8072 const bool isImplicitlyDeclared = true;
8073 const bool isDefined = false;
8074 const clang::ObjCImplementationControl impControl =
8075 clang::ObjCImplementationControl::None;
8076 const bool HasRelatedResultType = false;
8077
8078 setter =
8079 clang::ObjCMethodDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
8080 setter->setDeclName(setter_sel);
8081 setter->setReturnType(result_type);
8082 setter->setDeclContext(class_interface_decl);
8083 setter->setInstanceMethod(isInstance);
8084 setter->setVariadic(isVariadic);
8085 setter->setPropertyAccessor(isPropertyAccessor);
8086 setter->setSynthesizedAccessorStub(isSynthesizedAccessorStub);
8087 setter->setImplicit(isImplicitlyDeclared);
8088 setter->setDefined(isDefined);
8089 setter->setDeclImplementation(impControl);
8090 setter->setRelatedResultType(HasRelatedResultType);
8091 SetMemberOwningModule(member: setter, parent: class_interface_decl);
8092
8093 if (setter) {
8094 ast->SetMetadata(object: setter, metadata);
8095
8096 llvm::SmallVector<clang::ParmVarDecl *, 1> params;
8097 params.push_back(Elt: clang::ParmVarDecl::Create(
8098 C&: clang_ast, DC: setter, StartLoc: clang::SourceLocation(), IdLoc: clang::SourceLocation(),
8099 Id: nullptr, // anonymous
8100 T: ClangUtil::GetQualType(ct: property_clang_type_to_access), TInfo: nullptr,
8101 S: clang::SC_Auto, DefArg: nullptr));
8102
8103 setter->setMethodParams(C&: clang_ast,
8104 Params: llvm::ArrayRef<clang::ParmVarDecl *>(params),
8105 SelLocs: llvm::ArrayRef<clang::SourceLocation>());
8106
8107 class_interface_decl->addDecl(D: setter);
8108 }
8109 }
8110 if (setter) {
8111 setter->setPropertyAccessor(true);
8112 property_decl->setSetterMethodDecl(setter);
8113 }
8114
8115 return true;
8116}
8117
8118clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType(
8119 const CompilerType &type,
8120 const char *name, // the full symbol name as seen in the symbol table
8121 // (lldb::opaque_compiler_type_t type, "-[NString
8122 // stringWithCString:]")
8123 const CompilerType &method_clang_type, bool is_artificial, bool is_variadic,
8124 bool is_objc_direct_call) {
8125 if (!type || !method_clang_type.IsValid())
8126 return nullptr;
8127
8128 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8129
8130 if (class_interface_decl == nullptr)
8131 return nullptr;
8132 auto lldb_ast = type.GetTypeSystem<TypeSystemClang>();
8133 if (lldb_ast == nullptr)
8134 return nullptr;
8135 clang::ASTContext &ast = lldb_ast->getASTContext();
8136
8137 const char *selector_start = ::strchr(s: name, c: ' ');
8138 if (selector_start == nullptr)
8139 return nullptr;
8140
8141 selector_start++;
8142 llvm::SmallVector<const clang::IdentifierInfo *, 12> selector_idents;
8143
8144 size_t len = 0;
8145 const char *start;
8146
8147 unsigned num_selectors_with_args = 0;
8148 for (start = selector_start; start && *start != '\0' && *start != ']';
8149 start += len) {
8150 len = ::strcspn(s: start, reject: ":]");
8151 bool has_arg = (start[len] == ':');
8152 if (has_arg)
8153 ++num_selectors_with_args;
8154 selector_idents.push_back(Elt: &ast.Idents.get(Name: llvm::StringRef(start, len)));
8155 if (has_arg)
8156 len += 1;
8157 }
8158
8159 if (selector_idents.size() == 0)
8160 return nullptr;
8161
8162 clang::Selector method_selector = ast.Selectors.getSelector(
8163 NumArgs: num_selectors_with_args ? selector_idents.size() : 0,
8164 IIV: selector_idents.data());
8165
8166 clang::QualType method_qual_type(ClangUtil::GetQualType(ct: method_clang_type));
8167
8168 // Populate the method decl with parameter decls
8169 const clang::Type *method_type(method_qual_type.getTypePtr());
8170
8171 if (method_type == nullptr)
8172 return nullptr;
8173
8174 const clang::FunctionProtoType *method_function_prototype(
8175 llvm::dyn_cast<clang::FunctionProtoType>(Val: method_type));
8176
8177 if (!method_function_prototype)
8178 return nullptr;
8179
8180 const bool isInstance = (name[0] == '-');
8181 const bool isVariadic = is_variadic;
8182 const bool isPropertyAccessor = false;
8183 const bool isSynthesizedAccessorStub = false;
8184 /// Force this to true because we don't have source locations.
8185 const bool isImplicitlyDeclared = true;
8186 const bool isDefined = false;
8187 const clang::ObjCImplementationControl impControl =
8188 clang::ObjCImplementationControl::None;
8189 const bool HasRelatedResultType = false;
8190
8191 const unsigned num_args = method_function_prototype->getNumParams();
8192
8193 if (num_args != num_selectors_with_args)
8194 return nullptr; // some debug information is corrupt. We are not going to
8195 // deal with it.
8196
8197 auto *objc_method_decl =
8198 clang::ObjCMethodDecl::CreateDeserialized(C&: ast, ID: GlobalDeclID());
8199 objc_method_decl->setDeclName(method_selector);
8200 objc_method_decl->setReturnType(method_function_prototype->getReturnType());
8201 objc_method_decl->setDeclContext(
8202 lldb_ast->GetDeclContextForType(type: ClangUtil::GetQualType(ct: type)));
8203 objc_method_decl->setInstanceMethod(isInstance);
8204 objc_method_decl->setVariadic(isVariadic);
8205 objc_method_decl->setPropertyAccessor(isPropertyAccessor);
8206 objc_method_decl->setSynthesizedAccessorStub(isSynthesizedAccessorStub);
8207 objc_method_decl->setImplicit(isImplicitlyDeclared);
8208 objc_method_decl->setDefined(isDefined);
8209 objc_method_decl->setDeclImplementation(impControl);
8210 objc_method_decl->setRelatedResultType(HasRelatedResultType);
8211 SetMemberOwningModule(member: objc_method_decl, parent: class_interface_decl);
8212
8213 if (objc_method_decl == nullptr)
8214 return nullptr;
8215
8216 if (num_args > 0) {
8217 llvm::SmallVector<clang::ParmVarDecl *, 12> params;
8218
8219 for (unsigned param_index = 0; param_index < num_args; ++param_index) {
8220 params.push_back(Elt: clang::ParmVarDecl::Create(
8221 C&: ast, DC: objc_method_decl, StartLoc: clang::SourceLocation(),
8222 IdLoc: clang::SourceLocation(),
8223 Id: nullptr, // anonymous
8224 T: method_function_prototype->getParamType(i: param_index), TInfo: nullptr,
8225 S: clang::SC_Auto, DefArg: nullptr));
8226 }
8227
8228 objc_method_decl->setMethodParams(
8229 C&: ast, Params: llvm::ArrayRef<clang::ParmVarDecl *>(params),
8230 SelLocs: llvm::ArrayRef<clang::SourceLocation>());
8231 }
8232
8233 if (is_objc_direct_call) {
8234 // Add a the objc_direct attribute to the declaration we generate that
8235 // we generate a direct method call for this ObjCMethodDecl.
8236 objc_method_decl->addAttr(
8237 A: clang::ObjCDirectAttr::CreateImplicit(Ctx&: ast, Range: SourceLocation()));
8238 // Usually Sema is creating implicit parameters (e.g., self) when it
8239 // parses the method. We don't have a parsing Sema when we build our own
8240 // AST here so we manually need to create these implicit parameters to
8241 // make the direct call code generation happy.
8242 objc_method_decl->createImplicitParams(Context&: ast, ID: class_interface_decl);
8243 }
8244
8245 class_interface_decl->addDecl(D: objc_method_decl);
8246
8247 VerifyDecl(decl: objc_method_decl);
8248
8249 return objc_method_decl;
8250}
8251
8252bool TypeSystemClang::SetHasExternalStorage(lldb::opaque_compiler_type_t type,
8253 bool has_extern) {
8254 if (!type)
8255 return false;
8256
8257 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
8258
8259 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8260 switch (type_class) {
8261 case clang::Type::Record: {
8262 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
8263 if (cxx_record_decl) {
8264 cxx_record_decl->setHasExternalLexicalStorage(has_extern);
8265 cxx_record_decl->setHasExternalVisibleStorage(has_extern);
8266 return true;
8267 }
8268 } break;
8269
8270 case clang::Type::Enum: {
8271 clang::EnumDecl *enum_decl =
8272 llvm::cast<clang::EnumType>(Val&: qual_type)->getDecl();
8273 if (enum_decl) {
8274 enum_decl->setHasExternalLexicalStorage(has_extern);
8275 enum_decl->setHasExternalVisibleStorage(has_extern);
8276 return true;
8277 }
8278 } break;
8279
8280 case clang::Type::ObjCObject:
8281 case clang::Type::ObjCInterface: {
8282 const clang::ObjCObjectType *objc_class_type =
8283 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
8284 assert(objc_class_type);
8285 if (objc_class_type) {
8286 clang::ObjCInterfaceDecl *class_interface_decl =
8287 objc_class_type->getInterface();
8288
8289 if (class_interface_decl) {
8290 class_interface_decl->setHasExternalLexicalStorage(has_extern);
8291 class_interface_decl->setHasExternalVisibleStorage(has_extern);
8292 return true;
8293 }
8294 }
8295 } break;
8296
8297 default:
8298 break;
8299 }
8300 return false;
8301}
8302
8303#pragma mark TagDecl
8304
8305bool TypeSystemClang::StartTagDeclarationDefinition(const CompilerType &type) {
8306 clang::QualType qual_type(ClangUtil::GetQualType(ct: type));
8307 if (!qual_type.isNull()) {
8308 const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
8309 if (tag_type) {
8310 clang::TagDecl *tag_decl = tag_type->getDecl();
8311 if (tag_decl) {
8312 tag_decl->startDefinition();
8313 return true;
8314 }
8315 }
8316
8317 const clang::ObjCObjectType *object_type =
8318 qual_type->getAs<clang::ObjCObjectType>();
8319 if (object_type) {
8320 clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
8321 if (interface_decl) {
8322 interface_decl->startDefinition();
8323 return true;
8324 }
8325 }
8326 }
8327 return false;
8328}
8329
8330bool TypeSystemClang::CompleteTagDeclarationDefinition(
8331 const CompilerType &type) {
8332 clang::QualType qual_type(ClangUtil::GetQualType(ct: type));
8333 if (qual_type.isNull())
8334 return false;
8335
8336 auto lldb_ast = type.GetTypeSystem<TypeSystemClang>();
8337 if (lldb_ast == nullptr)
8338 return false;
8339
8340 // Make sure we use the same methodology as
8341 // TypeSystemClang::StartTagDeclarationDefinition() as to how we start/end
8342 // the definition.
8343 const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
8344 if (tag_type) {
8345 clang::TagDecl *tag_decl = tag_type->getDecl();
8346
8347 if (auto *cxx_record_decl = llvm::dyn_cast<CXXRecordDecl>(Val: tag_decl)) {
8348 // If we have a move constructor declared but no copy constructor we
8349 // need to explicitly mark it as deleted. Usually Sema would do this for
8350 // us in Sema::DeclareImplicitCopyConstructor but we don't have a Sema
8351 // when building an AST from debug information.
8352 // See also:
8353 // C++11 [class.copy]p7, p18:
8354 // If the class definition declares a move constructor or move assignment
8355 // operator, an implicitly declared copy constructor or copy assignment
8356 // operator is defined as deleted.
8357 if (cxx_record_decl->hasUserDeclaredMoveConstructor() ||
8358 cxx_record_decl->hasUserDeclaredMoveAssignment()) {
8359 if (cxx_record_decl->needsImplicitCopyConstructor())
8360 cxx_record_decl->setImplicitCopyConstructorIsDeleted();
8361 if (cxx_record_decl->needsImplicitCopyAssignment())
8362 cxx_record_decl->setImplicitCopyAssignmentIsDeleted();
8363 }
8364
8365 if (!cxx_record_decl->isCompleteDefinition())
8366 cxx_record_decl->completeDefinition();
8367 cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
8368 cxx_record_decl->setHasExternalLexicalStorage(false);
8369 cxx_record_decl->setHasExternalVisibleStorage(false);
8370 lldb_ast->SetCXXRecordDeclAccess(object: cxx_record_decl,
8371 access: clang::AccessSpecifier::AS_none);
8372 return true;
8373 }
8374 }
8375
8376 const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>();
8377
8378 if (!enutype)
8379 return false;
8380 clang::EnumDecl *enum_decl = enutype->getDecl();
8381
8382 if (enum_decl->isCompleteDefinition())
8383 return true;
8384
8385 QualType integer_type(enum_decl->getIntegerType());
8386 if (!integer_type.isNull()) {
8387 clang::ASTContext &ast = lldb_ast->getASTContext();
8388
8389 unsigned NumNegativeBits = 0;
8390 unsigned NumPositiveBits = 0;
8391 ast.computeEnumBits(EnumConstants: enum_decl->enumerators(), NumNegativeBits,
8392 NumPositiveBits);
8393
8394 clang::QualType BestPromotionType;
8395 clang::QualType BestType;
8396 ast.computeBestEnumTypes(/*IsPacked=*/false, NumNegativeBits,
8397 NumPositiveBits, BestType, BestPromotionType);
8398
8399 enum_decl->completeDefinition(NewType: enum_decl->getIntegerType(),
8400 PromotionType: BestPromotionType, NumPositiveBits,
8401 NumNegativeBits);
8402 }
8403 return true;
8404}
8405
8406clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
8407 const CompilerType &enum_type, const Declaration &decl, const char *name,
8408 const llvm::APSInt &value) {
8409
8410 if (!enum_type || ConstString(name).IsEmpty())
8411 return nullptr;
8412
8413 lldbassert(enum_type.GetTypeSystem().GetSharedPointer().get() ==
8414 static_cast<TypeSystem *>(this));
8415
8416 lldb::opaque_compiler_type_t enum_opaque_compiler_type =
8417 enum_type.GetOpaqueQualType();
8418
8419 if (!enum_opaque_compiler_type)
8420 return nullptr;
8421
8422 clang::QualType enum_qual_type(
8423 GetCanonicalQualType(type: enum_opaque_compiler_type));
8424
8425 const clang::Type *clang_type = enum_qual_type.getTypePtr();
8426
8427 if (!clang_type)
8428 return nullptr;
8429
8430 const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(Val: clang_type);
8431
8432 if (!enutype)
8433 return nullptr;
8434
8435 clang::EnumConstantDecl *enumerator_decl =
8436 clang::EnumConstantDecl::CreateDeserialized(C&: getASTContext(),
8437 ID: GlobalDeclID());
8438 enumerator_decl->setDeclContext(enutype->getDecl());
8439 if (name && name[0])
8440 enumerator_decl->setDeclName(&getASTContext().Idents.get(Name: name));
8441 enumerator_decl->setType(clang::QualType(enutype, 0));
8442 enumerator_decl->setInitVal(C: getASTContext(), V: value);
8443 SetMemberOwningModule(member: enumerator_decl, parent: enutype->getDecl());
8444
8445 if (!enumerator_decl)
8446 return nullptr;
8447
8448 enutype->getDecl()->addDecl(D: enumerator_decl);
8449
8450 VerifyDecl(decl: enumerator_decl);
8451 return enumerator_decl;
8452}
8453
8454clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
8455 const CompilerType &enum_type, const Declaration &decl, const char *name,
8456 uint64_t enum_value, uint32_t enum_value_bit_size) {
8457 assert(enum_type.IsEnumerationType());
8458 llvm::APSInt value(enum_value_bit_size,
8459 !enum_type.IsEnumerationIntegerTypeSigned());
8460 value = enum_value;
8461
8462 return AddEnumerationValueToEnumerationType(enum_type, decl, name, value);
8463}
8464
8465CompilerType TypeSystemClang::GetEnumerationIntegerType(CompilerType type) {
8466 clang::QualType qt(ClangUtil::GetQualType(ct: type));
8467 const clang::Type *clang_type = qt.getTypePtrOrNull();
8468 const auto *enum_type = llvm::dyn_cast_or_null<clang::EnumType>(Val: clang_type);
8469 if (!enum_type)
8470 return CompilerType();
8471
8472 return GetType(qt: enum_type->getDecl()->getIntegerType());
8473}
8474
8475CompilerType
8476TypeSystemClang::CreateMemberPointerType(const CompilerType &type,
8477 const CompilerType &pointee_type) {
8478 if (type && pointee_type.IsValid() &&
8479 type.GetTypeSystem() == pointee_type.GetTypeSystem()) {
8480 auto ast = type.GetTypeSystem<TypeSystemClang>();
8481 if (!ast)
8482 return CompilerType();
8483 return ast->GetType(qt: ast->getASTContext().getMemberPointerType(
8484 T: ClangUtil::GetQualType(ct: pointee_type),
8485 /*Qualifier=*/nullptr,
8486 Cls: ClangUtil::GetQualType(ct: type)->getAsCXXRecordDecl()));
8487 }
8488 return CompilerType();
8489}
8490
8491// Dumping types
8492#define DEPTH_INCREMENT 2
8493
8494#ifndef NDEBUG
8495LLVM_DUMP_METHOD void
8496TypeSystemClang::dump(lldb::opaque_compiler_type_t type) const {
8497 if (!type)
8498 return;
8499 clang::QualType qual_type(GetQualType(type));
8500 qual_type.dump();
8501}
8502#endif
8503
8504void TypeSystemClang::Dump(llvm::raw_ostream &output, llvm::StringRef filter) {
8505 auto consumer =
8506 clang::CreateASTDumper(OS&: output, FilterString: filter,
8507 /*DumpDecls=*/true,
8508 /*Deserialize=*/false,
8509 /*DumpLookups=*/false,
8510 /*DumpDeclTypes=*/false, Format: clang::ADOF_Default);
8511 assert(consumer);
8512 assert(m_ast_up);
8513 consumer->HandleTranslationUnit(Ctx&: *m_ast_up);
8514}
8515
8516void TypeSystemClang::DumpFromSymbolFile(Stream &s,
8517 llvm::StringRef symbol_name) {
8518 SymbolFile *symfile = GetSymbolFile();
8519
8520 if (!symfile)
8521 return;
8522
8523 lldb_private::TypeList type_list;
8524 symfile->GetTypes(sc_scope: nullptr, type_mask: eTypeClassAny, type_list);
8525 size_t ntypes = type_list.GetSize();
8526
8527 for (size_t i = 0; i < ntypes; ++i) {
8528 TypeSP type = type_list.GetTypeAtIndex(idx: i);
8529
8530 if (!symbol_name.empty())
8531 if (symbol_name != type->GetName().GetStringRef())
8532 continue;
8533
8534 s << type->GetName().AsCString() << "\n";
8535
8536 CompilerType full_type = type->GetFullCompilerType();
8537 if (clang::TagDecl *tag_decl = GetAsTagDecl(type: full_type)) {
8538 tag_decl->dump(Out&: s.AsRawOstream());
8539 continue;
8540 }
8541 if (clang::TypedefNameDecl *typedef_decl = GetAsTypedefDecl(type: full_type)) {
8542 typedef_decl->dump(Out&: s.AsRawOstream());
8543 continue;
8544 }
8545 if (auto *objc_obj = llvm::dyn_cast<clang::ObjCObjectType>(
8546 Val: ClangUtil::GetQualType(ct: full_type).getTypePtr())) {
8547 if (clang::ObjCInterfaceDecl *interface_decl = objc_obj->getInterface()) {
8548 interface_decl->dump(Out&: s.AsRawOstream());
8549 continue;
8550 }
8551 }
8552 GetCanonicalQualType(type: full_type.GetOpaqueQualType())
8553 .dump(OS&: s.AsRawOstream(), Context: getASTContext());
8554 }
8555}
8556
8557static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s,
8558 const DataExtractor &data, lldb::offset_t byte_offset,
8559 size_t byte_size, uint32_t bitfield_bit_offset,
8560 uint32_t bitfield_bit_size) {
8561 const clang::EnumType *enutype =
8562 llvm::cast<clang::EnumType>(Val: qual_type.getTypePtr());
8563 const clang::EnumDecl *enum_decl = enutype->getDecl();
8564 assert(enum_decl);
8565 lldb::offset_t offset = byte_offset;
8566 bool qual_type_is_signed = qual_type->isSignedIntegerOrEnumerationType();
8567 const uint64_t enum_svalue =
8568 qual_type_is_signed
8569 ? data.GetMaxS64Bitfield(offset_ptr: &offset, size: byte_size, bitfield_bit_size,
8570 bitfield_bit_offset)
8571 : data.GetMaxU64Bitfield(offset_ptr: &offset, size: byte_size, bitfield_bit_size,
8572 bitfield_bit_offset);
8573 bool can_be_bitfield = true;
8574 uint64_t covered_bits = 0;
8575 int num_enumerators = 0;
8576
8577 // Try to find an exact match for the value.
8578 // At the same time, we're applying a heuristic to determine whether we want
8579 // to print this enum as a bitfield. We're likely dealing with a bitfield if
8580 // every enumerator is either a one bit value or a superset of the previous
8581 // enumerators. Also 0 doesn't make sense when the enumerators are used as
8582 // flags.
8583 clang::EnumDecl::enumerator_range enumerators = enum_decl->enumerators();
8584 if (enumerators.empty())
8585 can_be_bitfield = false;
8586 else {
8587 for (auto *enumerator : enumerators) {
8588 llvm::APSInt init_val = enumerator->getInitVal();
8589 uint64_t val = qual_type_is_signed ? init_val.getSExtValue()
8590 : init_val.getZExtValue();
8591 if (qual_type_is_signed)
8592 val = llvm::SignExtend64(X: val, B: 8 * byte_size);
8593 if (llvm::popcount(Value: val) != 1 && (val & ~covered_bits) != 0)
8594 can_be_bitfield = false;
8595 covered_bits |= val;
8596 ++num_enumerators;
8597 if (val == enum_svalue) {
8598 // Found an exact match, that's all we need to do.
8599 s.PutCString(cstr: enumerator->getNameAsString());
8600 return true;
8601 }
8602 }
8603 }
8604
8605 // Unsigned values make more sense for flags.
8606 offset = byte_offset;
8607 const uint64_t enum_uvalue = data.GetMaxU64Bitfield(
8608 offset_ptr: &offset, size: byte_size, bitfield_bit_size, bitfield_bit_offset);
8609
8610 // No exact match, but we don't think this is a bitfield. Print the value as
8611 // decimal.
8612 if (!can_be_bitfield) {
8613 if (qual_type_is_signed)
8614 s.Printf(format: "%" PRIi64, enum_svalue);
8615 else
8616 s.Printf(format: "%" PRIu64, enum_uvalue);
8617 return true;
8618 }
8619
8620 if (!enum_uvalue) {
8621 // This is a bitfield enum, but the value is 0 so we know it won't match
8622 // with any of the enumerators.
8623 s.Printf(format: "0x%" PRIx64, enum_uvalue);
8624 return true;
8625 }
8626
8627 uint64_t remaining_value = enum_uvalue;
8628 std::vector<std::pair<uint64_t, llvm::StringRef>> values;
8629 values.reserve(n: num_enumerators);
8630 for (auto *enumerator : enum_decl->enumerators())
8631 if (auto val = enumerator->getInitVal().getZExtValue())
8632 values.emplace_back(args&: val, args: enumerator->getName());
8633
8634 // Sort in reverse order of the number of the population count, so that in
8635 // `enum {A, B, ALL = A|B }` we visit ALL first. Use a stable sort so that
8636 // A | C where A is declared before C is displayed in this order.
8637 llvm::stable_sort(Range&: values, C: [](const auto &a, const auto &b) {
8638 return llvm::popcount(a.first) > llvm::popcount(b.first);
8639 });
8640
8641 for (const auto &val : values) {
8642 if ((remaining_value & val.first) != val.first)
8643 continue;
8644 remaining_value &= ~val.first;
8645 s.PutCString(cstr: val.second);
8646 if (remaining_value)
8647 s.PutCString(cstr: " | ");
8648 }
8649
8650 // If there is a remainder that is not covered by the value, print it as
8651 // hex.
8652 if (remaining_value)
8653 s.Printf(format: "0x%" PRIx64, remaining_value);
8654
8655 return true;
8656}
8657
8658bool TypeSystemClang::DumpTypeValue(
8659 lldb::opaque_compiler_type_t type, Stream &s, lldb::Format format,
8660 const lldb_private::DataExtractor &data, lldb::offset_t byte_offset,
8661 size_t byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
8662 ExecutionContextScope *exe_scope) {
8663 if (!type)
8664 return false;
8665 if (IsAggregateType(type)) {
8666 return false;
8667 } else {
8668 clang::QualType qual_type(GetQualType(type));
8669
8670 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8671
8672 if (type_class == clang::Type::Elaborated) {
8673 qual_type = llvm::cast<clang::ElaboratedType>(Val&: qual_type)->getNamedType();
8674 return DumpTypeValue(type: qual_type.getAsOpaquePtr(), s, format, data, byte_offset, byte_size,
8675 bitfield_bit_size, bitfield_bit_offset, exe_scope);
8676 }
8677
8678 switch (type_class) {
8679 case clang::Type::Typedef: {
8680 clang::QualType typedef_qual_type =
8681 llvm::cast<clang::TypedefType>(Val&: qual_type)
8682 ->getDecl()
8683 ->getUnderlyingType();
8684 CompilerType typedef_clang_type = GetType(qt: typedef_qual_type);
8685 if (format == eFormatDefault)
8686 format = typedef_clang_type.GetFormat();
8687 clang::TypeInfo typedef_type_info =
8688 getASTContext().getTypeInfo(T: typedef_qual_type);
8689 uint64_t typedef_byte_size = typedef_type_info.Width / 8;
8690
8691 return typedef_clang_type.DumpTypeValue(
8692 s: &s,
8693 format, // The format with which to display the element
8694 data, // Data buffer containing all bytes for this type
8695 data_offset: byte_offset, // Offset into "data" where to grab value from
8696 data_byte_size: typedef_byte_size, // Size of this type in bytes
8697 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't
8698 // treat as a bitfield
8699 bitfield_bit_offset, // Offset in bits of a bitfield value if
8700 // bitfield_bit_size != 0
8701 exe_scope);
8702 } break;
8703
8704 case clang::Type::Enum:
8705 // If our format is enum or default, show the enumeration value as its
8706 // enumeration string value, else just display it as requested.
8707 if ((format == eFormatEnum || format == eFormatDefault) &&
8708 GetCompleteType(type))
8709 return DumpEnumValue(qual_type, s, data, byte_offset, byte_size,
8710 bitfield_bit_offset, bitfield_bit_size);
8711 // format was not enum, just fall through and dump the value as
8712 // requested....
8713 [[fallthrough]];
8714
8715 default:
8716 // We are down to a scalar type that we just need to display.
8717 {
8718 uint32_t item_count = 1;
8719 // A few formats, we might need to modify our size and count for
8720 // depending
8721 // on how we are trying to display the value...
8722 switch (format) {
8723 default:
8724 case eFormatBoolean:
8725 case eFormatBinary:
8726 case eFormatComplex:
8727 case eFormatCString: // NULL terminated C strings
8728 case eFormatDecimal:
8729 case eFormatEnum:
8730 case eFormatHex:
8731 case eFormatHexUppercase:
8732 case eFormatFloat:
8733 case eFormatOctal:
8734 case eFormatOSType:
8735 case eFormatUnsigned:
8736 case eFormatPointer:
8737 case eFormatVectorOfChar:
8738 case eFormatVectorOfSInt8:
8739 case eFormatVectorOfUInt8:
8740 case eFormatVectorOfSInt16:
8741 case eFormatVectorOfUInt16:
8742 case eFormatVectorOfSInt32:
8743 case eFormatVectorOfUInt32:
8744 case eFormatVectorOfSInt64:
8745 case eFormatVectorOfUInt64:
8746 case eFormatVectorOfFloat32:
8747 case eFormatVectorOfFloat64:
8748 case eFormatVectorOfUInt128:
8749 break;
8750
8751 case eFormatChar:
8752 case eFormatCharPrintable:
8753 case eFormatCharArray:
8754 case eFormatBytes:
8755 case eFormatUnicode8:
8756 case eFormatBytesWithASCII:
8757 item_count = byte_size;
8758 byte_size = 1;
8759 break;
8760
8761 case eFormatUnicode16:
8762 item_count = byte_size / 2;
8763 byte_size = 2;
8764 break;
8765
8766 case eFormatUnicode32:
8767 item_count = byte_size / 4;
8768 byte_size = 4;
8769 break;
8770 }
8771 return DumpDataExtractor(DE: data, s: &s, offset: byte_offset, item_format: format, item_byte_size: byte_size,
8772 item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
8773 item_bit_size: bitfield_bit_size, item_bit_offset: bitfield_bit_offset,
8774 exe_scope);
8775 }
8776 break;
8777 }
8778 }
8779 return false;
8780}
8781
8782void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
8783 lldb::DescriptionLevel level) {
8784 StreamFile s(stdout, false);
8785 DumpTypeDescription(type, s, level);
8786
8787 CompilerType ct(weak_from_this(), type);
8788 const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr();
8789 if (std::optional<ClangASTMetadata> metadata = GetMetadata(object: clang_type)) {
8790 metadata->Dump(s: &s);
8791 }
8792}
8793
8794void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
8795 Stream &s,
8796 lldb::DescriptionLevel level) {
8797 if (type) {
8798 clang::QualType qual_type =
8799 RemoveWrappingTypes(type: GetQualType(type), mask: {clang::Type::Typedef});
8800
8801 llvm::SmallVector<char, 1024> buf;
8802 llvm::raw_svector_ostream llvm_ostrm(buf);
8803
8804 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8805 switch (type_class) {
8806 case clang::Type::ObjCObject:
8807 case clang::Type::ObjCInterface: {
8808 GetCompleteType(type);
8809
8810 auto *objc_class_type =
8811 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
8812 assert(objc_class_type);
8813 if (!objc_class_type)
8814 break;
8815 clang::ObjCInterfaceDecl *class_interface_decl =
8816 objc_class_type->getInterface();
8817 if (!class_interface_decl)
8818 break;
8819 if (level == eDescriptionLevelVerbose)
8820 class_interface_decl->dump(Out&: llvm_ostrm);
8821 else
8822 class_interface_decl->print(Out&: llvm_ostrm,
8823 Policy: getASTContext().getPrintingPolicy(),
8824 Indentation: s.GetIndentLevel());
8825 } break;
8826
8827 case clang::Type::Typedef: {
8828 auto *typedef_type = qual_type->getAs<clang::TypedefType>();
8829 if (!typedef_type)
8830 break;
8831 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
8832 if (level == eDescriptionLevelVerbose)
8833 typedef_decl->dump(Out&: llvm_ostrm);
8834 else {
8835 std::string clang_typedef_name(GetTypeNameForDecl(named_decl: typedef_decl));
8836 if (!clang_typedef_name.empty()) {
8837 s.PutCString(cstr: "typedef ");
8838 s.PutCString(cstr: clang_typedef_name);
8839 }
8840 }
8841 } break;
8842
8843 case clang::Type::Record: {
8844 GetCompleteType(type);
8845
8846 auto *record_type = llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
8847 const clang::RecordDecl *record_decl = record_type->getDecl();
8848 if (level == eDescriptionLevelVerbose)
8849 record_decl->dump(Out&: llvm_ostrm);
8850 else {
8851 record_decl->print(Out&: llvm_ostrm, Policy: getASTContext().getPrintingPolicy(),
8852 Indentation: s.GetIndentLevel());
8853 }
8854 } break;
8855
8856 default: {
8857 if (auto *tag_type =
8858 llvm::dyn_cast<clang::TagType>(Val: qual_type.getTypePtr())) {
8859 if (clang::TagDecl *tag_decl = tag_type->getDecl()) {
8860 if (level == eDescriptionLevelVerbose)
8861 tag_decl->dump(Out&: llvm_ostrm);
8862 else
8863 tag_decl->print(Out&: llvm_ostrm, Indentation: 0);
8864 }
8865 } else {
8866 if (level == eDescriptionLevelVerbose)
8867 qual_type->dump(OS&: llvm_ostrm, Context: getASTContext());
8868 else {
8869 std::string clang_type_name(qual_type.getAsString());
8870 if (!clang_type_name.empty())
8871 s.PutCString(cstr: clang_type_name);
8872 }
8873 }
8874 }
8875 }
8876
8877 if (buf.size() > 0) {
8878 s.Write(src: buf.data(), src_len: buf.size());
8879 }
8880}
8881}
8882
8883void TypeSystemClang::DumpTypeName(const CompilerType &type) {
8884 if (ClangUtil::IsClangType(ct: type)) {
8885 clang::QualType qual_type(
8886 ClangUtil::GetCanonicalQualType(ct: ClangUtil::RemoveFastQualifiers(ct: type)));
8887
8888 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8889 switch (type_class) {
8890 case clang::Type::Record: {
8891 const clang::CXXRecordDecl *cxx_record_decl =
8892 qual_type->getAsCXXRecordDecl();
8893 if (cxx_record_decl)
8894 printf(format: "class %s", cxx_record_decl->getName().str().c_str());
8895 } break;
8896
8897 case clang::Type::Enum: {
8898 clang::EnumDecl *enum_decl =
8899 llvm::cast<clang::EnumType>(Val&: qual_type)->getDecl();
8900 if (enum_decl) {
8901 printf(format: "enum %s", enum_decl->getName().str().c_str());
8902 }
8903 } break;
8904
8905 case clang::Type::ObjCObject:
8906 case clang::Type::ObjCInterface: {
8907 const clang::ObjCObjectType *objc_class_type =
8908 llvm::dyn_cast<clang::ObjCObjectType>(Val&: qual_type);
8909 if (objc_class_type) {
8910 clang::ObjCInterfaceDecl *class_interface_decl =
8911 objc_class_type->getInterface();
8912 // We currently can't complete objective C types through the newly
8913 // added ASTContext because it only supports TagDecl objects right
8914 // now...
8915 if (class_interface_decl)
8916 printf(format: "@class %s", class_interface_decl->getName().str().c_str());
8917 }
8918 } break;
8919
8920 case clang::Type::Typedef:
8921 printf(format: "typedef %s", llvm::cast<clang::TypedefType>(Val&: qual_type)
8922 ->getDecl()
8923 ->getName()
8924 .str()
8925 .c_str());
8926 break;
8927
8928 case clang::Type::Auto:
8929 printf(format: "auto ");
8930 return DumpTypeName(type: CompilerType(type.GetTypeSystem(),
8931 llvm::cast<clang::AutoType>(Val&: qual_type)
8932 ->getDeducedType()
8933 .getAsOpaquePtr()));
8934
8935 case clang::Type::Elaborated:
8936 printf(format: "elaborated ");
8937 return DumpTypeName(type: CompilerType(
8938 type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(Val&: qual_type)
8939 ->getNamedType()
8940 .getAsOpaquePtr()));
8941
8942 case clang::Type::Paren:
8943 printf(format: "paren ");
8944 return DumpTypeName(type: CompilerType(
8945 type.GetTypeSystem(),
8946 llvm::cast<clang::ParenType>(Val&: qual_type)->desugar().getAsOpaquePtr()));
8947
8948 default:
8949 printf(format: "TypeSystemClang::DumpTypeName() type_class = %u", type_class);
8950 break;
8951 }
8952 }
8953}
8954
8955clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl(
8956 clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
8957 lldb::AccessType access_type, const char *parent_name, int tag_decl_kind,
8958 const TypeSystemClang::TemplateParameterInfos &template_param_infos) {
8959 if (template_param_infos.IsValid()) {
8960 std::string template_basename(parent_name);
8961 // With -gsimple-template-names we may omit template parameters in the name.
8962 if (auto i = template_basename.find(c: '<'); i != std::string::npos)
8963 template_basename.erase(pos: i);
8964
8965 return CreateClassTemplateDecl(decl_ctx, owning_module, access_type,
8966 class_name: template_basename.c_str(), kind: tag_decl_kind,
8967 template_param_infos);
8968 }
8969 return nullptr;
8970}
8971
8972void TypeSystemClang::CompleteTagDecl(clang::TagDecl *decl) {
8973 SymbolFile *sym_file = GetSymbolFile();
8974 if (sym_file) {
8975 CompilerType clang_type = GetTypeForDecl(decl);
8976 if (clang_type)
8977 sym_file->CompleteType(compiler_type&: clang_type);
8978 }
8979}
8980
8981void TypeSystemClang::CompleteObjCInterfaceDecl(
8982 clang::ObjCInterfaceDecl *decl) {
8983 SymbolFile *sym_file = GetSymbolFile();
8984 if (sym_file) {
8985 CompilerType clang_type = GetTypeForDecl(decl);
8986 if (clang_type)
8987 sym_file->CompleteType(compiler_type&: clang_type);
8988 }
8989}
8990
8991DWARFASTParser *TypeSystemClang::GetDWARFParser() {
8992 if (!m_dwarf_ast_parser_up)
8993 m_dwarf_ast_parser_up = std::make_unique<DWARFASTParserClang>(args&: *this);
8994 return m_dwarf_ast_parser_up.get();
8995}
8996
8997PDBASTParser *TypeSystemClang::GetPDBParser() {
8998 if (!m_pdb_ast_parser_up)
8999 m_pdb_ast_parser_up = std::make_unique<PDBASTParser>(args&: *this);
9000 return m_pdb_ast_parser_up.get();
9001}
9002
9003npdb::PdbAstBuilder *TypeSystemClang::GetNativePDBParser() {
9004 if (!m_native_pdb_ast_parser_up)
9005 m_native_pdb_ast_parser_up = std::make_unique<npdb::PdbAstBuilder>(args&: *this);
9006 return m_native_pdb_ast_parser_up.get();
9007}
9008
9009bool TypeSystemClang::LayoutRecordType(
9010 const clang::RecordDecl *record_decl, uint64_t &bit_size,
9011 uint64_t &alignment,
9012 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
9013 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
9014 &base_offsets,
9015 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
9016 &vbase_offsets) {
9017 lldb_private::ClangASTImporter *importer = nullptr;
9018 if (m_dwarf_ast_parser_up)
9019 importer = &m_dwarf_ast_parser_up->GetClangASTImporter();
9020 if (!importer && m_pdb_ast_parser_up)
9021 importer = &m_pdb_ast_parser_up->GetClangASTImporter();
9022 if (!importer && m_native_pdb_ast_parser_up)
9023 importer = &m_native_pdb_ast_parser_up->GetClangASTImporter();
9024 if (!importer)
9025 return false;
9026
9027 return importer->LayoutRecordType(record_decl, bit_size, alignment,
9028 field_offsets, base_offsets, vbase_offsets);
9029}
9030
9031// CompilerDecl override functions
9032
9033ConstString TypeSystemClang::DeclGetName(void *opaque_decl) {
9034 if (opaque_decl) {
9035 clang::NamedDecl *nd =
9036 llvm::dyn_cast<NamedDecl>(Val: (clang::Decl *)opaque_decl);
9037 if (nd != nullptr)
9038 return ConstString(GetTypeNameForDecl(named_decl: nd, /*qualified=*/false));
9039 }
9040 return ConstString();
9041}
9042
9043ConstString TypeSystemClang::DeclGetMangledName(void *opaque_decl) {
9044 clang::NamedDecl *nd = llvm::dyn_cast_or_null<clang::NamedDecl>(
9045 Val: static_cast<clang::Decl *>(opaque_decl));
9046
9047 if (!nd || llvm::isa<clang::ObjCMethodDecl>(Val: nd))
9048 return {};
9049
9050 clang::MangleContext *mc = getMangleContext();
9051 if (!mc || !mc->shouldMangleCXXName(D: nd))
9052 return {};
9053
9054 llvm::SmallVector<char, 1024> buf;
9055 llvm::raw_svector_ostream llvm_ostrm(buf);
9056 if (llvm::isa<clang::CXXConstructorDecl>(Val: nd)) {
9057 mc->mangleName(
9058 GD: clang::GlobalDecl(llvm::dyn_cast<clang::CXXConstructorDecl>(Val: nd),
9059 Ctor_Complete),
9060 llvm_ostrm);
9061 } else if (llvm::isa<clang::CXXDestructorDecl>(Val: nd)) {
9062 mc->mangleName(
9063 GD: clang::GlobalDecl(llvm::dyn_cast<clang::CXXDestructorDecl>(Val: nd),
9064 Dtor_Complete),
9065 llvm_ostrm);
9066 } else {
9067 mc->mangleName(GD: nd, llvm_ostrm);
9068 }
9069
9070 if (buf.size() > 0)
9071 return ConstString(buf.data(), buf.size());
9072
9073 return {};
9074}
9075
9076CompilerDeclContext TypeSystemClang::DeclGetDeclContext(void *opaque_decl) {
9077 if (opaque_decl)
9078 return CreateDeclContext(ctx: ((clang::Decl *)opaque_decl)->getDeclContext());
9079 return CompilerDeclContext();
9080}
9081
9082CompilerType TypeSystemClang::DeclGetFunctionReturnType(void *opaque_decl) {
9083 if (clang::FunctionDecl *func_decl =
9084 llvm::dyn_cast<clang::FunctionDecl>(Val: (clang::Decl *)opaque_decl))
9085 return GetType(qt: func_decl->getReturnType());
9086 if (clang::ObjCMethodDecl *objc_method =
9087 llvm::dyn_cast<clang::ObjCMethodDecl>(Val: (clang::Decl *)opaque_decl))
9088 return GetType(qt: objc_method->getReturnType());
9089 else
9090 return CompilerType();
9091}
9092
9093size_t TypeSystemClang::DeclGetFunctionNumArguments(void *opaque_decl) {
9094 if (clang::FunctionDecl *func_decl =
9095 llvm::dyn_cast<clang::FunctionDecl>(Val: (clang::Decl *)opaque_decl))
9096 return func_decl->param_size();
9097 if (clang::ObjCMethodDecl *objc_method =
9098 llvm::dyn_cast<clang::ObjCMethodDecl>(Val: (clang::Decl *)opaque_decl))
9099 return objc_method->param_size();
9100 else
9101 return 0;
9102}
9103
9104static CompilerContextKind GetCompilerKind(clang::Decl::Kind clang_kind,
9105 clang::DeclContext const *decl_ctx) {
9106 switch (clang_kind) {
9107 case Decl::TranslationUnit:
9108 return CompilerContextKind::TranslationUnit;
9109 case Decl::Namespace:
9110 return CompilerContextKind::Namespace;
9111 case Decl::Var:
9112 return CompilerContextKind::Variable;
9113 case Decl::Enum:
9114 return CompilerContextKind::Enum;
9115 case Decl::Typedef:
9116 return CompilerContextKind::Typedef;
9117 default:
9118 // Many other kinds have multiple values
9119 if (decl_ctx) {
9120 if (decl_ctx->isFunctionOrMethod())
9121 return CompilerContextKind::Function;
9122 if (decl_ctx->isRecord())
9123 return CompilerContextKind::ClassOrStruct | CompilerContextKind::Union;
9124 }
9125 break;
9126 }
9127 return CompilerContextKind::Any;
9128}
9129
9130static void
9131InsertCompilerContext(TypeSystemClang *ts, clang::DeclContext *decl_ctx,
9132 std::vector<lldb_private::CompilerContext> &context) {
9133 if (decl_ctx == nullptr)
9134 return;
9135 InsertCompilerContext(ts, decl_ctx: decl_ctx->getParent(), context);
9136 clang::Decl::Kind clang_kind = decl_ctx->getDeclKind();
9137 if (clang_kind == Decl::TranslationUnit)
9138 return; // Stop at the translation unit.
9139 const CompilerContextKind compiler_kind =
9140 GetCompilerKind(clang_kind, decl_ctx);
9141 ConstString decl_ctx_name = ts->DeclContextGetName(opaque_decl_ctx: decl_ctx);
9142 context.push_back(x: {compiler_kind, decl_ctx_name});
9143}
9144
9145std::vector<lldb_private::CompilerContext>
9146TypeSystemClang::DeclGetCompilerContext(void *opaque_decl) {
9147 std::vector<lldb_private::CompilerContext> context;
9148 ConstString decl_name = DeclGetName(opaque_decl);
9149 if (decl_name) {
9150 clang::Decl *decl = (clang::Decl *)opaque_decl;
9151 // Add the entire decl context first
9152 clang::DeclContext *decl_ctx = decl->getDeclContext();
9153 InsertCompilerContext(ts: this, decl_ctx, context);
9154 // Now add the decl information
9155 auto compiler_kind =
9156 GetCompilerKind(clang_kind: decl->getKind(), decl_ctx: dyn_cast<DeclContext>(Val: decl));
9157 context.push_back(x: {compiler_kind, decl_name});
9158 }
9159 return context;
9160}
9161
9162CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl,
9163 size_t idx) {
9164 if (clang::FunctionDecl *func_decl =
9165 llvm::dyn_cast<clang::FunctionDecl>(Val: (clang::Decl *)opaque_decl)) {
9166 if (idx < func_decl->param_size()) {
9167 ParmVarDecl *var_decl = func_decl->getParamDecl(i: idx);
9168 if (var_decl)
9169 return GetType(qt: var_decl->getOriginalType());
9170 }
9171 } else if (clang::ObjCMethodDecl *objc_method =
9172 llvm::dyn_cast<clang::ObjCMethodDecl>(
9173 Val: (clang::Decl *)opaque_decl)) {
9174 if (idx < objc_method->param_size())
9175 return GetType(qt: objc_method->parameters()[idx]->getOriginalType());
9176 }
9177 return CompilerType();
9178}
9179
9180Scalar TypeSystemClang::DeclGetConstantValue(void *opaque_decl) {
9181 clang::Decl *decl = static_cast<clang::Decl *>(opaque_decl);
9182 clang::VarDecl *var_decl = llvm::dyn_cast<clang::VarDecl>(Val: decl);
9183 if (!var_decl)
9184 return Scalar();
9185 clang::Expr *init_expr = var_decl->getInit();
9186 if (!init_expr)
9187 return Scalar();
9188 std::optional<llvm::APSInt> value =
9189 init_expr->getIntegerConstantExpr(Ctx: getASTContext());
9190 if (!value)
9191 return Scalar();
9192 return Scalar(*value);
9193}
9194
9195// CompilerDeclContext functions
9196
9197std::vector<CompilerDecl> TypeSystemClang::DeclContextFindDeclByName(
9198 void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) {
9199 std::vector<CompilerDecl> found_decls;
9200 SymbolFile *symbol_file = GetSymbolFile();
9201 if (opaque_decl_ctx && symbol_file) {
9202 DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
9203 std::set<DeclContext *> searched;
9204 std::multimap<DeclContext *, DeclContext *> search_queue;
9205
9206 for (clang::DeclContext *decl_context = root_decl_ctx;
9207 decl_context != nullptr && found_decls.empty();
9208 decl_context = decl_context->getParent()) {
9209 search_queue.insert(x: std::make_pair(x&: decl_context, y&: decl_context));
9210
9211 for (auto it = search_queue.find(x: decl_context); it != search_queue.end();
9212 it++) {
9213 if (!searched.insert(x: it->second).second)
9214 continue;
9215 symbol_file->ParseDeclsForContext(
9216 decl_ctx: CreateDeclContext(ctx: it->second));
9217
9218 for (clang::Decl *child : it->second->decls()) {
9219 if (clang::UsingDirectiveDecl *ud =
9220 llvm::dyn_cast<clang::UsingDirectiveDecl>(Val: child)) {
9221 if (ignore_using_decls)
9222 continue;
9223 clang::DeclContext *from = ud->getCommonAncestor();
9224 if (searched.find(x: ud->getNominatedNamespace()) == searched.end())
9225 search_queue.insert(
9226 x: std::make_pair(x&: from, y: ud->getNominatedNamespace()));
9227 } else if (clang::UsingDecl *ud =
9228 llvm::dyn_cast<clang::UsingDecl>(Val: child)) {
9229 if (ignore_using_decls)
9230 continue;
9231 for (clang::UsingShadowDecl *usd : ud->shadows()) {
9232 clang::Decl *target = usd->getTargetDecl();
9233 if (clang::NamedDecl *nd =
9234 llvm::dyn_cast<clang::NamedDecl>(Val: target)) {
9235 IdentifierInfo *ii = nd->getIdentifier();
9236 if (ii != nullptr && ii->getName() == name.AsCString(value_if_empty: nullptr))
9237 found_decls.push_back(x: GetCompilerDecl(decl: nd));
9238 }
9239 }
9240 } else if (clang::NamedDecl *nd =
9241 llvm::dyn_cast<clang::NamedDecl>(Val: child)) {
9242 IdentifierInfo *ii = nd->getIdentifier();
9243 if (ii != nullptr && ii->getName() == name.AsCString(value_if_empty: nullptr))
9244 found_decls.push_back(x: GetCompilerDecl(decl: nd));
9245 }
9246 }
9247 }
9248 }
9249 }
9250 return found_decls;
9251}
9252
9253// Look for child_decl_ctx's lookup scope in frame_decl_ctx and its parents,
9254// and return the number of levels it took to find it, or
9255// LLDB_INVALID_DECL_LEVEL if not found. If the decl was imported via a using
9256// declaration, its name and/or type, if set, will be used to check that the
9257// decl found in the scope is a match.
9258//
9259// The optional name is required by languages (like C++) to handle using
9260// declarations like:
9261//
9262// void poo();
9263// namespace ns {
9264// void foo();
9265// void goo();
9266// }
9267// void bar() {
9268// using ns::foo;
9269// // CountDeclLevels returns 0 for 'foo', 1 for 'poo', and
9270// // LLDB_INVALID_DECL_LEVEL for 'goo'.
9271// }
9272//
9273// The optional type is useful in the case that there's a specific overload
9274// that we're looking for that might otherwise be shadowed, like:
9275//
9276// void foo(int);
9277// namespace ns {
9278// void foo();
9279// }
9280// void bar() {
9281// using ns::foo;
9282// // CountDeclLevels returns 0 for { 'foo', void() },
9283// // 1 for { 'foo', void(int) }, and
9284// // LLDB_INVALID_DECL_LEVEL for { 'foo', void(int, int) }.
9285// }
9286//
9287// NOTE: Because file statics are at the TranslationUnit along with globals, a
9288// function at file scope will return the same level as a function at global
9289// scope. Ideally we'd like to treat the file scope as an additional scope just
9290// below the global scope. More work needs to be done to recognise that, if
9291// the decl we're trying to look up is static, we should compare its source
9292// file with that of the current scope and return a lower number for it.
9293uint32_t TypeSystemClang::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
9294 clang::DeclContext *child_decl_ctx,
9295 ConstString *child_name,
9296 CompilerType *child_type) {
9297 SymbolFile *symbol_file = GetSymbolFile();
9298 if (frame_decl_ctx && symbol_file) {
9299 std::set<DeclContext *> searched;
9300 std::multimap<DeclContext *, DeclContext *> search_queue;
9301
9302 // Get the lookup scope for the decl we're trying to find.
9303 clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent();
9304
9305 // Look for it in our scope's decl context and its parents.
9306 uint32_t level = 0;
9307 for (clang::DeclContext *decl_ctx = frame_decl_ctx; decl_ctx != nullptr;
9308 decl_ctx = decl_ctx->getParent()) {
9309 if (!decl_ctx->isLookupContext())
9310 continue;
9311 if (decl_ctx == parent_decl_ctx)
9312 // Found it!
9313 return level;
9314 search_queue.insert(x: std::make_pair(x&: decl_ctx, y&: decl_ctx));
9315 for (auto it = search_queue.find(x: decl_ctx); it != search_queue.end();
9316 it++) {
9317 if (searched.find(x: it->second) != searched.end())
9318 continue;
9319
9320 // Currently DWARF has one shared translation unit for all Decls at top
9321 // level, so this would erroneously find using statements anywhere. So
9322 // don't look at the top-level translation unit.
9323 // TODO fix this and add a testcase that depends on it.
9324
9325 if (llvm::isa<clang::TranslationUnitDecl>(Val: it->second))
9326 continue;
9327
9328 searched.insert(x: it->second);
9329 symbol_file->ParseDeclsForContext(
9330 decl_ctx: CreateDeclContext(ctx: it->second));
9331
9332 for (clang::Decl *child : it->second->decls()) {
9333 if (clang::UsingDirectiveDecl *ud =
9334 llvm::dyn_cast<clang::UsingDirectiveDecl>(Val: child)) {
9335 clang::DeclContext *ns = ud->getNominatedNamespace();
9336 if (ns == parent_decl_ctx)
9337 // Found it!
9338 return level;
9339 clang::DeclContext *from = ud->getCommonAncestor();
9340 if (searched.find(x: ns) == searched.end())
9341 search_queue.insert(x: std::make_pair(x&: from, y&: ns));
9342 } else if (child_name) {
9343 if (clang::UsingDecl *ud =
9344 llvm::dyn_cast<clang::UsingDecl>(Val: child)) {
9345 for (clang::UsingShadowDecl *usd : ud->shadows()) {
9346 clang::Decl *target = usd->getTargetDecl();
9347 clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(Val: target);
9348 if (!nd)
9349 continue;
9350 // Check names.
9351 IdentifierInfo *ii = nd->getIdentifier();
9352 if (ii == nullptr ||
9353 ii->getName() != child_name->AsCString(value_if_empty: nullptr))
9354 continue;
9355 // Check types, if one was provided.
9356 if (child_type) {
9357 CompilerType clang_type = GetTypeForDecl(decl: nd);
9358 if (!AreTypesSame(type1: clang_type, type2: *child_type,
9359 /*ignore_qualifiers=*/true))
9360 continue;
9361 }
9362 // Found it!
9363 return level;
9364 }
9365 }
9366 }
9367 }
9368 }
9369 ++level;
9370 }
9371 }
9372 return LLDB_INVALID_DECL_LEVEL;
9373}
9374
9375ConstString TypeSystemClang::DeclContextGetName(void *opaque_decl_ctx) {
9376 if (opaque_decl_ctx) {
9377 clang::NamedDecl *named_decl =
9378 llvm::dyn_cast<clang::NamedDecl>(Val: (clang::DeclContext *)opaque_decl_ctx);
9379 if (named_decl) {
9380 std::string name;
9381 llvm::raw_string_ostream stream{name};
9382 auto policy = GetTypePrintingPolicy();
9383 policy.AlwaysIncludeTypeForTemplateArgument = true;
9384 named_decl->getNameForDiagnostic(OS&: stream, Policy: policy, /*qualified=*/Qualified: false);
9385 return ConstString(name);
9386 }
9387 }
9388 return ConstString();
9389}
9390
9391ConstString
9392TypeSystemClang::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) {
9393 if (opaque_decl_ctx) {
9394 clang::NamedDecl *named_decl =
9395 llvm::dyn_cast<clang::NamedDecl>(Val: (clang::DeclContext *)opaque_decl_ctx);
9396 if (named_decl)
9397 return ConstString(GetTypeNameForDecl(named_decl));
9398 }
9399 return ConstString();
9400}
9401
9402bool TypeSystemClang::DeclContextIsClassMethod(void *opaque_decl_ctx) {
9403 if (!opaque_decl_ctx)
9404 return false;
9405
9406 clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
9407 if (llvm::isa<clang::ObjCMethodDecl>(Val: decl_ctx)) {
9408 return true;
9409 } else if (llvm::isa<clang::CXXMethodDecl>(Val: decl_ctx)) {
9410 return true;
9411 } else if (clang::FunctionDecl *fun_decl =
9412 llvm::dyn_cast<clang::FunctionDecl>(Val: decl_ctx)) {
9413 if (std::optional<ClangASTMetadata> metadata = GetMetadata(object: fun_decl))
9414 return metadata->HasObjectPtr();
9415 }
9416
9417 return false;
9418}
9419
9420std::vector<lldb_private::CompilerContext>
9421TypeSystemClang::DeclContextGetCompilerContext(void *opaque_decl_ctx) {
9422 auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
9423 std::vector<lldb_private::CompilerContext> context;
9424 InsertCompilerContext(ts: this, decl_ctx, context);
9425 return context;
9426}
9427
9428bool TypeSystemClang::DeclContextIsContainedInLookup(
9429 void *opaque_decl_ctx, void *other_opaque_decl_ctx) {
9430 auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
9431 auto *other = (clang::DeclContext *)other_opaque_decl_ctx;
9432
9433 // If we have an inline or anonymous namespace, then the lookup of the
9434 // parent context also includes those namespace contents.
9435 auto is_transparent_lookup_allowed = [](clang::DeclContext *DC) {
9436 if (DC->isInlineNamespace())
9437 return true;
9438
9439 if (auto const *NS = dyn_cast<NamespaceDecl>(Val: DC))
9440 return NS->isAnonymousNamespace();
9441
9442 return false;
9443 };
9444
9445 do {
9446 // A decl context always includes its own contents in its lookup.
9447 if (decl_ctx == other)
9448 return true;
9449 } while (is_transparent_lookup_allowed(other) &&
9450 (other = other->getParent()));
9451
9452 return false;
9453}
9454
9455lldb::LanguageType
9456TypeSystemClang::DeclContextGetLanguage(void *opaque_decl_ctx) {
9457 if (!opaque_decl_ctx)
9458 return eLanguageTypeUnknown;
9459
9460 auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
9461 if (llvm::isa<clang::ObjCMethodDecl>(Val: decl_ctx)) {
9462 return eLanguageTypeObjC;
9463 } else if (llvm::isa<clang::CXXMethodDecl>(Val: decl_ctx)) {
9464 return eLanguageTypeC_plus_plus;
9465 } else if (auto *fun_decl = llvm::dyn_cast<clang::FunctionDecl>(Val: decl_ctx)) {
9466 if (std::optional<ClangASTMetadata> metadata = GetMetadata(object: fun_decl))
9467 return metadata->GetObjectPtrLanguage();
9468 }
9469
9470 return eLanguageTypeUnknown;
9471}
9472
9473static bool IsClangDeclContext(const CompilerDeclContext &dc) {
9474 return dc.IsValid() && isa<TypeSystemClang>(Val: dc.GetTypeSystem());
9475}
9476
9477clang::DeclContext *
9478TypeSystemClang::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) {
9479 if (IsClangDeclContext(dc))
9480 return (clang::DeclContext *)dc.GetOpaqueDeclContext();
9481 return nullptr;
9482}
9483
9484ObjCMethodDecl *
9485TypeSystemClang::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) {
9486 if (IsClangDeclContext(dc))
9487 return llvm::dyn_cast<clang::ObjCMethodDecl>(
9488 Val: (clang::DeclContext *)dc.GetOpaqueDeclContext());
9489 return nullptr;
9490}
9491
9492CXXMethodDecl *
9493TypeSystemClang::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) {
9494 if (IsClangDeclContext(dc))
9495 return llvm::dyn_cast<clang::CXXMethodDecl>(
9496 Val: (clang::DeclContext *)dc.GetOpaqueDeclContext());
9497 return nullptr;
9498}
9499
9500clang::FunctionDecl *
9501TypeSystemClang::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) {
9502 if (IsClangDeclContext(dc))
9503 return llvm::dyn_cast<clang::FunctionDecl>(
9504 Val: (clang::DeclContext *)dc.GetOpaqueDeclContext());
9505 return nullptr;
9506}
9507
9508clang::NamespaceDecl *
9509TypeSystemClang::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) {
9510 if (IsClangDeclContext(dc))
9511 return llvm::dyn_cast<clang::NamespaceDecl>(
9512 Val: (clang::DeclContext *)dc.GetOpaqueDeclContext());
9513 return nullptr;
9514}
9515
9516std::optional<ClangASTMetadata>
9517TypeSystemClang::DeclContextGetMetaData(const CompilerDeclContext &dc,
9518 const Decl *object) {
9519 TypeSystemClang *ast = llvm::cast<TypeSystemClang>(Val: dc.GetTypeSystem());
9520 return ast->GetMetadata(object);
9521}
9522
9523clang::ASTContext *
9524TypeSystemClang::DeclContextGetTypeSystemClang(const CompilerDeclContext &dc) {
9525 TypeSystemClang *ast =
9526 llvm::dyn_cast_or_null<TypeSystemClang>(Val: dc.GetTypeSystem());
9527 if (ast)
9528 return &ast->getASTContext();
9529 return nullptr;
9530}
9531
9532void TypeSystemClang::RequireCompleteType(CompilerType type) {
9533 // Technically, enums can be incomplete too, but we don't handle those as they
9534 // are emitted even under -flimit-debug-info.
9535 if (!TypeSystemClang::IsCXXClassType(type))
9536 return;
9537
9538 if (type.GetCompleteType())
9539 return;
9540
9541 // No complete definition in this module. Mark the class as complete to
9542 // satisfy local ast invariants, but make a note of the fact that
9543 // it is not _really_ complete so we can later search for a definition in a
9544 // different module.
9545 // Since we provide layout assistance, layouts of types containing this class
9546 // will be correct even if we are not able to find the definition elsewhere.
9547 bool started = TypeSystemClang::StartTagDeclarationDefinition(type);
9548 lldbassert(started && "Unable to start a class type definition.");
9549 TypeSystemClang::CompleteTagDeclarationDefinition(type);
9550 const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type);
9551 auto ts = type.GetTypeSystem<TypeSystemClang>();
9552 if (ts)
9553 ts->SetDeclIsForcefullyCompleted(td);
9554}
9555
9556namespace {
9557/// A specialized scratch AST used within ScratchTypeSystemClang.
9558/// These are the ASTs backing the different IsolatedASTKinds. They behave
9559/// like a normal ScratchTypeSystemClang but they don't own their own
9560/// persistent storage or target reference.
9561class SpecializedScratchAST : public TypeSystemClang {
9562public:
9563 /// \param name The display name of the TypeSystemClang instance.
9564 /// \param triple The triple used for the TypeSystemClang instance.
9565 /// \param ast_source The ClangASTSource that should be used to complete
9566 /// type information.
9567 SpecializedScratchAST(llvm::StringRef name, llvm::Triple triple,
9568 std::unique_ptr<ClangASTSource> ast_source)
9569 : TypeSystemClang(name, triple),
9570 m_scratch_ast_source_up(std::move(ast_source)) {
9571 // Setup the ClangASTSource to complete this AST.
9572 m_scratch_ast_source_up->InstallASTContext(ast_context&: *this);
9573 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
9574 m_scratch_ast_source_up->CreateProxy());
9575 SetExternalSource(proxy_ast_source);
9576 }
9577
9578 /// The ExternalASTSource that performs lookups and completes types.
9579 std::unique_ptr<ClangASTSource> m_scratch_ast_source_up;
9580};
9581} // namespace
9582
9583char ScratchTypeSystemClang::ID;
9584const std::nullopt_t ScratchTypeSystemClang::DefaultAST = std::nullopt;
9585
9586ScratchTypeSystemClang::ScratchTypeSystemClang(Target &target,
9587 llvm::Triple triple)
9588 : TypeSystemClang("scratch ASTContext", triple), m_triple(triple),
9589 m_target_wp(target.shared_from_this()),
9590 m_persistent_variables(
9591 new ClangPersistentVariables(target.shared_from_this())) {
9592 m_scratch_ast_source_up = CreateASTSource();
9593 m_scratch_ast_source_up->InstallASTContext(ast_context&: *this);
9594 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
9595 m_scratch_ast_source_up->CreateProxy());
9596 SetExternalSource(proxy_ast_source);
9597}
9598
9599void ScratchTypeSystemClang::Finalize() {
9600 TypeSystemClang::Finalize();
9601 m_scratch_ast_source_up.reset();
9602}
9603
9604TypeSystemClangSP
9605ScratchTypeSystemClang::GetForTarget(Target &target,
9606 std::optional<IsolatedASTKind> ast_kind,
9607 bool create_on_demand) {
9608 auto type_system_or_err = target.GetScratchTypeSystemForLanguage(
9609 language: lldb::eLanguageTypeC, create_on_demand);
9610 if (auto err = type_system_or_err.takeError()) {
9611 LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),
9612 "Couldn't get scratch TypeSystemClang: {0}");
9613 return nullptr;
9614 }
9615 auto ts_sp = *type_system_or_err;
9616 ScratchTypeSystemClang *scratch_ast =
9617 llvm::dyn_cast_or_null<ScratchTypeSystemClang>(Val: ts_sp.get());
9618 if (!scratch_ast)
9619 return nullptr;
9620 // If no dedicated sub-AST was requested, just return the main AST.
9621 if (ast_kind == DefaultAST)
9622 return std::static_pointer_cast<TypeSystemClang>(r: ts_sp);
9623 // Search the sub-ASTs.
9624 return std::static_pointer_cast<TypeSystemClang>(
9625 r: scratch_ast->GetIsolatedAST(feature: *ast_kind).shared_from_this());
9626}
9627
9628/// Returns a human-readable name that uniquely identifiers the sub-AST kind.
9629static llvm::StringRef
9630GetNameForIsolatedASTKind(ScratchTypeSystemClang::IsolatedASTKind kind) {
9631 switch (kind) {
9632 case ScratchTypeSystemClang::IsolatedASTKind::CppModules:
9633 return "C++ modules";
9634 }
9635 llvm_unreachable("Unimplemented IsolatedASTKind?");
9636}
9637
9638void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output,
9639 llvm::StringRef filter) {
9640 // First dump the main scratch AST.
9641 output << "State of scratch Clang type system:\n";
9642 TypeSystemClang::Dump(output, filter);
9643
9644 // Now sort the isolated sub-ASTs.
9645 typedef std::pair<IsolatedASTKey, TypeSystem *> KeyAndTS;
9646 std::vector<KeyAndTS> sorted_typesystems;
9647 for (const auto &a : m_isolated_asts)
9648 sorted_typesystems.emplace_back(args: a.first, args: a.second.get());
9649 llvm::stable_sort(Range&: sorted_typesystems, C: llvm::less_first());
9650
9651 // Dump each sub-AST too.
9652 for (const auto &a : sorted_typesystems) {
9653 IsolatedASTKind kind =
9654 static_cast<ScratchTypeSystemClang::IsolatedASTKind>(a.first);
9655 output << "State of scratch Clang type subsystem "
9656 << GetNameForIsolatedASTKind(kind) << ":\n";
9657 a.second->Dump(output, filter);
9658 }
9659}
9660
9661UserExpression *ScratchTypeSystemClang::GetUserExpression(
9662 llvm::StringRef expr, llvm::StringRef prefix, SourceLanguage language,
9663 Expression::ResultType desired_type,
9664 const EvaluateExpressionOptions &options, ValueObject *ctx_obj) {
9665 TargetSP target_sp = m_target_wp.lock();
9666 if (!target_sp)
9667 return nullptr;
9668
9669 return new ClangUserExpression(*target_sp.get(), expr, prefix, language,
9670 desired_type, options, ctx_obj);
9671}
9672
9673FunctionCaller *ScratchTypeSystemClang::GetFunctionCaller(
9674 const CompilerType &return_type, const Address &function_address,
9675 const ValueList &arg_value_list, const char *name) {
9676 TargetSP target_sp = m_target_wp.lock();
9677 if (!target_sp)
9678 return nullptr;
9679
9680 Process *process = target_sp->GetProcessSP().get();
9681 if (!process)
9682 return nullptr;
9683
9684 return new ClangFunctionCaller(*process, return_type, function_address,
9685 arg_value_list, name);
9686}
9687
9688std::unique_ptr<UtilityFunction>
9689ScratchTypeSystemClang::CreateUtilityFunction(std::string text,
9690 std::string name) {
9691 TargetSP target_sp = m_target_wp.lock();
9692 if (!target_sp)
9693 return {};
9694
9695 return std::make_unique<ClangUtilityFunction>(
9696 args&: *target_sp.get(), args: std::move(text), args: std::move(name),
9697 args: target_sp->GetDebugUtilityExpression());
9698}
9699
9700PersistentExpressionState *
9701ScratchTypeSystemClang::GetPersistentExpressionState() {
9702 return m_persistent_variables.get();
9703}
9704
9705void ScratchTypeSystemClang::ForgetSource(ASTContext *src_ctx,
9706 ClangASTImporter &importer) {
9707 // Remove it as a source from the main AST.
9708 importer.ForgetSource(dst_ctx: &getASTContext(), src_ctx);
9709 // Remove it as a source from all created sub-ASTs.
9710 for (const auto &a : m_isolated_asts)
9711 importer.ForgetSource(dst_ctx: &a.second->getASTContext(), src_ctx);
9712}
9713
9714std::unique_ptr<ClangASTSource> ScratchTypeSystemClang::CreateASTSource() {
9715 return std::make_unique<ClangASTSource>(
9716 args: m_target_wp.lock()->shared_from_this(),
9717 args: m_persistent_variables->GetClangASTImporter());
9718}
9719
9720static llvm::StringRef
9721GetSpecializedASTName(ScratchTypeSystemClang::IsolatedASTKind feature) {
9722 switch (feature) {
9723 case ScratchTypeSystemClang::IsolatedASTKind::CppModules:
9724 return "scratch ASTContext for C++ module types";
9725 }
9726 llvm_unreachable("Unimplemented ASTFeature kind?");
9727}
9728
9729TypeSystemClang &ScratchTypeSystemClang::GetIsolatedAST(
9730 ScratchTypeSystemClang::IsolatedASTKind feature) {
9731 auto found_ast = m_isolated_asts.find(Val: feature);
9732 if (found_ast != m_isolated_asts.end())
9733 return *found_ast->second;
9734
9735 // Couldn't find the requested sub-AST, so create it now.
9736 std::shared_ptr<TypeSystemClang> new_ast_sp =
9737 std::make_shared<SpecializedScratchAST>(args: GetSpecializedASTName(feature),
9738 args&: m_triple, args: CreateASTSource());
9739 m_isolated_asts.insert(KV: {feature, new_ast_sp});
9740 return *new_ast_sp;
9741}
9742
9743bool TypeSystemClang::IsForcefullyCompleted(lldb::opaque_compiler_type_t type) {
9744 if (type) {
9745 clang::QualType qual_type(GetQualType(type));
9746 const clang::RecordType *record_type =
9747 llvm::dyn_cast<clang::RecordType>(Val: qual_type.getTypePtr());
9748 if (record_type) {
9749 const clang::RecordDecl *record_decl = record_type->getDecl();
9750 assert(record_decl);
9751 if (std::optional<ClangASTMetadata> metadata = GetMetadata(object: record_decl))
9752 return metadata->IsForcefullyCompleted();
9753 }
9754 }
9755 return false;
9756}
9757
9758bool TypeSystemClang::SetDeclIsForcefullyCompleted(const clang::TagDecl *td) {
9759 if (td == nullptr)
9760 return false;
9761 std::optional<ClangASTMetadata> metadata = GetMetadata(object: td);
9762 if (!metadata)
9763 return false;
9764 m_has_forcefully_completed_types = true;
9765 metadata->SetIsForcefullyCompleted();
9766 SetMetadata(object: td, metadata: *metadata);
9767
9768 return true;
9769}
9770
9771void TypeSystemClang::LogCreation() const {
9772 if (auto *log = GetLog(mask: LLDBLog::Expressions))
9773 LLDB_LOG(log, "Created new TypeSystem for (ASTContext*){0:x} '{1}'",
9774 &getASTContext(), getDisplayName());
9775}
9776

source code of lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp