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

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