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 context.getCanonicalType(m1->getType()));
133
134 const auto *m2Type = llvm::cast<clang::FunctionProtoType>(
135 context.getCanonicalType(m2->getType()));
136
137 auto compareArgTypes = [&context](const clang::QualType &m1p,
138 const clang::QualType &m2p) {
139 return context.hasSameType(m1p.getUnqualifiedType(),
140 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(m1Type->param_type_begin(), m1Type->param_type_end(),
147 m2Type->param_type_begin(), 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(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).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(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, ast.VoidPtrTy))
771 return GetType(qt: ast.VoidPtrTy);
772 break;
773
774 case eEncodingUint:
775 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy))
776 return GetType(qt: ast.UnsignedCharTy);
777 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy))
778 return GetType(qt: ast.UnsignedShortTy);
779 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy))
780 return GetType(qt: ast.UnsignedIntTy);
781 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy))
782 return GetType(qt: ast.UnsignedLongTy);
783 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy))
784 return GetType(qt: ast.UnsignedLongLongTy);
785 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty))
786 return GetType(qt: ast.UnsignedInt128Ty);
787 break;
788
789 case eEncodingSint:
790 if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy))
791 return GetType(qt: ast.SignedCharTy);
792 if (QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy))
793 return GetType(qt: ast.ShortTy);
794 if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy))
795 return GetType(qt: ast.IntTy);
796 if (QualTypeMatchesBitSize(bit_size, ast, ast.LongTy))
797 return GetType(qt: ast.LongTy);
798 if (QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy))
799 return GetType(qt: ast.LongLongTy);
800 if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty))
801 return GetType(qt: ast.Int128Ty);
802 break;
803
804 case eEncodingIEEE754:
805 if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy))
806 return GetType(qt: ast.FloatTy);
807 if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy))
808 return GetType(qt: ast.DoubleTy);
809 if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy))
810 return GetType(qt: ast.LongDoubleTy);
811 if (QualTypeMatchesBitSize(bit_size, ast, 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, ast.VoidPtrTy))
919 return GetType(qt: ast.VoidPtrTy);
920 break;
921
922 case DW_ATE_boolean:
923 if (QualTypeMatchesBitSize(bit_size, ast, ast.BoolTy))
924 return GetType(qt: ast.BoolTy);
925 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy))
926 return GetType(qt: ast.UnsignedCharTy);
927 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy))
928 return GetType(qt: ast.UnsignedShortTy);
929 if (QualTypeMatchesBitSize(bit_size, ast, 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(ast.FloatTy);
946 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: FloatComplexTy))
947 return GetType(qt: FloatComplexTy);
948
949 CanQualType DoubleComplexTy = ast.getComplexType(ast.DoubleTy);
950 if (QualTypeMatchesBitSize(bit_size, ast, qual_type: DoubleComplexTy))
951 return GetType(qt: DoubleComplexTy);
952
953 CanQualType LongDoubleComplexTy = ast.getComplexType(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, ast.FloatTy))
967 return GetType(qt: ast.FloatTy);
968 if (type_name == "double" &&
969 QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy))
970 return GetType(qt: ast.DoubleTy);
971 if (type_name == "long double" &&
972 QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy))
973 return GetType(qt: ast.LongDoubleTy);
974 // Fall back to not requiring a name match
975 if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy))
976 return GetType(qt: ast.FloatTy);
977 if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy))
978 return GetType(qt: ast.DoubleTy);
979 if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy))
980 return GetType(qt: ast.LongDoubleTy);
981 if (QualTypeMatchesBitSize(bit_size, ast, 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, 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, ast.VoidTy))
994 return GetType(qt: ast.VoidTy);
995 if (type_name.contains(Other: "long long") &&
996 QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy))
997 return GetType(qt: ast.LongLongTy);
998 if (type_name.contains(Other: "long") &&
999 QualTypeMatchesBitSize(bit_size, ast, ast.LongTy))
1000 return GetType(qt: ast.LongTy);
1001 if (type_name.contains(Other: "short") &&
1002 QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy))
1003 return GetType(qt: ast.ShortTy);
1004 if (type_name.contains(Other: "char")) {
1005 if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy))
1006 return GetType(qt: ast.CharTy);
1007 if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy))
1008 return GetType(qt: ast.SignedCharTy);
1009 }
1010 if (type_name.contains(Other: "int")) {
1011 if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy))
1012 return GetType(qt: ast.IntTy);
1013 if (QualTypeMatchesBitSize(bit_size, ast, 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, ast.CharTy))
1019 return GetType(qt: ast.CharTy);
1020 if (QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy))
1021 return GetType(qt: ast.ShortTy);
1022 if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy))
1023 return GetType(qt: ast.IntTy);
1024 if (QualTypeMatchesBitSize(bit_size, ast, ast.LongTy))
1025 return GetType(qt: ast.LongTy);
1026 if (QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy))
1027 return GetType(qt: ast.LongLongTy);
1028 if (QualTypeMatchesBitSize(bit_size, ast, 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, ast.CharTy))
1035 return GetType(qt: ast.CharTy);
1036 }
1037 if (QualTypeMatchesBitSize(bit_size, ast, 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, 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, ast.UnsignedLongLongTy))
1052 return GetType(qt: ast.UnsignedLongLongTy);
1053 } else if (type_name.contains(Other: "long")) {
1054 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy))
1055 return GetType(qt: ast.UnsignedLongTy);
1056 } else if (type_name.contains(Other: "short")) {
1057 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy))
1058 return GetType(qt: ast.UnsignedShortTy);
1059 } else if (type_name.contains(Other: "char")) {
1060 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy))
1061 return GetType(qt: ast.UnsignedCharTy);
1062 } else if (type_name.contains(Other: "int")) {
1063 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy))
1064 return GetType(qt: ast.UnsignedIntTy);
1065 if (QualTypeMatchesBitSize(bit_size, ast, 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, ast.UnsignedCharTy))
1071 return GetType(qt: ast.UnsignedCharTy);
1072 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy))
1073 return GetType(qt: ast.UnsignedShortTy);
1074 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy))
1075 return GetType(qt: ast.UnsignedIntTy);
1076 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy))
1077 return GetType(qt: ast.UnsignedLongTy);
1078 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy))
1079 return GetType(qt: ast.UnsignedLongLongTy);
1080 if (QualTypeMatchesBitSize(bit_size, ast, 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, ast.CharTy))
1087 return GetType(qt: ast.CharTy);
1088 }
1089 if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy))
1090 return GetType(qt: ast.UnsignedCharTy);
1091 if (QualTypeMatchesBitSize(bit_size, ast, 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(decl, *metadata);
1305
1306 if (access_type != eAccessNone)
1307 decl->setAccess(ConvertAccessTypeToAccessSpecifier(access: access_type));
1308
1309 if (decl_ctx)
1310 decl_ctx->addDecl(decl);
1311
1312 return GetType(qt: ast.getTagDeclType(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(ct, access_specifier, cxx_record_decl,
1349 SourceLocation(), 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(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(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(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(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(func_decl);
1434 SetOwningModule(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(instantiation_values.GetArgs(), params)) {
1547 const TemplateArgument &passed_arg = std::get<0>(pair);
1548 NamedDecl *found_param = std::get<1>(pair);
1549 if (!TemplateParameterAllowsValue(found_param, 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(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(template_cxx_decl);
1617 template_cxx_decl->setDescribedClassTemplate(class_template_decl);
1618 SetOwningModule(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(class_template_decl);
1625
1626 VerifyDecl(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(ast, decl_ctx, SourceLocation(),
1649 /*Depth=*/0, /*Position=*/0,
1650 /*IsParameterPack=*/false,
1651 &identifier_info, /*Typename=*/false,
1652 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(class_template_specialization_decl, 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(class_template_specialization_decl, owning_module);
1689 decl_ctx->addDecl(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(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(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(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(decl, *metadata);
1837
1838 return GetType(qt: ast.getObjCInterfaceType(Decl: decl));
1839}
1840
1841bool TypeSystemClang::BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) {
1842 return !TypeSystemClang::RecordHasFields(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(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(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(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(namespace_decl, owning_module);
1926
1927 VerifyDecl(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(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 getASTContext(), decl_ctx, clang::SourceLocation(),
1969 clang::SourceLocation(), clang::NestedNameSpecifierLoc(),
1970 clang::SourceLocation(), ns_decl,
1971 FindLCABetweenDecls(decl_ctx, ns_decl,
1972 translation_unit));
1973 decl_ctx->addDecl(using_decl);
1974 SetOwningModule(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(using_decl, owning_module);
1989 clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
1990 getASTContext(), current_decl_ctx, clang::SourceLocation(),
1991 target->getDeclName(), using_decl, target);
1992 SetOwningModule(shadow_decl, owning_module);
1993 using_decl->addShadowDecl(shadow_decl);
1994 current_decl_ctx->addDecl(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(var_decl, owning_module);
2011 var_decl->setAccess(clang::AS_public);
2012 decl_context->addDecl(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(ast->FloatTy).getAsOpaquePtr();
2074 case eBasicTypeDoubleComplex:
2075 return ast->getComplexType(ast->DoubleTy).getAsOpaquePtr();
2076 case eBasicTypeLongDoubleComplex:
2077 return ast->getComplexType(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(func_decl, owning_module);
2176 decl_ctx->addDecl(func_decl);
2177
2178 VerifyDecl(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(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(enum_decl, owning_module);
2332 if (decl_ctx)
2333 decl_ctx->addDecl(enum_decl);
2334
2335 if (enum_kind)
2336 enum_decl->addAttr(
2337 clang::EnumExtensibilityAttr::CreateImplicit(ast, *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(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(ast.SignedCharTy))
2356 return GetType(qt: ast.SignedCharTy);
2357
2358 if (bit_size == ast.getTypeSize(ast.ShortTy))
2359 return GetType(qt: ast.ShortTy);
2360
2361 if (bit_size == ast.getTypeSize(ast.IntTy))
2362 return GetType(qt: ast.IntTy);
2363
2364 if (bit_size == ast.getTypeSize(ast.LongTy))
2365 return GetType(qt: ast.LongTy);
2366
2367 if (bit_size == ast.getTypeSize(ast.LongLongTy))
2368 return GetType(qt: ast.LongLongTy);
2369
2370 if (bit_size == ast.getTypeSize(ast.Int128Ty))
2371 return GetType(qt: ast.Int128Ty);
2372 } else {
2373 if (bit_size == ast.getTypeSize(ast.UnsignedCharTy))
2374 return GetType(qt: ast.UnsignedCharTy);
2375
2376 if (bit_size == ast.getTypeSize(ast.UnsignedShortTy))
2377 return GetType(qt: ast.UnsignedShortTy);
2378
2379 if (bit_size == ast.getTypeSize(ast.UnsignedIntTy))
2380 return GetType(qt: ast.UnsignedIntTy);
2381
2382 if (bit_size == ast.getTypeSize(ast.UnsignedLongTy))
2383 return GetType(qt: ast.UnsignedLongTy);
2384
2385 if (bit_size == ast.getTypeSize(ast.UnsignedLongLongTy))
2386 return GetType(qt: ast.UnsignedLongLongTy);
2387
2388 if (bit_size == ast.getTypeSize(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(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 printf("%20s: %s%s\n", decl->getDeclKindName(),
2424 record_decl->getDeclName().getAsString().c_str(),
2425 record_decl->isInjectedClassName() ? " (injected class name)" : "");
2426
2427 } else {
2428 clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(Val: decl);
2429 if (named_decl) {
2430 printf(format: "%20s: %s\n", decl->getDeclKindName(),
2431 named_decl->getDeclName().getAsString().c_str());
2432 } else {
2433 printf(format: "%20s\n", decl->getDeclKindName());
2434 }
2435 }
2436}
2437
2438bool TypeSystemClang::GetCompleteDecl(clang::ASTContext *ast,
2439 clang::Decl *decl) {
2440 if (!decl)
2441 return false;
2442
2443 ExternalASTSource *ast_source = ast->getExternalSource();
2444
2445 if (!ast_source)
2446 return false;
2447
2448 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(Val: decl)) {
2449 if (tag_decl->isCompleteDefinition())
2450 return true;
2451
2452 if (!tag_decl->hasExternalLexicalStorage())
2453 return false;
2454
2455 ast_source->CompleteType(Tag: tag_decl);
2456
2457 return !tag_decl->getTypeForDecl()->isIncompleteType();
2458 } else if (clang::ObjCInterfaceDecl *objc_interface_decl =
2459 llvm::dyn_cast<clang::ObjCInterfaceDecl>(Val: decl)) {
2460 if (objc_interface_decl->getDefinition())
2461 return true;
2462
2463 if (!objc_interface_decl->hasExternalLexicalStorage())
2464 return false;
2465
2466 ast_source->CompleteType(Class: objc_interface_decl);
2467
2468 return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
2469 } else {
2470 return false;
2471 }
2472}
2473
2474void TypeSystemClang::SetMetadataAsUserID(const clang::Decl *decl,
2475 user_id_t user_id) {
2476 ClangASTMetadata meta_data;
2477 meta_data.SetUserID(user_id);
2478 SetMetadata(object: decl, meta_data);
2479}
2480
2481void TypeSystemClang::SetMetadataAsUserID(const clang::Type *type,
2482 user_id_t user_id) {
2483 ClangASTMetadata meta_data;
2484 meta_data.SetUserID(user_id);
2485 SetMetadata(object: type, meta_data);
2486}
2487
2488void TypeSystemClang::SetMetadata(const clang::Decl *object,
2489 ClangASTMetadata metadata) {
2490 m_decl_metadata[object] = metadata;
2491}
2492
2493void TypeSystemClang::SetMetadata(const clang::Type *object,
2494 ClangASTMetadata metadata) {
2495 m_type_metadata[object] = metadata;
2496}
2497
2498std::optional<ClangASTMetadata>
2499TypeSystemClang::GetMetadata(const clang::Decl *object) {
2500 auto It = m_decl_metadata.find(Val: object);
2501 if (It != m_decl_metadata.end())
2502 return It->second;
2503
2504 return std::nullopt;
2505}
2506
2507std::optional<ClangASTMetadata>
2508TypeSystemClang::GetMetadata(const clang::Type *object) {
2509 auto It = m_type_metadata.find(Val: object);
2510 if (It != m_type_metadata.end())
2511 return It->second;
2512
2513 return std::nullopt;
2514}
2515
2516void TypeSystemClang::SetCXXRecordDeclAccess(const clang::CXXRecordDecl *object,
2517 clang::AccessSpecifier access) {
2518 if (access == clang::AccessSpecifier::AS_none)
2519 m_cxx_record_decl_access.erase(Val: object);
2520 else
2521 m_cxx_record_decl_access[object] = access;
2522}
2523
2524clang::AccessSpecifier
2525TypeSystemClang::GetCXXRecordDeclAccess(const clang::CXXRecordDecl *object) {
2526 auto It = m_cxx_record_decl_access.find(Val: object);
2527 if (It != m_cxx_record_decl_access.end())
2528 return It->second;
2529 return clang::AccessSpecifier::AS_none;
2530}
2531
2532clang::DeclContext *
2533TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
2534 return GetDeclContextForType(type: ClangUtil::GetQualType(ct: type));
2535}
2536
2537CompilerDeclContext
2538TypeSystemClang::GetCompilerDeclContextForType(const CompilerType &type) {
2539 if (auto *decl_context = GetDeclContextForType(type))
2540 return CreateDeclContext(ctx: decl_context);
2541 return CompilerDeclContext();
2542}
2543
2544/// Aggressively desugar the provided type, skipping past various kinds of
2545/// syntactic sugar and other constructs one typically wants to ignore.
2546/// The \p mask argument allows one to skip certain kinds of simplifications,
2547/// when one wishes to handle a certain kind of type directly.
2548static QualType
2549RemoveWrappingTypes(QualType type, ArrayRef<clang::Type::TypeClass> mask = {}) {
2550 while (true) {
2551 if (find(Range&: mask, Val: type->getTypeClass()) != mask.end())
2552 return type;
2553 switch (type->getTypeClass()) {
2554 // This is not fully correct as _Atomic is more than sugar, but it is
2555 // sufficient for the purposes we care about.
2556 case clang::Type::Atomic:
2557 type = cast<clang::AtomicType>(Val&: type)->getValueType();
2558 break;
2559 case clang::Type::Auto:
2560 case clang::Type::Decltype:
2561 case clang::Type::Elaborated:
2562 case clang::Type::Paren:
2563 case clang::Type::SubstTemplateTypeParm:
2564 case clang::Type::TemplateSpecialization:
2565 case clang::Type::Typedef:
2566 case clang::Type::TypeOf:
2567 case clang::Type::TypeOfExpr:
2568 case clang::Type::Using:
2569 type = type->getLocallyUnqualifiedSingleStepDesugaredType();
2570 break;
2571 default:
2572 return type;
2573 }
2574 }
2575}
2576
2577clang::DeclContext *
2578TypeSystemClang::GetDeclContextForType(clang::QualType type) {
2579 if (type.isNull())
2580 return nullptr;
2581
2582 clang::QualType qual_type = RemoveWrappingTypes(type: type.getCanonicalType());
2583 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2584 switch (type_class) {
2585 case clang::Type::ObjCInterface:
2586 return llvm::cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr())
2587 ->getInterface();
2588 case clang::Type::ObjCObjectPointer:
2589 return GetDeclContextForType(
2590 type: llvm::cast<clang::ObjCObjectPointerType>(Val: qual_type.getTypePtr())
2591 ->getPointeeType());
2592 case clang::Type::Record:
2593 return llvm::cast<clang::RecordType>(Val&: qual_type)->getDecl();
2594 case clang::Type::Enum:
2595 return llvm::cast<clang::EnumType>(Val&: qual_type)->getDecl();
2596 default:
2597 break;
2598 }
2599 // No DeclContext in this type...
2600 return nullptr;
2601}
2602
2603/// Returns the clang::RecordType of the specified \ref qual_type. This
2604/// function will try to complete the type if necessary (and allowed
2605/// by the specified \ref allow_completion). If we fail to return a *complete*
2606/// type, returns nullptr.
2607static const clang::RecordType *GetCompleteRecordType(clang::ASTContext *ast,
2608 clang::QualType qual_type,
2609 bool allow_completion) {
2610 assert(qual_type->isRecordType());
2611
2612 const auto *tag_type = llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
2613
2614 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2615
2616 // RecordType with no way of completing it, return the plain
2617 // TagType.
2618 if (!cxx_record_decl || !cxx_record_decl->hasExternalLexicalStorage())
2619 return tag_type;
2620
2621 const bool is_complete = cxx_record_decl->isCompleteDefinition();
2622 const bool fields_loaded =
2623 cxx_record_decl->hasLoadedFieldsFromExternalStorage();
2624
2625 // Already completed this type, nothing to be done.
2626 if (is_complete && fields_loaded)
2627 return tag_type;
2628
2629 if (!allow_completion)
2630 return nullptr;
2631
2632 // Call the field_begin() accessor to for it to use the external source
2633 // to load the fields...
2634 //
2635 // TODO: if we need to complete the type but have no external source,
2636 // shouldn't we error out instead?
2637 clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2638 if (external_ast_source) {
2639 external_ast_source->CompleteType(cxx_record_decl);
2640 if (cxx_record_decl->isCompleteDefinition()) {
2641 cxx_record_decl->field_begin();
2642 cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
2643 }
2644 }
2645
2646 return tag_type;
2647}
2648
2649/// Returns the clang::EnumType of the specified \ref qual_type. This
2650/// function will try to complete the type if necessary (and allowed
2651/// by the specified \ref allow_completion). If we fail to return a *complete*
2652/// type, returns nullptr.
2653static const clang::EnumType *GetCompleteEnumType(clang::ASTContext *ast,
2654 clang::QualType qual_type,
2655 bool allow_completion) {
2656 assert(qual_type->isEnumeralType());
2657 assert(ast);
2658
2659 const clang::EnumType *enum_type =
2660 llvm::cast<clang::EnumType>(Val: qual_type.getTypePtr());
2661
2662 auto *tag_decl = enum_type->getAsTagDecl();
2663 assert(tag_decl);
2664
2665 // Already completed, nothing to be done.
2666 if (tag_decl->getDefinition())
2667 return enum_type;
2668
2669 if (!allow_completion)
2670 return nullptr;
2671
2672 // No definition but can't complete it, error out.
2673 if (!tag_decl->hasExternalLexicalStorage())
2674 return nullptr;
2675
2676 // We can't complete the type without an external source.
2677 clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2678 if (!external_ast_source)
2679 return nullptr;
2680
2681 external_ast_source->CompleteType(tag_decl);
2682 return enum_type;
2683}
2684
2685/// Returns the clang::ObjCObjectType of the specified \ref qual_type. This
2686/// function will try to complete the type if necessary (and allowed
2687/// by the specified \ref allow_completion). If we fail to return a *complete*
2688/// type, returns nullptr.
2689static const clang::ObjCObjectType *
2690GetCompleteObjCObjectType(clang::ASTContext *ast, QualType qual_type,
2691 bool allow_completion) {
2692 assert(qual_type->isObjCObjectType());
2693 assert(ast);
2694
2695 const clang::ObjCObjectType *objc_class_type =
2696 llvm::cast<clang::ObjCObjectType>(Val&: qual_type);
2697
2698 clang::ObjCInterfaceDecl *class_interface_decl =
2699 objc_class_type->getInterface();
2700 // We currently can't complete objective C types through the newly added
2701 // ASTContext because it only supports TagDecl objects right now...
2702 if (!class_interface_decl)
2703 return objc_class_type;
2704
2705 // Already complete, nothing to be done.
2706 if (class_interface_decl->getDefinition())
2707 return objc_class_type;
2708
2709 if (!allow_completion)
2710 return nullptr;
2711
2712 // No definition but can't complete it, error out.
2713 if (!class_interface_decl->hasExternalLexicalStorage())
2714 return nullptr;
2715
2716 // We can't complete the type without an external source.
2717 clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2718 if (!external_ast_source)
2719 return nullptr;
2720
2721 external_ast_source->CompleteType(Class: class_interface_decl);
2722 return objc_class_type;
2723}
2724
2725static bool GetCompleteQualType(clang::ASTContext *ast,
2726 clang::QualType qual_type,
2727 bool allow_completion = true) {
2728 qual_type = RemoveWrappingTypes(type: qual_type);
2729 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2730 switch (type_class) {
2731 case clang::Type::ConstantArray:
2732 case clang::Type::IncompleteArray:
2733 case clang::Type::VariableArray: {
2734 const clang::ArrayType *array_type =
2735 llvm::dyn_cast<clang::ArrayType>(Val: qual_type.getTypePtr());
2736
2737 if (array_type)
2738 return GetCompleteQualType(ast, qual_type: array_type->getElementType(),
2739 allow_completion);
2740 } break;
2741 case clang::Type::Record: {
2742 if (const auto *RT =
2743 GetCompleteRecordType(ast, qual_type, allow_completion))
2744 return !RT->isIncompleteType();
2745
2746 return false;
2747 } break;
2748
2749 case clang::Type::Enum: {
2750 if (const auto *ET = GetCompleteEnumType(ast, qual_type, allow_completion))
2751 return !ET->isIncompleteType();
2752
2753 return false;
2754 } break;
2755 case clang::Type::ObjCObject:
2756 case clang::Type::ObjCInterface: {
2757 if (const auto *OT =
2758 GetCompleteObjCObjectType(ast, qual_type, allow_completion))
2759 return !OT->isIncompleteType();
2760
2761 return false;
2762 } break;
2763
2764 case clang::Type::Attributed:
2765 return GetCompleteQualType(
2766 ast, qual_type: llvm::cast<clang::AttributedType>(Val&: qual_type)->getModifiedType(),
2767 allow_completion);
2768
2769 case clang::Type::MemberPointer:
2770 // MS C++ ABI requires type of the class to be complete of which the pointee
2771 // is a member.
2772 if (ast->getTargetInfo().getCXXABI().isMicrosoft()) {
2773 auto *MPT = qual_type.getTypePtr()->castAs<clang::MemberPointerType>();
2774 if (auto *RD = MPT->getMostRecentCXXRecordDecl())
2775 GetCompleteRecordType(ast, qual_type: QualType(RD->getTypeForDecl(), 0),
2776 allow_completion);
2777
2778 return !qual_type.getTypePtr()->isIncompleteType();
2779 }
2780 break;
2781
2782 default:
2783 break;
2784 }
2785
2786 return true;
2787}
2788
2789static clang::ObjCIvarDecl::AccessControl
2790ConvertAccessTypeToObjCIvarAccessControl(AccessType access) {
2791 switch (access) {
2792 case eAccessNone:
2793 return clang::ObjCIvarDecl::None;
2794 case eAccessPublic:
2795 return clang::ObjCIvarDecl::Public;
2796 case eAccessPrivate:
2797 return clang::ObjCIvarDecl::Private;
2798 case eAccessProtected:
2799 return clang::ObjCIvarDecl::Protected;
2800 case eAccessPackage:
2801 return clang::ObjCIvarDecl::Package;
2802 }
2803 return clang::ObjCIvarDecl::None;
2804}
2805
2806// Tests
2807
2808#ifndef NDEBUG
2809bool TypeSystemClang::Verify(lldb::opaque_compiler_type_t type) {
2810 return !type || llvm::isa<clang::Type>(Val: GetQualType(type).getTypePtr());
2811}
2812#endif
2813
2814bool TypeSystemClang::IsAggregateType(lldb::opaque_compiler_type_t type) {
2815 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
2816
2817 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2818 switch (type_class) {
2819 case clang::Type::IncompleteArray:
2820 case clang::Type::VariableArray:
2821 case clang::Type::ConstantArray:
2822 case clang::Type::ExtVector:
2823 case clang::Type::Vector:
2824 case clang::Type::Record:
2825 case clang::Type::ObjCObject:
2826 case clang::Type::ObjCInterface:
2827 return true;
2828 default:
2829 break;
2830 }
2831 // The clang type does have a value
2832 return false;
2833}
2834
2835bool TypeSystemClang::IsAnonymousType(lldb::opaque_compiler_type_t type) {
2836 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
2837
2838 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2839 switch (type_class) {
2840 case clang::Type::Record: {
2841 if (const clang::RecordType *record_type =
2842 llvm::dyn_cast_or_null<clang::RecordType>(
2843 Val: qual_type.getTypePtrOrNull())) {
2844 if (const clang::RecordDecl *record_decl = record_type->getDecl()) {
2845 return record_decl->isAnonymousStructOrUnion();
2846 }
2847 }
2848 break;
2849 }
2850 default:
2851 break;
2852 }
2853 // The clang type does have a value
2854 return false;
2855}
2856
2857bool TypeSystemClang::IsArrayType(lldb::opaque_compiler_type_t type,
2858 CompilerType *element_type_ptr,
2859 uint64_t *size, bool *is_incomplete) {
2860 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
2861
2862 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2863 switch (type_class) {
2864 default:
2865 break;
2866
2867 case clang::Type::ConstantArray:
2868 if (element_type_ptr)
2869 element_type_ptr->SetCompilerType(
2870 weak_from_this(), llvm::cast<clang::ConstantArrayType>(Val&: qual_type)
2871 ->getElementType()
2872 .getAsOpaquePtr());
2873 if (size)
2874 *size = llvm::cast<clang::ConstantArrayType>(Val&: qual_type)
2875 ->getSize()
2876 .getLimitedValue(ULLONG_MAX);
2877 if (is_incomplete)
2878 *is_incomplete = false;
2879 return true;
2880
2881 case clang::Type::IncompleteArray:
2882 if (element_type_ptr)
2883 element_type_ptr->SetCompilerType(
2884 weak_from_this(), llvm::cast<clang::IncompleteArrayType>(Val&: qual_type)
2885 ->getElementType()
2886 .getAsOpaquePtr());
2887 if (size)
2888 *size = 0;
2889 if (is_incomplete)
2890 *is_incomplete = true;
2891 return true;
2892
2893 case clang::Type::VariableArray:
2894 if (element_type_ptr)
2895 element_type_ptr->SetCompilerType(
2896 weak_from_this(), llvm::cast<clang::VariableArrayType>(Val&: qual_type)
2897 ->getElementType()
2898 .getAsOpaquePtr());
2899 if (size)
2900 *size = 0;
2901 if (is_incomplete)
2902 *is_incomplete = false;
2903 return true;
2904
2905 case clang::Type::DependentSizedArray:
2906 if (element_type_ptr)
2907 element_type_ptr->SetCompilerType(
2908 weak_from_this(),
2909 llvm::cast<clang::DependentSizedArrayType>(Val&: qual_type)
2910 ->getElementType()
2911 .getAsOpaquePtr());
2912 if (size)
2913 *size = 0;
2914 if (is_incomplete)
2915 *is_incomplete = false;
2916 return true;
2917 }
2918 if (element_type_ptr)
2919 element_type_ptr->Clear();
2920 if (size)
2921 *size = 0;
2922 if (is_incomplete)
2923 *is_incomplete = false;
2924 return false;
2925}
2926
2927bool TypeSystemClang::IsVectorType(lldb::opaque_compiler_type_t type,
2928 CompilerType *element_type, uint64_t *size) {
2929 clang::QualType qual_type(GetCanonicalQualType(type));
2930
2931 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2932 switch (type_class) {
2933 case clang::Type::Vector: {
2934 const clang::VectorType *vector_type =
2935 qual_type->getAs<clang::VectorType>();
2936 if (vector_type) {
2937 if (size)
2938 *size = vector_type->getNumElements();
2939 if (element_type)
2940 *element_type = GetType(qt: vector_type->getElementType());
2941 }
2942 return true;
2943 } break;
2944 case clang::Type::ExtVector: {
2945 const clang::ExtVectorType *ext_vector_type =
2946 qual_type->getAs<clang::ExtVectorType>();
2947 if (ext_vector_type) {
2948 if (size)
2949 *size = ext_vector_type->getNumElements();
2950 if (element_type)
2951 *element_type =
2952 CompilerType(weak_from_this(),
2953 ext_vector_type->getElementType().getAsOpaquePtr());
2954 }
2955 return true;
2956 }
2957 default:
2958 break;
2959 }
2960 return false;
2961}
2962
2963bool TypeSystemClang::IsRuntimeGeneratedType(
2964 lldb::opaque_compiler_type_t type) {
2965 clang::DeclContext *decl_ctx = GetDeclContextForType(type: GetQualType(type));
2966 if (!decl_ctx)
2967 return false;
2968
2969 if (!llvm::isa<clang::ObjCInterfaceDecl>(Val: decl_ctx))
2970 return false;
2971
2972 clang::ObjCInterfaceDecl *result_iface_decl =
2973 llvm::dyn_cast<clang::ObjCInterfaceDecl>(Val: decl_ctx);
2974
2975 std::optional<ClangASTMetadata> ast_metadata = GetMetadata(result_iface_decl);
2976 if (!ast_metadata)
2977 return false;
2978
2979 return (ast_metadata->GetISAPtr() != 0);
2980}
2981
2982bool TypeSystemClang::IsCharType(lldb::opaque_compiler_type_t type) {
2983 return GetQualType(type).getUnqualifiedType()->isCharType();
2984}
2985
2986bool TypeSystemClang::IsCompleteType(lldb::opaque_compiler_type_t type) {
2987 // If the type hasn't been lazily completed yet, complete it now so that we
2988 // can give the caller an accurate answer whether the type actually has a
2989 // definition. Without completing the type now we would just tell the user
2990 // the current (internal) completeness state of the type and most users don't
2991 // care (or even know) about this behavior.
2992 const bool allow_completion = true;
2993 return GetCompleteQualType(ast: &getASTContext(), qual_type: GetQualType(type),
2994 allow_completion);
2995}
2996
2997bool TypeSystemClang::IsConst(lldb::opaque_compiler_type_t type) {
2998 return GetQualType(type).isConstQualified();
2999}
3000
3001bool TypeSystemClang::IsCStringType(lldb::opaque_compiler_type_t type,
3002 uint32_t &length) {
3003 CompilerType pointee_or_element_clang_type;
3004 length = 0;
3005 Flags type_flags(GetTypeInfo(type, pointee_or_element_compiler_type: &pointee_or_element_clang_type));
3006
3007 if (!pointee_or_element_clang_type.IsValid())
3008 return false;
3009
3010 if (type_flags.AnySet(mask: eTypeIsArray | eTypeIsPointer)) {
3011 if (pointee_or_element_clang_type.IsCharType()) {
3012 if (type_flags.Test(bit: eTypeIsArray)) {
3013 // We know the size of the array and it could be a C string since it is
3014 // an array of characters
3015 length = llvm::cast<clang::ConstantArrayType>(
3016 Val: GetCanonicalQualType(type).getTypePtr())
3017 ->getSize()
3018 .getLimitedValue();
3019 }
3020 return true;
3021 }
3022 }
3023 return false;
3024}
3025
3026unsigned TypeSystemClang::GetPtrAuthKey(lldb::opaque_compiler_type_t type) {
3027 if (type) {
3028 clang::QualType qual_type(GetCanonicalQualType(type));
3029 if (auto pointer_auth = qual_type.getPointerAuth())
3030 return pointer_auth.getKey();
3031 }
3032 return 0;
3033}
3034
3035unsigned
3036TypeSystemClang::GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) {
3037 if (type) {
3038 clang::QualType qual_type(GetCanonicalQualType(type));
3039 if (auto pointer_auth = qual_type.getPointerAuth())
3040 return pointer_auth.getExtraDiscriminator();
3041 }
3042 return 0;
3043}
3044
3045bool TypeSystemClang::GetPtrAuthAddressDiversity(
3046 lldb::opaque_compiler_type_t type) {
3047 if (type) {
3048 clang::QualType qual_type(GetCanonicalQualType(type));
3049 if (auto pointer_auth = qual_type.getPointerAuth())
3050 return pointer_auth.isAddressDiscriminated();
3051 }
3052 return false;
3053}
3054
3055bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type) {
3056 auto isFunctionType = [&](clang::QualType qual_type) {
3057 return qual_type->isFunctionType();
3058 };
3059
3060 return IsTypeImpl(type, predicate: isFunctionType);
3061}
3062
3063// Used to detect "Homogeneous Floating-point Aggregates"
3064uint32_t
3065TypeSystemClang::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
3066 CompilerType *base_type_ptr) {
3067 if (!type)
3068 return 0;
3069
3070 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
3071 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3072 switch (type_class) {
3073 case clang::Type::Record:
3074 if (GetCompleteType(type)) {
3075 const clang::CXXRecordDecl *cxx_record_decl =
3076 qual_type->getAsCXXRecordDecl();
3077 if (cxx_record_decl) {
3078 if (cxx_record_decl->getNumBases() || cxx_record_decl->isDynamicClass())
3079 return 0;
3080 }
3081 const clang::RecordType *record_type =
3082 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
3083 if (record_type) {
3084 const clang::RecordDecl *record_decl = record_type->getDecl();
3085 if (record_decl) {
3086 // We are looking for a structure that contains only floating point
3087 // types
3088 clang::RecordDecl::field_iterator field_pos,
3089 field_end = record_decl->field_end();
3090 uint32_t num_fields = 0;
3091 bool is_hva = false;
3092 bool is_hfa = false;
3093 clang::QualType base_qual_type;
3094 uint64_t base_bitwidth = 0;
3095 for (field_pos = record_decl->field_begin(); field_pos != field_end;
3096 ++field_pos) {
3097 clang::QualType field_qual_type = field_pos->getType();
3098 uint64_t field_bitwidth = getASTContext().getTypeSize(T: qual_type);
3099 if (field_qual_type->isFloatingType()) {
3100 if (field_qual_type->isComplexType())
3101 return 0;
3102 else {
3103 if (num_fields == 0)
3104 base_qual_type = field_qual_type;
3105 else {
3106 if (is_hva)
3107 return 0;
3108 is_hfa = true;
3109 if (field_qual_type.getTypePtr() !=
3110 base_qual_type.getTypePtr())
3111 return 0;
3112 }
3113 }
3114 } else if (field_qual_type->isVectorType() ||
3115 field_qual_type->isExtVectorType()) {
3116 if (num_fields == 0) {
3117 base_qual_type = field_qual_type;
3118 base_bitwidth = field_bitwidth;
3119 } else {
3120 if (is_hfa)
3121 return 0;
3122 is_hva = true;
3123 if (base_bitwidth != field_bitwidth)
3124 return 0;
3125 if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
3126 return 0;
3127 }
3128 } else
3129 return 0;
3130 ++num_fields;
3131 }
3132 if (base_type_ptr)
3133 *base_type_ptr =
3134 CompilerType(weak_from_this(), base_qual_type.getAsOpaquePtr());
3135 return num_fields;
3136 }
3137 }
3138 }
3139 break;
3140
3141 default:
3142 break;
3143 }
3144 return 0;
3145}
3146
3147size_t TypeSystemClang::GetNumberOfFunctionArguments(
3148 lldb::opaque_compiler_type_t type) {
3149 if (type) {
3150 clang::QualType qual_type(GetCanonicalQualType(type));
3151 const clang::FunctionProtoType *func =
3152 llvm::dyn_cast<clang::FunctionProtoType>(Val: qual_type.getTypePtr());
3153 if (func)
3154 return func->getNumParams();
3155 }
3156 return 0;
3157}
3158
3159CompilerType
3160TypeSystemClang::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
3161 const size_t index) {
3162 if (type) {
3163 clang::QualType qual_type(GetQualType(type));
3164 const clang::FunctionProtoType *func =
3165 llvm::dyn_cast<clang::FunctionProtoType>(Val: qual_type.getTypePtr());
3166 if (func) {
3167 if (index < func->getNumParams())
3168 return CompilerType(weak_from_this(), func->getParamType(i: index).getAsOpaquePtr());
3169 }
3170 }
3171 return CompilerType();
3172}
3173
3174bool TypeSystemClang::IsTypeImpl(
3175 lldb::opaque_compiler_type_t type,
3176 llvm::function_ref<bool(clang::QualType)> predicate) const {
3177 if (type) {
3178 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
3179
3180 if (predicate(qual_type))
3181 return true;
3182
3183 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3184 switch (type_class) {
3185 default:
3186 break;
3187
3188 case clang::Type::LValueReference:
3189 case clang::Type::RValueReference: {
3190 const clang::ReferenceType *reference_type =
3191 llvm::cast<clang::ReferenceType>(Val: qual_type.getTypePtr());
3192 if (reference_type)
3193 return IsTypeImpl(type: reference_type->getPointeeType().getAsOpaquePtr(), predicate);
3194 } break;
3195 }
3196 }
3197 return false;
3198}
3199
3200bool TypeSystemClang::IsMemberFunctionPointerType(
3201 lldb::opaque_compiler_type_t type) {
3202 auto isMemberFunctionPointerType = [](clang::QualType qual_type) {
3203 return qual_type->isMemberFunctionPointerType();
3204 };
3205
3206 return IsTypeImpl(type, predicate: isMemberFunctionPointerType);
3207}
3208
3209bool TypeSystemClang::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
3210 auto isFunctionPointerType = [](clang::QualType qual_type) {
3211 return qual_type->isFunctionPointerType();
3212 };
3213
3214 return IsTypeImpl(type, predicate: isFunctionPointerType);
3215}
3216
3217bool TypeSystemClang::IsBlockPointerType(
3218 lldb::opaque_compiler_type_t type,
3219 CompilerType *function_pointer_type_ptr) {
3220 auto isBlockPointerType = [&](clang::QualType qual_type) {
3221 if (qual_type->isBlockPointerType()) {
3222 if (function_pointer_type_ptr) {
3223 const clang::BlockPointerType *block_pointer_type =
3224 qual_type->castAs<clang::BlockPointerType>();
3225 QualType pointee_type = block_pointer_type->getPointeeType();
3226 QualType function_pointer_type = m_ast_up->getPointerType(T: pointee_type);
3227 *function_pointer_type_ptr = CompilerType(
3228 weak_from_this(), function_pointer_type.getAsOpaquePtr());
3229 }
3230 return true;
3231 }
3232
3233 return false;
3234 };
3235
3236 return IsTypeImpl(type, predicate: isBlockPointerType);
3237}
3238
3239bool TypeSystemClang::IsIntegerType(lldb::opaque_compiler_type_t type,
3240 bool &is_signed) {
3241 if (!type)
3242 return false;
3243
3244 clang::QualType qual_type(GetCanonicalQualType(type));
3245 const clang::BuiltinType *builtin_type =
3246 llvm::dyn_cast<clang::BuiltinType>(Val: qual_type->getCanonicalTypeInternal());
3247
3248 if (builtin_type) {
3249 if (builtin_type->isInteger()) {
3250 is_signed = builtin_type->isSignedInteger();
3251 return true;
3252 }
3253 }
3254
3255 return false;
3256}
3257
3258bool TypeSystemClang::IsEnumerationType(lldb::opaque_compiler_type_t type,
3259 bool &is_signed) {
3260 if (type) {
3261 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
3262 Val: GetCanonicalQualType(type)->getCanonicalTypeInternal());
3263
3264 if (enum_type) {
3265 IsIntegerType(type: enum_type->getDecl()->getIntegerType().getAsOpaquePtr(),
3266 is_signed);
3267 return true;
3268 }
3269 }
3270
3271 return false;
3272}
3273
3274bool TypeSystemClang::IsScopedEnumerationType(
3275 lldb::opaque_compiler_type_t type) {
3276 if (type) {
3277 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
3278 Val: GetCanonicalQualType(type)->getCanonicalTypeInternal());
3279
3280 if (enum_type) {
3281 return enum_type->isScopedEnumeralType();
3282 }
3283 }
3284
3285 return false;
3286}
3287
3288bool TypeSystemClang::IsPointerType(lldb::opaque_compiler_type_t type,
3289 CompilerType *pointee_type) {
3290 if (type) {
3291 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
3292 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3293 switch (type_class) {
3294 case clang::Type::Builtin:
3295 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
3296 default:
3297 break;
3298 case clang::BuiltinType::ObjCId:
3299 case clang::BuiltinType::ObjCClass:
3300 return true;
3301 }
3302 return false;
3303 case clang::Type::ObjCObjectPointer:
3304 if (pointee_type)
3305 pointee_type->SetCompilerType(
3306 type_system: weak_from_this(),
3307 type: llvm::cast<clang::ObjCObjectPointerType>(Val&: qual_type)
3308 ->getPointeeType()
3309 .getAsOpaquePtr());
3310 return true;
3311 case clang::Type::BlockPointer:
3312 if (pointee_type)
3313 pointee_type->SetCompilerType(
3314 type_system: weak_from_this(), type: llvm::cast<clang::BlockPointerType>(Val&: qual_type)
3315 ->getPointeeType()
3316 .getAsOpaquePtr());
3317 return true;
3318 case clang::Type::Pointer:
3319 if (pointee_type)
3320 pointee_type->SetCompilerType(type_system: weak_from_this(),
3321 type: llvm::cast<clang::PointerType>(Val&: qual_type)
3322 ->getPointeeType()
3323 .getAsOpaquePtr());
3324 return true;
3325 case clang::Type::MemberPointer:
3326 if (pointee_type)
3327 pointee_type->SetCompilerType(
3328 type_system: weak_from_this(), type: llvm::cast<clang::MemberPointerType>(Val&: qual_type)
3329 ->getPointeeType()
3330 .getAsOpaquePtr());
3331 return true;
3332 default:
3333 break;
3334 }
3335 }
3336 if (pointee_type)
3337 pointee_type->Clear();
3338 return false;
3339}
3340
3341bool TypeSystemClang::IsPointerOrReferenceType(
3342 lldb::opaque_compiler_type_t type, CompilerType *pointee_type) {
3343 if (type) {
3344 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
3345 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3346 switch (type_class) {
3347 case clang::Type::Builtin:
3348 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
3349 default:
3350 break;
3351 case clang::BuiltinType::ObjCId:
3352 case clang::BuiltinType::ObjCClass:
3353 return true;
3354 }
3355 return false;
3356 case clang::Type::ObjCObjectPointer:
3357 if (pointee_type)
3358 pointee_type->SetCompilerType(
3359 type_system: weak_from_this(),
3360 type: llvm::cast<clang::ObjCObjectPointerType>(Val&: qual_type)
3361 ->getPointeeType()
3362 .getAsOpaquePtr());
3363 return true;
3364 case clang::Type::BlockPointer:
3365 if (pointee_type)
3366 pointee_type->SetCompilerType(
3367 type_system: weak_from_this(), type: llvm::cast<clang::BlockPointerType>(Val&: qual_type)
3368 ->getPointeeType()
3369 .getAsOpaquePtr());
3370 return true;
3371 case clang::Type::Pointer:
3372 if (pointee_type)
3373 pointee_type->SetCompilerType(type_system: weak_from_this(),
3374 type: llvm::cast<clang::PointerType>(Val&: qual_type)
3375 ->getPointeeType()
3376 .getAsOpaquePtr());
3377 return true;
3378 case clang::Type::MemberPointer:
3379 if (pointee_type)
3380 pointee_type->SetCompilerType(
3381 type_system: weak_from_this(), type: llvm::cast<clang::MemberPointerType>(Val&: qual_type)
3382 ->getPointeeType()
3383 .getAsOpaquePtr());
3384 return true;
3385 case clang::Type::LValueReference:
3386 if (pointee_type)
3387 pointee_type->SetCompilerType(
3388 type_system: weak_from_this(), type: llvm::cast<clang::LValueReferenceType>(Val&: qual_type)
3389 ->desugar()
3390 .getAsOpaquePtr());
3391 return true;
3392 case clang::Type::RValueReference:
3393 if (pointee_type)
3394 pointee_type->SetCompilerType(
3395 type_system: weak_from_this(), type: llvm::cast<clang::RValueReferenceType>(Val&: qual_type)
3396 ->desugar()
3397 .getAsOpaquePtr());
3398 return true;
3399 default:
3400 break;
3401 }
3402 }
3403 if (pointee_type)
3404 pointee_type->Clear();
3405 return false;
3406}
3407
3408bool TypeSystemClang::IsReferenceType(lldb::opaque_compiler_type_t type,
3409 CompilerType *pointee_type,
3410 bool *is_rvalue) {
3411 if (type) {
3412 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
3413 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3414
3415 switch (type_class) {
3416 case clang::Type::LValueReference:
3417 if (pointee_type)
3418 pointee_type->SetCompilerType(
3419 type_system: weak_from_this(), type: llvm::cast<clang::LValueReferenceType>(Val&: qual_type)
3420 ->desugar()
3421 .getAsOpaquePtr());
3422 if (is_rvalue)
3423 *is_rvalue = false;
3424 return true;
3425 case clang::Type::RValueReference:
3426 if (pointee_type)
3427 pointee_type->SetCompilerType(
3428 type_system: weak_from_this(), type: llvm::cast<clang::RValueReferenceType>(Val&: qual_type)
3429 ->desugar()
3430 .getAsOpaquePtr());
3431 if (is_rvalue)
3432 *is_rvalue = true;
3433 return true;
3434
3435 default:
3436 break;
3437 }
3438 }
3439 if (pointee_type)
3440 pointee_type->Clear();
3441 return false;
3442}
3443
3444bool TypeSystemClang::IsFloatingPointType(lldb::opaque_compiler_type_t type,
3445 uint32_t &count, bool &is_complex) {
3446 if (type) {
3447 clang::QualType qual_type(GetCanonicalQualType(type));
3448
3449 if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(
3450 Val: qual_type->getCanonicalTypeInternal())) {
3451 clang::BuiltinType::Kind kind = BT->getKind();
3452 if (kind >= clang::BuiltinType::Float &&
3453 kind <= clang::BuiltinType::LongDouble) {
3454 count = 1;
3455 is_complex = false;
3456 return true;
3457 }
3458 } else if (const clang::ComplexType *CT =
3459 llvm::dyn_cast<clang::ComplexType>(
3460 Val: qual_type->getCanonicalTypeInternal())) {
3461 if (IsFloatingPointType(type: CT->getElementType().getAsOpaquePtr(), count,
3462 is_complex)) {
3463 count = 2;
3464 is_complex = true;
3465 return true;
3466 }
3467 } else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(
3468 Val: qual_type->getCanonicalTypeInternal())) {
3469 if (IsFloatingPointType(type: VT->getElementType().getAsOpaquePtr(), count,
3470 is_complex)) {
3471 count = VT->getNumElements();
3472 is_complex = false;
3473 return true;
3474 }
3475 }
3476 }
3477 count = 0;
3478 is_complex = false;
3479 return false;
3480}
3481
3482bool TypeSystemClang::IsDefined(lldb::opaque_compiler_type_t type) {
3483 if (!type)
3484 return false;
3485
3486 clang::QualType qual_type(GetQualType(type));
3487 const clang::TagType *tag_type =
3488 llvm::dyn_cast<clang::TagType>(Val: qual_type.getTypePtr());
3489 if (tag_type) {
3490 clang::TagDecl *tag_decl = tag_type->getDecl();
3491 if (tag_decl)
3492 return tag_decl->isCompleteDefinition();
3493 return false;
3494 } else {
3495 const clang::ObjCObjectType *objc_class_type =
3496 llvm::dyn_cast<clang::ObjCObjectType>(Val&: qual_type);
3497 if (objc_class_type) {
3498 clang::ObjCInterfaceDecl *class_interface_decl =
3499 objc_class_type->getInterface();
3500 if (class_interface_decl)
3501 return class_interface_decl->getDefinition() != nullptr;
3502 return false;
3503 }
3504 }
3505 return true;
3506}
3507
3508bool TypeSystemClang::IsObjCClassType(const CompilerType &type) {
3509 if (ClangUtil::IsClangType(ct: type)) {
3510 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ct: type));
3511
3512 const clang::ObjCObjectPointerType *obj_pointer_type =
3513 llvm::dyn_cast<clang::ObjCObjectPointerType>(Val&: qual_type);
3514
3515 if (obj_pointer_type)
3516 return obj_pointer_type->isObjCClassType();
3517 }
3518 return false;
3519}
3520
3521bool TypeSystemClang::IsObjCObjectOrInterfaceType(const CompilerType &type) {
3522 if (ClangUtil::IsClangType(ct: type))
3523 return ClangUtil::GetCanonicalQualType(ct: type)->isObjCObjectOrInterfaceType();
3524 return false;
3525}
3526
3527bool TypeSystemClang::IsClassType(lldb::opaque_compiler_type_t type) {
3528 if (!type)
3529 return false;
3530 clang::QualType qual_type(GetCanonicalQualType(type));
3531 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3532 return (type_class == clang::Type::Record);
3533}
3534
3535bool TypeSystemClang::IsEnumType(lldb::opaque_compiler_type_t type) {
3536 if (!type)
3537 return false;
3538 clang::QualType qual_type(GetCanonicalQualType(type));
3539 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3540 return (type_class == clang::Type::Enum);
3541}
3542
3543bool TypeSystemClang::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
3544 if (type) {
3545 clang::QualType qual_type(GetCanonicalQualType(type));
3546 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3547 switch (type_class) {
3548 case clang::Type::Record:
3549 if (GetCompleteType(type)) {
3550 const clang::RecordType *record_type =
3551 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
3552 const clang::RecordDecl *record_decl = record_type->getDecl();
3553 if (record_decl) {
3554 const clang::CXXRecordDecl *cxx_record_decl =
3555 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
3556 if (cxx_record_decl) {
3557 // We can't just call is isPolymorphic() here because that just
3558 // means the current class has virtual functions, it doesn't check
3559 // if any inherited classes have virtual functions. The doc string
3560 // in SBType::IsPolymorphicClass() says it is looking for both
3561 // if the class has virtual methods or if any bases do, so this
3562 // should be more correct.
3563 return cxx_record_decl->isDynamicClass();
3564 }
3565 }
3566 }
3567 break;
3568
3569 default:
3570 break;
3571 }
3572 }
3573 return false;
3574}
3575
3576bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
3577 CompilerType *dynamic_pointee_type,
3578 bool check_cplusplus,
3579 bool check_objc) {
3580 if (dynamic_pointee_type)
3581 dynamic_pointee_type->Clear();
3582 if (!type)
3583 return false;
3584
3585 auto set_dynamic_pointee_type = [&](clang::QualType type) {
3586 if (dynamic_pointee_type)
3587 dynamic_pointee_type->SetCompilerType(type_system: weak_from_this(),
3588 type: type.getAsOpaquePtr());
3589 };
3590
3591 clang::QualType pointee_qual_type;
3592 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
3593 switch (qual_type->getTypeClass()) {
3594 case clang::Type::Builtin:
3595 if (check_objc && llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind() ==
3596 clang::BuiltinType::ObjCId) {
3597 set_dynamic_pointee_type(qual_type);
3598 return true;
3599 }
3600 return false;
3601
3602 case clang::Type::ObjCObjectPointer:
3603 if (!check_objc)
3604 return false;
3605 if (const auto *objc_pointee_type =
3606 qual_type->getPointeeType().getTypePtrOrNull()) {
3607 if (const auto *objc_object_type =
3608 llvm::dyn_cast_or_null<clang::ObjCObjectType>(
3609 Val: objc_pointee_type)) {
3610 if (objc_object_type->isObjCClass())
3611 return false;
3612 }
3613 }
3614 set_dynamic_pointee_type(
3615 llvm::cast<clang::ObjCObjectPointerType>(Val&: qual_type)->getPointeeType());
3616 return true;
3617
3618 case clang::Type::Pointer:
3619 pointee_qual_type =
3620 llvm::cast<clang::PointerType>(Val&: qual_type)->getPointeeType();
3621 break;
3622
3623 case clang::Type::LValueReference:
3624 case clang::Type::RValueReference:
3625 pointee_qual_type =
3626 llvm::cast<clang::ReferenceType>(Val&: qual_type)->getPointeeType();
3627 break;
3628
3629 default:
3630 return false;
3631 }
3632
3633 // Check to make sure what we are pointing to is a possible dynamic C++ type
3634 // We currently accept any "void *" (in case we have a class that has been
3635 // watered down to an opaque pointer) and virtual C++ classes.
3636 switch (pointee_qual_type.getCanonicalType()->getTypeClass()) {
3637 case clang::Type::Builtin:
3638 switch (llvm::cast<clang::BuiltinType>(Val&: pointee_qual_type)->getKind()) {
3639 case clang::BuiltinType::UnknownAny:
3640 case clang::BuiltinType::Void:
3641 set_dynamic_pointee_type(pointee_qual_type);
3642 return true;
3643 default:
3644 return false;
3645 }
3646
3647 case clang::Type::Record: {
3648 if (!check_cplusplus)
3649 return false;
3650 clang::CXXRecordDecl *cxx_record_decl =
3651 pointee_qual_type->getAsCXXRecordDecl();
3652 if (!cxx_record_decl)
3653 return false;
3654
3655 bool success;
3656 if (cxx_record_decl->isCompleteDefinition())
3657 success = cxx_record_decl->isDynamicClass();
3658 else {
3659 std::optional<ClangASTMetadata> metadata = GetMetadata(cxx_record_decl);
3660 std::optional<bool> is_dynamic =
3661 metadata ? metadata->GetIsDynamicCXXType() : std::nullopt;
3662 if (is_dynamic)
3663 success = *is_dynamic;
3664 else if (GetType(qt: pointee_qual_type).GetCompleteType())
3665 success = cxx_record_decl->isDynamicClass();
3666 else
3667 success = false;
3668 }
3669
3670 if (success)
3671 set_dynamic_pointee_type(pointee_qual_type);
3672 return success;
3673 }
3674
3675 case clang::Type::ObjCObject:
3676 case clang::Type::ObjCInterface:
3677 if (check_objc) {
3678 set_dynamic_pointee_type(pointee_qual_type);
3679 return true;
3680 }
3681 break;
3682
3683 default:
3684 break;
3685 }
3686 return false;
3687}
3688
3689bool TypeSystemClang::IsScalarType(lldb::opaque_compiler_type_t type) {
3690 if (!type)
3691 return false;
3692
3693 return (GetTypeInfo(type, pointee_or_element_compiler_type: nullptr) & eTypeIsScalar) != 0;
3694}
3695
3696bool TypeSystemClang::IsTypedefType(lldb::opaque_compiler_type_t type) {
3697 if (!type)
3698 return false;
3699 return RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef})
3700 ->getTypeClass() == clang::Type::Typedef;
3701}
3702
3703bool TypeSystemClang::IsVoidType(lldb::opaque_compiler_type_t type) {
3704 if (!type)
3705 return false;
3706 return GetCanonicalQualType(type)->isVoidType();
3707}
3708
3709bool TypeSystemClang::CanPassInRegisters(const CompilerType &type) {
3710 if (auto *record_decl =
3711 TypeSystemClang::GetAsRecordDecl(type)) {
3712 return record_decl->canPassInRegisters();
3713 }
3714 return false;
3715}
3716
3717bool TypeSystemClang::SupportsLanguage(lldb::LanguageType language) {
3718 return TypeSystemClangSupportsLanguage(language);
3719}
3720
3721std::optional<std::string>
3722TypeSystemClang::GetCXXClassName(const CompilerType &type) {
3723 if (!type)
3724 return std::nullopt;
3725
3726 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ct: type));
3727 if (qual_type.isNull())
3728 return std::nullopt;
3729
3730 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3731 if (!cxx_record_decl)
3732 return std::nullopt;
3733
3734 return std::string(cxx_record_decl->getIdentifier()->getNameStart());
3735}
3736
3737bool TypeSystemClang::IsCXXClassType(const CompilerType &type) {
3738 if (!type)
3739 return false;
3740
3741 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ct: type));
3742 return !qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr;
3743}
3744
3745bool TypeSystemClang::IsBeingDefined(lldb::opaque_compiler_type_t type) {
3746 if (!type)
3747 return false;
3748 clang::QualType qual_type(GetCanonicalQualType(type));
3749 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(Val&: qual_type);
3750 if (tag_type)
3751 return tag_type->isBeingDefined();
3752 return false;
3753}
3754
3755bool TypeSystemClang::IsObjCObjectPointerType(const CompilerType &type,
3756 CompilerType *class_type_ptr) {
3757 if (!ClangUtil::IsClangType(ct: type))
3758 return false;
3759
3760 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ct: type));
3761
3762 if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) {
3763 if (class_type_ptr) {
3764 if (!qual_type->isObjCClassType() && !qual_type->isObjCIdType()) {
3765 const clang::ObjCObjectPointerType *obj_pointer_type =
3766 llvm::dyn_cast<clang::ObjCObjectPointerType>(Val&: qual_type);
3767 if (obj_pointer_type == nullptr)
3768 class_type_ptr->Clear();
3769 else
3770 class_type_ptr->SetCompilerType(
3771 type_system: type.GetTypeSystem(),
3772 type: clang::QualType(obj_pointer_type->getInterfaceType(), 0)
3773 .getAsOpaquePtr());
3774 }
3775 }
3776 return true;
3777 }
3778 if (class_type_ptr)
3779 class_type_ptr->Clear();
3780 return false;
3781}
3782
3783// Type Completion
3784
3785bool TypeSystemClang::GetCompleteType(lldb::opaque_compiler_type_t type) {
3786 if (!type)
3787 return false;
3788 const bool allow_completion = true;
3789 return GetCompleteQualType(ast: &getASTContext(), qual_type: GetQualType(type),
3790 allow_completion);
3791}
3792
3793ConstString TypeSystemClang::GetTypeName(lldb::opaque_compiler_type_t type,
3794 bool base_only) {
3795 if (!type)
3796 return ConstString();
3797
3798 clang::QualType qual_type(GetQualType(type));
3799
3800 // Remove certain type sugar from the name. Sugar such as elaborated types
3801 // or template types which only serve to improve diagnostics shouldn't
3802 // act as their own types from the user's perspective (e.g., formatter
3803 // shouldn't format a variable differently depending on how the ser has
3804 // specified the type. '::Type' and 'Type' should behave the same).
3805 // Typedefs and atomic derived types are not removed as they are actually
3806 // useful for identifiying specific types.
3807 qual_type = RemoveWrappingTypes(qual_type,
3808 {clang::Type::Typedef, clang::Type::Atomic});
3809
3810 // For a typedef just return the qualified name.
3811 if (const auto *typedef_type = qual_type->getAs<clang::TypedefType>()) {
3812 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
3813 return ConstString(GetTypeNameForDecl(typedef_decl));
3814 }
3815
3816 // For consistency, this follows the same code path that clang uses to emit
3817 // debug info. This also handles when we don't want any scopes preceding the
3818 // name.
3819 if (auto *named_decl = qual_type->getAsTagDecl())
3820 return ConstString(GetTypeNameForDecl(named_decl, !base_only));
3821
3822 return ConstString(qual_type.getAsString(Policy: GetTypePrintingPolicy()));
3823}
3824
3825ConstString
3826TypeSystemClang::GetDisplayTypeName(lldb::opaque_compiler_type_t type) {
3827 if (!type)
3828 return ConstString();
3829
3830 clang::QualType qual_type(GetQualType(type));
3831 clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy());
3832 printing_policy.SuppressTagKeyword = true;
3833 printing_policy.SuppressScope = false;
3834 printing_policy.SuppressUnwrittenScope = true;
3835 printing_policy.SuppressInlineNamespace = true;
3836 return ConstString(qual_type.getAsString(Policy: printing_policy));
3837}
3838
3839uint32_t
3840TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type,
3841 CompilerType *pointee_or_element_clang_type) {
3842 if (!type)
3843 return 0;
3844
3845 if (pointee_or_element_clang_type)
3846 pointee_or_element_clang_type->Clear();
3847
3848 clang::QualType qual_type =
3849 RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef});
3850
3851 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3852 switch (type_class) {
3853 case clang::Type::Attributed:
3854 return GetTypeInfo(type: qual_type->castAs<clang::AttributedType>()
3855 ->getModifiedType()
3856 .getAsOpaquePtr(),
3857 pointee_or_element_clang_type);
3858 case clang::Type::Builtin: {
3859 const clang::BuiltinType *builtin_type =
3860 llvm::cast<clang::BuiltinType>(Val: qual_type->getCanonicalTypeInternal());
3861
3862 uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
3863 switch (builtin_type->getKind()) {
3864 case clang::BuiltinType::ObjCId:
3865 case clang::BuiltinType::ObjCClass:
3866 if (pointee_or_element_clang_type)
3867 pointee_or_element_clang_type->SetCompilerType(
3868 weak_from_this(),
3869 getASTContext().ObjCBuiltinClassTy.getAsOpaquePtr());
3870 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
3871 break;
3872
3873 case clang::BuiltinType::ObjCSel:
3874 if (pointee_or_element_clang_type)
3875 pointee_or_element_clang_type->SetCompilerType(
3876 weak_from_this(), getASTContext().CharTy.getAsOpaquePtr());
3877 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
3878 break;
3879
3880 case clang::BuiltinType::Bool:
3881 case clang::BuiltinType::Char_U:
3882 case clang::BuiltinType::UChar:
3883 case clang::BuiltinType::WChar_U:
3884 case clang::BuiltinType::Char16:
3885 case clang::BuiltinType::Char32:
3886 case clang::BuiltinType::UShort:
3887 case clang::BuiltinType::UInt:
3888 case clang::BuiltinType::ULong:
3889 case clang::BuiltinType::ULongLong:
3890 case clang::BuiltinType::UInt128:
3891 case clang::BuiltinType::Char_S:
3892 case clang::BuiltinType::SChar:
3893 case clang::BuiltinType::WChar_S:
3894 case clang::BuiltinType::Short:
3895 case clang::BuiltinType::Int:
3896 case clang::BuiltinType::Long:
3897 case clang::BuiltinType::LongLong:
3898 case clang::BuiltinType::Int128:
3899 case clang::BuiltinType::Float:
3900 case clang::BuiltinType::Double:
3901 case clang::BuiltinType::LongDouble:
3902 builtin_type_flags |= eTypeIsScalar;
3903 if (builtin_type->isInteger()) {
3904 builtin_type_flags |= eTypeIsInteger;
3905 if (builtin_type->isSignedInteger())
3906 builtin_type_flags |= eTypeIsSigned;
3907 } else if (builtin_type->isFloatingPoint())
3908 builtin_type_flags |= eTypeIsFloat;
3909 break;
3910 default:
3911 break;
3912 }
3913 return builtin_type_flags;
3914 }
3915
3916 case clang::Type::BlockPointer:
3917 if (pointee_or_element_clang_type)
3918 pointee_or_element_clang_type->SetCompilerType(
3919 type_system: weak_from_this(), type: qual_type->getPointeeType().getAsOpaquePtr());
3920 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
3921
3922 case clang::Type::Complex: {
3923 uint32_t complex_type_flags =
3924 eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
3925 const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(
3926 Val: qual_type->getCanonicalTypeInternal());
3927 if (complex_type) {
3928 clang::QualType complex_element_type(complex_type->getElementType());
3929 if (complex_element_type->isIntegerType())
3930 complex_type_flags |= eTypeIsFloat;
3931 else if (complex_element_type->isFloatingType())
3932 complex_type_flags |= eTypeIsInteger;
3933 }
3934 return complex_type_flags;
3935 } break;
3936
3937 case clang::Type::ConstantArray:
3938 case clang::Type::DependentSizedArray:
3939 case clang::Type::IncompleteArray:
3940 case clang::Type::VariableArray:
3941 if (pointee_or_element_clang_type)
3942 pointee_or_element_clang_type->SetCompilerType(
3943 type_system: weak_from_this(), type: llvm::cast<clang::ArrayType>(Val: qual_type.getTypePtr())
3944 ->getElementType()
3945 .getAsOpaquePtr());
3946 return eTypeHasChildren | eTypeIsArray;
3947
3948 case clang::Type::DependentName:
3949 return 0;
3950 case clang::Type::DependentSizedExtVector:
3951 return eTypeHasChildren | eTypeIsVector;
3952 case clang::Type::DependentTemplateSpecialization:
3953 return eTypeIsTemplate;
3954
3955 case clang::Type::Enum:
3956 if (pointee_or_element_clang_type)
3957 pointee_or_element_clang_type->SetCompilerType(
3958 type_system: weak_from_this(), type: llvm::cast<clang::EnumType>(Val&: qual_type)
3959 ->getDecl()
3960 ->getIntegerType()
3961 .getAsOpaquePtr());
3962 return eTypeIsEnumeration | eTypeHasValue;
3963
3964 case clang::Type::FunctionProto:
3965 return eTypeIsFuncPrototype | eTypeHasValue;
3966 case clang::Type::FunctionNoProto:
3967 return eTypeIsFuncPrototype | eTypeHasValue;
3968 case clang::Type::InjectedClassName:
3969 return 0;
3970
3971 case clang::Type::LValueReference:
3972 case clang::Type::RValueReference:
3973 if (pointee_or_element_clang_type)
3974 pointee_or_element_clang_type->SetCompilerType(
3975 type_system: weak_from_this(),
3976 type: llvm::cast<clang::ReferenceType>(Val: qual_type.getTypePtr())
3977 ->getPointeeType()
3978 .getAsOpaquePtr());
3979 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
3980
3981 case clang::Type::MemberPointer:
3982 return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
3983
3984 case clang::Type::ObjCObjectPointer:
3985 if (pointee_or_element_clang_type)
3986 pointee_or_element_clang_type->SetCompilerType(
3987 type_system: weak_from_this(), type: qual_type->getPointeeType().getAsOpaquePtr());
3988 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer |
3989 eTypeHasValue;
3990
3991 case clang::Type::ObjCObject:
3992 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
3993 case clang::Type::ObjCInterface:
3994 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
3995
3996 case clang::Type::Pointer:
3997 if (pointee_or_element_clang_type)
3998 pointee_or_element_clang_type->SetCompilerType(
3999 type_system: weak_from_this(), type: qual_type->getPointeeType().getAsOpaquePtr());
4000 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
4001
4002 case clang::Type::Record:
4003 if (qual_type->getAsCXXRecordDecl())
4004 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
4005 else
4006 return eTypeHasChildren | eTypeIsStructUnion;
4007 break;
4008 case clang::Type::SubstTemplateTypeParm:
4009 return eTypeIsTemplate;
4010 case clang::Type::TemplateTypeParm:
4011 return eTypeIsTemplate;
4012 case clang::Type::TemplateSpecialization:
4013 return eTypeIsTemplate;
4014
4015 case clang::Type::Typedef:
4016 return eTypeIsTypedef | GetType(qt: llvm::cast<clang::TypedefType>(Val&: qual_type)
4017 ->getDecl()
4018 ->getUnderlyingType())
4019 .GetTypeInfo(pointee_or_element_compiler_type: pointee_or_element_clang_type);
4020 case clang::Type::UnresolvedUsing:
4021 return 0;
4022
4023 case clang::Type::ExtVector:
4024 case clang::Type::Vector: {
4025 uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
4026 const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>(
4027 Val: qual_type->getCanonicalTypeInternal());
4028 if (vector_type) {
4029 if (vector_type->isIntegerType())
4030 vector_type_flags |= eTypeIsFloat;
4031 else if (vector_type->isFloatingType())
4032 vector_type_flags |= eTypeIsInteger;
4033 }
4034 return vector_type_flags;
4035 }
4036 default:
4037 return 0;
4038 }
4039 return 0;
4040}
4041
4042lldb::LanguageType
4043TypeSystemClang::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
4044 if (!type)
4045 return lldb::eLanguageTypeC;
4046
4047 // If the type is a reference, then resolve it to what it refers to first:
4048 clang::QualType qual_type(GetCanonicalQualType(type).getNonReferenceType());
4049 if (qual_type->isAnyPointerType()) {
4050 if (qual_type->isObjCObjectPointerType())
4051 return lldb::eLanguageTypeObjC;
4052 if (qual_type->getPointeeCXXRecordDecl())
4053 return lldb::eLanguageTypeC_plus_plus;
4054
4055 clang::QualType pointee_type(qual_type->getPointeeType());
4056 if (pointee_type->getPointeeCXXRecordDecl())
4057 return lldb::eLanguageTypeC_plus_plus;
4058 if (pointee_type->isObjCObjectOrInterfaceType())
4059 return lldb::eLanguageTypeObjC;
4060 if (pointee_type->isObjCClassType())
4061 return lldb::eLanguageTypeObjC;
4062 if (pointee_type.getTypePtr() ==
4063 getASTContext().ObjCBuiltinIdTy.getTypePtr())
4064 return lldb::eLanguageTypeObjC;
4065 } else {
4066 if (qual_type->isObjCObjectOrInterfaceType())
4067 return lldb::eLanguageTypeObjC;
4068 if (qual_type->getAsCXXRecordDecl())
4069 return lldb::eLanguageTypeC_plus_plus;
4070 switch (qual_type->getTypeClass()) {
4071 default:
4072 break;
4073 case clang::Type::Builtin:
4074 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
4075 default:
4076 case clang::BuiltinType::Void:
4077 case clang::BuiltinType::Bool:
4078 case clang::BuiltinType::Char_U:
4079 case clang::BuiltinType::UChar:
4080 case clang::BuiltinType::WChar_U:
4081 case clang::BuiltinType::Char16:
4082 case clang::BuiltinType::Char32:
4083 case clang::BuiltinType::UShort:
4084 case clang::BuiltinType::UInt:
4085 case clang::BuiltinType::ULong:
4086 case clang::BuiltinType::ULongLong:
4087 case clang::BuiltinType::UInt128:
4088 case clang::BuiltinType::Char_S:
4089 case clang::BuiltinType::SChar:
4090 case clang::BuiltinType::WChar_S:
4091 case clang::BuiltinType::Short:
4092 case clang::BuiltinType::Int:
4093 case clang::BuiltinType::Long:
4094 case clang::BuiltinType::LongLong:
4095 case clang::BuiltinType::Int128:
4096 case clang::BuiltinType::Float:
4097 case clang::BuiltinType::Double:
4098 case clang::BuiltinType::LongDouble:
4099 break;
4100
4101 case clang::BuiltinType::NullPtr:
4102 return eLanguageTypeC_plus_plus;
4103
4104 case clang::BuiltinType::ObjCId:
4105 case clang::BuiltinType::ObjCClass:
4106 case clang::BuiltinType::ObjCSel:
4107 return eLanguageTypeObjC;
4108
4109 case clang::BuiltinType::Dependent:
4110 case clang::BuiltinType::Overload:
4111 case clang::BuiltinType::BoundMember:
4112 case clang::BuiltinType::UnknownAny:
4113 break;
4114 }
4115 break;
4116 case clang::Type::Typedef:
4117 return GetType(qt: llvm::cast<clang::TypedefType>(Val&: qual_type)
4118 ->getDecl()
4119 ->getUnderlyingType())
4120 .GetMinimumLanguage();
4121 }
4122 }
4123 return lldb::eLanguageTypeC;
4124}
4125
4126lldb::TypeClass
4127TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) {
4128 if (!type)
4129 return lldb::eTypeClassInvalid;
4130
4131 clang::QualType qual_type =
4132 RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef});
4133
4134 switch (qual_type->getTypeClass()) {
4135 case clang::Type::Atomic:
4136 case clang::Type::Auto:
4137 case clang::Type::CountAttributed:
4138 case clang::Type::Decltype:
4139 case clang::Type::Elaborated:
4140 case clang::Type::Paren:
4141 case clang::Type::TypeOf:
4142 case clang::Type::TypeOfExpr:
4143 case clang::Type::Using:
4144 llvm_unreachable("Handled in RemoveWrappingTypes!");
4145 case clang::Type::UnaryTransform:
4146 break;
4147 case clang::Type::FunctionNoProto:
4148 return lldb::eTypeClassFunction;
4149 case clang::Type::FunctionProto:
4150 return lldb::eTypeClassFunction;
4151 case clang::Type::IncompleteArray:
4152 return lldb::eTypeClassArray;
4153 case clang::Type::VariableArray:
4154 return lldb::eTypeClassArray;
4155 case clang::Type::ConstantArray:
4156 return lldb::eTypeClassArray;
4157 case clang::Type::DependentSizedArray:
4158 return lldb::eTypeClassArray;
4159 case clang::Type::ArrayParameter:
4160 return lldb::eTypeClassArray;
4161 case clang::Type::DependentSizedExtVector:
4162 return lldb::eTypeClassVector;
4163 case clang::Type::DependentVector:
4164 return lldb::eTypeClassVector;
4165 case clang::Type::ExtVector:
4166 return lldb::eTypeClassVector;
4167 case clang::Type::Vector:
4168 return lldb::eTypeClassVector;
4169 case clang::Type::Builtin:
4170 // Ext-Int is just an integer type.
4171 case clang::Type::BitInt:
4172 case clang::Type::DependentBitInt:
4173 return lldb::eTypeClassBuiltin;
4174 case clang::Type::ObjCObjectPointer:
4175 return lldb::eTypeClassObjCObjectPointer;
4176 case clang::Type::BlockPointer:
4177 return lldb::eTypeClassBlockPointer;
4178 case clang::Type::Pointer:
4179 return lldb::eTypeClassPointer;
4180 case clang::Type::LValueReference:
4181 return lldb::eTypeClassReference;
4182 case clang::Type::RValueReference:
4183 return lldb::eTypeClassReference;
4184 case clang::Type::MemberPointer:
4185 return lldb::eTypeClassMemberPointer;
4186 case clang::Type::Complex:
4187 if (qual_type->isComplexType())
4188 return lldb::eTypeClassComplexFloat;
4189 else
4190 return lldb::eTypeClassComplexInteger;
4191 case clang::Type::ObjCObject:
4192 return lldb::eTypeClassObjCObject;
4193 case clang::Type::ObjCInterface:
4194 return lldb::eTypeClassObjCInterface;
4195 case clang::Type::Record: {
4196 const clang::RecordType *record_type =
4197 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
4198 const clang::RecordDecl *record_decl = record_type->getDecl();
4199 if (record_decl->isUnion())
4200 return lldb::eTypeClassUnion;
4201 else if (record_decl->isStruct())
4202 return lldb::eTypeClassStruct;
4203 else
4204 return lldb::eTypeClassClass;
4205 } break;
4206 case clang::Type::Enum:
4207 return lldb::eTypeClassEnumeration;
4208 case clang::Type::Typedef:
4209 return lldb::eTypeClassTypedef;
4210 case clang::Type::UnresolvedUsing:
4211 break;
4212
4213 case clang::Type::Attributed:
4214 case clang::Type::BTFTagAttributed:
4215 break;
4216 case clang::Type::TemplateTypeParm:
4217 break;
4218 case clang::Type::SubstTemplateTypeParm:
4219 break;
4220 case clang::Type::SubstTemplateTypeParmPack:
4221 break;
4222 case clang::Type::InjectedClassName:
4223 break;
4224 case clang::Type::DependentName:
4225 break;
4226 case clang::Type::DependentTemplateSpecialization:
4227 break;
4228 case clang::Type::PackExpansion:
4229 break;
4230
4231 case clang::Type::TemplateSpecialization:
4232 break;
4233 case clang::Type::DeducedTemplateSpecialization:
4234 break;
4235 case clang::Type::Pipe:
4236 break;
4237
4238 // pointer type decayed from an array or function type.
4239 case clang::Type::Decayed:
4240 break;
4241 case clang::Type::Adjusted:
4242 break;
4243 case clang::Type::ObjCTypeParam:
4244 break;
4245
4246 case clang::Type::DependentAddressSpace:
4247 break;
4248 case clang::Type::MacroQualified:
4249 break;
4250
4251 // Matrix types that we're not sure how to display at the moment.
4252 case clang::Type::ConstantMatrix:
4253 case clang::Type::DependentSizedMatrix:
4254 break;
4255
4256 // We don't handle pack indexing yet
4257 case clang::Type::PackIndexing:
4258 break;
4259
4260 case clang::Type::HLSLAttributedResource:
4261 break;
4262 case clang::Type::HLSLInlineSpirv:
4263 break;
4264 }
4265 // We don't know hot to display this type...
4266 return lldb::eTypeClassOther;
4267}
4268
4269unsigned TypeSystemClang::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
4270 if (type)
4271 return GetQualType(type).getQualifiers().getCVRQualifiers();
4272 return 0;
4273}
4274
4275// Creating related types
4276
4277CompilerType
4278TypeSystemClang::GetArrayElementType(lldb::opaque_compiler_type_t type,
4279 ExecutionContextScope *exe_scope) {
4280 if (type) {
4281 clang::QualType qual_type(GetQualType(type));
4282
4283 const clang::Type *array_eletype =
4284 qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
4285
4286 if (!array_eletype)
4287 return CompilerType();
4288
4289 return GetType(qt: clang::QualType(array_eletype, 0));
4290 }
4291 return CompilerType();
4292}
4293
4294CompilerType TypeSystemClang::GetArrayType(lldb::opaque_compiler_type_t type,
4295 uint64_t size) {
4296 if (type) {
4297 clang::QualType qual_type(GetCanonicalQualType(type));
4298 clang::ASTContext &ast_ctx = getASTContext();
4299 if (size != 0)
4300 return GetType(qt: ast_ctx.getConstantArrayType(
4301 EltTy: qual_type, ArySize: llvm::APInt(64, size), SizeExpr: nullptr,
4302 ASM: clang::ArraySizeModifier::Normal, IndexTypeQuals: 0));
4303 else
4304 return GetType(qt: ast_ctx.getIncompleteArrayType(
4305 EltTy: qual_type, ASM: clang::ArraySizeModifier::Normal, IndexTypeQuals: 0));
4306 }
4307
4308 return CompilerType();
4309}
4310
4311CompilerType
4312TypeSystemClang::GetCanonicalType(lldb::opaque_compiler_type_t type) {
4313 if (type)
4314 return GetType(qt: GetCanonicalQualType(type));
4315 return CompilerType();
4316}
4317
4318static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast,
4319 clang::QualType qual_type) {
4320 if (qual_type->isPointerType())
4321 qual_type = ast->getPointerType(
4322 T: GetFullyUnqualifiedType_Impl(ast, qual_type: qual_type->getPointeeType()));
4323 else if (const ConstantArrayType *arr =
4324 ast->getAsConstantArrayType(T: qual_type)) {
4325 qual_type = ast->getConstantArrayType(
4326 EltTy: GetFullyUnqualifiedType_Impl(ast, arr->getElementType()),
4327 ArySize: arr->getSize(), SizeExpr: arr->getSizeExpr(), ASM: arr->getSizeModifier(),
4328 IndexTypeQuals: arr->getIndexTypeQualifiers().getAsOpaqueValue());
4329 } else
4330 qual_type = qual_type.getUnqualifiedType();
4331 qual_type.removeLocalConst();
4332 qual_type.removeLocalRestrict();
4333 qual_type.removeLocalVolatile();
4334 return qual_type;
4335}
4336
4337CompilerType
4338TypeSystemClang::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
4339 if (type)
4340 return GetType(
4341 qt: GetFullyUnqualifiedType_Impl(ast: &getASTContext(), qual_type: GetQualType(type)));
4342 return CompilerType();
4343}
4344
4345CompilerType
4346TypeSystemClang::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) {
4347 if (type)
4348 return GetEnumerationIntegerType(type: GetType(qt: GetCanonicalQualType(type)));
4349 return CompilerType();
4350}
4351
4352int TypeSystemClang::GetFunctionArgumentCount(
4353 lldb::opaque_compiler_type_t type) {
4354 if (type) {
4355 const clang::FunctionProtoType *func =
4356 llvm::dyn_cast<clang::FunctionProtoType>(Val: GetCanonicalQualType(type));
4357 if (func)
4358 return func->getNumParams();
4359 }
4360 return -1;
4361}
4362
4363CompilerType TypeSystemClang::GetFunctionArgumentTypeAtIndex(
4364 lldb::opaque_compiler_type_t type, size_t idx) {
4365 if (type) {
4366 const clang::FunctionProtoType *func =
4367 llvm::dyn_cast<clang::FunctionProtoType>(Val: GetQualType(type));
4368 if (func) {
4369 const uint32_t num_args = func->getNumParams();
4370 if (idx < num_args)
4371 return GetType(qt: func->getParamType(i: idx));
4372 }
4373 }
4374 return CompilerType();
4375}
4376
4377CompilerType
4378TypeSystemClang::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
4379 if (type) {
4380 clang::QualType qual_type(GetQualType(type));
4381 const clang::FunctionProtoType *func =
4382 llvm::dyn_cast<clang::FunctionProtoType>(Val: qual_type.getTypePtr());
4383 if (func)
4384 return GetType(qt: func->getReturnType());
4385 }
4386 return CompilerType();
4387}
4388
4389size_t
4390TypeSystemClang::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
4391 size_t num_functions = 0;
4392 if (type) {
4393 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
4394 switch (qual_type->getTypeClass()) {
4395 case clang::Type::Record:
4396 if (GetCompleteQualType(ast: &getASTContext(), qual_type)) {
4397 const clang::RecordType *record_type =
4398 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
4399 const clang::RecordDecl *record_decl = record_type->getDecl();
4400 assert(record_decl);
4401 const clang::CXXRecordDecl *cxx_record_decl =
4402 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
4403 if (cxx_record_decl)
4404 num_functions = std::distance(first: cxx_record_decl->method_begin(),
4405 last: cxx_record_decl->method_end());
4406 }
4407 break;
4408
4409 case clang::Type::ObjCObjectPointer: {
4410 const clang::ObjCObjectPointerType *objc_class_type =
4411 qual_type->castAs<clang::ObjCObjectPointerType>();
4412 const clang::ObjCInterfaceType *objc_interface_type =
4413 objc_class_type->getInterfaceType();
4414 if (objc_interface_type &&
4415 GetCompleteType(type: static_cast<lldb::opaque_compiler_type_t>(
4416 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
4417 clang::ObjCInterfaceDecl *class_interface_decl =
4418 objc_interface_type->getDecl();
4419 if (class_interface_decl) {
4420 num_functions = std::distance(class_interface_decl->meth_begin(),
4421 class_interface_decl->meth_end());
4422 }
4423 }
4424 break;
4425 }
4426
4427 case clang::Type::ObjCObject:
4428 case clang::Type::ObjCInterface:
4429 if (GetCompleteType(type)) {
4430 const clang::ObjCObjectType *objc_class_type =
4431 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
4432 if (objc_class_type) {
4433 clang::ObjCInterfaceDecl *class_interface_decl =
4434 objc_class_type->getInterface();
4435 if (class_interface_decl)
4436 num_functions = std::distance(class_interface_decl->meth_begin(),
4437 class_interface_decl->meth_end());
4438 }
4439 }
4440 break;
4441
4442 default:
4443 break;
4444 }
4445 }
4446 return num_functions;
4447}
4448
4449TypeMemberFunctionImpl
4450TypeSystemClang::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
4451 size_t idx) {
4452 std::string name;
4453 MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
4454 CompilerType clang_type;
4455 CompilerDecl clang_decl;
4456 if (type) {
4457 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
4458 switch (qual_type->getTypeClass()) {
4459 case clang::Type::Record:
4460 if (GetCompleteQualType(ast: &getASTContext(), qual_type)) {
4461 const clang::RecordType *record_type =
4462 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
4463 const clang::RecordDecl *record_decl = record_type->getDecl();
4464 assert(record_decl);
4465 const clang::CXXRecordDecl *cxx_record_decl =
4466 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
4467 if (cxx_record_decl) {
4468 auto method_iter = cxx_record_decl->method_begin();
4469 auto method_end = cxx_record_decl->method_end();
4470 if (idx <
4471 static_cast<size_t>(std::distance(first: method_iter, last: method_end))) {
4472 std::advance(i&: method_iter, n: idx);
4473 clang::CXXMethodDecl *cxx_method_decl =
4474 method_iter->getCanonicalDecl();
4475 if (cxx_method_decl) {
4476 name = cxx_method_decl->getDeclName().getAsString();
4477 if (cxx_method_decl->isStatic())
4478 kind = lldb::eMemberFunctionKindStaticMethod;
4479 else if (llvm::isa<clang::CXXConstructorDecl>(Val: cxx_method_decl))
4480 kind = lldb::eMemberFunctionKindConstructor;
4481 else if (llvm::isa<clang::CXXDestructorDecl>(Val: cxx_method_decl))
4482 kind = lldb::eMemberFunctionKindDestructor;
4483 else
4484 kind = lldb::eMemberFunctionKindInstanceMethod;
4485 clang_type = GetType(qt: cxx_method_decl->getType());
4486 clang_decl = GetCompilerDecl(cxx_method_decl);
4487 }
4488 }
4489 }
4490 }
4491 break;
4492
4493 case clang::Type::ObjCObjectPointer: {
4494 const clang::ObjCObjectPointerType *objc_class_type =
4495 qual_type->castAs<clang::ObjCObjectPointerType>();
4496 const clang::ObjCInterfaceType *objc_interface_type =
4497 objc_class_type->getInterfaceType();
4498 if (objc_interface_type &&
4499 GetCompleteType(type: static_cast<lldb::opaque_compiler_type_t>(
4500 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
4501 clang::ObjCInterfaceDecl *class_interface_decl =
4502 objc_interface_type->getDecl();
4503 if (class_interface_decl) {
4504 auto method_iter = class_interface_decl->meth_begin();
4505 auto method_end = class_interface_decl->meth_end();
4506 if (idx <
4507 static_cast<size_t>(std::distance(method_iter, method_end))) {
4508 std::advance(method_iter, idx);
4509 clang::ObjCMethodDecl *objc_method_decl =
4510 method_iter->getCanonicalDecl();
4511 if (objc_method_decl) {
4512 clang_decl = GetCompilerDecl(objc_method_decl);
4513 name = objc_method_decl->getSelector().getAsString();
4514 if (objc_method_decl->isClassMethod())
4515 kind = lldb::eMemberFunctionKindStaticMethod;
4516 else
4517 kind = lldb::eMemberFunctionKindInstanceMethod;
4518 }
4519 }
4520 }
4521 }
4522 break;
4523 }
4524
4525 case clang::Type::ObjCObject:
4526 case clang::Type::ObjCInterface:
4527 if (GetCompleteType(type)) {
4528 const clang::ObjCObjectType *objc_class_type =
4529 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
4530 if (objc_class_type) {
4531 clang::ObjCInterfaceDecl *class_interface_decl =
4532 objc_class_type->getInterface();
4533 if (class_interface_decl) {
4534 auto method_iter = class_interface_decl->meth_begin();
4535 auto method_end = class_interface_decl->meth_end();
4536 if (idx <
4537 static_cast<size_t>(std::distance(method_iter, method_end))) {
4538 std::advance(method_iter, idx);
4539 clang::ObjCMethodDecl *objc_method_decl =
4540 method_iter->getCanonicalDecl();
4541 if (objc_method_decl) {
4542 clang_decl = GetCompilerDecl(objc_method_decl);
4543 name = objc_method_decl->getSelector().getAsString();
4544 if (objc_method_decl->isClassMethod())
4545 kind = lldb::eMemberFunctionKindStaticMethod;
4546 else
4547 kind = lldb::eMemberFunctionKindInstanceMethod;
4548 }
4549 }
4550 }
4551 }
4552 }
4553 break;
4554
4555 default:
4556 break;
4557 }
4558 }
4559
4560 if (kind == eMemberFunctionKindUnknown)
4561 return TypeMemberFunctionImpl();
4562 else
4563 return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
4564}
4565
4566CompilerType
4567TypeSystemClang::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
4568 if (type)
4569 return GetType(qt: GetQualType(type).getNonReferenceType());
4570 return CompilerType();
4571}
4572
4573CompilerType
4574TypeSystemClang::GetPointeeType(lldb::opaque_compiler_type_t type) {
4575 if (type) {
4576 clang::QualType qual_type(GetQualType(type));
4577 return GetType(qt: qual_type.getTypePtr()->getPointeeType());
4578 }
4579 return CompilerType();
4580}
4581
4582CompilerType
4583TypeSystemClang::GetPointerType(lldb::opaque_compiler_type_t type) {
4584 if (type) {
4585 clang::QualType qual_type(GetQualType(type));
4586
4587 switch (qual_type.getDesugaredType(Context: getASTContext())->getTypeClass()) {
4588 case clang::Type::ObjCObject:
4589 case clang::Type::ObjCInterface:
4590 return GetType(qt: getASTContext().getObjCObjectPointerType(OIT: qual_type));
4591
4592 default:
4593 return GetType(qt: getASTContext().getPointerType(T: qual_type));
4594 }
4595 }
4596 return CompilerType();
4597}
4598
4599CompilerType
4600TypeSystemClang::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
4601 if (type)
4602 return GetType(qt: getASTContext().getLValueReferenceType(T: GetQualType(type)));
4603 else
4604 return CompilerType();
4605}
4606
4607CompilerType
4608TypeSystemClang::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
4609 if (type)
4610 return GetType(qt: getASTContext().getRValueReferenceType(T: GetQualType(type)));
4611 else
4612 return CompilerType();
4613}
4614
4615CompilerType TypeSystemClang::GetAtomicType(lldb::opaque_compiler_type_t type) {
4616 if (!type)
4617 return CompilerType();
4618 return GetType(qt: getASTContext().getAtomicType(T: GetQualType(type)));
4619}
4620
4621CompilerType
4622TypeSystemClang::AddConstModifier(lldb::opaque_compiler_type_t type) {
4623 if (type) {
4624 clang::QualType result(GetQualType(type));
4625 result.addConst();
4626 return GetType(qt: result);
4627 }
4628 return CompilerType();
4629}
4630
4631CompilerType
4632TypeSystemClang::AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
4633 uint32_t payload) {
4634 if (type) {
4635 clang::ASTContext &clang_ast = getASTContext();
4636 auto pauth = PointerAuthQualifier::fromOpaqueValue(Opaque: payload);
4637 clang::QualType result =
4638 clang_ast.getPointerAuthType(Ty: GetQualType(type), PointerAuth: pauth);
4639 return GetType(qt: result);
4640 }
4641 return CompilerType();
4642}
4643
4644CompilerType
4645TypeSystemClang::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
4646 if (type) {
4647 clang::QualType result(GetQualType(type));
4648 result.addVolatile();
4649 return GetType(qt: result);
4650 }
4651 return CompilerType();
4652}
4653
4654CompilerType
4655TypeSystemClang::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
4656 if (type) {
4657 clang::QualType result(GetQualType(type));
4658 result.addRestrict();
4659 return GetType(qt: result);
4660 }
4661 return CompilerType();
4662}
4663
4664CompilerType TypeSystemClang::CreateTypedef(
4665 lldb::opaque_compiler_type_t type, const char *typedef_name,
4666 const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) {
4667 if (type && typedef_name && typedef_name[0]) {
4668 clang::ASTContext &clang_ast = getASTContext();
4669 clang::QualType qual_type(GetQualType(type));
4670
4671 clang::DeclContext *decl_ctx =
4672 TypeSystemClang::DeclContextGetAsDeclContext(dc: compiler_decl_ctx);
4673 if (!decl_ctx)
4674 decl_ctx = getASTContext().getTranslationUnitDecl();
4675
4676 clang::TypedefDecl *decl =
4677 clang::TypedefDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
4678 decl->setDeclContext(decl_ctx);
4679 decl->setDeclName(&clang_ast.Idents.get(Name: typedef_name));
4680 decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(T: qual_type));
4681 decl_ctx->addDecl(decl);
4682 SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule());
4683
4684 clang::TagDecl *tdecl = nullptr;
4685 if (!qual_type.isNull()) {
4686 if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
4687 tdecl = rt->getDecl();
4688 if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
4689 tdecl = et->getDecl();
4690 }
4691
4692 // Check whether this declaration is an anonymous struct, union, or enum,
4693 // hidden behind a typedef. If so, we try to check whether we have a
4694 // typedef tag to attach to the original record declaration
4695 if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
4696 tdecl->setTypedefNameForAnonDecl(decl);
4697
4698 decl->setAccess(clang::AS_public); // TODO respect proper access specifier
4699
4700 // Get a uniqued clang::QualType for the typedef decl type
4701 return GetType(qt: clang_ast.getTypedefType(decl));
4702 }
4703 return CompilerType();
4704}
4705
4706CompilerType
4707TypeSystemClang::GetTypedefedType(lldb::opaque_compiler_type_t type) {
4708 if (type) {
4709 const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(
4710 RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}));
4711 if (typedef_type)
4712 return GetType(qt: typedef_type->getDecl()->getUnderlyingType());
4713 }
4714 return CompilerType();
4715}
4716
4717// Create related types using the current type's AST
4718
4719CompilerType TypeSystemClang::GetBasicTypeFromAST(lldb::BasicType basic_type) {
4720 return TypeSystemClang::GetBasicType(basic_type);
4721}
4722
4723CompilerType TypeSystemClang::CreateGenericFunctionPrototype() {
4724 clang::ASTContext &ast = getASTContext();
4725 const FunctionType::ExtInfo generic_ext_info(
4726 /*noReturn=*/false,
4727 /*hasRegParm=*/false,
4728 /*regParm=*/0,
4729 CallingConv::CC_C,
4730 /*producesResult=*/false,
4731 /*noCallerSavedRegs=*/false,
4732 /*NoCfCheck=*/false,
4733 /*cmseNSCall=*/false);
4734 QualType func_type = ast.getFunctionNoProtoType(ast.VoidTy, generic_ext_info);
4735 return GetType(qt: func_type);
4736}
4737// Exploring the type
4738
4739const llvm::fltSemantics &
4740TypeSystemClang::GetFloatTypeSemantics(size_t byte_size) {
4741 clang::ASTContext &ast = getASTContext();
4742 const size_t bit_size = byte_size * 8;
4743 if (bit_size == ast.getTypeSize(ast.FloatTy))
4744 return ast.getFloatTypeSemantics(T: ast.FloatTy);
4745 else if (bit_size == ast.getTypeSize(ast.DoubleTy))
4746 return ast.getFloatTypeSemantics(T: ast.DoubleTy);
4747 else if (bit_size == ast.getTypeSize(ast.LongDoubleTy) ||
4748 bit_size == llvm::APFloat::semanticsSizeInBits(
4749 ast.getFloatTypeSemantics(T: ast.LongDoubleTy)))
4750 return ast.getFloatTypeSemantics(T: ast.LongDoubleTy);
4751 else if (bit_size == ast.getTypeSize(ast.HalfTy))
4752 return ast.getFloatTypeSemantics(T: ast.HalfTy);
4753 return llvm::APFloatBase::Bogus();
4754}
4755
4756llvm::Expected<uint64_t>
4757TypeSystemClang::GetObjCBitSize(QualType qual_type,
4758 ExecutionContextScope *exe_scope) {
4759 assert(qual_type->isObjCObjectOrInterfaceType());
4760 ExecutionContext exe_ctx(exe_scope);
4761 if (Process *process = exe_ctx.GetProcessPtr()) {
4762 if (ObjCLanguageRuntime *objc_runtime =
4763 ObjCLanguageRuntime::Get(process&: *process)) {
4764 if (std::optional<uint64_t> bit_size =
4765 objc_runtime->GetTypeBitSize(compiler_type: GetType(qt: qual_type)))
4766 return *bit_size;
4767 }
4768 } else {
4769 static bool g_printed = false;
4770 if (!g_printed) {
4771 StreamString s;
4772 DumpTypeDescription(type: qual_type.getAsOpaquePtr(), s);
4773
4774 llvm::outs() << "warning: trying to determine the size of type ";
4775 llvm::outs() << s.GetString() << "\n";
4776 llvm::outs() << "without a valid ExecutionContext. this is not "
4777 "reliable. please file a bug against LLDB.\n";
4778 llvm::outs() << "backtrace:\n";
4779 llvm::sys::PrintStackTrace(OS&: llvm::outs());
4780 llvm::outs() << "\n";
4781 g_printed = true;
4782 }
4783 }
4784
4785 return getASTContext().getTypeSize(T: qual_type) +
4786 getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy);
4787}
4788
4789llvm::Expected<uint64_t>
4790TypeSystemClang::GetBitSize(lldb::opaque_compiler_type_t type,
4791 ExecutionContextScope *exe_scope) {
4792 const bool base_name_only = true;
4793 if (!GetCompleteType(type))
4794 return llvm::createStringError(
4795 Fmt: "could not complete type %s",
4796 Vals: GetTypeName(type, base_only: base_name_only).AsCString(value_if_empty: ""));
4797
4798 clang::QualType qual_type(GetCanonicalQualType(type));
4799 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4800 switch (type_class) {
4801 case clang::Type::ConstantArray:
4802 case clang::Type::FunctionProto:
4803 case clang::Type::Record:
4804 return getASTContext().getTypeSize(T: qual_type);
4805 case clang::Type::ObjCInterface:
4806 case clang::Type::ObjCObject:
4807 return GetObjCBitSize(qual_type, exe_scope);
4808 case clang::Type::IncompleteArray: {
4809 const uint64_t bit_size = getASTContext().getTypeSize(T: qual_type);
4810 if (bit_size == 0)
4811 return getASTContext().getTypeSize(
4812 qual_type->getArrayElementTypeNoTypeQual()
4813 ->getCanonicalTypeUnqualified());
4814
4815 return bit_size;
4816 }
4817 default:
4818 if (const uint64_t bit_size = getASTContext().getTypeSize(T: qual_type))
4819 return bit_size;
4820 }
4821
4822 return llvm::createStringError(
4823 Fmt: "could not get size of type %s",
4824 Vals: GetTypeName(type, base_only: base_name_only).AsCString(value_if_empty: ""));
4825}
4826
4827std::optional<size_t>
4828TypeSystemClang::GetTypeBitAlign(lldb::opaque_compiler_type_t type,
4829 ExecutionContextScope *exe_scope) {
4830 if (GetCompleteType(type))
4831 return getASTContext().getTypeAlign(T: GetQualType(type));
4832 return {};
4833}
4834
4835lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
4836 uint64_t &count) {
4837 if (!type)
4838 return lldb::eEncodingInvalid;
4839
4840 count = 1;
4841 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
4842
4843 switch (qual_type->getTypeClass()) {
4844 case clang::Type::Atomic:
4845 case clang::Type::Auto:
4846 case clang::Type::CountAttributed:
4847 case clang::Type::Decltype:
4848 case clang::Type::Elaborated:
4849 case clang::Type::Paren:
4850 case clang::Type::Typedef:
4851 case clang::Type::TypeOf:
4852 case clang::Type::TypeOfExpr:
4853 case clang::Type::Using:
4854 llvm_unreachable("Handled in RemoveWrappingTypes!");
4855
4856 case clang::Type::UnaryTransform:
4857 break;
4858
4859 case clang::Type::FunctionNoProto:
4860 case clang::Type::FunctionProto:
4861 return lldb::eEncodingUint;
4862
4863 case clang::Type::IncompleteArray:
4864 case clang::Type::VariableArray:
4865 case clang::Type::ArrayParameter:
4866 break;
4867
4868 case clang::Type::ConstantArray:
4869 break;
4870
4871 case clang::Type::DependentVector:
4872 case clang::Type::ExtVector:
4873 case clang::Type::Vector:
4874 // TODO: Set this to more than one???
4875 break;
4876
4877 case clang::Type::BitInt:
4878 case clang::Type::DependentBitInt:
4879 return qual_type->isUnsignedIntegerType() ? lldb::eEncodingUint
4880 : lldb::eEncodingSint;
4881
4882 case clang::Type::Builtin:
4883 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
4884 case clang::BuiltinType::Void:
4885 break;
4886
4887 case clang::BuiltinType::Char_S:
4888 case clang::BuiltinType::SChar:
4889 case clang::BuiltinType::WChar_S:
4890 case clang::BuiltinType::Short:
4891 case clang::BuiltinType::Int:
4892 case clang::BuiltinType::Long:
4893 case clang::BuiltinType::LongLong:
4894 case clang::BuiltinType::Int128:
4895 return lldb::eEncodingSint;
4896
4897 case clang::BuiltinType::Bool:
4898 case clang::BuiltinType::Char_U:
4899 case clang::BuiltinType::UChar:
4900 case clang::BuiltinType::WChar_U:
4901 case clang::BuiltinType::Char8:
4902 case clang::BuiltinType::Char16:
4903 case clang::BuiltinType::Char32:
4904 case clang::BuiltinType::UShort:
4905 case clang::BuiltinType::UInt:
4906 case clang::BuiltinType::ULong:
4907 case clang::BuiltinType::ULongLong:
4908 case clang::BuiltinType::UInt128:
4909 return lldb::eEncodingUint;
4910
4911 // Fixed point types. Note that they are currently ignored.
4912 case clang::BuiltinType::ShortAccum:
4913 case clang::BuiltinType::Accum:
4914 case clang::BuiltinType::LongAccum:
4915 case clang::BuiltinType::UShortAccum:
4916 case clang::BuiltinType::UAccum:
4917 case clang::BuiltinType::ULongAccum:
4918 case clang::BuiltinType::ShortFract:
4919 case clang::BuiltinType::Fract:
4920 case clang::BuiltinType::LongFract:
4921 case clang::BuiltinType::UShortFract:
4922 case clang::BuiltinType::UFract:
4923 case clang::BuiltinType::ULongFract:
4924 case clang::BuiltinType::SatShortAccum:
4925 case clang::BuiltinType::SatAccum:
4926 case clang::BuiltinType::SatLongAccum:
4927 case clang::BuiltinType::SatUShortAccum:
4928 case clang::BuiltinType::SatUAccum:
4929 case clang::BuiltinType::SatULongAccum:
4930 case clang::BuiltinType::SatShortFract:
4931 case clang::BuiltinType::SatFract:
4932 case clang::BuiltinType::SatLongFract:
4933 case clang::BuiltinType::SatUShortFract:
4934 case clang::BuiltinType::SatUFract:
4935 case clang::BuiltinType::SatULongFract:
4936 break;
4937
4938 case clang::BuiltinType::Half:
4939 case clang::BuiltinType::Float:
4940 case clang::BuiltinType::Float16:
4941 case clang::BuiltinType::Float128:
4942 case clang::BuiltinType::Double:
4943 case clang::BuiltinType::LongDouble:
4944 case clang::BuiltinType::BFloat16:
4945 case clang::BuiltinType::Ibm128:
4946 return lldb::eEncodingIEEE754;
4947
4948 case clang::BuiltinType::ObjCClass:
4949 case clang::BuiltinType::ObjCId:
4950 case clang::BuiltinType::ObjCSel:
4951 return lldb::eEncodingUint;
4952
4953 case clang::BuiltinType::NullPtr:
4954 return lldb::eEncodingUint;
4955
4956 case clang::BuiltinType::Kind::ARCUnbridgedCast:
4957 case clang::BuiltinType::Kind::BoundMember:
4958 case clang::BuiltinType::Kind::BuiltinFn:
4959 case clang::BuiltinType::Kind::Dependent:
4960 case clang::BuiltinType::Kind::OCLClkEvent:
4961 case clang::BuiltinType::Kind::OCLEvent:
4962 case clang::BuiltinType::Kind::OCLImage1dRO:
4963 case clang::BuiltinType::Kind::OCLImage1dWO:
4964 case clang::BuiltinType::Kind::OCLImage1dRW:
4965 case clang::BuiltinType::Kind::OCLImage1dArrayRO:
4966 case clang::BuiltinType::Kind::OCLImage1dArrayWO:
4967 case clang::BuiltinType::Kind::OCLImage1dArrayRW:
4968 case clang::BuiltinType::Kind::OCLImage1dBufferRO:
4969 case clang::BuiltinType::Kind::OCLImage1dBufferWO:
4970 case clang::BuiltinType::Kind::OCLImage1dBufferRW:
4971 case clang::BuiltinType::Kind::OCLImage2dRO:
4972 case clang::BuiltinType::Kind::OCLImage2dWO:
4973 case clang::BuiltinType::Kind::OCLImage2dRW:
4974 case clang::BuiltinType::Kind::OCLImage2dArrayRO:
4975 case clang::BuiltinType::Kind::OCLImage2dArrayWO:
4976 case clang::BuiltinType::Kind::OCLImage2dArrayRW:
4977 case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
4978 case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
4979 case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
4980 case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
4981 case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
4982 case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
4983 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
4984 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
4985 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
4986 case clang::BuiltinType::Kind::OCLImage2dDepthRO:
4987 case clang::BuiltinType::Kind::OCLImage2dDepthWO:
4988 case clang::BuiltinType::Kind::OCLImage2dDepthRW:
4989 case clang::BuiltinType::Kind::OCLImage2dMSAARO:
4990 case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
4991 case clang::BuiltinType::Kind::OCLImage2dMSAARW:
4992 case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
4993 case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
4994 case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
4995 case clang::BuiltinType::Kind::OCLImage3dRO:
4996 case clang::BuiltinType::Kind::OCLImage3dWO:
4997 case clang::BuiltinType::Kind::OCLImage3dRW:
4998 case clang::BuiltinType::Kind::OCLQueue:
4999 case clang::BuiltinType::Kind::OCLReserveID:
5000 case clang::BuiltinType::Kind::OCLSampler:
5001 case clang::BuiltinType::Kind::HLSLResource:
5002 case clang::BuiltinType::Kind::ArraySection:
5003 case clang::BuiltinType::Kind::OMPArrayShaping:
5004 case clang::BuiltinType::Kind::OMPIterator:
5005 case clang::BuiltinType::Kind::Overload:
5006 case clang::BuiltinType::Kind::PseudoObject:
5007 case clang::BuiltinType::Kind::UnknownAny:
5008 break;
5009
5010 case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload:
5011 case clang::BuiltinType::OCLIntelSubgroupAVCImePayload:
5012 case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload:
5013 case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload:
5014 case clang::BuiltinType::OCLIntelSubgroupAVCMceResult:
5015 case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
5016 case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
5017 case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
5018 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleReferenceStreamout:
5019 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualReferenceStreamout:
5020 case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleReferenceStreamin:
5021 case clang::BuiltinType::OCLIntelSubgroupAVCImeDualReferenceStreamin:
5022 break;
5023
5024 // PowerPC -- Matrix Multiply Assist
5025 case clang::BuiltinType::VectorPair:
5026 case clang::BuiltinType::VectorQuad:
5027 break;
5028
5029 // ARM -- Scalable Vector Extension
5030#define SVE_TYPE(Name, Id, SingletonId) case clang::BuiltinType::Id:
5031#include "clang/Basic/AArch64ACLETypes.def"
5032 break;
5033
5034 // RISC-V V builtin types.
5035#define RVV_TYPE(Name, Id, SingletonId) case clang::BuiltinType::Id:
5036#include "clang/Basic/RISCVVTypes.def"
5037 break;
5038
5039 // WebAssembly builtin types.
5040 case clang::BuiltinType::WasmExternRef:
5041 break;
5042
5043 case clang::BuiltinType::IncompleteMatrixIdx:
5044 break;
5045
5046 case clang::BuiltinType::UnresolvedTemplate:
5047 break;
5048
5049 // AMD GPU builtin types.
5050#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) \
5051 case clang::BuiltinType::Id:
5052#include "clang/Basic/AMDGPUTypes.def"
5053 break;
5054 }
5055 break;
5056 // All pointer types are represented as unsigned integer encodings. We may
5057 // nee to add a eEncodingPointer if we ever need to know the difference
5058 case clang::Type::ObjCObjectPointer:
5059 case clang::Type::BlockPointer:
5060 case clang::Type::Pointer:
5061 case clang::Type::LValueReference:
5062 case clang::Type::RValueReference:
5063 case clang::Type::MemberPointer:
5064 return lldb::eEncodingUint;
5065 case clang::Type::Complex: {
5066 lldb::Encoding encoding = lldb::eEncodingIEEE754;
5067 if (qual_type->isComplexType())
5068 encoding = lldb::eEncodingIEEE754;
5069 else {
5070 const clang::ComplexType *complex_type =
5071 qual_type->getAsComplexIntegerType();
5072 if (complex_type)
5073 encoding = GetType(qt: complex_type->getElementType()).GetEncoding(count);
5074 else
5075 encoding = lldb::eEncodingSint;
5076 }
5077 count = 2;
5078 return encoding;
5079 }
5080
5081 case clang::Type::ObjCInterface:
5082 break;
5083 case clang::Type::Record:
5084 break;
5085 case clang::Type::Enum:
5086 return qual_type->isUnsignedIntegerOrEnumerationType()
5087 ? lldb::eEncodingUint
5088 : lldb::eEncodingSint;
5089 case clang::Type::DependentSizedArray:
5090 case clang::Type::DependentSizedExtVector:
5091 case clang::Type::UnresolvedUsing:
5092 case clang::Type::Attributed:
5093 case clang::Type::BTFTagAttributed:
5094 case clang::Type::TemplateTypeParm:
5095 case clang::Type::SubstTemplateTypeParm:
5096 case clang::Type::SubstTemplateTypeParmPack:
5097 case clang::Type::InjectedClassName:
5098 case clang::Type::DependentName:
5099 case clang::Type::DependentTemplateSpecialization:
5100 case clang::Type::PackExpansion:
5101 case clang::Type::ObjCObject:
5102
5103 case clang::Type::TemplateSpecialization:
5104 case clang::Type::DeducedTemplateSpecialization:
5105 case clang::Type::Adjusted:
5106 case clang::Type::Pipe:
5107 break;
5108
5109 // pointer type decayed from an array or function type.
5110 case clang::Type::Decayed:
5111 break;
5112 case clang::Type::ObjCTypeParam:
5113 break;
5114
5115 case clang::Type::DependentAddressSpace:
5116 break;
5117 case clang::Type::MacroQualified:
5118 break;
5119
5120 case clang::Type::ConstantMatrix:
5121 case clang::Type::DependentSizedMatrix:
5122 break;
5123
5124 // We don't handle pack indexing yet
5125 case clang::Type::PackIndexing:
5126 break;
5127
5128 case clang::Type::HLSLAttributedResource:
5129 break;
5130 case clang::Type::HLSLInlineSpirv:
5131 break;
5132 }
5133 count = 0;
5134 return lldb::eEncodingInvalid;
5135}
5136
5137lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
5138 if (!type)
5139 return lldb::eFormatDefault;
5140
5141 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5142
5143 switch (qual_type->getTypeClass()) {
5144 case clang::Type::Atomic:
5145 case clang::Type::Auto:
5146 case clang::Type::CountAttributed:
5147 case clang::Type::Decltype:
5148 case clang::Type::Elaborated:
5149 case clang::Type::Paren:
5150 case clang::Type::Typedef:
5151 case clang::Type::TypeOf:
5152 case clang::Type::TypeOfExpr:
5153 case clang::Type::Using:
5154 llvm_unreachable("Handled in RemoveWrappingTypes!");
5155 case clang::Type::UnaryTransform:
5156 break;
5157
5158 case clang::Type::FunctionNoProto:
5159 case clang::Type::FunctionProto:
5160 break;
5161
5162 case clang::Type::IncompleteArray:
5163 case clang::Type::VariableArray:
5164 case clang::Type::ArrayParameter:
5165 break;
5166
5167 case clang::Type::ConstantArray:
5168 return lldb::eFormatVoid; // no value
5169
5170 case clang::Type::DependentVector:
5171 case clang::Type::ExtVector:
5172 case clang::Type::Vector:
5173 break;
5174
5175 case clang::Type::BitInt:
5176 case clang::Type::DependentBitInt:
5177 return qual_type->isUnsignedIntegerType() ? lldb::eFormatUnsigned
5178 : lldb::eFormatDecimal;
5179
5180 case clang::Type::Builtin:
5181 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
5182 case clang::BuiltinType::UnknownAny:
5183 case clang::BuiltinType::Void:
5184 case clang::BuiltinType::BoundMember:
5185 break;
5186
5187 case clang::BuiltinType::Bool:
5188 return lldb::eFormatBoolean;
5189 case clang::BuiltinType::Char_S:
5190 case clang::BuiltinType::SChar:
5191 case clang::BuiltinType::WChar_S:
5192 case clang::BuiltinType::Char_U:
5193 case clang::BuiltinType::UChar:
5194 case clang::BuiltinType::WChar_U:
5195 return lldb::eFormatChar;
5196 case clang::BuiltinType::Char8:
5197 return lldb::eFormatUnicode8;
5198 case clang::BuiltinType::Char16:
5199 return lldb::eFormatUnicode16;
5200 case clang::BuiltinType::Char32:
5201 return lldb::eFormatUnicode32;
5202 case clang::BuiltinType::UShort:
5203 return lldb::eFormatUnsigned;
5204 case clang::BuiltinType::Short:
5205 return lldb::eFormatDecimal;
5206 case clang::BuiltinType::UInt:
5207 return lldb::eFormatUnsigned;
5208 case clang::BuiltinType::Int:
5209 return lldb::eFormatDecimal;
5210 case clang::BuiltinType::ULong:
5211 return lldb::eFormatUnsigned;
5212 case clang::BuiltinType::Long:
5213 return lldb::eFormatDecimal;
5214 case clang::BuiltinType::ULongLong:
5215 return lldb::eFormatUnsigned;
5216 case clang::BuiltinType::LongLong:
5217 return lldb::eFormatDecimal;
5218 case clang::BuiltinType::UInt128:
5219 return lldb::eFormatUnsigned;
5220 case clang::BuiltinType::Int128:
5221 return lldb::eFormatDecimal;
5222 case clang::BuiltinType::Half:
5223 case clang::BuiltinType::Float:
5224 case clang::BuiltinType::Double:
5225 case clang::BuiltinType::LongDouble:
5226 return lldb::eFormatFloat;
5227 default:
5228 return lldb::eFormatHex;
5229 }
5230 break;
5231 case clang::Type::ObjCObjectPointer:
5232 return lldb::eFormatHex;
5233 case clang::Type::BlockPointer:
5234 return lldb::eFormatHex;
5235 case clang::Type::Pointer:
5236 return lldb::eFormatHex;
5237 case clang::Type::LValueReference:
5238 case clang::Type::RValueReference:
5239 return lldb::eFormatHex;
5240 case clang::Type::MemberPointer:
5241 return lldb::eFormatHex;
5242 case clang::Type::Complex: {
5243 if (qual_type->isComplexType())
5244 return lldb::eFormatComplex;
5245 else
5246 return lldb::eFormatComplexInteger;
5247 }
5248 case clang::Type::ObjCInterface:
5249 break;
5250 case clang::Type::Record:
5251 break;
5252 case clang::Type::Enum:
5253 return lldb::eFormatEnum;
5254 case clang::Type::DependentSizedArray:
5255 case clang::Type::DependentSizedExtVector:
5256 case clang::Type::UnresolvedUsing:
5257 case clang::Type::Attributed:
5258 case clang::Type::BTFTagAttributed:
5259 case clang::Type::TemplateTypeParm:
5260 case clang::Type::SubstTemplateTypeParm:
5261 case clang::Type::SubstTemplateTypeParmPack:
5262 case clang::Type::InjectedClassName:
5263 case clang::Type::DependentName:
5264 case clang::Type::DependentTemplateSpecialization:
5265 case clang::Type::PackExpansion:
5266 case clang::Type::ObjCObject:
5267
5268 case clang::Type::TemplateSpecialization:
5269 case clang::Type::DeducedTemplateSpecialization:
5270 case clang::Type::Adjusted:
5271 case clang::Type::Pipe:
5272 break;
5273
5274 // pointer type decayed from an array or function type.
5275 case clang::Type::Decayed:
5276 break;
5277 case clang::Type::ObjCTypeParam:
5278 break;
5279
5280 case clang::Type::DependentAddressSpace:
5281 break;
5282 case clang::Type::MacroQualified:
5283 break;
5284
5285 // Matrix types we're not sure how to display yet.
5286 case clang::Type::ConstantMatrix:
5287 case clang::Type::DependentSizedMatrix:
5288 break;
5289
5290 // We don't handle pack indexing yet
5291 case clang::Type::PackIndexing:
5292 break;
5293
5294 case clang::Type::HLSLAttributedResource:
5295 break;
5296 case clang::Type::HLSLInlineSpirv:
5297 break;
5298 }
5299 // We don't know hot to display this type...
5300 return lldb::eFormatBytes;
5301}
5302
5303static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl) {
5304 while (class_interface_decl) {
5305 if (class_interface_decl->ivar_size() > 0)
5306 return true;
5307
5308 class_interface_decl = class_interface_decl->getSuperClass();
5309 }
5310 return false;
5311}
5312
5313static std::optional<SymbolFile::ArrayInfo>
5314GetDynamicArrayInfo(TypeSystemClang &ast, SymbolFile *sym_file,
5315 clang::QualType qual_type,
5316 const ExecutionContext *exe_ctx) {
5317 if (qual_type->isIncompleteArrayType())
5318 if (std::optional<ClangASTMetadata> metadata =
5319 ast.GetMetadata(object: qual_type.getTypePtr()))
5320 return sym_file->GetDynamicArrayInfoForUID(type_uid: metadata->GetUserID(),
5321 exe_ctx);
5322 return std::nullopt;
5323}
5324
5325llvm::Expected<uint32_t>
5326TypeSystemClang::GetNumChildren(lldb::opaque_compiler_type_t type,
5327 bool omit_empty_base_classes,
5328 const ExecutionContext *exe_ctx) {
5329 if (!type)
5330 return llvm::createStringError(Fmt: "invalid clang type");
5331
5332 uint32_t num_children = 0;
5333 clang::QualType qual_type(RemoveWrappingTypes(type: GetQualType(type)));
5334 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5335 switch (type_class) {
5336 case clang::Type::Builtin:
5337 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
5338 case clang::BuiltinType::ObjCId: // child is Class
5339 case clang::BuiltinType::ObjCClass: // child is Class
5340 num_children = 1;
5341 break;
5342
5343 default:
5344 break;
5345 }
5346 break;
5347
5348 case clang::Type::Complex:
5349 return 0;
5350 case clang::Type::Record:
5351 if (GetCompleteQualType(ast: &getASTContext(), qual_type)) {
5352 const clang::RecordType *record_type =
5353 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
5354 const clang::RecordDecl *record_decl = record_type->getDecl();
5355 assert(record_decl);
5356 const clang::CXXRecordDecl *cxx_record_decl =
5357 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
5358
5359 num_children +=
5360 GetNumBaseClasses(cxx_record_decl, omit_empty_base_classes);
5361 num_children += std::distance(first: record_decl->field_begin(),
5362 last: record_decl->field_end());
5363 } else
5364 return llvm::createStringError(
5365 S: "incomplete type \"" + GetDisplayTypeName(type).GetString() + "\"");
5366 break;
5367 case clang::Type::ObjCObject:
5368 case clang::Type::ObjCInterface:
5369 if (GetCompleteQualType(ast: &getASTContext(), qual_type)) {
5370 const clang::ObjCObjectType *objc_class_type =
5371 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
5372 assert(objc_class_type);
5373 if (objc_class_type) {
5374 clang::ObjCInterfaceDecl *class_interface_decl =
5375 objc_class_type->getInterface();
5376
5377 if (class_interface_decl) {
5378
5379 clang::ObjCInterfaceDecl *superclass_interface_decl =
5380 class_interface_decl->getSuperClass();
5381 if (superclass_interface_decl) {
5382 if (omit_empty_base_classes) {
5383 if (ObjCDeclHasIVars(class_interface_decl: superclass_interface_decl))
5384 ++num_children;
5385 } else
5386 ++num_children;
5387 }
5388
5389 num_children += class_interface_decl->ivar_size();
5390 }
5391 }
5392 }
5393 break;
5394
5395 case clang::Type::LValueReference:
5396 case clang::Type::RValueReference:
5397 case clang::Type::ObjCObjectPointer: {
5398 CompilerType pointee_clang_type(GetPointeeType(type));
5399
5400 uint32_t num_pointee_children = 0;
5401 if (pointee_clang_type.IsAggregateType()) {
5402 auto num_children_or_err =
5403 pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx);
5404 if (!num_children_or_err)
5405 return num_children_or_err;
5406 num_pointee_children = *num_children_or_err;
5407 }
5408 // If this type points to a simple type, then it has 1 child
5409 if (num_pointee_children == 0)
5410 num_children = 1;
5411 else
5412 num_children = num_pointee_children;
5413 } break;
5414
5415 case clang::Type::Vector:
5416 case clang::Type::ExtVector:
5417 num_children =
5418 llvm::cast<clang::VectorType>(Val: qual_type.getTypePtr())->getNumElements();
5419 break;
5420
5421 case clang::Type::ConstantArray:
5422 num_children = llvm::cast<clang::ConstantArrayType>(Val: qual_type.getTypePtr())
5423 ->getSize()
5424 .getLimitedValue();
5425 break;
5426 case clang::Type::IncompleteArray:
5427 if (auto array_info =
5428 GetDynamicArrayInfo(ast&: *this, sym_file: GetSymbolFile(), qual_type, exe_ctx))
5429 // FIXME: Only 1-dimensional arrays are supported.
5430 num_children = array_info->element_orders.size()
5431 ? array_info->element_orders.back().value_or(u: 0)
5432 : 0;
5433 break;
5434
5435 case clang::Type::Pointer: {
5436 const clang::PointerType *pointer_type =
5437 llvm::cast<clang::PointerType>(Val: qual_type.getTypePtr());
5438 clang::QualType pointee_type(pointer_type->getPointeeType());
5439 CompilerType pointee_clang_type(GetType(qt: pointee_type));
5440 uint32_t num_pointee_children = 0;
5441 if (pointee_clang_type.IsAggregateType()) {
5442 auto num_children_or_err =
5443 pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx);
5444 if (!num_children_or_err)
5445 return num_children_or_err;
5446 num_pointee_children = *num_children_or_err;
5447 }
5448 if (num_pointee_children == 0) {
5449 // We have a pointer to a pointee type that claims it has no children. We
5450 // will want to look at
5451 num_children = GetNumPointeeChildren(type: pointee_type);
5452 } else
5453 num_children = num_pointee_children;
5454 } break;
5455
5456 default:
5457 break;
5458 }
5459 return num_children;
5460}
5461
5462CompilerType TypeSystemClang::GetBuiltinTypeByName(ConstString name) {
5463 return GetBasicType(basic_type: GetBasicTypeEnumeration(name));
5464}
5465
5466lldb::BasicType
5467TypeSystemClang::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
5468 if (type) {
5469 clang::QualType qual_type(GetQualType(type));
5470 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5471 if (type_class == clang::Type::Builtin) {
5472 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
5473 case clang::BuiltinType::Void:
5474 return eBasicTypeVoid;
5475 case clang::BuiltinType::Bool:
5476 return eBasicTypeBool;
5477 case clang::BuiltinType::Char_S:
5478 return eBasicTypeSignedChar;
5479 case clang::BuiltinType::Char_U:
5480 return eBasicTypeUnsignedChar;
5481 case clang::BuiltinType::Char8:
5482 return eBasicTypeChar8;
5483 case clang::BuiltinType::Char16:
5484 return eBasicTypeChar16;
5485 case clang::BuiltinType::Char32:
5486 return eBasicTypeChar32;
5487 case clang::BuiltinType::UChar:
5488 return eBasicTypeUnsignedChar;
5489 case clang::BuiltinType::SChar:
5490 return eBasicTypeSignedChar;
5491 case clang::BuiltinType::WChar_S:
5492 return eBasicTypeSignedWChar;
5493 case clang::BuiltinType::WChar_U:
5494 return eBasicTypeUnsignedWChar;
5495 case clang::BuiltinType::Short:
5496 return eBasicTypeShort;
5497 case clang::BuiltinType::UShort:
5498 return eBasicTypeUnsignedShort;
5499 case clang::BuiltinType::Int:
5500 return eBasicTypeInt;
5501 case clang::BuiltinType::UInt:
5502 return eBasicTypeUnsignedInt;
5503 case clang::BuiltinType::Long:
5504 return eBasicTypeLong;
5505 case clang::BuiltinType::ULong:
5506 return eBasicTypeUnsignedLong;
5507 case clang::BuiltinType::LongLong:
5508 return eBasicTypeLongLong;
5509 case clang::BuiltinType::ULongLong:
5510 return eBasicTypeUnsignedLongLong;
5511 case clang::BuiltinType::Int128:
5512 return eBasicTypeInt128;
5513 case clang::BuiltinType::UInt128:
5514 return eBasicTypeUnsignedInt128;
5515
5516 case clang::BuiltinType::Half:
5517 return eBasicTypeHalf;
5518 case clang::BuiltinType::Float:
5519 return eBasicTypeFloat;
5520 case clang::BuiltinType::Double:
5521 return eBasicTypeDouble;
5522 case clang::BuiltinType::LongDouble:
5523 return eBasicTypeLongDouble;
5524
5525 case clang::BuiltinType::NullPtr:
5526 return eBasicTypeNullPtr;
5527 case clang::BuiltinType::ObjCId:
5528 return eBasicTypeObjCID;
5529 case clang::BuiltinType::ObjCClass:
5530 return eBasicTypeObjCClass;
5531 case clang::BuiltinType::ObjCSel:
5532 return eBasicTypeObjCSel;
5533 default:
5534 return eBasicTypeOther;
5535 }
5536 }
5537 }
5538 return eBasicTypeInvalid;
5539}
5540
5541void TypeSystemClang::ForEachEnumerator(
5542 lldb::opaque_compiler_type_t type,
5543 std::function<bool(const CompilerType &integer_type,
5544 ConstString name,
5545 const llvm::APSInt &value)> const &callback) {
5546 const clang::EnumType *enum_type =
5547 llvm::dyn_cast<clang::EnumType>(Val: GetCanonicalQualType(type));
5548 if (enum_type) {
5549 const clang::EnumDecl *enum_decl = enum_type->getDecl();
5550 if (enum_decl) {
5551 CompilerType integer_type = GetType(qt: enum_decl->getIntegerType());
5552
5553 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
5554 for (enum_pos = enum_decl->enumerator_begin(),
5555 enum_end_pos = enum_decl->enumerator_end();
5556 enum_pos != enum_end_pos; ++enum_pos) {
5557 ConstString name(enum_pos->getNameAsString().c_str());
5558 if (!callback(integer_type, name, enum_pos->getInitVal()))
5559 break;
5560 }
5561 }
5562 }
5563}
5564
5565#pragma mark Aggregate Types
5566
5567uint32_t TypeSystemClang::GetNumFields(lldb::opaque_compiler_type_t type) {
5568 if (!type)
5569 return 0;
5570
5571 uint32_t count = 0;
5572 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
5573 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5574 switch (type_class) {
5575 case clang::Type::Record:
5576 if (GetCompleteType(type)) {
5577 const clang::RecordType *record_type =
5578 llvm::dyn_cast<clang::RecordType>(Val: qual_type.getTypePtr());
5579 if (record_type) {
5580 clang::RecordDecl *record_decl = record_type->getDecl();
5581 if (record_decl) {
5582 count = std::distance(first: record_decl->field_begin(),
5583 last: record_decl->field_end());
5584 }
5585 }
5586 }
5587 break;
5588
5589 case clang::Type::ObjCObjectPointer: {
5590 const clang::ObjCObjectPointerType *objc_class_type =
5591 qual_type->castAs<clang::ObjCObjectPointerType>();
5592 const clang::ObjCInterfaceType *objc_interface_type =
5593 objc_class_type->getInterfaceType();
5594 if (objc_interface_type &&
5595 GetCompleteType(type: static_cast<lldb::opaque_compiler_type_t>(
5596 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
5597 clang::ObjCInterfaceDecl *class_interface_decl =
5598 objc_interface_type->getDecl();
5599 if (class_interface_decl) {
5600 count = class_interface_decl->ivar_size();
5601 }
5602 }
5603 break;
5604 }
5605
5606 case clang::Type::ObjCObject:
5607 case clang::Type::ObjCInterface:
5608 if (GetCompleteType(type)) {
5609 const clang::ObjCObjectType *objc_class_type =
5610 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
5611 if (objc_class_type) {
5612 clang::ObjCInterfaceDecl *class_interface_decl =
5613 objc_class_type->getInterface();
5614
5615 if (class_interface_decl)
5616 count = class_interface_decl->ivar_size();
5617 }
5618 }
5619 break;
5620
5621 default:
5622 break;
5623 }
5624 return count;
5625}
5626
5627static lldb::opaque_compiler_type_t
5628GetObjCFieldAtIndex(clang::ASTContext *ast,
5629 clang::ObjCInterfaceDecl *class_interface_decl, size_t idx,
5630 std::string &name, uint64_t *bit_offset_ptr,
5631 uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) {
5632 if (class_interface_decl) {
5633 if (idx < (class_interface_decl->ivar_size())) {
5634 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
5635 ivar_end = class_interface_decl->ivar_end();
5636 uint32_t ivar_idx = 0;
5637
5638 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end;
5639 ++ivar_pos, ++ivar_idx) {
5640 if (ivar_idx == idx) {
5641 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
5642
5643 clang::QualType ivar_qual_type(ivar_decl->getType());
5644
5645 name.assign(ivar_decl->getNameAsString());
5646
5647 if (bit_offset_ptr) {
5648 const clang::ASTRecordLayout &interface_layout =
5649 ast->getASTObjCInterfaceLayout(D: class_interface_decl);
5650 *bit_offset_ptr = interface_layout.getFieldOffset(FieldNo: ivar_idx);
5651 }
5652
5653 const bool is_bitfield = ivar_pos->isBitField();
5654
5655 if (bitfield_bit_size_ptr) {
5656 *bitfield_bit_size_ptr = 0;
5657
5658 if (is_bitfield && ast) {
5659 clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
5660 clang::Expr::EvalResult result;
5661 if (bitfield_bit_size_expr &&
5662 bitfield_bit_size_expr->EvaluateAsInt(Result&: result, Ctx: *ast)) {
5663 llvm::APSInt bitfield_apsint = result.Val.getInt();
5664 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
5665 }
5666 }
5667 }
5668 if (is_bitfield_ptr)
5669 *is_bitfield_ptr = is_bitfield;
5670
5671 return ivar_qual_type.getAsOpaquePtr();
5672 }
5673 }
5674 }
5675 }
5676 return nullptr;
5677}
5678
5679CompilerType TypeSystemClang::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
5680 size_t idx, std::string &name,
5681 uint64_t *bit_offset_ptr,
5682 uint32_t *bitfield_bit_size_ptr,
5683 bool *is_bitfield_ptr) {
5684 if (!type)
5685 return CompilerType();
5686
5687 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
5688 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5689 switch (type_class) {
5690 case clang::Type::Record:
5691 if (GetCompleteType(type)) {
5692 const clang::RecordType *record_type =
5693 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
5694 const clang::RecordDecl *record_decl = record_type->getDecl();
5695 uint32_t field_idx = 0;
5696 clang::RecordDecl::field_iterator field, field_end;
5697 for (field = record_decl->field_begin(),
5698 field_end = record_decl->field_end();
5699 field != field_end; ++field, ++field_idx) {
5700 if (idx == field_idx) {
5701 // Print the member type if requested
5702 // Print the member name and equal sign
5703 name.assign(field->getNameAsString());
5704
5705 // Figure out the type byte size (field_type_info.first) and
5706 // alignment (field_type_info.second) from the AST context.
5707 if (bit_offset_ptr) {
5708 const clang::ASTRecordLayout &record_layout =
5709 getASTContext().getASTRecordLayout(D: record_decl);
5710 *bit_offset_ptr = record_layout.getFieldOffset(FieldNo: field_idx);
5711 }
5712
5713 const bool is_bitfield = field->isBitField();
5714
5715 if (bitfield_bit_size_ptr) {
5716 *bitfield_bit_size_ptr = 0;
5717
5718 if (is_bitfield) {
5719 clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
5720 clang::Expr::EvalResult result;
5721 if (bitfield_bit_size_expr &&
5722 bitfield_bit_size_expr->EvaluateAsInt(Result&: result,
5723 Ctx: getASTContext())) {
5724 llvm::APSInt bitfield_apsint = result.Val.getInt();
5725 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
5726 }
5727 }
5728 }
5729 if (is_bitfield_ptr)
5730 *is_bitfield_ptr = is_bitfield;
5731
5732 return GetType(qt: field->getType());
5733 }
5734 }
5735 }
5736 break;
5737
5738 case clang::Type::ObjCObjectPointer: {
5739 const clang::ObjCObjectPointerType *objc_class_type =
5740 qual_type->castAs<clang::ObjCObjectPointerType>();
5741 const clang::ObjCInterfaceType *objc_interface_type =
5742 objc_class_type->getInterfaceType();
5743 if (objc_interface_type &&
5744 GetCompleteType(type: static_cast<lldb::opaque_compiler_type_t>(
5745 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
5746 clang::ObjCInterfaceDecl *class_interface_decl =
5747 objc_interface_type->getDecl();
5748 if (class_interface_decl) {
5749 return CompilerType(
5750 weak_from_this(),
5751 GetObjCFieldAtIndex(ast: &getASTContext(), class_interface_decl, idx,
5752 name, bit_offset_ptr, bitfield_bit_size_ptr,
5753 is_bitfield_ptr));
5754 }
5755 }
5756 break;
5757 }
5758
5759 case clang::Type::ObjCObject:
5760 case clang::Type::ObjCInterface:
5761 if (GetCompleteType(type)) {
5762 const clang::ObjCObjectType *objc_class_type =
5763 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
5764 assert(objc_class_type);
5765 if (objc_class_type) {
5766 clang::ObjCInterfaceDecl *class_interface_decl =
5767 objc_class_type->getInterface();
5768 return CompilerType(
5769 weak_from_this(),
5770 GetObjCFieldAtIndex(ast: &getASTContext(), class_interface_decl, idx,
5771 name, bit_offset_ptr, bitfield_bit_size_ptr,
5772 is_bitfield_ptr));
5773 }
5774 }
5775 break;
5776
5777 default:
5778 break;
5779 }
5780 return CompilerType();
5781}
5782
5783uint32_t
5784TypeSystemClang::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) {
5785 uint32_t count = 0;
5786 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5787 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5788 switch (type_class) {
5789 case clang::Type::Record:
5790 if (GetCompleteType(type)) {
5791 const clang::CXXRecordDecl *cxx_record_decl =
5792 qual_type->getAsCXXRecordDecl();
5793 if (cxx_record_decl)
5794 count = cxx_record_decl->getNumBases();
5795 }
5796 break;
5797
5798 case clang::Type::ObjCObjectPointer:
5799 count = GetPointeeType(type).GetNumDirectBaseClasses();
5800 break;
5801
5802 case clang::Type::ObjCObject:
5803 if (GetCompleteType(type)) {
5804 const clang::ObjCObjectType *objc_class_type =
5805 qual_type->getAsObjCQualifiedInterfaceType();
5806 if (objc_class_type) {
5807 clang::ObjCInterfaceDecl *class_interface_decl =
5808 objc_class_type->getInterface();
5809
5810 if (class_interface_decl && class_interface_decl->getSuperClass())
5811 count = 1;
5812 }
5813 }
5814 break;
5815 case clang::Type::ObjCInterface:
5816 if (GetCompleteType(type)) {
5817 const clang::ObjCInterfaceType *objc_interface_type =
5818 qual_type->getAs<clang::ObjCInterfaceType>();
5819 if (objc_interface_type) {
5820 clang::ObjCInterfaceDecl *class_interface_decl =
5821 objc_interface_type->getInterface();
5822
5823 if (class_interface_decl && class_interface_decl->getSuperClass())
5824 count = 1;
5825 }
5826 }
5827 break;
5828
5829 default:
5830 break;
5831 }
5832 return count;
5833}
5834
5835uint32_t
5836TypeSystemClang::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) {
5837 uint32_t count = 0;
5838 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5839 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5840 switch (type_class) {
5841 case clang::Type::Record:
5842 if (GetCompleteType(type)) {
5843 const clang::CXXRecordDecl *cxx_record_decl =
5844 qual_type->getAsCXXRecordDecl();
5845 if (cxx_record_decl)
5846 count = cxx_record_decl->getNumVBases();
5847 }
5848 break;
5849
5850 default:
5851 break;
5852 }
5853 return count;
5854}
5855
5856CompilerType TypeSystemClang::GetDirectBaseClassAtIndex(
5857 lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
5858 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5859 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5860 switch (type_class) {
5861 case clang::Type::Record:
5862 if (GetCompleteType(type)) {
5863 const clang::CXXRecordDecl *cxx_record_decl =
5864 qual_type->getAsCXXRecordDecl();
5865 if (cxx_record_decl) {
5866 uint32_t curr_idx = 0;
5867 clang::CXXRecordDecl::base_class_const_iterator base_class,
5868 base_class_end;
5869 for (base_class = cxx_record_decl->bases_begin(),
5870 base_class_end = cxx_record_decl->bases_end();
5871 base_class != base_class_end; ++base_class, ++curr_idx) {
5872 if (curr_idx == idx) {
5873 if (bit_offset_ptr) {
5874 const clang::ASTRecordLayout &record_layout =
5875 getASTContext().getASTRecordLayout(cxx_record_decl);
5876 const clang::CXXRecordDecl *base_class_decl =
5877 llvm::cast<clang::CXXRecordDecl>(
5878 Val: base_class->getType()
5879 ->castAs<clang::RecordType>()
5880 ->getDecl());
5881 if (base_class->isVirtual())
5882 *bit_offset_ptr =
5883 record_layout.getVBaseClassOffset(VBase: base_class_decl)
5884 .getQuantity() *
5885 8;
5886 else
5887 *bit_offset_ptr =
5888 record_layout.getBaseClassOffset(Base: base_class_decl)
5889 .getQuantity() *
5890 8;
5891 }
5892 return GetType(qt: base_class->getType());
5893 }
5894 }
5895 }
5896 }
5897 break;
5898
5899 case clang::Type::ObjCObjectPointer:
5900 return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr);
5901
5902 case clang::Type::ObjCObject:
5903 if (idx == 0 && GetCompleteType(type)) {
5904 const clang::ObjCObjectType *objc_class_type =
5905 qual_type->getAsObjCQualifiedInterfaceType();
5906 if (objc_class_type) {
5907 clang::ObjCInterfaceDecl *class_interface_decl =
5908 objc_class_type->getInterface();
5909
5910 if (class_interface_decl) {
5911 clang::ObjCInterfaceDecl *superclass_interface_decl =
5912 class_interface_decl->getSuperClass();
5913 if (superclass_interface_decl) {
5914 if (bit_offset_ptr)
5915 *bit_offset_ptr = 0;
5916 return GetType(qt: getASTContext().getObjCInterfaceType(
5917 Decl: superclass_interface_decl));
5918 }
5919 }
5920 }
5921 }
5922 break;
5923 case clang::Type::ObjCInterface:
5924 if (idx == 0 && GetCompleteType(type)) {
5925 const clang::ObjCObjectType *objc_interface_type =
5926 qual_type->getAs<clang::ObjCInterfaceType>();
5927 if (objc_interface_type) {
5928 clang::ObjCInterfaceDecl *class_interface_decl =
5929 objc_interface_type->getInterface();
5930
5931 if (class_interface_decl) {
5932 clang::ObjCInterfaceDecl *superclass_interface_decl =
5933 class_interface_decl->getSuperClass();
5934 if (superclass_interface_decl) {
5935 if (bit_offset_ptr)
5936 *bit_offset_ptr = 0;
5937 return GetType(qt: getASTContext().getObjCInterfaceType(
5938 Decl: superclass_interface_decl));
5939 }
5940 }
5941 }
5942 }
5943 break;
5944
5945 default:
5946 break;
5947 }
5948 return CompilerType();
5949}
5950
5951CompilerType TypeSystemClang::GetVirtualBaseClassAtIndex(
5952 lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
5953 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5954 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5955 switch (type_class) {
5956 case clang::Type::Record:
5957 if (GetCompleteType(type)) {
5958 const clang::CXXRecordDecl *cxx_record_decl =
5959 qual_type->getAsCXXRecordDecl();
5960 if (cxx_record_decl) {
5961 uint32_t curr_idx = 0;
5962 clang::CXXRecordDecl::base_class_const_iterator base_class,
5963 base_class_end;
5964 for (base_class = cxx_record_decl->vbases_begin(),
5965 base_class_end = cxx_record_decl->vbases_end();
5966 base_class != base_class_end; ++base_class, ++curr_idx) {
5967 if (curr_idx == idx) {
5968 if (bit_offset_ptr) {
5969 const clang::ASTRecordLayout &record_layout =
5970 getASTContext().getASTRecordLayout(cxx_record_decl);
5971 const clang::CXXRecordDecl *base_class_decl =
5972 llvm::cast<clang::CXXRecordDecl>(
5973 Val: base_class->getType()
5974 ->castAs<clang::RecordType>()
5975 ->getDecl());
5976 *bit_offset_ptr =
5977 record_layout.getVBaseClassOffset(VBase: base_class_decl)
5978 .getQuantity() *
5979 8;
5980 }
5981 return GetType(qt: base_class->getType());
5982 }
5983 }
5984 }
5985 }
5986 break;
5987
5988 default:
5989 break;
5990 }
5991 return CompilerType();
5992}
5993
5994CompilerDecl
5995TypeSystemClang::GetStaticFieldWithName(lldb::opaque_compiler_type_t type,
5996 llvm::StringRef name) {
5997 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
5998 switch (qual_type->getTypeClass()) {
5999 case clang::Type::Record: {
6000 if (!GetCompleteType(type))
6001 return CompilerDecl();
6002
6003 const clang::RecordType *record_type =
6004 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
6005 const clang::RecordDecl *record_decl = record_type->getDecl();
6006
6007 clang::DeclarationName decl_name(&getASTContext().Idents.get(Name: name));
6008 for (NamedDecl *decl : record_decl->lookup(decl_name)) {
6009 auto *var_decl = dyn_cast<clang::VarDecl>(decl);
6010 if (!var_decl || var_decl->getStorageClass() != clang::SC_Static)
6011 continue;
6012
6013 return CompilerDecl(this, var_decl);
6014 }
6015 break;
6016 }
6017
6018 default:
6019 break;
6020 }
6021 return CompilerDecl();
6022}
6023
6024// If a pointer to a pointee type (the clang_type arg) says that it has no
6025// children, then we either need to trust it, or override it and return a
6026// different result. For example, an "int *" has one child that is an integer,
6027// but a function pointer doesn't have any children. Likewise if a Record type
6028// claims it has no children, then there really is nothing to show.
6029uint32_t TypeSystemClang::GetNumPointeeChildren(clang::QualType type) {
6030 if (type.isNull())
6031 return 0;
6032
6033 clang::QualType qual_type = RemoveWrappingTypes(type: type.getCanonicalType());
6034 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6035 switch (type_class) {
6036 case clang::Type::Builtin:
6037 switch (llvm::cast<clang::BuiltinType>(Val&: qual_type)->getKind()) {
6038 case clang::BuiltinType::UnknownAny:
6039 case clang::BuiltinType::Void:
6040 case clang::BuiltinType::NullPtr:
6041 case clang::BuiltinType::OCLEvent:
6042 case clang::BuiltinType::OCLImage1dRO:
6043 case clang::BuiltinType::OCLImage1dWO:
6044 case clang::BuiltinType::OCLImage1dRW:
6045 case clang::BuiltinType::OCLImage1dArrayRO:
6046 case clang::BuiltinType::OCLImage1dArrayWO:
6047 case clang::BuiltinType::OCLImage1dArrayRW:
6048 case clang::BuiltinType::OCLImage1dBufferRO:
6049 case clang::BuiltinType::OCLImage1dBufferWO:
6050 case clang::BuiltinType::OCLImage1dBufferRW:
6051 case clang::BuiltinType::OCLImage2dRO:
6052 case clang::BuiltinType::OCLImage2dWO:
6053 case clang::BuiltinType::OCLImage2dRW:
6054 case clang::BuiltinType::OCLImage2dArrayRO:
6055 case clang::BuiltinType::OCLImage2dArrayWO:
6056 case clang::BuiltinType::OCLImage2dArrayRW:
6057 case clang::BuiltinType::OCLImage3dRO:
6058 case clang::BuiltinType::OCLImage3dWO:
6059 case clang::BuiltinType::OCLImage3dRW:
6060 case clang::BuiltinType::OCLSampler:
6061 case clang::BuiltinType::HLSLResource:
6062 return 0;
6063 case clang::BuiltinType::Bool:
6064 case clang::BuiltinType::Char_U:
6065 case clang::BuiltinType::UChar:
6066 case clang::BuiltinType::WChar_U:
6067 case clang::BuiltinType::Char16:
6068 case clang::BuiltinType::Char32:
6069 case clang::BuiltinType::UShort:
6070 case clang::BuiltinType::UInt:
6071 case clang::BuiltinType::ULong:
6072 case clang::BuiltinType::ULongLong:
6073 case clang::BuiltinType::UInt128:
6074 case clang::BuiltinType::Char_S:
6075 case clang::BuiltinType::SChar:
6076 case clang::BuiltinType::WChar_S:
6077 case clang::BuiltinType::Short:
6078 case clang::BuiltinType::Int:
6079 case clang::BuiltinType::Long:
6080 case clang::BuiltinType::LongLong:
6081 case clang::BuiltinType::Int128:
6082 case clang::BuiltinType::Float:
6083 case clang::BuiltinType::Double:
6084 case clang::BuiltinType::LongDouble:
6085 case clang::BuiltinType::Dependent:
6086 case clang::BuiltinType::Overload:
6087 case clang::BuiltinType::ObjCId:
6088 case clang::BuiltinType::ObjCClass:
6089 case clang::BuiltinType::ObjCSel:
6090 case clang::BuiltinType::BoundMember:
6091 case clang::BuiltinType::Half:
6092 case clang::BuiltinType::ARCUnbridgedCast:
6093 case clang::BuiltinType::PseudoObject:
6094 case clang::BuiltinType::BuiltinFn:
6095 case clang::BuiltinType::ArraySection:
6096 return 1;
6097 default:
6098 return 0;
6099 }
6100 break;
6101
6102 case clang::Type::Complex:
6103 return 1;
6104 case clang::Type::Pointer:
6105 return 1;
6106 case clang::Type::BlockPointer:
6107 return 0; // If block pointers don't have debug info, then no children for
6108 // them
6109 case clang::Type::LValueReference:
6110 return 1;
6111 case clang::Type::RValueReference:
6112 return 1;
6113 case clang::Type::MemberPointer:
6114 return 0;
6115 case clang::Type::ConstantArray:
6116 return 0;
6117 case clang::Type::IncompleteArray:
6118 return 0;
6119 case clang::Type::VariableArray:
6120 return 0;
6121 case clang::Type::DependentSizedArray:
6122 return 0;
6123 case clang::Type::DependentSizedExtVector:
6124 return 0;
6125 case clang::Type::Vector:
6126 return 0;
6127 case clang::Type::ExtVector:
6128 return 0;
6129 case clang::Type::FunctionProto:
6130 return 0; // When we function pointers, they have no children...
6131 case clang::Type::FunctionNoProto:
6132 return 0; // When we function pointers, they have no children...
6133 case clang::Type::UnresolvedUsing:
6134 return 0;
6135 case clang::Type::Record:
6136 return 0;
6137 case clang::Type::Enum:
6138 return 1;
6139 case clang::Type::TemplateTypeParm:
6140 return 1;
6141 case clang::Type::SubstTemplateTypeParm:
6142 return 1;
6143 case clang::Type::TemplateSpecialization:
6144 return 1;
6145 case clang::Type::InjectedClassName:
6146 return 0;
6147 case clang::Type::DependentName:
6148 return 1;
6149 case clang::Type::DependentTemplateSpecialization:
6150 return 1;
6151 case clang::Type::ObjCObject:
6152 return 0;
6153 case clang::Type::ObjCInterface:
6154 return 0;
6155 case clang::Type::ObjCObjectPointer:
6156 return 1;
6157 default:
6158 break;
6159 }
6160 return 0;
6161}
6162
6163llvm::Expected<CompilerType> TypeSystemClang::GetDereferencedType(
6164 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
6165 std::string &deref_name, uint32_t &deref_byte_size,
6166 int32_t &deref_byte_offset, ValueObject *valobj, uint64_t &language_flags) {
6167 bool type_valid = IsPointerOrReferenceType(type, pointee_type: nullptr) ||
6168 IsArrayType(type, element_type_ptr: nullptr, size: nullptr, is_incomplete: nullptr);
6169 if (!type_valid)
6170 return llvm::createStringError(Fmt: "not a pointer, reference or array type");
6171 uint32_t child_bitfield_bit_size = 0;
6172 uint32_t child_bitfield_bit_offset = 0;
6173 bool child_is_base_class;
6174 bool child_is_deref_of_parent;
6175 return GetChildCompilerTypeAtIndex(
6176 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,
6177 child_byte_offset&: deref_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
6178 child_is_base_class, child_is_deref_of_parent, valobj, language_flags);
6179}
6180
6181llvm::Expected<CompilerType> TypeSystemClang::GetChildCompilerTypeAtIndex(
6182 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
6183 bool transparent_pointers, bool omit_empty_base_classes,
6184 bool ignore_array_bounds, std::string &child_name,
6185 uint32_t &child_byte_size, int32_t &child_byte_offset,
6186 uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
6187 bool &child_is_base_class, bool &child_is_deref_of_parent,
6188 ValueObject *valobj, uint64_t &language_flags) {
6189 if (!type)
6190 return CompilerType();
6191
6192 auto get_exe_scope = [&exe_ctx]() {
6193 return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
6194 };
6195
6196 clang::QualType parent_qual_type(
6197 RemoveWrappingTypes(type: GetCanonicalQualType(type)));
6198 const clang::Type::TypeClass parent_type_class =
6199 parent_qual_type->getTypeClass();
6200 child_bitfield_bit_size = 0;
6201 child_bitfield_bit_offset = 0;
6202 child_is_base_class = false;
6203 language_flags = 0;
6204
6205 auto num_children_or_err =
6206 GetNumChildren(type, omit_empty_base_classes, exe_ctx);
6207 if (!num_children_or_err)
6208 return num_children_or_err.takeError();
6209
6210 const bool idx_is_valid = idx < *num_children_or_err;
6211 int32_t bit_offset;
6212 switch (parent_type_class) {
6213 case clang::Type::Builtin:
6214 if (idx_is_valid) {
6215 switch (llvm::cast<clang::BuiltinType>(Val&: parent_qual_type)->getKind()) {
6216 case clang::BuiltinType::ObjCId:
6217 case clang::BuiltinType::ObjCClass:
6218 child_name = "isa";
6219 child_byte_size =
6220 getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy) /
6221 CHAR_BIT;
6222 return GetType(qt: getASTContext().ObjCBuiltinClassTy);
6223
6224 default:
6225 break;
6226 }
6227 }
6228 break;
6229
6230 case clang::Type::Record:
6231 if (idx_is_valid && GetCompleteType(type)) {
6232 const clang::RecordType *record_type =
6233 llvm::cast<clang::RecordType>(Val: parent_qual_type.getTypePtr());
6234 const clang::RecordDecl *record_decl = record_type->getDecl();
6235 assert(record_decl);
6236 const clang::ASTRecordLayout &record_layout =
6237 getASTContext().getASTRecordLayout(D: record_decl);
6238 uint32_t child_idx = 0;
6239
6240 const clang::CXXRecordDecl *cxx_record_decl =
6241 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
6242 if (cxx_record_decl) {
6243 // We might have base classes to print out first
6244 clang::CXXRecordDecl::base_class_const_iterator base_class,
6245 base_class_end;
6246 for (base_class = cxx_record_decl->bases_begin(),
6247 base_class_end = cxx_record_decl->bases_end();
6248 base_class != base_class_end; ++base_class) {
6249 const clang::CXXRecordDecl *base_class_decl = nullptr;
6250
6251 // Skip empty base classes
6252 if (omit_empty_base_classes) {
6253 base_class_decl = llvm::cast<clang::CXXRecordDecl>(
6254 Val: base_class->getType()->getAs<clang::RecordType>()->getDecl());
6255 if (!TypeSystemClang::RecordHasFields(base_class_decl))
6256 continue;
6257 }
6258
6259 if (idx == child_idx) {
6260 if (base_class_decl == nullptr)
6261 base_class_decl = llvm::cast<clang::CXXRecordDecl>(
6262 Val: base_class->getType()->getAs<clang::RecordType>()->getDecl());
6263
6264 if (base_class->isVirtual()) {
6265 bool handled = false;
6266 if (valobj) {
6267 clang::VTableContextBase *vtable_ctx =
6268 getASTContext().getVTableContext();
6269 if (vtable_ctx)
6270 handled = GetVBaseBitOffset(vtable_ctx&: *vtable_ctx, valobj&: *valobj,
6271 record_layout, cxx_record_decl,
6272 base_class_decl, bit_offset);
6273 }
6274 if (!handled)
6275 bit_offset = record_layout.getVBaseClassOffset(VBase: base_class_decl)
6276 .getQuantity() *
6277 8;
6278 } else
6279 bit_offset = record_layout.getBaseClassOffset(Base: base_class_decl)
6280 .getQuantity() *
6281 8;
6282
6283 // Base classes should be a multiple of 8 bits in size
6284 child_byte_offset = bit_offset / 8;
6285 CompilerType base_class_clang_type = GetType(qt: base_class->getType());
6286 child_name = base_class_clang_type.GetTypeName().AsCString(value_if_empty: "");
6287 auto size_or_err =
6288 base_class_clang_type.GetBitSize(exe_scope: get_exe_scope());
6289 if (!size_or_err)
6290 return llvm::joinErrors(
6291 E1: llvm::createStringError(Fmt: "no size info for base class"),
6292 E2: size_or_err.takeError());
6293
6294 uint64_t base_class_clang_type_bit_size = *size_or_err;
6295
6296 // Base classes bit sizes should be a multiple of 8 bits in size
6297 assert(base_class_clang_type_bit_size % 8 == 0);
6298 child_byte_size = base_class_clang_type_bit_size / 8;
6299 child_is_base_class = true;
6300 return base_class_clang_type;
6301 }
6302 // We don't increment the child index in the for loop since we might
6303 // be skipping empty base classes
6304 ++child_idx;
6305 }
6306 }
6307 // Make sure index is in range...
6308 uint32_t field_idx = 0;
6309 clang::RecordDecl::field_iterator field, field_end;
6310 for (field = record_decl->field_begin(),
6311 field_end = record_decl->field_end();
6312 field != field_end; ++field, ++field_idx, ++child_idx) {
6313 if (idx == child_idx) {
6314 // Print the member type if requested
6315 // Print the member name and equal sign
6316 child_name.assign(field->getNameAsString());
6317
6318 // Figure out the type byte size (field_type_info.first) and
6319 // alignment (field_type_info.second) from the AST context.
6320 CompilerType field_clang_type = GetType(qt: field->getType());
6321 assert(field_idx < record_layout.getFieldCount());
6322 auto size_or_err = field_clang_type.GetByteSize(exe_scope: get_exe_scope());
6323 if (!size_or_err)
6324 return llvm::joinErrors(
6325 E1: llvm::createStringError(Fmt: "no size info for field"),
6326 E2: size_or_err.takeError());
6327
6328 child_byte_size = *size_or_err;
6329 const uint32_t child_bit_size = child_byte_size * 8;
6330
6331 // Figure out the field offset within the current struct/union/class
6332 // type
6333 bit_offset = record_layout.getFieldOffset(FieldNo: field_idx);
6334 if (FieldIsBitfield(field: *field, bitfield_bit_size&: child_bitfield_bit_size)) {
6335 child_bitfield_bit_offset = bit_offset % child_bit_size;
6336 const uint32_t child_bit_offset =
6337 bit_offset - child_bitfield_bit_offset;
6338 child_byte_offset = child_bit_offset / 8;
6339 } else {
6340 child_byte_offset = bit_offset / 8;
6341 }
6342
6343 return field_clang_type;
6344 }
6345 }
6346 }
6347 break;
6348
6349 case clang::Type::ObjCObject:
6350 case clang::Type::ObjCInterface:
6351 if (idx_is_valid && GetCompleteType(type)) {
6352 const clang::ObjCObjectType *objc_class_type =
6353 llvm::dyn_cast<clang::ObjCObjectType>(Val: parent_qual_type.getTypePtr());
6354 assert(objc_class_type);
6355 if (objc_class_type) {
6356 uint32_t child_idx = 0;
6357 clang::ObjCInterfaceDecl *class_interface_decl =
6358 objc_class_type->getInterface();
6359
6360 if (class_interface_decl) {
6361
6362 const clang::ASTRecordLayout &interface_layout =
6363 getASTContext().getASTObjCInterfaceLayout(D: class_interface_decl);
6364 clang::ObjCInterfaceDecl *superclass_interface_decl =
6365 class_interface_decl->getSuperClass();
6366 if (superclass_interface_decl) {
6367 if (omit_empty_base_classes) {
6368 CompilerType base_class_clang_type =
6369 GetType(qt: getASTContext().getObjCInterfaceType(
6370 Decl: superclass_interface_decl));
6371 if (llvm::expectedToStdOptional(
6372 E: base_class_clang_type.GetNumChildren(
6373 omit_empty_base_classes, exe_ctx))
6374 .value_or(u: 0) > 0) {
6375 if (idx == 0) {
6376 clang::QualType ivar_qual_type(
6377 getASTContext().getObjCInterfaceType(
6378 Decl: superclass_interface_decl));
6379
6380 child_name.assign(
6381 superclass_interface_decl->getNameAsString());
6382
6383 clang::TypeInfo ivar_type_info =
6384 getASTContext().getTypeInfo(T: ivar_qual_type.getTypePtr());
6385
6386 child_byte_size = ivar_type_info.Width / 8;
6387 child_byte_offset = 0;
6388 child_is_base_class = true;
6389
6390 return GetType(qt: ivar_qual_type);
6391 }
6392
6393 ++child_idx;
6394 }
6395 } else
6396 ++child_idx;
6397 }
6398
6399 const uint32_t superclass_idx = child_idx;
6400
6401 if (idx < (child_idx + class_interface_decl->ivar_size())) {
6402 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
6403 ivar_end = class_interface_decl->ivar_end();
6404
6405 for (ivar_pos = class_interface_decl->ivar_begin();
6406 ivar_pos != ivar_end; ++ivar_pos) {
6407 if (child_idx == idx) {
6408 clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
6409
6410 clang::QualType ivar_qual_type(ivar_decl->getType());
6411
6412 child_name.assign(ivar_decl->getNameAsString());
6413
6414 clang::TypeInfo ivar_type_info =
6415 getASTContext().getTypeInfo(T: ivar_qual_type.getTypePtr());
6416
6417 child_byte_size = ivar_type_info.Width / 8;
6418
6419 // Figure out the field offset within the current
6420 // struct/union/class type For ObjC objects, we can't trust the
6421 // bit offset we get from the Clang AST, since that doesn't
6422 // account for the space taken up by unbacked properties, or
6423 // from the changing size of base classes that are newer than
6424 // this class. So if we have a process around that we can ask
6425 // about this object, do so.
6426 child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
6427 Process *process = nullptr;
6428 if (exe_ctx)
6429 process = exe_ctx->GetProcessPtr();
6430 if (process) {
6431 ObjCLanguageRuntime *objc_runtime =
6432 ObjCLanguageRuntime::Get(process&: *process);
6433 if (objc_runtime != nullptr) {
6434 CompilerType parent_ast_type = GetType(qt: parent_qual_type);
6435 child_byte_offset = objc_runtime->GetByteOffsetForIvar(
6436 parent_qual_type&: parent_ast_type, ivar_name: ivar_decl->getNameAsString().c_str());
6437 }
6438 }
6439
6440 // Setting this to INT32_MAX to make sure we don't compute it
6441 // twice...
6442 bit_offset = INT32_MAX;
6443
6444 if (child_byte_offset ==
6445 static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET)) {
6446 bit_offset = interface_layout.getFieldOffset(FieldNo: child_idx -
6447 superclass_idx);
6448 child_byte_offset = bit_offset / 8;
6449 }
6450
6451 // Note, the ObjC Ivar Byte offset is just that, it doesn't
6452 // account for the bit offset of a bitfield within its
6453 // containing object. So regardless of where we get the byte
6454 // offset from, we still need to get the bit offset for
6455 // bitfields from the layout.
6456
6457 if (FieldIsBitfield(ivar_decl, child_bitfield_bit_size)) {
6458 if (bit_offset == INT32_MAX)
6459 bit_offset = interface_layout.getFieldOffset(
6460 FieldNo: child_idx - superclass_idx);
6461
6462 child_bitfield_bit_offset = bit_offset % 8;
6463 }
6464 return GetType(qt: ivar_qual_type);
6465 }
6466 ++child_idx;
6467 }
6468 }
6469 }
6470 }
6471 }
6472 break;
6473
6474 case clang::Type::ObjCObjectPointer:
6475 if (idx_is_valid) {
6476 CompilerType pointee_clang_type(GetPointeeType(type));
6477
6478 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6479 child_is_deref_of_parent = false;
6480 bool tmp_child_is_deref_of_parent = false;
6481 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6482 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6483 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6484 child_bitfield_bit_size, child_bitfield_bit_offset,
6485 child_is_base_class, child_is_deref_of_parent&: tmp_child_is_deref_of_parent, valobj,
6486 language_flags);
6487 } else {
6488 child_is_deref_of_parent = true;
6489 const char *parent_name =
6490 valobj ? valobj->GetName().GetCString() : nullptr;
6491 if (parent_name) {
6492 child_name.assign(n: 1, c: '*');
6493 child_name += parent_name;
6494 }
6495
6496 // We have a pointer to an simple type
6497 if (idx == 0 && pointee_clang_type.GetCompleteType()) {
6498 auto size_or_err = pointee_clang_type.GetByteSize(exe_scope: get_exe_scope());
6499 if (!size_or_err)
6500 return size_or_err.takeError();
6501 child_byte_size = *size_or_err;
6502 child_byte_offset = 0;
6503 return pointee_clang_type;
6504 }
6505 }
6506 }
6507 break;
6508
6509 case clang::Type::Vector:
6510 case clang::Type::ExtVector:
6511 if (idx_is_valid) {
6512 const clang::VectorType *array =
6513 llvm::cast<clang::VectorType>(Val: parent_qual_type.getTypePtr());
6514 if (array) {
6515 CompilerType element_type = GetType(qt: array->getElementType());
6516 if (element_type.GetCompleteType()) {
6517 char element_name[64];
6518 ::snprintf(s: element_name, maxlen: sizeof(element_name), format: "[%" PRIu64 "]",
6519 static_cast<uint64_t>(idx));
6520 child_name.assign(s: element_name);
6521 auto size_or_err = element_type.GetByteSize(exe_scope: get_exe_scope());
6522 if (!size_or_err)
6523 return size_or_err.takeError();
6524 child_byte_size = *size_or_err;
6525 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
6526 return element_type;
6527 }
6528 }
6529 }
6530 break;
6531
6532 case clang::Type::ConstantArray:
6533 case clang::Type::IncompleteArray:
6534 if (ignore_array_bounds || idx_is_valid) {
6535 const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
6536 if (array) {
6537 CompilerType element_type = GetType(qt: array->getElementType());
6538 if (element_type.GetCompleteType()) {
6539 child_name = std::string(llvm::formatv(Fmt: "[{0}]", Vals&: idx));
6540 auto size_or_err = element_type.GetByteSize(exe_scope: get_exe_scope());
6541 if (!size_or_err)
6542 return size_or_err.takeError();
6543 child_byte_size = *size_or_err;
6544 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
6545 return element_type;
6546 }
6547 }
6548 }
6549 break;
6550
6551 case clang::Type::Pointer: {
6552 CompilerType pointee_clang_type(GetPointeeType(type));
6553
6554 // Don't dereference "void *" pointers
6555 if (pointee_clang_type.IsVoidType())
6556 return CompilerType();
6557
6558 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6559 child_is_deref_of_parent = false;
6560 bool tmp_child_is_deref_of_parent = false;
6561 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6562 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6563 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6564 child_bitfield_bit_size, child_bitfield_bit_offset,
6565 child_is_base_class, child_is_deref_of_parent&: tmp_child_is_deref_of_parent, valobj,
6566 language_flags);
6567 } else {
6568 child_is_deref_of_parent = true;
6569
6570 const char *parent_name =
6571 valobj ? valobj->GetName().GetCString() : nullptr;
6572 if (parent_name) {
6573 child_name.assign(n: 1, c: '*');
6574 child_name += parent_name;
6575 }
6576
6577 // We have a pointer to an simple type
6578 if (idx == 0) {
6579 auto size_or_err = pointee_clang_type.GetByteSize(exe_scope: get_exe_scope());
6580 if (!size_or_err)
6581 return size_or_err.takeError();
6582 child_byte_size = *size_or_err;
6583 child_byte_offset = 0;
6584 return pointee_clang_type;
6585 }
6586 }
6587 break;
6588 }
6589
6590 case clang::Type::LValueReference:
6591 case clang::Type::RValueReference:
6592 if (idx_is_valid) {
6593 const clang::ReferenceType *reference_type =
6594 llvm::cast<clang::ReferenceType>(
6595 Val: RemoveWrappingTypes(type: GetQualType(type)).getTypePtr());
6596 CompilerType pointee_clang_type =
6597 GetType(qt: reference_type->getPointeeType());
6598 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6599 child_is_deref_of_parent = false;
6600 bool tmp_child_is_deref_of_parent = false;
6601 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6602 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6603 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6604 child_bitfield_bit_size, child_bitfield_bit_offset,
6605 child_is_base_class, child_is_deref_of_parent&: tmp_child_is_deref_of_parent, valobj,
6606 language_flags);
6607 } else {
6608 const char *parent_name =
6609 valobj ? valobj->GetName().GetCString() : nullptr;
6610 if (parent_name) {
6611 child_name.assign(n: 1, c: '&');
6612 child_name += parent_name;
6613 }
6614
6615 // We have a pointer to an simple type
6616 if (idx == 0) {
6617 auto size_or_err = pointee_clang_type.GetByteSize(exe_scope: get_exe_scope());
6618 if (!size_or_err)
6619 return size_or_err.takeError();
6620 child_byte_size = *size_or_err;
6621 child_byte_offset = 0;
6622 return pointee_clang_type;
6623 }
6624 }
6625 }
6626 break;
6627
6628 default:
6629 break;
6630 }
6631 return CompilerType();
6632}
6633
6634uint32_t TypeSystemClang::GetIndexForRecordBase(
6635 const clang::RecordDecl *record_decl,
6636 const clang::CXXBaseSpecifier *base_spec,
6637 bool omit_empty_base_classes) {
6638 uint32_t child_idx = 0;
6639
6640 const clang::CXXRecordDecl *cxx_record_decl =
6641 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
6642
6643 if (cxx_record_decl) {
6644 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
6645 for (base_class = cxx_record_decl->bases_begin(),
6646 base_class_end = cxx_record_decl->bases_end();
6647 base_class != base_class_end; ++base_class) {
6648 if (omit_empty_base_classes) {
6649 if (BaseSpecifierIsEmpty(b: base_class))
6650 continue;
6651 }
6652
6653 if (base_class == base_spec)
6654 return child_idx;
6655 ++child_idx;
6656 }
6657 }
6658
6659 return UINT32_MAX;
6660}
6661
6662uint32_t TypeSystemClang::GetIndexForRecordChild(
6663 const clang::RecordDecl *record_decl, clang::NamedDecl *canonical_decl,
6664 bool omit_empty_base_classes) {
6665 uint32_t child_idx = TypeSystemClang::GetNumBaseClasses(
6666 cxx_record_decl: llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl),
6667 omit_empty_base_classes);
6668
6669 clang::RecordDecl::field_iterator field, field_end;
6670 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
6671 field != field_end; ++field, ++child_idx) {
6672 if (field->getCanonicalDecl() == canonical_decl)
6673 return child_idx;
6674 }
6675
6676 return UINT32_MAX;
6677}
6678
6679// Look for a child member (doesn't include base classes, but it does include
6680// their members) in the type hierarchy. Returns an index path into
6681// "clang_type" on how to reach the appropriate member.
6682//
6683// class A
6684// {
6685// public:
6686// int m_a;
6687// int m_b;
6688// };
6689//
6690// class B
6691// {
6692// };
6693//
6694// class C :
6695// public B,
6696// public A
6697// {
6698// };
6699//
6700// If we have a clang type that describes "class C", and we wanted to looked
6701// "m_b" in it:
6702//
6703// With omit_empty_base_classes == false we would get an integer array back
6704// with: { 1, 1 } The first index 1 is the child index for "class A" within
6705// class C The second index 1 is the child index for "m_b" within class A
6706//
6707// With omit_empty_base_classes == true we would get an integer array back
6708// with: { 0, 1 } The first index 0 is the child index for "class A" within
6709// class C (since class B doesn't have any members it doesn't count) The second
6710// index 1 is the child index for "m_b" within class A
6711
6712size_t TypeSystemClang::GetIndexOfChildMemberWithName(
6713 lldb::opaque_compiler_type_t type, llvm::StringRef name,
6714 bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
6715 if (type && !name.empty()) {
6716 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
6717 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6718 switch (type_class) {
6719 case clang::Type::Record:
6720 if (GetCompleteType(type)) {
6721 const clang::RecordType *record_type =
6722 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
6723 const clang::RecordDecl *record_decl = record_type->getDecl();
6724
6725 assert(record_decl);
6726 uint32_t child_idx = 0;
6727
6728 const clang::CXXRecordDecl *cxx_record_decl =
6729 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
6730
6731 // Try and find a field that matches NAME
6732 clang::RecordDecl::field_iterator field, field_end;
6733 for (field = record_decl->field_begin(),
6734 field_end = record_decl->field_end();
6735 field != field_end; ++field, ++child_idx) {
6736 llvm::StringRef field_name = field->getName();
6737 if (field_name.empty()) {
6738 CompilerType field_type = GetType(qt: field->getType());
6739 std::vector<uint32_t> save_indices = child_indexes;
6740 child_indexes.push_back(
6741 x: child_idx + TypeSystemClang::GetNumBaseClasses(
6742 cxx_record_decl, omit_empty_base_classes));
6743 if (field_type.GetIndexOfChildMemberWithName(
6744 name, omit_empty_base_classes, child_indexes))
6745 return child_indexes.size();
6746 child_indexes = std::move(save_indices);
6747 } else if (field_name == name) {
6748 // We have to add on the number of base classes to this index!
6749 child_indexes.push_back(
6750 x: child_idx + TypeSystemClang::GetNumBaseClasses(
6751 cxx_record_decl, omit_empty_base_classes));
6752 return child_indexes.size();
6753 }
6754 }
6755
6756 if (cxx_record_decl) {
6757 const clang::RecordDecl *parent_record_decl = cxx_record_decl;
6758
6759 // Didn't find things easily, lets let clang do its thang...
6760 clang::IdentifierInfo &ident_ref = getASTContext().Idents.get(Name: name);
6761 clang::DeclarationName decl_name(&ident_ref);
6762
6763 clang::CXXBasePaths paths;
6764 if (cxx_record_decl->lookupInBases(
6765 [decl_name](const clang::CXXBaseSpecifier *specifier,
6766 clang::CXXBasePath &path) {
6767 CXXRecordDecl *record =
6768 specifier->getType()->getAsCXXRecordDecl();
6769 auto r = record->lookup(decl_name);
6770 path.Decls = r.begin();
6771 return !r.empty();
6772 },
6773 paths)) {
6774 clang::CXXBasePaths::const_paths_iterator path,
6775 path_end = paths.end();
6776 for (path = paths.begin(); path != path_end; ++path) {
6777 const size_t num_path_elements = path->size();
6778 for (size_t e = 0; e < num_path_elements; ++e) {
6779 clang::CXXBasePathElement elem = (*path)[e];
6780
6781 child_idx = GetIndexForRecordBase(record_decl: parent_record_decl, base_spec: elem.Base,
6782 omit_empty_base_classes);
6783 if (child_idx == UINT32_MAX) {
6784 child_indexes.clear();
6785 return 0;
6786 } else {
6787 child_indexes.push_back(x: child_idx);
6788 parent_record_decl = llvm::cast<clang::RecordDecl>(
6789 Val: elem.Base->getType()
6790 ->castAs<clang::RecordType>()
6791 ->getDecl());
6792 }
6793 }
6794 for (clang::DeclContext::lookup_iterator I = path->Decls, E;
6795 I != E; ++I) {
6796 child_idx = GetIndexForRecordChild(
6797 record_decl: parent_record_decl, canonical_decl: *I, omit_empty_base_classes);
6798 if (child_idx == UINT32_MAX) {
6799 child_indexes.clear();
6800 return 0;
6801 } else {
6802 child_indexes.push_back(x: child_idx);
6803 }
6804 }
6805 }
6806 return child_indexes.size();
6807 }
6808 }
6809 }
6810 break;
6811
6812 case clang::Type::ObjCObject:
6813 case clang::Type::ObjCInterface:
6814 if (GetCompleteType(type)) {
6815 llvm::StringRef name_sref(name);
6816 const clang::ObjCObjectType *objc_class_type =
6817 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
6818 assert(objc_class_type);
6819 if (objc_class_type) {
6820 uint32_t child_idx = 0;
6821 clang::ObjCInterfaceDecl *class_interface_decl =
6822 objc_class_type->getInterface();
6823
6824 if (class_interface_decl) {
6825 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
6826 ivar_end = class_interface_decl->ivar_end();
6827 clang::ObjCInterfaceDecl *superclass_interface_decl =
6828 class_interface_decl->getSuperClass();
6829
6830 for (ivar_pos = class_interface_decl->ivar_begin();
6831 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
6832 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
6833
6834 if (ivar_decl->getName() == name_sref) {
6835 if ((!omit_empty_base_classes && superclass_interface_decl) ||
6836 (omit_empty_base_classes &&
6837 ObjCDeclHasIVars(class_interface_decl: superclass_interface_decl)))
6838 ++child_idx;
6839
6840 child_indexes.push_back(x: child_idx);
6841 return child_indexes.size();
6842 }
6843 }
6844
6845 if (superclass_interface_decl) {
6846 // The super class index is always zero for ObjC classes, so we
6847 // push it onto the child indexes in case we find an ivar in our
6848 // superclass...
6849 child_indexes.push_back(x: 0);
6850
6851 CompilerType superclass_clang_type =
6852 GetType(qt: getASTContext().getObjCInterfaceType(
6853 Decl: superclass_interface_decl));
6854 if (superclass_clang_type.GetIndexOfChildMemberWithName(
6855 name, omit_empty_base_classes, child_indexes)) {
6856 // We did find an ivar in a superclass so just return the
6857 // results!
6858 return child_indexes.size();
6859 }
6860
6861 // We didn't find an ivar matching "name" in our superclass, pop
6862 // the superclass zero index that we pushed on above.
6863 child_indexes.pop_back();
6864 }
6865 }
6866 }
6867 }
6868 break;
6869
6870 case clang::Type::ObjCObjectPointer: {
6871 CompilerType objc_object_clang_type = GetType(
6872 qt: llvm::cast<clang::ObjCObjectPointerType>(Val: qual_type.getTypePtr())
6873 ->getPointeeType());
6874 return objc_object_clang_type.GetIndexOfChildMemberWithName(
6875 name, omit_empty_base_classes, child_indexes);
6876 } break;
6877
6878 case clang::Type::LValueReference:
6879 case clang::Type::RValueReference: {
6880 const clang::ReferenceType *reference_type =
6881 llvm::cast<clang::ReferenceType>(Val: qual_type.getTypePtr());
6882 clang::QualType pointee_type(reference_type->getPointeeType());
6883 CompilerType pointee_clang_type = GetType(qt: pointee_type);
6884
6885 if (pointee_clang_type.IsAggregateType()) {
6886 return pointee_clang_type.GetIndexOfChildMemberWithName(
6887 name, omit_empty_base_classes, child_indexes);
6888 }
6889 } break;
6890
6891 case clang::Type::Pointer: {
6892 CompilerType pointee_clang_type(GetPointeeType(type));
6893
6894 if (pointee_clang_type.IsAggregateType()) {
6895 return pointee_clang_type.GetIndexOfChildMemberWithName(
6896 name, omit_empty_base_classes, child_indexes);
6897 }
6898 } break;
6899
6900 default:
6901 break;
6902 }
6903 }
6904 return 0;
6905}
6906
6907// Get the index of the child of "clang_type" whose name matches. This function
6908// doesn't descend into the children, but only looks one level deep and name
6909// matches can include base class names.
6910
6911llvm::Expected<uint32_t>
6912TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
6913 llvm::StringRef name,
6914 bool omit_empty_base_classes) {
6915 if (type && !name.empty()) {
6916 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
6917
6918 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6919
6920 switch (type_class) {
6921 case clang::Type::Record:
6922 if (GetCompleteType(type)) {
6923 const clang::RecordType *record_type =
6924 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
6925 const clang::RecordDecl *record_decl = record_type->getDecl();
6926
6927 assert(record_decl);
6928 uint32_t child_idx = 0;
6929
6930 const clang::CXXRecordDecl *cxx_record_decl =
6931 llvm::dyn_cast<clang::CXXRecordDecl>(Val: record_decl);
6932
6933 if (cxx_record_decl) {
6934 clang::CXXRecordDecl::base_class_const_iterator base_class,
6935 base_class_end;
6936 for (base_class = cxx_record_decl->bases_begin(),
6937 base_class_end = cxx_record_decl->bases_end();
6938 base_class != base_class_end; ++base_class) {
6939 // Skip empty base classes
6940 clang::CXXRecordDecl *base_class_decl =
6941 llvm::cast<clang::CXXRecordDecl>(
6942 Val: base_class->getType()
6943 ->castAs<clang::RecordType>()
6944 ->getDecl());
6945 if (omit_empty_base_classes &&
6946 !TypeSystemClang::RecordHasFields(base_class_decl))
6947 continue;
6948
6949 CompilerType base_class_clang_type = GetType(qt: base_class->getType());
6950 std::string base_class_type_name(
6951 base_class_clang_type.GetTypeName().AsCString(value_if_empty: ""));
6952 if (base_class_type_name == name)
6953 return child_idx;
6954 ++child_idx;
6955 }
6956 }
6957
6958 // Try and find a field that matches NAME
6959 clang::RecordDecl::field_iterator field, field_end;
6960 for (field = record_decl->field_begin(),
6961 field_end = record_decl->field_end();
6962 field != field_end; ++field, ++child_idx) {
6963 if (field->getName() == name)
6964 return child_idx;
6965 }
6966 }
6967 break;
6968
6969 case clang::Type::ObjCObject:
6970 case clang::Type::ObjCInterface:
6971 if (GetCompleteType(type)) {
6972 const clang::ObjCObjectType *objc_class_type =
6973 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
6974 assert(objc_class_type);
6975 if (objc_class_type) {
6976 uint32_t child_idx = 0;
6977 clang::ObjCInterfaceDecl *class_interface_decl =
6978 objc_class_type->getInterface();
6979
6980 if (class_interface_decl) {
6981 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
6982 ivar_end = class_interface_decl->ivar_end();
6983 clang::ObjCInterfaceDecl *superclass_interface_decl =
6984 class_interface_decl->getSuperClass();
6985
6986 for (ivar_pos = class_interface_decl->ivar_begin();
6987 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
6988 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
6989
6990 if (ivar_decl->getName() == name) {
6991 if ((!omit_empty_base_classes && superclass_interface_decl) ||
6992 (omit_empty_base_classes &&
6993 ObjCDeclHasIVars(class_interface_decl: superclass_interface_decl)))
6994 ++child_idx;
6995
6996 return child_idx;
6997 }
6998 }
6999
7000 if (superclass_interface_decl) {
7001 if (superclass_interface_decl->getName() == name)
7002 return 0;
7003 }
7004 }
7005 }
7006 }
7007 break;
7008
7009 case clang::Type::ObjCObjectPointer: {
7010 CompilerType pointee_clang_type = GetType(
7011 qt: llvm::cast<clang::ObjCObjectPointerType>(Val: qual_type.getTypePtr())
7012 ->getPointeeType());
7013 return pointee_clang_type.GetIndexOfChildWithName(
7014 name, omit_empty_base_classes);
7015 } break;
7016
7017 case clang::Type::LValueReference:
7018 case clang::Type::RValueReference: {
7019 const clang::ReferenceType *reference_type =
7020 llvm::cast<clang::ReferenceType>(Val: qual_type.getTypePtr());
7021 CompilerType pointee_type = GetType(qt: reference_type->getPointeeType());
7022
7023 if (pointee_type.IsAggregateType()) {
7024 return pointee_type.GetIndexOfChildWithName(name,
7025 omit_empty_base_classes);
7026 }
7027 } break;
7028
7029 case clang::Type::Pointer: {
7030 const clang::PointerType *pointer_type =
7031 llvm::cast<clang::PointerType>(Val: qual_type.getTypePtr());
7032 CompilerType pointee_type = GetType(qt: pointer_type->getPointeeType());
7033
7034 if (pointee_type.IsAggregateType()) {
7035 return pointee_type.GetIndexOfChildWithName(name,
7036 omit_empty_base_classes);
7037 }
7038 } break;
7039
7040 default:
7041 break;
7042 }
7043 }
7044 return llvm::createStringError(Fmt: "Type has no child named '%s'",
7045 Vals: name.str().c_str());
7046}
7047
7048CompilerType
7049TypeSystemClang::GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type,
7050 llvm::StringRef name) {
7051 if (!type || name.empty())
7052 return CompilerType();
7053
7054 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
7055 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7056
7057 switch (type_class) {
7058 case clang::Type::Record: {
7059 if (!GetCompleteType(type))
7060 return CompilerType();
7061 const clang::RecordType *record_type =
7062 llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
7063 const clang::RecordDecl *record_decl = record_type->getDecl();
7064
7065 clang::DeclarationName decl_name(&getASTContext().Idents.get(Name: name));
7066 for (NamedDecl *decl : record_decl->lookup(decl_name)) {
7067 if (auto *tag_decl = dyn_cast<clang::TagDecl>(decl))
7068 return GetType(getASTContext().getTagDeclType(tag_decl));
7069 if (auto *typedef_decl = dyn_cast<clang::TypedefNameDecl>(decl))
7070 return GetType(getASTContext().getTypedefType(typedef_decl));
7071 }
7072 break;
7073 }
7074 default:
7075 break;
7076 }
7077 return CompilerType();
7078}
7079
7080bool TypeSystemClang::IsTemplateType(lldb::opaque_compiler_type_t type) {
7081 if (!type)
7082 return false;
7083 CompilerType ct(weak_from_this(), type);
7084 const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr();
7085 if (auto *cxx_record_decl = dyn_cast<clang::TagType>(Val: clang_type))
7086 return isa<clang::ClassTemplateSpecializationDecl>(
7087 Val: cxx_record_decl->getDecl());
7088 return false;
7089}
7090
7091size_t
7092TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
7093 bool expand_pack) {
7094 if (!type)
7095 return 0;
7096
7097 clang::QualType qual_type = RemoveWrappingTypes(type: GetCanonicalQualType(type));
7098 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7099 switch (type_class) {
7100 case clang::Type::Record:
7101 if (GetCompleteType(type)) {
7102 const clang::CXXRecordDecl *cxx_record_decl =
7103 qual_type->getAsCXXRecordDecl();
7104 if (cxx_record_decl) {
7105 const clang::ClassTemplateSpecializationDecl *template_decl =
7106 llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
7107 Val: cxx_record_decl);
7108 if (template_decl) {
7109 const auto &template_arg_list = template_decl->getTemplateArgs();
7110 size_t num_args = template_arg_list.size();
7111 assert(num_args && "template specialization without any args");
7112 if (expand_pack && num_args) {
7113 const auto &pack = template_arg_list[num_args - 1];
7114 if (pack.getKind() == clang::TemplateArgument::Pack)
7115 num_args += pack.pack_size() - 1;
7116 }
7117 return num_args;
7118 }
7119 }
7120 }
7121 break;
7122
7123 default:
7124 break;
7125 }
7126
7127 return 0;
7128}
7129
7130const clang::ClassTemplateSpecializationDecl *
7131TypeSystemClang::GetAsTemplateSpecialization(
7132 lldb::opaque_compiler_type_t type) {
7133 if (!type)
7134 return nullptr;
7135
7136 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
7137 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7138 switch (type_class) {
7139 case clang::Type::Record: {
7140 if (! GetCompleteType(type))
7141 return nullptr;
7142 const clang::CXXRecordDecl *cxx_record_decl =
7143 qual_type->getAsCXXRecordDecl();
7144 if (!cxx_record_decl)
7145 return nullptr;
7146 return llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
7147 Val: cxx_record_decl);
7148 }
7149
7150 default:
7151 return nullptr;
7152 }
7153}
7154
7155const TemplateArgument *
7156GetNthTemplateArgument(const clang::ClassTemplateSpecializationDecl *decl,
7157 size_t idx, bool expand_pack) {
7158 const auto &args = decl->getTemplateArgs();
7159 const size_t args_size = args.size();
7160
7161 assert(args_size && "template specialization without any args");
7162 if (!args_size)
7163 return nullptr;
7164
7165 const size_t last_idx = args_size - 1;
7166
7167 // We're asked for a template argument that can't be a parameter pack, so
7168 // return it without worrying about 'expand_pack'.
7169 if (idx < last_idx)
7170 return &args[idx];
7171
7172 // We're asked for the last template argument but we don't want/need to
7173 // expand it.
7174 if (!expand_pack || args[last_idx].getKind() != clang::TemplateArgument::Pack)
7175 return idx >= args.size() ? nullptr : &args[idx];
7176
7177 // Index into the expanded pack.
7178 // Note that 'idx' counts from the beginning of all template arguments
7179 // (including the ones preceding the parameter pack).
7180 const auto &pack = args[last_idx];
7181 const size_t pack_idx = idx - last_idx;
7182 if (pack_idx >= pack.pack_size())
7183 return nullptr;
7184 return &pack.pack_elements()[pack_idx];
7185}
7186
7187lldb::TemplateArgumentKind
7188TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
7189 size_t arg_idx, bool expand_pack) {
7190 const clang::ClassTemplateSpecializationDecl *template_decl =
7191 GetAsTemplateSpecialization(type);
7192 if (!template_decl)
7193 return eTemplateArgumentKindNull;
7194
7195 const auto *arg = GetNthTemplateArgument(decl: template_decl, idx: arg_idx, expand_pack);
7196 if (!arg)
7197 return eTemplateArgumentKindNull;
7198
7199 switch (arg->getKind()) {
7200 case clang::TemplateArgument::Null:
7201 return eTemplateArgumentKindNull;
7202
7203 case clang::TemplateArgument::NullPtr:
7204 return eTemplateArgumentKindNullPtr;
7205
7206 case clang::TemplateArgument::Type:
7207 return eTemplateArgumentKindType;
7208
7209 case clang::TemplateArgument::Declaration:
7210 return eTemplateArgumentKindDeclaration;
7211
7212 case clang::TemplateArgument::Integral:
7213 return eTemplateArgumentKindIntegral;
7214
7215 case clang::TemplateArgument::Template:
7216 return eTemplateArgumentKindTemplate;
7217
7218 case clang::TemplateArgument::TemplateExpansion:
7219 return eTemplateArgumentKindTemplateExpansion;
7220
7221 case clang::TemplateArgument::Expression:
7222 return eTemplateArgumentKindExpression;
7223
7224 case clang::TemplateArgument::Pack:
7225 return eTemplateArgumentKindPack;
7226
7227 case clang::TemplateArgument::StructuralValue:
7228 return eTemplateArgumentKindStructuralValue;
7229 }
7230 llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind");
7231}
7232
7233CompilerType
7234TypeSystemClang::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
7235 size_t idx, bool expand_pack) {
7236 const clang::ClassTemplateSpecializationDecl *template_decl =
7237 GetAsTemplateSpecialization(type);
7238 if (!template_decl)
7239 return CompilerType();
7240
7241 const auto *arg = GetNthTemplateArgument(decl: template_decl, idx, expand_pack);
7242 if (!arg || arg->getKind() != clang::TemplateArgument::Type)
7243 return CompilerType();
7244
7245 return GetType(qt: arg->getAsType());
7246}
7247
7248std::optional<CompilerType::IntegralTemplateArgument>
7249TypeSystemClang::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
7250 size_t idx, bool expand_pack) {
7251 const clang::ClassTemplateSpecializationDecl *template_decl =
7252 GetAsTemplateSpecialization(type);
7253 if (!template_decl)
7254 return std::nullopt;
7255
7256 const auto *arg = GetNthTemplateArgument(decl: template_decl, idx, expand_pack);
7257 if (!arg)
7258 return std::nullopt;
7259
7260 switch (arg->getKind()) {
7261 case clang::TemplateArgument::Integral:
7262 return {{.value: arg->getAsIntegral(), .type: GetType(qt: arg->getIntegralType())}};
7263 case clang::TemplateArgument::StructuralValue: {
7264 clang::APValue value = arg->getAsStructuralValue();
7265 CompilerType type = GetType(qt: arg->getStructuralValueType());
7266
7267 if (value.isFloat())
7268 return {{.value: value.getFloat(), .type: type}};
7269
7270 if (value.isInt())
7271 return {{.value: value.getInt(), .type: type}};
7272
7273 return std::nullopt;
7274 }
7275 default:
7276 return std::nullopt;
7277 }
7278}
7279
7280CompilerType TypeSystemClang::GetTypeForFormatters(void *type) {
7281 if (type)
7282 return ClangUtil::RemoveFastQualifiers(ct: CompilerType(weak_from_this(), type));
7283 return CompilerType();
7284}
7285
7286clang::EnumDecl *TypeSystemClang::GetAsEnumDecl(const CompilerType &type) {
7287 const clang::EnumType *enutype =
7288 llvm::dyn_cast<clang::EnumType>(Val: ClangUtil::GetCanonicalQualType(ct: type));
7289 if (enutype)
7290 return enutype->getDecl();
7291 return nullptr;
7292}
7293
7294clang::RecordDecl *TypeSystemClang::GetAsRecordDecl(const CompilerType &type) {
7295 const clang::RecordType *record_type =
7296 llvm::dyn_cast<clang::RecordType>(Val: ClangUtil::GetCanonicalQualType(ct: type));
7297 if (record_type)
7298 return record_type->getDecl();
7299 return nullptr;
7300}
7301
7302clang::TagDecl *TypeSystemClang::GetAsTagDecl(const CompilerType &type) {
7303 return ClangUtil::GetAsTagDecl(type);
7304}
7305
7306clang::TypedefNameDecl *
7307TypeSystemClang::GetAsTypedefDecl(const CompilerType &type) {
7308 const clang::TypedefType *typedef_type =
7309 llvm::dyn_cast<clang::TypedefType>(Val: ClangUtil::GetQualType(ct: type));
7310 if (typedef_type)
7311 return typedef_type->getDecl();
7312 return nullptr;
7313}
7314
7315clang::CXXRecordDecl *
7316TypeSystemClang::GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type) {
7317 return GetCanonicalQualType(type)->getAsCXXRecordDecl();
7318}
7319
7320clang::ObjCInterfaceDecl *
7321TypeSystemClang::GetAsObjCInterfaceDecl(const CompilerType &type) {
7322 const clang::ObjCObjectType *objc_class_type =
7323 llvm::dyn_cast<clang::ObjCObjectType>(
7324 Val: ClangUtil::GetCanonicalQualType(ct: type));
7325 if (objc_class_type)
7326 return objc_class_type->getInterface();
7327 return nullptr;
7328}
7329
7330clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
7331 const CompilerType &type, llvm::StringRef name,
7332 const CompilerType &field_clang_type, AccessType access,
7333 uint32_t bitfield_bit_size) {
7334 if (!type.IsValid() || !field_clang_type.IsValid())
7335 return nullptr;
7336 auto ast = type.GetTypeSystem<TypeSystemClang>();
7337 if (!ast)
7338 return nullptr;
7339 clang::ASTContext &clang_ast = ast->getASTContext();
7340 clang::IdentifierInfo *ident = nullptr;
7341 if (!name.empty())
7342 ident = &clang_ast.Idents.get(Name: name);
7343
7344 clang::FieldDecl *field = nullptr;
7345
7346 clang::Expr *bit_width = nullptr;
7347 if (bitfield_bit_size != 0) {
7348 if (clang_ast.IntTy.isNull()) {
7349 LLDB_LOG(
7350 GetLog(LLDBLog::Expressions),
7351 "{0} failed: builtin ASTContext types have not been initialized");
7352 return nullptr;
7353 }
7354
7355 llvm::APInt bitfield_bit_size_apint(clang_ast.getTypeSize(clang_ast.IntTy),
7356 bitfield_bit_size);
7357 bit_width = new (clang_ast)
7358 clang::IntegerLiteral(clang_ast, bitfield_bit_size_apint,
7359 clang_ast.IntTy, clang::SourceLocation());
7360 bit_width = clang::ConstantExpr::Create(
7361 Context: clang_ast, E: bit_width, Result: APValue(llvm::APSInt(bitfield_bit_size_apint)));
7362 }
7363
7364 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
7365 if (record_decl) {
7366 field = clang::FieldDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
7367 field->setDeclContext(record_decl);
7368 field->setDeclName(ident);
7369 field->setType(ClangUtil::GetQualType(ct: field_clang_type));
7370 if (bit_width)
7371 field->setBitWidth(bit_width);
7372 SetMemberOwningModule(field, record_decl);
7373
7374 if (name.empty()) {
7375 // Determine whether this field corresponds to an anonymous struct or
7376 // union.
7377 if (const clang::TagType *TagT =
7378 field->getType()->getAs<clang::TagType>()) {
7379 if (clang::RecordDecl *Rec =
7380 llvm::dyn_cast<clang::RecordDecl>(Val: TagT->getDecl()))
7381 if (!Rec->getDeclName()) {
7382 Rec->setAnonymousStructOrUnion(true);
7383 field->setImplicit();
7384 }
7385 }
7386 }
7387
7388 if (field) {
7389 clang::AccessSpecifier access_specifier =
7390 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
7391 field->setAccess(access_specifier);
7392
7393 if (clang::CXXRecordDecl *cxx_record_decl =
7394 llvm::dyn_cast<CXXRecordDecl>(Val: record_decl)) {
7395 AddAccessSpecifierDecl(cxx_record_decl, ct&: ast->getASTContext(),
7396 previous_access: ast->GetCXXRecordDeclAccess(object: cxx_record_decl),
7397 access_specifier);
7398 ast->SetCXXRecordDeclAccess(object: cxx_record_decl, access: access_specifier);
7399 }
7400 record_decl->addDecl(field);
7401
7402 VerifyDecl(field);
7403 }
7404 } else {
7405 clang::ObjCInterfaceDecl *class_interface_decl =
7406 ast->GetAsObjCInterfaceDecl(type);
7407
7408 if (class_interface_decl) {
7409 const bool is_synthesized = false;
7410
7411 field_clang_type.GetCompleteType();
7412
7413 auto *ivar =
7414 clang::ObjCIvarDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
7415 ivar->setDeclContext(class_interface_decl);
7416 ivar->setDeclName(ident);
7417 ivar->setType(ClangUtil::GetQualType(ct: field_clang_type));
7418 ivar->setAccessControl(ConvertAccessTypeToObjCIvarAccessControl(access));
7419 if (bit_width)
7420 ivar->setBitWidth(bit_width);
7421 ivar->setSynthesize(is_synthesized);
7422 field = ivar;
7423 SetMemberOwningModule(field, class_interface_decl);
7424
7425 if (field) {
7426 class_interface_decl->addDecl(field);
7427
7428 VerifyDecl(field);
7429 }
7430 }
7431 }
7432 return field;
7433}
7434
7435void TypeSystemClang::BuildIndirectFields(const CompilerType &type) {
7436 if (!type)
7437 return;
7438
7439 auto ast = type.GetTypeSystem<TypeSystemClang>();
7440 if (!ast)
7441 return;
7442
7443 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
7444
7445 if (!record_decl)
7446 return;
7447
7448 typedef llvm::SmallVector<clang::IndirectFieldDecl *, 1> IndirectFieldVector;
7449
7450 IndirectFieldVector indirect_fields;
7451 clang::RecordDecl::field_iterator field_pos;
7452 clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end();
7453 clang::RecordDecl::field_iterator last_field_pos = field_end_pos;
7454 for (field_pos = record_decl->field_begin(); field_pos != field_end_pos;
7455 last_field_pos = field_pos++) {
7456 if (field_pos->isAnonymousStructOrUnion()) {
7457 clang::QualType field_qual_type = field_pos->getType();
7458
7459 const clang::RecordType *field_record_type =
7460 field_qual_type->getAs<clang::RecordType>();
7461
7462 if (!field_record_type)
7463 continue;
7464
7465 clang::RecordDecl *field_record_decl = field_record_type->getDecl();
7466
7467 if (!field_record_decl)
7468 continue;
7469
7470 for (clang::RecordDecl::decl_iterator
7471 di = field_record_decl->decls_begin(),
7472 de = field_record_decl->decls_end();
7473 di != de; ++di) {
7474 if (clang::FieldDecl *nested_field_decl =
7475 llvm::dyn_cast<clang::FieldDecl>(Val: *di)) {
7476 clang::NamedDecl **chain =
7477 new (ast->getASTContext()) clang::NamedDecl *[2];
7478 chain[0] = *field_pos;
7479 chain[1] = nested_field_decl;
7480 clang::IndirectFieldDecl *indirect_field =
7481 clang::IndirectFieldDecl::Create(
7482 C&: ast->getASTContext(), DC: record_decl, L: clang::SourceLocation(),
7483 Id: nested_field_decl->getIdentifier(),
7484 T: nested_field_decl->getType(), CH: {chain, 2});
7485 SetMemberOwningModule(indirect_field, record_decl);
7486
7487 indirect_field->setImplicit();
7488
7489 indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers(
7490 lhs: field_pos->getAccess(), rhs: nested_field_decl->getAccess()));
7491
7492 indirect_fields.push_back(Elt: indirect_field);
7493 } else if (clang::IndirectFieldDecl *nested_indirect_field_decl =
7494 llvm::dyn_cast<clang::IndirectFieldDecl>(Val: *di)) {
7495 size_t nested_chain_size =
7496 nested_indirect_field_decl->getChainingSize();
7497 clang::NamedDecl **chain = new (ast->getASTContext())
7498 clang::NamedDecl *[nested_chain_size + 1];
7499 chain[0] = *field_pos;
7500
7501 int chain_index = 1;
7502 for (clang::IndirectFieldDecl::chain_iterator
7503 nci = nested_indirect_field_decl->chain_begin(),
7504 nce = nested_indirect_field_decl->chain_end();
7505 nci < nce; ++nci) {
7506 chain[chain_index] = *nci;
7507 chain_index++;
7508 }
7509
7510 clang::IndirectFieldDecl *indirect_field =
7511 clang::IndirectFieldDecl::Create(
7512 C&: ast->getASTContext(), DC: record_decl, L: clang::SourceLocation(),
7513 Id: nested_indirect_field_decl->getIdentifier(),
7514 T: nested_indirect_field_decl->getType(),
7515 CH: {chain, nested_chain_size + 1});
7516 SetMemberOwningModule(indirect_field, record_decl);
7517
7518 indirect_field->setImplicit();
7519
7520 indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers(
7521 lhs: field_pos->getAccess(), rhs: nested_indirect_field_decl->getAccess()));
7522
7523 indirect_fields.push_back(Elt: indirect_field);
7524 }
7525 }
7526 }
7527 }
7528
7529 // Check the last field to see if it has an incomplete array type as its last
7530 // member and if it does, the tell the record decl about it
7531 if (last_field_pos != field_end_pos) {
7532 if (last_field_pos->getType()->isIncompleteArrayType())
7533 record_decl->hasFlexibleArrayMember();
7534 }
7535
7536 for (IndirectFieldVector::iterator ifi = indirect_fields.begin(),
7537 ife = indirect_fields.end();
7538 ifi < ife; ++ifi) {
7539 record_decl->addDecl(*ifi);
7540 }
7541}
7542
7543void TypeSystemClang::SetIsPacked(const CompilerType &type) {
7544 if (type) {
7545 auto ast = type.GetTypeSystem<TypeSystemClang>();
7546 if (ast) {
7547 clang::RecordDecl *record_decl = GetAsRecordDecl(type);
7548
7549 if (!record_decl)
7550 return;
7551
7552 record_decl->addAttr(
7553 clang::PackedAttr::CreateImplicit(ast->getASTContext()));
7554 }
7555 }
7556}
7557
7558clang::VarDecl *TypeSystemClang::AddVariableToRecordType(
7559 const CompilerType &type, llvm::StringRef name,
7560 const CompilerType &var_type, AccessType access) {
7561 if (!type.IsValid() || !var_type.IsValid())
7562 return nullptr;
7563
7564 auto ast = type.GetTypeSystem<TypeSystemClang>();
7565 if (!ast)
7566 return nullptr;
7567
7568 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
7569 if (!record_decl)
7570 return nullptr;
7571
7572 clang::VarDecl *var_decl = nullptr;
7573 clang::IdentifierInfo *ident = nullptr;
7574 if (!name.empty())
7575 ident = &ast->getASTContext().Idents.get(Name: name);
7576
7577 var_decl =
7578 clang::VarDecl::CreateDeserialized(C&: ast->getASTContext(), ID: GlobalDeclID());
7579 var_decl->setDeclContext(record_decl);
7580 var_decl->setDeclName(ident);
7581 var_decl->setType(ClangUtil::GetQualType(ct: var_type));
7582 var_decl->setStorageClass(clang::SC_Static);
7583 SetMemberOwningModule(var_decl, record_decl);
7584 if (!var_decl)
7585 return nullptr;
7586
7587 var_decl->setAccess(
7588 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access));
7589 record_decl->addDecl(var_decl);
7590
7591 VerifyDecl(var_decl);
7592
7593 return var_decl;
7594}
7595
7596void TypeSystemClang::SetIntegerInitializerForVariable(
7597 VarDecl *var, const llvm::APInt &init_value) {
7598 assert(!var->hasInit() && "variable already initialized");
7599
7600 clang::ASTContext &ast = var->getASTContext();
7601 QualType qt = var->getType();
7602 assert(qt->isIntegralOrEnumerationType() &&
7603 "only integer or enum types supported");
7604 // If the variable is an enum type, take the underlying integer type as
7605 // the type of the integer literal.
7606 if (const EnumType *enum_type = qt->getAs<EnumType>()) {
7607 const EnumDecl *enum_decl = enum_type->getDecl();
7608 qt = enum_decl->getIntegerType();
7609 }
7610 // Bools are handled separately because the clang AST printer handles bools
7611 // separately from other integral types.
7612 if (qt->isSpecificBuiltinType(K: BuiltinType::Bool)) {
7613 var->setInit(CXXBoolLiteralExpr::Create(
7614 C: ast, Val: !init_value.isZero(), Ty: qt.getUnqualifiedType(), Loc: SourceLocation()));
7615 } else {
7616 var->setInit(IntegerLiteral::Create(
7617 C: ast, V: init_value, type: qt.getUnqualifiedType(), l: SourceLocation()));
7618 }
7619}
7620
7621void TypeSystemClang::SetFloatingInitializerForVariable(
7622 clang::VarDecl *var, const llvm::APFloat &init_value) {
7623 assert(!var->hasInit() && "variable already initialized");
7624
7625 clang::ASTContext &ast = var->getASTContext();
7626 QualType qt = var->getType();
7627 assert(qt->isFloatingType() && "only floating point types supported");
7628 var->setInit(FloatingLiteral::Create(
7629 C: ast, V: init_value, isexact: true, Type: qt.getUnqualifiedType(), L: SourceLocation()));
7630}
7631
7632llvm::SmallVector<clang::ParmVarDecl *>
7633TypeSystemClang::CreateParameterDeclarations(
7634 clang::FunctionDecl *func, const clang::FunctionProtoType &prototype,
7635 const llvm::SmallVector<llvm::StringRef> &parameter_names) {
7636 assert(func);
7637 assert(parameter_names.empty() ||
7638 parameter_names.size() == prototype.getNumParams());
7639
7640 llvm::SmallVector<clang::ParmVarDecl *> params;
7641 for (unsigned param_index = 0; param_index < prototype.getNumParams();
7642 ++param_index) {
7643 llvm::StringRef name =
7644 !parameter_names.empty() ? parameter_names[param_index] : "";
7645
7646 auto *param =
7647 CreateParameterDeclaration(func, /*owning_module=*/{}, name.data(),
7648 GetType(qt: prototype.getParamType(i: param_index)),
7649 clang::SC_None, /*add_decl=*/false);
7650 assert(param);
7651
7652 params.push_back(Elt: param);
7653 }
7654
7655 return params;
7656}
7657
7658clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
7659 lldb::opaque_compiler_type_t type, llvm::StringRef name,
7660 const char *mangled_name, const CompilerType &method_clang_type,
7661 lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline,
7662 bool is_explicit, bool is_attr_used, bool is_artificial) {
7663 if (!type || !method_clang_type.IsValid() || name.empty())
7664 return nullptr;
7665
7666 clang::QualType record_qual_type(GetCanonicalQualType(type));
7667
7668 clang::CXXRecordDecl *cxx_record_decl =
7669 record_qual_type->getAsCXXRecordDecl();
7670
7671 if (cxx_record_decl == nullptr)
7672 return nullptr;
7673
7674 clang::QualType method_qual_type(ClangUtil::GetQualType(ct: method_clang_type));
7675
7676 clang::CXXMethodDecl *cxx_method_decl = nullptr;
7677
7678 clang::DeclarationName decl_name(&getASTContext().Idents.get(Name: name));
7679
7680 const clang::FunctionType *function_type =
7681 llvm::dyn_cast<clang::FunctionType>(Val: method_qual_type.getTypePtr());
7682
7683 if (function_type == nullptr)
7684 return nullptr;
7685
7686 const clang::FunctionProtoType *method_function_prototype(
7687 llvm::dyn_cast<clang::FunctionProtoType>(Val: function_type));
7688
7689 if (!method_function_prototype)
7690 return nullptr;
7691
7692 unsigned int num_params = method_function_prototype->getNumParams();
7693
7694 clang::CXXDestructorDecl *cxx_dtor_decl(nullptr);
7695 clang::CXXConstructorDecl *cxx_ctor_decl(nullptr);
7696
7697 if (is_artificial)
7698 return nullptr; // skip everything artificial
7699
7700 const clang::ExplicitSpecifier explicit_spec(
7701 nullptr /*expr*/, is_explicit ? clang::ExplicitSpecKind::ResolvedTrue
7702 : clang::ExplicitSpecKind::ResolvedFalse);
7703
7704 if (name.starts_with(Prefix: "~")) {
7705 cxx_dtor_decl = clang::CXXDestructorDecl::CreateDeserialized(
7706 C&: getASTContext(), ID: GlobalDeclID());
7707 cxx_dtor_decl->setDeclContext(cxx_record_decl);
7708 cxx_dtor_decl->setDeclName(
7709 getASTContext().DeclarationNames.getCXXDestructorName(
7710 Ty: getASTContext().getCanonicalType(T: record_qual_type)));
7711 cxx_dtor_decl->setType(method_qual_type);
7712 cxx_dtor_decl->setImplicit(is_artificial);
7713 cxx_dtor_decl->setInlineSpecified(is_inline);
7714 cxx_dtor_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
7715 cxx_method_decl = cxx_dtor_decl;
7716 } else if (decl_name == cxx_record_decl->getDeclName()) {
7717 cxx_ctor_decl = clang::CXXConstructorDecl::CreateDeserialized(
7718 C&: getASTContext(), ID: GlobalDeclID(), AllocKind: 0);
7719 cxx_ctor_decl->setDeclContext(cxx_record_decl);
7720 cxx_ctor_decl->setDeclName(
7721 getASTContext().DeclarationNames.getCXXConstructorName(
7722 Ty: getASTContext().getCanonicalType(T: record_qual_type)));
7723 cxx_ctor_decl->setType(method_qual_type);
7724 cxx_ctor_decl->setImplicit(is_artificial);
7725 cxx_ctor_decl->setInlineSpecified(is_inline);
7726 cxx_ctor_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
7727 cxx_ctor_decl->setNumCtorInitializers(0);
7728 cxx_ctor_decl->setExplicitSpecifier(explicit_spec);
7729 cxx_method_decl = cxx_ctor_decl;
7730 } else {
7731 clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
7732 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
7733
7734 if (IsOperator(name, op_kind)) {
7735 if (op_kind != clang::NUM_OVERLOADED_OPERATORS) {
7736 // Check the number of operator parameters. Sometimes we have seen bad
7737 // DWARF that doesn't correctly describe operators and if we try to
7738 // create a method and add it to the class, clang will assert and
7739 // crash, so we need to make sure things are acceptable.
7740 const bool is_method = true;
7741 if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
7742 is_method, op_kind, num_params))
7743 return nullptr;
7744 cxx_method_decl = clang::CXXMethodDecl::CreateDeserialized(
7745 C&: getASTContext(), ID: GlobalDeclID());
7746 cxx_method_decl->setDeclContext(cxx_record_decl);
7747 cxx_method_decl->setDeclName(
7748 getASTContext().DeclarationNames.getCXXOperatorName(Op: op_kind));
7749 cxx_method_decl->setType(method_qual_type);
7750 cxx_method_decl->setStorageClass(SC);
7751 cxx_method_decl->setInlineSpecified(is_inline);
7752 cxx_method_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
7753 } else if (num_params == 0) {
7754 // Conversion operators don't take params...
7755 auto *cxx_conversion_decl =
7756 clang::CXXConversionDecl::CreateDeserialized(C&: getASTContext(),
7757 ID: GlobalDeclID());
7758 cxx_conversion_decl->setDeclContext(cxx_record_decl);
7759 cxx_conversion_decl->setDeclName(
7760 getASTContext().DeclarationNames.getCXXConversionFunctionName(
7761 Ty: getASTContext().getCanonicalType(
7762 T: function_type->getReturnType())));
7763 cxx_conversion_decl->setType(method_qual_type);
7764 cxx_conversion_decl->setInlineSpecified(is_inline);
7765 cxx_conversion_decl->setExplicitSpecifier(explicit_spec);
7766 cxx_conversion_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
7767 cxx_method_decl = cxx_conversion_decl;
7768 }
7769 }
7770
7771 if (cxx_method_decl == nullptr) {
7772 cxx_method_decl = clang::CXXMethodDecl::CreateDeserialized(
7773 C&: getASTContext(), ID: GlobalDeclID());
7774 cxx_method_decl->setDeclContext(cxx_record_decl);
7775 cxx_method_decl->setDeclName(decl_name);
7776 cxx_method_decl->setType(method_qual_type);
7777 cxx_method_decl->setInlineSpecified(is_inline);
7778 cxx_method_decl->setStorageClass(SC);
7779 cxx_method_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
7780 }
7781 }
7782 SetMemberOwningModule(cxx_method_decl, cxx_record_decl);
7783
7784 clang::AccessSpecifier access_specifier =
7785 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
7786
7787 cxx_method_decl->setAccess(access_specifier);
7788 cxx_method_decl->setVirtualAsWritten(is_virtual);
7789
7790 if (is_attr_used)
7791 cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(getASTContext()));
7792
7793 if (mangled_name != nullptr) {
7794 cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
7795 getASTContext(), mangled_name, /*literal=*/false));
7796 }
7797
7798 // Parameters on member function declarations in DWARF generally don't
7799 // have names, so we omit them when creating the ParmVarDecls.
7800 cxx_method_decl->setParams(CreateParameterDeclarations(
7801 cxx_method_decl, *method_function_prototype, /*parameter_names=*/{}));
7802
7803 AddAccessSpecifierDecl(cxx_record_decl, ct&: getASTContext(),
7804 previous_access: GetCXXRecordDeclAccess(object: cxx_record_decl),
7805 access_specifier);
7806 SetCXXRecordDeclAccess(object: cxx_record_decl, access: access_specifier);
7807
7808 cxx_record_decl->addDecl(cxx_method_decl);
7809
7810 // Sometimes the debug info will mention a constructor (default/copy/move),
7811 // destructor, or assignment operator (copy/move) but there won't be any
7812 // version of this in the code. So we check if the function was artificially
7813 // generated and if it is trivial and this lets the compiler/backend know
7814 // that it can inline the IR for these when it needs to and we can avoid a
7815 // "missing function" error when running expressions.
7816
7817 if (is_artificial) {
7818 if (cxx_ctor_decl && ((cxx_ctor_decl->isDefaultConstructor() &&
7819 cxx_record_decl->hasTrivialDefaultConstructor()) ||
7820 (cxx_ctor_decl->isCopyConstructor() &&
7821 cxx_record_decl->hasTrivialCopyConstructor()) ||
7822 (cxx_ctor_decl->isMoveConstructor() &&
7823 cxx_record_decl->hasTrivialMoveConstructor()))) {
7824 cxx_ctor_decl->setDefaulted();
7825 cxx_ctor_decl->setTrivial(true);
7826 } else if (cxx_dtor_decl) {
7827 if (cxx_record_decl->hasTrivialDestructor()) {
7828 cxx_dtor_decl->setDefaulted();
7829 cxx_dtor_decl->setTrivial(true);
7830 }
7831 } else if ((cxx_method_decl->isCopyAssignmentOperator() &&
7832 cxx_record_decl->hasTrivialCopyAssignment()) ||
7833 (cxx_method_decl->isMoveAssignmentOperator() &&
7834 cxx_record_decl->hasTrivialMoveAssignment())) {
7835 cxx_method_decl->setDefaulted();
7836 cxx_method_decl->setTrivial(true);
7837 }
7838 }
7839
7840 VerifyDecl(cxx_method_decl);
7841
7842 return cxx_method_decl;
7843}
7844
7845void TypeSystemClang::AddMethodOverridesForCXXRecordType(
7846 lldb::opaque_compiler_type_t type) {
7847 if (auto *record = GetAsCXXRecordDecl(type))
7848 for (auto *method : record->methods())
7849 addOverridesForMethod(decl: method);
7850}
7851
7852#pragma mark C++ Base Classes
7853
7854std::unique_ptr<clang::CXXBaseSpecifier>
7855TypeSystemClang::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
7856 AccessType access, bool is_virtual,
7857 bool base_of_class) {
7858 if (!type)
7859 return nullptr;
7860
7861 return std::make_unique<clang::CXXBaseSpecifier>(
7862 args: clang::SourceRange(), args&: is_virtual, args&: base_of_class,
7863 args: TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access),
7864 args: getASTContext().getTrivialTypeSourceInfo(T: GetQualType(type)),
7865 args: clang::SourceLocation());
7866}
7867
7868bool TypeSystemClang::TransferBaseClasses(
7869 lldb::opaque_compiler_type_t type,
7870 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases) {
7871 if (!type)
7872 return false;
7873 clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type);
7874 if (!cxx_record_decl)
7875 return false;
7876 std::vector<clang::CXXBaseSpecifier *> raw_bases;
7877 raw_bases.reserve(n: bases.size());
7878
7879 // Clang will make a copy of them, so it's ok that we pass pointers that we're
7880 // about to destroy.
7881 for (auto &b : bases)
7882 raw_bases.push_back(x: b.get());
7883 cxx_record_decl->setBases(Bases: raw_bases.data(), NumBases: raw_bases.size());
7884 return true;
7885}
7886
7887bool TypeSystemClang::SetObjCSuperClass(
7888 const CompilerType &type, const CompilerType &superclass_clang_type) {
7889 auto ast = type.GetTypeSystem<TypeSystemClang>();
7890 if (!ast)
7891 return false;
7892 clang::ASTContext &clang_ast = ast->getASTContext();
7893
7894 if (type && superclass_clang_type.IsValid() &&
7895 superclass_clang_type.GetTypeSystem() == type.GetTypeSystem()) {
7896 clang::ObjCInterfaceDecl *class_interface_decl =
7897 GetAsObjCInterfaceDecl(type);
7898 clang::ObjCInterfaceDecl *super_interface_decl =
7899 GetAsObjCInterfaceDecl(type: superclass_clang_type);
7900 if (class_interface_decl && super_interface_decl) {
7901 class_interface_decl->setSuperClass(clang_ast.getTrivialTypeSourceInfo(
7902 T: clang_ast.getObjCInterfaceType(Decl: super_interface_decl)));
7903 return true;
7904 }
7905 }
7906 return false;
7907}
7908
7909bool TypeSystemClang::AddObjCClassProperty(
7910 const CompilerType &type, const char *property_name,
7911 const CompilerType &property_clang_type, clang::ObjCIvarDecl *ivar_decl,
7912 const char *property_setter_name, const char *property_getter_name,
7913 uint32_t property_attributes, ClangASTMetadata metadata) {
7914 if (!type || !property_clang_type.IsValid() || property_name == nullptr ||
7915 property_name[0] == '\0')
7916 return false;
7917 auto ast = type.GetTypeSystem<TypeSystemClang>();
7918 if (!ast)
7919 return false;
7920 clang::ASTContext &clang_ast = ast->getASTContext();
7921
7922 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
7923 if (!class_interface_decl)
7924 return false;
7925
7926 CompilerType property_clang_type_to_access;
7927
7928 if (property_clang_type.IsValid())
7929 property_clang_type_to_access = property_clang_type;
7930 else if (ivar_decl)
7931 property_clang_type_to_access = ast->GetType(qt: ivar_decl->getType());
7932
7933 if (!class_interface_decl || !property_clang_type_to_access.IsValid())
7934 return false;
7935
7936 clang::TypeSourceInfo *prop_type_source;
7937 if (ivar_decl)
7938 prop_type_source = clang_ast.getTrivialTypeSourceInfo(T: ivar_decl->getType());
7939 else
7940 prop_type_source = clang_ast.getTrivialTypeSourceInfo(
7941 T: ClangUtil::GetQualType(ct: property_clang_type));
7942
7943 clang::ObjCPropertyDecl *property_decl =
7944 clang::ObjCPropertyDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
7945 property_decl->setDeclContext(class_interface_decl);
7946 property_decl->setDeclName(&clang_ast.Idents.get(Name: property_name));
7947 property_decl->setType(T: ivar_decl
7948 ? ivar_decl->getType()
7949 : ClangUtil::GetQualType(ct: property_clang_type),
7950 TSI: prop_type_source);
7951 SetMemberOwningModule(property_decl, class_interface_decl);
7952
7953 if (!property_decl)
7954 return false;
7955
7956 ast->SetMetadata(property_decl, metadata);
7957
7958 class_interface_decl->addDecl(property_decl);
7959
7960 clang::Selector setter_sel, getter_sel;
7961
7962 if (property_setter_name) {
7963 std::string property_setter_no_colon(property_setter_name,
7964 strlen(s: property_setter_name) - 1);
7965 const clang::IdentifierInfo *setter_ident =
7966 &clang_ast.Idents.get(Name: property_setter_no_colon);
7967 setter_sel = clang_ast.Selectors.getSelector(NumArgs: 1, IIV: &setter_ident);
7968 } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) {
7969 std::string setter_sel_string("set");
7970 setter_sel_string.push_back(c: ::toupper(c: property_name[0]));
7971 setter_sel_string.append(s: &property_name[1]);
7972 const clang::IdentifierInfo *setter_ident =
7973 &clang_ast.Idents.get(Name: setter_sel_string);
7974 setter_sel = clang_ast.Selectors.getSelector(NumArgs: 1, IIV: &setter_ident);
7975 }
7976 property_decl->setSetterName(Sel: setter_sel);
7977 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_setter);
7978
7979 if (property_getter_name != nullptr) {
7980 const clang::IdentifierInfo *getter_ident =
7981 &clang_ast.Idents.get(Name: property_getter_name);
7982 getter_sel = clang_ast.Selectors.getSelector(NumArgs: 0, IIV: &getter_ident);
7983 } else {
7984 const clang::IdentifierInfo *getter_ident =
7985 &clang_ast.Idents.get(Name: property_name);
7986 getter_sel = clang_ast.Selectors.getSelector(NumArgs: 0, IIV: &getter_ident);
7987 }
7988 property_decl->setGetterName(Sel: getter_sel);
7989 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_getter);
7990
7991 if (ivar_decl)
7992 property_decl->setPropertyIvarDecl(ivar_decl);
7993
7994 if (property_attributes & DW_APPLE_PROPERTY_readonly)
7995 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readonly);
7996 if (property_attributes & DW_APPLE_PROPERTY_readwrite)
7997 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readwrite);
7998 if (property_attributes & DW_APPLE_PROPERTY_assign)
7999 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_assign);
8000 if (property_attributes & DW_APPLE_PROPERTY_retain)
8001 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_retain);
8002 if (property_attributes & DW_APPLE_PROPERTY_copy)
8003 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_copy);
8004 if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
8005 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_nonatomic);
8006 if (property_attributes & ObjCPropertyAttribute::kind_nullability)
8007 property_decl->setPropertyAttributes(
8008 ObjCPropertyAttribute::kind_nullability);
8009 if (property_attributes & ObjCPropertyAttribute::kind_null_resettable)
8010 property_decl->setPropertyAttributes(
8011 ObjCPropertyAttribute::kind_null_resettable);
8012 if (property_attributes & ObjCPropertyAttribute::kind_class)
8013 property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_class);
8014
8015 const bool isInstance =
8016 (property_attributes & ObjCPropertyAttribute::kind_class) == 0;
8017
8018 clang::ObjCMethodDecl *getter = nullptr;
8019 if (!getter_sel.isNull())
8020 getter = isInstance ? class_interface_decl->lookupInstanceMethod(Sel: getter_sel)
8021 : class_interface_decl->lookupClassMethod(Sel: getter_sel);
8022 if (!getter_sel.isNull() && !getter) {
8023 const bool isVariadic = false;
8024 const bool isPropertyAccessor = true;
8025 const bool isSynthesizedAccessorStub = false;
8026 const bool isImplicitlyDeclared = true;
8027 const bool isDefined = false;
8028 const clang::ObjCImplementationControl impControl =
8029 clang::ObjCImplementationControl::None;
8030 const bool HasRelatedResultType = false;
8031
8032 getter =
8033 clang::ObjCMethodDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
8034 getter->setDeclName(getter_sel);
8035 getter->setReturnType(ClangUtil::GetQualType(ct: property_clang_type_to_access));
8036 getter->setDeclContext(class_interface_decl);
8037 getter->setInstanceMethod(isInstance);
8038 getter->setVariadic(isVariadic);
8039 getter->setPropertyAccessor(isPropertyAccessor);
8040 getter->setSynthesizedAccessorStub(isSynthesizedAccessorStub);
8041 getter->setImplicit(isImplicitlyDeclared);
8042 getter->setDefined(isDefined);
8043 getter->setDeclImplementation(impControl);
8044 getter->setRelatedResultType(HasRelatedResultType);
8045 SetMemberOwningModule(getter, class_interface_decl);
8046
8047 if (getter) {
8048 ast->SetMetadata(getter, metadata);
8049
8050 getter->setMethodParams(C&: clang_ast, Params: llvm::ArrayRef<clang::ParmVarDecl *>(),
8051 SelLocs: llvm::ArrayRef<clang::SourceLocation>());
8052 class_interface_decl->addDecl(getter);
8053 }
8054 }
8055 if (getter) {
8056 getter->setPropertyAccessor(true);
8057 property_decl->setGetterMethodDecl(getter);
8058 }
8059
8060 clang::ObjCMethodDecl *setter = nullptr;
8061 setter = isInstance ? class_interface_decl->lookupInstanceMethod(Sel: setter_sel)
8062 : class_interface_decl->lookupClassMethod(Sel: setter_sel);
8063 if (!setter_sel.isNull() && !setter) {
8064 clang::QualType result_type = clang_ast.VoidTy;
8065 const bool isVariadic = false;
8066 const bool isPropertyAccessor = true;
8067 const bool isSynthesizedAccessorStub = false;
8068 const bool isImplicitlyDeclared = true;
8069 const bool isDefined = false;
8070 const clang::ObjCImplementationControl impControl =
8071 clang::ObjCImplementationControl::None;
8072 const bool HasRelatedResultType = false;
8073
8074 setter =
8075 clang::ObjCMethodDecl::CreateDeserialized(C&: clang_ast, ID: GlobalDeclID());
8076 setter->setDeclName(setter_sel);
8077 setter->setReturnType(result_type);
8078 setter->setDeclContext(class_interface_decl);
8079 setter->setInstanceMethod(isInstance);
8080 setter->setVariadic(isVariadic);
8081 setter->setPropertyAccessor(isPropertyAccessor);
8082 setter->setSynthesizedAccessorStub(isSynthesizedAccessorStub);
8083 setter->setImplicit(isImplicitlyDeclared);
8084 setter->setDefined(isDefined);
8085 setter->setDeclImplementation(impControl);
8086 setter->setRelatedResultType(HasRelatedResultType);
8087 SetMemberOwningModule(setter, class_interface_decl);
8088
8089 if (setter) {
8090 ast->SetMetadata(setter, metadata);
8091
8092 llvm::SmallVector<clang::ParmVarDecl *, 1> params;
8093 params.push_back(Elt: clang::ParmVarDecl::Create(
8094 clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(),
8095 nullptr, // anonymous
8096 ClangUtil::GetQualType(ct: property_clang_type_to_access), nullptr,
8097 clang::SC_Auto, nullptr));
8098
8099 setter->setMethodParams(C&: clang_ast,
8100 Params: llvm::ArrayRef<clang::ParmVarDecl *>(params),
8101 SelLocs: llvm::ArrayRef<clang::SourceLocation>());
8102
8103 class_interface_decl->addDecl(setter);
8104 }
8105 }
8106 if (setter) {
8107 setter->setPropertyAccessor(true);
8108 property_decl->setSetterMethodDecl(setter);
8109 }
8110
8111 return true;
8112}
8113
8114clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType(
8115 const CompilerType &type,
8116 const char *name, // the full symbol name as seen in the symbol table
8117 // (lldb::opaque_compiler_type_t type, "-[NString
8118 // stringWithCString:]")
8119 const CompilerType &method_clang_type, bool is_artificial, bool is_variadic,
8120 bool is_objc_direct_call) {
8121 if (!type || !method_clang_type.IsValid())
8122 return nullptr;
8123
8124 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8125
8126 if (class_interface_decl == nullptr)
8127 return nullptr;
8128 auto lldb_ast = type.GetTypeSystem<TypeSystemClang>();
8129 if (lldb_ast == nullptr)
8130 return nullptr;
8131 clang::ASTContext &ast = lldb_ast->getASTContext();
8132
8133 const char *selector_start = ::strchr(s: name, c: ' ');
8134 if (selector_start == nullptr)
8135 return nullptr;
8136
8137 selector_start++;
8138 llvm::SmallVector<const clang::IdentifierInfo *, 12> selector_idents;
8139
8140 size_t len = 0;
8141 const char *start;
8142
8143 unsigned num_selectors_with_args = 0;
8144 for (start = selector_start; start && *start != '\0' && *start != ']';
8145 start += len) {
8146 len = ::strcspn(s: start, reject: ":]");
8147 bool has_arg = (start[len] == ':');
8148 if (has_arg)
8149 ++num_selectors_with_args;
8150 selector_idents.push_back(Elt: &ast.Idents.get(Name: llvm::StringRef(start, len)));
8151 if (has_arg)
8152 len += 1;
8153 }
8154
8155 if (selector_idents.size() == 0)
8156 return nullptr;
8157
8158 clang::Selector method_selector = ast.Selectors.getSelector(
8159 NumArgs: num_selectors_with_args ? selector_idents.size() : 0,
8160 IIV: selector_idents.data());
8161
8162 clang::QualType method_qual_type(ClangUtil::GetQualType(ct: method_clang_type));
8163
8164 // Populate the method decl with parameter decls
8165 const clang::Type *method_type(method_qual_type.getTypePtr());
8166
8167 if (method_type == nullptr)
8168 return nullptr;
8169
8170 const clang::FunctionProtoType *method_function_prototype(
8171 llvm::dyn_cast<clang::FunctionProtoType>(Val: method_type));
8172
8173 if (!method_function_prototype)
8174 return nullptr;
8175
8176 const bool isInstance = (name[0] == '-');
8177 const bool isVariadic = is_variadic;
8178 const bool isPropertyAccessor = false;
8179 const bool isSynthesizedAccessorStub = false;
8180 /// Force this to true because we don't have source locations.
8181 const bool isImplicitlyDeclared = true;
8182 const bool isDefined = false;
8183 const clang::ObjCImplementationControl impControl =
8184 clang::ObjCImplementationControl::None;
8185 const bool HasRelatedResultType = false;
8186
8187 const unsigned num_args = method_function_prototype->getNumParams();
8188
8189 if (num_args != num_selectors_with_args)
8190 return nullptr; // some debug information is corrupt. We are not going to
8191 // deal with it.
8192
8193 auto *objc_method_decl =
8194 clang::ObjCMethodDecl::CreateDeserialized(C&: ast, ID: GlobalDeclID());
8195 objc_method_decl->setDeclName(method_selector);
8196 objc_method_decl->setReturnType(method_function_prototype->getReturnType());
8197 objc_method_decl->setDeclContext(
8198 lldb_ast->GetDeclContextForType(type: ClangUtil::GetQualType(ct: type)));
8199 objc_method_decl->setInstanceMethod(isInstance);
8200 objc_method_decl->setVariadic(isVariadic);
8201 objc_method_decl->setPropertyAccessor(isPropertyAccessor);
8202 objc_method_decl->setSynthesizedAccessorStub(isSynthesizedAccessorStub);
8203 objc_method_decl->setImplicit(isImplicitlyDeclared);
8204 objc_method_decl->setDefined(isDefined);
8205 objc_method_decl->setDeclImplementation(impControl);
8206 objc_method_decl->setRelatedResultType(HasRelatedResultType);
8207 SetMemberOwningModule(objc_method_decl, class_interface_decl);
8208
8209 if (objc_method_decl == nullptr)
8210 return nullptr;
8211
8212 if (num_args > 0) {
8213 llvm::SmallVector<clang::ParmVarDecl *, 12> params;
8214
8215 for (unsigned param_index = 0; param_index < num_args; ++param_index) {
8216 params.push_back(Elt: clang::ParmVarDecl::Create(
8217 ast, objc_method_decl, clang::SourceLocation(),
8218 clang::SourceLocation(),
8219 nullptr, // anonymous
8220 method_function_prototype->getParamType(i: param_index), nullptr,
8221 clang::SC_Auto, nullptr));
8222 }
8223
8224 objc_method_decl->setMethodParams(
8225 C&: ast, Params: llvm::ArrayRef<clang::ParmVarDecl *>(params),
8226 SelLocs: llvm::ArrayRef<clang::SourceLocation>());
8227 }
8228
8229 if (is_objc_direct_call) {
8230 // Add a the objc_direct attribute to the declaration we generate that
8231 // we generate a direct method call for this ObjCMethodDecl.
8232 objc_method_decl->addAttr(
8233 clang::ObjCDirectAttr::CreateImplicit(ast, SourceLocation()));
8234 // Usually Sema is creating implicit parameters (e.g., self) when it
8235 // parses the method. We don't have a parsing Sema when we build our own
8236 // AST here so we manually need to create these implicit parameters to
8237 // make the direct call code generation happy.
8238 objc_method_decl->createImplicitParams(Context&: ast, ID: class_interface_decl);
8239 }
8240
8241 class_interface_decl->addDecl(objc_method_decl);
8242
8243 VerifyDecl(objc_method_decl);
8244
8245 return objc_method_decl;
8246}
8247
8248bool TypeSystemClang::SetHasExternalStorage(lldb::opaque_compiler_type_t type,
8249 bool has_extern) {
8250 if (!type)
8251 return false;
8252
8253 clang::QualType qual_type(RemoveWrappingTypes(type: GetCanonicalQualType(type)));
8254
8255 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8256 switch (type_class) {
8257 case clang::Type::Record: {
8258 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
8259 if (cxx_record_decl) {
8260 cxx_record_decl->setHasExternalLexicalStorage(has_extern);
8261 cxx_record_decl->setHasExternalVisibleStorage(has_extern);
8262 return true;
8263 }
8264 } break;
8265
8266 case clang::Type::Enum: {
8267 clang::EnumDecl *enum_decl =
8268 llvm::cast<clang::EnumType>(Val&: qual_type)->getDecl();
8269 if (enum_decl) {
8270 enum_decl->setHasExternalLexicalStorage(has_extern);
8271 enum_decl->setHasExternalVisibleStorage(has_extern);
8272 return true;
8273 }
8274 } break;
8275
8276 case clang::Type::ObjCObject:
8277 case clang::Type::ObjCInterface: {
8278 const clang::ObjCObjectType *objc_class_type =
8279 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
8280 assert(objc_class_type);
8281 if (objc_class_type) {
8282 clang::ObjCInterfaceDecl *class_interface_decl =
8283 objc_class_type->getInterface();
8284
8285 if (class_interface_decl) {
8286 class_interface_decl->setHasExternalLexicalStorage(has_extern);
8287 class_interface_decl->setHasExternalVisibleStorage(has_extern);
8288 return true;
8289 }
8290 }
8291 } break;
8292
8293 default:
8294 break;
8295 }
8296 return false;
8297}
8298
8299#pragma mark TagDecl
8300
8301bool TypeSystemClang::StartTagDeclarationDefinition(const CompilerType &type) {
8302 clang::QualType qual_type(ClangUtil::GetQualType(ct: type));
8303 if (!qual_type.isNull()) {
8304 const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
8305 if (tag_type) {
8306 clang::TagDecl *tag_decl = tag_type->getDecl();
8307 if (tag_decl) {
8308 tag_decl->startDefinition();
8309 return true;
8310 }
8311 }
8312
8313 const clang::ObjCObjectType *object_type =
8314 qual_type->getAs<clang::ObjCObjectType>();
8315 if (object_type) {
8316 clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
8317 if (interface_decl) {
8318 interface_decl->startDefinition();
8319 return true;
8320 }
8321 }
8322 }
8323 return false;
8324}
8325
8326bool TypeSystemClang::CompleteTagDeclarationDefinition(
8327 const CompilerType &type) {
8328 clang::QualType qual_type(ClangUtil::GetQualType(ct: type));
8329 if (qual_type.isNull())
8330 return false;
8331
8332 auto lldb_ast = type.GetTypeSystem<TypeSystemClang>();
8333 if (lldb_ast == nullptr)
8334 return false;
8335
8336 // Make sure we use the same methodology as
8337 // TypeSystemClang::StartTagDeclarationDefinition() as to how we start/end
8338 // the definition.
8339 const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
8340 if (tag_type) {
8341 clang::TagDecl *tag_decl = tag_type->getDecl();
8342
8343 if (auto *cxx_record_decl = llvm::dyn_cast<CXXRecordDecl>(Val: tag_decl)) {
8344 // If we have a move constructor declared but no copy constructor we
8345 // need to explicitly mark it as deleted. Usually Sema would do this for
8346 // us in Sema::DeclareImplicitCopyConstructor but we don't have a Sema
8347 // when building an AST from debug information.
8348 // See also:
8349 // C++11 [class.copy]p7, p18:
8350 // If the class definition declares a move constructor or move assignment
8351 // operator, an implicitly declared copy constructor or copy assignment
8352 // operator is defined as deleted.
8353 if (cxx_record_decl->hasUserDeclaredMoveConstructor() ||
8354 cxx_record_decl->hasUserDeclaredMoveAssignment()) {
8355 if (cxx_record_decl->needsImplicitCopyConstructor())
8356 cxx_record_decl->setImplicitCopyConstructorIsDeleted();
8357 if (cxx_record_decl->needsImplicitCopyAssignment())
8358 cxx_record_decl->setImplicitCopyAssignmentIsDeleted();
8359 }
8360
8361 if (!cxx_record_decl->isCompleteDefinition())
8362 cxx_record_decl->completeDefinition();
8363 cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
8364 cxx_record_decl->setHasExternalLexicalStorage(false);
8365 cxx_record_decl->setHasExternalVisibleStorage(false);
8366 lldb_ast->SetCXXRecordDeclAccess(object: cxx_record_decl,
8367 access: clang::AccessSpecifier::AS_none);
8368 return true;
8369 }
8370 }
8371
8372 const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>();
8373
8374 if (!enutype)
8375 return false;
8376 clang::EnumDecl *enum_decl = enutype->getDecl();
8377
8378 if (enum_decl->isCompleteDefinition())
8379 return true;
8380
8381 QualType integer_type(enum_decl->getIntegerType());
8382 if (!integer_type.isNull()) {
8383 clang::ASTContext &ast = lldb_ast->getASTContext();
8384
8385 unsigned NumNegativeBits = 0;
8386 unsigned NumPositiveBits = 0;
8387 ast.computeEnumBits(EnumConstants: enum_decl->enumerators(), NumNegativeBits,
8388 NumPositiveBits);
8389
8390 clang::QualType BestPromotionType;
8391 clang::QualType BestType;
8392 ast.computeBestEnumTypes(/*IsPacked=*/false, NumNegativeBits,
8393 NumPositiveBits, BestType, BestPromotionType);
8394
8395 enum_decl->completeDefinition(NewType: enum_decl->getIntegerType(),
8396 PromotionType: BestPromotionType, NumPositiveBits,
8397 NumNegativeBits);
8398 }
8399 return true;
8400}
8401
8402clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
8403 const CompilerType &enum_type, const Declaration &decl, const char *name,
8404 const llvm::APSInt &value) {
8405
8406 if (!enum_type || ConstString(name).IsEmpty())
8407 return nullptr;
8408
8409 lldbassert(enum_type.GetTypeSystem().GetSharedPointer().get() ==
8410 static_cast<TypeSystem *>(this));
8411
8412 lldb::opaque_compiler_type_t enum_opaque_compiler_type =
8413 enum_type.GetOpaqueQualType();
8414
8415 if (!enum_opaque_compiler_type)
8416 return nullptr;
8417
8418 clang::QualType enum_qual_type(
8419 GetCanonicalQualType(type: enum_opaque_compiler_type));
8420
8421 const clang::Type *clang_type = enum_qual_type.getTypePtr();
8422
8423 if (!clang_type)
8424 return nullptr;
8425
8426 const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(Val: clang_type);
8427
8428 if (!enutype)
8429 return nullptr;
8430
8431 clang::EnumConstantDecl *enumerator_decl =
8432 clang::EnumConstantDecl::CreateDeserialized(C&: getASTContext(),
8433 ID: GlobalDeclID());
8434 enumerator_decl->setDeclContext(enutype->getDecl());
8435 if (name && name[0])
8436 enumerator_decl->setDeclName(&getASTContext().Idents.get(Name: name));
8437 enumerator_decl->setType(clang::QualType(enutype, 0));
8438 enumerator_decl->setInitVal(C: getASTContext(), V: value);
8439 SetMemberOwningModule(enumerator_decl, enutype->getDecl());
8440
8441 if (!enumerator_decl)
8442 return nullptr;
8443
8444 enutype->getDecl()->addDecl(enumerator_decl);
8445
8446 VerifyDecl(enumerator_decl);
8447 return enumerator_decl;
8448}
8449
8450clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
8451 const CompilerType &enum_type, const Declaration &decl, const char *name,
8452 uint64_t enum_value, uint32_t enum_value_bit_size) {
8453 assert(enum_type.IsEnumerationType());
8454 llvm::APSInt value(enum_value_bit_size,
8455 !enum_type.IsEnumerationIntegerTypeSigned());
8456 value = enum_value;
8457
8458 return AddEnumerationValueToEnumerationType(enum_type, decl, name, value);
8459}
8460
8461CompilerType TypeSystemClang::GetEnumerationIntegerType(CompilerType type) {
8462 clang::QualType qt(ClangUtil::GetQualType(ct: type));
8463 const clang::Type *clang_type = qt.getTypePtrOrNull();
8464 const auto *enum_type = llvm::dyn_cast_or_null<clang::EnumType>(Val: clang_type);
8465 if (!enum_type)
8466 return CompilerType();
8467
8468 return GetType(qt: enum_type->getDecl()->getIntegerType());
8469}
8470
8471CompilerType
8472TypeSystemClang::CreateMemberPointerType(const CompilerType &type,
8473 const CompilerType &pointee_type) {
8474 if (type && pointee_type.IsValid() &&
8475 type.GetTypeSystem() == pointee_type.GetTypeSystem()) {
8476 auto ast = type.GetTypeSystem<TypeSystemClang>();
8477 if (!ast)
8478 return CompilerType();
8479 return ast->GetType(qt: ast->getASTContext().getMemberPointerType(
8480 T: ClangUtil::GetQualType(ct: pointee_type),
8481 /*Qualifier=*/nullptr,
8482 Cls: ClangUtil::GetQualType(ct: type)->getAsCXXRecordDecl()));
8483 }
8484 return CompilerType();
8485}
8486
8487// Dumping types
8488#define DEPTH_INCREMENT 2
8489
8490#ifndef NDEBUG
8491LLVM_DUMP_METHOD void
8492TypeSystemClang::dump(lldb::opaque_compiler_type_t type) const {
8493 if (!type)
8494 return;
8495 clang::QualType qual_type(GetQualType(type));
8496 qual_type.dump();
8497}
8498#endif
8499
8500void TypeSystemClang::Dump(llvm::raw_ostream &output, llvm::StringRef filter) {
8501 auto consumer =
8502 clang::CreateASTDumper(OS&: output, FilterString: filter,
8503 /*DumpDecls=*/true,
8504 /*Deserialize=*/false,
8505 /*DumpLookups=*/false,
8506 /*DumpDeclTypes=*/false, Format: clang::ADOF_Default);
8507 assert(consumer);
8508 assert(m_ast_up);
8509 consumer->HandleTranslationUnit(Ctx&: *m_ast_up);
8510}
8511
8512void TypeSystemClang::DumpFromSymbolFile(Stream &s,
8513 llvm::StringRef symbol_name) {
8514 SymbolFile *symfile = GetSymbolFile();
8515
8516 if (!symfile)
8517 return;
8518
8519 lldb_private::TypeList type_list;
8520 symfile->GetTypes(sc_scope: nullptr, type_mask: eTypeClassAny, type_list);
8521 size_t ntypes = type_list.GetSize();
8522
8523 for (size_t i = 0; i < ntypes; ++i) {
8524 TypeSP type = type_list.GetTypeAtIndex(idx: i);
8525
8526 if (!symbol_name.empty())
8527 if (symbol_name != type->GetName().GetStringRef())
8528 continue;
8529
8530 s << type->GetName().AsCString() << "\n";
8531
8532 CompilerType full_type = type->GetFullCompilerType();
8533 if (clang::TagDecl *tag_decl = GetAsTagDecl(type: full_type)) {
8534 tag_decl->dump(s.AsRawOstream());
8535 continue;
8536 }
8537 if (clang::TypedefNameDecl *typedef_decl = GetAsTypedefDecl(type: full_type)) {
8538 typedef_decl->dump(s.AsRawOstream());
8539 continue;
8540 }
8541 if (auto *objc_obj = llvm::dyn_cast<clang::ObjCObjectType>(
8542 Val: ClangUtil::GetQualType(ct: full_type).getTypePtr())) {
8543 if (clang::ObjCInterfaceDecl *interface_decl = objc_obj->getInterface()) {
8544 interface_decl->dump(s.AsRawOstream());
8545 continue;
8546 }
8547 }
8548 GetCanonicalQualType(type: full_type.GetOpaqueQualType())
8549 .dump(OS&: s.AsRawOstream(), Context: getASTContext());
8550 }
8551}
8552
8553static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s,
8554 const DataExtractor &data, lldb::offset_t byte_offset,
8555 size_t byte_size, uint32_t bitfield_bit_offset,
8556 uint32_t bitfield_bit_size) {
8557 const clang::EnumType *enutype =
8558 llvm::cast<clang::EnumType>(Val: qual_type.getTypePtr());
8559 const clang::EnumDecl *enum_decl = enutype->getDecl();
8560 assert(enum_decl);
8561 lldb::offset_t offset = byte_offset;
8562 bool qual_type_is_signed = qual_type->isSignedIntegerOrEnumerationType();
8563 const uint64_t enum_svalue =
8564 qual_type_is_signed
8565 ? data.GetMaxS64Bitfield(offset_ptr: &offset, size: byte_size, bitfield_bit_size,
8566 bitfield_bit_offset)
8567 : data.GetMaxU64Bitfield(offset_ptr: &offset, size: byte_size, bitfield_bit_size,
8568 bitfield_bit_offset);
8569 bool can_be_bitfield = true;
8570 uint64_t covered_bits = 0;
8571 int num_enumerators = 0;
8572
8573 // Try to find an exact match for the value.
8574 // At the same time, we're applying a heuristic to determine whether we want
8575 // to print this enum as a bitfield. We're likely dealing with a bitfield if
8576 // every enumerator is either a one bit value or a superset of the previous
8577 // enumerators. Also 0 doesn't make sense when the enumerators are used as
8578 // flags.
8579 clang::EnumDecl::enumerator_range enumerators = enum_decl->enumerators();
8580 if (enumerators.empty())
8581 can_be_bitfield = false;
8582 else {
8583 for (auto *enumerator : enumerators) {
8584 llvm::APSInt init_val = enumerator->getInitVal();
8585 uint64_t val = qual_type_is_signed ? init_val.getSExtValue()
8586 : init_val.getZExtValue();
8587 if (qual_type_is_signed)
8588 val = llvm::SignExtend64(X: val, B: 8 * byte_size);
8589 if (llvm::popcount(Value: val) != 1 && (val & ~covered_bits) != 0)
8590 can_be_bitfield = false;
8591 covered_bits |= val;
8592 ++num_enumerators;
8593 if (val == enum_svalue) {
8594 // Found an exact match, that's all we need to do.
8595 s.PutCString(cstr: enumerator->getNameAsString());
8596 return true;
8597 }
8598 }
8599 }
8600
8601 // Unsigned values make more sense for flags.
8602 offset = byte_offset;
8603 const uint64_t enum_uvalue = data.GetMaxU64Bitfield(
8604 offset_ptr: &offset, size: byte_size, bitfield_bit_size, bitfield_bit_offset);
8605
8606 // No exact match, but we don't think this is a bitfield. Print the value as
8607 // decimal.
8608 if (!can_be_bitfield) {
8609 if (qual_type_is_signed)
8610 s.Printf(format: "%" PRIi64, enum_svalue);
8611 else
8612 s.Printf(format: "%" PRIu64, enum_uvalue);
8613 return true;
8614 }
8615
8616 if (!enum_uvalue) {
8617 // This is a bitfield enum, but the value is 0 so we know it won't match
8618 // with any of the enumerators.
8619 s.Printf(format: "0x%" PRIx64, enum_uvalue);
8620 return true;
8621 }
8622
8623 uint64_t remaining_value = enum_uvalue;
8624 std::vector<std::pair<uint64_t, llvm::StringRef>> values;
8625 values.reserve(n: num_enumerators);
8626 for (auto *enumerator : enum_decl->enumerators())
8627 if (auto val = enumerator->getInitVal().getZExtValue())
8628 values.emplace_back(val, enumerator->getName());
8629
8630 // Sort in reverse order of the number of the population count, so that in
8631 // `enum {A, B, ALL = A|B }` we visit ALL first. Use a stable sort so that
8632 // A | C where A is declared before C is displayed in this order.
8633 llvm::stable_sort(Range&: values, C: [](const auto &a, const auto &b) {
8634 return llvm::popcount(a.first) > llvm::popcount(b.first);
8635 });
8636
8637 for (const auto &val : values) {
8638 if ((remaining_value & val.first) != val.first)
8639 continue;
8640 remaining_value &= ~val.first;
8641 s.PutCString(cstr: val.second);
8642 if (remaining_value)
8643 s.PutCString(cstr: " | ");
8644 }
8645
8646 // If there is a remainder that is not covered by the value, print it as
8647 // hex.
8648 if (remaining_value)
8649 s.Printf(format: "0x%" PRIx64, remaining_value);
8650
8651 return true;
8652}
8653
8654bool TypeSystemClang::DumpTypeValue(
8655 lldb::opaque_compiler_type_t type, Stream &s, lldb::Format format,
8656 const lldb_private::DataExtractor &data, lldb::offset_t byte_offset,
8657 size_t byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
8658 ExecutionContextScope *exe_scope) {
8659 if (!type)
8660 return false;
8661 if (IsAggregateType(type)) {
8662 return false;
8663 } else {
8664 clang::QualType qual_type(GetQualType(type));
8665
8666 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8667
8668 if (type_class == clang::Type::Elaborated) {
8669 qual_type = llvm::cast<clang::ElaboratedType>(Val&: qual_type)->getNamedType();
8670 return DumpTypeValue(type: qual_type.getAsOpaquePtr(), s, format, data, byte_offset, byte_size,
8671 bitfield_bit_size, bitfield_bit_offset, exe_scope);
8672 }
8673
8674 switch (type_class) {
8675 case clang::Type::Typedef: {
8676 clang::QualType typedef_qual_type =
8677 llvm::cast<clang::TypedefType>(Val&: qual_type)
8678 ->getDecl()
8679 ->getUnderlyingType();
8680 CompilerType typedef_clang_type = GetType(qt: typedef_qual_type);
8681 if (format == eFormatDefault)
8682 format = typedef_clang_type.GetFormat();
8683 clang::TypeInfo typedef_type_info =
8684 getASTContext().getTypeInfo(T: typedef_qual_type);
8685 uint64_t typedef_byte_size = typedef_type_info.Width / 8;
8686
8687 return typedef_clang_type.DumpTypeValue(
8688 s: &s,
8689 format, // The format with which to display the element
8690 data, // Data buffer containing all bytes for this type
8691 data_offset: byte_offset, // Offset into "data" where to grab value from
8692 data_byte_size: typedef_byte_size, // Size of this type in bytes
8693 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't
8694 // treat as a bitfield
8695 bitfield_bit_offset, // Offset in bits of a bitfield value if
8696 // bitfield_bit_size != 0
8697 exe_scope);
8698 } break;
8699
8700 case clang::Type::Enum:
8701 // If our format is enum or default, show the enumeration value as its
8702 // enumeration string value, else just display it as requested.
8703 if ((format == eFormatEnum || format == eFormatDefault) &&
8704 GetCompleteType(type))
8705 return DumpEnumValue(qual_type, s, data, byte_offset, byte_size,
8706 bitfield_bit_offset, bitfield_bit_size);
8707 // format was not enum, just fall through and dump the value as
8708 // requested....
8709 [[fallthrough]];
8710
8711 default:
8712 // We are down to a scalar type that we just need to display.
8713 {
8714 uint32_t item_count = 1;
8715 // A few formats, we might need to modify our size and count for
8716 // depending
8717 // on how we are trying to display the value...
8718 switch (format) {
8719 default:
8720 case eFormatBoolean:
8721 case eFormatBinary:
8722 case eFormatComplex:
8723 case eFormatCString: // NULL terminated C strings
8724 case eFormatDecimal:
8725 case eFormatEnum:
8726 case eFormatHex:
8727 case eFormatHexUppercase:
8728 case eFormatFloat:
8729 case eFormatOctal:
8730 case eFormatOSType:
8731 case eFormatUnsigned:
8732 case eFormatPointer:
8733 case eFormatVectorOfChar:
8734 case eFormatVectorOfSInt8:
8735 case eFormatVectorOfUInt8:
8736 case eFormatVectorOfSInt16:
8737 case eFormatVectorOfUInt16:
8738 case eFormatVectorOfSInt32:
8739 case eFormatVectorOfUInt32:
8740 case eFormatVectorOfSInt64:
8741 case eFormatVectorOfUInt64:
8742 case eFormatVectorOfFloat32:
8743 case eFormatVectorOfFloat64:
8744 case eFormatVectorOfUInt128:
8745 break;
8746
8747 case eFormatChar:
8748 case eFormatCharPrintable:
8749 case eFormatCharArray:
8750 case eFormatBytes:
8751 case eFormatUnicode8:
8752 case eFormatBytesWithASCII:
8753 item_count = byte_size;
8754 byte_size = 1;
8755 break;
8756
8757 case eFormatUnicode16:
8758 item_count = byte_size / 2;
8759 byte_size = 2;
8760 break;
8761
8762 case eFormatUnicode32:
8763 item_count = byte_size / 4;
8764 byte_size = 4;
8765 break;
8766 }
8767 return DumpDataExtractor(DE: data, s: &s, offset: byte_offset, item_format: format, item_byte_size: byte_size,
8768 item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
8769 item_bit_size: bitfield_bit_size, item_bit_offset: bitfield_bit_offset,
8770 exe_scope);
8771 }
8772 break;
8773 }
8774 }
8775 return false;
8776}
8777
8778void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
8779 lldb::DescriptionLevel level) {
8780 StreamFile s(stdout, false);
8781 DumpTypeDescription(type, s, level);
8782
8783 CompilerType ct(weak_from_this(), type);
8784 const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr();
8785 if (std::optional<ClangASTMetadata> metadata = GetMetadata(object: clang_type)) {
8786 metadata->Dump(s: &s);
8787 }
8788}
8789
8790void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
8791 Stream &s,
8792 lldb::DescriptionLevel level) {
8793 if (type) {
8794 clang::QualType qual_type =
8795 RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef});
8796
8797 llvm::SmallVector<char, 1024> buf;
8798 llvm::raw_svector_ostream llvm_ostrm(buf);
8799
8800 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8801 switch (type_class) {
8802 case clang::Type::ObjCObject:
8803 case clang::Type::ObjCInterface: {
8804 GetCompleteType(type);
8805
8806 auto *objc_class_type =
8807 llvm::dyn_cast<clang::ObjCObjectType>(Val: qual_type.getTypePtr());
8808 assert(objc_class_type);
8809 if (!objc_class_type)
8810 break;
8811 clang::ObjCInterfaceDecl *class_interface_decl =
8812 objc_class_type->getInterface();
8813 if (!class_interface_decl)
8814 break;
8815 if (level == eDescriptionLevelVerbose)
8816 class_interface_decl->dump(llvm_ostrm);
8817 else
8818 class_interface_decl->print(llvm_ostrm,
8819 getASTContext().getPrintingPolicy(),
8820 s.GetIndentLevel());
8821 } break;
8822
8823 case clang::Type::Typedef: {
8824 auto *typedef_type = qual_type->getAs<clang::TypedefType>();
8825 if (!typedef_type)
8826 break;
8827 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
8828 if (level == eDescriptionLevelVerbose)
8829 typedef_decl->dump(llvm_ostrm);
8830 else {
8831 std::string clang_typedef_name(GetTypeNameForDecl(typedef_decl));
8832 if (!clang_typedef_name.empty()) {
8833 s.PutCString(cstr: "typedef ");
8834 s.PutCString(cstr: clang_typedef_name);
8835 }
8836 }
8837 } break;
8838
8839 case clang::Type::Record: {
8840 GetCompleteType(type);
8841
8842 auto *record_type = llvm::cast<clang::RecordType>(Val: qual_type.getTypePtr());
8843 const clang::RecordDecl *record_decl = record_type->getDecl();
8844 if (level == eDescriptionLevelVerbose)
8845 record_decl->dump(llvm_ostrm);
8846 else {
8847 record_decl->print(llvm_ostrm, getASTContext().getPrintingPolicy(),
8848 s.GetIndentLevel());
8849 }
8850 } break;
8851
8852 default: {
8853 if (auto *tag_type =
8854 llvm::dyn_cast<clang::TagType>(Val: qual_type.getTypePtr())) {
8855 if (clang::TagDecl *tag_decl = tag_type->getDecl()) {
8856 if (level == eDescriptionLevelVerbose)
8857 tag_decl->dump(llvm_ostrm);
8858 else
8859 tag_decl->print(llvm_ostrm, 0);
8860 }
8861 } else {
8862 if (level == eDescriptionLevelVerbose)
8863 qual_type->dump(OS&: llvm_ostrm, Context: getASTContext());
8864 else {
8865 std::string clang_type_name(qual_type.getAsString());
8866 if (!clang_type_name.empty())
8867 s.PutCString(cstr: clang_type_name);
8868 }
8869 }
8870 }
8871 }
8872
8873 if (buf.size() > 0) {
8874 s.Write(src: buf.data(), src_len: buf.size());
8875 }
8876}
8877}
8878
8879void TypeSystemClang::DumpTypeName(const CompilerType &type) {
8880 if (ClangUtil::IsClangType(ct: type)) {
8881 clang::QualType qual_type(
8882 ClangUtil::GetCanonicalQualType(ct: ClangUtil::RemoveFastQualifiers(ct: type)));
8883
8884 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8885 switch (type_class) {
8886 case clang::Type::Record: {
8887 const clang::CXXRecordDecl *cxx_record_decl =
8888 qual_type->getAsCXXRecordDecl();
8889 if (cxx_record_decl)
8890 printf("class %s", cxx_record_decl->getName().str().c_str());
8891 } break;
8892
8893 case clang::Type::Enum: {
8894 clang::EnumDecl *enum_decl =
8895 llvm::cast<clang::EnumType>(Val&: qual_type)->getDecl();
8896 if (enum_decl) {
8897 printf("enum %s", enum_decl->getName().str().c_str());
8898 }
8899 } break;
8900
8901 case clang::Type::ObjCObject:
8902 case clang::Type::ObjCInterface: {
8903 const clang::ObjCObjectType *objc_class_type =
8904 llvm::dyn_cast<clang::ObjCObjectType>(Val&: qual_type);
8905 if (objc_class_type) {
8906 clang::ObjCInterfaceDecl *class_interface_decl =
8907 objc_class_type->getInterface();
8908 // We currently can't complete objective C types through the newly
8909 // added ASTContext because it only supports TagDecl objects right
8910 // now...
8911 if (class_interface_decl)
8912 printf("@class %s", class_interface_decl->getName().str().c_str());
8913 }
8914 } break;
8915
8916 case clang::Type::Typedef:
8917 printf("typedef %s", llvm::cast<clang::TypedefType>(Val&: qual_type)
8918 ->getDecl()
8919 ->getName()
8920 .str()
8921 .c_str());
8922 break;
8923
8924 case clang::Type::Auto:
8925 printf(format: "auto ");
8926 return DumpTypeName(type: CompilerType(type.GetTypeSystem(),
8927 llvm::cast<clang::AutoType>(Val&: qual_type)
8928 ->getDeducedType()
8929 .getAsOpaquePtr()));
8930
8931 case clang::Type::Elaborated:
8932 printf(format: "elaborated ");
8933 return DumpTypeName(type: CompilerType(
8934 type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(Val&: qual_type)
8935 ->getNamedType()
8936 .getAsOpaquePtr()));
8937
8938 case clang::Type::Paren:
8939 printf(format: "paren ");
8940 return DumpTypeName(type: CompilerType(
8941 type.GetTypeSystem(),
8942 llvm::cast<clang::ParenType>(Val&: qual_type)->desugar().getAsOpaquePtr()));
8943
8944 default:
8945 printf(format: "TypeSystemClang::DumpTypeName() type_class = %u", type_class);
8946 break;
8947 }
8948 }
8949}
8950
8951clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl(
8952 clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
8953 lldb::AccessType access_type, const char *parent_name, int tag_decl_kind,
8954 const TypeSystemClang::TemplateParameterInfos &template_param_infos) {
8955 if (template_param_infos.IsValid()) {
8956 std::string template_basename(parent_name);
8957 // With -gsimple-template-names we may omit template parameters in the name.
8958 if (auto i = template_basename.find(c: '<'); i != std::string::npos)
8959 template_basename.erase(pos: i);
8960
8961 return CreateClassTemplateDecl(decl_ctx, owning_module, access_type,
8962 template_basename.c_str(), tag_decl_kind,
8963 template_param_infos);
8964 }
8965 return nullptr;
8966}
8967
8968void TypeSystemClang::CompleteTagDecl(clang::TagDecl *decl) {
8969 SymbolFile *sym_file = GetSymbolFile();
8970 if (sym_file) {
8971 CompilerType clang_type = GetTypeForDecl(decl);
8972 if (clang_type)
8973 sym_file->CompleteType(compiler_type&: clang_type);
8974 }
8975}
8976
8977void TypeSystemClang::CompleteObjCInterfaceDecl(
8978 clang::ObjCInterfaceDecl *decl) {
8979 SymbolFile *sym_file = GetSymbolFile();
8980 if (sym_file) {
8981 CompilerType clang_type = GetTypeForDecl(decl);
8982 if (clang_type)
8983 sym_file->CompleteType(compiler_type&: clang_type);
8984 }
8985}
8986
8987DWARFASTParser *TypeSystemClang::GetDWARFParser() {
8988 if (!m_dwarf_ast_parser_up)
8989 m_dwarf_ast_parser_up = std::make_unique<DWARFASTParserClang>(args&: *this);
8990 return m_dwarf_ast_parser_up.get();
8991}
8992
8993PDBASTParser *TypeSystemClang::GetPDBParser() {
8994 if (!m_pdb_ast_parser_up)
8995 m_pdb_ast_parser_up = std::make_unique<PDBASTParser>(args&: *this);
8996 return m_pdb_ast_parser_up.get();
8997}
8998
8999npdb::PdbAstBuilder *TypeSystemClang::GetNativePDBParser() {
9000 if (!m_native_pdb_ast_parser_up)
9001 m_native_pdb_ast_parser_up = std::make_unique<npdb::PdbAstBuilder>(args&: *this);
9002 return m_native_pdb_ast_parser_up.get();
9003}
9004
9005bool TypeSystemClang::LayoutRecordType(
9006 const clang::RecordDecl *record_decl, uint64_t &bit_size,
9007 uint64_t &alignment,
9008 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
9009 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
9010 &base_offsets,
9011 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
9012 &vbase_offsets) {
9013 lldb_private::ClangASTImporter *importer = nullptr;
9014 if (m_dwarf_ast_parser_up)
9015 importer = &m_dwarf_ast_parser_up->GetClangASTImporter();
9016 if (!importer && m_pdb_ast_parser_up)
9017 importer = &m_pdb_ast_parser_up->GetClangASTImporter();
9018 if (!importer && m_native_pdb_ast_parser_up)
9019 importer = &m_native_pdb_ast_parser_up->GetClangASTImporter();
9020 if (!importer)
9021 return false;
9022
9023 return importer->LayoutRecordType(record_decl, bit_size, alignment,
9024 field_offsets, base_offsets, vbase_offsets);
9025}
9026
9027// CompilerDecl override functions
9028
9029ConstString TypeSystemClang::DeclGetName(void *opaque_decl) {
9030 if (opaque_decl) {
9031 clang::NamedDecl *nd =
9032 llvm::dyn_cast<NamedDecl>(Val: (clang::Decl *)opaque_decl);
9033 if (nd != nullptr)
9034 return ConstString(GetTypeNameForDecl(named_decl: nd, /*qualified=*/false));
9035 }
9036 return ConstString();
9037}
9038
9039ConstString TypeSystemClang::DeclGetMangledName(void *opaque_decl) {
9040 clang::NamedDecl *nd = llvm::dyn_cast_or_null<clang::NamedDecl>(
9041 Val: static_cast<clang::Decl *>(opaque_decl));
9042
9043 if (!nd || llvm::isa<clang::ObjCMethodDecl>(Val: nd))
9044 return {};
9045
9046 clang::MangleContext *mc = getMangleContext();
9047 if (!mc || !mc->shouldMangleCXXName(D: nd))
9048 return {};
9049
9050 llvm::SmallVector<char, 1024> buf;
9051 llvm::raw_svector_ostream llvm_ostrm(buf);
9052 if (llvm::isa<clang::CXXConstructorDecl>(Val: nd)) {
9053 mc->mangleName(
9054 GD: clang::GlobalDecl(llvm::dyn_cast<clang::CXXConstructorDecl>(Val: nd),
9055 Ctor_Complete),
9056 llvm_ostrm);
9057 } else if (llvm::isa<clang::CXXDestructorDecl>(Val: nd)) {
9058 mc->mangleName(
9059 GD: clang::GlobalDecl(llvm::dyn_cast<clang::CXXDestructorDecl>(Val: nd),
9060 Dtor_Complete),
9061 llvm_ostrm);
9062 } else {
9063 mc->mangleName(GD: nd, llvm_ostrm);
9064 }
9065
9066 if (buf.size() > 0)
9067 return ConstString(buf.data(), buf.size());
9068
9069 return {};
9070}
9071
9072CompilerDeclContext TypeSystemClang::DeclGetDeclContext(void *opaque_decl) {
9073 if (opaque_decl)
9074 return CreateDeclContext(ctx: ((clang::Decl *)opaque_decl)->getDeclContext());
9075 return CompilerDeclContext();
9076}
9077
9078CompilerType TypeSystemClang::DeclGetFunctionReturnType(void *opaque_decl) {
9079 if (clang::FunctionDecl *func_decl =
9080 llvm::dyn_cast<clang::FunctionDecl>(Val: (clang::Decl *)opaque_decl))
9081 return GetType(qt: func_decl->getReturnType());
9082 if (clang::ObjCMethodDecl *objc_method =
9083 llvm::dyn_cast<clang::ObjCMethodDecl>(Val: (clang::Decl *)opaque_decl))
9084 return GetType(qt: objc_method->getReturnType());
9085 else
9086 return CompilerType();
9087}
9088
9089size_t TypeSystemClang::DeclGetFunctionNumArguments(void *opaque_decl) {
9090 if (clang::FunctionDecl *func_decl =
9091 llvm::dyn_cast<clang::FunctionDecl>(Val: (clang::Decl *)opaque_decl))
9092 return func_decl->param_size();
9093 if (clang::ObjCMethodDecl *objc_method =
9094 llvm::dyn_cast<clang::ObjCMethodDecl>(Val: (clang::Decl *)opaque_decl))
9095 return objc_method->param_size();
9096 else
9097 return 0;
9098}
9099
9100static CompilerContextKind GetCompilerKind(clang::Decl::Kind clang_kind,
9101 clang::DeclContext const *decl_ctx) {
9102 switch (clang_kind) {
9103 case Decl::TranslationUnit:
9104 return CompilerContextKind::TranslationUnit;
9105 case Decl::Namespace:
9106 return CompilerContextKind::Namespace;
9107 case Decl::Var:
9108 return CompilerContextKind::Variable;
9109 case Decl::Enum:
9110 return CompilerContextKind::Enum;
9111 case Decl::Typedef:
9112 return CompilerContextKind::Typedef;
9113 default:
9114 // Many other kinds have multiple values
9115 if (decl_ctx) {
9116 if (decl_ctx->isFunctionOrMethod())
9117 return CompilerContextKind::Function;
9118 if (decl_ctx->isRecord())
9119 return CompilerContextKind::ClassOrStruct | CompilerContextKind::Union;
9120 }
9121 break;
9122 }
9123 return CompilerContextKind::Any;
9124}
9125
9126static void
9127InsertCompilerContext(TypeSystemClang *ts, clang::DeclContext *decl_ctx,
9128 std::vector<lldb_private::CompilerContext> &context) {
9129 if (decl_ctx == nullptr)
9130 return;
9131 InsertCompilerContext(ts, decl_ctx: decl_ctx->getParent(), context);
9132 clang::Decl::Kind clang_kind = decl_ctx->getDeclKind();
9133 if (clang_kind == Decl::TranslationUnit)
9134 return; // Stop at the translation unit.
9135 const CompilerContextKind compiler_kind =
9136 GetCompilerKind(clang_kind, decl_ctx);
9137 ConstString decl_ctx_name = ts->DeclContextGetName(opaque_decl_ctx: decl_ctx);
9138 context.push_back(x: {compiler_kind, decl_ctx_name});
9139}
9140
9141std::vector<lldb_private::CompilerContext>
9142TypeSystemClang::DeclGetCompilerContext(void *opaque_decl) {
9143 std::vector<lldb_private::CompilerContext> context;
9144 ConstString decl_name = DeclGetName(opaque_decl);
9145 if (decl_name) {
9146 clang::Decl *decl = (clang::Decl *)opaque_decl;
9147 // Add the entire decl context first
9148 clang::DeclContext *decl_ctx = decl->getDeclContext();
9149 InsertCompilerContext(ts: this, decl_ctx, context);
9150 // Now add the decl information
9151 auto compiler_kind =
9152 GetCompilerKind(clang_kind: decl->getKind(), decl_ctx: dyn_cast<DeclContext>(Val: decl));
9153 context.push_back(x: {compiler_kind, decl_name});
9154 }
9155 return context;
9156}
9157
9158CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl,
9159 size_t idx) {
9160 if (clang::FunctionDecl *func_decl =
9161 llvm::dyn_cast<clang::FunctionDecl>(Val: (clang::Decl *)opaque_decl)) {
9162 if (idx < func_decl->param_size()) {
9163 ParmVarDecl *var_decl = func_decl->getParamDecl(i: idx);
9164 if (var_decl)
9165 return GetType(qt: var_decl->getOriginalType());
9166 }
9167 } else if (clang::ObjCMethodDecl *objc_method =
9168 llvm::dyn_cast<clang::ObjCMethodDecl>(
9169 Val: (clang::Decl *)opaque_decl)) {
9170 if (idx < objc_method->param_size())
9171 return GetType(qt: objc_method->parameters()[idx]->getOriginalType());
9172 }
9173 return CompilerType();
9174}
9175
9176Scalar TypeSystemClang::DeclGetConstantValue(void *opaque_decl) {
9177 clang::Decl *decl = static_cast<clang::Decl *>(opaque_decl);
9178 clang::VarDecl *var_decl = llvm::dyn_cast<clang::VarDecl>(Val: decl);
9179 if (!var_decl)
9180 return Scalar();
9181 clang::Expr *init_expr = var_decl->getInit();
9182 if (!init_expr)
9183 return Scalar();
9184 std::optional<llvm::APSInt> value =
9185 init_expr->getIntegerConstantExpr(Ctx: getASTContext());
9186 if (!value)
9187 return Scalar();
9188 return Scalar(*value);
9189}
9190
9191// CompilerDeclContext functions
9192
9193std::vector<CompilerDecl> TypeSystemClang::DeclContextFindDeclByName(
9194 void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) {
9195 std::vector<CompilerDecl> found_decls;
9196 SymbolFile *symbol_file = GetSymbolFile();
9197 if (opaque_decl_ctx && symbol_file) {
9198 DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
9199 std::set<DeclContext *> searched;
9200 std::multimap<DeclContext *, DeclContext *> search_queue;
9201
9202 for (clang::DeclContext *decl_context = root_decl_ctx;
9203 decl_context != nullptr && found_decls.empty();
9204 decl_context = decl_context->getParent()) {
9205 search_queue.insert(x: std::make_pair(x&: decl_context, y&: decl_context));
9206
9207 for (auto it = search_queue.find(x: decl_context); it != search_queue.end();
9208 it++) {
9209 if (!searched.insert(x: it->second).second)
9210 continue;
9211 symbol_file->ParseDeclsForContext(
9212 decl_ctx: CreateDeclContext(ctx: it->second));
9213
9214 for (clang::Decl *child : it->second->decls()) {
9215 if (clang::UsingDirectiveDecl *ud =
9216 llvm::dyn_cast<clang::UsingDirectiveDecl>(Val: child)) {
9217 if (ignore_using_decls)
9218 continue;
9219 clang::DeclContext *from = ud->getCommonAncestor();
9220 if (searched.find(ud->getNominatedNamespace()) == searched.end())
9221 search_queue.insert(
9222 std::make_pair(x&: from, y: ud->getNominatedNamespace()));
9223 } else if (clang::UsingDecl *ud =
9224 llvm::dyn_cast<clang::UsingDecl>(Val: child)) {
9225 if (ignore_using_decls)
9226 continue;
9227 for (clang::UsingShadowDecl *usd : ud->shadows()) {
9228 clang::Decl *target = usd->getTargetDecl();
9229 if (clang::NamedDecl *nd =
9230 llvm::dyn_cast<clang::NamedDecl>(target)) {
9231 IdentifierInfo *ii = nd->getIdentifier();
9232 if (ii != nullptr && ii->getName() == name.AsCString(nullptr))
9233 found_decls.push_back(GetCompilerDecl(nd));
9234 }
9235 }
9236 } else if (clang::NamedDecl *nd =
9237 llvm::dyn_cast<clang::NamedDecl>(Val: child)) {
9238 IdentifierInfo *ii = nd->getIdentifier();
9239 if (ii != nullptr && ii->getName() == name.AsCString(value_if_empty: nullptr))
9240 found_decls.push_back(x: GetCompilerDecl(nd));
9241 }
9242 }
9243 }
9244 }
9245 }
9246 return found_decls;
9247}
9248
9249// Look for child_decl_ctx's lookup scope in frame_decl_ctx and its parents,
9250// and return the number of levels it took to find it, or
9251// LLDB_INVALID_DECL_LEVEL if not found. If the decl was imported via a using
9252// declaration, its name and/or type, if set, will be used to check that the
9253// decl found in the scope is a match.
9254//
9255// The optional name is required by languages (like C++) to handle using
9256// declarations like:
9257//
9258// void poo();
9259// namespace ns {
9260// void foo();
9261// void goo();
9262// }
9263// void bar() {
9264// using ns::foo;
9265// // CountDeclLevels returns 0 for 'foo', 1 for 'poo', and
9266// // LLDB_INVALID_DECL_LEVEL for 'goo'.
9267// }
9268//
9269// The optional type is useful in the case that there's a specific overload
9270// that we're looking for that might otherwise be shadowed, like:
9271//
9272// void foo(int);
9273// namespace ns {
9274// void foo();
9275// }
9276// void bar() {
9277// using ns::foo;
9278// // CountDeclLevels returns 0 for { 'foo', void() },
9279// // 1 for { 'foo', void(int) }, and
9280// // LLDB_INVALID_DECL_LEVEL for { 'foo', void(int, int) }.
9281// }
9282//
9283// NOTE: Because file statics are at the TranslationUnit along with globals, a
9284// function at file scope will return the same level as a function at global
9285// scope. Ideally we'd like to treat the file scope as an additional scope just
9286// below the global scope. More work needs to be done to recognise that, if
9287// the decl we're trying to look up is static, we should compare its source
9288// file with that of the current scope and return a lower number for it.
9289uint32_t TypeSystemClang::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
9290 clang::DeclContext *child_decl_ctx,
9291 ConstString *child_name,
9292 CompilerType *child_type) {
9293 SymbolFile *symbol_file = GetSymbolFile();
9294 if (frame_decl_ctx && symbol_file) {
9295 std::set<DeclContext *> searched;
9296 std::multimap<DeclContext *, DeclContext *> search_queue;
9297
9298 // Get the lookup scope for the decl we're trying to find.
9299 clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent();
9300
9301 // Look for it in our scope's decl context and its parents.
9302 uint32_t level = 0;
9303 for (clang::DeclContext *decl_ctx = frame_decl_ctx; decl_ctx != nullptr;
9304 decl_ctx = decl_ctx->getParent()) {
9305 if (!decl_ctx->isLookupContext())
9306 continue;
9307 if (decl_ctx == parent_decl_ctx)
9308 // Found it!
9309 return level;
9310 search_queue.insert(x: std::make_pair(x&: decl_ctx, y&: decl_ctx));
9311 for (auto it = search_queue.find(x: decl_ctx); it != search_queue.end();
9312 it++) {
9313 if (searched.find(x: it->second) != searched.end())
9314 continue;
9315
9316 // Currently DWARF has one shared translation unit for all Decls at top
9317 // level, so this would erroneously find using statements anywhere. So
9318 // don't look at the top-level translation unit.
9319 // TODO fix this and add a testcase that depends on it.
9320
9321 if (llvm::isa<clang::TranslationUnitDecl>(Val: it->second))
9322 continue;
9323
9324 searched.insert(x: it->second);
9325 symbol_file->ParseDeclsForContext(
9326 decl_ctx: CreateDeclContext(ctx: it->second));
9327
9328 for (clang::Decl *child : it->second->decls()) {
9329 if (clang::UsingDirectiveDecl *ud =
9330 llvm::dyn_cast<clang::UsingDirectiveDecl>(Val: child)) {
9331 clang::DeclContext *ns = ud->getNominatedNamespace();
9332 if (ns == parent_decl_ctx)
9333 // Found it!
9334 return level;
9335 clang::DeclContext *from = ud->getCommonAncestor();
9336 if (searched.find(x: ns) == searched.end())
9337 search_queue.insert(x: std::make_pair(x&: from, y&: ns));
9338 } else if (child_name) {
9339 if (clang::UsingDecl *ud =
9340 llvm::dyn_cast<clang::UsingDecl>(Val: child)) {
9341 for (clang::UsingShadowDecl *usd : ud->shadows()) {
9342 clang::Decl *target = usd->getTargetDecl();
9343 clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(target);
9344 if (!nd)
9345 continue;
9346 // Check names.
9347 IdentifierInfo *ii = nd->getIdentifier();
9348 if (ii == nullptr ||
9349 ii->getName() != child_name->AsCString(nullptr))
9350 continue;
9351 // Check types, if one was provided.
9352 if (child_type) {
9353 CompilerType clang_type = GetTypeForDecl(nd);
9354 if (!AreTypesSame(clang_type, *child_type,
9355 /*ignore_qualifiers=*/true))
9356 continue;
9357 }
9358 // Found it!
9359 return level;
9360 }
9361 }
9362 }
9363 }
9364 }
9365 ++level;
9366 }
9367 }
9368 return LLDB_INVALID_DECL_LEVEL;
9369}
9370
9371ConstString TypeSystemClang::DeclContextGetName(void *opaque_decl_ctx) {
9372 if (opaque_decl_ctx) {
9373 clang::NamedDecl *named_decl =
9374 llvm::dyn_cast<clang::NamedDecl>(Val: (clang::DeclContext *)opaque_decl_ctx);
9375 if (named_decl) {
9376 std::string name;
9377 llvm::raw_string_ostream stream{name};
9378 auto policy = GetTypePrintingPolicy();
9379 policy.AlwaysIncludeTypeForTemplateArgument = true;
9380 named_decl->getNameForDiagnostic(OS&: stream, Policy: policy, /*qualified=*/Qualified: false);
9381 return ConstString(name);
9382 }
9383 }
9384 return ConstString();
9385}
9386
9387ConstString
9388TypeSystemClang::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) {
9389 if (opaque_decl_ctx) {
9390 clang::NamedDecl *named_decl =
9391 llvm::dyn_cast<clang::NamedDecl>(Val: (clang::DeclContext *)opaque_decl_ctx);
9392 if (named_decl)
9393 return ConstString(GetTypeNameForDecl(named_decl));
9394 }
9395 return ConstString();
9396}
9397
9398bool TypeSystemClang::DeclContextIsClassMethod(void *opaque_decl_ctx) {
9399 if (!opaque_decl_ctx)
9400 return false;
9401
9402 clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
9403 if (llvm::isa<clang::ObjCMethodDecl>(Val: decl_ctx)) {
9404 return true;
9405 } else if (llvm::isa<clang::CXXMethodDecl>(Val: decl_ctx)) {
9406 return true;
9407 } else if (clang::FunctionDecl *fun_decl =
9408 llvm::dyn_cast<clang::FunctionDecl>(Val: decl_ctx)) {
9409 if (std::optional<ClangASTMetadata> metadata = GetMetadata(fun_decl))
9410 return metadata->HasObjectPtr();
9411 }
9412
9413 return false;
9414}
9415
9416std::vector<lldb_private::CompilerContext>
9417TypeSystemClang::DeclContextGetCompilerContext(void *opaque_decl_ctx) {
9418 auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
9419 std::vector<lldb_private::CompilerContext> context;
9420 InsertCompilerContext(ts: this, decl_ctx, context);
9421 return context;
9422}
9423
9424bool TypeSystemClang::DeclContextIsContainedInLookup(
9425 void *opaque_decl_ctx, void *other_opaque_decl_ctx) {
9426 auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
9427 auto *other = (clang::DeclContext *)other_opaque_decl_ctx;
9428
9429 // If we have an inline or anonymous namespace, then the lookup of the
9430 // parent context also includes those namespace contents.
9431 auto is_transparent_lookup_allowed = [](clang::DeclContext *DC) {
9432 if (DC->isInlineNamespace())
9433 return true;
9434
9435 if (auto const *NS = dyn_cast<NamespaceDecl>(Val: DC))
9436 return NS->isAnonymousNamespace();
9437
9438 return false;
9439 };
9440
9441 do {
9442 // A decl context always includes its own contents in its lookup.
9443 if (decl_ctx == other)
9444 return true;
9445 } while (is_transparent_lookup_allowed(other) &&
9446 (other = other->getParent()));
9447
9448 return false;
9449}
9450
9451lldb::LanguageType
9452TypeSystemClang::DeclContextGetLanguage(void *opaque_decl_ctx) {
9453 if (!opaque_decl_ctx)
9454 return eLanguageTypeUnknown;
9455
9456 auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
9457 if (llvm::isa<clang::ObjCMethodDecl>(Val: decl_ctx)) {
9458 return eLanguageTypeObjC;
9459 } else if (llvm::isa<clang::CXXMethodDecl>(Val: decl_ctx)) {
9460 return eLanguageTypeC_plus_plus;
9461 } else if (auto *fun_decl = llvm::dyn_cast<clang::FunctionDecl>(Val: decl_ctx)) {
9462 if (std::optional<ClangASTMetadata> metadata = GetMetadata(fun_decl))
9463 return metadata->GetObjectPtrLanguage();
9464 }
9465
9466 return eLanguageTypeUnknown;
9467}
9468
9469static bool IsClangDeclContext(const CompilerDeclContext &dc) {
9470 return dc.IsValid() && isa<TypeSystemClang>(Val: dc.GetTypeSystem());
9471}
9472
9473clang::DeclContext *
9474TypeSystemClang::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) {
9475 if (IsClangDeclContext(dc))
9476 return (clang::DeclContext *)dc.GetOpaqueDeclContext();
9477 return nullptr;
9478}
9479
9480ObjCMethodDecl *
9481TypeSystemClang::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) {
9482 if (IsClangDeclContext(dc))
9483 return llvm::dyn_cast<clang::ObjCMethodDecl>(
9484 Val: (clang::DeclContext *)dc.GetOpaqueDeclContext());
9485 return nullptr;
9486}
9487
9488CXXMethodDecl *
9489TypeSystemClang::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) {
9490 if (IsClangDeclContext(dc))
9491 return llvm::dyn_cast<clang::CXXMethodDecl>(
9492 Val: (clang::DeclContext *)dc.GetOpaqueDeclContext());
9493 return nullptr;
9494}
9495
9496clang::FunctionDecl *
9497TypeSystemClang::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) {
9498 if (IsClangDeclContext(dc))
9499 return llvm::dyn_cast<clang::FunctionDecl>(
9500 Val: (clang::DeclContext *)dc.GetOpaqueDeclContext());
9501 return nullptr;
9502}
9503
9504clang::NamespaceDecl *
9505TypeSystemClang::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) {
9506 if (IsClangDeclContext(dc))
9507 return llvm::dyn_cast<clang::NamespaceDecl>(
9508 Val: (clang::DeclContext *)dc.GetOpaqueDeclContext());
9509 return nullptr;
9510}
9511
9512std::optional<ClangASTMetadata>
9513TypeSystemClang::DeclContextGetMetaData(const CompilerDeclContext &dc,
9514 const Decl *object) {
9515 TypeSystemClang *ast = llvm::cast<TypeSystemClang>(Val: dc.GetTypeSystem());
9516 return ast->GetMetadata(object);
9517}
9518
9519clang::ASTContext *
9520TypeSystemClang::DeclContextGetTypeSystemClang(const CompilerDeclContext &dc) {
9521 TypeSystemClang *ast =
9522 llvm::dyn_cast_or_null<TypeSystemClang>(Val: dc.GetTypeSystem());
9523 if (ast)
9524 return &ast->getASTContext();
9525 return nullptr;
9526}
9527
9528void TypeSystemClang::RequireCompleteType(CompilerType type) {
9529 // Technically, enums can be incomplete too, but we don't handle those as they
9530 // are emitted even under -flimit-debug-info.
9531 if (!TypeSystemClang::IsCXXClassType(type))
9532 return;
9533
9534 if (type.GetCompleteType())
9535 return;
9536
9537 // No complete definition in this module. Mark the class as complete to
9538 // satisfy local ast invariants, but make a note of the fact that
9539 // it is not _really_ complete so we can later search for a definition in a
9540 // different module.
9541 // Since we provide layout assistance, layouts of types containing this class
9542 // will be correct even if we are not able to find the definition elsewhere.
9543 bool started = TypeSystemClang::StartTagDeclarationDefinition(type);
9544 lldbassert(started && "Unable to start a class type definition.");
9545 TypeSystemClang::CompleteTagDeclarationDefinition(type);
9546 const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type);
9547 auto ts = type.GetTypeSystem<TypeSystemClang>();
9548 if (ts)
9549 ts->SetDeclIsForcefullyCompleted(td);
9550}
9551
9552namespace {
9553/// A specialized scratch AST used within ScratchTypeSystemClang.
9554/// These are the ASTs backing the different IsolatedASTKinds. They behave
9555/// like a normal ScratchTypeSystemClang but they don't own their own
9556/// persistent storage or target reference.
9557class SpecializedScratchAST : public TypeSystemClang {
9558public:
9559 /// \param name The display name of the TypeSystemClang instance.
9560 /// \param triple The triple used for the TypeSystemClang instance.
9561 /// \param ast_source The ClangASTSource that should be used to complete
9562 /// type information.
9563 SpecializedScratchAST(llvm::StringRef name, llvm::Triple triple,
9564 std::unique_ptr<ClangASTSource> ast_source)
9565 : TypeSystemClang(name, triple),
9566 m_scratch_ast_source_up(std::move(ast_source)) {
9567 // Setup the ClangASTSource to complete this AST.
9568 m_scratch_ast_source_up->InstallASTContext(ast_context&: *this);
9569 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
9570 m_scratch_ast_source_up->CreateProxy());
9571 SetExternalSource(proxy_ast_source);
9572 }
9573
9574 /// The ExternalASTSource that performs lookups and completes types.
9575 std::unique_ptr<ClangASTSource> m_scratch_ast_source_up;
9576};
9577} // namespace
9578
9579char ScratchTypeSystemClang::ID;
9580const std::nullopt_t ScratchTypeSystemClang::DefaultAST = std::nullopt;
9581
9582ScratchTypeSystemClang::ScratchTypeSystemClang(Target &target,
9583 llvm::Triple triple)
9584 : TypeSystemClang("scratch ASTContext", triple), m_triple(triple),
9585 m_target_wp(target.shared_from_this()),
9586 m_persistent_variables(
9587 new ClangPersistentVariables(target.shared_from_this())) {
9588 m_scratch_ast_source_up = CreateASTSource();
9589 m_scratch_ast_source_up->InstallASTContext(ast_context&: *this);
9590 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
9591 m_scratch_ast_source_up->CreateProxy());
9592 SetExternalSource(proxy_ast_source);
9593}
9594
9595void ScratchTypeSystemClang::Finalize() {
9596 TypeSystemClang::Finalize();
9597 m_scratch_ast_source_up.reset();
9598}
9599
9600TypeSystemClangSP
9601ScratchTypeSystemClang::GetForTarget(Target &target,
9602 std::optional<IsolatedASTKind> ast_kind,
9603 bool create_on_demand) {
9604 auto type_system_or_err = target.GetScratchTypeSystemForLanguage(
9605 language: lldb::eLanguageTypeC, create_on_demand);
9606 if (auto err = type_system_or_err.takeError()) {
9607 LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),
9608 "Couldn't get scratch TypeSystemClang: {0}");
9609 return nullptr;
9610 }
9611 auto ts_sp = *type_system_or_err;
9612 ScratchTypeSystemClang *scratch_ast =
9613 llvm::dyn_cast_or_null<ScratchTypeSystemClang>(Val: ts_sp.get());
9614 if (!scratch_ast)
9615 return nullptr;
9616 // If no dedicated sub-AST was requested, just return the main AST.
9617 if (ast_kind == DefaultAST)
9618 return std::static_pointer_cast<TypeSystemClang>(r: ts_sp);
9619 // Search the sub-ASTs.
9620 return std::static_pointer_cast<TypeSystemClang>(
9621 r: scratch_ast->GetIsolatedAST(feature: *ast_kind).shared_from_this());
9622}
9623
9624/// Returns a human-readable name that uniquely identifiers the sub-AST kind.
9625static llvm::StringRef
9626GetNameForIsolatedASTKind(ScratchTypeSystemClang::IsolatedASTKind kind) {
9627 switch (kind) {
9628 case ScratchTypeSystemClang::IsolatedASTKind::CppModules:
9629 return "C++ modules";
9630 }
9631 llvm_unreachable("Unimplemented IsolatedASTKind?");
9632}
9633
9634void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output,
9635 llvm::StringRef filter) {
9636 // First dump the main scratch AST.
9637 output << "State of scratch Clang type system:\n";
9638 TypeSystemClang::Dump(output, filter);
9639
9640 // Now sort the isolated sub-ASTs.
9641 typedef std::pair<IsolatedASTKey, TypeSystem *> KeyAndTS;
9642 std::vector<KeyAndTS> sorted_typesystems;
9643 for (const auto &a : m_isolated_asts)
9644 sorted_typesystems.emplace_back(args: a.first, args: a.second.get());
9645 llvm::stable_sort(Range&: sorted_typesystems, C: llvm::less_first());
9646
9647 // Dump each sub-AST too.
9648 for (const auto &a : sorted_typesystems) {
9649 IsolatedASTKind kind =
9650 static_cast<ScratchTypeSystemClang::IsolatedASTKind>(a.first);
9651 output << "State of scratch Clang type subsystem "
9652 << GetNameForIsolatedASTKind(kind) << ":\n";
9653 a.second->Dump(output, filter);
9654 }
9655}
9656
9657UserExpression *ScratchTypeSystemClang::GetUserExpression(
9658 llvm::StringRef expr, llvm::StringRef prefix, SourceLanguage language,
9659 Expression::ResultType desired_type,
9660 const EvaluateExpressionOptions &options, ValueObject *ctx_obj) {
9661 TargetSP target_sp = m_target_wp.lock();
9662 if (!target_sp)
9663 return nullptr;
9664
9665 return new ClangUserExpression(*target_sp.get(), expr, prefix, language,
9666 desired_type, options, ctx_obj);
9667}
9668
9669FunctionCaller *ScratchTypeSystemClang::GetFunctionCaller(
9670 const CompilerType &return_type, const Address &function_address,
9671 const ValueList &arg_value_list, const char *name) {
9672 TargetSP target_sp = m_target_wp.lock();
9673 if (!target_sp)
9674 return nullptr;
9675
9676 Process *process = target_sp->GetProcessSP().get();
9677 if (!process)
9678 return nullptr;
9679
9680 return new ClangFunctionCaller(*process, return_type, function_address,
9681 arg_value_list, name);
9682}
9683
9684std::unique_ptr<UtilityFunction>
9685ScratchTypeSystemClang::CreateUtilityFunction(std::string text,
9686 std::string name) {
9687 TargetSP target_sp = m_target_wp.lock();
9688 if (!target_sp)
9689 return {};
9690
9691 return std::make_unique<ClangUtilityFunction>(
9692 args&: *target_sp.get(), args: std::move(text), args: std::move(name),
9693 args: target_sp->GetDebugUtilityExpression());
9694}
9695
9696PersistentExpressionState *
9697ScratchTypeSystemClang::GetPersistentExpressionState() {
9698 return m_persistent_variables.get();
9699}
9700
9701void ScratchTypeSystemClang::ForgetSource(ASTContext *src_ctx,
9702 ClangASTImporter &importer) {
9703 // Remove it as a source from the main AST.
9704 importer.ForgetSource(dst_ctx: &getASTContext(), src_ctx);
9705 // Remove it as a source from all created sub-ASTs.
9706 for (const auto &a : m_isolated_asts)
9707 importer.ForgetSource(dst_ctx: &a.second->getASTContext(), src_ctx);
9708}
9709
9710std::unique_ptr<ClangASTSource> ScratchTypeSystemClang::CreateASTSource() {
9711 return std::make_unique<ClangASTSource>(
9712 args: m_target_wp.lock()->shared_from_this(),
9713 args: m_persistent_variables->GetClangASTImporter());
9714}
9715
9716static llvm::StringRef
9717GetSpecializedASTName(ScratchTypeSystemClang::IsolatedASTKind feature) {
9718 switch (feature) {
9719 case ScratchTypeSystemClang::IsolatedASTKind::CppModules:
9720 return "scratch ASTContext for C++ module types";
9721 }
9722 llvm_unreachable("Unimplemented ASTFeature kind?");
9723}
9724
9725TypeSystemClang &ScratchTypeSystemClang::GetIsolatedAST(
9726 ScratchTypeSystemClang::IsolatedASTKind feature) {
9727 auto found_ast = m_isolated_asts.find(Val: feature);
9728 if (found_ast != m_isolated_asts.end())
9729 return *found_ast->second;
9730
9731 // Couldn't find the requested sub-AST, so create it now.
9732 std::shared_ptr<TypeSystemClang> new_ast_sp =
9733 std::make_shared<SpecializedScratchAST>(args: GetSpecializedASTName(feature),
9734 args&: m_triple, args: CreateASTSource());
9735 m_isolated_asts.insert(KV: {feature, new_ast_sp});
9736 return *new_ast_sp;
9737}
9738
9739bool TypeSystemClang::IsForcefullyCompleted(lldb::opaque_compiler_type_t type) {
9740 if (type) {
9741 clang::QualType qual_type(GetQualType(type));
9742 const clang::RecordType *record_type =
9743 llvm::dyn_cast<clang::RecordType>(Val: qual_type.getTypePtr());
9744 if (record_type) {
9745 const clang::RecordDecl *record_decl = record_type->getDecl();
9746 assert(record_decl);
9747 if (std::optional<ClangASTMetadata> metadata = GetMetadata(record_decl))
9748 return metadata->IsForcefullyCompleted();
9749 }
9750 }
9751 return false;
9752}
9753
9754bool TypeSystemClang::SetDeclIsForcefullyCompleted(const clang::TagDecl *td) {
9755 if (td == nullptr)
9756 return false;
9757 std::optional<ClangASTMetadata> metadata = GetMetadata(td);
9758 if (!metadata)
9759 return false;
9760 m_has_forcefully_completed_types = true;
9761 metadata->SetIsForcefullyCompleted();
9762 SetMetadata(td, *metadata);
9763
9764 return true;
9765}
9766
9767void TypeSystemClang::LogCreation() const {
9768 if (auto *log = GetLog(mask: LLDBLog::Expressions))
9769 LLDB_LOG(log, "Created new TypeSystem for (ASTContext*){0:x} '{1}'",
9770 &getASTContext(), getDisplayName());
9771}
9772

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