blob: edc8acf2a215c6519121a6a7bece07df0484f3a9 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006//
7//===----------------------------------------------------------------------===//
8
Eli Friedman932197d2010-06-13 19:06:42 +00009#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000010
Zachary Turner827d5d72016-12-16 04:27:00 +000011#include "llvm/Support/FormatAdapters.h"
12#include "llvm/Support/FormatVariadic.h"
13
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000014#include <mutex>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include <string>
Sean Callananfe38c852015-10-08 23:07:53 +000016#include <vector>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017
Greg Clayton6beaaa62011-01-17 03:46:26 +000018
Kate Stoneb9c1b512016-09-06 20:57:50 +000019// Clang headers like to use NDEBUG inside of them to enable/disable debug
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +000020// related features using "#ifndef NDEBUG" preprocessor blocks to do one thing
Greg Clayton6beaaa62011-01-17 03:46:26 +000021// or another. This is bad because it means that if clang was built in release
22// mode, it assumes that you are building in release mode which is not always
23// the case. You can end up with functions that are defined as empty in header
24// files when NDEBUG is not defined, and this can cause link errors with the
25// clang .a files that you have since you might be missing functions in the .a
26// file. So we have to define NDEBUG when including clang headers to avoid any
27// mismatches. This is covered by rdar://problem/8691220
28
Sean Callanan3b1d4f62011-10-26 17:46:51 +000029#if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF)
Greg Clayton6beaaa62011-01-17 03:46:26 +000030#define LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000031#define NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000032// Need to include assert.h so it is as clang would expect it to be (disabled)
33#include <assert.h>
34#endif
35
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036#include "clang/AST/ASTContext.h"
37#include "clang/AST/ASTImporter.h"
Greg Claytonf74c4032012-12-03 18:29:55 +000038#include "clang/AST/Attr.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "clang/AST/CXXInheritance.h"
Greg Clayton8cf05932010-07-22 18:30:50 +000040#include "clang/AST/DeclObjC.h"
Greg Claytonf0705c82011-10-22 03:33:13 +000041#include "clang/AST/DeclTemplate.h"
Greg Claytonfe689042015-11-10 17:47:04 +000042#include "clang/AST/Mangle.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043#include "clang/AST/RecordLayout.h"
44#include "clang/AST/Type.h"
Greg Claytond8d4a572015-08-11 21:38:15 +000045#include "clang/AST/VTableBuilder.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046#include "clang/Basic/Builtins.h"
Sean Callanan7e2863b2012-02-06 21:28:03 +000047#include "clang/Basic/Diagnostic.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048#include "clang/Basic/FileManager.h"
Sean Callanan79439e82010-11-18 02:56:27 +000049#include "clang/Basic/FileSystemOptions.h"
Rainer Orth6ca17072019-08-05 14:00:43 +000050#include "clang/Basic/LangStandard.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051#include "clang/Basic/SourceManager.h"
52#include "clang/Basic/TargetInfo.h"
53#include "clang/Basic/TargetOptions.h"
54#include "clang/Frontend/FrontendOptions.h"
Raphael Isemannf74a4c12019-04-30 08:41:35 +000055#include "clang/Sema/Sema.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000056
57#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000058#undef NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000059#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
60// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
61#include <assert.h>
62#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063
Greg Claytond8d4a572015-08-11 21:38:15 +000064#include "llvm/Support/Signals.h"
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000065#include "llvm/Support/Threading.h"
Greg Claytond8d4a572015-08-11 21:38:15 +000066
Zachary Turnerd133f6a2016-03-28 22:53:41 +000067#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
68#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
69#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
Pavel Labath5f19b902017-11-13 16:16:33 +000070#include "lldb/Utility/ArchSpec.h"
Zachary Turner01c32432017-02-14 19:06:07 +000071#include "lldb/Utility/Flags.h"
72
Zachary Turner29cb8682017-03-03 20:57:05 +000073#include "lldb/Core/DumpDataExtractor.h"
Greg Clayton56939cb2015-09-17 22:23:34 +000074#include "lldb/Core/Module.h"
75#include "lldb/Core/PluginManager.h"
Greg Claytond8d4a572015-08-11 21:38:15 +000076#include "lldb/Core/StreamFile.h"
Enrico Granata2267ad42014-09-16 17:28:40 +000077#include "lldb/Core/ThreadSafeDenseMap.h"
Greg Clayton57ee3062013-07-11 22:46:58 +000078#include "lldb/Core/UniqueCStringMap.h"
Greg Claytond8d4a572015-08-11 21:38:15 +000079#include "lldb/Symbol/ClangASTContext.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000080#include "lldb/Symbol/ClangASTImporter.h"
Greg Clayton6dc8d582015-08-18 22:32:36 +000081#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Sean Callanan3b107b12011-12-03 03:15:28 +000082#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000083#include "lldb/Symbol/ClangUtil.h"
Greg Clayton56939cb2015-09-17 22:23:34 +000084#include "lldb/Symbol/ObjectFile.h"
Greg Clayton261ac3f2015-08-28 01:01:03 +000085#include "lldb/Symbol/SymbolFile.h"
Sean Callanan5e9e1992011-10-26 01:06:27 +000086#include "lldb/Symbol/VerifyDecl.h"
Jim Inghamd555bac2011-06-24 22:03:24 +000087#include "lldb/Target/ExecutionContext.h"
Greg Clayton56939cb2015-09-17 22:23:34 +000088#include "lldb/Target/Language.h"
Jim Ingham151c0322015-09-15 21:13:50 +000089#include "lldb/Target/Process.h"
90#include "lldb/Target/Target.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000091#include "lldb/Utility/DataExtractor.h"
Sean Callananc530ba92016-05-02 21:15:31 +000092#include "lldb/Utility/LLDBAssert.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000093#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000094#include "lldb/Utility/RegularExpression.h"
Pavel Labathd821c992018-08-07 11:07:21 +000095#include "lldb/Utility/Scalar.h"
Jim Inghamd555bac2011-06-24 22:03:24 +000096
Alex Langfordb57017102019-07-15 22:56:12 +000097#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
Greg Clayton261ac3f2015-08-28 01:01:03 +000098#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
Zachary Turner42dff792016-04-15 00:21:26 +000099#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
Greg Clayton261ac3f2015-08-28 01:01:03 +0000100
Eli Friedman932197d2010-06-13 19:06:42 +0000101#include <stdio.h>
102
Greg Clayton1341baf2013-07-11 23:36:31 +0000103#include <mutex>
104
Greg Claytonc86103d2010-08-05 01:57:25 +0000105using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106using namespace lldb_private;
107using namespace llvm;
108using namespace clang;
109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110namespace {
111static inline bool
112ClangASTContextSupportsLanguage(lldb::LanguageType language) {
113 return language == eLanguageTypeUnknown || // Clang is the default type system
Rainer Orth6ca17072019-08-05 14:00:43 +0000114 lldb_private::Language::LanguageIsC(language) ||
115 lldb_private::Language::LanguageIsCPlusPlus(language) ||
116 lldb_private::Language::LanguageIsObjC(language) ||
117 lldb_private::Language::LanguageIsPascal(language) ||
Kate Stoneb9c1b512016-09-06 20:57:50 +0000118 // Use Clang for Rust until there is a proper language plugin for it
119 language == eLanguageTypeRust ||
Johan Engelen04799572016-11-25 11:01:12 +0000120 language == eLanguageTypeExtRenderScript ||
121 // Use Clang for D until there is a proper language plugin for it
Bruce Mitchenerb8233f82018-11-27 05:37:27 +0000122 language == eLanguageTypeD ||
123 // Open Dylan compiler debug info is designed to be Clang-compatible
124 language == eLanguageTypeDylan;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125}
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +0000126
127// Checks whether m1 is an overload of m2 (as opposed to an override). This is
128// called by addOverridesForMethod to distinguish overrides (which share a
129// vtable entry) from overloads (which require distinct entries).
130bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) {
131 // FIXME: This should detect covariant return types, but currently doesn't.
132 lldbassert(&m1->getASTContext() == &m2->getASTContext() &&
133 "Methods should have the same AST context");
134 clang::ASTContext &context = m1->getASTContext();
135
136 const auto *m1Type = llvm::cast<clang::FunctionProtoType>(
137 context.getCanonicalType(m1->getType()));
138
139 const auto *m2Type = llvm::cast<clang::FunctionProtoType>(
140 context.getCanonicalType(m2->getType()));
141
142 auto compareArgTypes = [&context](const clang::QualType &m1p,
143 const clang::QualType &m2p) {
144 return context.hasSameType(m1p.getUnqualifiedType(),
145 m2p.getUnqualifiedType());
146 };
147
148 // FIXME: In C++14 and later, we can just pass m2Type->param_type_end()
149 // as a fourth parameter to std::equal().
150 return (m1->getNumParams() != m2->getNumParams()) ||
151 !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(),
152 m2Type->param_type_begin(), compareArgTypes);
153}
154
155// If decl is a virtual method, walk the base classes looking for methods that
156// decl overrides. This table of overridden methods is used by IRGen to
157// determine the vtable layout for decl's parent class.
158void addOverridesForMethod(clang::CXXMethodDecl *decl) {
159 if (!decl->isVirtual())
160 return;
161
162 clang::CXXBasePaths paths;
163
164 auto find_overridden_methods =
165 [decl](const clang::CXXBaseSpecifier *specifier,
166 clang::CXXBasePath &path) {
167 if (auto *base_record = llvm::dyn_cast<clang::CXXRecordDecl>(
168 specifier->getType()->getAs<clang::RecordType>()->getDecl())) {
169
170 clang::DeclarationName name = decl->getDeclName();
171
172 // If this is a destructor, check whether the base class destructor is
173 // virtual.
174 if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
175 if (auto *baseDtorDecl = base_record->getDestructor()) {
176 if (baseDtorDecl->isVirtual()) {
177 path.Decls = baseDtorDecl;
178 return true;
179 } else
180 return false;
181 }
182
183 // Otherwise, search for name in the base class.
184 for (path.Decls = base_record->lookup(name); !path.Decls.empty();
185 path.Decls = path.Decls.slice(1)) {
186 if (auto *method_decl =
187 llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
188 if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
189 path.Decls = method_decl;
190 return true;
191 }
192 }
193 }
194
195 return false;
196 };
197
198 if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) {
199 for (auto *overridden_decl : paths.found_decls())
200 decl->addOverriddenMethod(
201 llvm::cast<clang::CXXMethodDecl>(overridden_decl));
202 }
203}
Greg Clayton56939cb2015-09-17 22:23:34 +0000204}
205
Aleksandr Urakov1dc51db2018-11-12 16:23:50 +0000206static lldb::addr_t GetVTableAddress(Process &process,
207 VTableContextBase &vtable_ctx,
208 ValueObject &valobj,
209 const ASTRecordLayout &record_layout) {
210 // Retrieve type info
211 CompilerType pointee_type;
212 CompilerType this_type(valobj.GetCompilerType());
213 uint32_t type_info = this_type.GetTypeInfo(&pointee_type);
214 if (!type_info)
215 return LLDB_INVALID_ADDRESS;
216
217 // Check if it's a pointer or reference
218 bool ptr_or_ref = false;
219 if (type_info & (eTypeIsPointer | eTypeIsReference)) {
220 ptr_or_ref = true;
221 type_info = pointee_type.GetTypeInfo();
222 }
223
224 // We process only C++ classes
225 const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus;
226 if ((type_info & cpp_class) != cpp_class)
227 return LLDB_INVALID_ADDRESS;
228
229 // Calculate offset to VTable pointer
230 lldb::offset_t vbtable_ptr_offset =
231 vtable_ctx.isMicrosoft() ? record_layout.getVBPtrOffset().getQuantity()
232 : 0;
233
234 if (ptr_or_ref) {
235 // We have a pointer / ref to object, so read
236 // VTable pointer from process memory
237
238 if (valobj.GetAddressTypeOfChildren() != eAddressTypeLoad)
239 return LLDB_INVALID_ADDRESS;
240
241 auto vbtable_ptr_addr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
242 if (vbtable_ptr_addr == LLDB_INVALID_ADDRESS)
243 return LLDB_INVALID_ADDRESS;
244
245 vbtable_ptr_addr += vbtable_ptr_offset;
246
247 Status err;
248 return process.ReadPointerFromMemory(vbtable_ptr_addr, err);
249 }
250
251 // We have an object already read from process memory,
252 // so just extract VTable pointer from it
253
254 DataExtractor data;
255 Status err;
256 auto size = valobj.GetData(data, err);
257 if (err.Fail() || vbtable_ptr_offset + data.GetAddressByteSize() > size)
258 return LLDB_INVALID_ADDRESS;
259
260 return data.GetPointer(&vbtable_ptr_offset);
261}
262
263static int64_t ReadVBaseOffsetFromVTable(Process &process,
264 VTableContextBase &vtable_ctx,
265 lldb::addr_t vtable_ptr,
266 const CXXRecordDecl *cxx_record_decl,
267 const CXXRecordDecl *base_class_decl) {
268 if (vtable_ctx.isMicrosoft()) {
269 clang::MicrosoftVTableContext &msoft_vtable_ctx =
270 static_cast<clang::MicrosoftVTableContext &>(vtable_ctx);
271
272 // Get the index into the virtual base table. The
273 // index is the index in uint32_t from vbtable_ptr
274 const unsigned vbtable_index =
275 msoft_vtable_ctx.getVBTableIndex(cxx_record_decl, base_class_decl);
276 const lldb::addr_t base_offset_addr = vtable_ptr + vbtable_index * 4;
277 Status err;
278 return process.ReadSignedIntegerFromMemory(base_offset_addr, 4, INT64_MAX,
279 err);
280 }
281
282 clang::ItaniumVTableContext &itanium_vtable_ctx =
283 static_cast<clang::ItaniumVTableContext &>(vtable_ctx);
284
285 clang::CharUnits base_offset_offset =
286 itanium_vtable_ctx.getVirtualBaseOffsetOffset(cxx_record_decl,
287 base_class_decl);
288 const lldb::addr_t base_offset_addr =
289 vtable_ptr + base_offset_offset.getQuantity();
290 const uint32_t base_offset_size = process.GetAddressByteSize();
291 Status err;
292 return process.ReadSignedIntegerFromMemory(base_offset_addr, base_offset_size,
293 INT64_MAX, err);
294}
295
296static bool GetVBaseBitOffset(VTableContextBase &vtable_ctx,
297 ValueObject &valobj,
298 const ASTRecordLayout &record_layout,
299 const CXXRecordDecl *cxx_record_decl,
300 const CXXRecordDecl *base_class_decl,
301 int32_t &bit_offset) {
302 ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
303 Process *process = exe_ctx.GetProcessPtr();
304 if (!process)
305 return false;
306
307 lldb::addr_t vtable_ptr =
308 GetVTableAddress(*process, vtable_ctx, valobj, record_layout);
309 if (vtable_ptr == LLDB_INVALID_ADDRESS)
310 return false;
311
312 auto base_offset = ReadVBaseOffsetFromVTable(
313 *process, vtable_ctx, vtable_ptr, cxx_record_decl, base_class_decl);
314 if (base_offset == INT64_MAX)
315 return false;
316
317 bit_offset = base_offset * 8;
318
319 return true;
320}
321
Kate Stoneb9c1b512016-09-06 20:57:50 +0000322typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, ClangASTContext *>
323 ClangASTMap;
Enrico Granata5d84a692014-08-19 21:46:37 +0000324
Kate Stoneb9c1b512016-09-06 20:57:50 +0000325static ClangASTMap &GetASTMap() {
326 static ClangASTMap *g_map_ptr = nullptr;
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000327 static llvm::once_flag g_once_flag;
328 llvm::call_once(g_once_flag, []() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000329 g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins
330 });
331 return *g_map_ptr;
Enrico Granata5d84a692014-08-19 21:46:37 +0000332}
333
Davide Italiano7e3ef4d2018-03-20 19:46:32 +0000334bool ClangASTContext::IsOperator(const char *name,
335 clang::OverloadedOperatorKind &op_kind) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000336 if (name == nullptr || name[0] == '\0')
337 return false;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000338
339#define OPERATOR_PREFIX "operator"
340#define OPERATOR_PREFIX_LENGTH (sizeof(OPERATOR_PREFIX) - 1)
341
Kate Stoneb9c1b512016-09-06 20:57:50 +0000342 const char *post_op_name = nullptr;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000343
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344 bool no_space = true;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000345
Kate Stoneb9c1b512016-09-06 20:57:50 +0000346 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
347 return false;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000348
Kate Stoneb9c1b512016-09-06 20:57:50 +0000349 post_op_name = name + OPERATOR_PREFIX_LENGTH;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000350
Kate Stoneb9c1b512016-09-06 20:57:50 +0000351 if (post_op_name[0] == ' ') {
352 post_op_name++;
353 no_space = false;
354 }
Pavel Labath1ac2b202016-08-15 14:32:32 +0000355
356#undef OPERATOR_PREFIX
357#undef OPERATOR_PREFIX_LENGTH
358
Adrian Prantl05097242018-04-30 16:49:04 +0000359 // This is an operator, set the overloaded operator kind to invalid in case
360 // this is a conversion operator...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361 op_kind = clang::NUM_OVERLOADED_OPERATORS;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000362
Kate Stoneb9c1b512016-09-06 20:57:50 +0000363 switch (post_op_name[0]) {
364 default:
365 if (no_space)
366 return false;
367 break;
368 case 'n':
369 if (no_space)
370 return false;
371 if (strcmp(post_op_name, "new") == 0)
372 op_kind = clang::OO_New;
373 else if (strcmp(post_op_name, "new[]") == 0)
374 op_kind = clang::OO_Array_New;
375 break;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000376
Kate Stoneb9c1b512016-09-06 20:57:50 +0000377 case 'd':
378 if (no_space)
379 return false;
380 if (strcmp(post_op_name, "delete") == 0)
381 op_kind = clang::OO_Delete;
382 else if (strcmp(post_op_name, "delete[]") == 0)
383 op_kind = clang::OO_Array_Delete;
384 break;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000385
Kate Stoneb9c1b512016-09-06 20:57:50 +0000386 case '+':
387 if (post_op_name[1] == '\0')
388 op_kind = clang::OO_Plus;
389 else if (post_op_name[2] == '\0') {
390 if (post_op_name[1] == '=')
391 op_kind = clang::OO_PlusEqual;
392 else if (post_op_name[1] == '+')
393 op_kind = clang::OO_PlusPlus;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000394 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395 break;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000396
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397 case '-':
398 if (post_op_name[1] == '\0')
399 op_kind = clang::OO_Minus;
400 else if (post_op_name[2] == '\0') {
401 switch (post_op_name[1]) {
402 case '=':
403 op_kind = clang::OO_MinusEqual;
404 break;
405 case '-':
406 op_kind = clang::OO_MinusMinus;
407 break;
408 case '>':
409 op_kind = clang::OO_Arrow;
410 break;
411 }
412 } else if (post_op_name[3] == '\0') {
413 if (post_op_name[2] == '*')
414 op_kind = clang::OO_ArrowStar;
415 break;
416 }
417 break;
418
419 case '*':
420 if (post_op_name[1] == '\0')
421 op_kind = clang::OO_Star;
422 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
423 op_kind = clang::OO_StarEqual;
424 break;
425
426 case '/':
427 if (post_op_name[1] == '\0')
428 op_kind = clang::OO_Slash;
429 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
430 op_kind = clang::OO_SlashEqual;
431 break;
432
433 case '%':
434 if (post_op_name[1] == '\0')
435 op_kind = clang::OO_Percent;
436 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
437 op_kind = clang::OO_PercentEqual;
438 break;
439
440 case '^':
441 if (post_op_name[1] == '\0')
442 op_kind = clang::OO_Caret;
443 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
444 op_kind = clang::OO_CaretEqual;
445 break;
446
447 case '&':
448 if (post_op_name[1] == '\0')
449 op_kind = clang::OO_Amp;
450 else if (post_op_name[2] == '\0') {
451 switch (post_op_name[1]) {
452 case '=':
453 op_kind = clang::OO_AmpEqual;
454 break;
455 case '&':
456 op_kind = clang::OO_AmpAmp;
457 break;
458 }
459 }
460 break;
461
462 case '|':
463 if (post_op_name[1] == '\0')
464 op_kind = clang::OO_Pipe;
465 else if (post_op_name[2] == '\0') {
466 switch (post_op_name[1]) {
467 case '=':
468 op_kind = clang::OO_PipeEqual;
469 break;
470 case '|':
471 op_kind = clang::OO_PipePipe;
472 break;
473 }
474 }
475 break;
476
477 case '~':
478 if (post_op_name[1] == '\0')
479 op_kind = clang::OO_Tilde;
480 break;
481
482 case '!':
483 if (post_op_name[1] == '\0')
484 op_kind = clang::OO_Exclaim;
485 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
486 op_kind = clang::OO_ExclaimEqual;
487 break;
488
489 case '=':
490 if (post_op_name[1] == '\0')
491 op_kind = clang::OO_Equal;
492 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
493 op_kind = clang::OO_EqualEqual;
494 break;
495
496 case '<':
497 if (post_op_name[1] == '\0')
498 op_kind = clang::OO_Less;
499 else if (post_op_name[2] == '\0') {
500 switch (post_op_name[1]) {
501 case '<':
502 op_kind = clang::OO_LessLess;
503 break;
504 case '=':
505 op_kind = clang::OO_LessEqual;
506 break;
507 }
508 } else if (post_op_name[3] == '\0') {
509 if (post_op_name[2] == '=')
510 op_kind = clang::OO_LessLessEqual;
511 }
512 break;
513
514 case '>':
515 if (post_op_name[1] == '\0')
516 op_kind = clang::OO_Greater;
517 else if (post_op_name[2] == '\0') {
518 switch (post_op_name[1]) {
519 case '>':
520 op_kind = clang::OO_GreaterGreater;
521 break;
522 case '=':
523 op_kind = clang::OO_GreaterEqual;
524 break;
525 }
526 } else if (post_op_name[1] == '>' && post_op_name[2] == '=' &&
527 post_op_name[3] == '\0') {
528 op_kind = clang::OO_GreaterGreaterEqual;
529 }
530 break;
531
532 case ',':
533 if (post_op_name[1] == '\0')
534 op_kind = clang::OO_Comma;
535 break;
536
537 case '(':
538 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
539 op_kind = clang::OO_Call;
540 break;
541
542 case '[':
543 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
544 op_kind = clang::OO_Subscript;
545 break;
546 }
547
548 return true;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000549}
Enrico Granata5d84a692014-08-19 21:46:37 +0000550
Greg Clayton57ee3062013-07-11 22:46:58 +0000551clang::AccessSpecifier
Kate Stoneb9c1b512016-09-06 20:57:50 +0000552ClangASTContext::ConvertAccessTypeToAccessSpecifier(AccessType access) {
553 switch (access) {
554 default:
555 break;
556 case eAccessNone:
Greg Clayton8cf05932010-07-22 18:30:50 +0000557 return AS_none;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000558 case eAccessPublic:
559 return AS_public;
560 case eAccessPrivate:
561 return AS_private;
562 case eAccessProtected:
563 return AS_protected;
564 }
565 return AS_none;
Greg Clayton8cf05932010-07-22 18:30:50 +0000566}
567
Kate Stoneb9c1b512016-09-06 20:57:50 +0000568static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
569 // FIXME: Cleanup per-file based stuff.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000570
Adrian Prantl05097242018-04-30 16:49:04 +0000571 // Set some properties which depend solely on the input kind; it would be
572 // nice to move these to the language standard, and have the driver resolve
573 // the input kind + language standard.
Rainer Orth6ca17072019-08-05 14:00:43 +0000574 if (IK.getLanguage() == clang::Language::Asm) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000575 Opts.AsmPreprocessor = 1;
Richard Smith8186cd42017-04-26 22:10:53 +0000576 } else if (IK.isObjectiveC()) {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000577 Opts.ObjC = 1;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000578 }
579
580 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
581
582 if (LangStd == LangStandard::lang_unspecified) {
583 // Based on the base language, pick one.
Richard Smith8186cd42017-04-26 22:10:53 +0000584 switch (IK.getLanguage()) {
Rainer Orth6ca17072019-08-05 14:00:43 +0000585 case clang::Language::Unknown:
586 case clang::Language::LLVM_IR:
587 case clang::Language::RenderScript:
David Blaikiea322f362017-01-06 00:38:06 +0000588 llvm_unreachable("Invalid input kind!");
Rainer Orth6ca17072019-08-05 14:00:43 +0000589 case clang::Language::OpenCL:
Pavel Labath47168542017-04-27 08:49:19 +0000590 LangStd = LangStandard::lang_opencl10;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000591 break;
Rainer Orth6ca17072019-08-05 14:00:43 +0000592 case clang::Language::CUDA:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000593 LangStd = LangStandard::lang_cuda;
594 break;
Rainer Orth6ca17072019-08-05 14:00:43 +0000595 case clang::Language::Asm:
596 case clang::Language::C:
597 case clang::Language::ObjC:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000598 LangStd = LangStandard::lang_gnu99;
599 break;
Rainer Orth6ca17072019-08-05 14:00:43 +0000600 case clang::Language::CXX:
601 case clang::Language::ObjCXX:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000602 LangStd = LangStandard::lang_gnucxx98;
603 break;
Rainer Orth6ca17072019-08-05 14:00:43 +0000604 case clang::Language::HIP:
Benjamin Kramer0d97c222018-04-25 13:22:47 +0000605 LangStd = LangStandard::lang_hip;
606 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000608 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000609
Kate Stoneb9c1b512016-09-06 20:57:50 +0000610 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
611 Opts.LineComment = Std.hasLineComments();
612 Opts.C99 = Std.isC99();
613 Opts.CPlusPlus = Std.isCPlusPlus();
614 Opts.CPlusPlus11 = Std.isCPlusPlus11();
615 Opts.Digraphs = Std.hasDigraphs();
616 Opts.GNUMode = Std.isGNUMode();
617 Opts.GNUInline = !Std.isC99();
618 Opts.HexFloats = Std.hasHexFloats();
619 Opts.ImplicitInt = Std.hasImplicitInt();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000620
Kate Stoneb9c1b512016-09-06 20:57:50 +0000621 Opts.WChar = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622
Kate Stoneb9c1b512016-09-06 20:57:50 +0000623 // OpenCL has some additional defaults.
Pavel Labath47168542017-04-27 08:49:19 +0000624 if (LangStd == LangStandard::lang_opencl10) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000625 Opts.OpenCL = 1;
626 Opts.AltiVec = 1;
627 Opts.CXXOperatorNames = 1;
628 Opts.LaxVectorConversions = 1;
629 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630
Kate Stoneb9c1b512016-09-06 20:57:50 +0000631 // OpenCL and C++ both have bool, true, false keywords.
632 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000633
Kate Stoneb9c1b512016-09-06 20:57:50 +0000634 Opts.setValueVisibilityMode(DefaultVisibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000635
Adrian Prantl05097242018-04-30 16:49:04 +0000636 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs is
637 // specified, or -std is set to a conforming mode.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000638 Opts.Trigraphs = !Opts.GNUMode;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000639 Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000640 Opts.OptimizeSize = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641
Kate Stoneb9c1b512016-09-06 20:57:50 +0000642 // FIXME: Eliminate this dependency.
643 // unsigned Opt =
644 // Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
645 // Opts.Optimize = Opt != 0;
646 unsigned Opt = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000647
Kate Stoneb9c1b512016-09-06 20:57:50 +0000648 // This is the __NO_INLINE__ define, which just depends on things like the
649 // optimization level and -fno-inline, not actually whether the backend has
650 // inlining enabled.
651 //
652 // FIXME: This is affected by other options (-fno-inline).
653 Opts.NoInlineDefine = !Opt;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000654}
655
Kate Stoneb9c1b512016-09-06 20:57:50 +0000656ClangASTContext::ClangASTContext(const char *target_triple)
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000657 : TypeSystem(TypeSystem::eKindClang), m_target_triple(), m_ast_up(),
658 m_language_options_up(), m_source_manager_up(), m_diagnostics_engine_up(),
659 m_target_options_rp(), m_target_info_up(), m_identifier_table_up(),
660 m_selector_table_up(), m_builtins_up(), m_callback_tag_decl(nullptr),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000661 m_callback_objc_decl(nullptr), m_callback_baton(nullptr),
662 m_pointer_byte_size(0), m_ast_owned(false) {
663 if (target_triple && target_triple[0])
664 SetTargetTriple(target_triple);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000665}
666
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000667// Destructor
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668ClangASTContext::~ClangASTContext() { Finalize(); }
669
670ConstString ClangASTContext::GetPluginNameStatic() {
671 return ConstString("clang");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672}
673
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674ConstString ClangASTContext::GetPluginName() {
675 return ClangASTContext::GetPluginNameStatic();
Greg Clayton56939cb2015-09-17 22:23:34 +0000676}
677
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678uint32_t ClangASTContext::GetPluginVersion() { return 1; }
Greg Clayton56939cb2015-09-17 22:23:34 +0000679
Kate Stoneb9c1b512016-09-06 20:57:50 +0000680lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language,
681 lldb_private::Module *module,
682 Target *target) {
683 if (ClangASTContextSupportsLanguage(language)) {
684 ArchSpec arch;
685 if (module)
686 arch = module->GetArchitecture();
687 else if (target)
688 arch = target->GetArchitecture();
Greg Clayton56939cb2015-09-17 22:23:34 +0000689
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690 if (arch.IsValid()) {
691 ArchSpec fixed_arch = arch;
692 // LLVM wants this to be set to iOS or MacOSX; if we're working on
693 // a bare-boards type image, change the triple for llvm's benefit.
694 if (fixed_arch.GetTriple().getVendor() == llvm::Triple::Apple &&
695 fixed_arch.GetTriple().getOS() == llvm::Triple::UnknownOS) {
696 if (fixed_arch.GetTriple().getArch() == llvm::Triple::arm ||
697 fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
698 fixed_arch.GetTriple().getArch() == llvm::Triple::thumb) {
699 fixed_arch.GetTriple().setOS(llvm::Triple::IOS);
700 } else {
701 fixed_arch.GetTriple().setOS(llvm::Triple::MacOSX);
Greg Clayton56939cb2015-09-17 22:23:34 +0000702 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000703 }
Greg Clayton56939cb2015-09-17 22:23:34 +0000704
Kate Stoneb9c1b512016-09-06 20:57:50 +0000705 if (module) {
706 std::shared_ptr<ClangASTContext> ast_sp(new ClangASTContext);
707 if (ast_sp) {
708 ast_sp->SetArchitecture(fixed_arch);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000709 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000710 return ast_sp;
711 } else if (target && target->IsValid()) {
712 std::shared_ptr<ClangASTContextForExpressions> ast_sp(
713 new ClangASTContextForExpressions(*target));
714 if (ast_sp) {
715 ast_sp->SetArchitecture(fixed_arch);
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000716 ast_sp->m_scratch_ast_source_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000717 new ClangASTSource(target->shared_from_this()));
Sean Callanan68e44232017-09-28 20:20:25 +0000718 lldbassert(ast_sp->getFileManager());
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000719 ast_sp->m_scratch_ast_source_up->InstallASTContext(
Sean Callanan68e44232017-09-28 20:20:25 +0000720 *ast_sp->getASTContext(), *ast_sp->getFileManager(), true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000721 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000722 ast_sp->m_scratch_ast_source_up->CreateProxy());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723 ast_sp->SetExternalSource(proxy_ast_source);
724 return ast_sp;
725 }
726 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000728 }
729 return lldb::TypeSystemSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000730}
731
Kate Stoneb9c1b512016-09-06 20:57:50 +0000732void ClangASTContext::EnumerateSupportedLanguages(
733 std::set<lldb::LanguageType> &languages_for_types,
734 std::set<lldb::LanguageType> &languages_for_expressions) {
735 static std::vector<lldb::LanguageType> s_supported_languages_for_types(
736 {lldb::eLanguageTypeC89, lldb::eLanguageTypeC, lldb::eLanguageTypeC11,
737 lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeC99,
738 lldb::eLanguageTypeObjC, lldb::eLanguageTypeObjC_plus_plus,
739 lldb::eLanguageTypeC_plus_plus_03, lldb::eLanguageTypeC_plus_plus_11,
740 lldb::eLanguageTypeC11, lldb::eLanguageTypeC_plus_plus_14});
741
742 static std::vector<lldb::LanguageType> s_supported_languages_for_expressions(
743 {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC_plus_plus,
744 lldb::eLanguageTypeC_plus_plus_03, lldb::eLanguageTypeC_plus_plus_11,
745 lldb::eLanguageTypeC_plus_plus_14});
746
747 languages_for_types.insert(s_supported_languages_for_types.begin(),
748 s_supported_languages_for_types.end());
749 languages_for_expressions.insert(
750 s_supported_languages_for_expressions.begin(),
751 s_supported_languages_for_expressions.end());
Enrico Granata5d84a692014-08-19 21:46:37 +0000752}
753
Kate Stoneb9c1b512016-09-06 20:57:50 +0000754void ClangASTContext::Initialize() {
755 PluginManager::RegisterPlugin(GetPluginNameStatic(),
756 "clang base AST context plug-in",
757 CreateInstance, EnumerateSupportedLanguages);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000758}
759
Kate Stoneb9c1b512016-09-06 20:57:50 +0000760void ClangASTContext::Terminate() {
761 PluginManager::UnregisterPlugin(CreateInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000762}
763
Kate Stoneb9c1b512016-09-06 20:57:50 +0000764void ClangASTContext::Finalize() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000765 if (m_ast_up) {
766 GetASTMap().Erase(m_ast_up.get());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000767 if (!m_ast_owned)
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000768 m_ast_up.release();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000769 }
770
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000771 m_builtins_up.reset();
772 m_selector_table_up.reset();
773 m_identifier_table_up.reset();
774 m_target_info_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 m_target_options_rp.reset();
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000776 m_diagnostics_engine_up.reset();
777 m_source_manager_up.reset();
778 m_language_options_up.reset();
779 m_ast_up.reset();
780 m_scratch_ast_source_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000781}
782
783void ClangASTContext::Clear() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000784 m_ast_up.reset();
785 m_language_options_up.reset();
786 m_source_manager_up.reset();
787 m_diagnostics_engine_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000788 m_target_options_rp.reset();
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000789 m_target_info_up.reset();
790 m_identifier_table_up.reset();
791 m_selector_table_up.reset();
792 m_builtins_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000793 m_pointer_byte_size = 0;
794}
795
Raphael Isemannf74a4c12019-04-30 08:41:35 +0000796void ClangASTContext::setSema(Sema *s) {
797 // Ensure that the new sema actually belongs to our ASTContext.
798 assert(s == nullptr || &s->getASTContext() == m_ast_up.get());
799 m_sema = s;
800}
801
Kate Stoneb9c1b512016-09-06 20:57:50 +0000802const char *ClangASTContext::GetTargetTriple() {
803 return m_target_triple.c_str();
804}
805
806void ClangASTContext::SetTargetTriple(const char *target_triple) {
807 Clear();
808 m_target_triple.assign(target_triple);
809}
810
811void ClangASTContext::SetArchitecture(const ArchSpec &arch) {
812 SetTargetTriple(arch.GetTriple().str().c_str());
813}
814
815bool ClangASTContext::HasExternalSource() {
816 ASTContext *ast = getASTContext();
817 if (ast)
818 return ast->getExternalSource() != nullptr;
819 return false;
820}
821
822void ClangASTContext::SetExternalSource(
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000823 llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000824 ASTContext *ast = getASTContext();
825 if (ast) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000826 ast->setExternalSource(ast_source_up);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000827 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000828 }
829}
830
831void ClangASTContext::RemoveExternalSource() {
832 ASTContext *ast = getASTContext();
833
834 if (ast) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000835 llvm::IntrusiveRefCntPtr<ExternalASTSource> empty_ast_source_up;
836 ast->setExternalSource(empty_ast_source_up);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000837 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000838 }
839}
840
841void ClangASTContext::setASTContext(clang::ASTContext *ast_ctx) {
842 if (!m_ast_owned) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000843 m_ast_up.release();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000844 }
845 m_ast_owned = false;
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000846 m_ast_up.reset(ast_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000847 GetASTMap().Insert(ast_ctx, this);
848}
849
850ASTContext *ClangASTContext::getASTContext() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000851 if (m_ast_up == nullptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000852 m_ast_owned = true;
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000853 m_ast_up.reset(new ASTContext(*getLanguageOptions(), *getSourceManager(),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000854 *getIdentifierTable(), *getSelectorTable(),
855 *getBuiltinContext()));
856
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000857 m_ast_up->getDiagnostics().setClient(getDiagnosticConsumer(), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000858
859 // This can be NULL if we don't know anything about the architecture or if
Adrian Prantl05097242018-04-30 16:49:04 +0000860 // the target for an architecture isn't enabled in the llvm/clang that we
861 // built
Kate Stoneb9c1b512016-09-06 20:57:50 +0000862 TargetInfo *target_info = getTargetInfo();
863 if (target_info)
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000864 m_ast_up->InitBuiltinTypes(*target_info);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000865
866 if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000867 m_ast_up->getTranslationUnitDecl()->setHasExternalLexicalStorage();
868 // m_ast_up->getTranslationUnitDecl()->setHasExternalVisibleStorage();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000869 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000871 GetASTMap().Insert(m_ast_up.get(), this);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000873 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_up(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000874 new ClangExternalASTSourceCallbacks(
875 ClangASTContext::CompleteTagDecl,
876 ClangASTContext::CompleteObjCInterfaceDecl, nullptr,
877 ClangASTContext::LayoutRecordType, this));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000878 SetExternalSource(ast_source_up);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000879 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000880 return m_ast_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000881}
882
Kate Stoneb9c1b512016-09-06 20:57:50 +0000883ClangASTContext *ClangASTContext::GetASTContext(clang::ASTContext *ast) {
884 ClangASTContext *clang_ast = GetASTMap().Lookup(ast);
885 return clang_ast;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000886}
887
Kate Stoneb9c1b512016-09-06 20:57:50 +0000888Builtin::Context *ClangASTContext::getBuiltinContext() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000889 if (m_builtins_up == nullptr)
890 m_builtins_up.reset(new Builtin::Context());
891 return m_builtins_up.get();
Sean Callanan79439e82010-11-18 02:56:27 +0000892}
893
Kate Stoneb9c1b512016-09-06 20:57:50 +0000894IdentifierTable *ClangASTContext::getIdentifierTable() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000895 if (m_identifier_table_up == nullptr)
896 m_identifier_table_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000897 new IdentifierTable(*ClangASTContext::getLanguageOptions(), nullptr));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000898 return m_identifier_table_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000899}
900
Kate Stoneb9c1b512016-09-06 20:57:50 +0000901LangOptions *ClangASTContext::getLanguageOptions() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000902 if (m_language_options_up == nullptr) {
903 m_language_options_up.reset(new LangOptions());
Rainer Orth6ca17072019-08-05 14:00:43 +0000904 ParseLangArgs(*m_language_options_up, clang::Language::ObjCXX,
905 GetTargetTriple());
906 // InitializeLangOptions(*m_language_options_up, Language::ObjCXX);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000907 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000908 return m_language_options_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000909}
910
Kate Stoneb9c1b512016-09-06 20:57:50 +0000911SelectorTable *ClangASTContext::getSelectorTable() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000912 if (m_selector_table_up == nullptr)
913 m_selector_table_up.reset(new SelectorTable());
914 return m_selector_table_up.get();
Greg Claytonfe689042015-11-10 17:47:04 +0000915}
916
Kate Stoneb9c1b512016-09-06 20:57:50 +0000917clang::FileManager *ClangASTContext::getFileManager() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000918 if (m_file_manager_up == nullptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919 clang::FileSystemOptions file_system_options;
Jonas Devlieghere9764b652019-02-18 20:31:18 +0000920 m_file_manager_up.reset(new clang::FileManager(
921 file_system_options, FileSystem::Instance().GetVirtualFileSystem()));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000922 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000923 return m_file_manager_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000924}
925
926clang::SourceManager *ClangASTContext::getSourceManager() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000927 if (m_source_manager_up == nullptr)
928 m_source_manager_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000929 new clang::SourceManager(*getDiagnosticsEngine(), *getFileManager()));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000930 return m_source_manager_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000931}
932
933clang::DiagnosticsEngine *ClangASTContext::getDiagnosticsEngine() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000934 if (m_diagnostics_engine_up == nullptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000936 m_diagnostics_engine_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000937 new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions()));
938 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000939 return m_diagnostics_engine_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940}
941
942clang::MangleContext *ClangASTContext::getMangleContext() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000943 if (m_mangle_ctx_up == nullptr)
944 m_mangle_ctx_up.reset(getASTContext()->createMangleContext());
945 return m_mangle_ctx_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000946}
947
948class NullDiagnosticConsumer : public DiagnosticConsumer {
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000949public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000950 NullDiagnosticConsumer() {
951 m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
952 }
Sean Callanan579e70c2016-03-19 00:03:59 +0000953
Kate Stoneb9c1b512016-09-06 20:57:50 +0000954 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
Raphael Isemann17566302019-05-03 10:03:28 +0000955 const clang::Diagnostic &info) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000956 if (m_log) {
957 llvm::SmallVector<char, 32> diag_str(10);
958 info.FormatDiagnostic(diag_str);
959 diag_str.push_back('\0');
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000960 LLDB_LOGF(m_log, "Compiler diagnostic: %s\n", diag_str.data());
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000961 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000962 }
963
964 DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
965 return new NullDiagnosticConsumer();
966 }
967
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000968private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000969 Log *m_log;
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000970};
971
Kate Stoneb9c1b512016-09-06 20:57:50 +0000972DiagnosticConsumer *ClangASTContext::getDiagnosticConsumer() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000973 if (m_diagnostic_consumer_up == nullptr)
974 m_diagnostic_consumer_up.reset(new NullDiagnosticConsumer);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000975
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000976 return m_diagnostic_consumer_up.get();
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000977}
978
Kate Stoneb9c1b512016-09-06 20:57:50 +0000979std::shared_ptr<clang::TargetOptions> &ClangASTContext::getTargetOptions() {
Jonas Devlieghere70355ac2019-02-12 03:47:39 +0000980 if (m_target_options_rp == nullptr && !m_target_triple.empty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000981 m_target_options_rp = std::make_shared<clang::TargetOptions>();
Jonas Devlieghere70355ac2019-02-12 03:47:39 +0000982 if (m_target_options_rp != nullptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000983 m_target_options_rp->Triple = m_target_triple;
984 }
985 return m_target_options_rp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000986}
987
Kate Stoneb9c1b512016-09-06 20:57:50 +0000988TargetInfo *ClangASTContext::getTargetInfo() {
989 // target_triple should be something like "x86_64-apple-macosx"
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000990 if (m_target_info_up == nullptr && !m_target_triple.empty())
991 m_target_info_up.reset(TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000992 getTargetOptions()));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000993 return m_target_info_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000994}
995
996#pragma mark Basic Types
997
Kate Stoneb9c1b512016-09-06 20:57:50 +0000998static inline bool QualTypeMatchesBitSize(const uint64_t bit_size,
999 ASTContext *ast, QualType qual_type) {
1000 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001001 return qual_type_bit_size == bit_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001002}
Greg Clayton56939cb2015-09-17 22:23:34 +00001003
Greg Claytona1e5dc82015-08-11 22:53:00 +00001004CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
1006 size_t bit_size) {
1007 return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
1008 getASTContext(), encoding, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009}
1010
Kate Stoneb9c1b512016-09-06 20:57:50 +00001011CompilerType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
1012 ASTContext *ast, Encoding encoding, uint32_t bit_size) {
1013 if (!ast)
Greg Claytona1e5dc82015-08-11 22:53:00 +00001014 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 switch (encoding) {
1016 case eEncodingInvalid:
1017 if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
1018 return CompilerType(ast, ast->VoidPtrTy);
1019 break;
1020
1021 case eEncodingUint:
1022 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
1023 return CompilerType(ast, ast->UnsignedCharTy);
1024 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
1025 return CompilerType(ast, ast->UnsignedShortTy);
1026 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
1027 return CompilerType(ast, ast->UnsignedIntTy);
1028 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
1029 return CompilerType(ast, ast->UnsignedLongTy);
1030 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
1031 return CompilerType(ast, ast->UnsignedLongLongTy);
1032 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
1033 return CompilerType(ast, ast->UnsignedInt128Ty);
1034 break;
1035
1036 case eEncodingSint:
1037 if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
1038 return CompilerType(ast, ast->SignedCharTy);
1039 if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
1040 return CompilerType(ast, ast->ShortTy);
1041 if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
1042 return CompilerType(ast, ast->IntTy);
1043 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
1044 return CompilerType(ast, ast->LongTy);
1045 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
1046 return CompilerType(ast, ast->LongLongTy);
1047 if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
1048 return CompilerType(ast, ast->Int128Ty);
1049 break;
1050
1051 case eEncodingIEEE754:
1052 if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
1053 return CompilerType(ast, ast->FloatTy);
1054 if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
1055 return CompilerType(ast, ast->DoubleTy);
1056 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
1057 return CompilerType(ast, ast->LongDoubleTy);
1058 if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
1059 return CompilerType(ast, ast->HalfTy);
1060 break;
1061
1062 case eEncodingVector:
1063 // Sanity check that bit_size is a multiple of 8's.
1064 if (bit_size && !(bit_size & 0x7u))
1065 return CompilerType(
1066 ast, ast->getExtVectorType(ast->UnsignedCharTy, bit_size / 8));
1067 break;
1068 }
1069
1070 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001071}
1072
Greg Clayton57ee3062013-07-11 22:46:58 +00001073lldb::BasicType
Adrian Prantl0e4c4822019-03-06 21:22:25 +00001074ClangASTContext::GetBasicTypeEnumeration(ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001075 if (name) {
1076 typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
1077 static TypeNameToBasicTypeMap g_type_map;
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +00001078 static llvm::once_flag g_once_flag;
1079 llvm::call_once(g_once_flag, []() {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001080 // "void"
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001081 g_type_map.Append(ConstString("void"), eBasicTypeVoid);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001082
1083 // "char"
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001084 g_type_map.Append(ConstString("char"), eBasicTypeChar);
1085 g_type_map.Append(ConstString("signed char"), eBasicTypeSignedChar);
1086 g_type_map.Append(ConstString("unsigned char"), eBasicTypeUnsignedChar);
1087 g_type_map.Append(ConstString("wchar_t"), eBasicTypeWChar);
1088 g_type_map.Append(ConstString("signed wchar_t"), eBasicTypeSignedWChar);
1089 g_type_map.Append(ConstString("unsigned wchar_t"),
Kate Stoneb9c1b512016-09-06 20:57:50 +00001090 eBasicTypeUnsignedWChar);
1091 // "short"
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001092 g_type_map.Append(ConstString("short"), eBasicTypeShort);
1093 g_type_map.Append(ConstString("short int"), eBasicTypeShort);
1094 g_type_map.Append(ConstString("unsigned short"), eBasicTypeUnsignedShort);
1095 g_type_map.Append(ConstString("unsigned short int"),
Kate Stoneb9c1b512016-09-06 20:57:50 +00001096 eBasicTypeUnsignedShort);
1097
1098 // "int"
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001099 g_type_map.Append(ConstString("int"), eBasicTypeInt);
1100 g_type_map.Append(ConstString("signed int"), eBasicTypeInt);
1101 g_type_map.Append(ConstString("unsigned int"), eBasicTypeUnsignedInt);
1102 g_type_map.Append(ConstString("unsigned"), eBasicTypeUnsignedInt);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001103
1104 // "long"
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001105 g_type_map.Append(ConstString("long"), eBasicTypeLong);
1106 g_type_map.Append(ConstString("long int"), eBasicTypeLong);
1107 g_type_map.Append(ConstString("unsigned long"), eBasicTypeUnsignedLong);
1108 g_type_map.Append(ConstString("unsigned long int"),
Kate Stoneb9c1b512016-09-06 20:57:50 +00001109 eBasicTypeUnsignedLong);
1110
1111 // "long long"
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001112 g_type_map.Append(ConstString("long long"), eBasicTypeLongLong);
1113 g_type_map.Append(ConstString("long long int"), eBasicTypeLongLong);
1114 g_type_map.Append(ConstString("unsigned long long"),
Kate Stoneb9c1b512016-09-06 20:57:50 +00001115 eBasicTypeUnsignedLongLong);
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001116 g_type_map.Append(ConstString("unsigned long long int"),
Kate Stoneb9c1b512016-09-06 20:57:50 +00001117 eBasicTypeUnsignedLongLong);
1118
1119 // "int128"
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001120 g_type_map.Append(ConstString("__int128_t"), eBasicTypeInt128);
1121 g_type_map.Append(ConstString("__uint128_t"), eBasicTypeUnsignedInt128);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001122
1123 // Miscellaneous
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001124 g_type_map.Append(ConstString("bool"), eBasicTypeBool);
1125 g_type_map.Append(ConstString("float"), eBasicTypeFloat);
1126 g_type_map.Append(ConstString("double"), eBasicTypeDouble);
1127 g_type_map.Append(ConstString("long double"), eBasicTypeLongDouble);
1128 g_type_map.Append(ConstString("id"), eBasicTypeObjCID);
1129 g_type_map.Append(ConstString("SEL"), eBasicTypeObjCSel);
1130 g_type_map.Append(ConstString("nullptr"), eBasicTypeNullPtr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001131 g_type_map.Sort();
1132 });
1133
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001134 return g_type_map.Find(name, eBasicTypeInvalid);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001135 }
1136 return eBasicTypeInvalid;
Greg Clayton57ee3062013-07-11 22:46:58 +00001137}
1138
Kate Stoneb9c1b512016-09-06 20:57:50 +00001139CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
Adrian Prantl0e4c4822019-03-06 21:22:25 +00001140 ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001141 if (ast) {
1142 lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration(name);
1143 return ClangASTContext::GetBasicType(ast, basic_type);
1144 }
1145 return CompilerType();
1146}
1147
1148uint32_t ClangASTContext::GetPointerByteSize() {
1149 if (m_pointer_byte_size == 0)
Adrian Prantld963a7c2019-01-15 18:07:52 +00001150 if (auto size = GetBasicType(lldb::eBasicTypeVoid)
1151 .GetPointerType()
1152 .GetByteSize(nullptr))
1153 m_pointer_byte_size = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154 return m_pointer_byte_size;
1155}
1156
1157CompilerType ClangASTContext::GetBasicType(lldb::BasicType basic_type) {
1158 return GetBasicType(getASTContext(), basic_type);
1159}
1160
1161CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
1162 lldb::BasicType basic_type) {
1163 if (!ast)
Greg Claytona1e5dc82015-08-11 22:53:00 +00001164 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001165 lldb::opaque_compiler_type_t clang_type =
1166 GetOpaqueCompilerType(ast, basic_type);
1167
1168 if (clang_type)
1169 return CompilerType(GetASTContext(ast), clang_type);
1170 return CompilerType();
Greg Clayton57ee3062013-07-11 22:46:58 +00001171}
1172
Kate Stoneb9c1b512016-09-06 20:57:50 +00001173CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
1174 const char *type_name, uint32_t dw_ate, uint32_t bit_size) {
1175 ASTContext *ast = getASTContext();
Greg Clayton57ee3062013-07-11 22:46:58 +00001176
Kate Stoneb9c1b512016-09-06 20:57:50 +00001177#define streq(a, b) strcmp(a, b) == 0
1178 assert(ast != nullptr);
1179 if (ast) {
1180 switch (dw_ate) {
1181 default:
1182 break;
Greg Clayton57ee3062013-07-11 22:46:58 +00001183
Kate Stoneb9c1b512016-09-06 20:57:50 +00001184 case DW_ATE_address:
1185 if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
1186 return CompilerType(ast, ast->VoidPtrTy);
1187 break;
Zachary Turner9d8a97e2016-04-01 23:20:35 +00001188
Kate Stoneb9c1b512016-09-06 20:57:50 +00001189 case DW_ATE_boolean:
1190 if (QualTypeMatchesBitSize(bit_size, ast, ast->BoolTy))
1191 return CompilerType(ast, ast->BoolTy);
1192 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
1193 return CompilerType(ast, ast->UnsignedCharTy);
1194 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
1195 return CompilerType(ast, ast->UnsignedShortTy);
1196 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
1197 return CompilerType(ast, ast->UnsignedIntTy);
1198 break;
Greg Clayton57ee3062013-07-11 22:46:58 +00001199
Kate Stoneb9c1b512016-09-06 20:57:50 +00001200 case DW_ATE_lo_user:
1201 // This has been seen to mean DW_AT_complex_integer
1202 if (type_name) {
1203 if (::strstr(type_name, "complex")) {
1204 CompilerType complex_int_clang_type =
1205 GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed,
1206 bit_size / 2);
1207 return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(
1208 complex_int_clang_type)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001210 }
1211 break;
1212
1213 case DW_ATE_complex_float:
1214 if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatComplexTy))
1215 return CompilerType(ast, ast->FloatComplexTy);
1216 else if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleComplexTy))
1217 return CompilerType(ast, ast->DoubleComplexTy);
1218 else if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleComplexTy))
1219 return CompilerType(ast, ast->LongDoubleComplexTy);
1220 else {
1221 CompilerType complex_float_clang_type =
1222 GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float,
1223 bit_size / 2);
1224 return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(
1225 complex_float_clang_type)));
1226 }
1227 break;
1228
1229 case DW_ATE_float:
1230 if (streq(type_name, "float") &&
1231 QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
1232 return CompilerType(ast, ast->FloatTy);
1233 if (streq(type_name, "double") &&
1234 QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
1235 return CompilerType(ast, ast->DoubleTy);
1236 if (streq(type_name, "long double") &&
1237 QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
1238 return CompilerType(ast, ast->LongDoubleTy);
1239 // Fall back to not requiring a name match
1240 if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
1241 return CompilerType(ast, ast->FloatTy);
1242 if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
1243 return CompilerType(ast, ast->DoubleTy);
1244 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
1245 return CompilerType(ast, ast->LongDoubleTy);
1246 if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
1247 return CompilerType(ast, ast->HalfTy);
1248 break;
1249
1250 case DW_ATE_signed:
1251 if (type_name) {
1252 if (streq(type_name, "wchar_t") &&
1253 QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy) &&
1254 (getTargetInfo() &&
1255 TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
1256 return CompilerType(ast, ast->WCharTy);
1257 if (streq(type_name, "void") &&
1258 QualTypeMatchesBitSize(bit_size, ast, ast->VoidTy))
1259 return CompilerType(ast, ast->VoidTy);
1260 if (strstr(type_name, "long long") &&
1261 QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
1262 return CompilerType(ast, ast->LongLongTy);
1263 if (strstr(type_name, "long") &&
1264 QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
1265 return CompilerType(ast, ast->LongTy);
1266 if (strstr(type_name, "short") &&
1267 QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
1268 return CompilerType(ast, ast->ShortTy);
1269 if (strstr(type_name, "char")) {
1270 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
1271 return CompilerType(ast, ast->CharTy);
1272 if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
1273 return CompilerType(ast, ast->SignedCharTy);
1274 }
1275 if (strstr(type_name, "int")) {
1276 if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
1277 return CompilerType(ast, ast->IntTy);
1278 if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
1279 return CompilerType(ast, ast->Int128Ty);
1280 }
1281 }
1282 // We weren't able to match up a type name, just search by size
1283 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
1284 return CompilerType(ast, ast->CharTy);
1285 if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
1286 return CompilerType(ast, ast->ShortTy);
1287 if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
1288 return CompilerType(ast, ast->IntTy);
1289 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
1290 return CompilerType(ast, ast->LongTy);
1291 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
1292 return CompilerType(ast, ast->LongLongTy);
1293 if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
1294 return CompilerType(ast, ast->Int128Ty);
1295 break;
1296
1297 case DW_ATE_signed_char:
1298 if (ast->getLangOpts().CharIsSigned && type_name &&
1299 streq(type_name, "char")) {
1300 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
1301 return CompilerType(ast, ast->CharTy);
1302 }
1303 if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
1304 return CompilerType(ast, ast->SignedCharTy);
1305 break;
1306
1307 case DW_ATE_unsigned:
1308 if (type_name) {
1309 if (streq(type_name, "wchar_t")) {
1310 if (QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy)) {
1311 if (!(getTargetInfo() &&
1312 TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
1313 return CompilerType(ast, ast->WCharTy);
1314 }
1315 }
1316 if (strstr(type_name, "long long")) {
1317 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
1318 return CompilerType(ast, ast->UnsignedLongLongTy);
1319 } else if (strstr(type_name, "long")) {
1320 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
1321 return CompilerType(ast, ast->UnsignedLongTy);
1322 } else if (strstr(type_name, "short")) {
1323 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
1324 return CompilerType(ast, ast->UnsignedShortTy);
1325 } else if (strstr(type_name, "char")) {
1326 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
1327 return CompilerType(ast, ast->UnsignedCharTy);
1328 } else if (strstr(type_name, "int")) {
1329 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
1330 return CompilerType(ast, ast->UnsignedIntTy);
1331 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
1332 return CompilerType(ast, ast->UnsignedInt128Ty);
1333 }
1334 }
1335 // We weren't able to match up a type name, just search by size
1336 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
1337 return CompilerType(ast, ast->UnsignedCharTy);
1338 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
1339 return CompilerType(ast, ast->UnsignedShortTy);
1340 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
1341 return CompilerType(ast, ast->UnsignedIntTy);
1342 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
1343 return CompilerType(ast, ast->UnsignedLongTy);
1344 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
1345 return CompilerType(ast, ast->UnsignedLongLongTy);
1346 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
1347 return CompilerType(ast, ast->UnsignedInt128Ty);
1348 break;
1349
1350 case DW_ATE_unsigned_char:
1351 if (!ast->getLangOpts().CharIsSigned && type_name &&
1352 streq(type_name, "char")) {
1353 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
1354 return CompilerType(ast, ast->CharTy);
1355 }
1356 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
1357 return CompilerType(ast, ast->UnsignedCharTy);
1358 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
1359 return CompilerType(ast, ast->UnsignedShortTy);
1360 break;
1361
1362 case DW_ATE_imaginary_float:
1363 break;
1364
1365 case DW_ATE_UTF:
1366 if (type_name) {
1367 if (streq(type_name, "char16_t")) {
1368 return CompilerType(ast, ast->Char16Ty);
1369 } else if (streq(type_name, "char32_t")) {
1370 return CompilerType(ast, ast->Char32Ty);
1371 }
1372 }
1373 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001374 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001375 }
1376 // This assert should fire for anything that we don't catch above so we know
1377 // to fix any issues we run into.
1378 if (type_name) {
1379 Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
1380 "DW_TAG_base_type '%s' encoded with "
1381 "DW_ATE = 0x%x, bit_size = %u\n",
1382 type_name, dw_ate, bit_size);
1383 } else {
1384 Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
1385 "DW_TAG_base_type encoded with "
1386 "DW_ATE = 0x%x, bit_size = %u\n",
1387 dw_ate, bit_size);
1388 }
1389 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001390}
1391
Kate Stoneb9c1b512016-09-06 20:57:50 +00001392CompilerType ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast) {
1393 if (ast)
1394 return CompilerType(ast, ast->UnknownAnyTy);
1395 return CompilerType();
Sean Callanan77502262011-05-12 23:54:16 +00001396}
1397
Kate Stoneb9c1b512016-09-06 20:57:50 +00001398CompilerType ClangASTContext::GetCStringType(bool is_const) {
1399 ASTContext *ast = getASTContext();
1400 QualType char_type(ast->CharTy);
1401
1402 if (is_const)
1403 char_type.addConst();
1404
1405 return CompilerType(ast, ast->getPointerType(char_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001406}
1407
Zachary Turner115209e2018-11-05 19:25:39 +00001408clang::DeclContext *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001409ClangASTContext::GetTranslationUnitDecl(clang::ASTContext *ast) {
1410 return ast->getTranslationUnitDecl();
Sean Callanan09ab4b72011-11-30 22:11:59 +00001411}
1412
Kate Stoneb9c1b512016-09-06 20:57:50 +00001413clang::Decl *ClangASTContext::CopyDecl(ASTContext *dst_ast, ASTContext *src_ast,
1414 clang::Decl *source_decl) {
1415 FileSystemOptions file_system_options;
1416 FileManager file_manager(file_system_options);
1417 ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager, false);
1418
Gabor Marton5ac6d492019-05-15 10:29:48 +00001419 if (llvm::Expected<clang::Decl *> ret_or_error =
1420 importer.Import(source_decl)) {
1421 return *ret_or_error;
1422 } else {
1423 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
1424 LLDB_LOG_ERROR(log, ret_or_error.takeError(), "Couldn't import decl: {0}");
1425 return nullptr;
1426 }
Greg Clayton526e5af2010-11-13 03:52:47 +00001427}
1428
Kate Stoneb9c1b512016-09-06 20:57:50 +00001429bool ClangASTContext::AreTypesSame(CompilerType type1, CompilerType type2,
1430 bool ignore_qualifiers) {
1431 ClangASTContext *ast =
1432 llvm::dyn_cast_or_null<ClangASTContext>(type1.GetTypeSystem());
1433 if (!ast || ast != type2.GetTypeSystem())
1434 return false;
Greg Clayton57ee3062013-07-11 22:46:58 +00001435
Kate Stoneb9c1b512016-09-06 20:57:50 +00001436 if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
1437 return true;
Greg Clayton55995eb2012-04-06 17:38:55 +00001438
Kate Stoneb9c1b512016-09-06 20:57:50 +00001439 QualType type1_qual = ClangUtil::GetQualType(type1);
1440 QualType type2_qual = ClangUtil::GetQualType(type2);
Zachary Turnerd133f6a2016-03-28 22:53:41 +00001441
Kate Stoneb9c1b512016-09-06 20:57:50 +00001442 if (ignore_qualifiers) {
1443 type1_qual = type1_qual.getUnqualifiedType();
1444 type2_qual = type2_qual.getUnqualifiedType();
1445 }
1446
1447 return ast->getASTContext()->hasSameType(type1_qual, type2_qual);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001448}
1449
Kate Stoneb9c1b512016-09-06 20:57:50 +00001450CompilerType ClangASTContext::GetTypeForDecl(clang::NamedDecl *decl) {
1451 if (clang::ObjCInterfaceDecl *interface_decl =
1452 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
1453 return GetTypeForDecl(interface_decl);
1454 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
1455 return GetTypeForDecl(tag_decl);
1456 return CompilerType();
Sean Callanan9998acd2014-12-05 01:21:59 +00001457}
1458
Kate Stoneb9c1b512016-09-06 20:57:50 +00001459CompilerType ClangASTContext::GetTypeForDecl(TagDecl *decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00001460 // No need to call the getASTContext() accessor (which can create the AST if
1461 // it isn't created yet, because we can't have created a decl in this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001462 // AST if our AST didn't already exist...
1463 ASTContext *ast = &decl->getASTContext();
1464 if (ast)
1465 return CompilerType(ast, ast->getTagDeclType(decl));
1466 return CompilerType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00001467}
1468
Kate Stoneb9c1b512016-09-06 20:57:50 +00001469CompilerType ClangASTContext::GetTypeForDecl(ObjCInterfaceDecl *decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00001470 // No need to call the getASTContext() accessor (which can create the AST if
1471 // it isn't created yet, because we can't have created a decl in this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001472 // AST if our AST didn't already exist...
1473 ASTContext *ast = &decl->getASTContext();
1474 if (ast)
1475 return CompilerType(ast, ast->getObjCInterfaceType(decl));
1476 return CompilerType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00001477}
1478
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001479#pragma mark Structure, Unions, Classes
1480
Kate Stoneb9c1b512016-09-06 20:57:50 +00001481CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx,
1482 AccessType access_type,
1483 const char *name, int kind,
1484 LanguageType language,
1485 ClangASTMetadata *metadata) {
1486 ASTContext *ast = getASTContext();
1487 assert(ast != nullptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001488
Kate Stoneb9c1b512016-09-06 20:57:50 +00001489 if (decl_ctx == nullptr)
1490 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton9e409562010-07-28 02:04:09 +00001491
Kate Stoneb9c1b512016-09-06 20:57:50 +00001492 if (language == eLanguageTypeObjC ||
1493 language == eLanguageTypeObjC_plus_plus) {
1494 bool isForwardDecl = true;
1495 bool isInternal = false;
1496 return CreateObjCClass(name, decl_ctx, isForwardDecl, isInternal, metadata);
1497 }
Greg Clayton9e409562010-07-28 02:04:09 +00001498
Kate Stoneb9c1b512016-09-06 20:57:50 +00001499 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
Adrian Prantl05097242018-04-30 16:49:04 +00001500 // we will need to update this code. I was told to currently always use the
1501 // CXXRecordDecl class since we often don't know from debug information if
1502 // something is struct or a class, so we default to always use the more
Kate Stoneb9c1b512016-09-06 20:57:50 +00001503 // complete definition just in case.
Greg Claytonc4ffd662013-03-08 01:37:30 +00001504
Kate Stoneb9c1b512016-09-06 20:57:50 +00001505 bool is_anonymous = (!name) || (!name[0]);
Greg Claytonc4ffd662013-03-08 01:37:30 +00001506
Kate Stoneb9c1b512016-09-06 20:57:50 +00001507 CXXRecordDecl *decl = CXXRecordDecl::Create(
1508 *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
1509 SourceLocation(), is_anonymous ? nullptr : &ast->Idents.get(name));
1510
1511 if (is_anonymous)
1512 decl->setAnonymousStructOrUnion(true);
1513
1514 if (decl) {
1515 if (metadata)
1516 SetMetadata(ast, decl, *metadata);
1517
1518 if (access_type != eAccessNone)
1519 decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type));
1520
1521 if (decl_ctx)
1522 decl_ctx->addDecl(decl);
1523
1524 return CompilerType(ast, ast->getTagDeclType(decl));
1525 }
1526 return CompilerType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00001527}
1528
Sean Callanan09e91ac2017-05-11 22:08:05 +00001529namespace {
1530 bool IsValueParam(const clang::TemplateArgument &argument) {
1531 return argument.getKind() == TemplateArgument::Integral;
1532 }
1533}
1534
Kate Stoneb9c1b512016-09-06 20:57:50 +00001535static TemplateParameterList *CreateTemplateParameterList(
1536 ASTContext *ast,
1537 const ClangASTContext::TemplateParameterInfos &template_param_infos,
1538 llvm::SmallVector<NamedDecl *, 8> &template_param_decls) {
1539 const bool parameter_pack = false;
1540 const bool is_typename = false;
1541 const unsigned depth = 0;
Sean Callanan09e91ac2017-05-11 22:08:05 +00001542 const size_t num_template_params = template_param_infos.args.size();
1543 DeclContext *const decl_context =
1544 ast->getTranslationUnitDecl(); // Is this the right decl context?,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001545 for (size_t i = 0; i < num_template_params; ++i) {
1546 const char *name = template_param_infos.names[i];
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001547
Kate Stoneb9c1b512016-09-06 20:57:50 +00001548 IdentifierInfo *identifier_info = nullptr;
1549 if (name && name[0])
1550 identifier_info = &ast->Idents.get(name);
Sean Callanan09e91ac2017-05-11 22:08:05 +00001551 if (IsValueParam(template_param_infos.args[i])) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001552 template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
Sean Callanan09e91ac2017-05-11 22:08:05 +00001553 *ast, decl_context,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001554 SourceLocation(), SourceLocation(), depth, i, identifier_info,
1555 template_param_infos.args[i].getIntegralType(), parameter_pack,
1556 nullptr));
1557
1558 } else {
1559 template_param_decls.push_back(TemplateTypeParmDecl::Create(
Sean Callanan09e91ac2017-05-11 22:08:05 +00001560 *ast, decl_context,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001561 SourceLocation(), SourceLocation(), depth, i, identifier_info,
1562 is_typename, parameter_pack));
1563 }
1564 }
Eugene Zemtsova9d928c2017-09-29 03:15:08 +00001565
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001566 if (template_param_infos.packed_args) {
Sean Callanan09e91ac2017-05-11 22:08:05 +00001567 IdentifierInfo *identifier_info = nullptr;
1568 if (template_param_infos.pack_name && template_param_infos.pack_name[0])
1569 identifier_info = &ast->Idents.get(template_param_infos.pack_name);
1570 const bool parameter_pack_true = true;
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001571
1572 if (!template_param_infos.packed_args->args.empty() &&
1573 IsValueParam(template_param_infos.packed_args->args[0])) {
Sean Callanan09e91ac2017-05-11 22:08:05 +00001574 template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001575 *ast, decl_context, SourceLocation(), SourceLocation(), depth,
1576 num_template_params, identifier_info,
Sean Callanan09e91ac2017-05-11 22:08:05 +00001577 template_param_infos.packed_args->args[0].getIntegralType(),
1578 parameter_pack_true, nullptr));
1579 } else {
1580 template_param_decls.push_back(TemplateTypeParmDecl::Create(
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001581 *ast, decl_context, SourceLocation(), SourceLocation(), depth,
1582 num_template_params, identifier_info, is_typename,
1583 parameter_pack_true));
Sean Callanan09e91ac2017-05-11 22:08:05 +00001584 }
1585 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001586 clang::Expr *const requires_clause = nullptr; // TODO: Concepts
1587 TemplateParameterList *template_param_list = TemplateParameterList::Create(
1588 *ast, SourceLocation(), SourceLocation(), template_param_decls,
1589 SourceLocation(), requires_clause);
1590 return template_param_list;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001591}
1592
Kate Stoneb9c1b512016-09-06 20:57:50 +00001593clang::FunctionTemplateDecl *ClangASTContext::CreateFunctionTemplateDecl(
1594 clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl,
1595 const char *name, const TemplateParameterInfos &template_param_infos) {
Adrian Prantld8f460e2018-05-02 16:55:16 +00001596 // /// Create a function template node.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001597 ASTContext *ast = getASTContext();
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001598
Kate Stoneb9c1b512016-09-06 20:57:50 +00001599 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001600
Kate Stoneb9c1b512016-09-06 20:57:50 +00001601 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1602 ast, template_param_infos, template_param_decls);
1603 FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create(
1604 *ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(),
1605 template_param_list, func_decl);
1606
1607 for (size_t i = 0, template_param_decl_count = template_param_decls.size();
1608 i < template_param_decl_count; ++i) {
1609 // TODO: verify which decl context we should put template_param_decls into..
1610 template_param_decls[i]->setDeclContext(func_decl);
1611 }
1612
1613 return func_tmpl_decl;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001614}
1615
Kate Stoneb9c1b512016-09-06 20:57:50 +00001616void ClangASTContext::CreateFunctionTemplateSpecializationInfo(
1617 FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl,
1618 const TemplateParameterInfos &infos) {
Shafik Yaghmoura0858e22019-07-17 20:16:13 +00001619 TemplateArgumentList *template_args_ptr =
1620 TemplateArgumentList::CreateCopy(func_decl->getASTContext(), infos.args);
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001621
Shafik Yaghmoura0858e22019-07-17 20:16:13 +00001622 func_decl->setFunctionTemplateSpecialization(func_tmpl_decl,
1623 template_args_ptr, nullptr);
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001624}
1625
Kate Stoneb9c1b512016-09-06 20:57:50 +00001626ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl(
1627 DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name,
1628 int kind, const TemplateParameterInfos &template_param_infos) {
1629 ASTContext *ast = getASTContext();
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001630
Kate Stoneb9c1b512016-09-06 20:57:50 +00001631 ClassTemplateDecl *class_template_decl = nullptr;
1632 if (decl_ctx == nullptr)
1633 decl_ctx = ast->getTranslationUnitDecl();
Greg Claytonf0705c82011-10-22 03:33:13 +00001634
Kate Stoneb9c1b512016-09-06 20:57:50 +00001635 IdentifierInfo &identifier_info = ast->Idents.get(class_name);
1636 DeclarationName decl_name(&identifier_info);
Greg Claytonf0705c82011-10-22 03:33:13 +00001637
Kate Stoneb9c1b512016-09-06 20:57:50 +00001638 clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
Greg Claytonf0705c82011-10-22 03:33:13 +00001639
Kate Stoneb9c1b512016-09-06 20:57:50 +00001640 for (NamedDecl *decl : result) {
1641 class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
Greg Claytonf0705c82011-10-22 03:33:13 +00001642 if (class_template_decl)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001643 return class_template_decl;
1644 }
1645
1646 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
1647
1648 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1649 ast, template_param_infos, template_param_decls);
1650
1651 CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create(
1652 *ast, (TagDecl::TagKind)kind,
1653 decl_ctx, // What decl context do we use here? TU? The actual decl
1654 // context?
1655 SourceLocation(), SourceLocation(), &identifier_info);
1656
1657 for (size_t i = 0, template_param_decl_count = template_param_decls.size();
1658 i < template_param_decl_count; ++i) {
1659 template_param_decls[i]->setDeclContext(template_cxx_decl);
1660 }
1661
1662 // With templated classes, we say that a class is templated with
1663 // specializations, but that the bare class has no functions.
1664 // template_cxx_decl->startDefinition();
1665 // template_cxx_decl->completeDefinition();
1666
1667 class_template_decl = ClassTemplateDecl::Create(
1668 *ast,
1669 decl_ctx, // What decl context do we use here? TU? The actual decl
1670 // context?
Pavel Labath4294de32017-01-12 10:44:16 +00001671 SourceLocation(), decl_name, template_param_list, template_cxx_decl);
Richard Smith35b007e2019-02-15 21:48:09 +00001672 template_cxx_decl->setDescribedClassTemplate(class_template_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001673
1674 if (class_template_decl) {
1675 if (access_type != eAccessNone)
1676 class_template_decl->setAccess(
1677 ConvertAccessTypeToAccessSpecifier(access_type));
1678
1679 // if (TagDecl *ctx_tag_decl = dyn_cast<TagDecl>(decl_ctx))
1680 // CompleteTagDeclarationDefinition(GetTypeForDecl(ctx_tag_decl));
1681
1682 decl_ctx->addDecl(class_template_decl);
1683
Sean Callanan5e9e1992011-10-26 01:06:27 +00001684#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00001685 VerifyDecl(class_template_decl);
Sean Callanan5e9e1992011-10-26 01:06:27 +00001686#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00001687 }
Greg Claytonf0705c82011-10-22 03:33:13 +00001688
Kate Stoneb9c1b512016-09-06 20:57:50 +00001689 return class_template_decl;
Greg Claytonf0705c82011-10-22 03:33:13 +00001690}
1691
Frederic Rissf4e7e522018-04-02 16:18:32 +00001692TemplateTemplateParmDecl *
1693ClangASTContext::CreateTemplateTemplateParmDecl(const char *template_name) {
1694 ASTContext *ast = getASTContext();
1695
1696 auto *decl_ctx = ast->getTranslationUnitDecl();
1697
1698 IdentifierInfo &identifier_info = ast->Idents.get(template_name);
1699 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
1700
1701 ClangASTContext::TemplateParameterInfos template_param_infos;
1702 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1703 ast, template_param_infos, template_param_decls);
1704
1705 // LLDB needs to create those decls only to be able to display a
Adrian Prantl05097242018-04-30 16:49:04 +00001706 // type that includes a template template argument. Only the name matters for
1707 // this purpose, so we use dummy values for the other characterisitcs of the
1708 // type.
Frederic Rissf4e7e522018-04-02 16:18:32 +00001709 return TemplateTemplateParmDecl::Create(
1710 *ast, decl_ctx, SourceLocation(),
1711 /*Depth*/ 0, /*Position*/ 0,
1712 /*IsParameterPack*/ false, &identifier_info, template_param_list);
1713}
1714
Greg Claytonf0705c82011-10-22 03:33:13 +00001715ClassTemplateSpecializationDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001716ClangASTContext::CreateClassTemplateSpecializationDecl(
1717 DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
1718 const TemplateParameterInfos &template_param_infos) {
1719 ASTContext *ast = getASTContext();
Sean Callanan09e91ac2017-05-11 22:08:05 +00001720 llvm::SmallVector<clang::TemplateArgument, 2> args(
1721 template_param_infos.args.size() +
1722 (template_param_infos.packed_args ? 1 : 0));
1723 std::copy(template_param_infos.args.begin(), template_param_infos.args.end(),
1724 args.begin());
1725 if (template_param_infos.packed_args) {
1726 args[args.size() - 1] = TemplateArgument::CreatePackCopy(
1727 *ast, template_param_infos.packed_args->args);
1728 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001729 ClassTemplateSpecializationDecl *class_template_specialization_decl =
1730 ClassTemplateSpecializationDecl::Create(
1731 *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
Sean Callanan09e91ac2017-05-11 22:08:05 +00001732 SourceLocation(), class_template_decl, args,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001733 nullptr);
1734
1735 class_template_specialization_decl->setSpecializationKind(
1736 TSK_ExplicitSpecialization);
1737
1738 return class_template_specialization_decl;
1739}
1740
1741CompilerType ClangASTContext::CreateClassTemplateSpecializationType(
1742 ClassTemplateSpecializationDecl *class_template_specialization_decl) {
1743 if (class_template_specialization_decl) {
Greg Claytonf0705c82011-10-22 03:33:13 +00001744 ASTContext *ast = getASTContext();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001745 if (ast)
1746 return CompilerType(
1747 ast, ast->getTagDeclType(class_template_specialization_decl));
1748 }
1749 return CompilerType();
Greg Claytonf0705c82011-10-22 03:33:13 +00001750}
1751
Kate Stoneb9c1b512016-09-06 20:57:50 +00001752static inline bool check_op_param(bool is_method,
1753 clang::OverloadedOperatorKind op_kind,
1754 bool unary, bool binary,
1755 uint32_t num_params) {
1756 // Special-case call since it can take any number of operands
1757 if (op_kind == OO_Call)
1758 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001759
Kate Stoneb9c1b512016-09-06 20:57:50 +00001760 // The parameter count doesn't include "this"
1761 if (is_method)
1762 ++num_params;
1763 if (num_params == 1)
1764 return unary;
1765 if (num_params == 2)
1766 return binary;
1767 else
Greg Clayton090d0982011-06-19 03:43:27 +00001768 return false;
1769}
Daniel Dunbardacdfb52011-10-31 22:50:57 +00001770
Kate Stoneb9c1b512016-09-06 20:57:50 +00001771bool ClangASTContext::CheckOverloadedOperatorKindParameterCount(
1772 bool is_method, clang::OverloadedOperatorKind op_kind,
1773 uint32_t num_params) {
1774 switch (op_kind) {
1775 default:
1776 break;
1777 // C++ standard allows any number of arguments to new/delete
1778 case OO_New:
1779 case OO_Array_New:
1780 case OO_Delete:
1781 case OO_Array_Delete:
1782 return true;
1783 }
Pavel Labath1ac2b202016-08-15 14:32:32 +00001784
Kate Stoneb9c1b512016-09-06 20:57:50 +00001785#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
1786 case OO_##Name: \
1787 return check_op_param(is_method, op_kind, Unary, Binary, num_params);
1788 switch (op_kind) {
Greg Clayton090d0982011-06-19 03:43:27 +00001789#include "clang/Basic/OperatorKinds.def"
Kate Stoneb9c1b512016-09-06 20:57:50 +00001790 default:
1791 break;
1792 }
1793 return false;
Greg Clayton090d0982011-06-19 03:43:27 +00001794}
1795
Greg Clayton57ee3062013-07-11 22:46:58 +00001796clang::AccessSpecifier
Kate Stoneb9c1b512016-09-06 20:57:50 +00001797ClangASTContext::UnifyAccessSpecifiers(clang::AccessSpecifier lhs,
1798 clang::AccessSpecifier rhs) {
1799 // Make the access equal to the stricter of the field and the nested field's
1800 // access
1801 if (lhs == AS_none || rhs == AS_none)
1802 return AS_none;
1803 if (lhs == AS_private || rhs == AS_private)
1804 return AS_private;
1805 if (lhs == AS_protected || rhs == AS_protected)
1806 return AS_protected;
1807 return AS_public;
Sean Callanane8c0cfb2012-03-02 01:03:45 +00001808}
1809
Kate Stoneb9c1b512016-09-06 20:57:50 +00001810bool ClangASTContext::FieldIsBitfield(FieldDecl *field,
1811 uint32_t &bitfield_bit_size) {
1812 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001813}
1814
Kate Stoneb9c1b512016-09-06 20:57:50 +00001815bool ClangASTContext::FieldIsBitfield(ASTContext *ast, FieldDecl *field,
1816 uint32_t &bitfield_bit_size) {
1817 if (ast == nullptr || field == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001818 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001819
Kate Stoneb9c1b512016-09-06 20:57:50 +00001820 if (field->isBitField()) {
1821 Expr *bit_width_expr = field->getBitWidth();
1822 if (bit_width_expr) {
1823 llvm::APSInt bit_width_apsint;
1824 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast)) {
1825 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001826 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001827 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001828 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001829 }
1830 return false;
1831}
1832
1833bool ClangASTContext::RecordHasFields(const RecordDecl *record_decl) {
1834 if (record_decl == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001835 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001836
1837 if (!record_decl->field_empty())
1838 return true;
1839
1840 // No fields, lets check this is a CXX record and check the base classes
1841 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1842 if (cxx_record_decl) {
1843 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1844 for (base_class = cxx_record_decl->bases_begin(),
1845 base_class_end = cxx_record_decl->bases_end();
1846 base_class != base_class_end; ++base_class) {
1847 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(
1848 base_class->getType()->getAs<RecordType>()->getDecl());
1849 if (RecordHasFields(base_class_decl))
1850 return true;
1851 }
1852 }
1853 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001854}
1855
Adrian Prantl4e8be2c2018-06-13 16:21:24 +00001856#pragma mark Objective-C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001857
Kate Stoneb9c1b512016-09-06 20:57:50 +00001858CompilerType ClangASTContext::CreateObjCClass(const char *name,
1859 DeclContext *decl_ctx,
1860 bool isForwardDecl,
1861 bool isInternal,
1862 ClangASTMetadata *metadata) {
1863 ASTContext *ast = getASTContext();
1864 assert(ast != nullptr);
1865 assert(name && name[0]);
1866 if (decl_ctx == nullptr)
1867 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001868
Kate Stoneb9c1b512016-09-06 20:57:50 +00001869 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create(
1870 *ast, decl_ctx, SourceLocation(), &ast->Idents.get(name), nullptr,
1871 nullptr, SourceLocation(),
1872 /*isForwardDecl,*/
1873 isInternal);
1874
1875 if (decl && metadata)
1876 SetMetadata(ast, decl, *metadata);
1877
1878 return CompilerType(ast, ast->getObjCInterfaceType(decl));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001879}
1880
Kate Stoneb9c1b512016-09-06 20:57:50 +00001881static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) {
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001882 return !ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001883}
1884
Greg Clayton57ee3062013-07-11 22:46:58 +00001885uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001886ClangASTContext::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl,
1887 bool omit_empty_base_classes) {
1888 uint32_t num_bases = 0;
1889 if (cxx_record_decl) {
1890 if (omit_empty_base_classes) {
1891 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1892 for (base_class = cxx_record_decl->bases_begin(),
1893 base_class_end = cxx_record_decl->bases_end();
1894 base_class != base_class_end; ++base_class) {
1895 // Skip empty base classes
1896 if (omit_empty_base_classes) {
1897 if (BaseSpecifierIsEmpty(base_class))
1898 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001899 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001900 ++num_bases;
1901 }
1902 } else
1903 num_bases = cxx_record_decl->getNumBases();
1904 }
1905 return num_bases;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001906}
1907
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001908#pragma mark Namespace Declarations
1909
Raphael Isemanna9469972019-03-12 07:45:04 +00001910NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration(
1911 const char *name, DeclContext *decl_ctx, bool is_inline) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001912 NamespaceDecl *namespace_decl = nullptr;
1913 ASTContext *ast = getASTContext();
1914 TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl();
1915 if (decl_ctx == nullptr)
1916 decl_ctx = translation_unit_decl;
Greg Clayton030a2042011-10-14 21:34:45 +00001917
Kate Stoneb9c1b512016-09-06 20:57:50 +00001918 if (name) {
1919 IdentifierInfo &identifier_info = ast->Idents.get(name);
1920 DeclarationName decl_name(&identifier_info);
1921 clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
1922 for (NamedDecl *decl : result) {
1923 namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
1924 if (namespace_decl)
1925 return namespace_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001926 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001927
1928 namespace_decl =
Raphael Isemanna9469972019-03-12 07:45:04 +00001929 NamespaceDecl::Create(*ast, decl_ctx, is_inline, SourceLocation(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00001930 SourceLocation(), &identifier_info, nullptr);
1931
1932 decl_ctx->addDecl(namespace_decl);
1933 } else {
1934 if (decl_ctx == translation_unit_decl) {
1935 namespace_decl = translation_unit_decl->getAnonymousNamespace();
1936 if (namespace_decl)
1937 return namespace_decl;
1938
1939 namespace_decl =
1940 NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
1941 SourceLocation(), nullptr, nullptr);
1942 translation_unit_decl->setAnonymousNamespace(namespace_decl);
1943 translation_unit_decl->addDecl(namespace_decl);
1944 assert(namespace_decl == translation_unit_decl->getAnonymousNamespace());
1945 } else {
1946 NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
1947 if (parent_namespace_decl) {
1948 namespace_decl = parent_namespace_decl->getAnonymousNamespace();
1949 if (namespace_decl)
1950 return namespace_decl;
1951 namespace_decl =
1952 NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
1953 SourceLocation(), nullptr, nullptr);
1954 parent_namespace_decl->setAnonymousNamespace(namespace_decl);
1955 parent_namespace_decl->addDecl(namespace_decl);
1956 assert(namespace_decl ==
1957 parent_namespace_decl->getAnonymousNamespace());
1958 } else {
Raphael Isemannc4944812019-07-04 19:49:31 +00001959 assert(false && "GetUniqueNamespaceDeclaration called with no name and "
1960 "no namespace as decl_ctx");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001961 }
Greg Clayton9d3d6882011-10-31 23:51:19 +00001962 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001963 }
Greg Clayton9d3d6882011-10-31 23:51:19 +00001964#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00001965 VerifyDecl(namespace_decl);
Greg Clayton9d3d6882011-10-31 23:51:19 +00001966#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00001967 return namespace_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001968}
1969
Kate Stoneb9c1b512016-09-06 20:57:50 +00001970NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration(
Raphael Isemanna9469972019-03-12 07:45:04 +00001971 clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx,
1972 bool is_inline) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001973 ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast);
1974 if (ast_ctx == nullptr)
1975 return nullptr;
Siva Chandra03ff5c82016-02-05 19:10:04 +00001976
Raphael Isemanna9469972019-03-12 07:45:04 +00001977 return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx, is_inline);
Siva Chandra03ff5c82016-02-05 19:10:04 +00001978}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001979
Paul Hermand628cbb2015-09-15 23:44:17 +00001980clang::BlockDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001981ClangASTContext::CreateBlockDeclaration(clang::DeclContext *ctx) {
1982 if (ctx != nullptr) {
1983 clang::BlockDecl *decl = clang::BlockDecl::Create(*getASTContext(), ctx,
1984 clang::SourceLocation());
1985 ctx->addDecl(decl);
1986 return decl;
1987 }
1988 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00001989}
1990
Kate Stoneb9c1b512016-09-06 20:57:50 +00001991clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left,
1992 clang::DeclContext *right,
1993 clang::DeclContext *root) {
1994 if (root == nullptr)
Paul Hermanea188fc2015-09-16 18:48:30 +00001995 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001996
1997 std::set<clang::DeclContext *> path_left;
1998 for (clang::DeclContext *d = left; d != nullptr; d = d->getParent())
1999 path_left.insert(d);
2000
2001 for (clang::DeclContext *d = right; d != nullptr; d = d->getParent())
2002 if (path_left.find(d) != path_left.end())
2003 return d;
2004
2005 return nullptr;
Paul Hermanea188fc2015-09-16 18:48:30 +00002006}
2007
Kate Stoneb9c1b512016-09-06 20:57:50 +00002008clang::UsingDirectiveDecl *ClangASTContext::CreateUsingDirectiveDeclaration(
2009 clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) {
2010 if (decl_ctx != nullptr && ns_decl != nullptr) {
2011 clang::TranslationUnitDecl *translation_unit =
2012 (clang::TranslationUnitDecl *)GetTranslationUnitDecl(getASTContext());
2013 clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
2014 *getASTContext(), decl_ctx, clang::SourceLocation(),
2015 clang::SourceLocation(), clang::NestedNameSpecifierLoc(),
2016 clang::SourceLocation(), ns_decl,
2017 FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit));
2018 decl_ctx->addDecl(using_decl);
2019 return using_decl;
2020 }
2021 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00002022}
2023
2024clang::UsingDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00002025ClangASTContext::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
2026 clang::NamedDecl *target) {
2027 if (current_decl_ctx != nullptr && target != nullptr) {
2028 clang::UsingDecl *using_decl = clang::UsingDecl::Create(
2029 *getASTContext(), current_decl_ctx, clang::SourceLocation(),
2030 clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
2031 clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
2032 *getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
2033 target);
2034 using_decl->addShadowDecl(shadow_decl);
2035 current_decl_ctx->addDecl(using_decl);
2036 return using_decl;
2037 }
2038 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00002039}
2040
Kate Stoneb9c1b512016-09-06 20:57:50 +00002041clang::VarDecl *ClangASTContext::CreateVariableDeclaration(
2042 clang::DeclContext *decl_context, const char *name, clang::QualType type) {
2043 if (decl_context != nullptr) {
2044 clang::VarDecl *var_decl = clang::VarDecl::Create(
2045 *getASTContext(), decl_context, clang::SourceLocation(),
2046 clang::SourceLocation(),
2047 name && name[0] ? &getASTContext()->Idents.getOwn(name) : nullptr, type,
2048 nullptr, clang::SC_None);
2049 var_decl->setAccess(clang::AS_public);
2050 decl_context->addDecl(var_decl);
2051 return var_decl;
2052 }
2053 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00002054}
2055
Zachary Turner9d8a97e2016-04-01 23:20:35 +00002056lldb::opaque_compiler_type_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00002057ClangASTContext::GetOpaqueCompilerType(clang::ASTContext *ast,
2058 lldb::BasicType basic_type) {
2059 switch (basic_type) {
2060 case eBasicTypeVoid:
2061 return ast->VoidTy.getAsOpaquePtr();
2062 case eBasicTypeChar:
2063 return ast->CharTy.getAsOpaquePtr();
2064 case eBasicTypeSignedChar:
2065 return ast->SignedCharTy.getAsOpaquePtr();
2066 case eBasicTypeUnsignedChar:
2067 return ast->UnsignedCharTy.getAsOpaquePtr();
2068 case eBasicTypeWChar:
2069 return ast->getWCharType().getAsOpaquePtr();
2070 case eBasicTypeSignedWChar:
2071 return ast->getSignedWCharType().getAsOpaquePtr();
2072 case eBasicTypeUnsignedWChar:
2073 return ast->getUnsignedWCharType().getAsOpaquePtr();
2074 case eBasicTypeChar16:
2075 return ast->Char16Ty.getAsOpaquePtr();
2076 case eBasicTypeChar32:
2077 return ast->Char32Ty.getAsOpaquePtr();
2078 case eBasicTypeShort:
2079 return ast->ShortTy.getAsOpaquePtr();
2080 case eBasicTypeUnsignedShort:
2081 return ast->UnsignedShortTy.getAsOpaquePtr();
2082 case eBasicTypeInt:
2083 return ast->IntTy.getAsOpaquePtr();
2084 case eBasicTypeUnsignedInt:
2085 return ast->UnsignedIntTy.getAsOpaquePtr();
2086 case eBasicTypeLong:
2087 return ast->LongTy.getAsOpaquePtr();
2088 case eBasicTypeUnsignedLong:
2089 return ast->UnsignedLongTy.getAsOpaquePtr();
2090 case eBasicTypeLongLong:
2091 return ast->LongLongTy.getAsOpaquePtr();
2092 case eBasicTypeUnsignedLongLong:
2093 return ast->UnsignedLongLongTy.getAsOpaquePtr();
2094 case eBasicTypeInt128:
2095 return ast->Int128Ty.getAsOpaquePtr();
2096 case eBasicTypeUnsignedInt128:
2097 return ast->UnsignedInt128Ty.getAsOpaquePtr();
2098 case eBasicTypeBool:
2099 return ast->BoolTy.getAsOpaquePtr();
2100 case eBasicTypeHalf:
2101 return ast->HalfTy.getAsOpaquePtr();
2102 case eBasicTypeFloat:
2103 return ast->FloatTy.getAsOpaquePtr();
2104 case eBasicTypeDouble:
2105 return ast->DoubleTy.getAsOpaquePtr();
2106 case eBasicTypeLongDouble:
2107 return ast->LongDoubleTy.getAsOpaquePtr();
2108 case eBasicTypeFloatComplex:
2109 return ast->FloatComplexTy.getAsOpaquePtr();
2110 case eBasicTypeDoubleComplex:
2111 return ast->DoubleComplexTy.getAsOpaquePtr();
2112 case eBasicTypeLongDoubleComplex:
2113 return ast->LongDoubleComplexTy.getAsOpaquePtr();
2114 case eBasicTypeObjCID:
2115 return ast->getObjCIdType().getAsOpaquePtr();
2116 case eBasicTypeObjCClass:
2117 return ast->getObjCClassType().getAsOpaquePtr();
2118 case eBasicTypeObjCSel:
2119 return ast->getObjCSelType().getAsOpaquePtr();
2120 case eBasicTypeNullPtr:
2121 return ast->NullPtrTy.getAsOpaquePtr();
2122 default:
2123 return nullptr;
2124 }
Zachary Turner9d8a97e2016-04-01 23:20:35 +00002125}
2126
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002127#pragma mark Function Types
2128
Pavel Labath1ac2b202016-08-15 14:32:32 +00002129clang::DeclarationName
Kate Stoneb9c1b512016-09-06 20:57:50 +00002130ClangASTContext::GetDeclarationName(const char *name,
2131 const CompilerType &function_clang_type) {
2132 if (!name || !name[0])
2133 return clang::DeclarationName();
Pavel Labath1ac2b202016-08-15 14:32:32 +00002134
Kate Stoneb9c1b512016-09-06 20:57:50 +00002135 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
2136 if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS)
2137 return DeclarationName(&getASTContext()->Idents.get(
2138 name)); // Not operator, but a regular function.
Pavel Labath1ac2b202016-08-15 14:32:32 +00002139
Adrian Prantl05097242018-04-30 16:49:04 +00002140 // Check the number of operator parameters. Sometimes we have seen bad DWARF
2141 // that doesn't correctly describe operators and if we try to create a method
2142 // and add it to the class, clang will assert and crash, so we need to make
2143 // sure things are acceptable.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002144 clang::QualType method_qual_type(ClangUtil::GetQualType(function_clang_type));
2145 const clang::FunctionProtoType *function_type =
2146 llvm::dyn_cast<clang::FunctionProtoType>(method_qual_type.getTypePtr());
2147 if (function_type == nullptr)
2148 return clang::DeclarationName();
Pavel Labath1ac2b202016-08-15 14:32:32 +00002149
Kate Stoneb9c1b512016-09-06 20:57:50 +00002150 const bool is_method = false;
2151 const unsigned int num_params = function_type->getNumParams();
2152 if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
2153 is_method, op_kind, num_params))
2154 return clang::DeclarationName();
Pavel Labath1ac2b202016-08-15 14:32:32 +00002155
Kate Stoneb9c1b512016-09-06 20:57:50 +00002156 return getASTContext()->DeclarationNames.getCXXOperatorName(op_kind);
Pavel Labath1ac2b202016-08-15 14:32:32 +00002157}
2158
Kate Stoneb9c1b512016-09-06 20:57:50 +00002159FunctionDecl *ClangASTContext::CreateFunctionDeclaration(
2160 DeclContext *decl_ctx, const char *name,
2161 const CompilerType &function_clang_type, int storage, bool is_inline) {
2162 FunctionDecl *func_decl = nullptr;
2163 ASTContext *ast = getASTContext();
2164 if (decl_ctx == nullptr)
2165 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002166
Kate Stoneb9c1b512016-09-06 20:57:50 +00002167 const bool hasWrittenPrototype = true;
2168 const bool isConstexprSpecified = false;
Greg Clayton0d551042013-06-28 21:08:47 +00002169
Kate Stoneb9c1b512016-09-06 20:57:50 +00002170 clang::DeclarationName declarationName =
2171 GetDeclarationName(name, function_clang_type);
2172 func_decl = FunctionDecl::Create(
2173 *ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName,
2174 ClangUtil::GetQualType(function_clang_type), nullptr,
2175 (clang::StorageClass)storage, is_inline, hasWrittenPrototype,
Gauthier Harnisch796ed032019-06-14 08:56:20 +00002176 isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002177 if (func_decl)
2178 decl_ctx->addDecl(func_decl);
2179
Sean Callanan5e9e1992011-10-26 01:06:27 +00002180#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00002181 VerifyDecl(func_decl);
Sean Callanan5e9e1992011-10-26 01:06:27 +00002182#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00002183
2184 return func_decl;
2185}
2186
2187CompilerType ClangASTContext::CreateFunctionType(
2188 ASTContext *ast, const CompilerType &result_type, const CompilerType *args,
Aleksandr Urakovbc4707c2018-09-26 09:03:34 +00002189 unsigned num_args, bool is_variadic, unsigned type_quals,
2190 clang::CallingConv cc) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002191 if (ast == nullptr)
2192 return CompilerType(); // invalid AST
2193
2194 if (!result_type || !ClangUtil::IsClangType(result_type))
2195 return CompilerType(); // invalid return type
2196
2197 std::vector<QualType> qual_type_args;
2198 if (num_args > 0 && args == nullptr)
2199 return CompilerType(); // invalid argument array passed in
2200
2201 // Verify that all arguments are valid and the right type
2202 for (unsigned i = 0; i < num_args; ++i) {
2203 if (args[i]) {
2204 // Make sure we have a clang type in args[i] and not a type from another
2205 // language whose name might match
2206 const bool is_clang_type = ClangUtil::IsClangType(args[i]);
2207 lldbassert(is_clang_type);
2208 if (is_clang_type)
2209 qual_type_args.push_back(ClangUtil::GetQualType(args[i]));
2210 else
2211 return CompilerType(); // invalid argument type (must be a clang type)
2212 } else
2213 return CompilerType(); // invalid argument type (empty)
2214 }
2215
2216 // TODO: Detect calling convention in DWARF?
2217 FunctionProtoType::ExtProtoInfo proto_info;
Aleksandr Urakovbc4707c2018-09-26 09:03:34 +00002218 proto_info.ExtInfo = cc;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002219 proto_info.Variadic = is_variadic;
2220 proto_info.ExceptionSpec = EST_None;
Mikael Nilsson8b3bf6c2018-12-13 10:17:26 +00002221 proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002222 proto_info.RefQualifier = RQ_None;
2223
2224 return CompilerType(ast,
2225 ast->getFunctionType(ClangUtil::GetQualType(result_type),
2226 qual_type_args, proto_info));
2227}
2228
2229ParmVarDecl *ClangASTContext::CreateParameterDeclaration(
Zachary Turner6753d2d2018-12-12 17:17:53 +00002230 clang::DeclContext *decl_ctx, const char *name,
Shafik Yaghmourfa5c3402019-08-02 21:41:50 +00002231 const CompilerType &param_type, int storage, bool add_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002232 ASTContext *ast = getASTContext();
2233 assert(ast != nullptr);
Zachary Turnerd3d2b9b2018-12-13 18:17:51 +00002234 auto *decl =
2235 ParmVarDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(),
2236 name && name[0] ? &ast->Idents.get(name) : nullptr,
2237 ClangUtil::GetQualType(param_type), nullptr,
2238 (clang::StorageClass)storage, nullptr);
Shafik Yaghmourfa5c3402019-08-02 21:41:50 +00002239 if (add_decl)
2240 decl_ctx->addDecl(decl);
2241
Zachary Turnerd3d2b9b2018-12-13 18:17:51 +00002242 return decl;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002243}
2244
2245void ClangASTContext::SetFunctionParameters(FunctionDecl *function_decl,
2246 ParmVarDecl **params,
2247 unsigned num_params) {
2248 if (function_decl)
2249 function_decl->setParams(ArrayRef<ParmVarDecl *>(params, num_params));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002250}
2251
Greg Claytona1e5dc82015-08-11 22:53:00 +00002252CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00002253ClangASTContext::CreateBlockPointerType(const CompilerType &function_type) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +00002254 QualType block_type = m_ast_up->getBlockPointerType(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002255 clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType()));
Greg Claytonceeb5212016-05-26 22:33:25 +00002256
Kate Stoneb9c1b512016-09-06 20:57:50 +00002257 return CompilerType(this, block_type.getAsOpaquePtr());
Sean Callananc530ba92016-05-02 21:15:31 +00002258}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002259
2260#pragma mark Array Types
2261
Kate Stoneb9c1b512016-09-06 20:57:50 +00002262CompilerType ClangASTContext::CreateArrayType(const CompilerType &element_type,
2263 size_t element_count,
2264 bool is_vector) {
2265 if (element_type.IsValid()) {
2266 ASTContext *ast = getASTContext();
2267 assert(ast != nullptr);
Greg Clayton4ef877f2012-12-06 02:33:54 +00002268
Kate Stoneb9c1b512016-09-06 20:57:50 +00002269 if (is_vector) {
2270 return CompilerType(
2271 ast, ast->getExtVectorType(ClangUtil::GetQualType(element_type),
2272 element_count));
2273 } else {
2274
2275 llvm::APInt ap_element_count(64, element_count);
2276 if (element_count == 0) {
2277 return CompilerType(ast, ast->getIncompleteArrayType(
2278 ClangUtil::GetQualType(element_type),
2279 clang::ArrayType::Normal, 0));
2280 } else {
2281 return CompilerType(
2282 ast, ast->getConstantArrayType(ClangUtil::GetQualType(element_type),
2283 ap_element_count,
2284 clang::ArrayType::Normal, 0));
2285 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002286 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002287 }
2288 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002289}
2290
Kate Stoneb9c1b512016-09-06 20:57:50 +00002291CompilerType ClangASTContext::CreateStructForIdentifier(
Adrian Prantl0e4c4822019-03-06 21:22:25 +00002292 ConstString type_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002293 const std::initializer_list<std::pair<const char *, CompilerType>>
2294 &type_fields,
2295 bool packed) {
2296 CompilerType type;
2297 if (!type_name.IsEmpty() &&
2298 (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name))
2299 .IsValid()) {
Pavel Labathf31c9d22017-01-05 13:18:42 +00002300 lldbassert(0 && "Trying to create a type for an existing name");
Enrico Granata76b08d52014-10-29 23:08:02 +00002301 return type;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002302 }
2303
2304 type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(),
2305 clang::TTK_Struct, lldb::eLanguageTypeC);
2306 StartTagDeclarationDefinition(type);
2307 for (const auto &field : type_fields)
2308 AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic,
2309 0);
2310 if (packed)
2311 SetIsPacked(type);
2312 CompleteTagDeclarationDefinition(type);
2313 return type;
Enrico Granata76b08d52014-10-29 23:08:02 +00002314}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002315
Kate Stoneb9c1b512016-09-06 20:57:50 +00002316CompilerType ClangASTContext::GetOrCreateStructForIdentifier(
Adrian Prantl0e4c4822019-03-06 21:22:25 +00002317 ConstString type_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002318 const std::initializer_list<std::pair<const char *, CompilerType>>
2319 &type_fields,
2320 bool packed) {
2321 CompilerType type;
2322 if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
2323 return type;
Sean Callananc530ba92016-05-02 21:15:31 +00002324
Kate Stoneb9c1b512016-09-06 20:57:50 +00002325 return CreateStructForIdentifier(type_name, type_fields, packed);
Sean Callananc530ba92016-05-02 21:15:31 +00002326}
2327
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002328#pragma mark Enumeration Types
2329
Greg Claytona1e5dc82015-08-11 22:53:00 +00002330CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00002331ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
2332 const Declaration &decl,
Tamas Berghammer59765832017-11-07 10:39:22 +00002333 const CompilerType &integer_clang_type,
2334 bool is_scoped) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002335 // TODO: Do something intelligent with the Declaration object passed in
2336 // like maybe filling in the SourceLocation with it...
2337 ASTContext *ast = getASTContext();
Zachary Turnerd133f6a2016-03-28 22:53:41 +00002338
Kate Stoneb9c1b512016-09-06 20:57:50 +00002339 // TODO: ask about these...
Kate Stoneb9c1b512016-09-06 20:57:50 +00002340 // const bool IsFixed = false;
2341
2342 EnumDecl *enum_decl = EnumDecl::Create(
2343 *ast, decl_ctx, SourceLocation(), SourceLocation(),
2344 name && name[0] ? &ast->Idents.get(name) : nullptr, nullptr,
Tamas Berghammercf6bf4c2017-11-07 13:43:55 +00002345 is_scoped, // IsScoped
2346 is_scoped, // IsScopedUsingClassTag
2347 false); // IsFixed
Kate Stoneb9c1b512016-09-06 20:57:50 +00002348
2349 if (enum_decl) {
Aleksandr Urakov709426b2018-09-10 08:08:43 +00002350 if (decl_ctx)
2351 decl_ctx->addDecl(enum_decl);
2352
Kate Stoneb9c1b512016-09-06 20:57:50 +00002353 // TODO: check if we should be setting the promotion type too?
2354 enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
2355
2356 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
2357
2358 return CompilerType(ast, ast->getTagDeclType(enum_decl));
2359 }
2360 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002361}
2362
Kate Stoneb9c1b512016-09-06 20:57:50 +00002363CompilerType ClangASTContext::GetIntTypeFromBitSize(clang::ASTContext *ast,
2364 size_t bit_size,
2365 bool is_signed) {
2366 if (ast) {
2367 if (is_signed) {
2368 if (bit_size == ast->getTypeSize(ast->SignedCharTy))
2369 return CompilerType(ast, ast->SignedCharTy);
2370
2371 if (bit_size == ast->getTypeSize(ast->ShortTy))
2372 return CompilerType(ast, ast->ShortTy);
2373
2374 if (bit_size == ast->getTypeSize(ast->IntTy))
2375 return CompilerType(ast, ast->IntTy);
2376
2377 if (bit_size == ast->getTypeSize(ast->LongTy))
2378 return CompilerType(ast, ast->LongTy);
2379
2380 if (bit_size == ast->getTypeSize(ast->LongLongTy))
2381 return CompilerType(ast, ast->LongLongTy);
2382
2383 if (bit_size == ast->getTypeSize(ast->Int128Ty))
2384 return CompilerType(ast, ast->Int128Ty);
2385 } else {
2386 if (bit_size == ast->getTypeSize(ast->UnsignedCharTy))
2387 return CompilerType(ast, ast->UnsignedCharTy);
2388
2389 if (bit_size == ast->getTypeSize(ast->UnsignedShortTy))
2390 return CompilerType(ast, ast->UnsignedShortTy);
2391
2392 if (bit_size == ast->getTypeSize(ast->UnsignedIntTy))
2393 return CompilerType(ast, ast->UnsignedIntTy);
2394
2395 if (bit_size == ast->getTypeSize(ast->UnsignedLongTy))
2396 return CompilerType(ast, ast->UnsignedLongTy);
2397
2398 if (bit_size == ast->getTypeSize(ast->UnsignedLongLongTy))
2399 return CompilerType(ast, ast->UnsignedLongLongTy);
2400
2401 if (bit_size == ast->getTypeSize(ast->UnsignedInt128Ty))
2402 return CompilerType(ast, ast->UnsignedInt128Ty);
Enrico Granatae8bf7492014-08-15 23:00:02 +00002403 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002404 }
2405 return CompilerType();
Enrico Granatae8bf7492014-08-15 23:00:02 +00002406}
2407
Kate Stoneb9c1b512016-09-06 20:57:50 +00002408CompilerType ClangASTContext::GetPointerSizedIntType(clang::ASTContext *ast,
2409 bool is_signed) {
2410 if (ast)
2411 return GetIntTypeFromBitSize(ast, ast->getTypeSize(ast->VoidPtrTy),
2412 is_signed);
2413 return CompilerType();
Enrico Granatae8bf7492014-08-15 23:00:02 +00002414}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002415
Kate Stoneb9c1b512016-09-06 20:57:50 +00002416void ClangASTContext::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) {
2417 if (decl_ctx) {
2418 DumpDeclContextHiearchy(decl_ctx->getParent());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002419
Kate Stoneb9c1b512016-09-06 20:57:50 +00002420 clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl_ctx);
2421 if (named_decl) {
2422 printf("%20s: %s\n", decl_ctx->getDeclKindName(),
2423 named_decl->getDeclName().getAsString().c_str());
2424 } else {
2425 printf("%20s\n", decl_ctx->getDeclKindName());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002426 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002427 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00002428}
2429
Kate Stoneb9c1b512016-09-06 20:57:50 +00002430void ClangASTContext::DumpDeclHiearchy(clang::Decl *decl) {
2431 if (decl == nullptr)
2432 return;
2433 DumpDeclContextHiearchy(decl->getDeclContext());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002434
Kate Stoneb9c1b512016-09-06 20:57:50 +00002435 clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl);
2436 if (record_decl) {
2437 printf("%20s: %s%s\n", decl->getDeclKindName(),
2438 record_decl->getDeclName().getAsString().c_str(),
2439 record_decl->isInjectedClassName() ? " (injected class name)" : "");
Greg Claytone6b36cd2015-12-08 01:02:08 +00002440
Kate Stoneb9c1b512016-09-06 20:57:50 +00002441 } else {
2442 clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl);
2443 if (named_decl) {
2444 printf("%20s: %s\n", decl->getDeclKindName(),
2445 named_decl->getDeclName().getAsString().c_str());
2446 } else {
2447 printf("%20s\n", decl->getDeclKindName());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002448 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002449 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00002450}
2451
Kate Stoneb9c1b512016-09-06 20:57:50 +00002452bool ClangASTContext::DeclsAreEquivalent(clang::Decl *lhs_decl,
2453 clang::Decl *rhs_decl) {
2454 if (lhs_decl && rhs_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002455 // Make sure the decl kinds match first
Kate Stoneb9c1b512016-09-06 20:57:50 +00002456 const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind();
2457 const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind();
Greg Claytone6b36cd2015-12-08 01:02:08 +00002458
Kate Stoneb9c1b512016-09-06 20:57:50 +00002459 if (lhs_decl_kind == rhs_decl_kind) {
Adrian Prantl05097242018-04-30 16:49:04 +00002460 // Now check that the decl contexts kinds are all equivalent before we
2461 // have to check any names of the decl contexts...
Kate Stoneb9c1b512016-09-06 20:57:50 +00002462 clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
2463 clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
2464 if (lhs_decl_ctx && rhs_decl_ctx) {
Jonas Devlieghere09ad8c82019-05-24 00:44:33 +00002465 while (true) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002466 if (lhs_decl_ctx && rhs_decl_ctx) {
2467 const clang::Decl::Kind lhs_decl_ctx_kind =
2468 lhs_decl_ctx->getDeclKind();
2469 const clang::Decl::Kind rhs_decl_ctx_kind =
2470 rhs_decl_ctx->getDeclKind();
2471 if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) {
2472 lhs_decl_ctx = lhs_decl_ctx->getParent();
2473 rhs_decl_ctx = rhs_decl_ctx->getParent();
Greg Claytone6b36cd2015-12-08 01:02:08 +00002474
Kate Stoneb9c1b512016-09-06 20:57:50 +00002475 if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr)
2476 break;
2477 } else
2478 return false;
2479 } else
Tamas Berghammerfcf334b2015-12-02 11:35:54 +00002480 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002481 }
2482
Kate Stoneb9c1b512016-09-06 20:57:50 +00002483 // Now make sure the name of the decls match
Kate Stoneb9c1b512016-09-06 20:57:50 +00002484 clang::NamedDecl *lhs_named_decl =
2485 llvm::dyn_cast<clang::NamedDecl>(lhs_decl);
2486 clang::NamedDecl *rhs_named_decl =
2487 llvm::dyn_cast<clang::NamedDecl>(rhs_decl);
2488 if (lhs_named_decl && rhs_named_decl) {
2489 clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
2490 clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
2491 if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
2492 if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
2493 return false;
2494 } else
Greg Claytona2721472011-06-25 00:44:06 +00002495 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002496 } else
2497 return false;
Greg Claytona2721472011-06-25 00:44:06 +00002498
Adrian Prantl05097242018-04-30 16:49:04 +00002499 // We know that the decl context kinds all match, so now we need to
2500 // make sure the names match as well
Kate Stoneb9c1b512016-09-06 20:57:50 +00002501 lhs_decl_ctx = lhs_decl->getDeclContext();
2502 rhs_decl_ctx = rhs_decl->getDeclContext();
Jonas Devlieghere09ad8c82019-05-24 00:44:33 +00002503 while (true) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002504 switch (lhs_decl_ctx->getDeclKind()) {
2505 case clang::Decl::TranslationUnit:
2506 // We don't care about the translation unit names
2507 return true;
2508 default: {
2509 clang::NamedDecl *lhs_named_decl =
2510 llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx);
2511 clang::NamedDecl *rhs_named_decl =
2512 llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx);
2513 if (lhs_named_decl && rhs_named_decl) {
2514 clang::DeclarationName lhs_decl_name =
2515 lhs_named_decl->getDeclName();
2516 clang::DeclarationName rhs_decl_name =
2517 rhs_named_decl->getDeclName();
2518 if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
2519 if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
2520 return false;
2521 } else
2522 return false;
2523 } else
2524 return false;
2525 } break;
2526 }
2527 lhs_decl_ctx = lhs_decl_ctx->getParent();
2528 rhs_decl_ctx = rhs_decl_ctx->getParent();
Greg Claytond8d4a572015-08-11 21:38:15 +00002529 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002530 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002531 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002532 }
2533 return false;
2534}
2535bool ClangASTContext::GetCompleteDecl(clang::ASTContext *ast,
2536 clang::Decl *decl) {
2537 if (!decl)
Greg Claytond8d4a572015-08-11 21:38:15 +00002538 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00002539
Kate Stoneb9c1b512016-09-06 20:57:50 +00002540 ExternalASTSource *ast_source = ast->getExternalSource();
Greg Claytond8d4a572015-08-11 21:38:15 +00002541
Kate Stoneb9c1b512016-09-06 20:57:50 +00002542 if (!ast_source)
Greg Claytond8d4a572015-08-11 21:38:15 +00002543 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002544
2545 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) {
2546 if (tag_decl->isCompleteDefinition())
2547 return true;
2548
2549 if (!tag_decl->hasExternalLexicalStorage())
2550 return false;
2551
2552 ast_source->CompleteType(tag_decl);
2553
2554 return !tag_decl->getTypeForDecl()->isIncompleteType();
2555 } else if (clang::ObjCInterfaceDecl *objc_interface_decl =
2556 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) {
2557 if (objc_interface_decl->getDefinition())
2558 return true;
2559
2560 if (!objc_interface_decl->hasExternalLexicalStorage())
2561 return false;
2562
2563 ast_source->CompleteType(objc_interface_decl);
2564
2565 return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
2566 } else {
2567 return false;
2568 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002569}
2570
Kate Stoneb9c1b512016-09-06 20:57:50 +00002571void ClangASTContext::SetMetadataAsUserID(const void *object,
2572 user_id_t user_id) {
2573 ClangASTMetadata meta_data;
2574 meta_data.SetUserID(user_id);
2575 SetMetadata(object, meta_data);
Greg Clayton99558cc42015-08-24 23:46:31 +00002576}
2577
Kate Stoneb9c1b512016-09-06 20:57:50 +00002578void ClangASTContext::SetMetadata(clang::ASTContext *ast, const void *object,
2579 ClangASTMetadata &metadata) {
2580 ClangExternalASTSourceCommon *external_source =
2581 ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
2582
2583 if (external_source)
2584 external_source->SetMetadata(object, metadata);
2585}
2586
2587ClangASTMetadata *ClangASTContext::GetMetadata(clang::ASTContext *ast,
2588 const void *object) {
2589 ClangExternalASTSourceCommon *external_source =
2590 ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
2591
2592 if (external_source && external_source->HasMetadata(object))
2593 return external_source->GetMetadata(object);
2594 else
Greg Claytond8d4a572015-08-11 21:38:15 +00002595 return nullptr;
2596}
2597
Kate Stoneb9c1b512016-09-06 20:57:50 +00002598clang::DeclContext *
2599ClangASTContext::GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl) {
2600 return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
2601}
Greg Claytone6b36cd2015-12-08 01:02:08 +00002602
Kate Stoneb9c1b512016-09-06 20:57:50 +00002603clang::DeclContext *
2604ClangASTContext::GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl) {
2605 return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
2606}
Greg Claytone6b36cd2015-12-08 01:02:08 +00002607
Kate Stoneb9c1b512016-09-06 20:57:50 +00002608bool ClangASTContext::SetTagTypeKind(clang::QualType tag_qual_type,
2609 int kind) const {
2610 const clang::Type *clang_type = tag_qual_type.getTypePtr();
2611 if (clang_type) {
2612 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
2613 if (tag_type) {
2614 clang::TagDecl *tag_decl =
2615 llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
2616 if (tag_decl) {
2617 tag_decl->setTagKind((clang::TagDecl::TagKind)kind);
2618 return true;
2619 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002620 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002621 }
2622 return false;
2623}
2624
2625bool ClangASTContext::SetDefaultAccessForRecordFields(
2626 clang::RecordDecl *record_decl, int default_accessibility,
2627 int *assigned_accessibilities, size_t num_assigned_accessibilities) {
2628 if (record_decl) {
2629 uint32_t field_idx;
2630 clang::RecordDecl::field_iterator field, field_end;
2631 for (field = record_decl->field_begin(),
2632 field_end = record_decl->field_end(), field_idx = 0;
2633 field != field_end; ++field, ++field_idx) {
2634 // If no accessibility was assigned, assign the correct one
2635 if (field_idx < num_assigned_accessibilities &&
2636 assigned_accessibilities[field_idx] == clang::AS_none)
2637 field->setAccess((clang::AccessSpecifier)default_accessibility);
2638 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002639 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002640 }
2641 return false;
2642}
2643
2644clang::DeclContext *
2645ClangASTContext::GetDeclContextForType(const CompilerType &type) {
2646 return GetDeclContextForType(ClangUtil::GetQualType(type));
2647}
2648
2649clang::DeclContext *
2650ClangASTContext::GetDeclContextForType(clang::QualType type) {
2651 if (type.isNull())
2652 return nullptr;
2653
2654 clang::QualType qual_type = type.getCanonicalType();
2655 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2656 switch (type_class) {
2657 case clang::Type::ObjCInterface:
2658 return llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr())
2659 ->getInterface();
2660 case clang::Type::ObjCObjectPointer:
2661 return GetDeclContextForType(
2662 llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
2663 ->getPointeeType());
2664 case clang::Type::Record:
2665 return llvm::cast<clang::RecordType>(qual_type)->getDecl();
2666 case clang::Type::Enum:
2667 return llvm::cast<clang::EnumType>(qual_type)->getDecl();
2668 case clang::Type::Typedef:
2669 return GetDeclContextForType(llvm::cast<clang::TypedefType>(qual_type)
2670 ->getDecl()
2671 ->getUnderlyingType());
2672 case clang::Type::Auto:
2673 return GetDeclContextForType(
2674 llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
2675 case clang::Type::Elaborated:
2676 return GetDeclContextForType(
2677 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
2678 case clang::Type::Paren:
2679 return GetDeclContextForType(
2680 llvm::cast<clang::ParenType>(qual_type)->desugar());
2681 default:
2682 break;
2683 }
2684 // No DeclContext in this type...
2685 return nullptr;
2686}
2687
2688static bool GetCompleteQualType(clang::ASTContext *ast,
2689 clang::QualType qual_type,
2690 bool allow_completion = true) {
2691 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2692 switch (type_class) {
2693 case clang::Type::ConstantArray:
2694 case clang::Type::IncompleteArray:
2695 case clang::Type::VariableArray: {
2696 const clang::ArrayType *array_type =
2697 llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
2698
2699 if (array_type)
2700 return GetCompleteQualType(ast, array_type->getElementType(),
2701 allow_completion);
2702 } break;
2703 case clang::Type::Record: {
2704 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2705 if (cxx_record_decl) {
2706 if (cxx_record_decl->hasExternalLexicalStorage()) {
2707 const bool is_complete = cxx_record_decl->isCompleteDefinition();
2708 const bool fields_loaded =
2709 cxx_record_decl->hasLoadedFieldsFromExternalStorage();
2710 if (is_complete && fields_loaded)
2711 return true;
2712
2713 if (!allow_completion)
2714 return false;
2715
2716 // Call the field_begin() accessor to for it to use the external source
2717 // to load the fields...
2718 clang::ExternalASTSource *external_ast_source =
2719 ast->getExternalSource();
2720 if (external_ast_source) {
2721 external_ast_source->CompleteType(cxx_record_decl);
2722 if (cxx_record_decl->isCompleteDefinition()) {
2723 cxx_record_decl->field_begin();
2724 cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
2725 }
2726 }
2727 }
2728 }
2729 const clang::TagType *tag_type =
2730 llvm::cast<clang::TagType>(qual_type.getTypePtr());
2731 return !tag_type->isIncompleteType();
2732 } break;
2733
2734 case clang::Type::Enum: {
2735 const clang::TagType *tag_type =
2736 llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
2737 if (tag_type) {
2738 clang::TagDecl *tag_decl = tag_type->getDecl();
2739 if (tag_decl) {
2740 if (tag_decl->getDefinition())
2741 return true;
2742
2743 if (!allow_completion)
2744 return false;
2745
2746 if (tag_decl->hasExternalLexicalStorage()) {
2747 if (ast) {
2748 clang::ExternalASTSource *external_ast_source =
2749 ast->getExternalSource();
2750 if (external_ast_source) {
2751 external_ast_source->CompleteType(tag_decl);
2752 return !tag_type->isIncompleteType();
2753 }
2754 }
2755 }
2756 return false;
2757 }
2758 }
2759
2760 } break;
2761 case clang::Type::ObjCObject:
2762 case clang::Type::ObjCInterface: {
2763 const clang::ObjCObjectType *objc_class_type =
2764 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
2765 if (objc_class_type) {
2766 clang::ObjCInterfaceDecl *class_interface_decl =
2767 objc_class_type->getInterface();
2768 // We currently can't complete objective C types through the newly added
Adrian Prantl05097242018-04-30 16:49:04 +00002769 // ASTContext because it only supports TagDecl objects right now...
Kate Stoneb9c1b512016-09-06 20:57:50 +00002770 if (class_interface_decl) {
2771 if (class_interface_decl->getDefinition())
2772 return true;
2773
2774 if (!allow_completion)
2775 return false;
2776
2777 if (class_interface_decl->hasExternalLexicalStorage()) {
2778 if (ast) {
2779 clang::ExternalASTSource *external_ast_source =
2780 ast->getExternalSource();
2781 if (external_ast_source) {
2782 external_ast_source->CompleteType(class_interface_decl);
2783 return !objc_class_type->isIncompleteType();
2784 }
2785 }
2786 }
2787 return false;
2788 }
2789 }
2790 } break;
2791
2792 case clang::Type::Typedef:
2793 return GetCompleteQualType(ast, llvm::cast<clang::TypedefType>(qual_type)
2794 ->getDecl()
2795 ->getUnderlyingType(),
2796 allow_completion);
2797
2798 case clang::Type::Auto:
2799 return GetCompleteQualType(
2800 ast, llvm::cast<clang::AutoType>(qual_type)->getDeducedType(),
2801 allow_completion);
2802
2803 case clang::Type::Elaborated:
2804 return GetCompleteQualType(
2805 ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(),
2806 allow_completion);
2807
2808 case clang::Type::Paren:
2809 return GetCompleteQualType(
2810 ast, llvm::cast<clang::ParenType>(qual_type)->desugar(),
2811 allow_completion);
2812
2813 case clang::Type::Attributed:
2814 return GetCompleteQualType(
2815 ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(),
2816 allow_completion);
2817
2818 default:
2819 break;
2820 }
2821
2822 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00002823}
2824
2825static clang::ObjCIvarDecl::AccessControl
Kate Stoneb9c1b512016-09-06 20:57:50 +00002826ConvertAccessTypeToObjCIvarAccessControl(AccessType access) {
2827 switch (access) {
2828 case eAccessNone:
Greg Claytond8d4a572015-08-11 21:38:15 +00002829 return clang::ObjCIvarDecl::None;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002830 case eAccessPublic:
2831 return clang::ObjCIvarDecl::Public;
2832 case eAccessPrivate:
2833 return clang::ObjCIvarDecl::Private;
2834 case eAccessProtected:
2835 return clang::ObjCIvarDecl::Protected;
2836 case eAccessPackage:
2837 return clang::ObjCIvarDecl::Package;
2838 }
2839 return clang::ObjCIvarDecl::None;
Greg Claytond8d4a572015-08-11 21:38:15 +00002840}
2841
Greg Claytond8d4a572015-08-11 21:38:15 +00002842// Tests
Greg Claytond8d4a572015-08-11 21:38:15 +00002843
Kate Stoneb9c1b512016-09-06 20:57:50 +00002844bool ClangASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
2845 clang::QualType qual_type(GetCanonicalQualType(type));
2846
2847 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2848 switch (type_class) {
2849 case clang::Type::IncompleteArray:
2850 case clang::Type::VariableArray:
2851 case clang::Type::ConstantArray:
2852 case clang::Type::ExtVector:
2853 case clang::Type::Vector:
2854 case clang::Type::Record:
2855 case clang::Type::ObjCObject:
2856 case clang::Type::ObjCInterface:
2857 return true;
2858 case clang::Type::Auto:
2859 return IsAggregateType(llvm::cast<clang::AutoType>(qual_type)
2860 ->getDeducedType()
2861 .getAsOpaquePtr());
2862 case clang::Type::Elaborated:
2863 return IsAggregateType(llvm::cast<clang::ElaboratedType>(qual_type)
2864 ->getNamedType()
2865 .getAsOpaquePtr());
2866 case clang::Type::Typedef:
2867 return IsAggregateType(llvm::cast<clang::TypedefType>(qual_type)
2868 ->getDecl()
2869 ->getUnderlyingType()
2870 .getAsOpaquePtr());
2871 case clang::Type::Paren:
2872 return IsAggregateType(
2873 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
2874 default:
2875 break;
2876 }
2877 // The clang type does have a value
2878 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00002879}
2880
Kate Stoneb9c1b512016-09-06 20:57:50 +00002881bool ClangASTContext::IsAnonymousType(lldb::opaque_compiler_type_t type) {
2882 clang::QualType qual_type(GetCanonicalQualType(type));
2883
2884 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2885 switch (type_class) {
2886 case clang::Type::Record: {
2887 if (const clang::RecordType *record_type =
2888 llvm::dyn_cast_or_null<clang::RecordType>(
2889 qual_type.getTypePtrOrNull())) {
2890 if (const clang::RecordDecl *record_decl = record_type->getDecl()) {
2891 return record_decl->isAnonymousStructOrUnion();
2892 }
Enrico Granata7123e2b2015-11-07 02:06:57 +00002893 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002894 break;
2895 }
2896 case clang::Type::Auto:
2897 return IsAnonymousType(llvm::cast<clang::AutoType>(qual_type)
2898 ->getDeducedType()
2899 .getAsOpaquePtr());
2900 case clang::Type::Elaborated:
2901 return IsAnonymousType(llvm::cast<clang::ElaboratedType>(qual_type)
2902 ->getNamedType()
2903 .getAsOpaquePtr());
2904 case clang::Type::Typedef:
2905 return IsAnonymousType(llvm::cast<clang::TypedefType>(qual_type)
2906 ->getDecl()
2907 ->getUnderlyingType()
2908 .getAsOpaquePtr());
2909 case clang::Type::Paren:
2910 return IsAnonymousType(
2911 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
2912 default:
2913 break;
2914 }
2915 // The clang type does have a value
2916 return false;
Enrico Granata7123e2b2015-11-07 02:06:57 +00002917}
2918
Kate Stoneb9c1b512016-09-06 20:57:50 +00002919bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
2920 CompilerType *element_type_ptr,
2921 uint64_t *size, bool *is_incomplete) {
2922 clang::QualType qual_type(GetCanonicalQualType(type));
Tamas Berghammer69d0b332015-10-09 12:43:08 +00002923
Kate Stoneb9c1b512016-09-06 20:57:50 +00002924 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2925 switch (type_class) {
2926 default:
2927 break;
Tamas Berghammer69d0b332015-10-09 12:43:08 +00002928
Kate Stoneb9c1b512016-09-06 20:57:50 +00002929 case clang::Type::ConstantArray:
Greg Claytond8d4a572015-08-11 21:38:15 +00002930 if (element_type_ptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002931 element_type_ptr->SetCompilerType(
2932 getASTContext(),
2933 llvm::cast<clang::ConstantArrayType>(qual_type)->getElementType());
Greg Claytond8d4a572015-08-11 21:38:15 +00002934 if (size)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002935 *size = llvm::cast<clang::ConstantArrayType>(qual_type)
2936 ->getSize()
2937 .getLimitedValue(ULLONG_MAX);
Greg Claytond8d4a572015-08-11 21:38:15 +00002938 if (is_incomplete)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002939 *is_incomplete = false;
2940 return true;
2941
2942 case clang::Type::IncompleteArray:
2943 if (element_type_ptr)
2944 element_type_ptr->SetCompilerType(
2945 getASTContext(),
2946 llvm::cast<clang::IncompleteArrayType>(qual_type)->getElementType());
2947 if (size)
2948 *size = 0;
2949 if (is_incomplete)
2950 *is_incomplete = true;
2951 return true;
2952
2953 case clang::Type::VariableArray:
2954 if (element_type_ptr)
2955 element_type_ptr->SetCompilerType(
2956 getASTContext(),
2957 llvm::cast<clang::VariableArrayType>(qual_type)->getElementType());
2958 if (size)
2959 *size = 0;
2960 if (is_incomplete)
2961 *is_incomplete = false;
2962 return true;
2963
2964 case clang::Type::DependentSizedArray:
2965 if (element_type_ptr)
2966 element_type_ptr->SetCompilerType(
2967 getASTContext(), llvm::cast<clang::DependentSizedArrayType>(qual_type)
2968 ->getElementType());
2969 if (size)
2970 *size = 0;
2971 if (is_incomplete)
2972 *is_incomplete = false;
2973 return true;
2974
2975 case clang::Type::Typedef:
2976 return IsArrayType(llvm::cast<clang::TypedefType>(qual_type)
2977 ->getDecl()
2978 ->getUnderlyingType()
2979 .getAsOpaquePtr(),
2980 element_type_ptr, size, is_incomplete);
2981 case clang::Type::Auto:
2982 return IsArrayType(llvm::cast<clang::AutoType>(qual_type)
2983 ->getDeducedType()
2984 .getAsOpaquePtr(),
2985 element_type_ptr, size, is_incomplete);
2986 case clang::Type::Elaborated:
2987 return IsArrayType(llvm::cast<clang::ElaboratedType>(qual_type)
2988 ->getNamedType()
2989 .getAsOpaquePtr(),
2990 element_type_ptr, size, is_incomplete);
2991 case clang::Type::Paren:
2992 return IsArrayType(
2993 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
2994 element_type_ptr, size, is_incomplete);
2995 }
2996 if (element_type_ptr)
2997 element_type_ptr->Clear();
2998 if (size)
2999 *size = 0;
3000 if (is_incomplete)
3001 *is_incomplete = false;
3002 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00003003}
3004
Kate Stoneb9c1b512016-09-06 20:57:50 +00003005bool ClangASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
3006 CompilerType *element_type, uint64_t *size) {
3007 clang::QualType qual_type(GetCanonicalQualType(type));
3008
3009 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3010 switch (type_class) {
3011 case clang::Type::Vector: {
3012 const clang::VectorType *vector_type =
3013 qual_type->getAs<clang::VectorType>();
3014 if (vector_type) {
3015 if (size)
3016 *size = vector_type->getNumElements();
3017 if (element_type)
3018 *element_type =
3019 CompilerType(getASTContext(), vector_type->getElementType());
3020 }
3021 return true;
3022 } break;
3023 case clang::Type::ExtVector: {
3024 const clang::ExtVectorType *ext_vector_type =
3025 qual_type->getAs<clang::ExtVectorType>();
3026 if (ext_vector_type) {
3027 if (size)
3028 *size = ext_vector_type->getNumElements();
3029 if (element_type)
3030 *element_type =
3031 CompilerType(getASTContext(), ext_vector_type->getElementType());
3032 }
3033 return true;
3034 }
3035 default:
3036 break;
3037 }
3038 return false;
3039}
3040
3041bool ClangASTContext::IsRuntimeGeneratedType(
3042 lldb::opaque_compiler_type_t type) {
3043 clang::DeclContext *decl_ctx = ClangASTContext::GetASTContext(getASTContext())
3044 ->GetDeclContextForType(GetQualType(type));
3045 if (!decl_ctx)
3046 return false;
3047
3048 if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
3049 return false;
3050
3051 clang::ObjCInterfaceDecl *result_iface_decl =
3052 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
3053
3054 ClangASTMetadata *ast_metadata =
3055 ClangASTContext::GetMetadata(getASTContext(), result_iface_decl);
3056 if (!ast_metadata)
3057 return false;
3058 return (ast_metadata->GetISAPtr() != 0);
3059}
3060
3061bool ClangASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
3062 return GetQualType(type).getUnqualifiedType()->isCharType();
3063}
3064
3065bool ClangASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
3066 const bool allow_completion = false;
3067 return GetCompleteQualType(getASTContext(), GetQualType(type),
3068 allow_completion);
3069}
3070
3071bool ClangASTContext::IsConst(lldb::opaque_compiler_type_t type) {
3072 return GetQualType(type).isConstQualified();
3073}
3074
3075bool ClangASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
3076 uint32_t &length) {
3077 CompilerType pointee_or_element_clang_type;
3078 length = 0;
3079 Flags type_flags(GetTypeInfo(type, &pointee_or_element_clang_type));
3080
3081 if (!pointee_or_element_clang_type.IsValid())
3082 return false;
3083
3084 if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer)) {
3085 if (pointee_or_element_clang_type.IsCharType()) {
3086 if (type_flags.Test(eTypeIsArray)) {
Adrian Prantl05097242018-04-30 16:49:04 +00003087 // We know the size of the array and it could be a C string since it is
3088 // an array of characters
Kate Stoneb9c1b512016-09-06 20:57:50 +00003089 length = llvm::cast<clang::ConstantArrayType>(
3090 GetCanonicalQualType(type).getTypePtr())
3091 ->getSize()
3092 .getLimitedValue();
3093 }
3094 return true;
3095 }
3096 }
3097 return false;
3098}
3099
3100bool ClangASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
3101 bool *is_variadic_ptr) {
3102 if (type) {
3103 clang::QualType qual_type(GetCanonicalQualType(type));
3104
3105 if (qual_type->isFunctionType()) {
3106 if (is_variadic_ptr) {
3107 const clang::FunctionProtoType *function_proto_type =
3108 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
3109 if (function_proto_type)
3110 *is_variadic_ptr = function_proto_type->isVariadic();
3111 else
3112 *is_variadic_ptr = false;
3113 }
3114 return true;
3115 }
3116
Greg Claytond8d4a572015-08-11 21:38:15 +00003117 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00003118 switch (type_class) {
3119 default:
3120 break;
3121 case clang::Type::Typedef:
3122 return IsFunctionType(llvm::cast<clang::TypedefType>(qual_type)
3123 ->getDecl()
3124 ->getUnderlyingType()
3125 .getAsOpaquePtr(),
3126 nullptr);
3127 case clang::Type::Auto:
3128 return IsFunctionType(llvm::cast<clang::AutoType>(qual_type)
3129 ->getDeducedType()
3130 .getAsOpaquePtr(),
3131 nullptr);
3132 case clang::Type::Elaborated:
3133 return IsFunctionType(llvm::cast<clang::ElaboratedType>(qual_type)
3134 ->getNamedType()
3135 .getAsOpaquePtr(),
3136 nullptr);
3137 case clang::Type::Paren:
3138 return IsFunctionType(
3139 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3140 nullptr);
3141 case clang::Type::LValueReference:
3142 case clang::Type::RValueReference: {
3143 const clang::ReferenceType *reference_type =
3144 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
3145 if (reference_type)
3146 return IsFunctionType(reference_type->getPointeeType().getAsOpaquePtr(),
3147 nullptr);
3148 } break;
Greg Claytond8d4a572015-08-11 21:38:15 +00003149 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003150 }
3151 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00003152}
3153
3154// Used to detect "Homogeneous Floating-point Aggregates"
3155uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00003156ClangASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
3157 CompilerType *base_type_ptr) {
3158 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00003159 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003160
3161 clang::QualType qual_type(GetCanonicalQualType(type));
3162 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3163 switch (type_class) {
3164 case clang::Type::Record:
3165 if (GetCompleteType(type)) {
3166 const clang::CXXRecordDecl *cxx_record_decl =
3167 qual_type->getAsCXXRecordDecl();
3168 if (cxx_record_decl) {
3169 if (cxx_record_decl->getNumBases() || cxx_record_decl->isDynamicClass())
3170 return 0;
3171 }
3172 const clang::RecordType *record_type =
3173 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
3174 if (record_type) {
3175 const clang::RecordDecl *record_decl = record_type->getDecl();
3176 if (record_decl) {
3177 // We are looking for a structure that contains only floating point
3178 // types
3179 clang::RecordDecl::field_iterator field_pos,
3180 field_end = record_decl->field_end();
3181 uint32_t num_fields = 0;
3182 bool is_hva = false;
3183 bool is_hfa = false;
3184 clang::QualType base_qual_type;
3185 uint64_t base_bitwidth = 0;
3186 for (field_pos = record_decl->field_begin(); field_pos != field_end;
3187 ++field_pos) {
3188 clang::QualType field_qual_type = field_pos->getType();
3189 uint64_t field_bitwidth = getASTContext()->getTypeSize(qual_type);
3190 if (field_qual_type->isFloatingType()) {
3191 if (field_qual_type->isComplexType())
3192 return 0;
3193 else {
3194 if (num_fields == 0)
3195 base_qual_type = field_qual_type;
3196 else {
3197 if (is_hva)
3198 return 0;
3199 is_hfa = true;
3200 if (field_qual_type.getTypePtr() !=
3201 base_qual_type.getTypePtr())
3202 return 0;
3203 }
3204 }
3205 } else if (field_qual_type->isVectorType() ||
3206 field_qual_type->isExtVectorType()) {
3207 if (num_fields == 0) {
3208 base_qual_type = field_qual_type;
3209 base_bitwidth = field_bitwidth;
3210 } else {
3211 if (is_hfa)
3212 return 0;
3213 is_hva = true;
3214 if (base_bitwidth != field_bitwidth)
3215 return 0;
3216 if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
3217 return 0;
3218 }
3219 } else
3220 return 0;
3221 ++num_fields;
3222 }
3223 if (base_type_ptr)
3224 *base_type_ptr = CompilerType(getASTContext(), base_qual_type);
3225 return num_fields;
3226 }
3227 }
3228 }
3229 break;
3230
3231 case clang::Type::Typedef:
3232 return IsHomogeneousAggregate(llvm::cast<clang::TypedefType>(qual_type)
3233 ->getDecl()
3234 ->getUnderlyingType()
3235 .getAsOpaquePtr(),
3236 base_type_ptr);
3237
3238 case clang::Type::Auto:
3239 return IsHomogeneousAggregate(llvm::cast<clang::AutoType>(qual_type)
3240 ->getDeducedType()
3241 .getAsOpaquePtr(),
3242 base_type_ptr);
3243
3244 case clang::Type::Elaborated:
3245 return IsHomogeneousAggregate(llvm::cast<clang::ElaboratedType>(qual_type)
3246 ->getNamedType()
3247 .getAsOpaquePtr(),
3248 base_type_ptr);
3249 default:
3250 break;
3251 }
3252 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00003253}
3254
Kate Stoneb9c1b512016-09-06 20:57:50 +00003255size_t ClangASTContext::GetNumberOfFunctionArguments(
3256 lldb::opaque_compiler_type_t type) {
3257 if (type) {
3258 clang::QualType qual_type(GetCanonicalQualType(type));
3259 const clang::FunctionProtoType *func =
3260 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
3261 if (func)
3262 return func->getNumParams();
3263 }
3264 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00003265}
3266
Greg Claytona1e5dc82015-08-11 22:53:00 +00003267CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00003268ClangASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
3269 const size_t index) {
3270 if (type) {
Greg Claytond8d4a572015-08-11 21:38:15 +00003271 clang::QualType qual_type(GetQualType(type));
Kate Stoneb9c1b512016-09-06 20:57:50 +00003272 const clang::FunctionProtoType *func =
3273 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
3274 if (func) {
3275 if (index < func->getNumParams())
3276 return CompilerType(getASTContext(), func->getParamType(index));
Greg Claytond8d4a572015-08-11 21:38:15 +00003277 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003278 }
3279 return CompilerType();
3280}
3281
3282bool ClangASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
3283 if (type) {
3284 clang::QualType qual_type(GetCanonicalQualType(type));
3285
3286 if (qual_type->isFunctionPointerType())
3287 return true;
3288
3289 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3290 switch (type_class) {
3291 default:
3292 break;
3293 case clang::Type::Typedef:
3294 return IsFunctionPointerType(llvm::cast<clang::TypedefType>(qual_type)
3295 ->getDecl()
3296 ->getUnderlyingType()
3297 .getAsOpaquePtr());
3298 case clang::Type::Auto:
3299 return IsFunctionPointerType(llvm::cast<clang::AutoType>(qual_type)
3300 ->getDeducedType()
3301 .getAsOpaquePtr());
3302 case clang::Type::Elaborated:
3303 return IsFunctionPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
3304 ->getNamedType()
3305 .getAsOpaquePtr());
3306 case clang::Type::Paren:
3307 return IsFunctionPointerType(
3308 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
3309
3310 case clang::Type::LValueReference:
3311 case clang::Type::RValueReference: {
3312 const clang::ReferenceType *reference_type =
3313 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
3314 if (reference_type)
3315 return IsFunctionPointerType(
3316 reference_type->getPointeeType().getAsOpaquePtr());
3317 } break;
3318 }
3319 }
3320 return false;
3321}
3322
3323bool ClangASTContext::IsBlockPointerType(
3324 lldb::opaque_compiler_type_t type,
3325 CompilerType *function_pointer_type_ptr) {
3326 if (type) {
3327 clang::QualType qual_type(GetCanonicalQualType(type));
3328
3329 if (qual_type->isBlockPointerType()) {
3330 if (function_pointer_type_ptr) {
3331 const clang::BlockPointerType *block_pointer_type =
3332 qual_type->getAs<clang::BlockPointerType>();
3333 QualType pointee_type = block_pointer_type->getPointeeType();
Jonas Devlieghered5b44032019-02-13 06:25:41 +00003334 QualType function_pointer_type = m_ast_up->getPointerType(pointee_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003335 *function_pointer_type_ptr =
3336 CompilerType(getASTContext(), function_pointer_type);
3337 }
3338 return true;
3339 }
3340
3341 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3342 switch (type_class) {
3343 default:
3344 break;
3345 case clang::Type::Typedef:
3346 return IsBlockPointerType(llvm::cast<clang::TypedefType>(qual_type)
3347 ->getDecl()
3348 ->getUnderlyingType()
3349 .getAsOpaquePtr(),
3350 function_pointer_type_ptr);
3351 case clang::Type::Auto:
3352 return IsBlockPointerType(llvm::cast<clang::AutoType>(qual_type)
3353 ->getDeducedType()
3354 .getAsOpaquePtr(),
3355 function_pointer_type_ptr);
3356 case clang::Type::Elaborated:
3357 return IsBlockPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
3358 ->getNamedType()
3359 .getAsOpaquePtr(),
3360 function_pointer_type_ptr);
3361 case clang::Type::Paren:
3362 return IsBlockPointerType(
3363 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3364 function_pointer_type_ptr);
3365
3366 case clang::Type::LValueReference:
3367 case clang::Type::RValueReference: {
3368 const clang::ReferenceType *reference_type =
3369 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
3370 if (reference_type)
3371 return IsBlockPointerType(
3372 reference_type->getPointeeType().getAsOpaquePtr(),
3373 function_pointer_type_ptr);
3374 } break;
3375 }
3376 }
3377 return false;
3378}
3379
3380bool ClangASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
3381 bool &is_signed) {
3382 if (!type)
3383 return false;
3384
3385 clang::QualType qual_type(GetCanonicalQualType(type));
3386 const clang::BuiltinType *builtin_type =
3387 llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
3388
3389 if (builtin_type) {
3390 if (builtin_type->isInteger()) {
3391 is_signed = builtin_type->isSignedInteger();
3392 return true;
3393 }
3394 }
3395
3396 return false;
3397}
3398
3399bool ClangASTContext::IsEnumerationType(lldb::opaque_compiler_type_t type,
3400 bool &is_signed) {
3401 if (type) {
3402 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
3403 GetCanonicalQualType(type)->getCanonicalTypeInternal());
3404
3405 if (enum_type) {
3406 IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(),
3407 is_signed);
3408 return true;
3409 }
3410 }
3411
3412 return false;
3413}
3414
3415bool ClangASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
3416 CompilerType *pointee_type) {
3417 if (type) {
3418 clang::QualType qual_type(GetCanonicalQualType(type));
3419 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3420 switch (type_class) {
3421 case clang::Type::Builtin:
3422 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
3423 default:
3424 break;
3425 case clang::BuiltinType::ObjCId:
3426 case clang::BuiltinType::ObjCClass:
3427 return true;
3428 }
3429 return false;
3430 case clang::Type::ObjCObjectPointer:
3431 if (pointee_type)
3432 pointee_type->SetCompilerType(
3433 getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)
3434 ->getPointeeType());
3435 return true;
3436 case clang::Type::BlockPointer:
3437 if (pointee_type)
3438 pointee_type->SetCompilerType(
3439 getASTContext(),
3440 llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
3441 return true;
3442 case clang::Type::Pointer:
3443 if (pointee_type)
3444 pointee_type->SetCompilerType(
3445 getASTContext(),
3446 llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
3447 return true;
3448 case clang::Type::MemberPointer:
3449 if (pointee_type)
3450 pointee_type->SetCompilerType(
3451 getASTContext(),
3452 llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
3453 return true;
3454 case clang::Type::Typedef:
3455 return IsPointerType(llvm::cast<clang::TypedefType>(qual_type)
3456 ->getDecl()
3457 ->getUnderlyingType()
3458 .getAsOpaquePtr(),
3459 pointee_type);
3460 case clang::Type::Auto:
3461 return IsPointerType(llvm::cast<clang::AutoType>(qual_type)
3462 ->getDeducedType()
3463 .getAsOpaquePtr(),
3464 pointee_type);
3465 case clang::Type::Elaborated:
3466 return IsPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
3467 ->getNamedType()
3468 .getAsOpaquePtr(),
3469 pointee_type);
3470 case clang::Type::Paren:
3471 return IsPointerType(
3472 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3473 pointee_type);
3474 default:
3475 break;
3476 }
3477 }
3478 if (pointee_type)
3479 pointee_type->Clear();
3480 return false;
3481}
3482
3483bool ClangASTContext::IsPointerOrReferenceType(
3484 lldb::opaque_compiler_type_t type, CompilerType *pointee_type) {
3485 if (type) {
3486 clang::QualType qual_type(GetCanonicalQualType(type));
3487 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3488 switch (type_class) {
3489 case clang::Type::Builtin:
3490 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
3491 default:
3492 break;
3493 case clang::BuiltinType::ObjCId:
3494 case clang::BuiltinType::ObjCClass:
3495 return true;
3496 }
3497 return false;
3498 case clang::Type::ObjCObjectPointer:
3499 if (pointee_type)
3500 pointee_type->SetCompilerType(
3501 getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)
3502 ->getPointeeType());
3503 return true;
3504 case clang::Type::BlockPointer:
3505 if (pointee_type)
3506 pointee_type->SetCompilerType(
3507 getASTContext(),
3508 llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
3509 return true;
3510 case clang::Type::Pointer:
3511 if (pointee_type)
3512 pointee_type->SetCompilerType(
3513 getASTContext(),
3514 llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
3515 return true;
3516 case clang::Type::MemberPointer:
3517 if (pointee_type)
3518 pointee_type->SetCompilerType(
3519 getASTContext(),
3520 llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
3521 return true;
3522 case clang::Type::LValueReference:
3523 if (pointee_type)
3524 pointee_type->SetCompilerType(
3525 getASTContext(),
3526 llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
3527 return true;
3528 case clang::Type::RValueReference:
3529 if (pointee_type)
3530 pointee_type->SetCompilerType(
3531 getASTContext(),
3532 llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
3533 return true;
3534 case clang::Type::Typedef:
3535 return IsPointerOrReferenceType(llvm::cast<clang::TypedefType>(qual_type)
3536 ->getDecl()
3537 ->getUnderlyingType()
3538 .getAsOpaquePtr(),
3539 pointee_type);
3540 case clang::Type::Auto:
3541 return IsPointerOrReferenceType(llvm::cast<clang::AutoType>(qual_type)
3542 ->getDeducedType()
3543 .getAsOpaquePtr(),
3544 pointee_type);
3545 case clang::Type::Elaborated:
3546 return IsPointerOrReferenceType(
3547 llvm::cast<clang::ElaboratedType>(qual_type)
3548 ->getNamedType()
3549 .getAsOpaquePtr(),
3550 pointee_type);
3551 case clang::Type::Paren:
3552 return IsPointerOrReferenceType(
3553 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3554 pointee_type);
3555 default:
3556 break;
3557 }
3558 }
3559 if (pointee_type)
3560 pointee_type->Clear();
3561 return false;
3562}
3563
3564bool ClangASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
3565 CompilerType *pointee_type,
3566 bool *is_rvalue) {
3567 if (type) {
3568 clang::QualType qual_type(GetCanonicalQualType(type));
3569 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3570
3571 switch (type_class) {
3572 case clang::Type::LValueReference:
3573 if (pointee_type)
3574 pointee_type->SetCompilerType(
3575 getASTContext(),
3576 llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
3577 if (is_rvalue)
3578 *is_rvalue = false;
3579 return true;
3580 case clang::Type::RValueReference:
3581 if (pointee_type)
3582 pointee_type->SetCompilerType(
3583 getASTContext(),
3584 llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
3585 if (is_rvalue)
3586 *is_rvalue = true;
3587 return true;
3588 case clang::Type::Typedef:
3589 return IsReferenceType(llvm::cast<clang::TypedefType>(qual_type)
3590 ->getDecl()
3591 ->getUnderlyingType()
3592 .getAsOpaquePtr(),
3593 pointee_type, is_rvalue);
3594 case clang::Type::Auto:
3595 return IsReferenceType(llvm::cast<clang::AutoType>(qual_type)
3596 ->getDeducedType()
3597 .getAsOpaquePtr(),
3598 pointee_type, is_rvalue);
3599 case clang::Type::Elaborated:
3600 return IsReferenceType(llvm::cast<clang::ElaboratedType>(qual_type)
3601 ->getNamedType()
3602 .getAsOpaquePtr(),
3603 pointee_type, is_rvalue);
3604 case clang::Type::Paren:
3605 return IsReferenceType(
3606 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3607 pointee_type, is_rvalue);
3608
3609 default:
3610 break;
3611 }
3612 }
3613 if (pointee_type)
3614 pointee_type->Clear();
3615 return false;
3616}
3617
3618bool ClangASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
3619 uint32_t &count, bool &is_complex) {
3620 if (type) {
3621 clang::QualType qual_type(GetCanonicalQualType(type));
3622
3623 if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(
3624 qual_type->getCanonicalTypeInternal())) {
3625 clang::BuiltinType::Kind kind = BT->getKind();
3626 if (kind >= clang::BuiltinType::Float &&
3627 kind <= clang::BuiltinType::LongDouble) {
3628 count = 1;
3629 is_complex = false;
3630 return true;
3631 }
3632 } else if (const clang::ComplexType *CT =
3633 llvm::dyn_cast<clang::ComplexType>(
3634 qual_type->getCanonicalTypeInternal())) {
3635 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count,
3636 is_complex)) {
3637 count = 2;
3638 is_complex = true;
3639 return true;
3640 }
3641 } else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(
3642 qual_type->getCanonicalTypeInternal())) {
3643 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count,
3644 is_complex)) {
3645 count = VT->getNumElements();
3646 is_complex = false;
3647 return true;
3648 }
3649 }
3650 }
3651 count = 0;
3652 is_complex = false;
3653 return false;
3654}
3655
3656bool ClangASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
3657 if (!type)
3658 return false;
3659
3660 clang::QualType qual_type(GetQualType(type));
3661 const clang::TagType *tag_type =
3662 llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
3663 if (tag_type) {
3664 clang::TagDecl *tag_decl = tag_type->getDecl();
3665 if (tag_decl)
3666 return tag_decl->isCompleteDefinition();
3667 return false;
3668 } else {
3669 const clang::ObjCObjectType *objc_class_type =
3670 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
3671 if (objc_class_type) {
3672 clang::ObjCInterfaceDecl *class_interface_decl =
3673 objc_class_type->getInterface();
3674 if (class_interface_decl)
3675 return class_interface_decl->getDefinition() != nullptr;
3676 return false;
3677 }
3678 }
3679 return true;
3680}
3681
3682bool ClangASTContext::IsObjCClassType(const CompilerType &type) {
3683 if (type) {
3684 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3685
3686 const clang::ObjCObjectPointerType *obj_pointer_type =
3687 llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
3688
3689 if (obj_pointer_type)
3690 return obj_pointer_type->isObjCClassType();
3691 }
3692 return false;
3693}
3694
3695bool ClangASTContext::IsObjCObjectOrInterfaceType(const CompilerType &type) {
3696 if (ClangUtil::IsClangType(type))
3697 return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
3698 return false;
3699}
3700
3701bool ClangASTContext::IsClassType(lldb::opaque_compiler_type_t type) {
3702 if (!type)
3703 return false;
3704 clang::QualType qual_type(GetCanonicalQualType(type));
3705 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3706 return (type_class == clang::Type::Record);
3707}
3708
3709bool ClangASTContext::IsEnumType(lldb::opaque_compiler_type_t type) {
3710 if (!type)
3711 return false;
3712 clang::QualType qual_type(GetCanonicalQualType(type));
3713 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3714 return (type_class == clang::Type::Enum);
3715}
3716
3717bool ClangASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
3718 if (type) {
3719 clang::QualType qual_type(GetCanonicalQualType(type));
3720 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3721 switch (type_class) {
3722 case clang::Type::Record:
3723 if (GetCompleteType(type)) {
3724 const clang::RecordType *record_type =
3725 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
3726 const clang::RecordDecl *record_decl = record_type->getDecl();
3727 if (record_decl) {
3728 const clang::CXXRecordDecl *cxx_record_decl =
3729 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
3730 if (cxx_record_decl)
3731 return cxx_record_decl->isPolymorphic();
Greg Claytond8d4a572015-08-11 21:38:15 +00003732 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003733 }
3734 break;
3735
3736 default:
3737 break;
3738 }
3739 }
3740 return false;
3741}
3742
3743bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
3744 CompilerType *dynamic_pointee_type,
3745 bool check_cplusplus,
3746 bool check_objc) {
3747 clang::QualType pointee_qual_type;
3748 if (type) {
3749 clang::QualType qual_type(GetCanonicalQualType(type));
3750 bool success = false;
3751 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3752 switch (type_class) {
3753 case clang::Type::Builtin:
3754 if (check_objc &&
3755 llvm::cast<clang::BuiltinType>(qual_type)->getKind() ==
3756 clang::BuiltinType::ObjCId) {
3757 if (dynamic_pointee_type)
3758 dynamic_pointee_type->SetCompilerType(this, type);
3759 return true;
3760 }
3761 break;
3762
3763 case clang::Type::ObjCObjectPointer:
3764 if (check_objc) {
3765 if (auto objc_pointee_type =
3766 qual_type->getPointeeType().getTypePtrOrNull()) {
3767 if (auto objc_object_type =
3768 llvm::dyn_cast_or_null<clang::ObjCObjectType>(
3769 objc_pointee_type)) {
3770 if (objc_object_type->isObjCClass())
3771 return false;
3772 }
3773 }
3774 if (dynamic_pointee_type)
3775 dynamic_pointee_type->SetCompilerType(
3776 getASTContext(),
3777 llvm::cast<clang::ObjCObjectPointerType>(qual_type)
3778 ->getPointeeType());
3779 return true;
3780 }
3781 break;
3782
3783 case clang::Type::Pointer:
3784 pointee_qual_type =
3785 llvm::cast<clang::PointerType>(qual_type)->getPointeeType();
3786 success = true;
3787 break;
3788
3789 case clang::Type::LValueReference:
3790 case clang::Type::RValueReference:
3791 pointee_qual_type =
3792 llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType();
3793 success = true;
3794 break;
3795
3796 case clang::Type::Typedef:
3797 return IsPossibleDynamicType(llvm::cast<clang::TypedefType>(qual_type)
3798 ->getDecl()
3799 ->getUnderlyingType()
3800 .getAsOpaquePtr(),
3801 dynamic_pointee_type, check_cplusplus,
3802 check_objc);
3803
3804 case clang::Type::Auto:
3805 return IsPossibleDynamicType(llvm::cast<clang::AutoType>(qual_type)
3806 ->getDeducedType()
3807 .getAsOpaquePtr(),
3808 dynamic_pointee_type, check_cplusplus,
3809 check_objc);
3810
3811 case clang::Type::Elaborated:
3812 return IsPossibleDynamicType(llvm::cast<clang::ElaboratedType>(qual_type)
3813 ->getNamedType()
3814 .getAsOpaquePtr(),
3815 dynamic_pointee_type, check_cplusplus,
3816 check_objc);
3817
3818 case clang::Type::Paren:
3819 return IsPossibleDynamicType(
3820 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3821 dynamic_pointee_type, check_cplusplus, check_objc);
3822 default:
3823 break;
3824 }
3825
3826 if (success) {
3827 // Check to make sure what we are pointing too is a possible dynamic C++
Adrian Prantl05097242018-04-30 16:49:04 +00003828 // type We currently accept any "void *" (in case we have a class that
3829 // has been watered down to an opaque pointer) and virtual C++ classes.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003830 const clang::Type::TypeClass pointee_type_class =
3831 pointee_qual_type.getCanonicalType()->getTypeClass();
3832 switch (pointee_type_class) {
3833 case clang::Type::Builtin:
3834 switch (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind()) {
3835 case clang::BuiltinType::UnknownAny:
3836 case clang::BuiltinType::Void:
3837 if (dynamic_pointee_type)
3838 dynamic_pointee_type->SetCompilerType(getASTContext(),
3839 pointee_qual_type);
3840 return true;
3841 default:
3842 break;
3843 }
3844 break;
3845
3846 case clang::Type::Record:
3847 if (check_cplusplus) {
3848 clang::CXXRecordDecl *cxx_record_decl =
3849 pointee_qual_type->getAsCXXRecordDecl();
3850 if (cxx_record_decl) {
3851 bool is_complete = cxx_record_decl->isCompleteDefinition();
3852
3853 if (is_complete)
3854 success = cxx_record_decl->isDynamicClass();
3855 else {
3856 ClangASTMetadata *metadata = ClangASTContext::GetMetadata(
3857 getASTContext(), cxx_record_decl);
3858 if (metadata)
3859 success = metadata->GetIsDynamicCXXType();
3860 else {
3861 is_complete = CompilerType(getASTContext(), pointee_qual_type)
3862 .GetCompleteType();
3863 if (is_complete)
3864 success = cxx_record_decl->isDynamicClass();
3865 else
3866 success = false;
3867 }
3868 }
3869
3870 if (success) {
3871 if (dynamic_pointee_type)
3872 dynamic_pointee_type->SetCompilerType(getASTContext(),
3873 pointee_qual_type);
3874 return true;
3875 }
3876 }
3877 }
3878 break;
3879
3880 case clang::Type::ObjCObject:
3881 case clang::Type::ObjCInterface:
3882 if (check_objc) {
3883 if (dynamic_pointee_type)
3884 dynamic_pointee_type->SetCompilerType(getASTContext(),
3885 pointee_qual_type);
3886 return true;
3887 }
3888 break;
3889
3890 default:
3891 break;
3892 }
3893 }
3894 }
3895 if (dynamic_pointee_type)
3896 dynamic_pointee_type->Clear();
3897 return false;
3898}
3899
3900bool ClangASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
3901 if (!type)
3902 return false;
3903
3904 return (GetTypeInfo(type, nullptr) & eTypeIsScalar) != 0;
3905}
3906
3907bool ClangASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
3908 if (!type)
3909 return false;
3910 return GetQualType(type)->getTypeClass() == clang::Type::Typedef;
3911}
3912
3913bool ClangASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
3914 if (!type)
3915 return false;
3916 return GetCanonicalQualType(type)->isVoidType();
3917}
3918
Alex Langforda03e2b22019-06-04 19:29:59 +00003919bool ClangASTContext::CanPassInRegisters(const CompilerType &type) {
3920 if (auto *record_decl =
3921 ClangASTContext::GetAsRecordDecl(type)) {
3922 return record_decl->canPassInRegisters();
3923 }
3924 return false;
3925}
3926
Kate Stoneb9c1b512016-09-06 20:57:50 +00003927bool ClangASTContext::SupportsLanguage(lldb::LanguageType language) {
3928 return ClangASTContextSupportsLanguage(language);
3929}
3930
3931bool ClangASTContext::GetCXXClassName(const CompilerType &type,
3932 std::string &class_name) {
3933 if (type) {
3934 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3935 if (!qual_type.isNull()) {
3936 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3937 if (cxx_record_decl) {
3938 class_name.assign(cxx_record_decl->getIdentifier()->getNameStart());
3939 return true;
3940 }
3941 }
3942 }
3943 class_name.clear();
3944 return false;
3945}
3946
3947bool ClangASTContext::IsCXXClassType(const CompilerType &type) {
3948 if (!type)
3949 return false;
3950
3951 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
Jonas Devliegherea6682a42018-12-15 00:15:33 +00003952 return !qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003953}
3954
3955bool ClangASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
3956 if (!type)
3957 return false;
3958 clang::QualType qual_type(GetCanonicalQualType(type));
3959 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type);
3960 if (tag_type)
3961 return tag_type->isBeingDefined();
3962 return false;
3963}
3964
3965bool ClangASTContext::IsObjCObjectPointerType(const CompilerType &type,
3966 CompilerType *class_type_ptr) {
3967 if (!type)
3968 return false;
3969
3970 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3971
3972 if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) {
3973 if (class_type_ptr) {
3974 if (!qual_type->isObjCClassType() && !qual_type->isObjCIdType()) {
3975 const clang::ObjCObjectPointerType *obj_pointer_type =
3976 llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
3977 if (obj_pointer_type == nullptr)
3978 class_type_ptr->Clear();
3979 else
3980 class_type_ptr->SetCompilerType(
3981 type.GetTypeSystem(),
3982 clang::QualType(obj_pointer_type->getInterfaceType(), 0)
3983 .getAsOpaquePtr());
3984 }
Greg Claytond8d4a572015-08-11 21:38:15 +00003985 }
3986 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003987 }
3988 if (class_type_ptr)
3989 class_type_ptr->Clear();
3990 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00003991}
3992
Kate Stoneb9c1b512016-09-06 20:57:50 +00003993bool ClangASTContext::GetObjCClassName(const CompilerType &type,
3994 std::string &class_name) {
3995 if (!type)
3996 return false;
Zachary Turnerd133f6a2016-03-28 22:53:41 +00003997
Kate Stoneb9c1b512016-09-06 20:57:50 +00003998 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3999
4000 const clang::ObjCObjectType *object_type =
4001 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
4002 if (object_type) {
4003 const clang::ObjCInterfaceDecl *interface = object_type->getInterface();
4004 if (interface) {
4005 class_name = interface->getNameAsString();
4006 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00004007 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004008 }
4009 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00004010}
4011
Greg Claytond8d4a572015-08-11 21:38:15 +00004012// Type Completion
Greg Claytond8d4a572015-08-11 21:38:15 +00004013
Kate Stoneb9c1b512016-09-06 20:57:50 +00004014bool ClangASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
4015 if (!type)
4016 return false;
4017 const bool allow_completion = true;
4018 return GetCompleteQualType(getASTContext(), GetQualType(type),
4019 allow_completion);
Greg Claytond8d4a572015-08-11 21:38:15 +00004020}
4021
Kate Stoneb9c1b512016-09-06 20:57:50 +00004022ConstString ClangASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
4023 std::string type_name;
4024 if (type) {
4025 clang::PrintingPolicy printing_policy(getASTContext()->getPrintingPolicy());
4026 clang::QualType qual_type(GetQualType(type));
4027 printing_policy.SuppressTagKeyword = true;
4028 const clang::TypedefType *typedef_type =
4029 qual_type->getAs<clang::TypedefType>();
4030 if (typedef_type) {
4031 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
4032 type_name = typedef_decl->getQualifiedNameAsString();
4033 } else {
4034 type_name = qual_type.getAsString(printing_policy);
Greg Claytond8d4a572015-08-11 21:38:15 +00004035 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004036 }
4037 return ConstString(type_name);
Greg Claytond8d4a572015-08-11 21:38:15 +00004038}
4039
4040uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00004041ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
4042 CompilerType *pointee_or_element_clang_type) {
4043 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00004044 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004045
4046 if (pointee_or_element_clang_type)
4047 pointee_or_element_clang_type->Clear();
4048
4049 clang::QualType qual_type(GetQualType(type));
4050
4051 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4052 switch (type_class) {
Sean Callananddf802a2017-06-02 01:24:18 +00004053 case clang::Type::Attributed:
4054 return GetTypeInfo(
4055 qual_type->getAs<clang::AttributedType>()
4056 ->getModifiedType().getAsOpaquePtr(),
4057 pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004058 case clang::Type::Builtin: {
4059 const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(
4060 qual_type->getCanonicalTypeInternal());
4061
4062 uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
4063 switch (builtin_type->getKind()) {
4064 case clang::BuiltinType::ObjCId:
4065 case clang::BuiltinType::ObjCClass:
4066 if (pointee_or_element_clang_type)
4067 pointee_or_element_clang_type->SetCompilerType(
4068 getASTContext(), getASTContext()->ObjCBuiltinClassTy);
4069 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
4070 break;
4071
4072 case clang::BuiltinType::ObjCSel:
4073 if (pointee_or_element_clang_type)
4074 pointee_or_element_clang_type->SetCompilerType(getASTContext(),
4075 getASTContext()->CharTy);
4076 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
4077 break;
4078
4079 case clang::BuiltinType::Bool:
4080 case clang::BuiltinType::Char_U:
4081 case clang::BuiltinType::UChar:
4082 case clang::BuiltinType::WChar_U:
4083 case clang::BuiltinType::Char16:
4084 case clang::BuiltinType::Char32:
4085 case clang::BuiltinType::UShort:
4086 case clang::BuiltinType::UInt:
4087 case clang::BuiltinType::ULong:
4088 case clang::BuiltinType::ULongLong:
4089 case clang::BuiltinType::UInt128:
4090 case clang::BuiltinType::Char_S:
4091 case clang::BuiltinType::SChar:
4092 case clang::BuiltinType::WChar_S:
4093 case clang::BuiltinType::Short:
4094 case clang::BuiltinType::Int:
4095 case clang::BuiltinType::Long:
4096 case clang::BuiltinType::LongLong:
4097 case clang::BuiltinType::Int128:
4098 case clang::BuiltinType::Float:
4099 case clang::BuiltinType::Double:
4100 case clang::BuiltinType::LongDouble:
4101 builtin_type_flags |= eTypeIsScalar;
4102 if (builtin_type->isInteger()) {
4103 builtin_type_flags |= eTypeIsInteger;
4104 if (builtin_type->isSignedInteger())
4105 builtin_type_flags |= eTypeIsSigned;
4106 } else if (builtin_type->isFloatingPoint())
4107 builtin_type_flags |= eTypeIsFloat;
4108 break;
4109 default:
4110 break;
4111 }
4112 return builtin_type_flags;
4113 }
4114
4115 case clang::Type::BlockPointer:
4116 if (pointee_or_element_clang_type)
4117 pointee_or_element_clang_type->SetCompilerType(
4118 getASTContext(), qual_type->getPointeeType());
4119 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
4120
4121 case clang::Type::Complex: {
4122 uint32_t complex_type_flags =
4123 eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
4124 const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(
4125 qual_type->getCanonicalTypeInternal());
4126 if (complex_type) {
4127 clang::QualType complex_element_type(complex_type->getElementType());
4128 if (complex_element_type->isIntegerType())
4129 complex_type_flags |= eTypeIsFloat;
4130 else if (complex_element_type->isFloatingType())
4131 complex_type_flags |= eTypeIsInteger;
4132 }
4133 return complex_type_flags;
4134 } break;
4135
4136 case clang::Type::ConstantArray:
4137 case clang::Type::DependentSizedArray:
4138 case clang::Type::IncompleteArray:
4139 case clang::Type::VariableArray:
4140 if (pointee_or_element_clang_type)
4141 pointee_or_element_clang_type->SetCompilerType(
4142 getASTContext(), llvm::cast<clang::ArrayType>(qual_type.getTypePtr())
4143 ->getElementType());
4144 return eTypeHasChildren | eTypeIsArray;
4145
4146 case clang::Type::DependentName:
4147 return 0;
4148 case clang::Type::DependentSizedExtVector:
4149 return eTypeHasChildren | eTypeIsVector;
4150 case clang::Type::DependentTemplateSpecialization:
4151 return eTypeIsTemplate;
4152 case clang::Type::Decltype:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004153 return CompilerType(
4154 getASTContext(),
4155 llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
4156 .GetTypeInfo(pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004157
4158 case clang::Type::Enum:
4159 if (pointee_or_element_clang_type)
4160 pointee_or_element_clang_type->SetCompilerType(
4161 getASTContext(),
4162 llvm::cast<clang::EnumType>(qual_type)->getDecl()->getIntegerType());
4163 return eTypeIsEnumeration | eTypeHasValue;
4164
4165 case clang::Type::Auto:
4166 return CompilerType(
4167 getASTContext(),
4168 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
4169 .GetTypeInfo(pointee_or_element_clang_type);
4170 case clang::Type::Elaborated:
4171 return CompilerType(
4172 getASTContext(),
4173 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
4174 .GetTypeInfo(pointee_or_element_clang_type);
4175 case clang::Type::Paren:
4176 return CompilerType(getASTContext(),
4177 llvm::cast<clang::ParenType>(qual_type)->desugar())
4178 .GetTypeInfo(pointee_or_element_clang_type);
4179
4180 case clang::Type::FunctionProto:
4181 return eTypeIsFuncPrototype | eTypeHasValue;
4182 case clang::Type::FunctionNoProto:
4183 return eTypeIsFuncPrototype | eTypeHasValue;
4184 case clang::Type::InjectedClassName:
4185 return 0;
4186
4187 case clang::Type::LValueReference:
4188 case clang::Type::RValueReference:
4189 if (pointee_or_element_clang_type)
4190 pointee_or_element_clang_type->SetCompilerType(
4191 getASTContext(),
4192 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())
4193 ->getPointeeType());
4194 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
4195
4196 case clang::Type::MemberPointer:
4197 return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
4198
4199 case clang::Type::ObjCObjectPointer:
4200 if (pointee_or_element_clang_type)
4201 pointee_or_element_clang_type->SetCompilerType(
4202 getASTContext(), qual_type->getPointeeType());
4203 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer |
4204 eTypeHasValue;
4205
4206 case clang::Type::ObjCObject:
4207 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
4208 case clang::Type::ObjCInterface:
4209 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
4210
4211 case clang::Type::Pointer:
4212 if (pointee_or_element_clang_type)
4213 pointee_or_element_clang_type->SetCompilerType(
4214 getASTContext(), qual_type->getPointeeType());
4215 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
4216
4217 case clang::Type::Record:
4218 if (qual_type->getAsCXXRecordDecl())
4219 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
4220 else
4221 return eTypeHasChildren | eTypeIsStructUnion;
4222 break;
4223 case clang::Type::SubstTemplateTypeParm:
4224 return eTypeIsTemplate;
4225 case clang::Type::TemplateTypeParm:
4226 return eTypeIsTemplate;
4227 case clang::Type::TemplateSpecialization:
4228 return eTypeIsTemplate;
4229
4230 case clang::Type::Typedef:
4231 return eTypeIsTypedef |
4232 CompilerType(getASTContext(),
4233 llvm::cast<clang::TypedefType>(qual_type)
4234 ->getDecl()
4235 ->getUnderlyingType())
4236 .GetTypeInfo(pointee_or_element_clang_type);
4237 case clang::Type::TypeOfExpr:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004238 return CompilerType(getASTContext(),
4239 llvm::cast<clang::TypeOfExprType>(qual_type)
4240 ->getUnderlyingExpr()
4241 ->getType())
4242 .GetTypeInfo(pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004243 case clang::Type::TypeOf:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004244 return CompilerType(
4245 getASTContext(),
4246 llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
4247 .GetTypeInfo(pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004248 case clang::Type::UnresolvedUsing:
4249 return 0;
4250
4251 case clang::Type::ExtVector:
4252 case clang::Type::Vector: {
4253 uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
4254 const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>(
4255 qual_type->getCanonicalTypeInternal());
4256 if (vector_type) {
4257 if (vector_type->isIntegerType())
4258 vector_type_flags |= eTypeIsFloat;
4259 else if (vector_type->isFloatingType())
4260 vector_type_flags |= eTypeIsInteger;
4261 }
4262 return vector_type_flags;
4263 }
4264 default:
4265 return 0;
4266 }
4267 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00004268}
4269
Greg Claytond8d4a572015-08-11 21:38:15 +00004270lldb::LanguageType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004271ClangASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
4272 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00004273 return lldb::eLanguageTypeC;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004274
4275 // If the type is a reference, then resolve it to what it refers to first:
4276 clang::QualType qual_type(GetCanonicalQualType(type).getNonReferenceType());
4277 if (qual_type->isAnyPointerType()) {
4278 if (qual_type->isObjCObjectPointerType())
4279 return lldb::eLanguageTypeObjC;
Adrian Prantl1db0f0c2019-05-02 23:07:23 +00004280 if (qual_type->getPointeeCXXRecordDecl())
4281 return lldb::eLanguageTypeC_plus_plus;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004282
4283 clang::QualType pointee_type(qual_type->getPointeeType());
Adrian Prantl1db0f0c2019-05-02 23:07:23 +00004284 if (pointee_type->getPointeeCXXRecordDecl())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004285 return lldb::eLanguageTypeC_plus_plus;
4286 if (pointee_type->isObjCObjectOrInterfaceType())
4287 return lldb::eLanguageTypeObjC;
4288 if (pointee_type->isObjCClassType())
4289 return lldb::eLanguageTypeObjC;
4290 if (pointee_type.getTypePtr() ==
4291 getASTContext()->ObjCBuiltinIdTy.getTypePtr())
4292 return lldb::eLanguageTypeObjC;
4293 } else {
4294 if (qual_type->isObjCObjectOrInterfaceType())
4295 return lldb::eLanguageTypeObjC;
4296 if (qual_type->getAsCXXRecordDecl())
4297 return lldb::eLanguageTypeC_plus_plus;
4298 switch (qual_type->getTypeClass()) {
4299 default:
4300 break;
4301 case clang::Type::Builtin:
4302 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
4303 default:
4304 case clang::BuiltinType::Void:
4305 case clang::BuiltinType::Bool:
4306 case clang::BuiltinType::Char_U:
4307 case clang::BuiltinType::UChar:
4308 case clang::BuiltinType::WChar_U:
4309 case clang::BuiltinType::Char16:
4310 case clang::BuiltinType::Char32:
4311 case clang::BuiltinType::UShort:
4312 case clang::BuiltinType::UInt:
4313 case clang::BuiltinType::ULong:
4314 case clang::BuiltinType::ULongLong:
4315 case clang::BuiltinType::UInt128:
4316 case clang::BuiltinType::Char_S:
4317 case clang::BuiltinType::SChar:
4318 case clang::BuiltinType::WChar_S:
4319 case clang::BuiltinType::Short:
4320 case clang::BuiltinType::Int:
4321 case clang::BuiltinType::Long:
4322 case clang::BuiltinType::LongLong:
4323 case clang::BuiltinType::Int128:
4324 case clang::BuiltinType::Float:
4325 case clang::BuiltinType::Double:
4326 case clang::BuiltinType::LongDouble:
4327 break;
4328
4329 case clang::BuiltinType::NullPtr:
4330 return eLanguageTypeC_plus_plus;
4331
4332 case clang::BuiltinType::ObjCId:
4333 case clang::BuiltinType::ObjCClass:
4334 case clang::BuiltinType::ObjCSel:
4335 return eLanguageTypeObjC;
4336
4337 case clang::BuiltinType::Dependent:
4338 case clang::BuiltinType::Overload:
4339 case clang::BuiltinType::BoundMember:
4340 case clang::BuiltinType::UnknownAny:
4341 break;
4342 }
4343 break;
4344 case clang::Type::Typedef:
4345 return CompilerType(getASTContext(),
4346 llvm::cast<clang::TypedefType>(qual_type)
4347 ->getDecl()
4348 ->getUnderlyingType())
4349 .GetMinimumLanguage();
4350 }
4351 }
4352 return lldb::eLanguageTypeC;
Greg Claytond8d4a572015-08-11 21:38:15 +00004353}
4354
4355lldb::TypeClass
Kate Stoneb9c1b512016-09-06 20:57:50 +00004356ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
4357 if (!type)
4358 return lldb::eTypeClassInvalid;
4359
4360 clang::QualType qual_type(GetQualType(type));
4361
4362 switch (qual_type->getTypeClass()) {
4363 case clang::Type::UnaryTransform:
4364 break;
4365 case clang::Type::FunctionNoProto:
4366 return lldb::eTypeClassFunction;
4367 case clang::Type::FunctionProto:
4368 return lldb::eTypeClassFunction;
4369 case clang::Type::IncompleteArray:
4370 return lldb::eTypeClassArray;
4371 case clang::Type::VariableArray:
4372 return lldb::eTypeClassArray;
4373 case clang::Type::ConstantArray:
4374 return lldb::eTypeClassArray;
4375 case clang::Type::DependentSizedArray:
4376 return lldb::eTypeClassArray;
4377 case clang::Type::DependentSizedExtVector:
4378 return lldb::eTypeClassVector;
Fangrui Song8f284882018-07-13 22:40:40 +00004379 case clang::Type::DependentVector:
4380 return lldb::eTypeClassVector;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004381 case clang::Type::ExtVector:
4382 return lldb::eTypeClassVector;
4383 case clang::Type::Vector:
4384 return lldb::eTypeClassVector;
4385 case clang::Type::Builtin:
4386 return lldb::eTypeClassBuiltin;
4387 case clang::Type::ObjCObjectPointer:
4388 return lldb::eTypeClassObjCObjectPointer;
4389 case clang::Type::BlockPointer:
4390 return lldb::eTypeClassBlockPointer;
4391 case clang::Type::Pointer:
4392 return lldb::eTypeClassPointer;
4393 case clang::Type::LValueReference:
4394 return lldb::eTypeClassReference;
4395 case clang::Type::RValueReference:
4396 return lldb::eTypeClassReference;
4397 case clang::Type::MemberPointer:
4398 return lldb::eTypeClassMemberPointer;
4399 case clang::Type::Complex:
4400 if (qual_type->isComplexType())
4401 return lldb::eTypeClassComplexFloat;
4402 else
4403 return lldb::eTypeClassComplexInteger;
4404 case clang::Type::ObjCObject:
4405 return lldb::eTypeClassObjCObject;
4406 case clang::Type::ObjCInterface:
4407 return lldb::eTypeClassObjCInterface;
4408 case clang::Type::Record: {
4409 const clang::RecordType *record_type =
4410 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4411 const clang::RecordDecl *record_decl = record_type->getDecl();
4412 if (record_decl->isUnion())
4413 return lldb::eTypeClassUnion;
4414 else if (record_decl->isStruct())
4415 return lldb::eTypeClassStruct;
4416 else
4417 return lldb::eTypeClassClass;
4418 } break;
4419 case clang::Type::Enum:
4420 return lldb::eTypeClassEnumeration;
4421 case clang::Type::Typedef:
4422 return lldb::eTypeClassTypedef;
4423 case clang::Type::UnresolvedUsing:
4424 break;
4425 case clang::Type::Paren:
4426 return CompilerType(getASTContext(),
4427 llvm::cast<clang::ParenType>(qual_type)->desugar())
4428 .GetTypeClass();
4429 case clang::Type::Auto:
4430 return CompilerType(
4431 getASTContext(),
4432 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
4433 .GetTypeClass();
4434 case clang::Type::Elaborated:
4435 return CompilerType(
4436 getASTContext(),
4437 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
4438 .GetTypeClass();
4439
4440 case clang::Type::Attributed:
4441 break;
4442 case clang::Type::TemplateTypeParm:
4443 break;
4444 case clang::Type::SubstTemplateTypeParm:
4445 break;
4446 case clang::Type::SubstTemplateTypeParmPack:
4447 break;
4448 case clang::Type::InjectedClassName:
4449 break;
4450 case clang::Type::DependentName:
4451 break;
4452 case clang::Type::DependentTemplateSpecialization:
4453 break;
4454 case clang::Type::PackExpansion:
4455 break;
4456
4457 case clang::Type::TypeOfExpr:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004458 return CompilerType(getASTContext(),
4459 llvm::cast<clang::TypeOfExprType>(qual_type)
4460 ->getUnderlyingExpr()
4461 ->getType())
4462 .GetTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00004463 case clang::Type::TypeOf:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004464 return CompilerType(
4465 getASTContext(),
4466 llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
4467 .GetTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00004468 case clang::Type::Decltype:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004469 return CompilerType(
4470 getASTContext(),
4471 llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
4472 .GetTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00004473 case clang::Type::TemplateSpecialization:
4474 break;
Pavel Labath4f19fce22017-02-17 13:39:50 +00004475 case clang::Type::DeducedTemplateSpecialization:
4476 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004477 case clang::Type::Atomic:
4478 break;
4479 case clang::Type::Pipe:
4480 break;
4481
4482 // pointer type decayed from an array or function type.
4483 case clang::Type::Decayed:
4484 break;
4485 case clang::Type::Adjusted:
4486 break;
Zachary Turner5a8ad4592016-10-05 17:07:34 +00004487 case clang::Type::ObjCTypeParam:
4488 break;
Ted Woodward66060cf2017-10-11 22:42:21 +00004489
4490 case clang::Type::DependentAddressSpace:
4491 break;
Krasimir Georgiev435e76a2019-05-07 13:59:30 +00004492 case clang::Type::MacroQualified:
4493 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004494 }
4495 // We don't know hot to display this type...
4496 return lldb::eTypeClassOther;
Greg Claytond8d4a572015-08-11 21:38:15 +00004497}
4498
Kate Stoneb9c1b512016-09-06 20:57:50 +00004499unsigned ClangASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
4500 if (type)
4501 return GetQualType(type).getQualifiers().getCVRQualifiers();
4502 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00004503}
4504
Greg Claytond8d4a572015-08-11 21:38:15 +00004505// Creating related types
Greg Claytond8d4a572015-08-11 21:38:15 +00004506
Greg Claytona1e5dc82015-08-11 22:53:00 +00004507CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004508ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
4509 uint64_t *stride) {
4510 if (type) {
4511 clang::QualType qual_type(GetCanonicalQualType(type));
4512
4513 const clang::Type *array_eletype =
4514 qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
4515
4516 if (!array_eletype)
4517 return CompilerType();
4518
4519 CompilerType element_type(getASTContext(),
4520 array_eletype->getCanonicalTypeUnqualified());
4521
4522 // TODO: the real stride will be >= this value.. find the real one!
4523 if (stride)
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00004524 if (Optional<uint64_t> size = element_type.GetByteSize(nullptr))
Adrian Prantld963a7c2019-01-15 18:07:52 +00004525 *stride = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004526
4527 return element_type;
4528 }
4529 return CompilerType();
4530}
4531
4532CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type,
4533 uint64_t size) {
4534 if (type) {
4535 clang::QualType qual_type(GetCanonicalQualType(type));
4536 if (clang::ASTContext *ast_ctx = getASTContext()) {
4537 if (size != 0)
4538 return CompilerType(
4539 ast_ctx, ast_ctx->getConstantArrayType(
4540 qual_type, llvm::APInt(64, size),
4541 clang::ArrayType::ArraySizeModifier::Normal, 0));
4542 else
4543 return CompilerType(
4544 ast_ctx,
4545 ast_ctx->getIncompleteArrayType(
4546 qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0));
Greg Claytond8d4a572015-08-11 21:38:15 +00004547 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004548 }
4549
4550 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004551}
4552
Greg Claytona1e5dc82015-08-11 22:53:00 +00004553CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004554ClangASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
4555 if (type)
4556 return CompilerType(getASTContext(), GetCanonicalQualType(type));
4557 return CompilerType();
4558}
4559
4560static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast,
4561 clang::QualType qual_type) {
4562 if (qual_type->isPointerType())
4563 qual_type = ast->getPointerType(
4564 GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType()));
4565 else
4566 qual_type = qual_type.getUnqualifiedType();
4567 qual_type.removeLocalConst();
4568 qual_type.removeLocalRestrict();
4569 qual_type.removeLocalVolatile();
4570 return qual_type;
Enrico Granata639392f2016-08-30 20:39:58 +00004571}
4572
4573CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004574ClangASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
4575 if (type)
4576 return CompilerType(
4577 getASTContext(),
4578 GetFullyUnqualifiedType_Impl(getASTContext(), GetQualType(type)));
4579 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004580}
4581
Kate Stoneb9c1b512016-09-06 20:57:50 +00004582int ClangASTContext::GetFunctionArgumentCount(
4583 lldb::opaque_compiler_type_t type) {
4584 if (type) {
4585 const clang::FunctionProtoType *func =
4586 llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType(type));
4587 if (func)
4588 return func->getNumParams();
4589 }
4590 return -1;
4591}
4592
4593CompilerType ClangASTContext::GetFunctionArgumentTypeAtIndex(
4594 lldb::opaque_compiler_type_t type, size_t idx) {
4595 if (type) {
4596 const clang::FunctionProtoType *func =
4597 llvm::dyn_cast<clang::FunctionProtoType>(GetQualType(type));
4598 if (func) {
4599 const uint32_t num_args = func->getNumParams();
4600 if (idx < num_args)
4601 return CompilerType(getASTContext(), func->getParamType(idx));
4602 }
4603 }
4604 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004605}
4606
Greg Claytona1e5dc82015-08-11 22:53:00 +00004607CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004608ClangASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
4609 if (type) {
4610 clang::QualType qual_type(GetQualType(type));
4611 const clang::FunctionProtoType *func =
4612 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
4613 if (func)
4614 return CompilerType(getASTContext(), func->getReturnType());
4615 }
4616 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004617}
4618
4619size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00004620ClangASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
4621 size_t num_functions = 0;
4622 if (type) {
4623 clang::QualType qual_type(GetCanonicalQualType(type));
4624 switch (qual_type->getTypeClass()) {
4625 case clang::Type::Record:
4626 if (GetCompleteQualType(getASTContext(), qual_type)) {
4627 const clang::RecordType *record_type =
4628 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4629 const clang::RecordDecl *record_decl = record_type->getDecl();
4630 assert(record_decl);
4631 const clang::CXXRecordDecl *cxx_record_decl =
4632 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
4633 if (cxx_record_decl)
4634 num_functions = std::distance(cxx_record_decl->method_begin(),
4635 cxx_record_decl->method_end());
4636 }
4637 break;
Enrico Granata36f51e42015-12-18 22:41:25 +00004638
Sean Callananf9c622a2016-09-30 18:44:43 +00004639 case clang::Type::ObjCObjectPointer: {
4640 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00004641 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00004642 const clang::ObjCInterfaceType *objc_interface_type =
4643 objc_class_type->getInterfaceType();
4644 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00004645 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
4646 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00004647 clang::ObjCInterfaceDecl *class_interface_decl =
4648 objc_interface_type->getDecl();
4649 if (class_interface_decl) {
4650 num_functions = std::distance(class_interface_decl->meth_begin(),
4651 class_interface_decl->meth_end());
Greg Claytond8d4a572015-08-11 21:38:15 +00004652 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004653 }
4654 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00004655 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004656
4657 case clang::Type::ObjCObject:
4658 case clang::Type::ObjCInterface:
4659 if (GetCompleteType(type)) {
4660 const clang::ObjCObjectType *objc_class_type =
4661 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
4662 if (objc_class_type) {
4663 clang::ObjCInterfaceDecl *class_interface_decl =
4664 objc_class_type->getInterface();
4665 if (class_interface_decl)
4666 num_functions = std::distance(class_interface_decl->meth_begin(),
4667 class_interface_decl->meth_end());
4668 }
4669 }
4670 break;
4671
4672 case clang::Type::Typedef:
4673 return CompilerType(getASTContext(),
4674 llvm::cast<clang::TypedefType>(qual_type)
4675 ->getDecl()
4676 ->getUnderlyingType())
4677 .GetNumMemberFunctions();
4678
4679 case clang::Type::Auto:
4680 return CompilerType(
4681 getASTContext(),
4682 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
4683 .GetNumMemberFunctions();
4684
4685 case clang::Type::Elaborated:
4686 return CompilerType(
4687 getASTContext(),
4688 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
4689 .GetNumMemberFunctions();
4690
4691 case clang::Type::Paren:
4692 return CompilerType(getASTContext(),
4693 llvm::cast<clang::ParenType>(qual_type)->desugar())
4694 .GetNumMemberFunctions();
4695
4696 default:
4697 break;
Greg Claytond8d4a572015-08-11 21:38:15 +00004698 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004699 }
4700 return num_functions;
Greg Claytond8d4a572015-08-11 21:38:15 +00004701}
4702
4703TypeMemberFunctionImpl
Kate Stoneb9c1b512016-09-06 20:57:50 +00004704ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
4705 size_t idx) {
4706 std::string name;
4707 MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
4708 CompilerType clang_type;
4709 CompilerDecl clang_decl;
4710 if (type) {
4711 clang::QualType qual_type(GetCanonicalQualType(type));
4712 switch (qual_type->getTypeClass()) {
4713 case clang::Type::Record:
4714 if (GetCompleteQualType(getASTContext(), qual_type)) {
4715 const clang::RecordType *record_type =
4716 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4717 const clang::RecordDecl *record_decl = record_type->getDecl();
4718 assert(record_decl);
4719 const clang::CXXRecordDecl *cxx_record_decl =
4720 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
4721 if (cxx_record_decl) {
4722 auto method_iter = cxx_record_decl->method_begin();
4723 auto method_end = cxx_record_decl->method_end();
4724 if (idx <
4725 static_cast<size_t>(std::distance(method_iter, method_end))) {
4726 std::advance(method_iter, idx);
4727 clang::CXXMethodDecl *cxx_method_decl =
4728 method_iter->getCanonicalDecl();
4729 if (cxx_method_decl) {
4730 name = cxx_method_decl->getDeclName().getAsString();
4731 if (cxx_method_decl->isStatic())
4732 kind = lldb::eMemberFunctionKindStaticMethod;
4733 else if (llvm::isa<clang::CXXConstructorDecl>(cxx_method_decl))
4734 kind = lldb::eMemberFunctionKindConstructor;
4735 else if (llvm::isa<clang::CXXDestructorDecl>(cxx_method_decl))
4736 kind = lldb::eMemberFunctionKindDestructor;
4737 else
4738 kind = lldb::eMemberFunctionKindInstanceMethod;
4739 clang_type = CompilerType(
4740 this, cxx_method_decl->getType().getAsOpaquePtr());
4741 clang_decl = CompilerDecl(this, cxx_method_decl);
4742 }
4743 }
Greg Claytond8d4a572015-08-11 21:38:15 +00004744 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004745 }
4746 break;
Greg Claytond8d4a572015-08-11 21:38:15 +00004747
Sean Callananf9c622a2016-09-30 18:44:43 +00004748 case clang::Type::ObjCObjectPointer: {
4749 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00004750 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00004751 const clang::ObjCInterfaceType *objc_interface_type =
4752 objc_class_type->getInterfaceType();
4753 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00004754 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
4755 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00004756 clang::ObjCInterfaceDecl *class_interface_decl =
4757 objc_interface_type->getDecl();
4758 if (class_interface_decl) {
4759 auto method_iter = class_interface_decl->meth_begin();
4760 auto method_end = class_interface_decl->meth_end();
4761 if (idx <
4762 static_cast<size_t>(std::distance(method_iter, method_end))) {
4763 std::advance(method_iter, idx);
4764 clang::ObjCMethodDecl *objc_method_decl =
4765 method_iter->getCanonicalDecl();
4766 if (objc_method_decl) {
4767 clang_decl = CompilerDecl(this, objc_method_decl);
4768 name = objc_method_decl->getSelector().getAsString();
4769 if (objc_method_decl->isClassMethod())
4770 kind = lldb::eMemberFunctionKindStaticMethod;
4771 else
4772 kind = lldb::eMemberFunctionKindInstanceMethod;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004773 }
4774 }
Greg Claytond8d4a572015-08-11 21:38:15 +00004775 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004776 }
4777 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00004778 }
Greg Claytond8d4a572015-08-11 21:38:15 +00004779
Kate Stoneb9c1b512016-09-06 20:57:50 +00004780 case clang::Type::ObjCObject:
4781 case clang::Type::ObjCInterface:
4782 if (GetCompleteType(type)) {
4783 const clang::ObjCObjectType *objc_class_type =
4784 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
4785 if (objc_class_type) {
4786 clang::ObjCInterfaceDecl *class_interface_decl =
4787 objc_class_type->getInterface();
4788 if (class_interface_decl) {
4789 auto method_iter = class_interface_decl->meth_begin();
4790 auto method_end = class_interface_decl->meth_end();
4791 if (idx <
4792 static_cast<size_t>(std::distance(method_iter, method_end))) {
4793 std::advance(method_iter, idx);
4794 clang::ObjCMethodDecl *objc_method_decl =
4795 method_iter->getCanonicalDecl();
4796 if (objc_method_decl) {
4797 clang_decl = CompilerDecl(this, objc_method_decl);
4798 name = objc_method_decl->getSelector().getAsString();
4799 if (objc_method_decl->isClassMethod())
4800 kind = lldb::eMemberFunctionKindStaticMethod;
4801 else
4802 kind = lldb::eMemberFunctionKindInstanceMethod;
4803 }
4804 }
4805 }
Ewan Crawford27fc7a72016-03-15 09:50:16 +00004806 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004807 }
4808 break;
Ewan Crawford27fc7a72016-03-15 09:50:16 +00004809
Kate Stoneb9c1b512016-09-06 20:57:50 +00004810 case clang::Type::Typedef:
4811 return GetMemberFunctionAtIndex(llvm::cast<clang::TypedefType>(qual_type)
4812 ->getDecl()
4813 ->getUnderlyingType()
4814 .getAsOpaquePtr(),
4815 idx);
Ewan Crawford27fc7a72016-03-15 09:50:16 +00004816
Kate Stoneb9c1b512016-09-06 20:57:50 +00004817 case clang::Type::Auto:
4818 return GetMemberFunctionAtIndex(llvm::cast<clang::AutoType>(qual_type)
4819 ->getDeducedType()
4820 .getAsOpaquePtr(),
4821 idx);
Greg Clayton56939cb2015-09-17 22:23:34 +00004822
Kate Stoneb9c1b512016-09-06 20:57:50 +00004823 case clang::Type::Elaborated:
4824 return GetMemberFunctionAtIndex(
4825 llvm::cast<clang::ElaboratedType>(qual_type)
4826 ->getNamedType()
4827 .getAsOpaquePtr(),
4828 idx);
Greg Clayton56939cb2015-09-17 22:23:34 +00004829
Kate Stoneb9c1b512016-09-06 20:57:50 +00004830 case clang::Type::Paren:
4831 return GetMemberFunctionAtIndex(
4832 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
4833 idx);
4834
4835 default:
4836 break;
Greg Clayton56939cb2015-09-17 22:23:34 +00004837 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004838 }
Greg Clayton56939cb2015-09-17 22:23:34 +00004839
Kate Stoneb9c1b512016-09-06 20:57:50 +00004840 if (kind == eMemberFunctionKindUnknown)
4841 return TypeMemberFunctionImpl();
4842 else
4843 return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
Greg Clayton56939cb2015-09-17 22:23:34 +00004844}
4845
Greg Claytona1e5dc82015-08-11 22:53:00 +00004846CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004847ClangASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
4848 if (type)
4849 return CompilerType(getASTContext(),
4850 GetQualType(type).getNonReferenceType());
4851 return CompilerType();
4852}
4853
4854CompilerType ClangASTContext::CreateTypedefType(
4855 const CompilerType &type, const char *typedef_name,
4856 const CompilerDeclContext &compiler_decl_ctx) {
4857 if (type && typedef_name && typedef_name[0]) {
4858 ClangASTContext *ast =
4859 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
4860 if (!ast)
4861 return CompilerType();
4862 clang::ASTContext *clang_ast = ast->getASTContext();
4863 clang::QualType qual_type(ClangUtil::GetQualType(type));
4864
4865 clang::DeclContext *decl_ctx =
4866 ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
4867 if (decl_ctx == nullptr)
4868 decl_ctx = ast->getASTContext()->getTranslationUnitDecl();
4869
4870 clang::TypedefDecl *decl = clang::TypedefDecl::Create(
4871 *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
4872 &clang_ast->Idents.get(typedef_name),
4873 clang_ast->getTrivialTypeSourceInfo(qual_type));
4874
4875 decl->setAccess(clang::AS_public); // TODO respect proper access specifier
4876
Aleksandr Urakov709426b2018-09-10 08:08:43 +00004877 decl_ctx->addDecl(decl);
4878
Kate Stoneb9c1b512016-09-06 20:57:50 +00004879 // Get a uniqued clang::QualType for the typedef decl type
4880 return CompilerType(clang_ast, clang_ast->getTypedefType(decl));
4881 }
4882 return CompilerType();
4883}
4884
4885CompilerType
4886ClangASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
4887 if (type) {
4888 clang::QualType qual_type(GetQualType(type));
4889 return CompilerType(getASTContext(),
4890 qual_type.getTypePtr()->getPointeeType());
4891 }
4892 return CompilerType();
4893}
4894
4895CompilerType
4896ClangASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
4897 if (type) {
4898 clang::QualType qual_type(GetQualType(type));
4899
4900 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4901 switch (type_class) {
4902 case clang::Type::ObjCObject:
4903 case clang::Type::ObjCInterface:
4904 return CompilerType(getASTContext(),
4905 getASTContext()->getObjCObjectPointerType(qual_type));
4906
4907 default:
4908 return CompilerType(getASTContext(),
4909 getASTContext()->getPointerType(qual_type));
Greg Claytond8d4a572015-08-11 21:38:15 +00004910 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004911 }
4912 return CompilerType();
4913}
4914
4915CompilerType
4916ClangASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
4917 if (type)
4918 return CompilerType(this, getASTContext()
4919 ->getLValueReferenceType(GetQualType(type))
4920 .getAsOpaquePtr());
4921 else
Greg Claytona1e5dc82015-08-11 22:53:00 +00004922 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004923}
4924
Kate Stoneb9c1b512016-09-06 20:57:50 +00004925CompilerType
4926ClangASTContext::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
4927 if (type)
4928 return CompilerType(this, getASTContext()
4929 ->getRValueReferenceType(GetQualType(type))
4930 .getAsOpaquePtr());
4931 else
4932 return CompilerType();
4933}
4934
4935CompilerType
4936ClangASTContext::AddConstModifier(lldb::opaque_compiler_type_t type) {
4937 if (type) {
4938 clang::QualType result(GetQualType(type));
4939 result.addConst();
4940 return CompilerType(this, result.getAsOpaquePtr());
4941 }
4942 return CompilerType();
4943}
4944
4945CompilerType
4946ClangASTContext::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
4947 if (type) {
4948 clang::QualType result(GetQualType(type));
4949 result.addVolatile();
4950 return CompilerType(this, result.getAsOpaquePtr());
4951 }
4952 return CompilerType();
4953}
4954
4955CompilerType
4956ClangASTContext::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
4957 if (type) {
4958 clang::QualType result(GetQualType(type));
4959 result.addRestrict();
4960 return CompilerType(this, result.getAsOpaquePtr());
4961 }
4962 return CompilerType();
4963}
4964
4965CompilerType
4966ClangASTContext::CreateTypedef(lldb::opaque_compiler_type_t type,
4967 const char *typedef_name,
4968 const CompilerDeclContext &compiler_decl_ctx) {
4969 if (type) {
4970 clang::ASTContext *clang_ast = getASTContext();
4971 clang::QualType qual_type(GetQualType(type));
4972
4973 clang::DeclContext *decl_ctx =
4974 ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
4975 if (decl_ctx == nullptr)
4976 decl_ctx = getASTContext()->getTranslationUnitDecl();
4977
4978 clang::TypedefDecl *decl = clang::TypedefDecl::Create(
4979 *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
4980 &clang_ast->Idents.get(typedef_name),
4981 clang_ast->getTrivialTypeSourceInfo(qual_type));
4982
4983 clang::TagDecl *tdecl = nullptr;
4984 if (!qual_type.isNull()) {
4985 if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
4986 tdecl = rt->getDecl();
4987 if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
4988 tdecl = et->getDecl();
4989 }
4990
4991 // Check whether this declaration is an anonymous struct, union, or enum,
Adrian Prantl05097242018-04-30 16:49:04 +00004992 // hidden behind a typedef. If so, we try to check whether we have a
4993 // typedef tag to attach to the original record declaration
Kate Stoneb9c1b512016-09-06 20:57:50 +00004994 if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
4995 tdecl->setTypedefNameForAnonDecl(decl);
4996
4997 decl->setAccess(clang::AS_public); // TODO respect proper access specifier
4998
4999 // Get a uniqued clang::QualType for the typedef decl type
5000 return CompilerType(this, clang_ast->getTypedefType(decl).getAsOpaquePtr());
5001 }
5002 return CompilerType();
5003}
5004
5005CompilerType
5006ClangASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
5007 if (type) {
5008 const clang::TypedefType *typedef_type =
5009 llvm::dyn_cast<clang::TypedefType>(GetQualType(type));
5010 if (typedef_type)
5011 return CompilerType(getASTContext(),
5012 typedef_type->getDecl()->getUnderlyingType());
5013 }
5014 return CompilerType();
5015}
Greg Claytond8d4a572015-08-11 21:38:15 +00005016
Greg Claytond8d4a572015-08-11 21:38:15 +00005017// Create related types using the current type's AST
Greg Claytond8d4a572015-08-11 21:38:15 +00005018
Kate Stoneb9c1b512016-09-06 20:57:50 +00005019CompilerType ClangASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
5020 return ClangASTContext::GetBasicType(getASTContext(), basic_type);
Greg Claytond8d4a572015-08-11 21:38:15 +00005021}
Greg Claytond8d4a572015-08-11 21:38:15 +00005022// Exploring the type
Greg Claytond8d4a572015-08-11 21:38:15 +00005023
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005024Optional<uint64_t>
5025ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
5026 ExecutionContextScope *exe_scope) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005027 if (GetCompleteType(type)) {
Greg Claytond8d4a572015-08-11 21:38:15 +00005028 clang::QualType qual_type(GetCanonicalQualType(type));
Greg Claytond8d4a572015-08-11 21:38:15 +00005029 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005030 switch (type_class) {
5031 case clang::Type::Record:
5032 if (GetCompleteType(type))
5033 return getASTContext()->getTypeSize(qual_type);
5034 else
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005035 return None;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005036 break;
Enrico Granata36f51e42015-12-18 22:41:25 +00005037
Kate Stoneb9c1b512016-09-06 20:57:50 +00005038 case clang::Type::ObjCInterface:
5039 case clang::Type::ObjCObject: {
5040 ExecutionContext exe_ctx(exe_scope);
5041 Process *process = exe_ctx.GetProcessPtr();
5042 if (process) {
Alex Langforde823bbe2019-06-10 20:53:23 +00005043 ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005044 if (objc_runtime) {
5045 uint64_t bit_size = 0;
5046 if (objc_runtime->GetTypeBitSize(
5047 CompilerType(getASTContext(), qual_type), bit_size))
5048 return bit_size;
5049 }
5050 } else {
5051 static bool g_printed = false;
5052 if (!g_printed) {
5053 StreamString s;
5054 DumpTypeDescription(type, &s);
5055
5056 llvm::outs() << "warning: trying to determine the size of type ";
5057 llvm::outs() << s.GetString() << "\n";
5058 llvm::outs() << "without a valid ExecutionContext. this is not "
5059 "reliable. please file a bug against LLDB.\n";
5060 llvm::outs() << "backtrace:\n";
5061 llvm::sys::PrintStackTrace(llvm::outs());
5062 llvm::outs() << "\n";
5063 g_printed = true;
5064 }
5065 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005066 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005067 LLVM_FALLTHROUGH;
5068 default:
5069 const uint32_t bit_size = getASTContext()->getTypeSize(qual_type);
5070 if (bit_size == 0) {
5071 if (qual_type->isIncompleteArrayType())
5072 return getASTContext()->getTypeSize(
5073 qual_type->getArrayElementTypeNoTypeQual()
5074 ->getCanonicalTypeUnqualified());
5075 }
5076 if (qual_type->isObjCObjectOrInterfaceType())
5077 return bit_size +
5078 getASTContext()->getTypeSize(
5079 getASTContext()->ObjCBuiltinClassTy);
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005080 // Function types actually have a size of 0, that's not an error.
5081 if (qual_type->isFunctionProtoType())
5082 return bit_size;
5083 if (bit_size)
5084 return bit_size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005085 }
5086 }
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005087 return None;
Greg Claytond8d4a572015-08-11 21:38:15 +00005088}
5089
Davide Italiano36f13e42019-08-12 20:03:19 +00005090llvm::Optional<size_t>
5091ClangASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005092 if (GetCompleteType(type))
5093 return getASTContext()->getTypeAlign(GetQualType(type));
Davide Italiano36f13e42019-08-12 20:03:19 +00005094 return {};
Kate Stoneb9c1b512016-09-06 20:57:50 +00005095}
5096
5097lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
5098 uint64_t &count) {
5099 if (!type)
5100 return lldb::eEncodingInvalid;
5101
5102 count = 1;
5103 clang::QualType qual_type(GetCanonicalQualType(type));
5104
5105 switch (qual_type->getTypeClass()) {
5106 case clang::Type::UnaryTransform:
5107 break;
5108
5109 case clang::Type::FunctionNoProto:
5110 case clang::Type::FunctionProto:
5111 break;
5112
5113 case clang::Type::IncompleteArray:
5114 case clang::Type::VariableArray:
5115 break;
5116
5117 case clang::Type::ConstantArray:
5118 break;
5119
Fangrui Song8f284882018-07-13 22:40:40 +00005120 case clang::Type::DependentVector:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005121 case clang::Type::ExtVector:
5122 case clang::Type::Vector:
5123 // TODO: Set this to more than one???
5124 break;
5125
5126 case clang::Type::Builtin:
5127 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5128 case clang::BuiltinType::Void:
5129 break;
5130
5131 case clang::BuiltinType::Bool:
5132 case clang::BuiltinType::Char_S:
5133 case clang::BuiltinType::SChar:
5134 case clang::BuiltinType::WChar_S:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005135 case clang::BuiltinType::Short:
5136 case clang::BuiltinType::Int:
5137 case clang::BuiltinType::Long:
5138 case clang::BuiltinType::LongLong:
5139 case clang::BuiltinType::Int128:
5140 return lldb::eEncodingSint;
5141
5142 case clang::BuiltinType::Char_U:
5143 case clang::BuiltinType::UChar:
5144 case clang::BuiltinType::WChar_U:
Richard Smith51d12d82018-05-02 02:43:22 +00005145 case clang::BuiltinType::Char8:
5146 case clang::BuiltinType::Char16:
5147 case clang::BuiltinType::Char32:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005148 case clang::BuiltinType::UShort:
5149 case clang::BuiltinType::UInt:
5150 case clang::BuiltinType::ULong:
5151 case clang::BuiltinType::ULongLong:
5152 case clang::BuiltinType::UInt128:
5153 return lldb::eEncodingUint;
5154
Ilya Biryukovfc48ac62018-06-05 10:07:07 +00005155 // Fixed point types. Note that they are currently ignored.
5156 case clang::BuiltinType::ShortAccum:
5157 case clang::BuiltinType::Accum:
5158 case clang::BuiltinType::LongAccum:
5159 case clang::BuiltinType::UShortAccum:
5160 case clang::BuiltinType::UAccum:
5161 case clang::BuiltinType::ULongAccum:
Fangrui Songa5e59c52018-06-14 18:19:40 +00005162 case clang::BuiltinType::ShortFract:
Fangrui Songa5e59c52018-06-14 18:19:40 +00005163 case clang::BuiltinType::Fract:
5164 case clang::BuiltinType::LongFract:
5165 case clang::BuiltinType::UShortFract:
5166 case clang::BuiltinType::UFract:
5167 case clang::BuiltinType::ULongFract:
5168 case clang::BuiltinType::SatShortAccum:
5169 case clang::BuiltinType::SatAccum:
5170 case clang::BuiltinType::SatLongAccum:
5171 case clang::BuiltinType::SatUShortAccum:
5172 case clang::BuiltinType::SatUAccum:
5173 case clang::BuiltinType::SatULongAccum:
5174 case clang::BuiltinType::SatShortFract:
5175 case clang::BuiltinType::SatFract:
5176 case clang::BuiltinType::SatLongFract:
5177 case clang::BuiltinType::SatUShortFract:
5178 case clang::BuiltinType::SatUFract:
5179 case clang::BuiltinType::SatULongFract:
Ilya Biryukovfc48ac62018-06-05 10:07:07 +00005180 break;
5181
Kate Stoneb9c1b512016-09-06 20:57:50 +00005182 case clang::BuiltinType::Half:
5183 case clang::BuiltinType::Float:
Ted Woodward4355c7c2017-09-20 19:16:53 +00005184 case clang::BuiltinType::Float16:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005185 case clang::BuiltinType::Float128:
5186 case clang::BuiltinType::Double:
5187 case clang::BuiltinType::LongDouble:
5188 return lldb::eEncodingIEEE754;
5189
5190 case clang::BuiltinType::ObjCClass:
5191 case clang::BuiltinType::ObjCId:
5192 case clang::BuiltinType::ObjCSel:
5193 return lldb::eEncodingUint;
5194
5195 case clang::BuiltinType::NullPtr:
5196 return lldb::eEncodingUint;
5197
5198 case clang::BuiltinType::Kind::ARCUnbridgedCast:
5199 case clang::BuiltinType::Kind::BoundMember:
5200 case clang::BuiltinType::Kind::BuiltinFn:
5201 case clang::BuiltinType::Kind::Dependent:
5202 case clang::BuiltinType::Kind::OCLClkEvent:
5203 case clang::BuiltinType::Kind::OCLEvent:
5204 case clang::BuiltinType::Kind::OCLImage1dRO:
5205 case clang::BuiltinType::Kind::OCLImage1dWO:
5206 case clang::BuiltinType::Kind::OCLImage1dRW:
5207 case clang::BuiltinType::Kind::OCLImage1dArrayRO:
5208 case clang::BuiltinType::Kind::OCLImage1dArrayWO:
5209 case clang::BuiltinType::Kind::OCLImage1dArrayRW:
5210 case clang::BuiltinType::Kind::OCLImage1dBufferRO:
5211 case clang::BuiltinType::Kind::OCLImage1dBufferWO:
5212 case clang::BuiltinType::Kind::OCLImage1dBufferRW:
5213 case clang::BuiltinType::Kind::OCLImage2dRO:
5214 case clang::BuiltinType::Kind::OCLImage2dWO:
5215 case clang::BuiltinType::Kind::OCLImage2dRW:
5216 case clang::BuiltinType::Kind::OCLImage2dArrayRO:
5217 case clang::BuiltinType::Kind::OCLImage2dArrayWO:
5218 case clang::BuiltinType::Kind::OCLImage2dArrayRW:
5219 case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
5220 case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
5221 case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
5222 case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
5223 case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
5224 case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
5225 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
5226 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
5227 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
5228 case clang::BuiltinType::Kind::OCLImage2dDepthRO:
5229 case clang::BuiltinType::Kind::OCLImage2dDepthWO:
5230 case clang::BuiltinType::Kind::OCLImage2dDepthRW:
5231 case clang::BuiltinType::Kind::OCLImage2dMSAARO:
5232 case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
5233 case clang::BuiltinType::Kind::OCLImage2dMSAARW:
5234 case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
5235 case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
5236 case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
5237 case clang::BuiltinType::Kind::OCLImage3dRO:
5238 case clang::BuiltinType::Kind::OCLImage3dWO:
5239 case clang::BuiltinType::Kind::OCLImage3dRW:
5240 case clang::BuiltinType::Kind::OCLQueue:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005241 case clang::BuiltinType::Kind::OCLReserveID:
5242 case clang::BuiltinType::Kind::OCLSampler:
5243 case clang::BuiltinType::Kind::OMPArraySection:
5244 case clang::BuiltinType::Kind::Overload:
5245 case clang::BuiltinType::Kind::PseudoObject:
5246 case clang::BuiltinType::Kind::UnknownAny:
5247 break;
Jorge Gorbe Moyaa6e6c182018-11-08 22:04:58 +00005248
5249 case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload:
5250 case clang::BuiltinType::OCLIntelSubgroupAVCImePayload:
5251 case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload:
5252 case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload:
5253 case clang::BuiltinType::OCLIntelSubgroupAVCMceResult:
5254 case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
5255 case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
5256 case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
5257 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout:
5258 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout:
5259 case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin:
5260 case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
5261 break;
Raphael Isemann339b5d12019-08-09 09:58:47 +00005262
5263 case clang::BuiltinType::SveBool:
5264 case clang::BuiltinType::SveInt8:
5265 case clang::BuiltinType::SveInt16:
5266 case clang::BuiltinType::SveInt32:
5267 case clang::BuiltinType::SveInt64:
5268 case clang::BuiltinType::SveUint8:
5269 case clang::BuiltinType::SveUint16:
5270 case clang::BuiltinType::SveUint32:
5271 case clang::BuiltinType::SveUint64:
5272 case clang::BuiltinType::SveFloat16:
5273 case clang::BuiltinType::SveFloat32:
5274 case clang::BuiltinType::SveFloat64:
5275 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005276 }
5277 break;
Adrian Prantl05097242018-04-30 16:49:04 +00005278 // All pointer types are represented as unsigned integer encodings. We may
5279 // nee to add a eEncodingPointer if we ever need to know the difference
Kate Stoneb9c1b512016-09-06 20:57:50 +00005280 case clang::Type::ObjCObjectPointer:
5281 case clang::Type::BlockPointer:
5282 case clang::Type::Pointer:
5283 case clang::Type::LValueReference:
5284 case clang::Type::RValueReference:
5285 case clang::Type::MemberPointer:
5286 return lldb::eEncodingUint;
5287 case clang::Type::Complex: {
5288 lldb::Encoding encoding = lldb::eEncodingIEEE754;
5289 if (qual_type->isComplexType())
5290 encoding = lldb::eEncodingIEEE754;
5291 else {
5292 const clang::ComplexType *complex_type =
5293 qual_type->getAsComplexIntegerType();
5294 if (complex_type)
5295 encoding = CompilerType(getASTContext(), complex_type->getElementType())
5296 .GetEncoding(count);
5297 else
5298 encoding = lldb::eEncodingSint;
5299 }
5300 count = 2;
5301 return encoding;
5302 }
5303
5304 case clang::Type::ObjCInterface:
5305 break;
5306 case clang::Type::Record:
5307 break;
5308 case clang::Type::Enum:
5309 return lldb::eEncodingSint;
5310 case clang::Type::Typedef:
5311 return CompilerType(getASTContext(),
5312 llvm::cast<clang::TypedefType>(qual_type)
5313 ->getDecl()
5314 ->getUnderlyingType())
5315 .GetEncoding(count);
5316
5317 case clang::Type::Auto:
5318 return CompilerType(
5319 getASTContext(),
5320 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
5321 .GetEncoding(count);
5322
5323 case clang::Type::Elaborated:
5324 return CompilerType(
5325 getASTContext(),
5326 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
5327 .GetEncoding(count);
5328
5329 case clang::Type::Paren:
5330 return CompilerType(getASTContext(),
5331 llvm::cast<clang::ParenType>(qual_type)->desugar())
5332 .GetEncoding(count);
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005333 case clang::Type::TypeOfExpr:
5334 return CompilerType(getASTContext(),
5335 llvm::cast<clang::TypeOfExprType>(qual_type)
5336 ->getUnderlyingExpr()
5337 ->getType())
5338 .GetEncoding(count);
5339 case clang::Type::TypeOf:
5340 return CompilerType(
5341 getASTContext(),
5342 llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
5343 .GetEncoding(count);
5344 case clang::Type::Decltype:
5345 return CompilerType(
5346 getASTContext(),
5347 llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
5348 .GetEncoding(count);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005349 case clang::Type::DependentSizedArray:
5350 case clang::Type::DependentSizedExtVector:
5351 case clang::Type::UnresolvedUsing:
5352 case clang::Type::Attributed:
5353 case clang::Type::TemplateTypeParm:
5354 case clang::Type::SubstTemplateTypeParm:
5355 case clang::Type::SubstTemplateTypeParmPack:
5356 case clang::Type::InjectedClassName:
5357 case clang::Type::DependentName:
5358 case clang::Type::DependentTemplateSpecialization:
5359 case clang::Type::PackExpansion:
5360 case clang::Type::ObjCObject:
5361
Kate Stoneb9c1b512016-09-06 20:57:50 +00005362 case clang::Type::TemplateSpecialization:
Pavel Labath4f19fce22017-02-17 13:39:50 +00005363 case clang::Type::DeducedTemplateSpecialization:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005364 case clang::Type::Atomic:
5365 case clang::Type::Adjusted:
5366 case clang::Type::Pipe:
5367 break;
5368
5369 // pointer type decayed from an array or function type.
5370 case clang::Type::Decayed:
5371 break;
Zachary Turner5a8ad4592016-10-05 17:07:34 +00005372 case clang::Type::ObjCTypeParam:
5373 break;
Ted Woodward66060cf2017-10-11 22:42:21 +00005374
5375 case clang::Type::DependentAddressSpace:
5376 break;
Krasimir Georgiev435e76a2019-05-07 13:59:30 +00005377 case clang::Type::MacroQualified:
5378 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005379 }
5380 count = 0;
5381 return lldb::eEncodingInvalid;
5382}
5383
5384lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
5385 if (!type)
5386 return lldb::eFormatDefault;
5387
5388 clang::QualType qual_type(GetCanonicalQualType(type));
5389
5390 switch (qual_type->getTypeClass()) {
5391 case clang::Type::UnaryTransform:
5392 break;
5393
5394 case clang::Type::FunctionNoProto:
5395 case clang::Type::FunctionProto:
5396 break;
5397
5398 case clang::Type::IncompleteArray:
5399 case clang::Type::VariableArray:
5400 break;
5401
5402 case clang::Type::ConstantArray:
5403 return lldb::eFormatVoid; // no value
5404
Fangrui Song8f284882018-07-13 22:40:40 +00005405 case clang::Type::DependentVector:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005406 case clang::Type::ExtVector:
5407 case clang::Type::Vector:
5408 break;
5409
5410 case clang::Type::Builtin:
5411 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5412 // default: assert(0 && "Unknown builtin type!");
5413 case clang::BuiltinType::UnknownAny:
5414 case clang::BuiltinType::Void:
5415 case clang::BuiltinType::BoundMember:
5416 break;
5417
5418 case clang::BuiltinType::Bool:
5419 return lldb::eFormatBoolean;
5420 case clang::BuiltinType::Char_S:
5421 case clang::BuiltinType::SChar:
5422 case clang::BuiltinType::WChar_S:
5423 case clang::BuiltinType::Char_U:
5424 case clang::BuiltinType::UChar:
5425 case clang::BuiltinType::WChar_U:
5426 return lldb::eFormatChar;
5427 case clang::BuiltinType::Char16:
5428 return lldb::eFormatUnicode16;
5429 case clang::BuiltinType::Char32:
5430 return lldb::eFormatUnicode32;
5431 case clang::BuiltinType::UShort:
5432 return lldb::eFormatUnsigned;
5433 case clang::BuiltinType::Short:
5434 return lldb::eFormatDecimal;
5435 case clang::BuiltinType::UInt:
5436 return lldb::eFormatUnsigned;
5437 case clang::BuiltinType::Int:
5438 return lldb::eFormatDecimal;
5439 case clang::BuiltinType::ULong:
5440 return lldb::eFormatUnsigned;
5441 case clang::BuiltinType::Long:
5442 return lldb::eFormatDecimal;
5443 case clang::BuiltinType::ULongLong:
5444 return lldb::eFormatUnsigned;
5445 case clang::BuiltinType::LongLong:
5446 return lldb::eFormatDecimal;
5447 case clang::BuiltinType::UInt128:
5448 return lldb::eFormatUnsigned;
5449 case clang::BuiltinType::Int128:
5450 return lldb::eFormatDecimal;
5451 case clang::BuiltinType::Half:
5452 case clang::BuiltinType::Float:
5453 case clang::BuiltinType::Double:
5454 case clang::BuiltinType::LongDouble:
5455 return lldb::eFormatFloat;
5456 default:
5457 return lldb::eFormatHex;
5458 }
5459 break;
5460 case clang::Type::ObjCObjectPointer:
5461 return lldb::eFormatHex;
5462 case clang::Type::BlockPointer:
5463 return lldb::eFormatHex;
5464 case clang::Type::Pointer:
5465 return lldb::eFormatHex;
5466 case clang::Type::LValueReference:
5467 case clang::Type::RValueReference:
5468 return lldb::eFormatHex;
5469 case clang::Type::MemberPointer:
5470 break;
5471 case clang::Type::Complex: {
5472 if (qual_type->isComplexType())
5473 return lldb::eFormatComplex;
5474 else
5475 return lldb::eFormatComplexInteger;
5476 }
5477 case clang::Type::ObjCInterface:
5478 break;
5479 case clang::Type::Record:
5480 break;
5481 case clang::Type::Enum:
5482 return lldb::eFormatEnum;
5483 case clang::Type::Typedef:
5484 return CompilerType(getASTContext(),
5485 llvm::cast<clang::TypedefType>(qual_type)
5486 ->getDecl()
5487 ->getUnderlyingType())
5488 .GetFormat();
5489 case clang::Type::Auto:
5490 return CompilerType(getASTContext(),
5491 llvm::cast<clang::AutoType>(qual_type)->desugar())
5492 .GetFormat();
5493 case clang::Type::Paren:
5494 return CompilerType(getASTContext(),
5495 llvm::cast<clang::ParenType>(qual_type)->desugar())
5496 .GetFormat();
5497 case clang::Type::Elaborated:
5498 return CompilerType(
5499 getASTContext(),
5500 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
5501 .GetFormat();
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005502 case clang::Type::TypeOfExpr:
5503 return CompilerType(getASTContext(),
5504 llvm::cast<clang::TypeOfExprType>(qual_type)
5505 ->getUnderlyingExpr()
5506 ->getType())
5507 .GetFormat();
5508 case clang::Type::TypeOf:
5509 return CompilerType(
5510 getASTContext(),
5511 llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
5512 .GetFormat();
5513 case clang::Type::Decltype:
5514 return CompilerType(
5515 getASTContext(),
5516 llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
5517 .GetFormat();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005518 case clang::Type::DependentSizedArray:
5519 case clang::Type::DependentSizedExtVector:
5520 case clang::Type::UnresolvedUsing:
5521 case clang::Type::Attributed:
5522 case clang::Type::TemplateTypeParm:
5523 case clang::Type::SubstTemplateTypeParm:
5524 case clang::Type::SubstTemplateTypeParmPack:
5525 case clang::Type::InjectedClassName:
5526 case clang::Type::DependentName:
5527 case clang::Type::DependentTemplateSpecialization:
5528 case clang::Type::PackExpansion:
5529 case clang::Type::ObjCObject:
5530
Kate Stoneb9c1b512016-09-06 20:57:50 +00005531 case clang::Type::TemplateSpecialization:
Pavel Labath4f19fce22017-02-17 13:39:50 +00005532 case clang::Type::DeducedTemplateSpecialization:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005533 case clang::Type::Atomic:
5534 case clang::Type::Adjusted:
5535 case clang::Type::Pipe:
5536 break;
5537
5538 // pointer type decayed from an array or function type.
5539 case clang::Type::Decayed:
5540 break;
Zachary Turner5a8ad4592016-10-05 17:07:34 +00005541 case clang::Type::ObjCTypeParam:
5542 break;
Ted Woodward66060cf2017-10-11 22:42:21 +00005543
5544 case clang::Type::DependentAddressSpace:
5545 break;
Krasimir Georgiev435e76a2019-05-07 13:59:30 +00005546 case clang::Type::MacroQualified:
5547 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005548 }
5549 // We don't know hot to display this type...
5550 return lldb::eFormatBytes;
5551}
5552
5553static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl,
5554 bool check_superclass) {
5555 while (class_interface_decl) {
5556 if (class_interface_decl->ivar_size() > 0)
5557 return true;
5558
5559 if (check_superclass)
5560 class_interface_decl = class_interface_decl->getSuperClass();
5561 else
5562 break;
5563 }
5564 return false;
5565}
5566
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00005567static Optional<SymbolFile::ArrayInfo>
Adrian Prantleca07c52018-11-05 20:49:07 +00005568GetDynamicArrayInfo(ClangASTContext &ast, SymbolFile *sym_file,
5569 clang::QualType qual_type,
5570 const ExecutionContext *exe_ctx) {
5571 if (qual_type->isIncompleteArrayType())
5572 if (auto *metadata = ast.GetMetadata(qual_type.getAsOpaquePtr()))
Pavel Labathffec31e2018-12-28 13:34:44 +00005573 return sym_file->GetDynamicArrayInfoForUID(metadata->GetUserID(),
5574 exe_ctx);
Adrian Prantleca07c52018-11-05 20:49:07 +00005575 return llvm::None;
5576}
5577
Kate Stoneb9c1b512016-09-06 20:57:50 +00005578uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
Adrian Prantleca07c52018-11-05 20:49:07 +00005579 bool omit_empty_base_classes,
5580 const ExecutionContext *exe_ctx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005581 if (!type)
5582 return 0;
5583
5584 uint32_t num_children = 0;
5585 clang::QualType qual_type(GetQualType(type));
5586 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5587 switch (type_class) {
5588 case clang::Type::Builtin:
5589 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5590 case clang::BuiltinType::ObjCId: // child is Class
5591 case clang::BuiltinType::ObjCClass: // child is Class
5592 num_children = 1;
5593 break;
5594
5595 default:
5596 break;
5597 }
5598 break;
5599
5600 case clang::Type::Complex:
5601 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005602 case clang::Type::Record:
5603 if (GetCompleteQualType(getASTContext(), qual_type)) {
5604 const clang::RecordType *record_type =
5605 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
5606 const clang::RecordDecl *record_decl = record_type->getDecl();
5607 assert(record_decl);
5608 const clang::CXXRecordDecl *cxx_record_decl =
5609 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
5610 if (cxx_record_decl) {
5611 if (omit_empty_base_classes) {
Adrian Prantl05097242018-04-30 16:49:04 +00005612 // Check each base classes to see if it or any of its base classes
5613 // contain any fields. This can help limit the noise in variable
5614 // views by not having to show base classes that contain no members.
Kate Stoneb9c1b512016-09-06 20:57:50 +00005615 clang::CXXRecordDecl::base_class_const_iterator base_class,
5616 base_class_end;
5617 for (base_class = cxx_record_decl->bases_begin(),
5618 base_class_end = cxx_record_decl->bases_end();
5619 base_class != base_class_end; ++base_class) {
5620 const clang::CXXRecordDecl *base_class_decl =
5621 llvm::cast<clang::CXXRecordDecl>(
5622 base_class->getType()
5623 ->getAs<clang::RecordType>()
5624 ->getDecl());
5625
5626 // Skip empty base classes
Jonas Devliegherea6682a42018-12-15 00:15:33 +00005627 if (!ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00005628 continue;
5629
5630 num_children++;
5631 }
5632 } else {
5633 // Include all base classes
5634 num_children += cxx_record_decl->getNumBases();
5635 }
5636 }
5637 clang::RecordDecl::field_iterator field, field_end;
5638 for (field = record_decl->field_begin(),
5639 field_end = record_decl->field_end();
5640 field != field_end; ++field)
5641 ++num_children;
5642 }
5643 break;
5644
5645 case clang::Type::ObjCObject:
5646 case clang::Type::ObjCInterface:
5647 if (GetCompleteQualType(getASTContext(), qual_type)) {
5648 const clang::ObjCObjectType *objc_class_type =
5649 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
5650 assert(objc_class_type);
5651 if (objc_class_type) {
5652 clang::ObjCInterfaceDecl *class_interface_decl =
5653 objc_class_type->getInterface();
5654
5655 if (class_interface_decl) {
5656
5657 clang::ObjCInterfaceDecl *superclass_interface_decl =
5658 class_interface_decl->getSuperClass();
5659 if (superclass_interface_decl) {
5660 if (omit_empty_base_classes) {
5661 if (ObjCDeclHasIVars(superclass_interface_decl, true))
5662 ++num_children;
5663 } else
5664 ++num_children;
5665 }
5666
5667 num_children += class_interface_decl->ivar_size();
5668 }
5669 }
5670 }
5671 break;
5672
5673 case clang::Type::ObjCObjectPointer: {
5674 const clang::ObjCObjectPointerType *pointer_type =
5675 llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
5676 clang::QualType pointee_type = pointer_type->getPointeeType();
5677 uint32_t num_pointee_children =
5678 CompilerType(getASTContext(), pointee_type)
Adrian Prantleca07c52018-11-05 20:49:07 +00005679 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005680 // If this type points to a simple type, then it has 1 child
5681 if (num_pointee_children == 0)
5682 num_children = 1;
5683 else
5684 num_children = num_pointee_children;
5685 } break;
5686
5687 case clang::Type::Vector:
5688 case clang::Type::ExtVector:
5689 num_children =
5690 llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements();
5691 break;
5692
5693 case clang::Type::ConstantArray:
5694 num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr())
5695 ->getSize()
5696 .getLimitedValue();
5697 break;
Adrian Prantleca07c52018-11-05 20:49:07 +00005698 case clang::Type::IncompleteArray:
5699 if (auto array_info =
5700 GetDynamicArrayInfo(*this, GetSymbolFile(), qual_type, exe_ctx))
5701 // Only 1-dimensional arrays are supported.
5702 num_children = array_info->element_orders.size()
5703 ? array_info->element_orders.back()
5704 : 0;
5705 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005706
5707 case clang::Type::Pointer: {
5708 const clang::PointerType *pointer_type =
5709 llvm::cast<clang::PointerType>(qual_type.getTypePtr());
5710 clang::QualType pointee_type(pointer_type->getPointeeType());
5711 uint32_t num_pointee_children =
5712 CompilerType(getASTContext(), pointee_type)
Adrian Prantleca07c52018-11-05 20:49:07 +00005713 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005714 if (num_pointee_children == 0) {
Adrian Prantl05097242018-04-30 16:49:04 +00005715 // We have a pointer to a pointee type that claims it has no children. We
5716 // will want to look at
Kate Stoneb9c1b512016-09-06 20:57:50 +00005717 num_children = GetNumPointeeChildren(pointee_type);
5718 } else
5719 num_children = num_pointee_children;
5720 } break;
5721
5722 case clang::Type::LValueReference:
5723 case clang::Type::RValueReference: {
5724 const clang::ReferenceType *reference_type =
5725 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
5726 clang::QualType pointee_type = reference_type->getPointeeType();
5727 uint32_t num_pointee_children =
5728 CompilerType(getASTContext(), pointee_type)
Adrian Prantleca07c52018-11-05 20:49:07 +00005729 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005730 // If this type points to a simple type, then it has 1 child
5731 if (num_pointee_children == 0)
5732 num_children = 1;
5733 else
5734 num_children = num_pointee_children;
5735 } break;
5736
5737 case clang::Type::Typedef:
5738 num_children =
5739 CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)
5740 ->getDecl()
5741 ->getUnderlyingType())
Adrian Prantleca07c52018-11-05 20:49:07 +00005742 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005743 break;
5744
5745 case clang::Type::Auto:
5746 num_children =
5747 CompilerType(getASTContext(),
5748 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
Adrian Prantleca07c52018-11-05 20:49:07 +00005749 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005750 break;
5751
5752 case clang::Type::Elaborated:
5753 num_children =
5754 CompilerType(
5755 getASTContext(),
5756 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
Adrian Prantleca07c52018-11-05 20:49:07 +00005757 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005758 break;
5759
5760 case clang::Type::Paren:
5761 num_children =
5762 CompilerType(getASTContext(),
5763 llvm::cast<clang::ParenType>(qual_type)->desugar())
Adrian Prantleca07c52018-11-05 20:49:07 +00005764 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005765 break;
5766 default:
5767 break;
5768 }
5769 return num_children;
5770}
5771
Adrian Prantl0e4c4822019-03-06 21:22:25 +00005772CompilerType ClangASTContext::GetBuiltinTypeByName(ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005773 return GetBasicType(GetBasicTypeEnumeration(name));
Greg Clayton56939cb2015-09-17 22:23:34 +00005774}
5775
Greg Claytond8d4a572015-08-11 21:38:15 +00005776lldb::BasicType
Kate Stoneb9c1b512016-09-06 20:57:50 +00005777ClangASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
5778 if (type) {
5779 clang::QualType qual_type(GetQualType(type));
5780 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5781 if (type_class == clang::Type::Builtin) {
5782 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5783 case clang::BuiltinType::Void:
5784 return eBasicTypeVoid;
5785 case clang::BuiltinType::Bool:
5786 return eBasicTypeBool;
5787 case clang::BuiltinType::Char_S:
5788 return eBasicTypeSignedChar;
5789 case clang::BuiltinType::Char_U:
5790 return eBasicTypeUnsignedChar;
5791 case clang::BuiltinType::Char16:
5792 return eBasicTypeChar16;
5793 case clang::BuiltinType::Char32:
5794 return eBasicTypeChar32;
5795 case clang::BuiltinType::UChar:
5796 return eBasicTypeUnsignedChar;
5797 case clang::BuiltinType::SChar:
5798 return eBasicTypeSignedChar;
5799 case clang::BuiltinType::WChar_S:
5800 return eBasicTypeSignedWChar;
5801 case clang::BuiltinType::WChar_U:
5802 return eBasicTypeUnsignedWChar;
5803 case clang::BuiltinType::Short:
5804 return eBasicTypeShort;
5805 case clang::BuiltinType::UShort:
5806 return eBasicTypeUnsignedShort;
5807 case clang::BuiltinType::Int:
5808 return eBasicTypeInt;
5809 case clang::BuiltinType::UInt:
5810 return eBasicTypeUnsignedInt;
5811 case clang::BuiltinType::Long:
5812 return eBasicTypeLong;
5813 case clang::BuiltinType::ULong:
5814 return eBasicTypeUnsignedLong;
5815 case clang::BuiltinType::LongLong:
5816 return eBasicTypeLongLong;
5817 case clang::BuiltinType::ULongLong:
5818 return eBasicTypeUnsignedLongLong;
5819 case clang::BuiltinType::Int128:
5820 return eBasicTypeInt128;
5821 case clang::BuiltinType::UInt128:
5822 return eBasicTypeUnsignedInt128;
5823
5824 case clang::BuiltinType::Half:
5825 return eBasicTypeHalf;
5826 case clang::BuiltinType::Float:
5827 return eBasicTypeFloat;
5828 case clang::BuiltinType::Double:
5829 return eBasicTypeDouble;
5830 case clang::BuiltinType::LongDouble:
5831 return eBasicTypeLongDouble;
5832
5833 case clang::BuiltinType::NullPtr:
5834 return eBasicTypeNullPtr;
5835 case clang::BuiltinType::ObjCId:
5836 return eBasicTypeObjCID;
5837 case clang::BuiltinType::ObjCClass:
5838 return eBasicTypeObjCClass;
5839 case clang::BuiltinType::ObjCSel:
5840 return eBasicTypeObjCSel;
5841 default:
5842 return eBasicTypeOther;
5843 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005844 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005845 }
5846 return eBasicTypeInvalid;
Greg Claytond8d4a572015-08-11 21:38:15 +00005847}
5848
Kate Stoneb9c1b512016-09-06 20:57:50 +00005849void ClangASTContext::ForEachEnumerator(
5850 lldb::opaque_compiler_type_t type,
5851 std::function<bool(const CompilerType &integer_type,
Adrian Prantl0e4c4822019-03-06 21:22:25 +00005852 ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00005853 const llvm::APSInt &value)> const &callback) {
5854 const clang::EnumType *enum_type =
5855 llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
5856 if (enum_type) {
5857 const clang::EnumDecl *enum_decl = enum_type->getDecl();
5858 if (enum_decl) {
5859 CompilerType integer_type(this,
5860 enum_decl->getIntegerType().getAsOpaquePtr());
Greg Clayton99558cc42015-08-24 23:46:31 +00005861
Kate Stoneb9c1b512016-09-06 20:57:50 +00005862 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
5863 for (enum_pos = enum_decl->enumerator_begin(),
5864 enum_end_pos = enum_decl->enumerator_end();
5865 enum_pos != enum_end_pos; ++enum_pos) {
5866 ConstString name(enum_pos->getNameAsString().c_str());
5867 if (!callback(integer_type, name, enum_pos->getInitVal()))
5868 break;
5869 }
Greg Clayton99558cc42015-08-24 23:46:31 +00005870 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005871 }
Greg Clayton99558cc42015-08-24 23:46:31 +00005872}
5873
Greg Claytond8d4a572015-08-11 21:38:15 +00005874#pragma mark Aggregate Types
5875
Kate Stoneb9c1b512016-09-06 20:57:50 +00005876uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
5877 if (!type)
5878 return 0;
Enrico Granata36f51e42015-12-18 22:41:25 +00005879
Kate Stoneb9c1b512016-09-06 20:57:50 +00005880 uint32_t count = 0;
5881 clang::QualType qual_type(GetCanonicalQualType(type));
5882 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5883 switch (type_class) {
5884 case clang::Type::Record:
5885 if (GetCompleteType(type)) {
5886 const clang::RecordType *record_type =
5887 llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
5888 if (record_type) {
5889 clang::RecordDecl *record_decl = record_type->getDecl();
5890 if (record_decl) {
5891 uint32_t field_idx = 0;
5892 clang::RecordDecl::field_iterator field, field_end;
5893 for (field = record_decl->field_begin(),
5894 field_end = record_decl->field_end();
5895 field != field_end; ++field)
5896 ++field_idx;
5897 count = field_idx;
5898 }
5899 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005900 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005901 break;
5902
5903 case clang::Type::Typedef:
5904 count =
5905 CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)
5906 ->getDecl()
5907 ->getUnderlyingType())
5908 .GetNumFields();
5909 break;
5910
5911 case clang::Type::Auto:
5912 count =
5913 CompilerType(getASTContext(),
5914 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
5915 .GetNumFields();
5916 break;
5917
5918 case clang::Type::Elaborated:
5919 count = CompilerType(
5920 getASTContext(),
5921 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
5922 .GetNumFields();
5923 break;
5924
5925 case clang::Type::Paren:
5926 count = CompilerType(getASTContext(),
5927 llvm::cast<clang::ParenType>(qual_type)->desugar())
5928 .GetNumFields();
5929 break;
5930
Sean Callananf9c622a2016-09-30 18:44:43 +00005931 case clang::Type::ObjCObjectPointer: {
5932 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00005933 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00005934 const clang::ObjCInterfaceType *objc_interface_type =
5935 objc_class_type->getInterfaceType();
5936 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00005937 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
5938 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00005939 clang::ObjCInterfaceDecl *class_interface_decl =
5940 objc_interface_type->getDecl();
5941 if (class_interface_decl) {
5942 count = class_interface_decl->ivar_size();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005943 }
5944 }
5945 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00005946 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005947
5948 case clang::Type::ObjCObject:
5949 case clang::Type::ObjCInterface:
5950 if (GetCompleteType(type)) {
5951 const clang::ObjCObjectType *objc_class_type =
5952 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
5953 if (objc_class_type) {
5954 clang::ObjCInterfaceDecl *class_interface_decl =
5955 objc_class_type->getInterface();
5956
5957 if (class_interface_decl)
5958 count = class_interface_decl->ivar_size();
5959 }
5960 }
5961 break;
5962
5963 default:
5964 break;
5965 }
5966 return count;
Greg Claytond8d4a572015-08-11 21:38:15 +00005967}
5968
Bruce Mitchener48ea9002015-09-23 00:18:24 +00005969static lldb::opaque_compiler_type_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00005970GetObjCFieldAtIndex(clang::ASTContext *ast,
5971 clang::ObjCInterfaceDecl *class_interface_decl, size_t idx,
5972 std::string &name, uint64_t *bit_offset_ptr,
5973 uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) {
5974 if (class_interface_decl) {
5975 if (idx < (class_interface_decl->ivar_size())) {
5976 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
5977 ivar_end = class_interface_decl->ivar_end();
5978 uint32_t ivar_idx = 0;
5979
5980 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end;
5981 ++ivar_pos, ++ivar_idx) {
5982 if (ivar_idx == idx) {
5983 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
5984
5985 clang::QualType ivar_qual_type(ivar_decl->getType());
5986
5987 name.assign(ivar_decl->getNameAsString());
5988
5989 if (bit_offset_ptr) {
5990 const clang::ASTRecordLayout &interface_layout =
5991 ast->getASTObjCInterfaceLayout(class_interface_decl);
5992 *bit_offset_ptr = interface_layout.getFieldOffset(ivar_idx);
5993 }
5994
5995 const bool is_bitfield = ivar_pos->isBitField();
5996
5997 if (bitfield_bit_size_ptr) {
5998 *bitfield_bit_size_ptr = 0;
5999
6000 if (is_bitfield && ast) {
6001 clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
Hans Wennborg30ce9622018-11-28 14:30:18 +00006002 clang::Expr::EvalResult result;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006003 if (bitfield_bit_size_expr &&
Hans Wennborg30ce9622018-11-28 14:30:18 +00006004 bitfield_bit_size_expr->EvaluateAsInt(result, *ast)) {
6005 llvm::APSInt bitfield_apsint = result.Val.getInt();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006006 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
6007 }
Greg Claytond8d4a572015-08-11 21:38:15 +00006008 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006009 }
6010 if (is_bitfield_ptr)
6011 *is_bitfield_ptr = is_bitfield;
6012
6013 return ivar_qual_type.getAsOpaquePtr();
Greg Claytond8d4a572015-08-11 21:38:15 +00006014 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006015 }
Greg Claytond8d4a572015-08-11 21:38:15 +00006016 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006017 }
6018 return nullptr;
Greg Claytond8d4a572015-08-11 21:38:15 +00006019}
6020
Kate Stoneb9c1b512016-09-06 20:57:50 +00006021CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
6022 size_t idx, std::string &name,
6023 uint64_t *bit_offset_ptr,
6024 uint32_t *bitfield_bit_size_ptr,
6025 bool *is_bitfield_ptr) {
6026 if (!type)
Greg Claytona1e5dc82015-08-11 22:53:00 +00006027 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006028
6029 clang::QualType qual_type(GetCanonicalQualType(type));
6030 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6031 switch (type_class) {
6032 case clang::Type::Record:
6033 if (GetCompleteType(type)) {
6034 const clang::RecordType *record_type =
6035 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
6036 const clang::RecordDecl *record_decl = record_type->getDecl();
6037 uint32_t field_idx = 0;
6038 clang::RecordDecl::field_iterator field, field_end;
6039 for (field = record_decl->field_begin(),
6040 field_end = record_decl->field_end();
6041 field != field_end; ++field, ++field_idx) {
6042 if (idx == field_idx) {
6043 // Print the member type if requested
6044 // Print the member name and equal sign
6045 name.assign(field->getNameAsString());
6046
6047 // Figure out the type byte size (field_type_info.first) and
6048 // alignment (field_type_info.second) from the AST context.
6049 if (bit_offset_ptr) {
6050 const clang::ASTRecordLayout &record_layout =
6051 getASTContext()->getASTRecordLayout(record_decl);
6052 *bit_offset_ptr = record_layout.getFieldOffset(field_idx);
6053 }
6054
6055 const bool is_bitfield = field->isBitField();
6056
6057 if (bitfield_bit_size_ptr) {
6058 *bitfield_bit_size_ptr = 0;
6059
6060 if (is_bitfield) {
6061 clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
Hans Wennborg30ce9622018-11-28 14:30:18 +00006062 clang::Expr::EvalResult result;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006063 if (bitfield_bit_size_expr &&
Hans Wennborg30ce9622018-11-28 14:30:18 +00006064 bitfield_bit_size_expr->EvaluateAsInt(result,
Kate Stoneb9c1b512016-09-06 20:57:50 +00006065 *getASTContext())) {
Hans Wennborg30ce9622018-11-28 14:30:18 +00006066 llvm::APSInt bitfield_apsint = result.Val.getInt();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006067 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
6068 }
6069 }
6070 }
6071 if (is_bitfield_ptr)
6072 *is_bitfield_ptr = is_bitfield;
6073
6074 return CompilerType(getASTContext(), field->getType());
6075 }
6076 }
6077 }
6078 break;
6079
Sean Callananf9c622a2016-09-30 18:44:43 +00006080 case clang::Type::ObjCObjectPointer: {
6081 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00006082 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00006083 const clang::ObjCInterfaceType *objc_interface_type =
6084 objc_class_type->getInterfaceType();
6085 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00006086 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
6087 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00006088 clang::ObjCInterfaceDecl *class_interface_decl =
6089 objc_interface_type->getDecl();
6090 if (class_interface_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00006091 return CompilerType(
6092 this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl,
6093 idx, name, bit_offset_ptr,
6094 bitfield_bit_size_ptr, is_bitfield_ptr));
6095 }
6096 }
6097 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00006098 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006099
6100 case clang::Type::ObjCObject:
6101 case clang::Type::ObjCInterface:
6102 if (GetCompleteType(type)) {
6103 const clang::ObjCObjectType *objc_class_type =
6104 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
6105 assert(objc_class_type);
6106 if (objc_class_type) {
6107 clang::ObjCInterfaceDecl *class_interface_decl =
6108 objc_class_type->getInterface();
6109 return CompilerType(
6110 this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl,
6111 idx, name, bit_offset_ptr,
6112 bitfield_bit_size_ptr, is_bitfield_ptr));
6113 }
6114 }
6115 break;
6116
6117 case clang::Type::Typedef:
6118 return CompilerType(getASTContext(),
6119 llvm::cast<clang::TypedefType>(qual_type)
6120 ->getDecl()
6121 ->getUnderlyingType())
6122 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6123 is_bitfield_ptr);
6124
6125 case clang::Type::Auto:
6126 return CompilerType(
6127 getASTContext(),
6128 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
6129 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6130 is_bitfield_ptr);
6131
6132 case clang::Type::Elaborated:
6133 return CompilerType(
6134 getASTContext(),
6135 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
6136 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6137 is_bitfield_ptr);
6138
6139 case clang::Type::Paren:
6140 return CompilerType(getASTContext(),
6141 llvm::cast<clang::ParenType>(qual_type)->desugar())
6142 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6143 is_bitfield_ptr);
6144
6145 default:
6146 break;
6147 }
6148 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00006149}
6150
Greg Clayton99558cc42015-08-24 23:46:31 +00006151uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00006152ClangASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) {
6153 uint32_t count = 0;
6154 clang::QualType qual_type(GetCanonicalQualType(type));
6155 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6156 switch (type_class) {
6157 case clang::Type::Record:
6158 if (GetCompleteType(type)) {
6159 const clang::CXXRecordDecl *cxx_record_decl =
6160 qual_type->getAsCXXRecordDecl();
6161 if (cxx_record_decl)
6162 count = cxx_record_decl->getNumBases();
Greg Clayton99558cc42015-08-24 23:46:31 +00006163 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006164 break;
Greg Clayton99558cc42015-08-24 23:46:31 +00006165
Kate Stoneb9c1b512016-09-06 20:57:50 +00006166 case clang::Type::ObjCObjectPointer:
6167 count = GetPointeeType(type).GetNumDirectBaseClasses();
6168 break;
6169
6170 case clang::Type::ObjCObject:
6171 if (GetCompleteType(type)) {
6172 const clang::ObjCObjectType *objc_class_type =
6173 qual_type->getAsObjCQualifiedInterfaceType();
6174 if (objc_class_type) {
6175 clang::ObjCInterfaceDecl *class_interface_decl =
6176 objc_class_type->getInterface();
6177
6178 if (class_interface_decl && class_interface_decl->getSuperClass())
6179 count = 1;
6180 }
6181 }
6182 break;
6183 case clang::Type::ObjCInterface:
6184 if (GetCompleteType(type)) {
6185 const clang::ObjCInterfaceType *objc_interface_type =
6186 qual_type->getAs<clang::ObjCInterfaceType>();
6187 if (objc_interface_type) {
6188 clang::ObjCInterfaceDecl *class_interface_decl =
6189 objc_interface_type->getInterface();
6190
6191 if (class_interface_decl && class_interface_decl->getSuperClass())
6192 count = 1;
6193 }
6194 }
6195 break;
6196
6197 case clang::Type::Typedef:
6198 count = GetNumDirectBaseClasses(llvm::cast<clang::TypedefType>(qual_type)
6199 ->getDecl()
6200 ->getUnderlyingType()
6201 .getAsOpaquePtr());
6202 break;
6203
6204 case clang::Type::Auto:
6205 count = GetNumDirectBaseClasses(llvm::cast<clang::AutoType>(qual_type)
6206 ->getDeducedType()
6207 .getAsOpaquePtr());
6208 break;
6209
6210 case clang::Type::Elaborated:
6211 count = GetNumDirectBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)
6212 ->getNamedType()
6213 .getAsOpaquePtr());
6214 break;
6215
6216 case clang::Type::Paren:
6217 return GetNumDirectBaseClasses(
6218 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
6219
6220 default:
6221 break;
6222 }
6223 return count;
Greg Clayton99558cc42015-08-24 23:46:31 +00006224}
6225
6226uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00006227ClangASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) {
6228 uint32_t count = 0;
6229 clang::QualType qual_type(GetCanonicalQualType(type));
6230 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6231 switch (type_class) {
6232 case clang::Type::Record:
6233 if (GetCompleteType(type)) {
6234 const clang::CXXRecordDecl *cxx_record_decl =
6235 qual_type->getAsCXXRecordDecl();
6236 if (cxx_record_decl)
6237 count = cxx_record_decl->getNumVBases();
Greg Clayton99558cc42015-08-24 23:46:31 +00006238 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006239 break;
Greg Clayton99558cc42015-08-24 23:46:31 +00006240
Kate Stoneb9c1b512016-09-06 20:57:50 +00006241 case clang::Type::Typedef:
6242 count = GetNumVirtualBaseClasses(llvm::cast<clang::TypedefType>(qual_type)
6243 ->getDecl()
6244 ->getUnderlyingType()
6245 .getAsOpaquePtr());
6246 break;
6247
6248 case clang::Type::Auto:
6249 count = GetNumVirtualBaseClasses(llvm::cast<clang::AutoType>(qual_type)
6250 ->getDeducedType()
6251 .getAsOpaquePtr());
6252 break;
6253
6254 case clang::Type::Elaborated:
6255 count =
6256 GetNumVirtualBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)
6257 ->getNamedType()
6258 .getAsOpaquePtr());
6259 break;
6260
6261 case clang::Type::Paren:
6262 count = GetNumVirtualBaseClasses(
6263 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
6264 break;
6265
6266 default:
6267 break;
6268 }
6269 return count;
Greg Clayton99558cc42015-08-24 23:46:31 +00006270}
6271
Kate Stoneb9c1b512016-09-06 20:57:50 +00006272CompilerType ClangASTContext::GetDirectBaseClassAtIndex(
6273 lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
6274 clang::QualType qual_type(GetCanonicalQualType(type));
6275 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6276 switch (type_class) {
6277 case clang::Type::Record:
6278 if (GetCompleteType(type)) {
6279 const clang::CXXRecordDecl *cxx_record_decl =
6280 qual_type->getAsCXXRecordDecl();
6281 if (cxx_record_decl) {
6282 uint32_t curr_idx = 0;
6283 clang::CXXRecordDecl::base_class_const_iterator base_class,
6284 base_class_end;
6285 for (base_class = cxx_record_decl->bases_begin(),
6286 base_class_end = cxx_record_decl->bases_end();
6287 base_class != base_class_end; ++base_class, ++curr_idx) {
6288 if (curr_idx == idx) {
6289 if (bit_offset_ptr) {
6290 const clang::ASTRecordLayout &record_layout =
6291 getASTContext()->getASTRecordLayout(cxx_record_decl);
6292 const clang::CXXRecordDecl *base_class_decl =
6293 llvm::cast<clang::CXXRecordDecl>(
6294 base_class->getType()
6295 ->getAs<clang::RecordType>()
6296 ->getDecl());
6297 if (base_class->isVirtual())
6298 *bit_offset_ptr =
6299 record_layout.getVBaseClassOffset(base_class_decl)
6300 .getQuantity() *
6301 8;
6302 else
6303 *bit_offset_ptr =
6304 record_layout.getBaseClassOffset(base_class_decl)
6305 .getQuantity() *
6306 8;
Greg Clayton99558cc42015-08-24 23:46:31 +00006307 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006308 return CompilerType(this, base_class->getType().getAsOpaquePtr());
6309 }
6310 }
6311 }
Greg Clayton99558cc42015-08-24 23:46:31 +00006312 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006313 break;
6314
6315 case clang::Type::ObjCObjectPointer:
6316 return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr);
6317
6318 case clang::Type::ObjCObject:
6319 if (idx == 0 && GetCompleteType(type)) {
6320 const clang::ObjCObjectType *objc_class_type =
6321 qual_type->getAsObjCQualifiedInterfaceType();
6322 if (objc_class_type) {
6323 clang::ObjCInterfaceDecl *class_interface_decl =
6324 objc_class_type->getInterface();
6325
6326 if (class_interface_decl) {
6327 clang::ObjCInterfaceDecl *superclass_interface_decl =
6328 class_interface_decl->getSuperClass();
6329 if (superclass_interface_decl) {
6330 if (bit_offset_ptr)
6331 *bit_offset_ptr = 0;
6332 return CompilerType(getASTContext(),
6333 getASTContext()->getObjCInterfaceType(
6334 superclass_interface_decl));
6335 }
6336 }
6337 }
6338 }
6339 break;
6340 case clang::Type::ObjCInterface:
6341 if (idx == 0 && GetCompleteType(type)) {
6342 const clang::ObjCObjectType *objc_interface_type =
6343 qual_type->getAs<clang::ObjCInterfaceType>();
6344 if (objc_interface_type) {
6345 clang::ObjCInterfaceDecl *class_interface_decl =
6346 objc_interface_type->getInterface();
6347
6348 if (class_interface_decl) {
6349 clang::ObjCInterfaceDecl *superclass_interface_decl =
6350 class_interface_decl->getSuperClass();
6351 if (superclass_interface_decl) {
6352 if (bit_offset_ptr)
6353 *bit_offset_ptr = 0;
6354 return CompilerType(getASTContext(),
6355 getASTContext()->getObjCInterfaceType(
6356 superclass_interface_decl));
6357 }
6358 }
6359 }
6360 }
6361 break;
6362
6363 case clang::Type::Typedef:
6364 return GetDirectBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type)
6365 ->getDecl()
6366 ->getUnderlyingType()
6367 .getAsOpaquePtr(),
6368 idx, bit_offset_ptr);
6369
6370 case clang::Type::Auto:
6371 return GetDirectBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type)
6372 ->getDeducedType()
6373 .getAsOpaquePtr(),
6374 idx, bit_offset_ptr);
6375
6376 case clang::Type::Elaborated:
6377 return GetDirectBaseClassAtIndex(
6378 llvm::cast<clang::ElaboratedType>(qual_type)
6379 ->getNamedType()
6380 .getAsOpaquePtr(),
6381 idx, bit_offset_ptr);
6382
6383 case clang::Type::Paren:
6384 return GetDirectBaseClassAtIndex(
6385 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
6386 idx, bit_offset_ptr);
6387
6388 default:
6389 break;
6390 }
6391 return CompilerType();
Greg Clayton99558cc42015-08-24 23:46:31 +00006392}
6393
Kate Stoneb9c1b512016-09-06 20:57:50 +00006394CompilerType ClangASTContext::GetVirtualBaseClassAtIndex(
6395 lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
6396 clang::QualType qual_type(GetCanonicalQualType(type));
6397 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6398 switch (type_class) {
6399 case clang::Type::Record:
6400 if (GetCompleteType(type)) {
6401 const clang::CXXRecordDecl *cxx_record_decl =
6402 qual_type->getAsCXXRecordDecl();
6403 if (cxx_record_decl) {
6404 uint32_t curr_idx = 0;
6405 clang::CXXRecordDecl::base_class_const_iterator base_class,
6406 base_class_end;
6407 for (base_class = cxx_record_decl->vbases_begin(),
6408 base_class_end = cxx_record_decl->vbases_end();
6409 base_class != base_class_end; ++base_class, ++curr_idx) {
6410 if (curr_idx == idx) {
6411 if (bit_offset_ptr) {
6412 const clang::ASTRecordLayout &record_layout =
6413 getASTContext()->getASTRecordLayout(cxx_record_decl);
6414 const clang::CXXRecordDecl *base_class_decl =
6415 llvm::cast<clang::CXXRecordDecl>(
6416 base_class->getType()
6417 ->getAs<clang::RecordType>()
6418 ->getDecl());
6419 *bit_offset_ptr =
6420 record_layout.getVBaseClassOffset(base_class_decl)
6421 .getQuantity() *
6422 8;
Greg Clayton99558cc42015-08-24 23:46:31 +00006423 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006424 return CompilerType(this, base_class->getType().getAsOpaquePtr());
6425 }
6426 }
6427 }
Greg Clayton99558cc42015-08-24 23:46:31 +00006428 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006429 break;
Greg Clayton99558cc42015-08-24 23:46:31 +00006430
Kate Stoneb9c1b512016-09-06 20:57:50 +00006431 case clang::Type::Typedef:
6432 return GetVirtualBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type)
6433 ->getDecl()
6434 ->getUnderlyingType()
6435 .getAsOpaquePtr(),
6436 idx, bit_offset_ptr);
6437
6438 case clang::Type::Auto:
6439 return GetVirtualBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type)
6440 ->getDeducedType()
6441 .getAsOpaquePtr(),
6442 idx, bit_offset_ptr);
6443
6444 case clang::Type::Elaborated:
6445 return GetVirtualBaseClassAtIndex(
6446 llvm::cast<clang::ElaboratedType>(qual_type)
6447 ->getNamedType()
6448 .getAsOpaquePtr(),
6449 idx, bit_offset_ptr);
6450
6451 case clang::Type::Paren:
6452 return GetVirtualBaseClassAtIndex(
6453 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
6454 idx, bit_offset_ptr);
6455
6456 default:
6457 break;
6458 }
6459 return CompilerType();
Greg Clayton99558cc42015-08-24 23:46:31 +00006460}
6461
Greg Claytond8d4a572015-08-11 21:38:15 +00006462// If a pointer to a pointee type (the clang_type arg) says that it has no
6463// children, then we either need to trust it, or override it and return a
6464// different result. For example, an "int *" has one child that is an integer,
6465// but a function pointer doesn't have any children. Likewise if a Record type
6466// claims it has no children, then there really is nothing to show.
Kate Stoneb9c1b512016-09-06 20:57:50 +00006467uint32_t ClangASTContext::GetNumPointeeChildren(clang::QualType type) {
6468 if (type.isNull())
Greg Claytond8d4a572015-08-11 21:38:15 +00006469 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006470
6471 clang::QualType qual_type(type.getCanonicalType());
6472 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6473 switch (type_class) {
6474 case clang::Type::Builtin:
6475 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
6476 case clang::BuiltinType::UnknownAny:
6477 case clang::BuiltinType::Void:
6478 case clang::BuiltinType::NullPtr:
6479 case clang::BuiltinType::OCLEvent:
6480 case clang::BuiltinType::OCLImage1dRO:
6481 case clang::BuiltinType::OCLImage1dWO:
6482 case clang::BuiltinType::OCLImage1dRW:
6483 case clang::BuiltinType::OCLImage1dArrayRO:
6484 case clang::BuiltinType::OCLImage1dArrayWO:
6485 case clang::BuiltinType::OCLImage1dArrayRW:
6486 case clang::BuiltinType::OCLImage1dBufferRO:
6487 case clang::BuiltinType::OCLImage1dBufferWO:
6488 case clang::BuiltinType::OCLImage1dBufferRW:
6489 case clang::BuiltinType::OCLImage2dRO:
6490 case clang::BuiltinType::OCLImage2dWO:
6491 case clang::BuiltinType::OCLImage2dRW:
6492 case clang::BuiltinType::OCLImage2dArrayRO:
6493 case clang::BuiltinType::OCLImage2dArrayWO:
6494 case clang::BuiltinType::OCLImage2dArrayRW:
6495 case clang::BuiltinType::OCLImage3dRO:
6496 case clang::BuiltinType::OCLImage3dWO:
6497 case clang::BuiltinType::OCLImage3dRW:
6498 case clang::BuiltinType::OCLSampler:
6499 return 0;
6500 case clang::BuiltinType::Bool:
6501 case clang::BuiltinType::Char_U:
6502 case clang::BuiltinType::UChar:
6503 case clang::BuiltinType::WChar_U:
6504 case clang::BuiltinType::Char16:
6505 case clang::BuiltinType::Char32:
6506 case clang::BuiltinType::UShort:
6507 case clang::BuiltinType::UInt:
6508 case clang::BuiltinType::ULong:
6509 case clang::BuiltinType::ULongLong:
6510 case clang::BuiltinType::UInt128:
6511 case clang::BuiltinType::Char_S:
6512 case clang::BuiltinType::SChar:
6513 case clang::BuiltinType::WChar_S:
6514 case clang::BuiltinType::Short:
6515 case clang::BuiltinType::Int:
6516 case clang::BuiltinType::Long:
6517 case clang::BuiltinType::LongLong:
6518 case clang::BuiltinType::Int128:
6519 case clang::BuiltinType::Float:
6520 case clang::BuiltinType::Double:
6521 case clang::BuiltinType::LongDouble:
6522 case clang::BuiltinType::Dependent:
6523 case clang::BuiltinType::Overload:
6524 case clang::BuiltinType::ObjCId:
6525 case clang::BuiltinType::ObjCClass:
6526 case clang::BuiltinType::ObjCSel:
6527 case clang::BuiltinType::BoundMember:
6528 case clang::BuiltinType::Half:
6529 case clang::BuiltinType::ARCUnbridgedCast:
6530 case clang::BuiltinType::PseudoObject:
6531 case clang::BuiltinType::BuiltinFn:
6532 case clang::BuiltinType::OMPArraySection:
6533 return 1;
6534 default:
6535 return 0;
6536 }
6537 break;
6538
6539 case clang::Type::Complex:
6540 return 1;
6541 case clang::Type::Pointer:
6542 return 1;
6543 case clang::Type::BlockPointer:
6544 return 0; // If block pointers don't have debug info, then no children for
6545 // them
6546 case clang::Type::LValueReference:
6547 return 1;
6548 case clang::Type::RValueReference:
6549 return 1;
6550 case clang::Type::MemberPointer:
6551 return 0;
6552 case clang::Type::ConstantArray:
6553 return 0;
6554 case clang::Type::IncompleteArray:
6555 return 0;
6556 case clang::Type::VariableArray:
6557 return 0;
6558 case clang::Type::DependentSizedArray:
6559 return 0;
6560 case clang::Type::DependentSizedExtVector:
6561 return 0;
6562 case clang::Type::Vector:
6563 return 0;
6564 case clang::Type::ExtVector:
6565 return 0;
6566 case clang::Type::FunctionProto:
6567 return 0; // When we function pointers, they have no children...
6568 case clang::Type::FunctionNoProto:
6569 return 0; // When we function pointers, they have no children...
6570 case clang::Type::UnresolvedUsing:
6571 return 0;
6572 case clang::Type::Paren:
6573 return GetNumPointeeChildren(
6574 llvm::cast<clang::ParenType>(qual_type)->desugar());
6575 case clang::Type::Typedef:
6576 return GetNumPointeeChildren(llvm::cast<clang::TypedefType>(qual_type)
6577 ->getDecl()
6578 ->getUnderlyingType());
6579 case clang::Type::Auto:
6580 return GetNumPointeeChildren(
6581 llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
6582 case clang::Type::Elaborated:
6583 return GetNumPointeeChildren(
6584 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
6585 case clang::Type::TypeOfExpr:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00006586 return GetNumPointeeChildren(llvm::cast<clang::TypeOfExprType>(qual_type)
6587 ->getUnderlyingExpr()
6588 ->getType());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006589 case clang::Type::TypeOf:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00006590 return GetNumPointeeChildren(
6591 llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006592 case clang::Type::Decltype:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00006593 return GetNumPointeeChildren(
6594 llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006595 case clang::Type::Record:
6596 return 0;
6597 case clang::Type::Enum:
6598 return 1;
6599 case clang::Type::TemplateTypeParm:
6600 return 1;
6601 case clang::Type::SubstTemplateTypeParm:
6602 return 1;
6603 case clang::Type::TemplateSpecialization:
6604 return 1;
6605 case clang::Type::InjectedClassName:
6606 return 0;
6607 case clang::Type::DependentName:
6608 return 1;
6609 case clang::Type::DependentTemplateSpecialization:
6610 return 1;
6611 case clang::Type::ObjCObject:
6612 return 0;
6613 case clang::Type::ObjCInterface:
6614 return 0;
6615 case clang::Type::ObjCObjectPointer:
6616 return 1;
6617 default:
6618 break;
6619 }
6620 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00006621}
6622
Kate Stoneb9c1b512016-09-06 20:57:50 +00006623CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
6624 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
6625 bool transparent_pointers, bool omit_empty_base_classes,
6626 bool ignore_array_bounds, std::string &child_name,
6627 uint32_t &child_byte_size, int32_t &child_byte_offset,
6628 uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
6629 bool &child_is_base_class, bool &child_is_deref_of_parent,
6630 ValueObject *valobj, uint64_t &language_flags) {
6631 if (!type)
Greg Claytona1e5dc82015-08-11 22:53:00 +00006632 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00006633
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006634 auto get_exe_scope = [&exe_ctx]() {
6635 return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
6636 };
6637
Kate Stoneb9c1b512016-09-06 20:57:50 +00006638 clang::QualType parent_qual_type(GetCanonicalQualType(type));
6639 const clang::Type::TypeClass parent_type_class =
6640 parent_qual_type->getTypeClass();
6641 child_bitfield_bit_size = 0;
6642 child_bitfield_bit_offset = 0;
6643 child_is_base_class = false;
6644 language_flags = 0;
6645
Adrian Prantleca07c52018-11-05 20:49:07 +00006646 const bool idx_is_valid =
6647 idx < GetNumChildren(type, omit_empty_base_classes, exe_ctx);
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00006648 int32_t bit_offset;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006649 switch (parent_type_class) {
6650 case clang::Type::Builtin:
6651 if (idx_is_valid) {
6652 switch (llvm::cast<clang::BuiltinType>(parent_qual_type)->getKind()) {
6653 case clang::BuiltinType::ObjCId:
6654 case clang::BuiltinType::ObjCClass:
6655 child_name = "isa";
6656 child_byte_size =
6657 getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy) /
6658 CHAR_BIT;
6659 return CompilerType(getASTContext(),
6660 getASTContext()->ObjCBuiltinClassTy);
6661
6662 default:
6663 break;
6664 }
6665 }
6666 break;
6667
6668 case clang::Type::Record:
6669 if (idx_is_valid && GetCompleteType(type)) {
6670 const clang::RecordType *record_type =
6671 llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr());
6672 const clang::RecordDecl *record_decl = record_type->getDecl();
6673 assert(record_decl);
6674 const clang::ASTRecordLayout &record_layout =
6675 getASTContext()->getASTRecordLayout(record_decl);
6676 uint32_t child_idx = 0;
6677
6678 const clang::CXXRecordDecl *cxx_record_decl =
6679 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
6680 if (cxx_record_decl) {
6681 // We might have base classes to print out first
6682 clang::CXXRecordDecl::base_class_const_iterator base_class,
6683 base_class_end;
6684 for (base_class = cxx_record_decl->bases_begin(),
6685 base_class_end = cxx_record_decl->bases_end();
6686 base_class != base_class_end; ++base_class) {
6687 const clang::CXXRecordDecl *base_class_decl = nullptr;
6688
6689 // Skip empty base classes
6690 if (omit_empty_base_classes) {
6691 base_class_decl = llvm::cast<clang::CXXRecordDecl>(
6692 base_class->getType()->getAs<clang::RecordType>()->getDecl());
Jonas Devliegherea6682a42018-12-15 00:15:33 +00006693 if (!ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00006694 continue;
6695 }
6696
6697 if (idx == child_idx) {
6698 if (base_class_decl == nullptr)
6699 base_class_decl = llvm::cast<clang::CXXRecordDecl>(
6700 base_class->getType()->getAs<clang::RecordType>()->getDecl());
6701
6702 if (base_class->isVirtual()) {
6703 bool handled = false;
6704 if (valobj) {
Aleksandr Urakov1dc51db2018-11-12 16:23:50 +00006705 clang::VTableContextBase *vtable_ctx =
6706 getASTContext()->getVTableContext();
6707 if (vtable_ctx)
6708 handled = GetVBaseBitOffset(*vtable_ctx, *valobj,
6709 record_layout, cxx_record_decl,
6710 base_class_decl, bit_offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00006711 }
6712 if (!handled)
6713 bit_offset = record_layout.getVBaseClassOffset(base_class_decl)
6714 .getQuantity() *
6715 8;
6716 } else
6717 bit_offset = record_layout.getBaseClassOffset(base_class_decl)
6718 .getQuantity() *
6719 8;
6720
6721 // Base classes should be a multiple of 8 bits in size
6722 child_byte_offset = bit_offset / 8;
6723 CompilerType base_class_clang_type(getASTContext(),
6724 base_class->getType());
6725 child_name = base_class_clang_type.GetTypeName().AsCString("");
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006726 Optional<uint64_t> size =
6727 base_class_clang_type.GetBitSize(get_exe_scope());
Adrian Prantld963a7c2019-01-15 18:07:52 +00006728 if (!size)
6729 return {};
6730 uint64_t base_class_clang_type_bit_size = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006731
6732 // Base classes bit sizes should be a multiple of 8 bits in size
6733 assert(base_class_clang_type_bit_size % 8 == 0);
6734 child_byte_size = base_class_clang_type_bit_size / 8;
6735 child_is_base_class = true;
6736 return base_class_clang_type;
6737 }
6738 // We don't increment the child index in the for loop since we might
6739 // be skipping empty base classes
6740 ++child_idx;
Greg Claytond8d4a572015-08-11 21:38:15 +00006741 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006742 }
6743 // Make sure index is in range...
6744 uint32_t field_idx = 0;
6745 clang::RecordDecl::field_iterator field, field_end;
6746 for (field = record_decl->field_begin(),
6747 field_end = record_decl->field_end();
6748 field != field_end; ++field, ++field_idx, ++child_idx) {
6749 if (idx == child_idx) {
6750 // Print the member type if requested
6751 // Print the member name and equal sign
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00006752 child_name.assign(field->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006753
6754 // Figure out the type byte size (field_type_info.first) and
6755 // alignment (field_type_info.second) from the AST context.
6756 CompilerType field_clang_type(getASTContext(), field->getType());
6757 assert(field_idx < record_layout.getFieldCount());
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006758 Optional<uint64_t> size =
6759 field_clang_type.GetByteSize(get_exe_scope());
Adrian Prantld963a7c2019-01-15 18:07:52 +00006760 if (!size)
6761 return {};
6762 child_byte_size = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006763 const uint32_t child_bit_size = child_byte_size * 8;
6764
6765 // Figure out the field offset within the current struct/union/class
6766 // type
6767 bit_offset = record_layout.getFieldOffset(field_idx);
6768 if (ClangASTContext::FieldIsBitfield(getASTContext(), *field,
6769 child_bitfield_bit_size)) {
6770 child_bitfield_bit_offset = bit_offset % child_bit_size;
6771 const uint32_t child_bit_offset =
6772 bit_offset - child_bitfield_bit_offset;
6773 child_byte_offset = child_bit_offset / 8;
6774 } else {
6775 child_byte_offset = bit_offset / 8;
6776 }
6777
6778 return field_clang_type;
6779 }
6780 }
Greg Claytond8d4a572015-08-11 21:38:15 +00006781 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006782 break;
6783
6784 case clang::Type::ObjCObject:
6785 case clang::Type::ObjCInterface:
6786 if (idx_is_valid && GetCompleteType(type)) {
6787 const clang::ObjCObjectType *objc_class_type =
6788 llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr());
6789 assert(objc_class_type);
6790 if (objc_class_type) {
6791 uint32_t child_idx = 0;
6792 clang::ObjCInterfaceDecl *class_interface_decl =
6793 objc_class_type->getInterface();
6794
6795 if (class_interface_decl) {
6796
6797 const clang::ASTRecordLayout &interface_layout =
6798 getASTContext()->getASTObjCInterfaceLayout(class_interface_decl);
6799 clang::ObjCInterfaceDecl *superclass_interface_decl =
6800 class_interface_decl->getSuperClass();
6801 if (superclass_interface_decl) {
6802 if (omit_empty_base_classes) {
6803 CompilerType base_class_clang_type(
6804 getASTContext(), getASTContext()->getObjCInterfaceType(
6805 superclass_interface_decl));
Adrian Prantleca07c52018-11-05 20:49:07 +00006806 if (base_class_clang_type.GetNumChildren(omit_empty_base_classes,
6807 exe_ctx) > 0) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00006808 if (idx == 0) {
6809 clang::QualType ivar_qual_type(
6810 getASTContext()->getObjCInterfaceType(
6811 superclass_interface_decl));
6812
6813 child_name.assign(
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00006814 superclass_interface_decl->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006815
6816 clang::TypeInfo ivar_type_info =
6817 getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
6818
6819 child_byte_size = ivar_type_info.Width / 8;
6820 child_byte_offset = 0;
6821 child_is_base_class = true;
6822
6823 return CompilerType(getASTContext(), ivar_qual_type);
6824 }
6825
6826 ++child_idx;
6827 }
6828 } else
6829 ++child_idx;
6830 }
6831
6832 const uint32_t superclass_idx = child_idx;
6833
6834 if (idx < (child_idx + class_interface_decl->ivar_size())) {
6835 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
6836 ivar_end = class_interface_decl->ivar_end();
6837
6838 for (ivar_pos = class_interface_decl->ivar_begin();
6839 ivar_pos != ivar_end; ++ivar_pos) {
6840 if (child_idx == idx) {
6841 clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
6842
6843 clang::QualType ivar_qual_type(ivar_decl->getType());
6844
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00006845 child_name.assign(ivar_decl->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006846
6847 clang::TypeInfo ivar_type_info =
6848 getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
6849
6850 child_byte_size = ivar_type_info.Width / 8;
6851
6852 // Figure out the field offset within the current
Adrian Prantl05097242018-04-30 16:49:04 +00006853 // struct/union/class type For ObjC objects, we can't trust the
6854 // bit offset we get from the Clang AST, since that doesn't
6855 // account for the space taken up by unbacked properties, or
6856 // from the changing size of base classes that are newer than
6857 // this class. So if we have a process around that we can ask
6858 // about this object, do so.
Kate Stoneb9c1b512016-09-06 20:57:50 +00006859 child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
6860 Process *process = nullptr;
6861 if (exe_ctx)
6862 process = exe_ctx->GetProcessPtr();
6863 if (process) {
6864 ObjCLanguageRuntime *objc_runtime =
Alex Langforde823bbe2019-06-10 20:53:23 +00006865 ObjCLanguageRuntime::Get(*process);
Kate Stoneb9c1b512016-09-06 20:57:50 +00006866 if (objc_runtime != nullptr) {
6867 CompilerType parent_ast_type(getASTContext(),
6868 parent_qual_type);
6869 child_byte_offset = objc_runtime->GetByteOffsetForIvar(
6870 parent_ast_type, ivar_decl->getNameAsString().c_str());
6871 }
6872 }
6873
Aleksandr Urakovff701722018-08-20 05:59:27 +00006874 // Setting this to INT32_MAX to make sure we don't compute it
Kate Stoneb9c1b512016-09-06 20:57:50 +00006875 // twice...
Aleksandr Urakov53459482018-08-17 07:28:24 +00006876 bit_offset = INT32_MAX;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006877
6878 if (child_byte_offset ==
6879 static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET)) {
6880 bit_offset = interface_layout.getFieldOffset(child_idx -
6881 superclass_idx);
6882 child_byte_offset = bit_offset / 8;
6883 }
6884
6885 // Note, the ObjC Ivar Byte offset is just that, it doesn't
Adrian Prantl05097242018-04-30 16:49:04 +00006886 // account for the bit offset of a bitfield within its
6887 // containing object. So regardless of where we get the byte
Kate Stoneb9c1b512016-09-06 20:57:50 +00006888 // offset from, we still need to get the bit offset for
6889 // bitfields from the layout.
6890
6891 if (ClangASTContext::FieldIsBitfield(getASTContext(), ivar_decl,
6892 child_bitfield_bit_size)) {
Aleksandr Urakov53459482018-08-17 07:28:24 +00006893 if (bit_offset == INT32_MAX)
Kate Stoneb9c1b512016-09-06 20:57:50 +00006894 bit_offset = interface_layout.getFieldOffset(
6895 child_idx - superclass_idx);
6896
6897 child_bitfield_bit_offset = bit_offset % 8;
6898 }
6899 return CompilerType(getASTContext(), ivar_qual_type);
6900 }
6901 ++child_idx;
6902 }
6903 }
6904 }
6905 }
6906 }
6907 break;
6908
6909 case clang::Type::ObjCObjectPointer:
6910 if (idx_is_valid) {
6911 CompilerType pointee_clang_type(GetPointeeType(type));
6912
6913 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6914 child_is_deref_of_parent = false;
6915 bool tmp_child_is_deref_of_parent = false;
6916 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6917 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6918 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6919 child_bitfield_bit_size, child_bitfield_bit_offset,
6920 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
6921 language_flags);
6922 } else {
6923 child_is_deref_of_parent = true;
6924 const char *parent_name =
Konrad Kleine248a1302019-05-23 11:14:47 +00006925 valobj ? valobj->GetName().GetCString() : nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006926 if (parent_name) {
6927 child_name.assign(1, '*');
6928 child_name += parent_name;
6929 }
6930
6931 // We have a pointer to an simple type
6932 if (idx == 0 && pointee_clang_type.GetCompleteType()) {
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006933 if (Optional<uint64_t> size =
6934 pointee_clang_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00006935 child_byte_size = *size;
6936 child_byte_offset = 0;
6937 return pointee_clang_type;
6938 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006939 }
6940 }
6941 }
6942 break;
6943
6944 case clang::Type::Vector:
6945 case clang::Type::ExtVector:
6946 if (idx_is_valid) {
6947 const clang::VectorType *array =
6948 llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr());
6949 if (array) {
6950 CompilerType element_type(getASTContext(), array->getElementType());
6951 if (element_type.GetCompleteType()) {
6952 char element_name[64];
6953 ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]",
6954 static_cast<uint64_t>(idx));
6955 child_name.assign(element_name);
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006956 if (Optional<uint64_t> size =
6957 element_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00006958 child_byte_size = *size;
6959 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
6960 return element_type;
6961 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006962 }
6963 }
6964 }
6965 break;
6966
6967 case clang::Type::ConstantArray:
6968 case clang::Type::IncompleteArray:
6969 if (ignore_array_bounds || idx_is_valid) {
6970 const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
6971 if (array) {
6972 CompilerType element_type(getASTContext(), array->getElementType());
6973 if (element_type.GetCompleteType()) {
Zachary Turner827d5d72016-12-16 04:27:00 +00006974 child_name = llvm::formatv("[{0}]", idx);
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006975 if (Optional<uint64_t> size =
6976 element_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00006977 child_byte_size = *size;
6978 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
6979 return element_type;
6980 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006981 }
6982 }
6983 }
6984 break;
6985
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006986 case clang::Type::Pointer: {
6987 CompilerType pointee_clang_type(GetPointeeType(type));
Kate Stoneb9c1b512016-09-06 20:57:50 +00006988
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006989 // Don't dereference "void *" pointers
6990 if (pointee_clang_type.IsVoidType())
6991 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006992
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006993 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6994 child_is_deref_of_parent = false;
6995 bool tmp_child_is_deref_of_parent = false;
6996 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6997 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6998 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6999 child_bitfield_bit_size, child_bitfield_bit_offset,
7000 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
7001 language_flags);
7002 } else {
7003 child_is_deref_of_parent = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007004
Tamas Berghammer1c62e032017-01-07 16:39:07 +00007005 const char *parent_name =
Konrad Kleine248a1302019-05-23 11:14:47 +00007006 valobj ? valobj->GetName().GetCString() : nullptr;
Tamas Berghammer1c62e032017-01-07 16:39:07 +00007007 if (parent_name) {
7008 child_name.assign(1, '*');
7009 child_name += parent_name;
7010 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007011
Tamas Berghammer1c62e032017-01-07 16:39:07 +00007012 // We have a pointer to an simple type
7013 if (idx == 0) {
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00007014 if (Optional<uint64_t> size =
7015 pointee_clang_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00007016 child_byte_size = *size;
7017 child_byte_offset = 0;
7018 return pointee_clang_type;
7019 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007020 }
7021 }
7022 break;
Tamas Berghammer1c62e032017-01-07 16:39:07 +00007023 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007024
7025 case clang::Type::LValueReference:
7026 case clang::Type::RValueReference:
7027 if (idx_is_valid) {
7028 const clang::ReferenceType *reference_type =
7029 llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
7030 CompilerType pointee_clang_type(getASTContext(),
7031 reference_type->getPointeeType());
7032 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
7033 child_is_deref_of_parent = false;
7034 bool tmp_child_is_deref_of_parent = false;
7035 return pointee_clang_type.GetChildCompilerTypeAtIndex(
7036 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7037 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7038 child_bitfield_bit_size, child_bitfield_bit_offset,
7039 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
7040 language_flags);
7041 } else {
7042 const char *parent_name =
Konrad Kleine248a1302019-05-23 11:14:47 +00007043 valobj ? valobj->GetName().GetCString() : nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007044 if (parent_name) {
7045 child_name.assign(1, '&');
7046 child_name += parent_name;
7047 }
7048
7049 // We have a pointer to an simple type
7050 if (idx == 0) {
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00007051 if (Optional<uint64_t> size =
7052 pointee_clang_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00007053 child_byte_size = *size;
7054 child_byte_offset = 0;
7055 return pointee_clang_type;
7056 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007057 }
7058 }
7059 }
7060 break;
7061
7062 case clang::Type::Typedef: {
7063 CompilerType typedefed_clang_type(
7064 getASTContext(), llvm::cast<clang::TypedefType>(parent_qual_type)
7065 ->getDecl()
7066 ->getUnderlyingType());
7067 return typedefed_clang_type.GetChildCompilerTypeAtIndex(
7068 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7069 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7070 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7071 child_is_deref_of_parent, valobj, language_flags);
7072 } break;
7073
7074 case clang::Type::Auto: {
7075 CompilerType elaborated_clang_type(
7076 getASTContext(),
7077 llvm::cast<clang::AutoType>(parent_qual_type)->getDeducedType());
7078 return elaborated_clang_type.GetChildCompilerTypeAtIndex(
7079 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7080 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7081 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7082 child_is_deref_of_parent, valobj, language_flags);
7083 }
7084
7085 case clang::Type::Elaborated: {
7086 CompilerType elaborated_clang_type(
7087 getASTContext(),
7088 llvm::cast<clang::ElaboratedType>(parent_qual_type)->getNamedType());
7089 return elaborated_clang_type.GetChildCompilerTypeAtIndex(
7090 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7091 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7092 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7093 child_is_deref_of_parent, valobj, language_flags);
7094 }
7095
7096 case clang::Type::Paren: {
7097 CompilerType paren_clang_type(
7098 getASTContext(),
7099 llvm::cast<clang::ParenType>(parent_qual_type)->desugar());
7100 return paren_clang_type.GetChildCompilerTypeAtIndex(
7101 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7102 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7103 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7104 child_is_deref_of_parent, valobj, language_flags);
7105 }
7106
7107 default:
7108 break;
7109 }
7110 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00007111}
7112
Kate Stoneb9c1b512016-09-06 20:57:50 +00007113static uint32_t GetIndexForRecordBase(const clang::RecordDecl *record_decl,
7114 const clang::CXXBaseSpecifier *base_spec,
7115 bool omit_empty_base_classes) {
7116 uint32_t child_idx = 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00007117
Kate Stoneb9c1b512016-09-06 20:57:50 +00007118 const clang::CXXRecordDecl *cxx_record_decl =
7119 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
7120
7121 // const char *super_name = record_decl->getNameAsCString();
7122 // const char *base_name =
7123 // base_spec->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString();
7124 // printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
7125 //
7126 if (cxx_record_decl) {
7127 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
7128 for (base_class = cxx_record_decl->bases_begin(),
7129 base_class_end = cxx_record_decl->bases_end();
7130 base_class != base_class_end; ++base_class) {
7131 if (omit_empty_base_classes) {
7132 if (BaseSpecifierIsEmpty(base_class))
7133 continue;
7134 }
7135
7136 // printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
7137 // super_name, base_name,
7138 // child_idx,
7139 // base_class->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString());
7140 //
7141 //
7142 if (base_class == base_spec)
7143 return child_idx;
7144 ++child_idx;
Greg Claytond8d4a572015-08-11 21:38:15 +00007145 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007146 }
7147
7148 return UINT32_MAX;
7149}
7150
7151static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl,
7152 clang::NamedDecl *canonical_decl,
7153 bool omit_empty_base_classes) {
7154 uint32_t child_idx = ClangASTContext::GetNumBaseClasses(
7155 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
7156 omit_empty_base_classes);
7157
7158 clang::RecordDecl::field_iterator field, field_end;
7159 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
7160 field != field_end; ++field, ++child_idx) {
7161 if (field->getCanonicalDecl() == canonical_decl)
7162 return child_idx;
7163 }
7164
7165 return UINT32_MAX;
Greg Claytond8d4a572015-08-11 21:38:15 +00007166}
7167
7168// Look for a child member (doesn't include base classes, but it does include
Adrian Prantl05097242018-04-30 16:49:04 +00007169// their members) in the type hierarchy. Returns an index path into
7170// "clang_type" on how to reach the appropriate member.
Greg Claytond8d4a572015-08-11 21:38:15 +00007171//
7172// class A
7173// {
7174// public:
7175// int m_a;
7176// int m_b;
7177// };
7178//
7179// class B
7180// {
7181// };
7182//
7183// class C :
7184// public B,
7185// public A
7186// {
7187// };
7188//
7189// If we have a clang type that describes "class C", and we wanted to looked
7190// "m_b" in it:
7191//
Kate Stoneb9c1b512016-09-06 20:57:50 +00007192// With omit_empty_base_classes == false we would get an integer array back
Adrian Prantl05097242018-04-30 16:49:04 +00007193// with: { 1, 1 } The first index 1 is the child index for "class A" within
7194// class C The second index 1 is the child index for "m_b" within class A
Greg Claytond8d4a572015-08-11 21:38:15 +00007195//
Adrian Prantl05097242018-04-30 16:49:04 +00007196// With omit_empty_base_classes == true we would get an integer array back
7197// with: { 0, 1 } The first index 0 is the child index for "class A" within
7198// class C (since class B doesn't have any members it doesn't count) The second
7199// index 1 is the child index for "m_b" within class A
Greg Claytond8d4a572015-08-11 21:38:15 +00007200
Kate Stoneb9c1b512016-09-06 20:57:50 +00007201size_t ClangASTContext::GetIndexOfChildMemberWithName(
7202 lldb::opaque_compiler_type_t type, const char *name,
7203 bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
7204 if (type && name && name[0]) {
7205 clang::QualType qual_type(GetCanonicalQualType(type));
7206 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7207 switch (type_class) {
7208 case clang::Type::Record:
7209 if (GetCompleteType(type)) {
7210 const clang::RecordType *record_type =
7211 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
7212 const clang::RecordDecl *record_decl = record_type->getDecl();
Enrico Granata36f51e42015-12-18 22:41:25 +00007213
Kate Stoneb9c1b512016-09-06 20:57:50 +00007214 assert(record_decl);
7215 uint32_t child_idx = 0;
7216
7217 const clang::CXXRecordDecl *cxx_record_decl =
7218 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
7219
7220 // Try and find a field that matches NAME
7221 clang::RecordDecl::field_iterator field, field_end;
7222 llvm::StringRef name_sref(name);
7223 for (field = record_decl->field_begin(),
7224 field_end = record_decl->field_end();
7225 field != field_end; ++field, ++child_idx) {
7226 llvm::StringRef field_name = field->getName();
7227 if (field_name.empty()) {
7228 CompilerType field_type(getASTContext(), field->getType());
7229 child_indexes.push_back(child_idx);
7230 if (field_type.GetIndexOfChildMemberWithName(
7231 name, omit_empty_base_classes, child_indexes))
7232 return child_indexes.size();
7233 child_indexes.pop_back();
7234
7235 } else if (field_name.equals(name_sref)) {
7236 // We have to add on the number of base classes to this index!
7237 child_indexes.push_back(
7238 child_idx + ClangASTContext::GetNumBaseClasses(
7239 cxx_record_decl, omit_empty_base_classes));
7240 return child_indexes.size();
7241 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007242 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007243
Kate Stoneb9c1b512016-09-06 20:57:50 +00007244 if (cxx_record_decl) {
7245 const clang::RecordDecl *parent_record_decl = cxx_record_decl;
7246
7247 // printf ("parent = %s\n", parent_record_decl->getNameAsCString());
7248
7249 // const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
7250 // Didn't find things easily, lets let clang do its thang...
7251 clang::IdentifierInfo &ident_ref =
7252 getASTContext()->Idents.get(name_sref);
7253 clang::DeclarationName decl_name(&ident_ref);
7254
7255 clang::CXXBasePaths paths;
7256 if (cxx_record_decl->lookupInBases(
7257 [decl_name](const clang::CXXBaseSpecifier *specifier,
7258 clang::CXXBasePath &path) {
7259 return clang::CXXRecordDecl::FindOrdinaryMember(
7260 specifier, path, decl_name);
7261 },
7262 paths)) {
7263 clang::CXXBasePaths::const_paths_iterator path,
7264 path_end = paths.end();
7265 for (path = paths.begin(); path != path_end; ++path) {
7266 const size_t num_path_elements = path->size();
7267 for (size_t e = 0; e < num_path_elements; ++e) {
7268 clang::CXXBasePathElement elem = (*path)[e];
7269
7270 child_idx = GetIndexForRecordBase(parent_record_decl, elem.Base,
7271 omit_empty_base_classes);
7272 if (child_idx == UINT32_MAX) {
7273 child_indexes.clear();
7274 return 0;
7275 } else {
7276 child_indexes.push_back(child_idx);
7277 parent_record_decl = llvm::cast<clang::RecordDecl>(
7278 elem.Base->getType()
7279 ->getAs<clang::RecordType>()
7280 ->getDecl());
7281 }
7282 }
7283 for (clang::NamedDecl *path_decl : path->Decls) {
7284 child_idx = GetIndexForRecordChild(
7285 parent_record_decl, path_decl, omit_empty_base_classes);
7286 if (child_idx == UINT32_MAX) {
7287 child_indexes.clear();
7288 return 0;
7289 } else {
7290 child_indexes.push_back(child_idx);
7291 }
7292 }
7293 }
7294 return child_indexes.size();
7295 }
7296 }
7297 }
7298 break;
7299
7300 case clang::Type::ObjCObject:
7301 case clang::Type::ObjCInterface:
7302 if (GetCompleteType(type)) {
7303 llvm::StringRef name_sref(name);
7304 const clang::ObjCObjectType *objc_class_type =
7305 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
7306 assert(objc_class_type);
7307 if (objc_class_type) {
7308 uint32_t child_idx = 0;
7309 clang::ObjCInterfaceDecl *class_interface_decl =
7310 objc_class_type->getInterface();
7311
7312 if (class_interface_decl) {
7313 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
7314 ivar_end = class_interface_decl->ivar_end();
7315 clang::ObjCInterfaceDecl *superclass_interface_decl =
7316 class_interface_decl->getSuperClass();
7317
7318 for (ivar_pos = class_interface_decl->ivar_begin();
7319 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
7320 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
7321
7322 if (ivar_decl->getName().equals(name_sref)) {
7323 if ((!omit_empty_base_classes && superclass_interface_decl) ||
7324 (omit_empty_base_classes &&
7325 ObjCDeclHasIVars(superclass_interface_decl, true)))
7326 ++child_idx;
7327
7328 child_indexes.push_back(child_idx);
7329 return child_indexes.size();
7330 }
7331 }
7332
7333 if (superclass_interface_decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00007334 // The super class index is always zero for ObjC classes, so we
7335 // push it onto the child indexes in case we find an ivar in our
7336 // superclass...
Kate Stoneb9c1b512016-09-06 20:57:50 +00007337 child_indexes.push_back(0);
7338
7339 CompilerType superclass_clang_type(
7340 getASTContext(), getASTContext()->getObjCInterfaceType(
7341 superclass_interface_decl));
7342 if (superclass_clang_type.GetIndexOfChildMemberWithName(
7343 name, omit_empty_base_classes, child_indexes)) {
Adrian Prantl05097242018-04-30 16:49:04 +00007344 // We did find an ivar in a superclass so just return the
7345 // results!
Kate Stoneb9c1b512016-09-06 20:57:50 +00007346 return child_indexes.size();
7347 }
7348
Adrian Prantl05097242018-04-30 16:49:04 +00007349 // We didn't find an ivar matching "name" in our superclass, pop
7350 // the superclass zero index that we pushed on above.
Kate Stoneb9c1b512016-09-06 20:57:50 +00007351 child_indexes.pop_back();
7352 }
7353 }
7354 }
7355 }
7356 break;
7357
7358 case clang::Type::ObjCObjectPointer: {
7359 CompilerType objc_object_clang_type(
7360 getASTContext(),
7361 llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
7362 ->getPointeeType());
7363 return objc_object_clang_type.GetIndexOfChildMemberWithName(
7364 name, omit_empty_base_classes, child_indexes);
7365 } break;
7366
7367 case clang::Type::ConstantArray: {
7368 // const clang::ConstantArrayType *array =
7369 // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
7370 // const uint64_t element_count =
7371 // array->getSize().getLimitedValue();
7372 //
7373 // if (idx < element_count)
7374 // {
7375 // std::pair<uint64_t, unsigned> field_type_info =
7376 // ast->getTypeInfo(array->getElementType());
7377 //
7378 // char element_name[32];
7379 // ::snprintf (element_name, sizeof (element_name),
7380 // "%s[%u]", parent_name ? parent_name : "", idx);
7381 //
7382 // child_name.assign(element_name);
7383 // assert(field_type_info.first % 8 == 0);
7384 // child_byte_size = field_type_info.first / 8;
7385 // child_byte_offset = idx * child_byte_size;
7386 // return array->getElementType().getAsOpaquePtr();
7387 // }
7388 } break;
7389
7390 // case clang::Type::MemberPointerType:
7391 // {
7392 // MemberPointerType *mem_ptr_type =
7393 // llvm::cast<MemberPointerType>(qual_type.getTypePtr());
7394 // clang::QualType pointee_type =
7395 // mem_ptr_type->getPointeeType();
7396 //
7397 // if (ClangASTContext::IsAggregateType
7398 // (pointee_type.getAsOpaquePtr()))
7399 // {
7400 // return GetIndexOfChildWithName (ast,
7401 // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
7402 // name);
7403 // }
7404 // }
7405 // break;
7406 //
7407 case clang::Type::LValueReference:
7408 case clang::Type::RValueReference: {
7409 const clang::ReferenceType *reference_type =
7410 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
7411 clang::QualType pointee_type(reference_type->getPointeeType());
7412 CompilerType pointee_clang_type(getASTContext(), pointee_type);
7413
7414 if (pointee_clang_type.IsAggregateType()) {
7415 return pointee_clang_type.GetIndexOfChildMemberWithName(
7416 name, omit_empty_base_classes, child_indexes);
7417 }
7418 } break;
7419
7420 case clang::Type::Pointer: {
7421 CompilerType pointee_clang_type(GetPointeeType(type));
7422
7423 if (pointee_clang_type.IsAggregateType()) {
7424 return pointee_clang_type.GetIndexOfChildMemberWithName(
7425 name, omit_empty_base_classes, child_indexes);
7426 }
7427 } break;
7428
7429 case clang::Type::Typedef:
7430 return CompilerType(getASTContext(),
7431 llvm::cast<clang::TypedefType>(qual_type)
7432 ->getDecl()
7433 ->getUnderlyingType())
7434 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7435 child_indexes);
7436
7437 case clang::Type::Auto:
7438 return CompilerType(
7439 getASTContext(),
7440 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
7441 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7442 child_indexes);
7443
7444 case clang::Type::Elaborated:
7445 return CompilerType(
7446 getASTContext(),
7447 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
7448 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7449 child_indexes);
7450
7451 case clang::Type::Paren:
7452 return CompilerType(getASTContext(),
7453 llvm::cast<clang::ParenType>(qual_type)->desugar())
7454 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7455 child_indexes);
7456
7457 default:
7458 break;
7459 }
7460 }
7461 return 0;
7462}
Greg Claytond8d4a572015-08-11 21:38:15 +00007463
7464// Get the index of the child of "clang_type" whose name matches. This function
7465// doesn't descend into the children, but only looks one level deep and name
7466// matches can include base class names.
7467
7468uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00007469ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
7470 const char *name,
7471 bool omit_empty_base_classes) {
7472 if (type && name && name[0]) {
7473 clang::QualType qual_type(GetCanonicalQualType(type));
Enrico Granata36f51e42015-12-18 22:41:25 +00007474
Kate Stoneb9c1b512016-09-06 20:57:50 +00007475 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7476
7477 switch (type_class) {
7478 case clang::Type::Record:
7479 if (GetCompleteType(type)) {
7480 const clang::RecordType *record_type =
7481 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
7482 const clang::RecordDecl *record_decl = record_type->getDecl();
7483
7484 assert(record_decl);
7485 uint32_t child_idx = 0;
7486
7487 const clang::CXXRecordDecl *cxx_record_decl =
7488 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
7489
7490 if (cxx_record_decl) {
7491 clang::CXXRecordDecl::base_class_const_iterator base_class,
7492 base_class_end;
7493 for (base_class = cxx_record_decl->bases_begin(),
7494 base_class_end = cxx_record_decl->bases_end();
7495 base_class != base_class_end; ++base_class) {
7496 // Skip empty base classes
7497 clang::CXXRecordDecl *base_class_decl =
7498 llvm::cast<clang::CXXRecordDecl>(
7499 base_class->getType()
7500 ->getAs<clang::RecordType>()
7501 ->getDecl());
7502 if (omit_empty_base_classes &&
Jonas Devliegherea6682a42018-12-15 00:15:33 +00007503 !ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00007504 continue;
7505
7506 CompilerType base_class_clang_type(getASTContext(),
7507 base_class->getType());
7508 std::string base_class_type_name(
7509 base_class_clang_type.GetTypeName().AsCString(""));
Jonas Devlieghere8d20cfd2018-12-21 22:46:10 +00007510 if (base_class_type_name == name)
Kate Stoneb9c1b512016-09-06 20:57:50 +00007511 return child_idx;
7512 ++child_idx;
7513 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007514 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007515
Kate Stoneb9c1b512016-09-06 20:57:50 +00007516 // Try and find a field that matches NAME
7517 clang::RecordDecl::field_iterator field, field_end;
7518 llvm::StringRef name_sref(name);
7519 for (field = record_decl->field_begin(),
7520 field_end = record_decl->field_end();
7521 field != field_end; ++field, ++child_idx) {
7522 if (field->getName().equals(name_sref))
7523 return child_idx;
7524 }
7525 }
7526 break;
7527
7528 case clang::Type::ObjCObject:
7529 case clang::Type::ObjCInterface:
7530 if (GetCompleteType(type)) {
7531 llvm::StringRef name_sref(name);
7532 const clang::ObjCObjectType *objc_class_type =
7533 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
7534 assert(objc_class_type);
7535 if (objc_class_type) {
7536 uint32_t child_idx = 0;
7537 clang::ObjCInterfaceDecl *class_interface_decl =
7538 objc_class_type->getInterface();
7539
7540 if (class_interface_decl) {
7541 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
7542 ivar_end = class_interface_decl->ivar_end();
7543 clang::ObjCInterfaceDecl *superclass_interface_decl =
7544 class_interface_decl->getSuperClass();
7545
7546 for (ivar_pos = class_interface_decl->ivar_begin();
7547 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
7548 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
7549
7550 if (ivar_decl->getName().equals(name_sref)) {
7551 if ((!omit_empty_base_classes && superclass_interface_decl) ||
7552 (omit_empty_base_classes &&
7553 ObjCDeclHasIVars(superclass_interface_decl, true)))
7554 ++child_idx;
7555
7556 return child_idx;
7557 }
7558 }
7559
7560 if (superclass_interface_decl) {
7561 if (superclass_interface_decl->getName().equals(name_sref))
7562 return 0;
7563 }
7564 }
7565 }
7566 }
7567 break;
7568
7569 case clang::Type::ObjCObjectPointer: {
7570 CompilerType pointee_clang_type(
7571 getASTContext(),
7572 llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
7573 ->getPointeeType());
7574 return pointee_clang_type.GetIndexOfChildWithName(
7575 name, omit_empty_base_classes);
7576 } break;
7577
7578 case clang::Type::ConstantArray: {
7579 // const clang::ConstantArrayType *array =
7580 // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
7581 // const uint64_t element_count =
7582 // array->getSize().getLimitedValue();
7583 //
7584 // if (idx < element_count)
7585 // {
7586 // std::pair<uint64_t, unsigned> field_type_info =
7587 // ast->getTypeInfo(array->getElementType());
7588 //
7589 // char element_name[32];
7590 // ::snprintf (element_name, sizeof (element_name),
7591 // "%s[%u]", parent_name ? parent_name : "", idx);
7592 //
7593 // child_name.assign(element_name);
7594 // assert(field_type_info.first % 8 == 0);
7595 // child_byte_size = field_type_info.first / 8;
7596 // child_byte_offset = idx * child_byte_size;
7597 // return array->getElementType().getAsOpaquePtr();
7598 // }
7599 } break;
7600
7601 // case clang::Type::MemberPointerType:
7602 // {
7603 // MemberPointerType *mem_ptr_type =
7604 // llvm::cast<MemberPointerType>(qual_type.getTypePtr());
7605 // clang::QualType pointee_type =
7606 // mem_ptr_type->getPointeeType();
7607 //
7608 // if (ClangASTContext::IsAggregateType
7609 // (pointee_type.getAsOpaquePtr()))
7610 // {
7611 // return GetIndexOfChildWithName (ast,
7612 // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
7613 // name);
7614 // }
7615 // }
7616 // break;
7617 //
7618 case clang::Type::LValueReference:
7619 case clang::Type::RValueReference: {
7620 const clang::ReferenceType *reference_type =
7621 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
7622 CompilerType pointee_type(getASTContext(),
7623 reference_type->getPointeeType());
7624
7625 if (pointee_type.IsAggregateType()) {
7626 return pointee_type.GetIndexOfChildWithName(name,
7627 omit_empty_base_classes);
7628 }
7629 } break;
7630
7631 case clang::Type::Pointer: {
7632 const clang::PointerType *pointer_type =
7633 llvm::cast<clang::PointerType>(qual_type.getTypePtr());
7634 CompilerType pointee_type(getASTContext(),
7635 pointer_type->getPointeeType());
7636
7637 if (pointee_type.IsAggregateType()) {
7638 return pointee_type.GetIndexOfChildWithName(name,
7639 omit_empty_base_classes);
7640 } else {
7641 // if (parent_name)
7642 // {
7643 // child_name.assign(1, '*');
7644 // child_name += parent_name;
7645 // }
7646 //
7647 // // We have a pointer to an simple type
7648 // if (idx == 0)
7649 // {
7650 // std::pair<uint64_t, unsigned> clang_type_info
7651 // = ast->getTypeInfo(pointee_type);
7652 // assert(clang_type_info.first % 8 == 0);
7653 // child_byte_size = clang_type_info.first / 8;
7654 // child_byte_offset = 0;
7655 // return pointee_type.getAsOpaquePtr();
7656 // }
7657 }
7658 } break;
7659
7660 case clang::Type::Auto:
7661 return CompilerType(
7662 getASTContext(),
7663 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
7664 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7665
7666 case clang::Type::Elaborated:
7667 return CompilerType(
7668 getASTContext(),
7669 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
7670 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7671
7672 case clang::Type::Paren:
7673 return CompilerType(getASTContext(),
7674 llvm::cast<clang::ParenType>(qual_type)->desugar())
7675 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7676
7677 case clang::Type::Typedef:
7678 return CompilerType(getASTContext(),
7679 llvm::cast<clang::TypedefType>(qual_type)
7680 ->getDecl()
7681 ->getUnderlyingType())
7682 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7683
7684 default:
7685 break;
7686 }
7687 }
7688 return UINT32_MAX;
7689}
Greg Claytond8d4a572015-08-11 21:38:15 +00007690
7691size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00007692ClangASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
7693 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00007694 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00007695
Kate Stoneb9c1b512016-09-06 20:57:50 +00007696 clang::QualType qual_type(GetCanonicalQualType(type));
7697 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7698 switch (type_class) {
7699 case clang::Type::Record:
7700 if (GetCompleteType(type)) {
7701 const clang::CXXRecordDecl *cxx_record_decl =
7702 qual_type->getAsCXXRecordDecl();
7703 if (cxx_record_decl) {
7704 const clang::ClassTemplateSpecializationDecl *template_decl =
7705 llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
7706 cxx_record_decl);
7707 if (template_decl)
7708 return template_decl->getTemplateArgs().size();
7709 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007710 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007711 break;
7712
7713 case clang::Type::Typedef:
7714 return (CompilerType(getASTContext(),
7715 llvm::cast<clang::TypedefType>(qual_type)
7716 ->getDecl()
7717 ->getUnderlyingType()))
7718 .GetNumTemplateArguments();
7719
7720 case clang::Type::Auto:
7721 return (CompilerType(
7722 getASTContext(),
7723 llvm::cast<clang::AutoType>(qual_type)->getDeducedType()))
7724 .GetNumTemplateArguments();
7725
7726 case clang::Type::Elaborated:
7727 return (CompilerType(
7728 getASTContext(),
7729 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()))
7730 .GetNumTemplateArguments();
7731
7732 case clang::Type::Paren:
7733 return (CompilerType(getASTContext(),
7734 llvm::cast<clang::ParenType>(qual_type)->desugar()))
7735 .GetNumTemplateArguments();
7736
7737 default:
7738 break;
7739 }
7740
7741 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00007742}
7743
Pavel Labath769b21e2017-11-13 14:26:21 +00007744const clang::ClassTemplateSpecializationDecl *
7745ClangASTContext::GetAsTemplateSpecialization(
7746 lldb::opaque_compiler_type_t type) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00007747 if (!type)
Pavel Labath769b21e2017-11-13 14:26:21 +00007748 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007749
7750 clang::QualType qual_type(GetCanonicalQualType(type));
7751 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7752 switch (type_class) {
Pavel Labath769b21e2017-11-13 14:26:21 +00007753 case clang::Type::Record: {
7754 if (! GetCompleteType(type))
7755 return nullptr;
7756 const clang::CXXRecordDecl *cxx_record_decl =
7757 qual_type->getAsCXXRecordDecl();
7758 if (!cxx_record_decl)
7759 return nullptr;
7760 return llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
7761 cxx_record_decl);
7762 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007763
7764 case clang::Type::Typedef:
Pavel Labath769b21e2017-11-13 14:26:21 +00007765 return GetAsTemplateSpecialization(llvm::cast<clang::TypedefType>(qual_type)
7766 ->getDecl()
7767 ->getUnderlyingType()
7768 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007769
7770 case clang::Type::Auto:
Pavel Labath769b21e2017-11-13 14:26:21 +00007771 return GetAsTemplateSpecialization(llvm::cast<clang::AutoType>(qual_type)
7772 ->getDeducedType()
7773 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007774
7775 case clang::Type::Elaborated:
Pavel Labath769b21e2017-11-13 14:26:21 +00007776 return GetAsTemplateSpecialization(
7777 llvm::cast<clang::ElaboratedType>(qual_type)
7778 ->getNamedType()
7779 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007780
7781 case clang::Type::Paren:
Pavel Labath769b21e2017-11-13 14:26:21 +00007782 return GetAsTemplateSpecialization(
7783 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007784
7785 default:
Pavel Labath769b21e2017-11-13 14:26:21 +00007786 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007787 }
Pavel Labath769b21e2017-11-13 14:26:21 +00007788}
7789
7790lldb::TemplateArgumentKind
7791ClangASTContext::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
7792 size_t arg_idx) {
7793 const clang::ClassTemplateSpecializationDecl *template_decl =
7794 GetAsTemplateSpecialization(type);
7795 if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size())
7796 return eTemplateArgumentKindNull;
7797
7798 switch (template_decl->getTemplateArgs()[arg_idx].getKind()) {
7799 case clang::TemplateArgument::Null:
7800 return eTemplateArgumentKindNull;
7801
7802 case clang::TemplateArgument::NullPtr:
7803 return eTemplateArgumentKindNullPtr;
7804
7805 case clang::TemplateArgument::Type:
7806 return eTemplateArgumentKindType;
7807
7808 case clang::TemplateArgument::Declaration:
7809 return eTemplateArgumentKindDeclaration;
7810
7811 case clang::TemplateArgument::Integral:
7812 return eTemplateArgumentKindIntegral;
7813
7814 case clang::TemplateArgument::Template:
7815 return eTemplateArgumentKindTemplate;
7816
7817 case clang::TemplateArgument::TemplateExpansion:
7818 return eTemplateArgumentKindTemplateExpansion;
7819
7820 case clang::TemplateArgument::Expression:
7821 return eTemplateArgumentKindExpression;
7822
7823 case clang::TemplateArgument::Pack:
7824 return eTemplateArgumentKindPack;
7825 }
7826 llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind");
7827}
7828
7829CompilerType
7830ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
7831 size_t idx) {
7832 const clang::ClassTemplateSpecializationDecl *template_decl =
7833 GetAsTemplateSpecialization(type);
7834 if (!template_decl || idx >= template_decl->getTemplateArgs().size())
7835 return CompilerType();
7836
7837 const clang::TemplateArgument &template_arg =
7838 template_decl->getTemplateArgs()[idx];
7839 if (template_arg.getKind() != clang::TemplateArgument::Type)
7840 return CompilerType();
7841
7842 return CompilerType(getASTContext(), template_arg.getAsType());
7843}
7844
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00007845Optional<CompilerType::IntegralTemplateArgument>
Pavel Labath769b21e2017-11-13 14:26:21 +00007846ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
7847 size_t idx) {
7848 const clang::ClassTemplateSpecializationDecl *template_decl =
7849 GetAsTemplateSpecialization(type);
7850 if (! template_decl || idx >= template_decl->getTemplateArgs().size())
Pavel Labathf59056f2017-11-30 10:16:54 +00007851 return llvm::None;
Pavel Labath769b21e2017-11-13 14:26:21 +00007852
7853 const clang::TemplateArgument &template_arg =
7854 template_decl->getTemplateArgs()[idx];
7855 if (template_arg.getKind() != clang::TemplateArgument::Integral)
Pavel Labathf59056f2017-11-30 10:16:54 +00007856 return llvm::None;
Pavel Labath769b21e2017-11-13 14:26:21 +00007857
Pavel Labathf59056f2017-11-30 10:16:54 +00007858 return {{template_arg.getAsIntegral(),
7859 CompilerType(getASTContext(), template_arg.getIntegralType())}};
Enrico Granatac6bf2e22015-09-23 01:39:46 +00007860}
7861
Kate Stoneb9c1b512016-09-06 20:57:50 +00007862CompilerType ClangASTContext::GetTypeForFormatters(void *type) {
7863 if (type)
7864 return ClangUtil::RemoveFastQualifiers(CompilerType(this, type));
7865 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00007866}
7867
Kate Stoneb9c1b512016-09-06 20:57:50 +00007868clang::EnumDecl *ClangASTContext::GetAsEnumDecl(const CompilerType &type) {
7869 const clang::EnumType *enutype =
7870 llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type));
7871 if (enutype)
7872 return enutype->getDecl();
Konrad Kleine248a1302019-05-23 11:14:47 +00007873 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007874}
7875
7876clang::RecordDecl *ClangASTContext::GetAsRecordDecl(const CompilerType &type) {
7877 const clang::RecordType *record_type =
7878 llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type));
7879 if (record_type)
7880 return record_type->getDecl();
7881 return nullptr;
7882}
7883
7884clang::TagDecl *ClangASTContext::GetAsTagDecl(const CompilerType &type) {
Zachary Turner1639c6b2018-12-17 16:15:13 +00007885 return ClangUtil::GetAsTagDecl(type);
Greg Claytone6b36cd2015-12-08 01:02:08 +00007886}
7887
Aleksandr Urakov709426b2018-09-10 08:08:43 +00007888clang::TypedefNameDecl *
7889ClangASTContext::GetAsTypedefDecl(const CompilerType &type) {
7890 const clang::TypedefType *typedef_type =
7891 llvm::dyn_cast<clang::TypedefType>(ClangUtil::GetQualType(type));
7892 if (typedef_type)
7893 return typedef_type->getDecl();
7894 return nullptr;
7895}
7896
Greg Claytond8d4a572015-08-11 21:38:15 +00007897clang::CXXRecordDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00007898ClangASTContext::GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type) {
7899 return GetCanonicalQualType(type)->getAsCXXRecordDecl();
Greg Claytond8d4a572015-08-11 21:38:15 +00007900}
7901
7902clang::ObjCInterfaceDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00007903ClangASTContext::GetAsObjCInterfaceDecl(const CompilerType &type) {
7904 const clang::ObjCObjectType *objc_class_type =
7905 llvm::dyn_cast<clang::ObjCObjectType>(
7906 ClangUtil::GetCanonicalQualType(type));
7907 if (objc_class_type)
7908 return objc_class_type->getInterface();
7909 return nullptr;
7910}
7911
7912clang::FieldDecl *ClangASTContext::AddFieldToRecordType(
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007913 const CompilerType &type, llvm::StringRef name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00007914 const CompilerType &field_clang_type, AccessType access,
7915 uint32_t bitfield_bit_size) {
7916 if (!type.IsValid() || !field_clang_type.IsValid())
Greg Claytond8d4a572015-08-11 21:38:15 +00007917 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007918 ClangASTContext *ast =
7919 llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
7920 if (!ast)
7921 return nullptr;
7922 clang::ASTContext *clang_ast = ast->getASTContext();
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007923 clang::IdentifierInfo *ident = nullptr;
7924 if (!name.empty())
7925 ident = &clang_ast->Idents.get(name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00007926
7927 clang::FieldDecl *field = nullptr;
7928
7929 clang::Expr *bit_width = nullptr;
7930 if (bitfield_bit_size != 0) {
7931 llvm::APInt bitfield_bit_size_apint(
7932 clang_ast->getTypeSize(clang_ast->IntTy), bitfield_bit_size);
7933 bit_width = new (*clang_ast)
7934 clang::IntegerLiteral(*clang_ast, bitfield_bit_size_apint,
7935 clang_ast->IntTy, clang::SourceLocation());
7936 }
7937
7938 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
7939 if (record_decl) {
7940 field = clang::FieldDecl::Create(
7941 *clang_ast, record_decl, clang::SourceLocation(),
7942 clang::SourceLocation(),
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007943 ident, // Identifier
7944 ClangUtil::GetQualType(field_clang_type), // Field type
7945 nullptr, // TInfo *
7946 bit_width, // BitWidth
7947 false, // Mutable
7948 clang::ICIS_NoInit); // HasInit
Kate Stoneb9c1b512016-09-06 20:57:50 +00007949
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007950 if (name.empty()) {
Adrian Prantl05097242018-04-30 16:49:04 +00007951 // Determine whether this field corresponds to an anonymous struct or
7952 // union.
Kate Stoneb9c1b512016-09-06 20:57:50 +00007953 if (const clang::TagType *TagT =
7954 field->getType()->getAs<clang::TagType>()) {
7955 if (clang::RecordDecl *Rec =
7956 llvm::dyn_cast<clang::RecordDecl>(TagT->getDecl()))
7957 if (!Rec->getDeclName()) {
7958 Rec->setAnonymousStructOrUnion(true);
7959 field->setImplicit();
7960 }
7961 }
7962 }
7963
7964 if (field) {
7965 field->setAccess(
7966 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access));
7967
7968 record_decl->addDecl(field);
7969
7970#ifdef LLDB_CONFIGURATION_DEBUG
7971 VerifyDecl(field);
7972#endif
7973 }
7974 } else {
7975 clang::ObjCInterfaceDecl *class_interface_decl =
7976 ast->GetAsObjCInterfaceDecl(type);
7977
7978 if (class_interface_decl) {
7979 const bool is_synthesized = false;
7980
7981 field_clang_type.GetCompleteType();
7982
7983 field = clang::ObjCIvarDecl::Create(
7984 *clang_ast, class_interface_decl, clang::SourceLocation(),
7985 clang::SourceLocation(),
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007986 ident, // Identifier
7987 ClangUtil::GetQualType(field_clang_type), // Field type
7988 nullptr, // TypeSourceInfo *
Kate Stoneb9c1b512016-09-06 20:57:50 +00007989 ConvertAccessTypeToObjCIvarAccessControl(access), bit_width,
7990 is_synthesized);
7991
7992 if (field) {
7993 class_interface_decl->addDecl(field);
7994
7995#ifdef LLDB_CONFIGURATION_DEBUG
7996 VerifyDecl(field);
7997#endif
7998 }
7999 }
8000 }
8001 return field;
Greg Claytond8d4a572015-08-11 21:38:15 +00008002}
8003
Kate Stoneb9c1b512016-09-06 20:57:50 +00008004void ClangASTContext::BuildIndirectFields(const CompilerType &type) {
8005 if (!type)
8006 return;
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008007
Kate Stoneb9c1b512016-09-06 20:57:50 +00008008 ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8009 if (!ast)
8010 return;
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008011
Kate Stoneb9c1b512016-09-06 20:57:50 +00008012 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008013
Kate Stoneb9c1b512016-09-06 20:57:50 +00008014 if (!record_decl)
8015 return;
8016
8017 typedef llvm::SmallVector<clang::IndirectFieldDecl *, 1> IndirectFieldVector;
8018
8019 IndirectFieldVector indirect_fields;
8020 clang::RecordDecl::field_iterator field_pos;
8021 clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end();
8022 clang::RecordDecl::field_iterator last_field_pos = field_end_pos;
8023 for (field_pos = record_decl->field_begin(); field_pos != field_end_pos;
8024 last_field_pos = field_pos++) {
8025 if (field_pos->isAnonymousStructOrUnion()) {
8026 clang::QualType field_qual_type = field_pos->getType();
8027
8028 const clang::RecordType *field_record_type =
8029 field_qual_type->getAs<clang::RecordType>();
8030
8031 if (!field_record_type)
8032 continue;
8033
8034 clang::RecordDecl *field_record_decl = field_record_type->getDecl();
8035
8036 if (!field_record_decl)
8037 continue;
8038
8039 for (clang::RecordDecl::decl_iterator
8040 di = field_record_decl->decls_begin(),
8041 de = field_record_decl->decls_end();
8042 di != de; ++di) {
8043 if (clang::FieldDecl *nested_field_decl =
8044 llvm::dyn_cast<clang::FieldDecl>(*di)) {
8045 clang::NamedDecl **chain =
8046 new (*ast->getASTContext()) clang::NamedDecl *[2];
8047 chain[0] = *field_pos;
8048 chain[1] = nested_field_decl;
8049 clang::IndirectFieldDecl *indirect_field =
8050 clang::IndirectFieldDecl::Create(
8051 *ast->getASTContext(), record_decl, clang::SourceLocation(),
8052 nested_field_decl->getIdentifier(),
8053 nested_field_decl->getType(), {chain, 2});
8054
8055 indirect_field->setImplicit();
8056
8057 indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(
8058 field_pos->getAccess(), nested_field_decl->getAccess()));
8059
8060 indirect_fields.push_back(indirect_field);
8061 } else if (clang::IndirectFieldDecl *nested_indirect_field_decl =
8062 llvm::dyn_cast<clang::IndirectFieldDecl>(*di)) {
8063 size_t nested_chain_size =
8064 nested_indirect_field_decl->getChainingSize();
8065 clang::NamedDecl **chain = new (*ast->getASTContext())
8066 clang::NamedDecl *[nested_chain_size + 1];
8067 chain[0] = *field_pos;
8068
8069 int chain_index = 1;
8070 for (clang::IndirectFieldDecl::chain_iterator
8071 nci = nested_indirect_field_decl->chain_begin(),
8072 nce = nested_indirect_field_decl->chain_end();
8073 nci < nce; ++nci) {
8074 chain[chain_index] = *nci;
8075 chain_index++;
8076 }
8077
8078 clang::IndirectFieldDecl *indirect_field =
8079 clang::IndirectFieldDecl::Create(
8080 *ast->getASTContext(), record_decl, clang::SourceLocation(),
8081 nested_indirect_field_decl->getIdentifier(),
8082 nested_indirect_field_decl->getType(),
8083 {chain, nested_chain_size + 1});
8084
8085 indirect_field->setImplicit();
8086
8087 indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(
8088 field_pos->getAccess(), nested_indirect_field_decl->getAccess()));
8089
8090 indirect_fields.push_back(indirect_field);
Greg Claytond8d4a572015-08-11 21:38:15 +00008091 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008092 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008093 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008094 }
8095
Adrian Prantl05097242018-04-30 16:49:04 +00008096 // Check the last field to see if it has an incomplete array type as its last
8097 // member and if it does, the tell the record decl about it
Kate Stoneb9c1b512016-09-06 20:57:50 +00008098 if (last_field_pos != field_end_pos) {
8099 if (last_field_pos->getType()->isIncompleteArrayType())
8100 record_decl->hasFlexibleArrayMember();
8101 }
8102
8103 for (IndirectFieldVector::iterator ifi = indirect_fields.begin(),
8104 ife = indirect_fields.end();
8105 ifi < ife; ++ifi) {
8106 record_decl->addDecl(*ifi);
8107 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008108}
8109
Kate Stoneb9c1b512016-09-06 20:57:50 +00008110void ClangASTContext::SetIsPacked(const CompilerType &type) {
8111 if (type) {
8112 ClangASTContext *ast =
8113 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8114 if (ast) {
8115 clang::RecordDecl *record_decl = GetAsRecordDecl(type);
8116
8117 if (!record_decl)
Greg Claytonf73034f2015-09-08 18:15:05 +00008118 return;
8119
Kate Stoneb9c1b512016-09-06 20:57:50 +00008120 record_decl->addAttr(
8121 clang::PackedAttr::CreateImplicit(*ast->getASTContext()));
Greg Claytond8d4a572015-08-11 21:38:15 +00008122 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008123 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008124}
8125
Kate Stoneb9c1b512016-09-06 20:57:50 +00008126clang::VarDecl *ClangASTContext::AddVariableToRecordType(
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008127 const CompilerType &type, llvm::StringRef name,
8128 const CompilerType &var_type, AccessType access) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00008129 if (!type.IsValid() || !var_type.IsValid())
8130 return nullptr;
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008131
Kate Stoneb9c1b512016-09-06 20:57:50 +00008132 ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8133 if (!ast)
8134 return nullptr;
8135
8136 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008137 if (!record_decl)
8138 return nullptr;
8139
8140 clang::VarDecl *var_decl = nullptr;
8141 clang::IdentifierInfo *ident = nullptr;
8142 if (!name.empty())
8143 ident = &ast->getASTContext()->Idents.get(name);
8144
8145 var_decl = clang::VarDecl::Create(
8146 *ast->getASTContext(), // ASTContext &
8147 record_decl, // DeclContext *
8148 clang::SourceLocation(), // clang::SourceLocation StartLoc
8149 clang::SourceLocation(), // clang::SourceLocation IdLoc
8150 ident, // clang::IdentifierInfo *
8151 ClangUtil::GetQualType(var_type), // Variable clang::QualType
8152 nullptr, // TypeSourceInfo *
8153 clang::SC_Static); // StorageClass
8154 if (!var_decl)
8155 return nullptr;
8156
8157 var_decl->setAccess(
8158 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access));
8159 record_decl->addDecl(var_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008160
Greg Claytond8d4a572015-08-11 21:38:15 +00008161#ifdef LLDB_CONFIGURATION_DEBUG
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008162 VerifyDecl(var_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008163#endif
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008164
Kate Stoneb9c1b512016-09-06 20:57:50 +00008165 return var_decl;
Greg Claytond8d4a572015-08-11 21:38:15 +00008166}
8167
Kate Stoneb9c1b512016-09-06 20:57:50 +00008168clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
Davide Italiano675767a2018-03-27 19:40:50 +00008169 lldb::opaque_compiler_type_t type, const char *name, const char *mangled_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00008170 const CompilerType &method_clang_type, lldb::AccessType access,
8171 bool is_virtual, bool is_static, bool is_inline, bool is_explicit,
8172 bool is_attr_used, bool is_artificial) {
8173 if (!type || !method_clang_type.IsValid() || name == nullptr ||
8174 name[0] == '\0')
8175 return nullptr;
Greg Claytond8d4a572015-08-11 21:38:15 +00008176
Kate Stoneb9c1b512016-09-06 20:57:50 +00008177 clang::QualType record_qual_type(GetCanonicalQualType(type));
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008178
Kate Stoneb9c1b512016-09-06 20:57:50 +00008179 clang::CXXRecordDecl *cxx_record_decl =
8180 record_qual_type->getAsCXXRecordDecl();
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008181
Kate Stoneb9c1b512016-09-06 20:57:50 +00008182 if (cxx_record_decl == nullptr)
8183 return nullptr;
8184
8185 clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
8186
8187 clang::CXXMethodDecl *cxx_method_decl = nullptr;
8188
8189 clang::DeclarationName decl_name(&getASTContext()->Idents.get(name));
8190
8191 const clang::FunctionType *function_type =
8192 llvm::dyn_cast<clang::FunctionType>(method_qual_type.getTypePtr());
8193
8194 if (function_type == nullptr)
8195 return nullptr;
8196
8197 const clang::FunctionProtoType *method_function_prototype(
8198 llvm::dyn_cast<clang::FunctionProtoType>(function_type));
8199
8200 if (!method_function_prototype)
8201 return nullptr;
8202
8203 unsigned int num_params = method_function_prototype->getNumParams();
8204
8205 clang::CXXDestructorDecl *cxx_dtor_decl(nullptr);
8206 clang::CXXConstructorDecl *cxx_ctor_decl(nullptr);
8207
8208 if (is_artificial)
8209 return nullptr; // skip everything artificial
8210
Richard Smith36851a62019-05-09 04:40:57 +00008211 const clang::ExplicitSpecifier explicit_spec(
8212 nullptr /*expr*/, is_explicit
8213 ? clang::ExplicitSpecKind::ResolvedTrue
8214 : clang::ExplicitSpecKind::ResolvedFalse);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008215 if (name[0] == '~') {
8216 cxx_dtor_decl = clang::CXXDestructorDecl::Create(
8217 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8218 clang::DeclarationNameInfo(
8219 getASTContext()->DeclarationNames.getCXXDestructorName(
8220 getASTContext()->getCanonicalType(record_qual_type)),
8221 clang::SourceLocation()),
8222 method_qual_type, nullptr, is_inline, is_artificial);
8223 cxx_method_decl = cxx_dtor_decl;
8224 } else if (decl_name == cxx_record_decl->getDeclName()) {
8225 cxx_ctor_decl = clang::CXXConstructorDecl::Create(
8226 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8227 clang::DeclarationNameInfo(
8228 getASTContext()->DeclarationNames.getCXXConstructorName(
8229 getASTContext()->getCanonicalType(record_qual_type)),
8230 clang::SourceLocation()),
8231 method_qual_type,
8232 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008233 explicit_spec, is_inline, is_artificial, CSK_unspecified);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008234 cxx_method_decl = cxx_ctor_decl;
8235 } else {
8236 clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
8237 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
8238
8239 if (IsOperator(name, op_kind)) {
8240 if (op_kind != clang::NUM_OVERLOADED_OPERATORS) {
Adrian Prantl05097242018-04-30 16:49:04 +00008241 // Check the number of operator parameters. Sometimes we have seen bad
8242 // DWARF that doesn't correctly describe operators and if we try to
8243 // create a method and add it to the class, clang will assert and
8244 // crash, so we need to make sure things are acceptable.
Kate Stoneb9c1b512016-09-06 20:57:50 +00008245 const bool is_method = true;
8246 if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
8247 is_method, op_kind, num_params))
8248 return nullptr;
8249 cxx_method_decl = clang::CXXMethodDecl::Create(
8250 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8251 clang::DeclarationNameInfo(
8252 getASTContext()->DeclarationNames.getCXXOperatorName(op_kind),
8253 clang::SourceLocation()),
8254 method_qual_type,
8255 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008256 SC, is_inline, CSK_unspecified, clang::SourceLocation());
Kate Stoneb9c1b512016-09-06 20:57:50 +00008257 } else if (num_params == 0) {
8258 // Conversion operators don't take params...
8259 cxx_method_decl = clang::CXXConversionDecl::Create(
8260 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8261 clang::DeclarationNameInfo(
8262 getASTContext()->DeclarationNames.getCXXConversionFunctionName(
8263 getASTContext()->getCanonicalType(
8264 function_type->getReturnType())),
8265 clang::SourceLocation()),
8266 method_qual_type,
8267 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008268 is_inline, explicit_spec, CSK_unspecified,
Kate Stoneb9c1b512016-09-06 20:57:50 +00008269 clang::SourceLocation());
8270 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008271 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008272
8273 if (cxx_method_decl == nullptr) {
8274 cxx_method_decl = clang::CXXMethodDecl::Create(
8275 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8276 clang::DeclarationNameInfo(decl_name, clang::SourceLocation()),
8277 method_qual_type,
8278 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008279 SC, is_inline, CSK_unspecified, clang::SourceLocation());
Greg Claytond8d4a572015-08-11 21:38:15 +00008280 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008281 }
8282
8283 clang::AccessSpecifier access_specifier =
8284 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access);
8285
8286 cxx_method_decl->setAccess(access_specifier);
8287 cxx_method_decl->setVirtualAsWritten(is_virtual);
8288
8289 if (is_attr_used)
8290 cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*getASTContext()));
8291
Konrad Kleine248a1302019-05-23 11:14:47 +00008292 if (mangled_name != nullptr) {
Davide Italiano675767a2018-03-27 19:40:50 +00008293 cxx_method_decl->addAttr(
8294 clang::AsmLabelAttr::CreateImplicit(*getASTContext(), mangled_name));
8295 }
8296
Kate Stoneb9c1b512016-09-06 20:57:50 +00008297 // Populate the method decl with parameter decls
8298
8299 llvm::SmallVector<clang::ParmVarDecl *, 12> params;
8300
8301 for (unsigned param_index = 0; param_index < num_params; ++param_index) {
8302 params.push_back(clang::ParmVarDecl::Create(
8303 *getASTContext(), cxx_method_decl, clang::SourceLocation(),
8304 clang::SourceLocation(),
8305 nullptr, // anonymous
8306 method_function_prototype->getParamType(param_index), nullptr,
8307 clang::SC_None, nullptr));
8308 }
8309
8310 cxx_method_decl->setParams(llvm::ArrayRef<clang::ParmVarDecl *>(params));
8311
8312 cxx_record_decl->addDecl(cxx_method_decl);
8313
8314 // Sometimes the debug info will mention a constructor (default/copy/move),
8315 // destructor, or assignment operator (copy/move) but there won't be any
8316 // version of this in the code. So we check if the function was artificially
8317 // generated and if it is trivial and this lets the compiler/backend know
8318 // that it can inline the IR for these when it needs to and we can avoid a
8319 // "missing function" error when running expressions.
8320
8321 if (is_artificial) {
8322 if (cxx_ctor_decl && ((cxx_ctor_decl->isDefaultConstructor() &&
8323 cxx_record_decl->hasTrivialDefaultConstructor()) ||
8324 (cxx_ctor_decl->isCopyConstructor() &&
8325 cxx_record_decl->hasTrivialCopyConstructor()) ||
8326 (cxx_ctor_decl->isMoveConstructor() &&
8327 cxx_record_decl->hasTrivialMoveConstructor()))) {
8328 cxx_ctor_decl->setDefaulted();
8329 cxx_ctor_decl->setTrivial(true);
8330 } else if (cxx_dtor_decl) {
8331 if (cxx_record_decl->hasTrivialDestructor()) {
8332 cxx_dtor_decl->setDefaulted();
8333 cxx_dtor_decl->setTrivial(true);
8334 }
8335 } else if ((cxx_method_decl->isCopyAssignmentOperator() &&
8336 cxx_record_decl->hasTrivialCopyAssignment()) ||
8337 (cxx_method_decl->isMoveAssignmentOperator() &&
8338 cxx_record_decl->hasTrivialMoveAssignment())) {
8339 cxx_method_decl->setDefaulted();
8340 cxx_method_decl->setTrivial(true);
Greg Claytond8d4a572015-08-11 21:38:15 +00008341 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008342 }
8343
Greg Claytond8d4a572015-08-11 21:38:15 +00008344#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00008345 VerifyDecl(cxx_method_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008346#endif
Greg Claytond8d4a572015-08-11 21:38:15 +00008347
Kate Stoneb9c1b512016-09-06 20:57:50 +00008348 return cxx_method_decl;
8349}
Greg Claytond8d4a572015-08-11 21:38:15 +00008350
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00008351void ClangASTContext::AddMethodOverridesForCXXRecordType(
8352 lldb::opaque_compiler_type_t type) {
8353 if (auto *record = GetAsCXXRecordDecl(type))
8354 for (auto *method : record->methods())
8355 addOverridesForMethod(method);
8356}
8357
Greg Claytond8d4a572015-08-11 21:38:15 +00008358#pragma mark C++ Base Classes
8359
Zachary Turner970f38e2018-10-25 20:44:56 +00008360std::unique_ptr<clang::CXXBaseSpecifier>
Kate Stoneb9c1b512016-09-06 20:57:50 +00008361ClangASTContext::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
8362 AccessType access, bool is_virtual,
8363 bool base_of_class) {
Zachary Turner970f38e2018-10-25 20:44:56 +00008364 if (!type)
8365 return nullptr;
8366
8367 return llvm::make_unique<clang::CXXBaseSpecifier>(
8368 clang::SourceRange(), is_virtual, base_of_class,
8369 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access),
8370 getASTContext()->getTrivialTypeSourceInfo(GetQualType(type)),
8371 clang::SourceLocation());
Kate Stoneb9c1b512016-09-06 20:57:50 +00008372}
8373
Zachary Turner970f38e2018-10-25 20:44:56 +00008374bool ClangASTContext::TransferBaseClasses(
Kate Stoneb9c1b512016-09-06 20:57:50 +00008375 lldb::opaque_compiler_type_t type,
Zachary Turner970f38e2018-10-25 20:44:56 +00008376 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases) {
8377 if (!type)
8378 return false;
8379 clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type);
8380 if (!cxx_record_decl)
8381 return false;
8382 std::vector<clang::CXXBaseSpecifier *> raw_bases;
8383 raw_bases.reserve(bases.size());
8384
8385 // Clang will make a copy of them, so it's ok that we pass pointers that we're
8386 // about to destroy.
8387 for (auto &b : bases)
8388 raw_bases.push_back(b.get());
8389 cxx_record_decl->setBases(raw_bases.data(), raw_bases.size());
8390 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00008391}
8392
8393bool ClangASTContext::SetObjCSuperClass(
8394 const CompilerType &type, const CompilerType &superclass_clang_type) {
8395 ClangASTContext *ast =
8396 llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
8397 if (!ast)
8398 return false;
8399 clang::ASTContext *clang_ast = ast->getASTContext();
8400
8401 if (type && superclass_clang_type.IsValid() &&
8402 superclass_clang_type.GetTypeSystem() == type.GetTypeSystem()) {
8403 clang::ObjCInterfaceDecl *class_interface_decl =
8404 GetAsObjCInterfaceDecl(type);
8405 clang::ObjCInterfaceDecl *super_interface_decl =
8406 GetAsObjCInterfaceDecl(superclass_clang_type);
8407 if (class_interface_decl && super_interface_decl) {
8408 class_interface_decl->setSuperClass(clang_ast->getTrivialTypeSourceInfo(
8409 clang_ast->getObjCInterfaceType(super_interface_decl)));
8410 return true;
8411 }
8412 }
8413 return false;
8414}
8415
8416bool ClangASTContext::AddObjCClassProperty(
8417 const CompilerType &type, const char *property_name,
8418 const CompilerType &property_clang_type, clang::ObjCIvarDecl *ivar_decl,
8419 const char *property_setter_name, const char *property_getter_name,
8420 uint32_t property_attributes, ClangASTMetadata *metadata) {
8421 if (!type || !property_clang_type.IsValid() || property_name == nullptr ||
8422 property_name[0] == '\0')
8423 return false;
8424 ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8425 if (!ast)
8426 return false;
8427 clang::ASTContext *clang_ast = ast->getASTContext();
8428
8429 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8430
8431 if (class_interface_decl) {
8432 CompilerType property_clang_type_to_access;
8433
8434 if (property_clang_type.IsValid())
8435 property_clang_type_to_access = property_clang_type;
8436 else if (ivar_decl)
8437 property_clang_type_to_access =
8438 CompilerType(clang_ast, ivar_decl->getType());
8439
8440 if (class_interface_decl && property_clang_type_to_access.IsValid()) {
8441 clang::TypeSourceInfo *prop_type_source;
8442 if (ivar_decl)
8443 prop_type_source =
8444 clang_ast->getTrivialTypeSourceInfo(ivar_decl->getType());
8445 else
8446 prop_type_source = clang_ast->getTrivialTypeSourceInfo(
8447 ClangUtil::GetQualType(property_clang_type));
8448
8449 clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create(
8450 *clang_ast, class_interface_decl,
8451 clang::SourceLocation(), // Source Location
8452 &clang_ast->Idents.get(property_name),
8453 clang::SourceLocation(), // Source Location for AT
8454 clang::SourceLocation(), // Source location for (
8455 ivar_decl ? ivar_decl->getType()
8456 : ClangUtil::GetQualType(property_clang_type),
8457 prop_type_source);
8458
8459 if (property_decl) {
8460 if (metadata)
8461 ClangASTContext::SetMetadata(clang_ast, property_decl, *metadata);
8462
8463 class_interface_decl->addDecl(property_decl);
8464
8465 clang::Selector setter_sel, getter_sel;
8466
8467 if (property_setter_name != nullptr) {
8468 std::string property_setter_no_colon(
8469 property_setter_name, strlen(property_setter_name) - 1);
8470 clang::IdentifierInfo *setter_ident =
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00008471 &clang_ast->Idents.get(property_setter_no_colon);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008472 setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
8473 } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) {
8474 std::string setter_sel_string("set");
8475 setter_sel_string.push_back(::toupper(property_name[0]));
8476 setter_sel_string.append(&property_name[1]);
8477 clang::IdentifierInfo *setter_ident =
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00008478 &clang_ast->Idents.get(setter_sel_string);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008479 setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
8480 }
8481 property_decl->setSetterName(setter_sel);
8482 property_decl->setPropertyAttributes(
8483 clang::ObjCPropertyDecl::OBJC_PR_setter);
8484
8485 if (property_getter_name != nullptr) {
8486 clang::IdentifierInfo *getter_ident =
8487 &clang_ast->Idents.get(property_getter_name);
8488 getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
8489 } else {
8490 clang::IdentifierInfo *getter_ident =
8491 &clang_ast->Idents.get(property_name);
8492 getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
8493 }
8494 property_decl->setGetterName(getter_sel);
8495 property_decl->setPropertyAttributes(
8496 clang::ObjCPropertyDecl::OBJC_PR_getter);
8497
8498 if (ivar_decl)
8499 property_decl->setPropertyIvarDecl(ivar_decl);
8500
8501 if (property_attributes & DW_APPLE_PROPERTY_readonly)
8502 property_decl->setPropertyAttributes(
8503 clang::ObjCPropertyDecl::OBJC_PR_readonly);
8504 if (property_attributes & DW_APPLE_PROPERTY_readwrite)
8505 property_decl->setPropertyAttributes(
8506 clang::ObjCPropertyDecl::OBJC_PR_readwrite);
8507 if (property_attributes & DW_APPLE_PROPERTY_assign)
8508 property_decl->setPropertyAttributes(
8509 clang::ObjCPropertyDecl::OBJC_PR_assign);
8510 if (property_attributes & DW_APPLE_PROPERTY_retain)
8511 property_decl->setPropertyAttributes(
8512 clang::ObjCPropertyDecl::OBJC_PR_retain);
8513 if (property_attributes & DW_APPLE_PROPERTY_copy)
8514 property_decl->setPropertyAttributes(
8515 clang::ObjCPropertyDecl::OBJC_PR_copy);
8516 if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
8517 property_decl->setPropertyAttributes(
8518 clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
8519 if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_nullability)
8520 property_decl->setPropertyAttributes(
8521 clang::ObjCPropertyDecl::OBJC_PR_nullability);
8522 if (property_attributes &
8523 clang::ObjCPropertyDecl::OBJC_PR_null_resettable)
8524 property_decl->setPropertyAttributes(
8525 clang::ObjCPropertyDecl::OBJC_PR_null_resettable);
8526 if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class)
8527 property_decl->setPropertyAttributes(
8528 clang::ObjCPropertyDecl::OBJC_PR_class);
8529
8530 const bool isInstance =
8531 (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) == 0;
8532
8533 if (!getter_sel.isNull() &&
8534 !(isInstance
8535 ? class_interface_decl->lookupInstanceMethod(getter_sel)
8536 : class_interface_decl->lookupClassMethod(getter_sel))) {
8537 const bool isVariadic = false;
8538 const bool isSynthesized = false;
8539 const bool isImplicitlyDeclared = true;
8540 const bool isDefined = false;
8541 const clang::ObjCMethodDecl::ImplementationControl impControl =
8542 clang::ObjCMethodDecl::None;
8543 const bool HasRelatedResultType = false;
8544
8545 clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create(
8546 *clang_ast, clang::SourceLocation(), clang::SourceLocation(),
8547 getter_sel, ClangUtil::GetQualType(property_clang_type_to_access),
8548 nullptr, class_interface_decl, isInstance, isVariadic,
8549 isSynthesized, isImplicitlyDeclared, isDefined, impControl,
8550 HasRelatedResultType);
8551
8552 if (getter && metadata)
8553 ClangASTContext::SetMetadata(clang_ast, getter, *metadata);
8554
8555 if (getter) {
8556 getter->setMethodParams(*clang_ast,
8557 llvm::ArrayRef<clang::ParmVarDecl *>(),
8558 llvm::ArrayRef<clang::SourceLocation>());
8559
8560 class_interface_decl->addDecl(getter);
8561 }
8562 }
8563
8564 if (!setter_sel.isNull() &&
8565 !(isInstance
8566 ? class_interface_decl->lookupInstanceMethod(setter_sel)
8567 : class_interface_decl->lookupClassMethod(setter_sel))) {
8568 clang::QualType result_type = clang_ast->VoidTy;
8569 const bool isVariadic = false;
8570 const bool isSynthesized = false;
8571 const bool isImplicitlyDeclared = true;
8572 const bool isDefined = false;
8573 const clang::ObjCMethodDecl::ImplementationControl impControl =
8574 clang::ObjCMethodDecl::None;
8575 const bool HasRelatedResultType = false;
8576
8577 clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create(
8578 *clang_ast, clang::SourceLocation(), clang::SourceLocation(),
8579 setter_sel, result_type, nullptr, class_interface_decl,
8580 isInstance, isVariadic, isSynthesized, isImplicitlyDeclared,
8581 isDefined, impControl, HasRelatedResultType);
8582
8583 if (setter && metadata)
8584 ClangASTContext::SetMetadata(clang_ast, setter, *metadata);
8585
8586 llvm::SmallVector<clang::ParmVarDecl *, 1> params;
8587
8588 params.push_back(clang::ParmVarDecl::Create(
8589 *clang_ast, setter, clang::SourceLocation(),
8590 clang::SourceLocation(),
8591 nullptr, // anonymous
8592 ClangUtil::GetQualType(property_clang_type_to_access), nullptr,
8593 clang::SC_Auto, nullptr));
8594
8595 if (setter) {
8596 setter->setMethodParams(
8597 *clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(params),
8598 llvm::ArrayRef<clang::SourceLocation>());
8599
8600 class_interface_decl->addDecl(setter);
8601 }
8602 }
8603
8604 return true;
8605 }
8606 }
8607 }
8608 return false;
8609}
8610
8611bool ClangASTContext::IsObjCClassTypeAndHasIVars(const CompilerType &type,
8612 bool check_superclass) {
8613 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8614 if (class_interface_decl)
8615 return ObjCDeclHasIVars(class_interface_decl, check_superclass);
8616 return false;
8617}
8618
8619clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType(
8620 const CompilerType &type,
8621 const char *name, // the full symbol name as seen in the symbol table
8622 // (lldb::opaque_compiler_type_t type, "-[NString
8623 // stringWithCString:]")
8624 const CompilerType &method_clang_type, lldb::AccessType access,
8625 bool is_artificial, bool is_variadic) {
8626 if (!type || !method_clang_type.IsValid())
Greg Claytond8d4a572015-08-11 21:38:15 +00008627 return nullptr;
Greg Claytond8d4a572015-08-11 21:38:15 +00008628
Kate Stoneb9c1b512016-09-06 20:57:50 +00008629 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8630
8631 if (class_interface_decl == nullptr)
8632 return nullptr;
8633 ClangASTContext *lldb_ast =
8634 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8635 if (lldb_ast == nullptr)
8636 return nullptr;
8637 clang::ASTContext *ast = lldb_ast->getASTContext();
8638
8639 const char *selector_start = ::strchr(name, ' ');
8640 if (selector_start == nullptr)
8641 return nullptr;
8642
8643 selector_start++;
8644 llvm::SmallVector<clang::IdentifierInfo *, 12> selector_idents;
8645
8646 size_t len = 0;
8647 const char *start;
8648 // printf ("name = '%s'\n", name);
8649
8650 unsigned num_selectors_with_args = 0;
8651 for (start = selector_start; start && *start != '\0' && *start != ']';
8652 start += len) {
8653 len = ::strcspn(start, ":]");
8654 bool has_arg = (start[len] == ':');
8655 if (has_arg)
8656 ++num_selectors_with_args;
8657 selector_idents.push_back(&ast->Idents.get(llvm::StringRef(start, len)));
8658 if (has_arg)
8659 len += 1;
8660 }
8661
8662 if (selector_idents.size() == 0)
8663 return nullptr;
8664
8665 clang::Selector method_selector = ast->Selectors.getSelector(
8666 num_selectors_with_args ? selector_idents.size() : 0,
8667 selector_idents.data());
8668
8669 clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
8670
8671 // Populate the method decl with parameter decls
8672 const clang::Type *method_type(method_qual_type.getTypePtr());
8673
8674 if (method_type == nullptr)
8675 return nullptr;
8676
8677 const clang::FunctionProtoType *method_function_prototype(
8678 llvm::dyn_cast<clang::FunctionProtoType>(method_type));
8679
8680 if (!method_function_prototype)
8681 return nullptr;
8682
8683 bool is_synthesized = false;
8684 bool is_defined = false;
8685 clang::ObjCMethodDecl::ImplementationControl imp_control =
8686 clang::ObjCMethodDecl::None;
8687
8688 const unsigned num_args = method_function_prototype->getNumParams();
8689
8690 if (num_args != num_selectors_with_args)
8691 return nullptr; // some debug information is corrupt. We are not going to
8692 // deal with it.
8693
8694 clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create(
8695 *ast,
8696 clang::SourceLocation(), // beginLoc,
8697 clang::SourceLocation(), // endLoc,
8698 method_selector, method_function_prototype->getReturnType(),
8699 nullptr, // TypeSourceInfo *ResultTInfo,
8700 ClangASTContext::GetASTContext(ast)->GetDeclContextForType(
8701 ClangUtil::GetQualType(type)),
8702 name[0] == '-', is_variadic, is_synthesized,
8703 true, // is_implicitly_declared; we force this to true because we don't
8704 // have source locations
8705 is_defined, imp_control, false /*has_related_result_type*/);
8706
8707 if (objc_method_decl == nullptr)
8708 return nullptr;
8709
8710 if (num_args > 0) {
8711 llvm::SmallVector<clang::ParmVarDecl *, 12> params;
8712
8713 for (unsigned param_index = 0; param_index < num_args; ++param_index) {
8714 params.push_back(clang::ParmVarDecl::Create(
8715 *ast, objc_method_decl, clang::SourceLocation(),
8716 clang::SourceLocation(),
8717 nullptr, // anonymous
8718 method_function_prototype->getParamType(param_index), nullptr,
8719 clang::SC_Auto, nullptr));
Greg Claytond8d4a572015-08-11 21:38:15 +00008720 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008721
Kate Stoneb9c1b512016-09-06 20:57:50 +00008722 objc_method_decl->setMethodParams(
8723 *ast, llvm::ArrayRef<clang::ParmVarDecl *>(params),
8724 llvm::ArrayRef<clang::SourceLocation>());
8725 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008726
Kate Stoneb9c1b512016-09-06 20:57:50 +00008727 class_interface_decl->addDecl(objc_method_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008728
Greg Claytond8d4a572015-08-11 21:38:15 +00008729#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00008730 VerifyDecl(objc_method_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008731#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00008732
8733 return objc_method_decl;
Greg Claytond8d4a572015-08-11 21:38:15 +00008734}
8735
Kate Stoneb9c1b512016-09-06 20:57:50 +00008736bool ClangASTContext::GetHasExternalStorage(const CompilerType &type) {
8737 if (ClangUtil::IsClangType(type))
Greg Claytone6b36cd2015-12-08 01:02:08 +00008738 return false;
Greg Claytone6b36cd2015-12-08 01:02:08 +00008739
Kate Stoneb9c1b512016-09-06 20:57:50 +00008740 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
Greg Claytone6b36cd2015-12-08 01:02:08 +00008741
Kate Stoneb9c1b512016-09-06 20:57:50 +00008742 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8743 switch (type_class) {
8744 case clang::Type::Record: {
8745 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
8746 if (cxx_record_decl)
8747 return cxx_record_decl->hasExternalLexicalStorage() ||
8748 cxx_record_decl->hasExternalVisibleStorage();
8749 } break;
Enrico Granata36f51e42015-12-18 22:41:25 +00008750
Kate Stoneb9c1b512016-09-06 20:57:50 +00008751 case clang::Type::Enum: {
8752 clang::EnumDecl *enum_decl =
8753 llvm::cast<clang::EnumType>(qual_type)->getDecl();
8754 if (enum_decl)
8755 return enum_decl->hasExternalLexicalStorage() ||
8756 enum_decl->hasExternalVisibleStorage();
8757 } break;
8758
8759 case clang::Type::ObjCObject:
8760 case clang::Type::ObjCInterface: {
8761 const clang::ObjCObjectType *objc_class_type =
8762 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
8763 assert(objc_class_type);
8764 if (objc_class_type) {
8765 clang::ObjCInterfaceDecl *class_interface_decl =
8766 objc_class_type->getInterface();
8767
8768 if (class_interface_decl)
8769 return class_interface_decl->hasExternalLexicalStorage() ||
8770 class_interface_decl->hasExternalVisibleStorage();
Greg Claytond8d4a572015-08-11 21:38:15 +00008771 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008772 } break;
8773
8774 case clang::Type::Typedef:
8775 return GetHasExternalStorage(CompilerType(
8776 type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)
8777 ->getDecl()
8778 ->getUnderlyingType()
8779 .getAsOpaquePtr()));
8780
8781 case clang::Type::Auto:
8782 return GetHasExternalStorage(CompilerType(
8783 type.GetTypeSystem(), llvm::cast<clang::AutoType>(qual_type)
8784 ->getDeducedType()
8785 .getAsOpaquePtr()));
8786
8787 case clang::Type::Elaborated:
8788 return GetHasExternalStorage(CompilerType(
8789 type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)
8790 ->getNamedType()
8791 .getAsOpaquePtr()));
8792
8793 case clang::Type::Paren:
8794 return GetHasExternalStorage(CompilerType(
8795 type.GetTypeSystem(),
8796 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
8797
8798 default:
8799 break;
8800 }
8801 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00008802}
8803
Kate Stoneb9c1b512016-09-06 20:57:50 +00008804bool ClangASTContext::SetHasExternalStorage(lldb::opaque_compiler_type_t type,
8805 bool has_extern) {
8806 if (!type)
8807 return false;
8808
8809 clang::QualType qual_type(GetCanonicalQualType(type));
8810
8811 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8812 switch (type_class) {
8813 case clang::Type::Record: {
8814 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
8815 if (cxx_record_decl) {
8816 cxx_record_decl->setHasExternalLexicalStorage(has_extern);
8817 cxx_record_decl->setHasExternalVisibleStorage(has_extern);
8818 return true;
8819 }
8820 } break;
8821
8822 case clang::Type::Enum: {
8823 clang::EnumDecl *enum_decl =
8824 llvm::cast<clang::EnumType>(qual_type)->getDecl();
8825 if (enum_decl) {
8826 enum_decl->setHasExternalLexicalStorage(has_extern);
8827 enum_decl->setHasExternalVisibleStorage(has_extern);
8828 return true;
8829 }
8830 } break;
8831
8832 case clang::Type::ObjCObject:
8833 case clang::Type::ObjCInterface: {
8834 const clang::ObjCObjectType *objc_class_type =
8835 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
8836 assert(objc_class_type);
8837 if (objc_class_type) {
8838 clang::ObjCInterfaceDecl *class_interface_decl =
8839 objc_class_type->getInterface();
8840
8841 if (class_interface_decl) {
8842 class_interface_decl->setHasExternalLexicalStorage(has_extern);
8843 class_interface_decl->setHasExternalVisibleStorage(has_extern);
8844 return true;
8845 }
8846 }
8847 } break;
8848
8849 case clang::Type::Typedef:
8850 return SetHasExternalStorage(llvm::cast<clang::TypedefType>(qual_type)
8851 ->getDecl()
8852 ->getUnderlyingType()
8853 .getAsOpaquePtr(),
8854 has_extern);
8855
8856 case clang::Type::Auto:
8857 return SetHasExternalStorage(llvm::cast<clang::AutoType>(qual_type)
8858 ->getDeducedType()
8859 .getAsOpaquePtr(),
8860 has_extern);
8861
8862 case clang::Type::Elaborated:
8863 return SetHasExternalStorage(llvm::cast<clang::ElaboratedType>(qual_type)
8864 ->getNamedType()
8865 .getAsOpaquePtr(),
8866 has_extern);
8867
8868 case clang::Type::Paren:
8869 return SetHasExternalStorage(
8870 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
8871 has_extern);
8872
8873 default:
8874 break;
8875 }
8876 return false;
8877}
Greg Claytond8d4a572015-08-11 21:38:15 +00008878
8879#pragma mark TagDecl
8880
Kate Stoneb9c1b512016-09-06 20:57:50 +00008881bool ClangASTContext::StartTagDeclarationDefinition(const CompilerType &type) {
8882 clang::QualType qual_type(ClangUtil::GetQualType(type));
8883 if (!qual_type.isNull()) {
8884 const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
8885 if (tag_type) {
8886 clang::TagDecl *tag_decl = tag_type->getDecl();
8887 if (tag_decl) {
8888 tag_decl->startDefinition();
8889 return true;
8890 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008891 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008892
8893 const clang::ObjCObjectType *object_type =
8894 qual_type->getAs<clang::ObjCObjectType>();
8895 if (object_type) {
8896 clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
8897 if (interface_decl) {
8898 interface_decl->startDefinition();
8899 return true;
8900 }
8901 }
8902 }
8903 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00008904}
8905
Kate Stoneb9c1b512016-09-06 20:57:50 +00008906bool ClangASTContext::CompleteTagDeclarationDefinition(
8907 const CompilerType &type) {
8908 clang::QualType qual_type(ClangUtil::GetQualType(type));
8909 if (!qual_type.isNull()) {
8910 // Make sure we use the same methodology as
Adrian Prantl05097242018-04-30 16:49:04 +00008911 // ClangASTContext::StartTagDeclarationDefinition() as to how we start/end
8912 // the definition. Previously we were calling
Kate Stoneb9c1b512016-09-06 20:57:50 +00008913 const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
8914 if (tag_type) {
8915 clang::TagDecl *tag_decl = tag_type->getDecl();
8916 if (tag_decl) {
8917 clang::CXXRecordDecl *cxx_record_decl =
8918 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(tag_decl);
8919
8920 if (cxx_record_decl) {
8921 if (!cxx_record_decl->isCompleteDefinition())
8922 cxx_record_decl->completeDefinition();
8923 cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
8924 cxx_record_decl->setHasExternalLexicalStorage(false);
8925 cxx_record_decl->setHasExternalVisibleStorage(false);
8926 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00008927 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008928 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008929 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008930
8931 const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>();
8932
8933 if (enutype) {
8934 clang::EnumDecl *enum_decl = enutype->getDecl();
8935
8936 if (enum_decl) {
8937 if (!enum_decl->isCompleteDefinition()) {
8938 ClangASTContext *lldb_ast =
8939 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8940 if (lldb_ast == nullptr)
8941 return false;
8942 clang::ASTContext *ast = lldb_ast->getASTContext();
8943
8944 /// TODO This really needs to be fixed.
8945
8946 QualType integer_type(enum_decl->getIntegerType());
8947 if (!integer_type.isNull()) {
8948 unsigned NumPositiveBits = 1;
8949 unsigned NumNegativeBits = 0;
8950
8951 clang::QualType promotion_qual_type;
8952 // If the enum integer type is less than an integer in bit width,
8953 // then we must promote it to an integer size.
8954 if (ast->getTypeSize(enum_decl->getIntegerType()) <
8955 ast->getTypeSize(ast->IntTy)) {
8956 if (enum_decl->getIntegerType()->isSignedIntegerType())
8957 promotion_qual_type = ast->IntTy;
8958 else
8959 promotion_qual_type = ast->UnsignedIntTy;
8960 } else
8961 promotion_qual_type = enum_decl->getIntegerType();
8962
8963 enum_decl->completeDefinition(enum_decl->getIntegerType(),
8964 promotion_qual_type, NumPositiveBits,
8965 NumNegativeBits);
8966 }
8967 }
8968 return true;
8969 }
8970 }
8971 }
8972 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00008973}
8974
Aleksandr Urakov709426b2018-09-10 08:08:43 +00008975clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType(
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008976 const CompilerType &enum_type, const Declaration &decl, const char *name,
Zachary Turner1639c6b2018-12-17 16:15:13 +00008977 const llvm::APSInt &value) {
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008978
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008979 if (!enum_type || ConstString(name).IsEmpty())
8980 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00008981
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008982 lldbassert(enum_type.GetTypeSystem() == static_cast<TypeSystem *>(this));
Kate Stoneb9c1b512016-09-06 20:57:50 +00008983
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008984 lldb::opaque_compiler_type_t enum_opaque_compiler_type =
8985 enum_type.GetOpaqueQualType();
8986
8987 if (!enum_opaque_compiler_type)
8988 return nullptr;
8989
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008990 clang::QualType enum_qual_type(
8991 GetCanonicalQualType(enum_opaque_compiler_type));
8992
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008993 const clang::Type *clang_type = enum_qual_type.getTypePtr();
8994
8995 if (!clang_type)
8996 return nullptr;
8997
8998 const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(clang_type);
8999
9000 if (!enutype)
9001 return nullptr;
9002
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00009003 clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create(
9004 *getASTContext(), enutype->getDecl(), clang::SourceLocation(),
9005 name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier
Zachary Turner1639c6b2018-12-17 16:15:13 +00009006 clang::QualType(enutype, 0), nullptr, value);
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00009007
9008 if (!enumerator_decl)
9009 return nullptr;
9010
9011 enutype->getDecl()->addDecl(enumerator_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009012
9013#ifdef LLDB_CONFIGURATION_DEBUG
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00009014 VerifyDecl(enumerator_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009015#endif
9016
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00009017 return enumerator_decl;
Greg Claytond8d4a572015-08-11 21:38:15 +00009018}
9019
Zachary Turner1639c6b2018-12-17 16:15:13 +00009020clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType(
9021 const CompilerType &enum_type, const Declaration &decl, const char *name,
9022 int64_t enum_value, uint32_t enum_value_bit_size) {
9023 CompilerType underlying_type =
9024 GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
9025 bool is_signed = false;
9026 underlying_type.IsIntegerType(is_signed);
9027
9028 llvm::APSInt value(enum_value_bit_size, is_signed);
9029 value = enum_value;
9030
9031 return AddEnumerationValueToEnumerationType(enum_type, decl, name, value);
9032}
9033
Greg Claytona1e5dc82015-08-11 22:53:00 +00009034CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00009035ClangASTContext::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) {
9036 clang::QualType enum_qual_type(GetCanonicalQualType(type));
9037 const clang::Type *clang_type = enum_qual_type.getTypePtr();
9038 if (clang_type) {
9039 const clang::EnumType *enutype =
9040 llvm::dyn_cast<clang::EnumType>(clang_type);
9041 if (enutype) {
9042 clang::EnumDecl *enum_decl = enutype->getDecl();
9043 if (enum_decl)
9044 return CompilerType(getASTContext(), enum_decl->getIntegerType());
Greg Claytond8d4a572015-08-11 21:38:15 +00009045 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009046 }
9047 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00009048}
9049
Kate Stoneb9c1b512016-09-06 20:57:50 +00009050CompilerType
9051ClangASTContext::CreateMemberPointerType(const CompilerType &type,
9052 const CompilerType &pointee_type) {
9053 if (type && pointee_type.IsValid() &&
9054 type.GetTypeSystem() == pointee_type.GetTypeSystem()) {
9055 ClangASTContext *ast =
9056 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
9057 if (!ast)
9058 return CompilerType();
9059 return CompilerType(ast->getASTContext(),
9060 ast->getASTContext()->getMemberPointerType(
9061 ClangUtil::GetQualType(pointee_type),
9062 ClangUtil::GetQualType(type).getTypePtr()));
9063 }
9064 return CompilerType();
9065}
Greg Claytond8d4a572015-08-11 21:38:15 +00009066
Greg Claytond8d4a572015-08-11 21:38:15 +00009067// Dumping types
Greg Claytond8d4a572015-08-11 21:38:15 +00009068#define DEPTH_INCREMENT 2
9069
Adrian Prantl0c72a422019-03-07 20:20:02 +00009070#ifndef NDEBUG
9071LLVM_DUMP_METHOD void
9072ClangASTContext::dump(lldb::opaque_compiler_type_t type) const {
9073 if (!type)
9074 return;
9075 clang::QualType qual_type(GetQualType(type));
9076 qual_type.dump();
9077}
9078#endif
9079
Zachary Turner49110232018-11-05 17:40:28 +00009080void ClangASTContext::Dump(Stream &s) {
Zachary Turner115209e2018-11-05 19:25:39 +00009081 Decl *tu = Decl::castFromDeclContext(GetTranslationUnitDecl());
Zachary Turner49110232018-11-05 17:40:28 +00009082 tu->dump(s.AsRawOstream());
9083}
9084
Kate Stoneb9c1b512016-09-06 20:57:50 +00009085void ClangASTContext::DumpValue(
9086 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
Zachary Turner29cb8682017-03-03 20:57:05 +00009087 lldb::Format format, const DataExtractor &data,
Kate Stoneb9c1b512016-09-06 20:57:50 +00009088 lldb::offset_t data_byte_offset, size_t data_byte_size,
9089 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types,
9090 bool show_summary, bool verbose, uint32_t depth) {
9091 if (!type)
9092 return;
9093
9094 clang::QualType qual_type(GetQualType(type));
9095 switch (qual_type->getTypeClass()) {
9096 case clang::Type::Record:
9097 if (GetCompleteType(type)) {
9098 const clang::RecordType *record_type =
9099 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
9100 const clang::RecordDecl *record_decl = record_type->getDecl();
9101 assert(record_decl);
9102 uint32_t field_bit_offset = 0;
9103 uint32_t field_byte_offset = 0;
9104 const clang::ASTRecordLayout &record_layout =
9105 getASTContext()->getASTRecordLayout(record_decl);
9106 uint32_t child_idx = 0;
9107
9108 const clang::CXXRecordDecl *cxx_record_decl =
9109 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
9110 if (cxx_record_decl) {
9111 // We might have base classes to print out first
9112 clang::CXXRecordDecl::base_class_const_iterator base_class,
9113 base_class_end;
9114 for (base_class = cxx_record_decl->bases_begin(),
9115 base_class_end = cxx_record_decl->bases_end();
9116 base_class != base_class_end; ++base_class) {
9117 const clang::CXXRecordDecl *base_class_decl =
9118 llvm::cast<clang::CXXRecordDecl>(
9119 base_class->getType()->getAs<clang::RecordType>()->getDecl());
9120
9121 // Skip empty base classes
Jonas Devliegherea6682a42018-12-15 00:15:33 +00009122 if (!verbose && !ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00009123 continue;
9124
9125 if (base_class->isVirtual())
9126 field_bit_offset =
9127 record_layout.getVBaseClassOffset(base_class_decl)
9128 .getQuantity() *
9129 8;
9130 else
9131 field_bit_offset = record_layout.getBaseClassOffset(base_class_decl)
9132 .getQuantity() *
9133 8;
9134 field_byte_offset = field_bit_offset / 8;
9135 assert(field_bit_offset % 8 == 0);
9136 if (child_idx == 0)
9137 s->PutChar('{');
9138 else
9139 s->PutChar(',');
9140
9141 clang::QualType base_class_qual_type = base_class->getType();
9142 std::string base_class_type_name(base_class_qual_type.getAsString());
9143
9144 // Indent and print the base class type name
Zachary Turner827d5d72016-12-16 04:27:00 +00009145 s->Format("\n{0}{1}", llvm::fmt_repeat(" ", depth + DEPTH_INCREMENT),
9146 base_class_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009147
9148 clang::TypeInfo base_class_type_info =
9149 getASTContext()->getTypeInfo(base_class_qual_type);
9150
9151 // Dump the value of the member
9152 CompilerType base_clang_type(getASTContext(), base_class_qual_type);
9153 base_clang_type.DumpValue(
9154 exe_ctx,
9155 s, // Stream to dump to
9156 base_clang_type
9157 .GetFormat(), // The format with which to display the member
9158 data, // Data buffer containing all bytes for this type
9159 data_byte_offset + field_byte_offset, // Offset into "data" where
9160 // to grab value from
9161 base_class_type_info.Width / 8, // Size of this type in bytes
9162 0, // Bitfield bit size
9163 0, // Bitfield bit offset
9164 show_types, // Boolean indicating if we should show the variable
9165 // types
9166 show_summary, // Boolean indicating if we should show a summary
9167 // for the current type
9168 verbose, // Verbose output?
9169 depth + DEPTH_INCREMENT); // Scope depth for any types that have
9170 // children
9171
9172 ++child_idx;
9173 }
9174 }
9175 uint32_t field_idx = 0;
9176 clang::RecordDecl::field_iterator field, field_end;
9177 for (field = record_decl->field_begin(),
9178 field_end = record_decl->field_end();
9179 field != field_end; ++field, ++field_idx, ++child_idx) {
Adrian Prantl05097242018-04-30 16:49:04 +00009180 // Print the starting squiggly bracket (if this is the first member) or
9181 // comma (for member 2 and beyond) for the struct/union/class member.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009182 if (child_idx == 0)
9183 s->PutChar('{');
9184 else
9185 s->PutChar(',');
9186
9187 // Indent
9188 s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
9189
9190 clang::QualType field_type = field->getType();
9191 // Print the member type if requested
Adrian Prantl05097242018-04-30 16:49:04 +00009192 // Figure out the type byte size (field_type_info.first) and alignment
9193 // (field_type_info.second) from the AST context.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009194 clang::TypeInfo field_type_info =
9195 getASTContext()->getTypeInfo(field_type);
9196 assert(field_idx < record_layout.getFieldCount());
9197 // Figure out the field offset within the current struct/union/class
9198 // type
9199 field_bit_offset = record_layout.getFieldOffset(field_idx);
9200 field_byte_offset = field_bit_offset / 8;
9201 uint32_t field_bitfield_bit_size = 0;
9202 uint32_t field_bitfield_bit_offset = 0;
9203 if (ClangASTContext::FieldIsBitfield(getASTContext(), *field,
9204 field_bitfield_bit_size))
9205 field_bitfield_bit_offset = field_bit_offset % 8;
9206
9207 if (show_types) {
9208 std::string field_type_name(field_type.getAsString());
9209 if (field_bitfield_bit_size > 0)
9210 s->Printf("(%s:%u) ", field_type_name.c_str(),
9211 field_bitfield_bit_size);
9212 else
9213 s->Printf("(%s) ", field_type_name.c_str());
9214 }
9215 // Print the member name and equal sign
9216 s->Printf("%s = ", field->getNameAsString().c_str());
9217
9218 // Dump the value of the member
9219 CompilerType field_clang_type(getASTContext(), field_type);
9220 field_clang_type.DumpValue(
9221 exe_ctx,
9222 s, // Stream to dump to
9223 field_clang_type
9224 .GetFormat(), // The format with which to display the member
9225 data, // Data buffer containing all bytes for this type
9226 data_byte_offset + field_byte_offset, // Offset into "data" where to
9227 // grab value from
9228 field_type_info.Width / 8, // Size of this type in bytes
9229 field_bitfield_bit_size, // Bitfield bit size
9230 field_bitfield_bit_offset, // Bitfield bit offset
9231 show_types, // Boolean indicating if we should show the variable
9232 // types
9233 show_summary, // Boolean indicating if we should show a summary for
9234 // the current type
9235 verbose, // Verbose output?
9236 depth + DEPTH_INCREMENT); // Scope depth for any types that have
9237 // children
9238 }
9239
9240 // Indent the trailing squiggly bracket
9241 if (child_idx > 0)
9242 s->Printf("\n%*s}", depth, "");
9243 }
9244 return;
9245
9246 case clang::Type::Enum:
9247 if (GetCompleteType(type)) {
9248 const clang::EnumType *enutype =
9249 llvm::cast<clang::EnumType>(qual_type.getTypePtr());
9250 const clang::EnumDecl *enum_decl = enutype->getDecl();
9251 assert(enum_decl);
9252 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
9253 lldb::offset_t offset = data_byte_offset;
9254 const int64_t enum_value = data.GetMaxU64Bitfield(
9255 &offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
9256 for (enum_pos = enum_decl->enumerator_begin(),
9257 enum_end_pos = enum_decl->enumerator_end();
9258 enum_pos != enum_end_pos; ++enum_pos) {
9259 if (enum_pos->getInitVal() == enum_value) {
9260 s->Printf("%s", enum_pos->getNameAsString().c_str());
9261 return;
9262 }
9263 }
Adrian Prantl05097242018-04-30 16:49:04 +00009264 // If we have gotten here we didn't get find the enumerator in the enum
9265 // decl, so just print the integer.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009266 s->Printf("%" PRIi64, enum_value);
9267 }
9268 return;
9269
9270 case clang::Type::ConstantArray: {
9271 const clang::ConstantArrayType *array =
9272 llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
9273 bool is_array_of_characters = false;
9274 clang::QualType element_qual_type = array->getElementType();
9275
9276 const clang::Type *canonical_type =
9277 element_qual_type->getCanonicalTypeInternal().getTypePtr();
9278 if (canonical_type)
9279 is_array_of_characters = canonical_type->isCharType();
9280
9281 const uint64_t element_count = array->getSize().getLimitedValue();
9282
9283 clang::TypeInfo field_type_info =
9284 getASTContext()->getTypeInfo(element_qual_type);
9285
9286 uint32_t element_idx = 0;
9287 uint32_t element_offset = 0;
9288 uint64_t element_byte_size = field_type_info.Width / 8;
9289 uint32_t element_stride = element_byte_size;
9290
9291 if (is_array_of_characters) {
9292 s->PutChar('"');
Zachary Turner29cb8682017-03-03 20:57:05 +00009293 DumpDataExtractor(data, s, data_byte_offset, lldb::eFormatChar,
9294 element_byte_size, element_count, UINT32_MAX,
9295 LLDB_INVALID_ADDRESS, 0, 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009296 s->PutChar('"');
9297 return;
9298 } else {
9299 CompilerType element_clang_type(getASTContext(), element_qual_type);
9300 lldb::Format element_format = element_clang_type.GetFormat();
9301
9302 for (element_idx = 0; element_idx < element_count; ++element_idx) {
Adrian Prantl05097242018-04-30 16:49:04 +00009303 // Print the starting squiggly bracket (if this is the first member) or
9304 // comman (for member 2 and beyong) for the struct/union/class member.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009305 if (element_idx == 0)
9306 s->PutChar('{');
9307 else
9308 s->PutChar(',');
9309
9310 // Indent and print the index
9311 s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
9312
9313 // Figure out the field offset within the current struct/union/class
9314 // type
9315 element_offset = element_idx * element_stride;
9316
9317 // Dump the value of the member
9318 element_clang_type.DumpValue(
9319 exe_ctx,
9320 s, // Stream to dump to
9321 element_format, // The format with which to display the element
9322 data, // Data buffer containing all bytes for this type
9323 data_byte_offset +
9324 element_offset, // Offset into "data" where to grab value from
9325 element_byte_size, // Size of this type in bytes
9326 0, // Bitfield bit size
9327 0, // Bitfield bit offset
9328 show_types, // Boolean indicating if we should show the variable
9329 // types
9330 show_summary, // Boolean indicating if we should show a summary for
9331 // the current type
9332 verbose, // Verbose output?
9333 depth + DEPTH_INCREMENT); // Scope depth for any types that have
9334 // children
9335 }
9336
9337 // Indent the trailing squiggly bracket
9338 if (element_idx > 0)
9339 s->Printf("\n%*s}", depth, "");
9340 }
9341 }
9342 return;
9343
9344 case clang::Type::Typedef: {
9345 clang::QualType typedef_qual_type =
9346 llvm::cast<clang::TypedefType>(qual_type)
9347 ->getDecl()
9348 ->getUnderlyingType();
9349
9350 CompilerType typedef_clang_type(getASTContext(), typedef_qual_type);
9351 lldb::Format typedef_format = typedef_clang_type.GetFormat();
9352 clang::TypeInfo typedef_type_info =
9353 getASTContext()->getTypeInfo(typedef_qual_type);
9354 uint64_t typedef_byte_size = typedef_type_info.Width / 8;
9355
9356 return typedef_clang_type.DumpValue(
9357 exe_ctx,
9358 s, // Stream to dump to
9359 typedef_format, // The format with which to display the element
9360 data, // Data buffer containing all bytes for this type
9361 data_byte_offset, // Offset into "data" where to grab value from
9362 typedef_byte_size, // Size of this type in bytes
9363 bitfield_bit_size, // Bitfield bit size
9364 bitfield_bit_offset, // Bitfield bit offset
9365 show_types, // Boolean indicating if we should show the variable types
9366 show_summary, // Boolean indicating if we should show a summary for the
9367 // current type
9368 verbose, // Verbose output?
9369 depth); // Scope depth for any types that have children
9370 } break;
9371
9372 case clang::Type::Auto: {
9373 clang::QualType elaborated_qual_type =
9374 llvm::cast<clang::AutoType>(qual_type)->getDeducedType();
9375 CompilerType elaborated_clang_type(getASTContext(), elaborated_qual_type);
9376 lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
9377 clang::TypeInfo elaborated_type_info =
9378 getASTContext()->getTypeInfo(elaborated_qual_type);
9379 uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
9380
9381 return elaborated_clang_type.DumpValue(
9382 exe_ctx,
9383 s, // Stream to dump to
9384 elaborated_format, // The format with which to display the element
9385 data, // Data buffer containing all bytes for this type
9386 data_byte_offset, // Offset into "data" where to grab value from
9387 elaborated_byte_size, // Size of this type in bytes
9388 bitfield_bit_size, // Bitfield bit size
9389 bitfield_bit_offset, // Bitfield bit offset
9390 show_types, // Boolean indicating if we should show the variable types
9391 show_summary, // Boolean indicating if we should show a summary for the
9392 // current type
9393 verbose, // Verbose output?
9394 depth); // Scope depth for any types that have children
9395 } break;
9396
9397 case clang::Type::Elaborated: {
9398 clang::QualType elaborated_qual_type =
9399 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
9400 CompilerType elaborated_clang_type(getASTContext(), elaborated_qual_type);
9401 lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
9402 clang::TypeInfo elaborated_type_info =
9403 getASTContext()->getTypeInfo(elaborated_qual_type);
9404 uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
9405
9406 return elaborated_clang_type.DumpValue(
9407 exe_ctx,
9408 s, // Stream to dump to
9409 elaborated_format, // The format with which to display the element
9410 data, // Data buffer containing all bytes for this type
9411 data_byte_offset, // Offset into "data" where to grab value from
9412 elaborated_byte_size, // Size of this type in bytes
9413 bitfield_bit_size, // Bitfield bit size
9414 bitfield_bit_offset, // Bitfield bit offset
9415 show_types, // Boolean indicating if we should show the variable types
9416 show_summary, // Boolean indicating if we should show a summary for the
9417 // current type
9418 verbose, // Verbose output?
9419 depth); // Scope depth for any types that have children
9420 } break;
9421
9422 case clang::Type::Paren: {
9423 clang::QualType desugar_qual_type =
9424 llvm::cast<clang::ParenType>(qual_type)->desugar();
9425 CompilerType desugar_clang_type(getASTContext(), desugar_qual_type);
9426
9427 lldb::Format desugar_format = desugar_clang_type.GetFormat();
9428 clang::TypeInfo desugar_type_info =
9429 getASTContext()->getTypeInfo(desugar_qual_type);
9430 uint64_t desugar_byte_size = desugar_type_info.Width / 8;
9431
9432 return desugar_clang_type.DumpValue(
9433 exe_ctx,
9434 s, // Stream to dump to
9435 desugar_format, // The format with which to display the element
9436 data, // Data buffer containing all bytes for this type
9437 data_byte_offset, // Offset into "data" where to grab value from
9438 desugar_byte_size, // Size of this type in bytes
9439 bitfield_bit_size, // Bitfield bit size
9440 bitfield_bit_offset, // Bitfield bit offset
9441 show_types, // Boolean indicating if we should show the variable types
9442 show_summary, // Boolean indicating if we should show a summary for the
9443 // current type
9444 verbose, // Verbose output?
9445 depth); // Scope depth for any types that have children
9446 } break;
9447
9448 default:
9449 // We are down to a scalar type that we just need to display.
Zachary Turner29cb8682017-03-03 20:57:05 +00009450 DumpDataExtractor(data, s, data_byte_offset, format, data_byte_size, 1,
9451 UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
9452 bitfield_bit_offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009453
9454 if (show_summary)
9455 DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
9456 break;
9457 }
9458}
9459
9460bool ClangASTContext::DumpTypeValue(
9461 lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
Zachary Turner29cb8682017-03-03 20:57:05 +00009462 const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size,
9463 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
Kate Stoneb9c1b512016-09-06 20:57:50 +00009464 ExecutionContextScope *exe_scope) {
9465 if (!type)
9466 return false;
9467 if (IsAggregateType(type)) {
9468 return false;
9469 } else {
Greg Claytond8d4a572015-08-11 21:38:15 +00009470 clang::QualType qual_type(GetQualType(type));
Kate Stoneb9c1b512016-09-06 20:57:50 +00009471
9472 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
9473 switch (type_class) {
9474 case clang::Type::Typedef: {
9475 clang::QualType typedef_qual_type =
9476 llvm::cast<clang::TypedefType>(qual_type)
9477 ->getDecl()
9478 ->getUnderlyingType();
9479 CompilerType typedef_clang_type(getASTContext(), typedef_qual_type);
9480 if (format == eFormatDefault)
9481 format = typedef_clang_type.GetFormat();
9482 clang::TypeInfo typedef_type_info =
9483 getASTContext()->getTypeInfo(typedef_qual_type);
9484 uint64_t typedef_byte_size = typedef_type_info.Width / 8;
9485
9486 return typedef_clang_type.DumpTypeValue(
9487 s,
9488 format, // The format with which to display the element
9489 data, // Data buffer containing all bytes for this type
9490 byte_offset, // Offset into "data" where to grab value from
9491 typedef_byte_size, // Size of this type in bytes
9492 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't
9493 // treat as a bitfield
9494 bitfield_bit_offset, // Offset in bits of a bitfield value if
9495 // bitfield_bit_size != 0
9496 exe_scope);
9497 } break;
9498
9499 case clang::Type::Enum:
Adrian Prantl05097242018-04-30 16:49:04 +00009500 // If our format is enum or default, show the enumeration value as its
9501 // enumeration string value, else just display it as requested.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009502 if ((format == eFormatEnum || format == eFormatDefault) &&
9503 GetCompleteType(type)) {
9504 const clang::EnumType *enutype =
9505 llvm::cast<clang::EnumType>(qual_type.getTypePtr());
9506 const clang::EnumDecl *enum_decl = enutype->getDecl();
9507 assert(enum_decl);
9508 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
9509 const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
9510 lldb::offset_t offset = byte_offset;
9511 if (is_signed) {
9512 const int64_t enum_svalue = data.GetMaxS64Bitfield(
9513 &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
9514 for (enum_pos = enum_decl->enumerator_begin(),
9515 enum_end_pos = enum_decl->enumerator_end();
9516 enum_pos != enum_end_pos; ++enum_pos) {
9517 if (enum_pos->getInitVal().getSExtValue() == enum_svalue) {
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009518 s->PutCString(enum_pos->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009519 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00009520 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009521 }
9522 // If we have gotten here we didn't get find the enumerator in the
9523 // enum decl, so just print the integer.
9524 s->Printf("%" PRIi64, enum_svalue);
9525 } else {
9526 const uint64_t enum_uvalue = data.GetMaxU64Bitfield(
9527 &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
9528 for (enum_pos = enum_decl->enumerator_begin(),
9529 enum_end_pos = enum_decl->enumerator_end();
9530 enum_pos != enum_end_pos; ++enum_pos) {
9531 if (enum_pos->getInitVal().getZExtValue() == enum_uvalue) {
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009532 s->PutCString(enum_pos->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009533 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00009534 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009535 }
9536 // If we have gotten here we didn't get find the enumerator in the
9537 // enum decl, so just print the integer.
9538 s->Printf("%" PRIu64, enum_uvalue);
Greg Claytond8d4a572015-08-11 21:38:15 +00009539 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009540 return true;
9541 }
9542 // format was not enum, just fall through and dump the value as
9543 // requested....
9544 LLVM_FALLTHROUGH;
9545
9546 default:
9547 // We are down to a scalar type that we just need to display.
9548 {
9549 uint32_t item_count = 1;
9550 // A few formats, we might need to modify our size and count for
9551 // depending
9552 // on how we are trying to display the value...
9553 switch (format) {
Greg Claytond8d4a572015-08-11 21:38:15 +00009554 default:
Kate Stoneb9c1b512016-09-06 20:57:50 +00009555 case eFormatBoolean:
9556 case eFormatBinary:
9557 case eFormatComplex:
9558 case eFormatCString: // NULL terminated C strings
9559 case eFormatDecimal:
9560 case eFormatEnum:
9561 case eFormatHex:
9562 case eFormatHexUppercase:
9563 case eFormatFloat:
9564 case eFormatOctal:
9565 case eFormatOSType:
9566 case eFormatUnsigned:
9567 case eFormatPointer:
9568 case eFormatVectorOfChar:
9569 case eFormatVectorOfSInt8:
9570 case eFormatVectorOfUInt8:
9571 case eFormatVectorOfSInt16:
9572 case eFormatVectorOfUInt16:
9573 case eFormatVectorOfSInt32:
9574 case eFormatVectorOfUInt32:
9575 case eFormatVectorOfSInt64:
9576 case eFormatVectorOfUInt64:
9577 case eFormatVectorOfFloat32:
9578 case eFormatVectorOfFloat64:
9579 case eFormatVectorOfUInt128:
9580 break;
9581
9582 case eFormatChar:
9583 case eFormatCharPrintable:
9584 case eFormatCharArray:
9585 case eFormatBytes:
9586 case eFormatBytesWithASCII:
9587 item_count = byte_size;
9588 byte_size = 1;
9589 break;
9590
9591 case eFormatUnicode16:
9592 item_count = byte_size / 2;
9593 byte_size = 2;
9594 break;
9595
9596 case eFormatUnicode32:
9597 item_count = byte_size / 4;
9598 byte_size = 4;
9599 break;
9600 }
Zachary Turner29cb8682017-03-03 20:57:05 +00009601 return DumpDataExtractor(data, s, byte_offset, format, byte_size,
9602 item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
9603 bitfield_bit_size, bitfield_bit_offset,
9604 exe_scope);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009605 }
9606 break;
9607 }
9608 }
Jonas Devlieghere09ad8c82019-05-24 00:44:33 +00009609 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00009610}
9611
9612void ClangASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
9613 ExecutionContext *exe_ctx, Stream *s,
9614 const lldb_private::DataExtractor &data,
9615 lldb::offset_t data_byte_offset,
9616 size_t data_byte_size) {
9617 uint32_t length = 0;
9618 if (IsCStringType(type, length)) {
9619 if (exe_ctx) {
9620 Process *process = exe_ctx->GetProcessPtr();
9621 if (process) {
9622 lldb::offset_t offset = data_byte_offset;
9623 lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size);
9624 std::vector<uint8_t> buf;
9625 if (length > 0)
9626 buf.resize(length);
9627 else
9628 buf.resize(256);
9629
Zachary Turner29cb8682017-03-03 20:57:05 +00009630 DataExtractor cstr_data(&buf.front(), buf.size(),
9631 process->GetByteOrder(), 4);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009632 buf.back() = '\0';
9633 size_t bytes_read;
9634 size_t total_cstr_len = 0;
Zachary Turner97206d52017-05-12 04:51:55 +00009635 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00009636 while ((bytes_read = process->ReadMemory(pointer_address, &buf.front(),
9637 buf.size(), error)) > 0) {
9638 const size_t len = strlen((const char *)&buf.front());
9639 if (len == 0)
Greg Claytond8d4a572015-08-11 21:38:15 +00009640 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00009641 if (total_cstr_len == 0)
9642 s->PutCString(" \"");
Zachary Turner29cb8682017-03-03 20:57:05 +00009643 DumpDataExtractor(cstr_data, s, 0, lldb::eFormatChar, 1, len,
9644 UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009645 total_cstr_len += len;
9646 if (len < buf.size())
9647 break;
9648 pointer_address += total_cstr_len;
Greg Claytond8d4a572015-08-11 21:38:15 +00009649 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009650 if (total_cstr_len > 0)
9651 s->PutChar('"');
9652 }
Greg Claytond8d4a572015-08-11 21:38:15 +00009653 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009654 }
Greg Claytond8d4a572015-08-11 21:38:15 +00009655}
9656
Kate Stoneb9c1b512016-09-06 20:57:50 +00009657void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) {
9658 StreamFile s(stdout, false);
9659 DumpTypeDescription(type, &s);
9660 ClangASTMetadata *metadata =
9661 ClangASTContext::GetMetadata(getASTContext(), type);
9662 if (metadata) {
9663 metadata->Dump(&s);
9664 }
9665}
Greg Claytond8d4a572015-08-11 21:38:15 +00009666
Kate Stoneb9c1b512016-09-06 20:57:50 +00009667void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
9668 Stream *s) {
9669 if (type) {
9670 clang::QualType qual_type(GetQualType(type));
Greg Claytond8d4a572015-08-11 21:38:15 +00009671
Kate Stoneb9c1b512016-09-06 20:57:50 +00009672 llvm::SmallVector<char, 1024> buf;
9673 llvm::raw_svector_ostream llvm_ostrm(buf);
9674
9675 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
9676 switch (type_class) {
9677 case clang::Type::ObjCObject:
9678 case clang::Type::ObjCInterface: {
9679 GetCompleteType(type);
9680
9681 const clang::ObjCObjectType *objc_class_type =
9682 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
9683 assert(objc_class_type);
9684 if (objc_class_type) {
9685 clang::ObjCInterfaceDecl *class_interface_decl =
9686 objc_class_type->getInterface();
9687 if (class_interface_decl) {
9688 clang::PrintingPolicy policy = getASTContext()->getPrintingPolicy();
9689 class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
Greg Claytond8d4a572015-08-11 21:38:15 +00009690 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009691 }
9692 } break;
Greg Claytond8d4a572015-08-11 21:38:15 +00009693
Kate Stoneb9c1b512016-09-06 20:57:50 +00009694 case clang::Type::Typedef: {
9695 const clang::TypedefType *typedef_type =
9696 qual_type->getAs<clang::TypedefType>();
9697 if (typedef_type) {
9698 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
9699 std::string clang_typedef_name(
9700 typedef_decl->getQualifiedNameAsString());
9701 if (!clang_typedef_name.empty()) {
9702 s->PutCString("typedef ");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009703 s->PutCString(clang_typedef_name);
Greg Claytond8d4a572015-08-11 21:38:15 +00009704 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009705 }
9706 } break;
9707
9708 case clang::Type::Auto:
9709 CompilerType(getASTContext(),
9710 llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
9711 .DumpTypeDescription(s);
9712 return;
9713
9714 case clang::Type::Elaborated:
9715 CompilerType(getASTContext(),
9716 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
9717 .DumpTypeDescription(s);
9718 return;
9719
9720 case clang::Type::Paren:
9721 CompilerType(getASTContext(),
9722 llvm::cast<clang::ParenType>(qual_type)->desugar())
9723 .DumpTypeDescription(s);
9724 return;
9725
9726 case clang::Type::Record: {
9727 GetCompleteType(type);
9728
9729 const clang::RecordType *record_type =
9730 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
9731 const clang::RecordDecl *record_decl = record_type->getDecl();
9732 const clang::CXXRecordDecl *cxx_record_decl =
9733 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
9734
9735 if (cxx_record_decl)
9736 cxx_record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(),
9737 s->GetIndentLevel());
9738 else
9739 record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(),
9740 s->GetIndentLevel());
9741 } break;
9742
9743 default: {
9744 const clang::TagType *tag_type =
9745 llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
9746 if (tag_type) {
9747 clang::TagDecl *tag_decl = tag_type->getDecl();
9748 if (tag_decl)
9749 tag_decl->print(llvm_ostrm, 0);
9750 } else {
9751 std::string clang_type_name(qual_type.getAsString());
9752 if (!clang_type_name.empty())
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009753 s->PutCString(clang_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009754 }
Greg Claytond8d4a572015-08-11 21:38:15 +00009755 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00009756 }
9757
Kate Stoneb9c1b512016-09-06 20:57:50 +00009758 if (buf.size() > 0) {
9759 s->Write(buf.data(), buf.size());
Greg Clayton8b4edba2015-08-14 20:02:05 +00009760 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009761 }
Greg Clayton8b4edba2015-08-14 20:02:05 +00009762}
9763
Kate Stoneb9c1b512016-09-06 20:57:50 +00009764void ClangASTContext::DumpTypeName(const CompilerType &type) {
9765 if (ClangUtil::IsClangType(type)) {
9766 clang::QualType qual_type(
9767 ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
9768
9769 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
9770 switch (type_class) {
9771 case clang::Type::Record: {
9772 const clang::CXXRecordDecl *cxx_record_decl =
9773 qual_type->getAsCXXRecordDecl();
9774 if (cxx_record_decl)
9775 printf("class %s", cxx_record_decl->getName().str().c_str());
9776 } break;
9777
9778 case clang::Type::Enum: {
9779 clang::EnumDecl *enum_decl =
9780 llvm::cast<clang::EnumType>(qual_type)->getDecl();
9781 if (enum_decl) {
9782 printf("enum %s", enum_decl->getName().str().c_str());
9783 }
9784 } break;
9785
9786 case clang::Type::ObjCObject:
9787 case clang::Type::ObjCInterface: {
9788 const clang::ObjCObjectType *objc_class_type =
9789 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
9790 if (objc_class_type) {
9791 clang::ObjCInterfaceDecl *class_interface_decl =
9792 objc_class_type->getInterface();
Adrian Prantl05097242018-04-30 16:49:04 +00009793 // We currently can't complete objective C types through the newly
9794 // added ASTContext because it only supports TagDecl objects right
9795 // now...
Kate Stoneb9c1b512016-09-06 20:57:50 +00009796 if (class_interface_decl)
9797 printf("@class %s", class_interface_decl->getName().str().c_str());
9798 }
9799 } break;
9800
9801 case clang::Type::Typedef:
9802 printf("typedef %s", llvm::cast<clang::TypedefType>(qual_type)
9803 ->getDecl()
9804 ->getName()
9805 .str()
9806 .c_str());
9807 break;
9808
9809 case clang::Type::Auto:
9810 printf("auto ");
9811 return DumpTypeName(CompilerType(type.GetTypeSystem(),
9812 llvm::cast<clang::AutoType>(qual_type)
9813 ->getDeducedType()
9814 .getAsOpaquePtr()));
9815
9816 case clang::Type::Elaborated:
9817 printf("elaborated ");
9818 return DumpTypeName(CompilerType(
9819 type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)
9820 ->getNamedType()
9821 .getAsOpaquePtr()));
9822
9823 case clang::Type::Paren:
9824 printf("paren ");
9825 return DumpTypeName(CompilerType(
9826 type.GetTypeSystem(),
9827 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
9828
9829 default:
9830 printf("ClangASTContext::DumpTypeName() type_class = %u", type_class);
9831 break;
Greg Clayton6dc8d582015-08-18 22:32:36 +00009832 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009833 }
Greg Clayton6dc8d582015-08-18 22:32:36 +00009834}
9835
Kate Stoneb9c1b512016-09-06 20:57:50 +00009836clang::ClassTemplateDecl *ClangASTContext::ParseClassTemplateDecl(
9837 clang::DeclContext *decl_ctx, lldb::AccessType access_type,
9838 const char *parent_name, int tag_decl_kind,
9839 const ClangASTContext::TemplateParameterInfos &template_param_infos) {
9840 if (template_param_infos.IsValid()) {
9841 std::string template_basename(parent_name);
9842 template_basename.erase(template_basename.find('<'));
9843
9844 return CreateClassTemplateDecl(decl_ctx, access_type,
9845 template_basename.c_str(), tag_decl_kind,
9846 template_param_infos);
9847 }
Konrad Kleine248a1302019-05-23 11:14:47 +00009848 return nullptr;
Greg Clayton6dc8d582015-08-18 22:32:36 +00009849}
Greg Clayton8b4edba2015-08-14 20:02:05 +00009850
Kate Stoneb9c1b512016-09-06 20:57:50 +00009851void ClangASTContext::CompleteTagDecl(void *baton, clang::TagDecl *decl) {
9852 ClangASTContext *ast = (ClangASTContext *)baton;
9853 SymbolFile *sym_file = ast->GetSymbolFile();
9854 if (sym_file) {
9855 CompilerType clang_type = GetTypeForDecl(decl);
9856 if (clang_type)
9857 sym_file->CompleteType(clang_type);
9858 }
Greg Clayton261ac3f2015-08-28 01:01:03 +00009859}
9860
Kate Stoneb9c1b512016-09-06 20:57:50 +00009861void ClangASTContext::CompleteObjCInterfaceDecl(
9862 void *baton, clang::ObjCInterfaceDecl *decl) {
9863 ClangASTContext *ast = (ClangASTContext *)baton;
9864 SymbolFile *sym_file = ast->GetSymbolFile();
9865 if (sym_file) {
9866 CompilerType clang_type = GetTypeForDecl(decl);
9867 if (clang_type)
9868 sym_file->CompleteType(clang_type);
9869 }
Zachary Turner42dff792016-04-15 00:21:26 +00009870}
Greg Clayton261ac3f2015-08-28 01:01:03 +00009871
Kate Stoneb9c1b512016-09-06 20:57:50 +00009872DWARFASTParser *ClangASTContext::GetDWARFParser() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +00009873 if (!m_dwarf_ast_parser_up)
9874 m_dwarf_ast_parser_up.reset(new DWARFASTParserClang(*this));
9875 return m_dwarf_ast_parser_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +00009876}
9877
9878PDBASTParser *ClangASTContext::GetPDBParser() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +00009879 if (!m_pdb_ast_parser_up)
9880 m_pdb_ast_parser_up.reset(new PDBASTParser(*this));
9881 return m_pdb_ast_parser_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +00009882}
9883
9884bool ClangASTContext::LayoutRecordType(
9885 void *baton, const clang::RecordDecl *record_decl, uint64_t &bit_size,
9886 uint64_t &alignment,
9887 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
9888 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
9889 &base_offsets,
9890 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
9891 &vbase_offsets) {
9892 ClangASTContext *ast = (ClangASTContext *)baton;
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00009893 lldb_private::ClangASTImporter *importer = nullptr;
Jonas Devlieghered5b44032019-02-13 06:25:41 +00009894 if (ast->m_dwarf_ast_parser_up)
9895 importer = &ast->m_dwarf_ast_parser_up->GetClangASTImporter();
9896 if (!importer && ast->m_pdb_ast_parser_up)
9897 importer = &ast->m_pdb_ast_parser_up->GetClangASTImporter();
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00009898 if (!importer)
9899 return false;
9900
9901 return importer->LayoutRecordType(record_decl, bit_size, alignment,
9902 field_offsets, base_offsets, vbase_offsets);
Greg Clayton8b4edba2015-08-14 20:02:05 +00009903}
9904
Paul Hermand628cbb2015-09-15 23:44:17 +00009905// CompilerDecl override functions
Paul Hermand628cbb2015-09-15 23:44:17 +00009906
Kate Stoneb9c1b512016-09-06 20:57:50 +00009907ConstString ClangASTContext::DeclGetName(void *opaque_decl) {
9908 if (opaque_decl) {
9909 clang::NamedDecl *nd =
9910 llvm::dyn_cast<NamedDecl>((clang::Decl *)opaque_decl);
9911 if (nd != nullptr)
9912 return ConstString(nd->getDeclName().getAsString());
9913 }
9914 return ConstString();
Paul Hermand628cbb2015-09-15 23:44:17 +00009915}
9916
Kate Stoneb9c1b512016-09-06 20:57:50 +00009917ConstString ClangASTContext::DeclGetMangledName(void *opaque_decl) {
9918 if (opaque_decl) {
9919 clang::NamedDecl *nd =
9920 llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)opaque_decl);
9921 if (nd != nullptr && !llvm::isa<clang::ObjCMethodDecl>(nd)) {
9922 clang::MangleContext *mc = getMangleContext();
9923 if (mc && mc->shouldMangleCXXName(nd)) {
9924 llvm::SmallVector<char, 1024> buf;
9925 llvm::raw_svector_ostream llvm_ostrm(buf);
9926 if (llvm::isa<clang::CXXConstructorDecl>(nd)) {
9927 mc->mangleCXXCtor(llvm::dyn_cast<clang::CXXConstructorDecl>(nd),
9928 Ctor_Complete, llvm_ostrm);
9929 } else if (llvm::isa<clang::CXXDestructorDecl>(nd)) {
9930 mc->mangleCXXDtor(llvm::dyn_cast<clang::CXXDestructorDecl>(nd),
9931 Dtor_Complete, llvm_ostrm);
9932 } else {
9933 mc->mangleName(nd, llvm_ostrm);
Greg Claytonfe689042015-11-10 17:47:04 +00009934 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009935 if (buf.size() > 0)
9936 return ConstString(buf.data(), buf.size());
9937 }
Greg Claytonfe689042015-11-10 17:47:04 +00009938 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009939 }
9940 return ConstString();
Greg Claytonfe689042015-11-10 17:47:04 +00009941}
9942
Kate Stoneb9c1b512016-09-06 20:57:50 +00009943CompilerDeclContext ClangASTContext::DeclGetDeclContext(void *opaque_decl) {
9944 if (opaque_decl)
9945 return CompilerDeclContext(this,
9946 ((clang::Decl *)opaque_decl)->getDeclContext());
9947 else
9948 return CompilerDeclContext();
Greg Claytonfe689042015-11-10 17:47:04 +00009949}
9950
Kate Stoneb9c1b512016-09-06 20:57:50 +00009951CompilerType ClangASTContext::DeclGetFunctionReturnType(void *opaque_decl) {
9952 if (clang::FunctionDecl *func_decl =
9953 llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl))
9954 return CompilerType(this, func_decl->getReturnType().getAsOpaquePtr());
9955 if (clang::ObjCMethodDecl *objc_method =
9956 llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl))
9957 return CompilerType(this, objc_method->getReturnType().getAsOpaquePtr());
9958 else
Greg Claytonfe689042015-11-10 17:47:04 +00009959 return CompilerType();
9960}
9961
Kate Stoneb9c1b512016-09-06 20:57:50 +00009962size_t ClangASTContext::DeclGetFunctionNumArguments(void *opaque_decl) {
9963 if (clang::FunctionDecl *func_decl =
9964 llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl))
9965 return func_decl->param_size();
9966 if (clang::ObjCMethodDecl *objc_method =
9967 llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl))
9968 return objc_method->param_size();
9969 else
9970 return 0;
9971}
9972
9973CompilerType ClangASTContext::DeclGetFunctionArgumentType(void *opaque_decl,
9974 size_t idx) {
9975 if (clang::FunctionDecl *func_decl =
9976 llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl)) {
9977 if (idx < func_decl->param_size()) {
9978 ParmVarDecl *var_decl = func_decl->getParamDecl(idx);
9979 if (var_decl)
9980 return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr());
9981 }
9982 } else if (clang::ObjCMethodDecl *objc_method =
9983 llvm::dyn_cast<clang::ObjCMethodDecl>(
9984 (clang::Decl *)opaque_decl)) {
9985 if (idx < objc_method->param_size())
9986 return CompilerType(
9987 this,
9988 objc_method->parameters()[idx]->getOriginalType().getAsOpaquePtr());
9989 }
9990 return CompilerType();
9991}
9992
Greg Clayton99558cc42015-08-24 23:46:31 +00009993// CompilerDeclContext functions
Greg Clayton99558cc42015-08-24 23:46:31 +00009994
Kate Stoneb9c1b512016-09-06 20:57:50 +00009995std::vector<CompilerDecl> ClangASTContext::DeclContextFindDeclByName(
9996 void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) {
9997 std::vector<CompilerDecl> found_decls;
9998 if (opaque_decl_ctx) {
9999 DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
10000 std::set<DeclContext *> searched;
10001 std::multimap<DeclContext *, DeclContext *> search_queue;
10002 SymbolFile *symbol_file = GetSymbolFile();
Paul Hermand628cbb2015-09-15 23:44:17 +000010003
Kate Stoneb9c1b512016-09-06 20:57:50 +000010004 for (clang::DeclContext *decl_context = root_decl_ctx;
10005 decl_context != nullptr && found_decls.empty();
10006 decl_context = decl_context->getParent()) {
10007 search_queue.insert(std::make_pair(decl_context, decl_context));
Paul Hermand628cbb2015-09-15 23:44:17 +000010008
Kate Stoneb9c1b512016-09-06 20:57:50 +000010009 for (auto it = search_queue.find(decl_context); it != search_queue.end();
10010 it++) {
10011 if (!searched.insert(it->second).second)
10012 continue;
10013 symbol_file->ParseDeclsForContext(
10014 CompilerDeclContext(this, it->second));
Paul Hermanea188fc2015-09-16 18:48:30 +000010015
Kate Stoneb9c1b512016-09-06 20:57:50 +000010016 for (clang::Decl *child : it->second->decls()) {
10017 if (clang::UsingDirectiveDecl *ud =
10018 llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) {
10019 if (ignore_using_decls)
10020 continue;
10021 clang::DeclContext *from = ud->getCommonAncestor();
10022 if (searched.find(ud->getNominatedNamespace()) == searched.end())
10023 search_queue.insert(
10024 std::make_pair(from, ud->getNominatedNamespace()));
10025 } else if (clang::UsingDecl *ud =
10026 llvm::dyn_cast<clang::UsingDecl>(child)) {
10027 if (ignore_using_decls)
10028 continue;
10029 for (clang::UsingShadowDecl *usd : ud->shadows()) {
10030 clang::Decl *target = usd->getTargetDecl();
10031 if (clang::NamedDecl *nd =
10032 llvm::dyn_cast<clang::NamedDecl>(target)) {
10033 IdentifierInfo *ii = nd->getIdentifier();
10034 if (ii != nullptr &&
10035 ii->getName().equals(name.AsCString(nullptr)))
10036 found_decls.push_back(CompilerDecl(this, nd));
10037 }
Paul Hermand628cbb2015-09-15 23:44:17 +000010038 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010039 } else if (clang::NamedDecl *nd =
10040 llvm::dyn_cast<clang::NamedDecl>(child)) {
10041 IdentifierInfo *ii = nd->getIdentifier();
10042 if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr)))
10043 found_decls.push_back(CompilerDecl(this, nd));
10044 }
Paul Hermand628cbb2015-09-15 23:44:17 +000010045 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010046 }
Paul Hermand628cbb2015-09-15 23:44:17 +000010047 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010048 }
10049 return found_decls;
Paul Hermand628cbb2015-09-15 23:44:17 +000010050}
10051
Dawn Perchikb5925782015-12-12 19:31:41 +000010052// Look for child_decl_ctx's lookup scope in frame_decl_ctx and its parents,
Kate Stoneb9c1b512016-09-06 20:57:50 +000010053// and return the number of levels it took to find it, or
Adrian Prantl05097242018-04-30 16:49:04 +000010054// LLDB_INVALID_DECL_LEVEL if not found. If the decl was imported via a using
10055// declaration, its name and/or type, if set, will be used to check that the
10056// decl found in the scope is a match.
Dawn Perchikb5925782015-12-12 19:31:41 +000010057//
Kate Stoneb9c1b512016-09-06 20:57:50 +000010058// The optional name is required by languages (like C++) to handle using
Adrian Prantl05097242018-04-30 16:49:04 +000010059// declarations like:
Dawn Perchikb5925782015-12-12 19:31:41 +000010060//
10061// void poo();
10062// namespace ns {
10063// void foo();
10064// void goo();
10065// }
10066// void bar() {
10067// using ns::foo;
10068// // CountDeclLevels returns 0 for 'foo', 1 for 'poo', and
10069// // LLDB_INVALID_DECL_LEVEL for 'goo'.
10070// }
10071//
10072// The optional type is useful in the case that there's a specific overload
10073// that we're looking for that might otherwise be shadowed, like:
10074//
10075// void foo(int);
10076// namespace ns {
10077// void foo();
10078// }
10079// void bar() {
10080// using ns::foo;
10081// // CountDeclLevels returns 0 for { 'foo', void() },
10082// // 1 for { 'foo', void(int) }, and
10083// // LLDB_INVALID_DECL_LEVEL for { 'foo', void(int, int) }.
10084// }
10085//
10086// NOTE: Because file statics are at the TranslationUnit along with globals, a
Kate Stoneb9c1b512016-09-06 20:57:50 +000010087// function at file scope will return the same level as a function at global
Adrian Prantl05097242018-04-30 16:49:04 +000010088// scope. Ideally we'd like to treat the file scope as an additional scope just
10089// below the global scope. More work needs to be done to recognise that, if
10090// the decl we're trying to look up is static, we should compare its source
10091// file with that of the current scope and return a lower number for it.
Kate Stoneb9c1b512016-09-06 20:57:50 +000010092uint32_t ClangASTContext::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
10093 clang::DeclContext *child_decl_ctx,
10094 ConstString *child_name,
10095 CompilerType *child_type) {
10096 if (frame_decl_ctx) {
10097 std::set<DeclContext *> searched;
10098 std::multimap<DeclContext *, DeclContext *> search_queue;
10099 SymbolFile *symbol_file = GetSymbolFile();
Dawn Perchikb5925782015-12-12 19:31:41 +000010100
Kate Stoneb9c1b512016-09-06 20:57:50 +000010101 // Get the lookup scope for the decl we're trying to find.
10102 clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent();
Dawn Perchikb5925782015-12-12 19:31:41 +000010103
Kate Stoneb9c1b512016-09-06 20:57:50 +000010104 // Look for it in our scope's decl context and its parents.
10105 uint32_t level = 0;
10106 for (clang::DeclContext *decl_ctx = frame_decl_ctx; decl_ctx != nullptr;
10107 decl_ctx = decl_ctx->getParent()) {
10108 if (!decl_ctx->isLookupContext())
10109 continue;
10110 if (decl_ctx == parent_decl_ctx)
10111 // Found it!
10112 return level;
10113 search_queue.insert(std::make_pair(decl_ctx, decl_ctx));
10114 for (auto it = search_queue.find(decl_ctx); it != search_queue.end();
10115 it++) {
10116 if (searched.find(it->second) != searched.end())
10117 continue;
10118
10119 // Currently DWARF has one shared translation unit for all Decls at top
Adrian Prantl05097242018-04-30 16:49:04 +000010120 // level, so this would erroneously find using statements anywhere. So
10121 // don't look at the top-level translation unit.
Kate Stoneb9c1b512016-09-06 20:57:50 +000010122 // TODO fix this and add a testcase that depends on it.
10123
10124 if (llvm::isa<clang::TranslationUnitDecl>(it->second))
10125 continue;
10126
10127 searched.insert(it->second);
10128 symbol_file->ParseDeclsForContext(
10129 CompilerDeclContext(this, it->second));
10130
10131 for (clang::Decl *child : it->second->decls()) {
10132 if (clang::UsingDirectiveDecl *ud =
10133 llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) {
10134 clang::DeclContext *ns = ud->getNominatedNamespace();
10135 if (ns == parent_decl_ctx)
10136 // Found it!
10137 return level;
10138 clang::DeclContext *from = ud->getCommonAncestor();
10139 if (searched.find(ns) == searched.end())
10140 search_queue.insert(std::make_pair(from, ns));
10141 } else if (child_name) {
10142 if (clang::UsingDecl *ud =
10143 llvm::dyn_cast<clang::UsingDecl>(child)) {
10144 for (clang::UsingShadowDecl *usd : ud->shadows()) {
10145 clang::Decl *target = usd->getTargetDecl();
10146 clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(target);
10147 if (!nd)
10148 continue;
10149 // Check names.
10150 IdentifierInfo *ii = nd->getIdentifier();
10151 if (ii == nullptr ||
10152 !ii->getName().equals(child_name->AsCString(nullptr)))
10153 continue;
10154 // Check types, if one was provided.
10155 if (child_type) {
10156 CompilerType clang_type = ClangASTContext::GetTypeForDecl(nd);
10157 if (!AreTypesSame(clang_type, *child_type,
10158 /*ignore_qualifiers=*/true))
10159 continue;
10160 }
Dawn Perchikb5925782015-12-12 19:31:41 +000010161 // Found it!
10162 return level;
Kate Stoneb9c1b512016-09-06 20:57:50 +000010163 }
Dawn Perchikb5925782015-12-12 19:31:41 +000010164 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010165 }
Dawn Perchikb5925782015-12-12 19:31:41 +000010166 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010167 }
10168 ++level;
Dawn Perchikb5925782015-12-12 19:31:41 +000010169 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010170 }
10171 return LLDB_INVALID_DECL_LEVEL;
Dawn Perchikb5925782015-12-12 19:31:41 +000010172}
10173
Kate Stoneb9c1b512016-09-06 20:57:50 +000010174bool ClangASTContext::DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) {
10175 if (opaque_decl_ctx)
10176 return ((clang::DeclContext *)opaque_decl_ctx)->isRecord();
10177 else
Greg Clayton99558cc42015-08-24 23:46:31 +000010178 return false;
10179}
10180
Kate Stoneb9c1b512016-09-06 20:57:50 +000010181ConstString ClangASTContext::DeclContextGetName(void *opaque_decl_ctx) {
10182 if (opaque_decl_ctx) {
10183 clang::NamedDecl *named_decl =
10184 llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
10185 if (named_decl)
10186 return ConstString(named_decl->getName());
10187 }
10188 return ConstString();
Greg Clayton99558cc42015-08-24 23:46:31 +000010189}
10190
Kate Stoneb9c1b512016-09-06 20:57:50 +000010191ConstString
10192ClangASTContext::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) {
10193 if (opaque_decl_ctx) {
10194 clang::NamedDecl *named_decl =
10195 llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
10196 if (named_decl)
10197 return ConstString(
10198 llvm::StringRef(named_decl->getQualifiedNameAsString()));
10199 }
10200 return ConstString();
10201}
10202
10203bool ClangASTContext::DeclContextIsClassMethod(
10204 void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
10205 bool *is_instance_method_ptr, ConstString *language_object_name_ptr) {
10206 if (opaque_decl_ctx) {
10207 clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
10208 if (ObjCMethodDecl *objc_method =
10209 llvm::dyn_cast<clang::ObjCMethodDecl>(decl_ctx)) {
10210 if (is_instance_method_ptr)
10211 *is_instance_method_ptr = objc_method->isInstanceMethod();
10212 if (language_ptr)
10213 *language_ptr = eLanguageTypeObjC;
10214 if (language_object_name_ptr)
10215 language_object_name_ptr->SetCString("self");
10216 return true;
10217 } else if (CXXMethodDecl *cxx_method =
10218 llvm::dyn_cast<clang::CXXMethodDecl>(decl_ctx)) {
10219 if (is_instance_method_ptr)
10220 *is_instance_method_ptr = cxx_method->isInstance();
10221 if (language_ptr)
10222 *language_ptr = eLanguageTypeC_plus_plus;
10223 if (language_object_name_ptr)
10224 language_object_name_ptr->SetCString("this");
10225 return true;
10226 } else if (clang::FunctionDecl *function_decl =
10227 llvm::dyn_cast<clang::FunctionDecl>(decl_ctx)) {
10228 ClangASTMetadata *metadata =
10229 GetMetadata(&decl_ctx->getParentASTContext(), function_decl);
10230 if (metadata && metadata->HasObjectPtr()) {
10231 if (is_instance_method_ptr)
10232 *is_instance_method_ptr = true;
10233 if (language_ptr)
10234 *language_ptr = eLanguageTypeObjC;
10235 if (language_object_name_ptr)
10236 language_object_name_ptr->SetCString(metadata->GetObjectPtrName());
10237 return true;
10238 }
10239 }
10240 }
10241 return false;
10242}
10243
Raphael Isemanna9469972019-03-12 07:45:04 +000010244bool ClangASTContext::DeclContextIsContainedInLookup(
10245 void *opaque_decl_ctx, void *other_opaque_decl_ctx) {
10246 auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
10247 auto *other = (clang::DeclContext *)other_opaque_decl_ctx;
10248
10249 do {
10250 // A decl context always includes its own contents in its lookup.
10251 if (decl_ctx == other)
10252 return true;
10253
10254 // If we have an inline namespace, then the lookup of the parent context
10255 // also includes the inline namespace contents.
10256 } while (other->isInlineNamespace() && (other = other->getParent()));
10257
10258 return false;
10259}
10260
Kate Stoneb9c1b512016-09-06 20:57:50 +000010261clang::DeclContext *
10262ClangASTContext::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) {
10263 if (dc.IsClang())
10264 return (clang::DeclContext *)dc.GetOpaqueDeclContext();
10265 return nullptr;
10266}
Greg Clayton99558cc42015-08-24 23:46:31 +000010267
10268ObjCMethodDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010269ClangASTContext::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) {
10270 if (dc.IsClang())
10271 return llvm::dyn_cast<clang::ObjCMethodDecl>(
10272 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10273 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010274}
10275
10276CXXMethodDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010277ClangASTContext::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) {
10278 if (dc.IsClang())
10279 return llvm::dyn_cast<clang::CXXMethodDecl>(
10280 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10281 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010282}
10283
10284clang::FunctionDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010285ClangASTContext::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) {
10286 if (dc.IsClang())
10287 return llvm::dyn_cast<clang::FunctionDecl>(
10288 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10289 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010290}
10291
10292clang::NamespaceDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010293ClangASTContext::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) {
10294 if (dc.IsClang())
10295 return llvm::dyn_cast<clang::NamespaceDecl>(
10296 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10297 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010298}
10299
10300ClangASTMetadata *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010301ClangASTContext::DeclContextGetMetaData(const CompilerDeclContext &dc,
10302 const void *object) {
10303 clang::ASTContext *ast = DeclContextGetClangASTContext(dc);
10304 if (ast)
10305 return ClangASTContext::GetMetadata(ast, object);
10306 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010307}
10308
10309clang::ASTContext *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010310ClangASTContext::DeclContextGetClangASTContext(const CompilerDeclContext &dc) {
10311 ClangASTContext *ast =
10312 llvm::dyn_cast_or_null<ClangASTContext>(dc.GetTypeSystem());
10313 if (ast)
10314 return ast->getASTContext();
10315 return nullptr;
10316}
10317
10318ClangASTContextForExpressions::ClangASTContextForExpressions(Target &target)
10319 : ClangASTContext(target.GetArchitecture().GetTriple().getTriple().c_str()),
10320 m_target_wp(target.shared_from_this()),
10321 m_persistent_variables(new ClangPersistentVariables) {}
10322
10323UserExpression *ClangASTContextForExpressions::GetUserExpression(
Zachary Turnerc5d7df92016-11-08 04:52:16 +000010324 llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
Kate Stoneb9c1b512016-09-06 20:57:50 +000010325 Expression::ResultType desired_type,
Aleksandr Urakov40624a02019-02-05 09:14:36 +000010326 const EvaluateExpressionOptions &options,
10327 ValueObject *ctx_obj) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000010328 TargetSP target_sp = m_target_wp.lock();
10329 if (!target_sp)
Greg Clayton99558cc42015-08-24 23:46:31 +000010330 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +000010331
Zachary Turnerc5d7df92016-11-08 04:52:16 +000010332 return new ClangUserExpression(*target_sp.get(), expr, prefix, language,
Aleksandr Urakov40624a02019-02-05 09:14:36 +000010333 desired_type, options, ctx_obj);
Greg Clayton8b4edba2015-08-14 20:02:05 +000010334}
10335
Kate Stoneb9c1b512016-09-06 20:57:50 +000010336FunctionCaller *ClangASTContextForExpressions::GetFunctionCaller(
10337 const CompilerType &return_type, const Address &function_address,
10338 const ValueList &arg_value_list, const char *name) {
10339 TargetSP target_sp = m_target_wp.lock();
10340 if (!target_sp)
10341 return nullptr;
Jim Ingham151c0322015-09-15 21:13:50 +000010342
Kate Stoneb9c1b512016-09-06 20:57:50 +000010343 Process *process = target_sp->GetProcessSP().get();
10344 if (!process)
10345 return nullptr;
Jim Ingham151c0322015-09-15 21:13:50 +000010346
Kate Stoneb9c1b512016-09-06 20:57:50 +000010347 return new ClangFunctionCaller(*process, return_type, function_address,
10348 arg_value_list, name);
Jim Ingham151c0322015-09-15 21:13:50 +000010349}
10350
10351UtilityFunction *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010352ClangASTContextForExpressions::GetUtilityFunction(const char *text,
10353 const char *name) {
10354 TargetSP target_sp = m_target_wp.lock();
10355 if (!target_sp)
10356 return nullptr;
10357
10358 return new ClangUtilityFunction(*target_sp.get(), text, name);
Jim Ingham151c0322015-09-15 21:13:50 +000010359}
Sean Callanan8f1f9a12015-09-30 19:57:57 +000010360
10361PersistentExpressionState *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010362ClangASTContextForExpressions::GetPersistentExpressionState() {
10363 return m_persistent_variables.get();
Sean Callanan8f1f9a12015-09-30 19:57:57 +000010364}
Sean Callanan68e44232017-09-28 20:20:25 +000010365
10366clang::ExternalASTMerger &
10367ClangASTContextForExpressions::GetMergerUnchecked() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +000010368 lldbassert(m_scratch_ast_source_up != nullptr);
10369 return m_scratch_ast_source_up->GetMergerUnchecked();
Sean Callanan68e44232017-09-28 20:20:25 +000010370}