blob: 97952469ce5d876ecba3729af3b44ea3487b506f [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"
Alex Langford9e865612019-09-09 23:11:43 +000068#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000069#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
70#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
Pavel Labath5f19b902017-11-13 16:16:33 +000071#include "lldb/Utility/ArchSpec.h"
Zachary Turner01c32432017-02-14 19:06:07 +000072#include "lldb/Utility/Flags.h"
73
Zachary Turner29cb8682017-03-03 20:57:05 +000074#include "lldb/Core/DumpDataExtractor.h"
Greg Clayton56939cb2015-09-17 22:23:34 +000075#include "lldb/Core/Module.h"
76#include "lldb/Core/PluginManager.h"
Greg Claytond8d4a572015-08-11 21:38:15 +000077#include "lldb/Core/StreamFile.h"
Enrico Granata2267ad42014-09-16 17:28:40 +000078#include "lldb/Core/ThreadSafeDenseMap.h"
Greg Clayton57ee3062013-07-11 22:46:58 +000079#include "lldb/Core/UniqueCStringMap.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"
Jim Inghamd555bac2011-06-24 22:03:24 +000086#include "lldb/Target/ExecutionContext.h"
Greg Clayton56939cb2015-09-17 22:23:34 +000087#include "lldb/Target/Language.h"
Jim Ingham151c0322015-09-15 21:13:50 +000088#include "lldb/Target/Process.h"
89#include "lldb/Target/Target.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000090#include "lldb/Utility/DataExtractor.h"
Sean Callananc530ba92016-05-02 21:15:31 +000091#include "lldb/Utility/LLDBAssert.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000092#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000093#include "lldb/Utility/RegularExpression.h"
Pavel Labathd821c992018-08-07 11:07:21 +000094#include "lldb/Utility/Scalar.h"
Jim Inghamd555bac2011-06-24 22:03:24 +000095
Alex Langfordb57017102019-07-15 22:56:12 +000096#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
Greg Clayton261ac3f2015-08-28 01:01:03 +000097#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
Zachary Turner42dff792016-04-15 00:21:26 +000098#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
Greg Clayton261ac3f2015-08-28 01:01:03 +000099
Eli Friedman932197d2010-06-13 19:06:42 +0000100#include <stdio.h>
101
Greg Clayton1341baf2013-07-11 23:36:31 +0000102#include <mutex>
103
Greg Claytonc86103d2010-08-05 01:57:25 +0000104using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105using namespace lldb_private;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106using namespace clang;
Pavel Labath6f23a682019-09-30 13:44:17 +0000107using llvm::StringSwitch;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109namespace {
Pavel Labath65a376f2019-08-21 13:11:30 +0000110#ifdef LLDB_CONFIGURATION_DEBUG
Alex Langfordb2232a12019-08-20 22:06:13 +0000111static void VerifyDecl(clang::Decl *decl) {
112 assert(decl && "VerifyDecl called with nullptr?");
113 decl->getAccess();
114}
Pavel Labath65a376f2019-08-21 13:11:30 +0000115#endif
Alex Langfordb2232a12019-08-20 22:06:13 +0000116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117static inline bool
118ClangASTContextSupportsLanguage(lldb::LanguageType language) {
119 return language == eLanguageTypeUnknown || // Clang is the default type system
Rainer Orth6ca17072019-08-05 14:00:43 +0000120 lldb_private::Language::LanguageIsC(language) ||
121 lldb_private::Language::LanguageIsCPlusPlus(language) ||
122 lldb_private::Language::LanguageIsObjC(language) ||
123 lldb_private::Language::LanguageIsPascal(language) ||
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 // Use Clang for Rust until there is a proper language plugin for it
125 language == eLanguageTypeRust ||
Johan Engelen04799572016-11-25 11:01:12 +0000126 language == eLanguageTypeExtRenderScript ||
127 // Use Clang for D until there is a proper language plugin for it
Bruce Mitchenerb8233f82018-11-27 05:37:27 +0000128 language == eLanguageTypeD ||
129 // Open Dylan compiler debug info is designed to be Clang-compatible
130 language == eLanguageTypeDylan;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131}
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +0000132
133// Checks whether m1 is an overload of m2 (as opposed to an override). This is
134// called by addOverridesForMethod to distinguish overrides (which share a
135// vtable entry) from overloads (which require distinct entries).
136bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) {
137 // FIXME: This should detect covariant return types, but currently doesn't.
138 lldbassert(&m1->getASTContext() == &m2->getASTContext() &&
139 "Methods should have the same AST context");
140 clang::ASTContext &context = m1->getASTContext();
141
142 const auto *m1Type = llvm::cast<clang::FunctionProtoType>(
143 context.getCanonicalType(m1->getType()));
144
145 const auto *m2Type = llvm::cast<clang::FunctionProtoType>(
146 context.getCanonicalType(m2->getType()));
147
148 auto compareArgTypes = [&context](const clang::QualType &m1p,
149 const clang::QualType &m2p) {
150 return context.hasSameType(m1p.getUnqualifiedType(),
151 m2p.getUnqualifiedType());
152 };
153
154 // FIXME: In C++14 and later, we can just pass m2Type->param_type_end()
155 // as a fourth parameter to std::equal().
156 return (m1->getNumParams() != m2->getNumParams()) ||
157 !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(),
158 m2Type->param_type_begin(), compareArgTypes);
159}
160
161// If decl is a virtual method, walk the base classes looking for methods that
162// decl overrides. This table of overridden methods is used by IRGen to
163// determine the vtable layout for decl's parent class.
164void addOverridesForMethod(clang::CXXMethodDecl *decl) {
165 if (!decl->isVirtual())
166 return;
167
168 clang::CXXBasePaths paths;
169
170 auto find_overridden_methods =
171 [decl](const clang::CXXBaseSpecifier *specifier,
172 clang::CXXBasePath &path) {
173 if (auto *base_record = llvm::dyn_cast<clang::CXXRecordDecl>(
174 specifier->getType()->getAs<clang::RecordType>()->getDecl())) {
175
176 clang::DeclarationName name = decl->getDeclName();
177
178 // If this is a destructor, check whether the base class destructor is
179 // virtual.
180 if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
181 if (auto *baseDtorDecl = base_record->getDestructor()) {
182 if (baseDtorDecl->isVirtual()) {
183 path.Decls = baseDtorDecl;
184 return true;
185 } else
186 return false;
187 }
188
189 // Otherwise, search for name in the base class.
190 for (path.Decls = base_record->lookup(name); !path.Decls.empty();
191 path.Decls = path.Decls.slice(1)) {
192 if (auto *method_decl =
193 llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
194 if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
195 path.Decls = method_decl;
196 return true;
197 }
198 }
199 }
200
201 return false;
202 };
203
204 if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) {
205 for (auto *overridden_decl : paths.found_decls())
206 decl->addOverriddenMethod(
207 llvm::cast<clang::CXXMethodDecl>(overridden_decl));
208 }
209}
Greg Clayton56939cb2015-09-17 22:23:34 +0000210}
211
Aleksandr Urakov1dc51db2018-11-12 16:23:50 +0000212static lldb::addr_t GetVTableAddress(Process &process,
213 VTableContextBase &vtable_ctx,
214 ValueObject &valobj,
215 const ASTRecordLayout &record_layout) {
216 // Retrieve type info
217 CompilerType pointee_type;
218 CompilerType this_type(valobj.GetCompilerType());
219 uint32_t type_info = this_type.GetTypeInfo(&pointee_type);
220 if (!type_info)
221 return LLDB_INVALID_ADDRESS;
222
223 // Check if it's a pointer or reference
224 bool ptr_or_ref = false;
225 if (type_info & (eTypeIsPointer | eTypeIsReference)) {
226 ptr_or_ref = true;
227 type_info = pointee_type.GetTypeInfo();
228 }
229
230 // We process only C++ classes
231 const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus;
232 if ((type_info & cpp_class) != cpp_class)
233 return LLDB_INVALID_ADDRESS;
234
235 // Calculate offset to VTable pointer
236 lldb::offset_t vbtable_ptr_offset =
237 vtable_ctx.isMicrosoft() ? record_layout.getVBPtrOffset().getQuantity()
238 : 0;
239
240 if (ptr_or_ref) {
241 // We have a pointer / ref to object, so read
242 // VTable pointer from process memory
243
244 if (valobj.GetAddressTypeOfChildren() != eAddressTypeLoad)
245 return LLDB_INVALID_ADDRESS;
246
247 auto vbtable_ptr_addr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
248 if (vbtable_ptr_addr == LLDB_INVALID_ADDRESS)
249 return LLDB_INVALID_ADDRESS;
250
251 vbtable_ptr_addr += vbtable_ptr_offset;
252
253 Status err;
254 return process.ReadPointerFromMemory(vbtable_ptr_addr, err);
255 }
256
257 // We have an object already read from process memory,
258 // so just extract VTable pointer from it
259
260 DataExtractor data;
261 Status err;
262 auto size = valobj.GetData(data, err);
263 if (err.Fail() || vbtable_ptr_offset + data.GetAddressByteSize() > size)
264 return LLDB_INVALID_ADDRESS;
265
266 return data.GetPointer(&vbtable_ptr_offset);
267}
268
269static int64_t ReadVBaseOffsetFromVTable(Process &process,
270 VTableContextBase &vtable_ctx,
271 lldb::addr_t vtable_ptr,
272 const CXXRecordDecl *cxx_record_decl,
273 const CXXRecordDecl *base_class_decl) {
274 if (vtable_ctx.isMicrosoft()) {
275 clang::MicrosoftVTableContext &msoft_vtable_ctx =
276 static_cast<clang::MicrosoftVTableContext &>(vtable_ctx);
277
278 // Get the index into the virtual base table. The
279 // index is the index in uint32_t from vbtable_ptr
280 const unsigned vbtable_index =
281 msoft_vtable_ctx.getVBTableIndex(cxx_record_decl, base_class_decl);
282 const lldb::addr_t base_offset_addr = vtable_ptr + vbtable_index * 4;
283 Status err;
284 return process.ReadSignedIntegerFromMemory(base_offset_addr, 4, INT64_MAX,
285 err);
286 }
287
288 clang::ItaniumVTableContext &itanium_vtable_ctx =
289 static_cast<clang::ItaniumVTableContext &>(vtable_ctx);
290
291 clang::CharUnits base_offset_offset =
292 itanium_vtable_ctx.getVirtualBaseOffsetOffset(cxx_record_decl,
293 base_class_decl);
294 const lldb::addr_t base_offset_addr =
295 vtable_ptr + base_offset_offset.getQuantity();
296 const uint32_t base_offset_size = process.GetAddressByteSize();
297 Status err;
298 return process.ReadSignedIntegerFromMemory(base_offset_addr, base_offset_size,
299 INT64_MAX, err);
300}
301
302static bool GetVBaseBitOffset(VTableContextBase &vtable_ctx,
303 ValueObject &valobj,
304 const ASTRecordLayout &record_layout,
305 const CXXRecordDecl *cxx_record_decl,
306 const CXXRecordDecl *base_class_decl,
307 int32_t &bit_offset) {
308 ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
309 Process *process = exe_ctx.GetProcessPtr();
310 if (!process)
311 return false;
312
313 lldb::addr_t vtable_ptr =
314 GetVTableAddress(*process, vtable_ctx, valobj, record_layout);
315 if (vtable_ptr == LLDB_INVALID_ADDRESS)
316 return false;
317
318 auto base_offset = ReadVBaseOffsetFromVTable(
319 *process, vtable_ctx, vtable_ptr, cxx_record_decl, base_class_decl);
320 if (base_offset == INT64_MAX)
321 return false;
322
323 bit_offset = base_offset * 8;
324
325 return true;
326}
327
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, ClangASTContext *>
329 ClangASTMap;
Enrico Granata5d84a692014-08-19 21:46:37 +0000330
Kate Stoneb9c1b512016-09-06 20:57:50 +0000331static ClangASTMap &GetASTMap() {
332 static ClangASTMap *g_map_ptr = nullptr;
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000333 static llvm::once_flag g_once_flag;
334 llvm::call_once(g_once_flag, []() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335 g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins
336 });
337 return *g_map_ptr;
Enrico Granata5d84a692014-08-19 21:46:37 +0000338}
339
Raphael Isemann2f323fc2019-08-28 13:46:01 +0000340bool ClangASTContext::IsOperator(llvm::StringRef name,
Davide Italiano7e3ef4d2018-03-20 19:46:32 +0000341 clang::OverloadedOperatorKind &op_kind) {
Raphael Isemann2f323fc2019-08-28 13:46:01 +0000342 // All operators have to start with "operator".
343 if (!name.consume_front("operator"))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344 return false;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000345
Raphael Isemann2f323fc2019-08-28 13:46:01 +0000346 // Remember if there was a space after "operator". This is necessary to
347 // check for collisions with strangely named functions like "operatorint()".
348 bool space_after_operator = name.consume_front(" ");
Pavel Labath1ac2b202016-08-15 14:32:32 +0000349
Raphael Isemann2f323fc2019-08-28 13:46:01 +0000350 op_kind = StringSwitch<clang::OverloadedOperatorKind>(name)
351 .Case("+", clang::OO_Plus)
352 .Case("+=", clang::OO_PlusEqual)
353 .Case("++", clang::OO_PlusPlus)
354 .Case("-", clang::OO_Minus)
355 .Case("-=", clang::OO_MinusEqual)
356 .Case("--", clang::OO_MinusMinus)
357 .Case("->", clang::OO_Arrow)
358 .Case("->*", clang::OO_ArrowStar)
359 .Case("*", clang::OO_Star)
360 .Case("*=", clang::OO_StarEqual)
361 .Case("/", clang::OO_Slash)
362 .Case("/=", clang::OO_SlashEqual)
363 .Case("%", clang::OO_Percent)
364 .Case("%=", clang::OO_PercentEqual)
365 .Case("^", clang::OO_Caret)
366 .Case("^=", clang::OO_CaretEqual)
367 .Case("&", clang::OO_Amp)
368 .Case("&=", clang::OO_AmpEqual)
369 .Case("&&", clang::OO_AmpAmp)
370 .Case("|", clang::OO_Pipe)
371 .Case("|=", clang::OO_PipeEqual)
372 .Case("||", clang::OO_PipePipe)
373 .Case("~", clang::OO_Tilde)
374 .Case("!", clang::OO_Exclaim)
375 .Case("!=", clang::OO_ExclaimEqual)
376 .Case("=", clang::OO_Equal)
377 .Case("==", clang::OO_EqualEqual)
378 .Case("<", clang::OO_Less)
379 .Case("<<", clang::OO_LessLess)
380 .Case("<<=", clang::OO_LessLessEqual)
381 .Case("<=", clang::OO_LessEqual)
382 .Case(">", clang::OO_Greater)
383 .Case(">>", clang::OO_GreaterGreater)
384 .Case(">>=", clang::OO_GreaterGreaterEqual)
385 .Case(">=", clang::OO_GreaterEqual)
386 .Case("()", clang::OO_Call)
387 .Case("[]", clang::OO_Subscript)
388 .Case(",", clang::OO_Comma)
389 .Default(clang::NUM_OVERLOADED_OPERATORS);
Pavel Labath1ac2b202016-08-15 14:32:32 +0000390
Raphael Isemann2f323fc2019-08-28 13:46:01 +0000391 // We found a fitting operator, so we can exit now.
392 if (op_kind != clang::NUM_OVERLOADED_OPERATORS)
393 return true;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000394
Raphael Isemann2f323fc2019-08-28 13:46:01 +0000395 // After the "operator " or "operator" part is something unknown. This means
396 // it's either one of the named operators (new/delete), a conversion operator
397 // (e.g. operator bool) or a function which name starts with "operator"
398 // (e.g. void operatorbool).
Pavel Labath1ac2b202016-08-15 14:32:32 +0000399
Raphael Isemann2f323fc2019-08-28 13:46:01 +0000400 // If it's a function that starts with operator it can't have a space after
401 // "operator" because identifiers can't contain spaces.
402 // E.g. "operator int" (conversion operator)
403 // vs. "operatorint" (function with colliding name).
404 if (!space_after_operator)
405 return false; // not an operator.
Pavel Labath1ac2b202016-08-15 14:32:32 +0000406
Raphael Isemann2f323fc2019-08-28 13:46:01 +0000407 // Now the operator is either one of the named operators or a conversion
408 // operator.
409 op_kind = StringSwitch<clang::OverloadedOperatorKind>(name)
410 .Case("new", clang::OO_New)
411 .Case("new[]", clang::OO_Array_New)
412 .Case("delete", clang::OO_Delete)
413 .Case("delete[]", clang::OO_Array_Delete)
414 // conversion operators hit this case.
415 .Default(clang::NUM_OVERLOADED_OPERATORS);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000416
417 return true;
Pavel Labath1ac2b202016-08-15 14:32:32 +0000418}
Enrico Granata5d84a692014-08-19 21:46:37 +0000419
Greg Clayton57ee3062013-07-11 22:46:58 +0000420clang::AccessSpecifier
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421ClangASTContext::ConvertAccessTypeToAccessSpecifier(AccessType access) {
422 switch (access) {
423 default:
424 break;
425 case eAccessNone:
Greg Clayton8cf05932010-07-22 18:30:50 +0000426 return AS_none;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427 case eAccessPublic:
428 return AS_public;
429 case eAccessPrivate:
430 return AS_private;
431 case eAccessProtected:
432 return AS_protected;
433 }
434 return AS_none;
Greg Clayton8cf05932010-07-22 18:30:50 +0000435}
436
Kate Stoneb9c1b512016-09-06 20:57:50 +0000437static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
438 // FIXME: Cleanup per-file based stuff.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439
Adrian Prantl05097242018-04-30 16:49:04 +0000440 // Set some properties which depend solely on the input kind; it would be
441 // nice to move these to the language standard, and have the driver resolve
442 // the input kind + language standard.
Rainer Orth6ca17072019-08-05 14:00:43 +0000443 if (IK.getLanguage() == clang::Language::Asm) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444 Opts.AsmPreprocessor = 1;
Richard Smith8186cd42017-04-26 22:10:53 +0000445 } else if (IK.isObjectiveC()) {
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000446 Opts.ObjC = 1;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447 }
448
449 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
450
451 if (LangStd == LangStandard::lang_unspecified) {
452 // Based on the base language, pick one.
Richard Smith8186cd42017-04-26 22:10:53 +0000453 switch (IK.getLanguage()) {
Rainer Orth6ca17072019-08-05 14:00:43 +0000454 case clang::Language::Unknown:
455 case clang::Language::LLVM_IR:
456 case clang::Language::RenderScript:
David Blaikiea322f362017-01-06 00:38:06 +0000457 llvm_unreachable("Invalid input kind!");
Rainer Orth6ca17072019-08-05 14:00:43 +0000458 case clang::Language::OpenCL:
Pavel Labath47168542017-04-27 08:49:19 +0000459 LangStd = LangStandard::lang_opencl10;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000460 break;
Rainer Orth6ca17072019-08-05 14:00:43 +0000461 case clang::Language::CUDA:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000462 LangStd = LangStandard::lang_cuda;
463 break;
Rainer Orth6ca17072019-08-05 14:00:43 +0000464 case clang::Language::Asm:
465 case clang::Language::C:
466 case clang::Language::ObjC:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000467 LangStd = LangStandard::lang_gnu99;
468 break;
Rainer Orth6ca17072019-08-05 14:00:43 +0000469 case clang::Language::CXX:
470 case clang::Language::ObjCXX:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000471 LangStd = LangStandard::lang_gnucxx98;
472 break;
Rainer Orth6ca17072019-08-05 14:00:43 +0000473 case clang::Language::HIP:
Benjamin Kramer0d97c222018-04-25 13:22:47 +0000474 LangStd = LangStandard::lang_hip;
475 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000477 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478
Kate Stoneb9c1b512016-09-06 20:57:50 +0000479 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
480 Opts.LineComment = Std.hasLineComments();
481 Opts.C99 = Std.isC99();
482 Opts.CPlusPlus = Std.isCPlusPlus();
483 Opts.CPlusPlus11 = Std.isCPlusPlus11();
484 Opts.Digraphs = Std.hasDigraphs();
485 Opts.GNUMode = Std.isGNUMode();
486 Opts.GNUInline = !Std.isC99();
487 Opts.HexFloats = Std.hasHexFloats();
488 Opts.ImplicitInt = Std.hasImplicitInt();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489
Kate Stoneb9c1b512016-09-06 20:57:50 +0000490 Opts.WChar = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491
Kate Stoneb9c1b512016-09-06 20:57:50 +0000492 // OpenCL has some additional defaults.
Pavel Labath47168542017-04-27 08:49:19 +0000493 if (LangStd == LangStandard::lang_opencl10) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000494 Opts.OpenCL = 1;
495 Opts.AltiVec = 1;
496 Opts.CXXOperatorNames = 1;
Richard Smithc6245102019-09-13 06:02:15 +0000497 Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::All);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000498 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499
Kate Stoneb9c1b512016-09-06 20:57:50 +0000500 // OpenCL and C++ both have bool, true, false keywords.
501 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000502
Kate Stoneb9c1b512016-09-06 20:57:50 +0000503 Opts.setValueVisibilityMode(DefaultVisibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000504
Adrian Prantl05097242018-04-30 16:49:04 +0000505 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs is
506 // specified, or -std is set to a conforming mode.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000507 Opts.Trigraphs = !Opts.GNUMode;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000508 Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000509 Opts.OptimizeSize = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510
Kate Stoneb9c1b512016-09-06 20:57:50 +0000511 // FIXME: Eliminate this dependency.
512 // unsigned Opt =
513 // Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
514 // Opts.Optimize = Opt != 0;
515 unsigned Opt = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000516
Kate Stoneb9c1b512016-09-06 20:57:50 +0000517 // This is the __NO_INLINE__ define, which just depends on things like the
518 // optimization level and -fno-inline, not actually whether the backend has
519 // inlining enabled.
520 //
521 // FIXME: This is affected by other options (-fno-inline).
522 Opts.NoInlineDefine = !Opt;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523}
524
Raphael Isemannd01b4a72019-10-01 12:28:14 +0000525ClangASTContext::ClangASTContext(llvm::StringRef target_triple)
526 : TypeSystem(TypeSystem::eKindClang) {
527 if (!target_triple.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000528 SetTargetTriple(target_triple);
Raphael Isemann2eb963a2019-10-02 12:26:08 +0000529 // The caller didn't pass an ASTContext so create a new one for this
530 // ClangASTContext.
531 CreateASTContext();
532}
533
534ClangASTContext::ClangASTContext(ArchSpec arch)
535 : TypeSystem(TypeSystem::eKindClang) {
536 SetTargetTriple(arch.GetTriple().str());
537 // The caller didn't pass an ASTContext so create a new one for this
538 // ClangASTContext.
539 CreateASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540}
541
Raphael Isemannc73bfc92019-10-01 12:55:37 +0000542ClangASTContext::ClangASTContext(ASTContext &existing_ctxt)
543 : TypeSystem(TypeSystem::eKindClang) {
544 SetTargetTriple(existing_ctxt.getTargetInfo().getTriple().str());
545
546 m_ast_up.reset(&existing_ctxt);
547 GetASTMap().Insert(&existing_ctxt, this);
548}
549
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550// Destructor
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551ClangASTContext::~ClangASTContext() { Finalize(); }
552
553ConstString ClangASTContext::GetPluginNameStatic() {
554 return ConstString("clang");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000555}
556
Kate Stoneb9c1b512016-09-06 20:57:50 +0000557ConstString ClangASTContext::GetPluginName() {
558 return ClangASTContext::GetPluginNameStatic();
Greg Clayton56939cb2015-09-17 22:23:34 +0000559}
560
Kate Stoneb9c1b512016-09-06 20:57:50 +0000561uint32_t ClangASTContext::GetPluginVersion() { return 1; }
Greg Clayton56939cb2015-09-17 22:23:34 +0000562
Kate Stoneb9c1b512016-09-06 20:57:50 +0000563lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language,
564 lldb_private::Module *module,
565 Target *target) {
566 if (ClangASTContextSupportsLanguage(language)) {
567 ArchSpec arch;
568 if (module)
569 arch = module->GetArchitecture();
570 else if (target)
571 arch = target->GetArchitecture();
Greg Clayton56939cb2015-09-17 22:23:34 +0000572
Kate Stoneb9c1b512016-09-06 20:57:50 +0000573 if (arch.IsValid()) {
574 ArchSpec fixed_arch = arch;
575 // LLVM wants this to be set to iOS or MacOSX; if we're working on
576 // a bare-boards type image, change the triple for llvm's benefit.
577 if (fixed_arch.GetTriple().getVendor() == llvm::Triple::Apple &&
578 fixed_arch.GetTriple().getOS() == llvm::Triple::UnknownOS) {
579 if (fixed_arch.GetTriple().getArch() == llvm::Triple::arm ||
580 fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
581 fixed_arch.GetTriple().getArch() == llvm::Triple::thumb) {
582 fixed_arch.GetTriple().setOS(llvm::Triple::IOS);
583 } else {
584 fixed_arch.GetTriple().setOS(llvm::Triple::MacOSX);
Greg Clayton56939cb2015-09-17 22:23:34 +0000585 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000586 }
Greg Clayton56939cb2015-09-17 22:23:34 +0000587
Kate Stoneb9c1b512016-09-06 20:57:50 +0000588 if (module) {
Raphael Isemann2eb963a2019-10-02 12:26:08 +0000589 std::shared_ptr<ClangASTContext> ast_sp(
590 new ClangASTContext(fixed_arch));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000591 return ast_sp;
592 } else if (target && target->IsValid()) {
593 std::shared_ptr<ClangASTContextForExpressions> ast_sp(
Raphael Isemann2eb963a2019-10-02 12:26:08 +0000594 new ClangASTContextForExpressions(*target, fixed_arch));
595 ast_sp->m_scratch_ast_source_up.reset(
596 new ClangASTSource(target->shared_from_this()));
597 lldbassert(ast_sp->getFileManager());
598 ast_sp->m_scratch_ast_source_up->InstallASTContext(
599 *ast_sp->getASTContext(), *ast_sp->getFileManager(), true);
600 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
601 ast_sp->m_scratch_ast_source_up->CreateProxy());
602 ast_sp->SetExternalSource(proxy_ast_source);
603 return ast_sp;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000604 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000606 }
607 return lldb::TypeSystemSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000608}
609
Adrian Prantlaa97a892019-08-22 21:45:58 +0000610LanguageSet ClangASTContext::GetSupportedLanguagesForTypes() {
611 LanguageSet languages;
612 languages.Insert(lldb::eLanguageTypeC89);
613 languages.Insert(lldb::eLanguageTypeC);
614 languages.Insert(lldb::eLanguageTypeC11);
615 languages.Insert(lldb::eLanguageTypeC_plus_plus);
616 languages.Insert(lldb::eLanguageTypeC99);
617 languages.Insert(lldb::eLanguageTypeObjC);
618 languages.Insert(lldb::eLanguageTypeObjC_plus_plus);
619 languages.Insert(lldb::eLanguageTypeC_plus_plus_03);
620 languages.Insert(lldb::eLanguageTypeC_plus_plus_11);
621 languages.Insert(lldb::eLanguageTypeC11);
622 languages.Insert(lldb::eLanguageTypeC_plus_plus_14);
623 return languages;
624}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000625
Adrian Prantlaa97a892019-08-22 21:45:58 +0000626LanguageSet ClangASTContext::GetSupportedLanguagesForExpressions() {
627 LanguageSet languages;
628 languages.Insert(lldb::eLanguageTypeC_plus_plus);
629 languages.Insert(lldb::eLanguageTypeObjC_plus_plus);
630 languages.Insert(lldb::eLanguageTypeC_plus_plus_03);
631 languages.Insert(lldb::eLanguageTypeC_plus_plus_11);
632 languages.Insert(lldb::eLanguageTypeC_plus_plus_14);
633 return languages;
Enrico Granata5d84a692014-08-19 21:46:37 +0000634}
635
Kate Stoneb9c1b512016-09-06 20:57:50 +0000636void ClangASTContext::Initialize() {
Adrian Prantlaa97a892019-08-22 21:45:58 +0000637 PluginManager::RegisterPlugin(
638 GetPluginNameStatic(), "clang base AST context plug-in", CreateInstance,
639 GetSupportedLanguagesForTypes(), GetSupportedLanguagesForExpressions());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000640}
641
Kate Stoneb9c1b512016-09-06 20:57:50 +0000642void ClangASTContext::Terminate() {
643 PluginManager::UnregisterPlugin(CreateInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000644}
645
Kate Stoneb9c1b512016-09-06 20:57:50 +0000646void ClangASTContext::Finalize() {
Raphael Isemann2eb963a2019-10-02 12:26:08 +0000647 assert(m_ast_up);
648 GetASTMap().Erase(m_ast_up.get());
649 if (!m_ast_owned)
650 m_ast_up.release();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000652 m_builtins_up.reset();
653 m_selector_table_up.reset();
654 m_identifier_table_up.reset();
655 m_target_info_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000656 m_target_options_rp.reset();
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000657 m_diagnostics_engine_up.reset();
658 m_source_manager_up.reset();
659 m_language_options_up.reset();
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000660 m_scratch_ast_source_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000661}
662
663void ClangASTContext::Clear() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000664 m_language_options_up.reset();
665 m_source_manager_up.reset();
666 m_diagnostics_engine_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000667 m_target_options_rp.reset();
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000668 m_target_info_up.reset();
669 m_identifier_table_up.reset();
670 m_selector_table_up.reset();
671 m_builtins_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000672 m_pointer_byte_size = 0;
673}
674
Raphael Isemannf74a4c12019-04-30 08:41:35 +0000675void ClangASTContext::setSema(Sema *s) {
676 // Ensure that the new sema actually belongs to our ASTContext.
677 assert(s == nullptr || &s->getASTContext() == m_ast_up.get());
678 m_sema = s;
679}
680
Kate Stoneb9c1b512016-09-06 20:57:50 +0000681const char *ClangASTContext::GetTargetTriple() {
682 return m_target_triple.c_str();
683}
684
Raphael Isemannd01b4a72019-10-01 12:28:14 +0000685void ClangASTContext::SetTargetTriple(llvm::StringRef target_triple) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000686 Clear();
Raphael Isemannd01b4a72019-10-01 12:28:14 +0000687 m_target_triple = target_triple.str();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000688}
689
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690void ClangASTContext::SetExternalSource(
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000691 llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000692 ASTContext *ast = getASTContext();
693 if (ast) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000694 ast->setExternalSource(ast_source_up);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000695 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000696 }
697}
698
Kate Stoneb9c1b512016-09-06 20:57:50 +0000699ASTContext *ClangASTContext::getASTContext() {
Raphael Isemann2eb963a2019-10-02 12:26:08 +0000700 assert(m_ast_up);
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000701 return m_ast_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000702}
703
Raphael Isemann2eb963a2019-10-02 12:26:08 +0000704void ClangASTContext::CreateASTContext() {
705 assert(!m_ast_up);
706 m_ast_owned = true;
707 m_ast_up.reset(new ASTContext(*getLanguageOptions(), *getSourceManager(),
708 *getIdentifierTable(), *getSelectorTable(),
709 *getBuiltinContext()));
710
711 m_ast_up->getDiagnostics().setClient(getDiagnosticConsumer(), false);
712
713 // This can be NULL if we don't know anything about the architecture or if
714 // the target for an architecture isn't enabled in the llvm/clang that we
715 // built
716 TargetInfo *target_info = getTargetInfo();
717 if (target_info)
718 m_ast_up->InitBuiltinTypes(*target_info);
719
720 if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) {
721 m_ast_up->getTranslationUnitDecl()->setHasExternalLexicalStorage();
722 // m_ast_up->getTranslationUnitDecl()->setHasExternalVisibleStorage();
723 }
724
725 GetASTMap().Insert(m_ast_up.get(), this);
726
727 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_up(
728 new ClangExternalASTSourceCallbacks(
729 ClangASTContext::CompleteTagDecl,
730 ClangASTContext::CompleteObjCInterfaceDecl, nullptr,
731 ClangASTContext::LayoutRecordType, this));
732 SetExternalSource(ast_source_up);
733}
734
Kate Stoneb9c1b512016-09-06 20:57:50 +0000735ClangASTContext *ClangASTContext::GetASTContext(clang::ASTContext *ast) {
736 ClangASTContext *clang_ast = GetASTMap().Lookup(ast);
737 return clang_ast;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000738}
739
Kate Stoneb9c1b512016-09-06 20:57:50 +0000740Builtin::Context *ClangASTContext::getBuiltinContext() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000741 if (m_builtins_up == nullptr)
742 m_builtins_up.reset(new Builtin::Context());
743 return m_builtins_up.get();
Sean Callanan79439e82010-11-18 02:56:27 +0000744}
745
Kate Stoneb9c1b512016-09-06 20:57:50 +0000746IdentifierTable *ClangASTContext::getIdentifierTable() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000747 if (m_identifier_table_up == nullptr)
748 m_identifier_table_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000749 new IdentifierTable(*ClangASTContext::getLanguageOptions(), nullptr));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000750 return m_identifier_table_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000751}
752
Kate Stoneb9c1b512016-09-06 20:57:50 +0000753LangOptions *ClangASTContext::getLanguageOptions() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000754 if (m_language_options_up == nullptr) {
755 m_language_options_up.reset(new LangOptions());
Rainer Orth6ca17072019-08-05 14:00:43 +0000756 ParseLangArgs(*m_language_options_up, clang::Language::ObjCXX,
757 GetTargetTriple());
758 // InitializeLangOptions(*m_language_options_up, Language::ObjCXX);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000759 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000760 return m_language_options_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761}
762
Kate Stoneb9c1b512016-09-06 20:57:50 +0000763SelectorTable *ClangASTContext::getSelectorTable() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000764 if (m_selector_table_up == nullptr)
765 m_selector_table_up.reset(new SelectorTable());
766 return m_selector_table_up.get();
Greg Claytonfe689042015-11-10 17:47:04 +0000767}
768
Kate Stoneb9c1b512016-09-06 20:57:50 +0000769clang::FileManager *ClangASTContext::getFileManager() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000770 if (m_file_manager_up == nullptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000771 clang::FileSystemOptions file_system_options;
Jonas Devlieghere9764b652019-02-18 20:31:18 +0000772 m_file_manager_up.reset(new clang::FileManager(
773 file_system_options, FileSystem::Instance().GetVirtualFileSystem()));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000774 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000775 return m_file_manager_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000776}
777
778clang::SourceManager *ClangASTContext::getSourceManager() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000779 if (m_source_manager_up == nullptr)
780 m_source_manager_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000781 new clang::SourceManager(*getDiagnosticsEngine(), *getFileManager()));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000782 return m_source_manager_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000783}
784
785clang::DiagnosticsEngine *ClangASTContext::getDiagnosticsEngine() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000786 if (m_diagnostics_engine_up == nullptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000787 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000788 m_diagnostics_engine_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000789 new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions()));
790 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000791 return m_diagnostics_engine_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000792}
793
794clang::MangleContext *ClangASTContext::getMangleContext() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000795 if (m_mangle_ctx_up == nullptr)
796 m_mangle_ctx_up.reset(getASTContext()->createMangleContext());
797 return m_mangle_ctx_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000798}
799
800class NullDiagnosticConsumer : public DiagnosticConsumer {
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000801public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000802 NullDiagnosticConsumer() {
803 m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
804 }
Sean Callanan579e70c2016-03-19 00:03:59 +0000805
Kate Stoneb9c1b512016-09-06 20:57:50 +0000806 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
Raphael Isemann17566302019-05-03 10:03:28 +0000807 const clang::Diagnostic &info) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000808 if (m_log) {
809 llvm::SmallVector<char, 32> diag_str(10);
810 info.FormatDiagnostic(diag_str);
811 diag_str.push_back('\0');
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000812 LLDB_LOGF(m_log, "Compiler diagnostic: %s\n", diag_str.data());
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000813 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000814 }
815
816 DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
817 return new NullDiagnosticConsumer();
818 }
819
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000820private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000821 Log *m_log;
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000822};
823
Kate Stoneb9c1b512016-09-06 20:57:50 +0000824DiagnosticConsumer *ClangASTContext::getDiagnosticConsumer() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000825 if (m_diagnostic_consumer_up == nullptr)
826 m_diagnostic_consumer_up.reset(new NullDiagnosticConsumer);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000827
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000828 return m_diagnostic_consumer_up.get();
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000829}
830
Kate Stoneb9c1b512016-09-06 20:57:50 +0000831std::shared_ptr<clang::TargetOptions> &ClangASTContext::getTargetOptions() {
Jonas Devlieghere70355ac2019-02-12 03:47:39 +0000832 if (m_target_options_rp == nullptr && !m_target_triple.empty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000833 m_target_options_rp = std::make_shared<clang::TargetOptions>();
Jonas Devlieghere70355ac2019-02-12 03:47:39 +0000834 if (m_target_options_rp != nullptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000835 m_target_options_rp->Triple = m_target_triple;
836 }
837 return m_target_options_rp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000838}
839
Kate Stoneb9c1b512016-09-06 20:57:50 +0000840TargetInfo *ClangASTContext::getTargetInfo() {
841 // target_triple should be something like "x86_64-apple-macosx"
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000842 if (m_target_info_up == nullptr && !m_target_triple.empty())
843 m_target_info_up.reset(TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000844 getTargetOptions()));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000845 return m_target_info_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000846}
847
848#pragma mark Basic Types
849
Kate Stoneb9c1b512016-09-06 20:57:50 +0000850static inline bool QualTypeMatchesBitSize(const uint64_t bit_size,
851 ASTContext *ast, QualType qual_type) {
852 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000853 return qual_type_bit_size == bit_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000854}
Greg Clayton56939cb2015-09-17 22:23:34 +0000855
Greg Claytona1e5dc82015-08-11 22:53:00 +0000856CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000857ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
858 size_t bit_size) {
859 return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
860 getASTContext(), encoding, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000861}
862
Kate Stoneb9c1b512016-09-06 20:57:50 +0000863CompilerType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
864 ASTContext *ast, Encoding encoding, uint32_t bit_size) {
Alex Langfordbddab072019-08-13 19:40:36 +0000865 auto *clang_ast_context = ClangASTContext::GetASTContext(ast);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000866 if (!ast)
Greg Claytona1e5dc82015-08-11 22:53:00 +0000867 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000868 switch (encoding) {
869 case eEncodingInvalid:
870 if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000871 return CompilerType(clang_ast_context, ast->VoidPtrTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872 break;
873
874 case eEncodingUint:
875 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000876 return CompilerType(clang_ast_context,
877 ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000878 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000879 return CompilerType(clang_ast_context,
880 ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000881 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000882 return CompilerType(clang_ast_context,
883 ast->UnsignedIntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000884 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000885 return CompilerType(clang_ast_context,
886 ast->UnsignedLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000887 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000888 return CompilerType(clang_ast_context,
889 ast->UnsignedLongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000890 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +0000891 return CompilerType(clang_ast_context,
892 ast->UnsignedInt128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000893 break;
894
895 case eEncodingSint:
896 if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000897 return CompilerType(clang_ast_context,
898 ast->SignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000899 if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000900 return CompilerType(clang_ast_context, ast->ShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000901 if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000902 return CompilerType(clang_ast_context, ast->IntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000903 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000904 return CompilerType(clang_ast_context, ast->LongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000905 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000906 return CompilerType(clang_ast_context, ast->LongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000907 if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +0000908 return CompilerType(clang_ast_context, ast->Int128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000909 break;
910
911 case eEncodingIEEE754:
912 if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000913 return CompilerType(clang_ast_context, ast->FloatTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000914 if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000915 return CompilerType(clang_ast_context, ast->DoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000916 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000917 return CompilerType(clang_ast_context,
918 ast->LongDoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919 if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000920 return CompilerType(clang_ast_context, ast->HalfTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000921 break;
922
923 case eEncodingVector:
924 // Sanity check that bit_size is a multiple of 8's.
925 if (bit_size && !(bit_size & 0x7u))
926 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +0000927 clang_ast_context,
928 ast->getExtVectorType(ast->UnsignedCharTy, bit_size / 8)
929 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000930 break;
931 }
932
933 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934}
935
Greg Clayton57ee3062013-07-11 22:46:58 +0000936lldb::BasicType
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000937ClangASTContext::GetBasicTypeEnumeration(ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000938 if (name) {
939 typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
940 static TypeNameToBasicTypeMap g_type_map;
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000941 static llvm::once_flag g_once_flag;
942 llvm::call_once(g_once_flag, []() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000943 // "void"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000944 g_type_map.Append(ConstString("void"), eBasicTypeVoid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000945
946 // "char"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000947 g_type_map.Append(ConstString("char"), eBasicTypeChar);
948 g_type_map.Append(ConstString("signed char"), eBasicTypeSignedChar);
949 g_type_map.Append(ConstString("unsigned char"), eBasicTypeUnsignedChar);
950 g_type_map.Append(ConstString("wchar_t"), eBasicTypeWChar);
951 g_type_map.Append(ConstString("signed wchar_t"), eBasicTypeSignedWChar);
952 g_type_map.Append(ConstString("unsigned wchar_t"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000953 eBasicTypeUnsignedWChar);
954 // "short"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000955 g_type_map.Append(ConstString("short"), eBasicTypeShort);
956 g_type_map.Append(ConstString("short int"), eBasicTypeShort);
957 g_type_map.Append(ConstString("unsigned short"), eBasicTypeUnsignedShort);
958 g_type_map.Append(ConstString("unsigned short int"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000959 eBasicTypeUnsignedShort);
960
961 // "int"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000962 g_type_map.Append(ConstString("int"), eBasicTypeInt);
963 g_type_map.Append(ConstString("signed int"), eBasicTypeInt);
964 g_type_map.Append(ConstString("unsigned int"), eBasicTypeUnsignedInt);
965 g_type_map.Append(ConstString("unsigned"), eBasicTypeUnsignedInt);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000966
967 // "long"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000968 g_type_map.Append(ConstString("long"), eBasicTypeLong);
969 g_type_map.Append(ConstString("long int"), eBasicTypeLong);
970 g_type_map.Append(ConstString("unsigned long"), eBasicTypeUnsignedLong);
971 g_type_map.Append(ConstString("unsigned long int"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000972 eBasicTypeUnsignedLong);
973
974 // "long long"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000975 g_type_map.Append(ConstString("long long"), eBasicTypeLongLong);
976 g_type_map.Append(ConstString("long long int"), eBasicTypeLongLong);
977 g_type_map.Append(ConstString("unsigned long long"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000978 eBasicTypeUnsignedLongLong);
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000979 g_type_map.Append(ConstString("unsigned long long int"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000980 eBasicTypeUnsignedLongLong);
981
982 // "int128"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000983 g_type_map.Append(ConstString("__int128_t"), eBasicTypeInt128);
984 g_type_map.Append(ConstString("__uint128_t"), eBasicTypeUnsignedInt128);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000985
986 // Miscellaneous
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000987 g_type_map.Append(ConstString("bool"), eBasicTypeBool);
988 g_type_map.Append(ConstString("float"), eBasicTypeFloat);
989 g_type_map.Append(ConstString("double"), eBasicTypeDouble);
990 g_type_map.Append(ConstString("long double"), eBasicTypeLongDouble);
991 g_type_map.Append(ConstString("id"), eBasicTypeObjCID);
992 g_type_map.Append(ConstString("SEL"), eBasicTypeObjCSel);
993 g_type_map.Append(ConstString("nullptr"), eBasicTypeNullPtr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000994 g_type_map.Sort();
995 });
996
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000997 return g_type_map.Find(name, eBasicTypeInvalid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000998 }
999 return eBasicTypeInvalid;
Greg Clayton57ee3062013-07-11 22:46:58 +00001000}
1001
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
Adrian Prantl0e4c4822019-03-06 21:22:25 +00001003 ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001004 if (ast) {
1005 lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration(name);
1006 return ClangASTContext::GetBasicType(ast, basic_type);
1007 }
1008 return CompilerType();
1009}
1010
1011uint32_t ClangASTContext::GetPointerByteSize() {
1012 if (m_pointer_byte_size == 0)
Adrian Prantld963a7c2019-01-15 18:07:52 +00001013 if (auto size = GetBasicType(lldb::eBasicTypeVoid)
1014 .GetPointerType()
1015 .GetByteSize(nullptr))
1016 m_pointer_byte_size = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001017 return m_pointer_byte_size;
1018}
1019
1020CompilerType ClangASTContext::GetBasicType(lldb::BasicType basic_type) {
1021 return GetBasicType(getASTContext(), basic_type);
1022}
1023
1024CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
1025 lldb::BasicType basic_type) {
1026 if (!ast)
Greg Claytona1e5dc82015-08-11 22:53:00 +00001027 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001028 lldb::opaque_compiler_type_t clang_type =
1029 GetOpaqueCompilerType(ast, basic_type);
1030
1031 if (clang_type)
1032 return CompilerType(GetASTContext(ast), clang_type);
1033 return CompilerType();
Greg Clayton57ee3062013-07-11 22:46:58 +00001034}
1035
Kate Stoneb9c1b512016-09-06 20:57:50 +00001036CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
1037 const char *type_name, uint32_t dw_ate, uint32_t bit_size) {
1038 ASTContext *ast = getASTContext();
Greg Clayton57ee3062013-07-11 22:46:58 +00001039
Kate Stoneb9c1b512016-09-06 20:57:50 +00001040#define streq(a, b) strcmp(a, b) == 0
1041 assert(ast != nullptr);
1042 if (ast) {
1043 switch (dw_ate) {
1044 default:
1045 break;
Greg Clayton57ee3062013-07-11 22:46:58 +00001046
Kate Stoneb9c1b512016-09-06 20:57:50 +00001047 case DW_ATE_address:
1048 if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001049 return CompilerType(this, ast->VoidPtrTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001050 break;
Zachary Turner9d8a97e2016-04-01 23:20:35 +00001051
Kate Stoneb9c1b512016-09-06 20:57:50 +00001052 case DW_ATE_boolean:
1053 if (QualTypeMatchesBitSize(bit_size, ast, ast->BoolTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001054 return CompilerType(this, ast->BoolTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001055 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001056 return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001057 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001058 return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001059 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001060 return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001061 break;
Greg Clayton57ee3062013-07-11 22:46:58 +00001062
Kate Stoneb9c1b512016-09-06 20:57:50 +00001063 case DW_ATE_lo_user:
1064 // This has been seen to mean DW_AT_complex_integer
1065 if (type_name) {
1066 if (::strstr(type_name, "complex")) {
1067 CompilerType complex_int_clang_type =
1068 GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed,
1069 bit_size / 2);
Alex Langfordbddab072019-08-13 19:40:36 +00001070 return CompilerType(
1071 this, ast->getComplexType(
1072 ClangUtil::GetQualType(complex_int_clang_type))
1073 .getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001075 }
1076 break;
1077
1078 case DW_ATE_complex_float:
1079 if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatComplexTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001080 return CompilerType(this, ast->FloatComplexTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001081 else if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleComplexTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001082 return CompilerType(this, ast->DoubleComplexTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083 else if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleComplexTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001084 return CompilerType(this, ast->LongDoubleComplexTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001085 else {
1086 CompilerType complex_float_clang_type =
1087 GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float,
1088 bit_size / 2);
Alex Langfordbddab072019-08-13 19:40:36 +00001089 return CompilerType(
1090 this, ast->getComplexType(
1091 ClangUtil::GetQualType(complex_float_clang_type))
1092 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 }
1094 break;
1095
1096 case DW_ATE_float:
1097 if (streq(type_name, "float") &&
1098 QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001099 return CompilerType(this, ast->FloatTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001100 if (streq(type_name, "double") &&
1101 QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001102 return CompilerType(this, ast->DoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001103 if (streq(type_name, "long double") &&
1104 QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001105 return CompilerType(this, ast->LongDoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001106 // Fall back to not requiring a name match
1107 if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001108 return CompilerType(this, ast->FloatTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001109 if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001110 return CompilerType(this, ast->DoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001111 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001112 return CompilerType(this, ast->LongDoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001113 if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001114 return CompilerType(this, ast->HalfTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001115 break;
1116
1117 case DW_ATE_signed:
1118 if (type_name) {
1119 if (streq(type_name, "wchar_t") &&
1120 QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy) &&
1121 (getTargetInfo() &&
1122 TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
Alex Langfordbddab072019-08-13 19:40:36 +00001123 return CompilerType(this, ast->WCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001124 if (streq(type_name, "void") &&
1125 QualTypeMatchesBitSize(bit_size, ast, ast->VoidTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001126 return CompilerType(this, ast->VoidTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001127 if (strstr(type_name, "long long") &&
1128 QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001129 return CompilerType(this, ast->LongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001130 if (strstr(type_name, "long") &&
1131 QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001132 return CompilerType(this, ast->LongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001133 if (strstr(type_name, "short") &&
1134 QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001135 return CompilerType(this, ast->ShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136 if (strstr(type_name, "char")) {
1137 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001138 return CompilerType(this, ast->CharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001139 if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001140 return CompilerType(this, ast->SignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001141 }
1142 if (strstr(type_name, "int")) {
1143 if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001144 return CompilerType(this, ast->IntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145 if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00001146 return CompilerType(this, ast->Int128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001147 }
1148 }
1149 // We weren't able to match up a type name, just search by size
1150 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001151 return CompilerType(this, ast->CharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001152 if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001153 return CompilerType(this, ast->ShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154 if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001155 return CompilerType(this, ast->IntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001156 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001157 return CompilerType(this, ast->LongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001158 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001159 return CompilerType(this, ast->LongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001160 if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00001161 return CompilerType(this, ast->Int128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001162 break;
1163
1164 case DW_ATE_signed_char:
1165 if (ast->getLangOpts().CharIsSigned && type_name &&
1166 streq(type_name, "char")) {
1167 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001168 return CompilerType(this, ast->CharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001169 }
1170 if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001171 return CompilerType(this, ast->SignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001172 break;
1173
1174 case DW_ATE_unsigned:
1175 if (type_name) {
1176 if (streq(type_name, "wchar_t")) {
1177 if (QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy)) {
1178 if (!(getTargetInfo() &&
1179 TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
Alex Langfordbddab072019-08-13 19:40:36 +00001180 return CompilerType(this, ast->WCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001181 }
1182 }
1183 if (strstr(type_name, "long long")) {
1184 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001185 return CompilerType(this, ast->UnsignedLongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001186 } else if (strstr(type_name, "long")) {
1187 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001188 return CompilerType(this, ast->UnsignedLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001189 } else if (strstr(type_name, "short")) {
1190 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001191 return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001192 } else if (strstr(type_name, "char")) {
1193 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001194 return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001195 } else if (strstr(type_name, "int")) {
1196 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001197 return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001198 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00001199 return CompilerType(this, ast->UnsignedInt128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001200 }
1201 }
1202 // We weren't able to match up a type name, just search by size
1203 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001204 return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001205 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001206 return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001207 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001208 return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001209 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001210 return CompilerType(this, ast->UnsignedLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001211 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001212 return CompilerType(this, ast->UnsignedLongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001213 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00001214 return CompilerType(this, ast->UnsignedInt128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001215 break;
1216
1217 case DW_ATE_unsigned_char:
1218 if (!ast->getLangOpts().CharIsSigned && type_name &&
1219 streq(type_name, "char")) {
1220 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001221 return CompilerType(this, ast->CharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001222 }
1223 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001224 return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001225 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001226 return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001227 break;
1228
1229 case DW_ATE_imaginary_float:
1230 break;
1231
1232 case DW_ATE_UTF:
1233 if (type_name) {
Jonas Devliegherec46d39b2019-08-21 21:30:55 +00001234 if (streq(type_name, "char16_t"))
Alex Langfordbddab072019-08-13 19:40:36 +00001235 return CompilerType(this, ast->Char16Ty.getAsOpaquePtr());
Jonas Devlieghere6c9dc122019-08-23 04:11:38 +00001236 if (streq(type_name, "char32_t"))
Alex Langfordbddab072019-08-13 19:40:36 +00001237 return CompilerType(this, ast->Char32Ty.getAsOpaquePtr());
Jonas Devlieghere6c9dc122019-08-23 04:11:38 +00001238 if (streq(type_name, "char8_t"))
Jonas Devliegherec46d39b2019-08-21 21:30:55 +00001239 return CompilerType(this, ast->Char8Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001240 }
1241 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001242 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001243 }
1244 // This assert should fire for anything that we don't catch above so we know
1245 // to fix any issues we run into.
1246 if (type_name) {
1247 Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
1248 "DW_TAG_base_type '%s' encoded with "
1249 "DW_ATE = 0x%x, bit_size = %u\n",
1250 type_name, dw_ate, bit_size);
1251 } else {
1252 Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
1253 "DW_TAG_base_type encoded with "
1254 "DW_ATE = 0x%x, bit_size = %u\n",
1255 dw_ate, bit_size);
1256 }
1257 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001258}
1259
Kate Stoneb9c1b512016-09-06 20:57:50 +00001260CompilerType ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast) {
1261 if (ast)
Alex Langfordbddab072019-08-13 19:40:36 +00001262 return CompilerType(ClangASTContext::GetASTContext(ast),
1263 ast->UnknownAnyTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001264 return CompilerType();
Sean Callanan77502262011-05-12 23:54:16 +00001265}
1266
Kate Stoneb9c1b512016-09-06 20:57:50 +00001267CompilerType ClangASTContext::GetCStringType(bool is_const) {
1268 ASTContext *ast = getASTContext();
1269 QualType char_type(ast->CharTy);
1270
1271 if (is_const)
1272 char_type.addConst();
1273
Alex Langfordbddab072019-08-13 19:40:36 +00001274 return CompilerType(this, ast->getPointerType(char_type).getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001275}
1276
Zachary Turner115209e2018-11-05 19:25:39 +00001277clang::DeclContext *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001278ClangASTContext::GetTranslationUnitDecl(clang::ASTContext *ast) {
1279 return ast->getTranslationUnitDecl();
Sean Callanan09ab4b72011-11-30 22:11:59 +00001280}
1281
Kate Stoneb9c1b512016-09-06 20:57:50 +00001282clang::Decl *ClangASTContext::CopyDecl(ASTContext *dst_ast, ASTContext *src_ast,
1283 clang::Decl *source_decl) {
1284 FileSystemOptions file_system_options;
1285 FileManager file_manager(file_system_options);
1286 ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager, false);
1287
Gabor Marton5ac6d492019-05-15 10:29:48 +00001288 if (llvm::Expected<clang::Decl *> ret_or_error =
1289 importer.Import(source_decl)) {
1290 return *ret_or_error;
1291 } else {
1292 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
1293 LLDB_LOG_ERROR(log, ret_or_error.takeError(), "Couldn't import decl: {0}");
1294 return nullptr;
1295 }
Greg Clayton526e5af2010-11-13 03:52:47 +00001296}
1297
Kate Stoneb9c1b512016-09-06 20:57:50 +00001298bool ClangASTContext::AreTypesSame(CompilerType type1, CompilerType type2,
1299 bool ignore_qualifiers) {
1300 ClangASTContext *ast =
1301 llvm::dyn_cast_or_null<ClangASTContext>(type1.GetTypeSystem());
1302 if (!ast || ast != type2.GetTypeSystem())
1303 return false;
Greg Clayton57ee3062013-07-11 22:46:58 +00001304
Kate Stoneb9c1b512016-09-06 20:57:50 +00001305 if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
1306 return true;
Greg Clayton55995eb2012-04-06 17:38:55 +00001307
Kate Stoneb9c1b512016-09-06 20:57:50 +00001308 QualType type1_qual = ClangUtil::GetQualType(type1);
1309 QualType type2_qual = ClangUtil::GetQualType(type2);
Zachary Turnerd133f6a2016-03-28 22:53:41 +00001310
Kate Stoneb9c1b512016-09-06 20:57:50 +00001311 if (ignore_qualifiers) {
1312 type1_qual = type1_qual.getUnqualifiedType();
1313 type2_qual = type2_qual.getUnqualifiedType();
1314 }
1315
1316 return ast->getASTContext()->hasSameType(type1_qual, type2_qual);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001317}
1318
Alex Langfordcb68bd72019-08-23 06:11:32 +00001319CompilerType ClangASTContext::GetTypeForDecl(void *opaque_decl) {
1320 if (!opaque_decl)
1321 return CompilerType();
1322
1323 clang::Decl *decl = static_cast<clang::Decl *>(opaque_decl);
1324 if (auto *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl))
1325 return GetTypeForDecl(named_decl);
1326 return CompilerType();
1327}
1328
Kate Stoneb9c1b512016-09-06 20:57:50 +00001329CompilerType ClangASTContext::GetTypeForDecl(clang::NamedDecl *decl) {
1330 if (clang::ObjCInterfaceDecl *interface_decl =
1331 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
1332 return GetTypeForDecl(interface_decl);
1333 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
1334 return GetTypeForDecl(tag_decl);
1335 return CompilerType();
Sean Callanan9998acd2014-12-05 01:21:59 +00001336}
1337
Kate Stoneb9c1b512016-09-06 20:57:50 +00001338CompilerType ClangASTContext::GetTypeForDecl(TagDecl *decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00001339 // No need to call the getASTContext() accessor (which can create the AST if
1340 // it isn't created yet, because we can't have created a decl in this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001341 // AST if our AST didn't already exist...
1342 ASTContext *ast = &decl->getASTContext();
1343 if (ast)
Alex Langfordbddab072019-08-13 19:40:36 +00001344 return CompilerType(ClangASTContext::GetASTContext(ast),
1345 ast->getTagDeclType(decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001346 return CompilerType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00001347}
1348
Kate Stoneb9c1b512016-09-06 20:57:50 +00001349CompilerType ClangASTContext::GetTypeForDecl(ObjCInterfaceDecl *decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00001350 // No need to call the getASTContext() accessor (which can create the AST if
1351 // it isn't created yet, because we can't have created a decl in this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001352 // AST if our AST didn't already exist...
1353 ASTContext *ast = &decl->getASTContext();
1354 if (ast)
Alex Langfordbddab072019-08-13 19:40:36 +00001355 return CompilerType(ClangASTContext::GetASTContext(ast),
1356 ast->getObjCInterfaceType(decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001357 return CompilerType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00001358}
1359
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001360#pragma mark Structure, Unions, Classes
1361
Kate Stoneb9c1b512016-09-06 20:57:50 +00001362CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx,
1363 AccessType access_type,
1364 const char *name, int kind,
1365 LanguageType language,
1366 ClangASTMetadata *metadata) {
1367 ASTContext *ast = getASTContext();
1368 assert(ast != nullptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001369
Kate Stoneb9c1b512016-09-06 20:57:50 +00001370 if (decl_ctx == nullptr)
1371 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton9e409562010-07-28 02:04:09 +00001372
Kate Stoneb9c1b512016-09-06 20:57:50 +00001373 if (language == eLanguageTypeObjC ||
1374 language == eLanguageTypeObjC_plus_plus) {
1375 bool isForwardDecl = true;
1376 bool isInternal = false;
1377 return CreateObjCClass(name, decl_ctx, isForwardDecl, isInternal, metadata);
1378 }
Greg Clayton9e409562010-07-28 02:04:09 +00001379
Kate Stoneb9c1b512016-09-06 20:57:50 +00001380 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
Adrian Prantl05097242018-04-30 16:49:04 +00001381 // we will need to update this code. I was told to currently always use the
1382 // CXXRecordDecl class since we often don't know from debug information if
1383 // something is struct or a class, so we default to always use the more
Kate Stoneb9c1b512016-09-06 20:57:50 +00001384 // complete definition just in case.
Greg Claytonc4ffd662013-03-08 01:37:30 +00001385
Shafik Yaghmour62abe492019-08-14 22:30:29 +00001386 bool has_name = name && name[0];
Greg Claytonc4ffd662013-03-08 01:37:30 +00001387
Kate Stoneb9c1b512016-09-06 20:57:50 +00001388 CXXRecordDecl *decl = CXXRecordDecl::Create(
1389 *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
Shafik Yaghmour62abe492019-08-14 22:30:29 +00001390 SourceLocation(), has_name ? &ast->Idents.get(name) : nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001391
Shafik Yaghmour62abe492019-08-14 22:30:29 +00001392 if (!has_name) {
1393 // In C++ a lambda is also represented as an unnamed class. This is
1394 // different from an *anonymous class* that the user wrote:
1395 //
1396 // struct A {
1397 // // anonymous class (GNU/MSVC extension)
1398 // struct {
1399 // int x;
1400 // };
1401 // // unnamed class within a class
1402 // struct {
1403 // int y;
1404 // } B;
1405 // };
1406 //
1407 // void f() {
1408 // // unammed class outside of a class
1409 // struct {
1410 // int z;
1411 // } C;
1412 // }
1413 //
1414 // Anonymous classes is a GNU/MSVC extension that clang supports. It
1415 // requires the anonymous class be embedded within a class. So the new
1416 // heuristic verifies this condition.
1417 //
1418 // FIXME: An unnamed class within a class is also wrongly recognized as an
1419 // anonymous struct.
Pavel Labath9cb31792019-08-21 08:22:19 +00001420 if (isa<CXXRecordDecl>(decl_ctx))
Shafik Yaghmour62abe492019-08-14 22:30:29 +00001421 decl->setAnonymousStructOrUnion(true);
Shafik Yaghmour62abe492019-08-14 22:30:29 +00001422 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001423
1424 if (decl) {
1425 if (metadata)
1426 SetMetadata(ast, decl, *metadata);
1427
1428 if (access_type != eAccessNone)
1429 decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type));
1430
1431 if (decl_ctx)
1432 decl_ctx->addDecl(decl);
1433
Alex Langfordbddab072019-08-13 19:40:36 +00001434 return CompilerType(this, ast->getTagDeclType(decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001435 }
1436 return CompilerType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00001437}
1438
Sean Callanan09e91ac2017-05-11 22:08:05 +00001439namespace {
1440 bool IsValueParam(const clang::TemplateArgument &argument) {
1441 return argument.getKind() == TemplateArgument::Integral;
1442 }
1443}
1444
Kate Stoneb9c1b512016-09-06 20:57:50 +00001445static TemplateParameterList *CreateTemplateParameterList(
1446 ASTContext *ast,
1447 const ClangASTContext::TemplateParameterInfos &template_param_infos,
1448 llvm::SmallVector<NamedDecl *, 8> &template_param_decls) {
1449 const bool parameter_pack = false;
1450 const bool is_typename = false;
1451 const unsigned depth = 0;
Sean Callanan09e91ac2017-05-11 22:08:05 +00001452 const size_t num_template_params = template_param_infos.args.size();
1453 DeclContext *const decl_context =
1454 ast->getTranslationUnitDecl(); // Is this the right decl context?,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001455 for (size_t i = 0; i < num_template_params; ++i) {
1456 const char *name = template_param_infos.names[i];
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001457
Kate Stoneb9c1b512016-09-06 20:57:50 +00001458 IdentifierInfo *identifier_info = nullptr;
1459 if (name && name[0])
1460 identifier_info = &ast->Idents.get(name);
Sean Callanan09e91ac2017-05-11 22:08:05 +00001461 if (IsValueParam(template_param_infos.args[i])) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001462 template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
Sean Callanan09e91ac2017-05-11 22:08:05 +00001463 *ast, decl_context,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001464 SourceLocation(), SourceLocation(), depth, i, identifier_info,
1465 template_param_infos.args[i].getIntegralType(), parameter_pack,
1466 nullptr));
1467
1468 } else {
1469 template_param_decls.push_back(TemplateTypeParmDecl::Create(
Sean Callanan09e91ac2017-05-11 22:08:05 +00001470 *ast, decl_context,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001471 SourceLocation(), SourceLocation(), depth, i, identifier_info,
1472 is_typename, parameter_pack));
1473 }
1474 }
Eugene Zemtsova9d928c2017-09-29 03:15:08 +00001475
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001476 if (template_param_infos.packed_args) {
Sean Callanan09e91ac2017-05-11 22:08:05 +00001477 IdentifierInfo *identifier_info = nullptr;
1478 if (template_param_infos.pack_name && template_param_infos.pack_name[0])
1479 identifier_info = &ast->Idents.get(template_param_infos.pack_name);
1480 const bool parameter_pack_true = true;
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001481
1482 if (!template_param_infos.packed_args->args.empty() &&
1483 IsValueParam(template_param_infos.packed_args->args[0])) {
Sean Callanan09e91ac2017-05-11 22:08:05 +00001484 template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001485 *ast, decl_context, SourceLocation(), SourceLocation(), depth,
1486 num_template_params, identifier_info,
Sean Callanan09e91ac2017-05-11 22:08:05 +00001487 template_param_infos.packed_args->args[0].getIntegralType(),
1488 parameter_pack_true, nullptr));
1489 } else {
1490 template_param_decls.push_back(TemplateTypeParmDecl::Create(
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001491 *ast, decl_context, SourceLocation(), SourceLocation(), depth,
1492 num_template_params, identifier_info, is_typename,
1493 parameter_pack_true));
Sean Callanan09e91ac2017-05-11 22:08:05 +00001494 }
1495 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001496 clang::Expr *const requires_clause = nullptr; // TODO: Concepts
1497 TemplateParameterList *template_param_list = TemplateParameterList::Create(
1498 *ast, SourceLocation(), SourceLocation(), template_param_decls,
1499 SourceLocation(), requires_clause);
1500 return template_param_list;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001501}
1502
Kate Stoneb9c1b512016-09-06 20:57:50 +00001503clang::FunctionTemplateDecl *ClangASTContext::CreateFunctionTemplateDecl(
1504 clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl,
1505 const char *name, const TemplateParameterInfos &template_param_infos) {
Adrian Prantld8f460e2018-05-02 16:55:16 +00001506 // /// Create a function template node.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001507 ASTContext *ast = getASTContext();
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001508
Kate Stoneb9c1b512016-09-06 20:57:50 +00001509 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001510
Kate Stoneb9c1b512016-09-06 20:57:50 +00001511 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1512 ast, template_param_infos, template_param_decls);
1513 FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create(
1514 *ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(),
1515 template_param_list, func_decl);
1516
1517 for (size_t i = 0, template_param_decl_count = template_param_decls.size();
1518 i < template_param_decl_count; ++i) {
1519 // TODO: verify which decl context we should put template_param_decls into..
1520 template_param_decls[i]->setDeclContext(func_decl);
1521 }
1522
1523 return func_tmpl_decl;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001524}
1525
Kate Stoneb9c1b512016-09-06 20:57:50 +00001526void ClangASTContext::CreateFunctionTemplateSpecializationInfo(
1527 FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl,
1528 const TemplateParameterInfos &infos) {
Shafik Yaghmoura0858e22019-07-17 20:16:13 +00001529 TemplateArgumentList *template_args_ptr =
1530 TemplateArgumentList::CreateCopy(func_decl->getASTContext(), infos.args);
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001531
Shafik Yaghmoura0858e22019-07-17 20:16:13 +00001532 func_decl->setFunctionTemplateSpecialization(func_tmpl_decl,
1533 template_args_ptr, nullptr);
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001534}
1535
Kate Stoneb9c1b512016-09-06 20:57:50 +00001536ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl(
1537 DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name,
1538 int kind, const TemplateParameterInfos &template_param_infos) {
1539 ASTContext *ast = getASTContext();
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001540
Kate Stoneb9c1b512016-09-06 20:57:50 +00001541 ClassTemplateDecl *class_template_decl = nullptr;
1542 if (decl_ctx == nullptr)
1543 decl_ctx = ast->getTranslationUnitDecl();
Greg Claytonf0705c82011-10-22 03:33:13 +00001544
Kate Stoneb9c1b512016-09-06 20:57:50 +00001545 IdentifierInfo &identifier_info = ast->Idents.get(class_name);
1546 DeclarationName decl_name(&identifier_info);
Greg Claytonf0705c82011-10-22 03:33:13 +00001547
Kate Stoneb9c1b512016-09-06 20:57:50 +00001548 clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
Greg Claytonf0705c82011-10-22 03:33:13 +00001549
Kate Stoneb9c1b512016-09-06 20:57:50 +00001550 for (NamedDecl *decl : result) {
1551 class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
Greg Claytonf0705c82011-10-22 03:33:13 +00001552 if (class_template_decl)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001553 return class_template_decl;
1554 }
1555
1556 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
1557
1558 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1559 ast, template_param_infos, template_param_decls);
1560
1561 CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create(
1562 *ast, (TagDecl::TagKind)kind,
1563 decl_ctx, // What decl context do we use here? TU? The actual decl
1564 // context?
1565 SourceLocation(), SourceLocation(), &identifier_info);
1566
1567 for (size_t i = 0, template_param_decl_count = template_param_decls.size();
1568 i < template_param_decl_count; ++i) {
1569 template_param_decls[i]->setDeclContext(template_cxx_decl);
1570 }
1571
1572 // With templated classes, we say that a class is templated with
1573 // specializations, but that the bare class has no functions.
1574 // template_cxx_decl->startDefinition();
1575 // template_cxx_decl->completeDefinition();
1576
1577 class_template_decl = ClassTemplateDecl::Create(
1578 *ast,
1579 decl_ctx, // What decl context do we use here? TU? The actual decl
1580 // context?
Pavel Labath4294de32017-01-12 10:44:16 +00001581 SourceLocation(), decl_name, template_param_list, template_cxx_decl);
Richard Smith35b007e2019-02-15 21:48:09 +00001582 template_cxx_decl->setDescribedClassTemplate(class_template_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001583
1584 if (class_template_decl) {
1585 if (access_type != eAccessNone)
1586 class_template_decl->setAccess(
1587 ConvertAccessTypeToAccessSpecifier(access_type));
1588
1589 // if (TagDecl *ctx_tag_decl = dyn_cast<TagDecl>(decl_ctx))
1590 // CompleteTagDeclarationDefinition(GetTypeForDecl(ctx_tag_decl));
1591
1592 decl_ctx->addDecl(class_template_decl);
1593
Sean Callanan5e9e1992011-10-26 01:06:27 +00001594#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00001595 VerifyDecl(class_template_decl);
Sean Callanan5e9e1992011-10-26 01:06:27 +00001596#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00001597 }
Greg Claytonf0705c82011-10-22 03:33:13 +00001598
Kate Stoneb9c1b512016-09-06 20:57:50 +00001599 return class_template_decl;
Greg Claytonf0705c82011-10-22 03:33:13 +00001600}
1601
Frederic Rissf4e7e522018-04-02 16:18:32 +00001602TemplateTemplateParmDecl *
1603ClangASTContext::CreateTemplateTemplateParmDecl(const char *template_name) {
1604 ASTContext *ast = getASTContext();
1605
1606 auto *decl_ctx = ast->getTranslationUnitDecl();
1607
1608 IdentifierInfo &identifier_info = ast->Idents.get(template_name);
1609 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
1610
1611 ClangASTContext::TemplateParameterInfos template_param_infos;
1612 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1613 ast, template_param_infos, template_param_decls);
1614
1615 // LLDB needs to create those decls only to be able to display a
Adrian Prantl05097242018-04-30 16:49:04 +00001616 // type that includes a template template argument. Only the name matters for
1617 // this purpose, so we use dummy values for the other characterisitcs of the
1618 // type.
Frederic Rissf4e7e522018-04-02 16:18:32 +00001619 return TemplateTemplateParmDecl::Create(
1620 *ast, decl_ctx, SourceLocation(),
1621 /*Depth*/ 0, /*Position*/ 0,
1622 /*IsParameterPack*/ false, &identifier_info, template_param_list);
1623}
1624
Greg Claytonf0705c82011-10-22 03:33:13 +00001625ClassTemplateSpecializationDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001626ClangASTContext::CreateClassTemplateSpecializationDecl(
1627 DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
1628 const TemplateParameterInfos &template_param_infos) {
1629 ASTContext *ast = getASTContext();
Sean Callanan09e91ac2017-05-11 22:08:05 +00001630 llvm::SmallVector<clang::TemplateArgument, 2> args(
1631 template_param_infos.args.size() +
1632 (template_param_infos.packed_args ? 1 : 0));
1633 std::copy(template_param_infos.args.begin(), template_param_infos.args.end(),
1634 args.begin());
1635 if (template_param_infos.packed_args) {
1636 args[args.size() - 1] = TemplateArgument::CreatePackCopy(
1637 *ast, template_param_infos.packed_args->args);
1638 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001639 ClassTemplateSpecializationDecl *class_template_specialization_decl =
1640 ClassTemplateSpecializationDecl::Create(
1641 *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
Sean Callanan09e91ac2017-05-11 22:08:05 +00001642 SourceLocation(), class_template_decl, args,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001643 nullptr);
1644
1645 class_template_specialization_decl->setSpecializationKind(
1646 TSK_ExplicitSpecialization);
1647
1648 return class_template_specialization_decl;
1649}
1650
1651CompilerType ClangASTContext::CreateClassTemplateSpecializationType(
1652 ClassTemplateSpecializationDecl *class_template_specialization_decl) {
1653 if (class_template_specialization_decl) {
Greg Claytonf0705c82011-10-22 03:33:13 +00001654 ASTContext *ast = getASTContext();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001655 if (ast)
1656 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00001657 this, ast->getTagDeclType(class_template_specialization_decl)
1658 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001659 }
1660 return CompilerType();
Greg Claytonf0705c82011-10-22 03:33:13 +00001661}
1662
Kate Stoneb9c1b512016-09-06 20:57:50 +00001663static inline bool check_op_param(bool is_method,
1664 clang::OverloadedOperatorKind op_kind,
1665 bool unary, bool binary,
1666 uint32_t num_params) {
1667 // Special-case call since it can take any number of operands
1668 if (op_kind == OO_Call)
1669 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001670
Kate Stoneb9c1b512016-09-06 20:57:50 +00001671 // The parameter count doesn't include "this"
1672 if (is_method)
1673 ++num_params;
1674 if (num_params == 1)
1675 return unary;
1676 if (num_params == 2)
1677 return binary;
1678 else
Greg Clayton090d0982011-06-19 03:43:27 +00001679 return false;
1680}
Daniel Dunbardacdfb52011-10-31 22:50:57 +00001681
Kate Stoneb9c1b512016-09-06 20:57:50 +00001682bool ClangASTContext::CheckOverloadedOperatorKindParameterCount(
1683 bool is_method, clang::OverloadedOperatorKind op_kind,
1684 uint32_t num_params) {
1685 switch (op_kind) {
1686 default:
1687 break;
1688 // C++ standard allows any number of arguments to new/delete
1689 case OO_New:
1690 case OO_Array_New:
1691 case OO_Delete:
1692 case OO_Array_Delete:
1693 return true;
1694 }
Pavel Labath1ac2b202016-08-15 14:32:32 +00001695
Kate Stoneb9c1b512016-09-06 20:57:50 +00001696#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
1697 case OO_##Name: \
1698 return check_op_param(is_method, op_kind, Unary, Binary, num_params);
1699 switch (op_kind) {
Greg Clayton090d0982011-06-19 03:43:27 +00001700#include "clang/Basic/OperatorKinds.def"
Kate Stoneb9c1b512016-09-06 20:57:50 +00001701 default:
1702 break;
1703 }
1704 return false;
Greg Clayton090d0982011-06-19 03:43:27 +00001705}
1706
Greg Clayton57ee3062013-07-11 22:46:58 +00001707clang::AccessSpecifier
Kate Stoneb9c1b512016-09-06 20:57:50 +00001708ClangASTContext::UnifyAccessSpecifiers(clang::AccessSpecifier lhs,
1709 clang::AccessSpecifier rhs) {
1710 // Make the access equal to the stricter of the field and the nested field's
1711 // access
1712 if (lhs == AS_none || rhs == AS_none)
1713 return AS_none;
1714 if (lhs == AS_private || rhs == AS_private)
1715 return AS_private;
1716 if (lhs == AS_protected || rhs == AS_protected)
1717 return AS_protected;
1718 return AS_public;
Sean Callanane8c0cfb2012-03-02 01:03:45 +00001719}
1720
Kate Stoneb9c1b512016-09-06 20:57:50 +00001721bool ClangASTContext::FieldIsBitfield(FieldDecl *field,
1722 uint32_t &bitfield_bit_size) {
1723 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001724}
1725
Kate Stoneb9c1b512016-09-06 20:57:50 +00001726bool ClangASTContext::FieldIsBitfield(ASTContext *ast, FieldDecl *field,
1727 uint32_t &bitfield_bit_size) {
1728 if (ast == nullptr || field == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001729 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001730
Kate Stoneb9c1b512016-09-06 20:57:50 +00001731 if (field->isBitField()) {
1732 Expr *bit_width_expr = field->getBitWidth();
1733 if (bit_width_expr) {
1734 llvm::APSInt bit_width_apsint;
1735 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast)) {
1736 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001737 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001738 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001739 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001740 }
1741 return false;
1742}
1743
1744bool ClangASTContext::RecordHasFields(const RecordDecl *record_decl) {
1745 if (record_decl == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001746 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001747
1748 if (!record_decl->field_empty())
1749 return true;
1750
1751 // No fields, lets check this is a CXX record and check the base classes
1752 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1753 if (cxx_record_decl) {
1754 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1755 for (base_class = cxx_record_decl->bases_begin(),
1756 base_class_end = cxx_record_decl->bases_end();
1757 base_class != base_class_end; ++base_class) {
1758 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(
1759 base_class->getType()->getAs<RecordType>()->getDecl());
1760 if (RecordHasFields(base_class_decl))
1761 return true;
1762 }
1763 }
1764 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001765}
1766
Adrian Prantl4e8be2c2018-06-13 16:21:24 +00001767#pragma mark Objective-C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001768
Kate Stoneb9c1b512016-09-06 20:57:50 +00001769CompilerType ClangASTContext::CreateObjCClass(const char *name,
1770 DeclContext *decl_ctx,
1771 bool isForwardDecl,
1772 bool isInternal,
1773 ClangASTMetadata *metadata) {
1774 ASTContext *ast = getASTContext();
1775 assert(ast != nullptr);
1776 assert(name && name[0]);
1777 if (decl_ctx == nullptr)
1778 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001779
Kate Stoneb9c1b512016-09-06 20:57:50 +00001780 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create(
1781 *ast, decl_ctx, SourceLocation(), &ast->Idents.get(name), nullptr,
1782 nullptr, SourceLocation(),
1783 /*isForwardDecl,*/
1784 isInternal);
1785
1786 if (decl && metadata)
1787 SetMetadata(ast, decl, *metadata);
1788
Alex Langfordbddab072019-08-13 19:40:36 +00001789 return CompilerType(this, ast->getObjCInterfaceType(decl).getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001790}
1791
Kate Stoneb9c1b512016-09-06 20:57:50 +00001792static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) {
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001793 return !ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001794}
1795
Greg Clayton57ee3062013-07-11 22:46:58 +00001796uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001797ClangASTContext::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl,
1798 bool omit_empty_base_classes) {
1799 uint32_t num_bases = 0;
1800 if (cxx_record_decl) {
1801 if (omit_empty_base_classes) {
1802 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1803 for (base_class = cxx_record_decl->bases_begin(),
1804 base_class_end = cxx_record_decl->bases_end();
1805 base_class != base_class_end; ++base_class) {
1806 // Skip empty base classes
1807 if (omit_empty_base_classes) {
1808 if (BaseSpecifierIsEmpty(base_class))
1809 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001810 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001811 ++num_bases;
1812 }
1813 } else
1814 num_bases = cxx_record_decl->getNumBases();
1815 }
1816 return num_bases;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001817}
1818
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001819#pragma mark Namespace Declarations
1820
Raphael Isemanna9469972019-03-12 07:45:04 +00001821NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration(
1822 const char *name, DeclContext *decl_ctx, bool is_inline) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001823 NamespaceDecl *namespace_decl = nullptr;
1824 ASTContext *ast = getASTContext();
1825 TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl();
1826 if (decl_ctx == nullptr)
1827 decl_ctx = translation_unit_decl;
Greg Clayton030a2042011-10-14 21:34:45 +00001828
Kate Stoneb9c1b512016-09-06 20:57:50 +00001829 if (name) {
1830 IdentifierInfo &identifier_info = ast->Idents.get(name);
1831 DeclarationName decl_name(&identifier_info);
1832 clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
1833 for (NamedDecl *decl : result) {
1834 namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
1835 if (namespace_decl)
1836 return namespace_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001837 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001838
1839 namespace_decl =
Raphael Isemanna9469972019-03-12 07:45:04 +00001840 NamespaceDecl::Create(*ast, decl_ctx, is_inline, SourceLocation(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00001841 SourceLocation(), &identifier_info, nullptr);
1842
1843 decl_ctx->addDecl(namespace_decl);
1844 } else {
1845 if (decl_ctx == translation_unit_decl) {
1846 namespace_decl = translation_unit_decl->getAnonymousNamespace();
1847 if (namespace_decl)
1848 return namespace_decl;
1849
1850 namespace_decl =
1851 NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
1852 SourceLocation(), nullptr, nullptr);
1853 translation_unit_decl->setAnonymousNamespace(namespace_decl);
1854 translation_unit_decl->addDecl(namespace_decl);
1855 assert(namespace_decl == translation_unit_decl->getAnonymousNamespace());
1856 } else {
1857 NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
1858 if (parent_namespace_decl) {
1859 namespace_decl = parent_namespace_decl->getAnonymousNamespace();
1860 if (namespace_decl)
1861 return namespace_decl;
1862 namespace_decl =
1863 NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
1864 SourceLocation(), nullptr, nullptr);
1865 parent_namespace_decl->setAnonymousNamespace(namespace_decl);
1866 parent_namespace_decl->addDecl(namespace_decl);
1867 assert(namespace_decl ==
1868 parent_namespace_decl->getAnonymousNamespace());
1869 } else {
Raphael Isemannc4944812019-07-04 19:49:31 +00001870 assert(false && "GetUniqueNamespaceDeclaration called with no name and "
1871 "no namespace as decl_ctx");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001872 }
Greg Clayton9d3d6882011-10-31 23:51:19 +00001873 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001874 }
Greg Clayton9d3d6882011-10-31 23:51:19 +00001875#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00001876 VerifyDecl(namespace_decl);
Greg Clayton9d3d6882011-10-31 23:51:19 +00001877#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00001878 return namespace_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001879}
1880
Kate Stoneb9c1b512016-09-06 20:57:50 +00001881NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration(
Raphael Isemanna9469972019-03-12 07:45:04 +00001882 clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx,
1883 bool is_inline) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001884 ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast);
1885 if (ast_ctx == nullptr)
1886 return nullptr;
Siva Chandra03ff5c82016-02-05 19:10:04 +00001887
Raphael Isemanna9469972019-03-12 07:45:04 +00001888 return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx, is_inline);
Siva Chandra03ff5c82016-02-05 19:10:04 +00001889}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001890
Paul Hermand628cbb2015-09-15 23:44:17 +00001891clang::BlockDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001892ClangASTContext::CreateBlockDeclaration(clang::DeclContext *ctx) {
1893 if (ctx != nullptr) {
1894 clang::BlockDecl *decl = clang::BlockDecl::Create(*getASTContext(), ctx,
1895 clang::SourceLocation());
1896 ctx->addDecl(decl);
1897 return decl;
1898 }
1899 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00001900}
1901
Kate Stoneb9c1b512016-09-06 20:57:50 +00001902clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left,
1903 clang::DeclContext *right,
1904 clang::DeclContext *root) {
1905 if (root == nullptr)
Paul Hermanea188fc2015-09-16 18:48:30 +00001906 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001907
1908 std::set<clang::DeclContext *> path_left;
1909 for (clang::DeclContext *d = left; d != nullptr; d = d->getParent())
1910 path_left.insert(d);
1911
1912 for (clang::DeclContext *d = right; d != nullptr; d = d->getParent())
1913 if (path_left.find(d) != path_left.end())
1914 return d;
1915
1916 return nullptr;
Paul Hermanea188fc2015-09-16 18:48:30 +00001917}
1918
Kate Stoneb9c1b512016-09-06 20:57:50 +00001919clang::UsingDirectiveDecl *ClangASTContext::CreateUsingDirectiveDeclaration(
1920 clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) {
1921 if (decl_ctx != nullptr && ns_decl != nullptr) {
1922 clang::TranslationUnitDecl *translation_unit =
1923 (clang::TranslationUnitDecl *)GetTranslationUnitDecl(getASTContext());
1924 clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
1925 *getASTContext(), decl_ctx, clang::SourceLocation(),
1926 clang::SourceLocation(), clang::NestedNameSpecifierLoc(),
1927 clang::SourceLocation(), ns_decl,
1928 FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit));
1929 decl_ctx->addDecl(using_decl);
1930 return using_decl;
1931 }
1932 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00001933}
1934
1935clang::UsingDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001936ClangASTContext::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
1937 clang::NamedDecl *target) {
1938 if (current_decl_ctx != nullptr && target != nullptr) {
1939 clang::UsingDecl *using_decl = clang::UsingDecl::Create(
1940 *getASTContext(), current_decl_ctx, clang::SourceLocation(),
1941 clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
1942 clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
1943 *getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
1944 target);
1945 using_decl->addShadowDecl(shadow_decl);
1946 current_decl_ctx->addDecl(using_decl);
1947 return using_decl;
1948 }
1949 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00001950}
1951
Kate Stoneb9c1b512016-09-06 20:57:50 +00001952clang::VarDecl *ClangASTContext::CreateVariableDeclaration(
1953 clang::DeclContext *decl_context, const char *name, clang::QualType type) {
1954 if (decl_context != nullptr) {
1955 clang::VarDecl *var_decl = clang::VarDecl::Create(
1956 *getASTContext(), decl_context, clang::SourceLocation(),
1957 clang::SourceLocation(),
1958 name && name[0] ? &getASTContext()->Idents.getOwn(name) : nullptr, type,
1959 nullptr, clang::SC_None);
1960 var_decl->setAccess(clang::AS_public);
1961 decl_context->addDecl(var_decl);
1962 return var_decl;
1963 }
1964 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00001965}
1966
Zachary Turner9d8a97e2016-04-01 23:20:35 +00001967lldb::opaque_compiler_type_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001968ClangASTContext::GetOpaqueCompilerType(clang::ASTContext *ast,
1969 lldb::BasicType basic_type) {
1970 switch (basic_type) {
1971 case eBasicTypeVoid:
1972 return ast->VoidTy.getAsOpaquePtr();
1973 case eBasicTypeChar:
1974 return ast->CharTy.getAsOpaquePtr();
1975 case eBasicTypeSignedChar:
1976 return ast->SignedCharTy.getAsOpaquePtr();
1977 case eBasicTypeUnsignedChar:
1978 return ast->UnsignedCharTy.getAsOpaquePtr();
1979 case eBasicTypeWChar:
1980 return ast->getWCharType().getAsOpaquePtr();
1981 case eBasicTypeSignedWChar:
1982 return ast->getSignedWCharType().getAsOpaquePtr();
1983 case eBasicTypeUnsignedWChar:
1984 return ast->getUnsignedWCharType().getAsOpaquePtr();
1985 case eBasicTypeChar16:
1986 return ast->Char16Ty.getAsOpaquePtr();
1987 case eBasicTypeChar32:
1988 return ast->Char32Ty.getAsOpaquePtr();
1989 case eBasicTypeShort:
1990 return ast->ShortTy.getAsOpaquePtr();
1991 case eBasicTypeUnsignedShort:
1992 return ast->UnsignedShortTy.getAsOpaquePtr();
1993 case eBasicTypeInt:
1994 return ast->IntTy.getAsOpaquePtr();
1995 case eBasicTypeUnsignedInt:
1996 return ast->UnsignedIntTy.getAsOpaquePtr();
1997 case eBasicTypeLong:
1998 return ast->LongTy.getAsOpaquePtr();
1999 case eBasicTypeUnsignedLong:
2000 return ast->UnsignedLongTy.getAsOpaquePtr();
2001 case eBasicTypeLongLong:
2002 return ast->LongLongTy.getAsOpaquePtr();
2003 case eBasicTypeUnsignedLongLong:
2004 return ast->UnsignedLongLongTy.getAsOpaquePtr();
2005 case eBasicTypeInt128:
2006 return ast->Int128Ty.getAsOpaquePtr();
2007 case eBasicTypeUnsignedInt128:
2008 return ast->UnsignedInt128Ty.getAsOpaquePtr();
2009 case eBasicTypeBool:
2010 return ast->BoolTy.getAsOpaquePtr();
2011 case eBasicTypeHalf:
2012 return ast->HalfTy.getAsOpaquePtr();
2013 case eBasicTypeFloat:
2014 return ast->FloatTy.getAsOpaquePtr();
2015 case eBasicTypeDouble:
2016 return ast->DoubleTy.getAsOpaquePtr();
2017 case eBasicTypeLongDouble:
2018 return ast->LongDoubleTy.getAsOpaquePtr();
2019 case eBasicTypeFloatComplex:
2020 return ast->FloatComplexTy.getAsOpaquePtr();
2021 case eBasicTypeDoubleComplex:
2022 return ast->DoubleComplexTy.getAsOpaquePtr();
2023 case eBasicTypeLongDoubleComplex:
2024 return ast->LongDoubleComplexTy.getAsOpaquePtr();
2025 case eBasicTypeObjCID:
2026 return ast->getObjCIdType().getAsOpaquePtr();
2027 case eBasicTypeObjCClass:
2028 return ast->getObjCClassType().getAsOpaquePtr();
2029 case eBasicTypeObjCSel:
2030 return ast->getObjCSelType().getAsOpaquePtr();
2031 case eBasicTypeNullPtr:
2032 return ast->NullPtrTy.getAsOpaquePtr();
2033 default:
2034 return nullptr;
2035 }
Zachary Turner9d8a97e2016-04-01 23:20:35 +00002036}
2037
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002038#pragma mark Function Types
2039
Pavel Labath1ac2b202016-08-15 14:32:32 +00002040clang::DeclarationName
Kate Stoneb9c1b512016-09-06 20:57:50 +00002041ClangASTContext::GetDeclarationName(const char *name,
2042 const CompilerType &function_clang_type) {
2043 if (!name || !name[0])
2044 return clang::DeclarationName();
Pavel Labath1ac2b202016-08-15 14:32:32 +00002045
Kate Stoneb9c1b512016-09-06 20:57:50 +00002046 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
2047 if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS)
2048 return DeclarationName(&getASTContext()->Idents.get(
2049 name)); // Not operator, but a regular function.
Pavel Labath1ac2b202016-08-15 14:32:32 +00002050
Adrian Prantl05097242018-04-30 16:49:04 +00002051 // Check the number of operator parameters. Sometimes we have seen bad DWARF
2052 // that doesn't correctly describe operators and if we try to create a method
2053 // and add it to the class, clang will assert and crash, so we need to make
2054 // sure things are acceptable.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002055 clang::QualType method_qual_type(ClangUtil::GetQualType(function_clang_type));
2056 const clang::FunctionProtoType *function_type =
2057 llvm::dyn_cast<clang::FunctionProtoType>(method_qual_type.getTypePtr());
2058 if (function_type == nullptr)
2059 return clang::DeclarationName();
Pavel Labath1ac2b202016-08-15 14:32:32 +00002060
Kate Stoneb9c1b512016-09-06 20:57:50 +00002061 const bool is_method = false;
2062 const unsigned int num_params = function_type->getNumParams();
2063 if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
2064 is_method, op_kind, num_params))
2065 return clang::DeclarationName();
Pavel Labath1ac2b202016-08-15 14:32:32 +00002066
Kate Stoneb9c1b512016-09-06 20:57:50 +00002067 return getASTContext()->DeclarationNames.getCXXOperatorName(op_kind);
Pavel Labath1ac2b202016-08-15 14:32:32 +00002068}
2069
Kate Stoneb9c1b512016-09-06 20:57:50 +00002070FunctionDecl *ClangASTContext::CreateFunctionDeclaration(
2071 DeclContext *decl_ctx, const char *name,
2072 const CompilerType &function_clang_type, int storage, bool is_inline) {
2073 FunctionDecl *func_decl = nullptr;
2074 ASTContext *ast = getASTContext();
2075 if (decl_ctx == nullptr)
2076 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002077
Kate Stoneb9c1b512016-09-06 20:57:50 +00002078 const bool hasWrittenPrototype = true;
2079 const bool isConstexprSpecified = false;
Greg Clayton0d551042013-06-28 21:08:47 +00002080
Kate Stoneb9c1b512016-09-06 20:57:50 +00002081 clang::DeclarationName declarationName =
2082 GetDeclarationName(name, function_clang_type);
2083 func_decl = FunctionDecl::Create(
2084 *ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName,
2085 ClangUtil::GetQualType(function_clang_type), nullptr,
2086 (clang::StorageClass)storage, is_inline, hasWrittenPrototype,
Gauthier Harnisch796ed032019-06-14 08:56:20 +00002087 isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002088 if (func_decl)
2089 decl_ctx->addDecl(func_decl);
2090
Sean Callanan5e9e1992011-10-26 01:06:27 +00002091#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00002092 VerifyDecl(func_decl);
Sean Callanan5e9e1992011-10-26 01:06:27 +00002093#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00002094
2095 return func_decl;
2096}
2097
2098CompilerType ClangASTContext::CreateFunctionType(
2099 ASTContext *ast, const CompilerType &result_type, const CompilerType *args,
Aleksandr Urakovbc4707c2018-09-26 09:03:34 +00002100 unsigned num_args, bool is_variadic, unsigned type_quals,
2101 clang::CallingConv cc) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002102 if (ast == nullptr)
2103 return CompilerType(); // invalid AST
2104
2105 if (!result_type || !ClangUtil::IsClangType(result_type))
2106 return CompilerType(); // invalid return type
2107
2108 std::vector<QualType> qual_type_args;
2109 if (num_args > 0 && args == nullptr)
2110 return CompilerType(); // invalid argument array passed in
2111
2112 // Verify that all arguments are valid and the right type
2113 for (unsigned i = 0; i < num_args; ++i) {
2114 if (args[i]) {
2115 // Make sure we have a clang type in args[i] and not a type from another
2116 // language whose name might match
2117 const bool is_clang_type = ClangUtil::IsClangType(args[i]);
2118 lldbassert(is_clang_type);
2119 if (is_clang_type)
2120 qual_type_args.push_back(ClangUtil::GetQualType(args[i]));
2121 else
2122 return CompilerType(); // invalid argument type (must be a clang type)
2123 } else
2124 return CompilerType(); // invalid argument type (empty)
2125 }
2126
2127 // TODO: Detect calling convention in DWARF?
2128 FunctionProtoType::ExtProtoInfo proto_info;
Aleksandr Urakovbc4707c2018-09-26 09:03:34 +00002129 proto_info.ExtInfo = cc;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002130 proto_info.Variadic = is_variadic;
2131 proto_info.ExceptionSpec = EST_None;
Mikael Nilsson8b3bf6c2018-12-13 10:17:26 +00002132 proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002133 proto_info.RefQualifier = RQ_None;
2134
Alex Langfordbddab072019-08-13 19:40:36 +00002135 return CompilerType(ClangASTContext::GetASTContext(ast),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002136 ast->getFunctionType(ClangUtil::GetQualType(result_type),
Alex Langfordbddab072019-08-13 19:40:36 +00002137 qual_type_args, proto_info).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002138}
2139
2140ParmVarDecl *ClangASTContext::CreateParameterDeclaration(
Zachary Turner6753d2d2018-12-12 17:17:53 +00002141 clang::DeclContext *decl_ctx, const char *name,
Shafik Yaghmourfa5c3402019-08-02 21:41:50 +00002142 const CompilerType &param_type, int storage, bool add_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002143 ASTContext *ast = getASTContext();
2144 assert(ast != nullptr);
Zachary Turnerd3d2b9b2018-12-13 18:17:51 +00002145 auto *decl =
2146 ParmVarDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(),
2147 name && name[0] ? &ast->Idents.get(name) : nullptr,
2148 ClangUtil::GetQualType(param_type), nullptr,
2149 (clang::StorageClass)storage, nullptr);
Shafik Yaghmourfa5c3402019-08-02 21:41:50 +00002150 if (add_decl)
2151 decl_ctx->addDecl(decl);
2152
Zachary Turnerd3d2b9b2018-12-13 18:17:51 +00002153 return decl;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002154}
2155
2156void ClangASTContext::SetFunctionParameters(FunctionDecl *function_decl,
2157 ParmVarDecl **params,
2158 unsigned num_params) {
2159 if (function_decl)
2160 function_decl->setParams(ArrayRef<ParmVarDecl *>(params, num_params));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002161}
2162
Greg Claytona1e5dc82015-08-11 22:53:00 +00002163CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00002164ClangASTContext::CreateBlockPointerType(const CompilerType &function_type) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +00002165 QualType block_type = m_ast_up->getBlockPointerType(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002166 clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType()));
Greg Claytonceeb5212016-05-26 22:33:25 +00002167
Kate Stoneb9c1b512016-09-06 20:57:50 +00002168 return CompilerType(this, block_type.getAsOpaquePtr());
Sean Callananc530ba92016-05-02 21:15:31 +00002169}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002170
2171#pragma mark Array Types
2172
Kate Stoneb9c1b512016-09-06 20:57:50 +00002173CompilerType ClangASTContext::CreateArrayType(const CompilerType &element_type,
2174 size_t element_count,
2175 bool is_vector) {
2176 if (element_type.IsValid()) {
2177 ASTContext *ast = getASTContext();
2178 assert(ast != nullptr);
Greg Clayton4ef877f2012-12-06 02:33:54 +00002179
Kate Stoneb9c1b512016-09-06 20:57:50 +00002180 if (is_vector) {
2181 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00002182 this, ast->getExtVectorType(ClangUtil::GetQualType(element_type),
2183 element_count)
2184 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002185 } else {
2186
2187 llvm::APInt ap_element_count(64, element_count);
2188 if (element_count == 0) {
Alex Langfordbddab072019-08-13 19:40:36 +00002189 return CompilerType(this, ast->getIncompleteArrayType(
2190 ClangUtil::GetQualType(element_type),
2191 clang::ArrayType::Normal, 0)
2192 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002193 } else {
Alex Langfordbddab072019-08-13 19:40:36 +00002194 return CompilerType(this, ast->getConstantArrayType(
2195 ClangUtil::GetQualType(element_type),
2196 ap_element_count,
2197 clang::ArrayType::Normal, 0)
2198 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002199 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002200 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002201 }
2202 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002203}
2204
Kate Stoneb9c1b512016-09-06 20:57:50 +00002205CompilerType ClangASTContext::CreateStructForIdentifier(
Adrian Prantl0e4c4822019-03-06 21:22:25 +00002206 ConstString type_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002207 const std::initializer_list<std::pair<const char *, CompilerType>>
2208 &type_fields,
2209 bool packed) {
2210 CompilerType type;
2211 if (!type_name.IsEmpty() &&
2212 (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name))
2213 .IsValid()) {
Pavel Labathf31c9d22017-01-05 13:18:42 +00002214 lldbassert(0 && "Trying to create a type for an existing name");
Enrico Granata76b08d52014-10-29 23:08:02 +00002215 return type;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002216 }
2217
2218 type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(),
2219 clang::TTK_Struct, lldb::eLanguageTypeC);
2220 StartTagDeclarationDefinition(type);
2221 for (const auto &field : type_fields)
2222 AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic,
2223 0);
2224 if (packed)
2225 SetIsPacked(type);
2226 CompleteTagDeclarationDefinition(type);
2227 return type;
Enrico Granata76b08d52014-10-29 23:08:02 +00002228}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002229
Kate Stoneb9c1b512016-09-06 20:57:50 +00002230CompilerType ClangASTContext::GetOrCreateStructForIdentifier(
Adrian Prantl0e4c4822019-03-06 21:22:25 +00002231 ConstString type_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002232 const std::initializer_list<std::pair<const char *, CompilerType>>
2233 &type_fields,
2234 bool packed) {
2235 CompilerType type;
2236 if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
2237 return type;
Sean Callananc530ba92016-05-02 21:15:31 +00002238
Kate Stoneb9c1b512016-09-06 20:57:50 +00002239 return CreateStructForIdentifier(type_name, type_fields, packed);
Sean Callananc530ba92016-05-02 21:15:31 +00002240}
2241
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002242#pragma mark Enumeration Types
2243
Greg Claytona1e5dc82015-08-11 22:53:00 +00002244CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00002245ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
2246 const Declaration &decl,
Tamas Berghammer59765832017-11-07 10:39:22 +00002247 const CompilerType &integer_clang_type,
2248 bool is_scoped) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002249 // TODO: Do something intelligent with the Declaration object passed in
2250 // like maybe filling in the SourceLocation with it...
2251 ASTContext *ast = getASTContext();
Zachary Turnerd133f6a2016-03-28 22:53:41 +00002252
Kate Stoneb9c1b512016-09-06 20:57:50 +00002253 // TODO: ask about these...
Kate Stoneb9c1b512016-09-06 20:57:50 +00002254 // const bool IsFixed = false;
2255
2256 EnumDecl *enum_decl = EnumDecl::Create(
2257 *ast, decl_ctx, SourceLocation(), SourceLocation(),
2258 name && name[0] ? &ast->Idents.get(name) : nullptr, nullptr,
Tamas Berghammercf6bf4c2017-11-07 13:43:55 +00002259 is_scoped, // IsScoped
2260 is_scoped, // IsScopedUsingClassTag
2261 false); // IsFixed
Kate Stoneb9c1b512016-09-06 20:57:50 +00002262
2263 if (enum_decl) {
Aleksandr Urakov709426b2018-09-10 08:08:43 +00002264 if (decl_ctx)
2265 decl_ctx->addDecl(enum_decl);
2266
Kate Stoneb9c1b512016-09-06 20:57:50 +00002267 // TODO: check if we should be setting the promotion type too?
2268 enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
2269
2270 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
2271
Alex Langfordbddab072019-08-13 19:40:36 +00002272 return CompilerType(this, ast->getTagDeclType(enum_decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002273 }
2274 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002275}
2276
Kate Stoneb9c1b512016-09-06 20:57:50 +00002277CompilerType ClangASTContext::GetIntTypeFromBitSize(clang::ASTContext *ast,
2278 size_t bit_size,
2279 bool is_signed) {
2280 if (ast) {
Alex Langfordbddab072019-08-13 19:40:36 +00002281 auto *clang_ast_context = ClangASTContext::GetASTContext(ast);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002282 if (is_signed) {
2283 if (bit_size == ast->getTypeSize(ast->SignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002284 return CompilerType(clang_ast_context,
2285 ast->SignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002286
2287 if (bit_size == ast->getTypeSize(ast->ShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002288 return CompilerType(clang_ast_context, ast->ShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002289
2290 if (bit_size == ast->getTypeSize(ast->IntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002291 return CompilerType(clang_ast_context, ast->IntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002292
2293 if (bit_size == ast->getTypeSize(ast->LongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002294 return CompilerType(clang_ast_context, ast->LongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002295
2296 if (bit_size == ast->getTypeSize(ast->LongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002297 return CompilerType(clang_ast_context,
2298 ast->LongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002299
2300 if (bit_size == ast->getTypeSize(ast->Int128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00002301 return CompilerType(clang_ast_context, ast->Int128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002302 } else {
2303 if (bit_size == ast->getTypeSize(ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002304 return CompilerType(clang_ast_context,
2305 ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002306
2307 if (bit_size == ast->getTypeSize(ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002308 return CompilerType(clang_ast_context,
2309 ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002310
2311 if (bit_size == ast->getTypeSize(ast->UnsignedIntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002312 return CompilerType(clang_ast_context,
2313 ast->UnsignedIntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002314
2315 if (bit_size == ast->getTypeSize(ast->UnsignedLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002316 return CompilerType(clang_ast_context,
2317 ast->UnsignedLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002318
2319 if (bit_size == ast->getTypeSize(ast->UnsignedLongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002320 return CompilerType(clang_ast_context,
2321 ast->UnsignedLongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002322
2323 if (bit_size == ast->getTypeSize(ast->UnsignedInt128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00002324 return CompilerType(clang_ast_context,
2325 ast->UnsignedInt128Ty.getAsOpaquePtr());
Enrico Granatae8bf7492014-08-15 23:00:02 +00002326 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002327 }
2328 return CompilerType();
Enrico Granatae8bf7492014-08-15 23:00:02 +00002329}
2330
Kate Stoneb9c1b512016-09-06 20:57:50 +00002331CompilerType ClangASTContext::GetPointerSizedIntType(clang::ASTContext *ast,
2332 bool is_signed) {
2333 if (ast)
2334 return GetIntTypeFromBitSize(ast, ast->getTypeSize(ast->VoidPtrTy),
2335 is_signed);
2336 return CompilerType();
Enrico Granatae8bf7492014-08-15 23:00:02 +00002337}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002338
Kate Stoneb9c1b512016-09-06 20:57:50 +00002339void ClangASTContext::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) {
2340 if (decl_ctx) {
2341 DumpDeclContextHiearchy(decl_ctx->getParent());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002342
Kate Stoneb9c1b512016-09-06 20:57:50 +00002343 clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl_ctx);
2344 if (named_decl) {
2345 printf("%20s: %s\n", decl_ctx->getDeclKindName(),
2346 named_decl->getDeclName().getAsString().c_str());
2347 } else {
2348 printf("%20s\n", decl_ctx->getDeclKindName());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002349 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002350 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00002351}
2352
Kate Stoneb9c1b512016-09-06 20:57:50 +00002353void ClangASTContext::DumpDeclHiearchy(clang::Decl *decl) {
2354 if (decl == nullptr)
2355 return;
2356 DumpDeclContextHiearchy(decl->getDeclContext());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002357
Kate Stoneb9c1b512016-09-06 20:57:50 +00002358 clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl);
2359 if (record_decl) {
2360 printf("%20s: %s%s\n", decl->getDeclKindName(),
2361 record_decl->getDeclName().getAsString().c_str(),
2362 record_decl->isInjectedClassName() ? " (injected class name)" : "");
Greg Claytone6b36cd2015-12-08 01:02:08 +00002363
Kate Stoneb9c1b512016-09-06 20:57:50 +00002364 } else {
2365 clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl);
2366 if (named_decl) {
2367 printf("%20s: %s\n", decl->getDeclKindName(),
2368 named_decl->getDeclName().getAsString().c_str());
2369 } else {
2370 printf("%20s\n", decl->getDeclKindName());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002371 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002372 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00002373}
2374
Kate Stoneb9c1b512016-09-06 20:57:50 +00002375bool ClangASTContext::DeclsAreEquivalent(clang::Decl *lhs_decl,
2376 clang::Decl *rhs_decl) {
2377 if (lhs_decl && rhs_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002378 // Make sure the decl kinds match first
Kate Stoneb9c1b512016-09-06 20:57:50 +00002379 const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind();
2380 const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind();
Greg Claytone6b36cd2015-12-08 01:02:08 +00002381
Kate Stoneb9c1b512016-09-06 20:57:50 +00002382 if (lhs_decl_kind == rhs_decl_kind) {
Adrian Prantl05097242018-04-30 16:49:04 +00002383 // Now check that the decl contexts kinds are all equivalent before we
2384 // have to check any names of the decl contexts...
Kate Stoneb9c1b512016-09-06 20:57:50 +00002385 clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
2386 clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
2387 if (lhs_decl_ctx && rhs_decl_ctx) {
Jonas Devlieghere09ad8c82019-05-24 00:44:33 +00002388 while (true) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002389 if (lhs_decl_ctx && rhs_decl_ctx) {
2390 const clang::Decl::Kind lhs_decl_ctx_kind =
2391 lhs_decl_ctx->getDeclKind();
2392 const clang::Decl::Kind rhs_decl_ctx_kind =
2393 rhs_decl_ctx->getDeclKind();
2394 if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) {
2395 lhs_decl_ctx = lhs_decl_ctx->getParent();
2396 rhs_decl_ctx = rhs_decl_ctx->getParent();
Greg Claytone6b36cd2015-12-08 01:02:08 +00002397
Kate Stoneb9c1b512016-09-06 20:57:50 +00002398 if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr)
2399 break;
2400 } else
2401 return false;
2402 } else
Tamas Berghammerfcf334b2015-12-02 11:35:54 +00002403 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002404 }
2405
Kate Stoneb9c1b512016-09-06 20:57:50 +00002406 // Now make sure the name of the decls match
Kate Stoneb9c1b512016-09-06 20:57:50 +00002407 clang::NamedDecl *lhs_named_decl =
2408 llvm::dyn_cast<clang::NamedDecl>(lhs_decl);
2409 clang::NamedDecl *rhs_named_decl =
2410 llvm::dyn_cast<clang::NamedDecl>(rhs_decl);
2411 if (lhs_named_decl && rhs_named_decl) {
2412 clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
2413 clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
2414 if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
2415 if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
2416 return false;
2417 } else
Greg Claytona2721472011-06-25 00:44:06 +00002418 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002419 } else
2420 return false;
Greg Claytona2721472011-06-25 00:44:06 +00002421
Adrian Prantl05097242018-04-30 16:49:04 +00002422 // We know that the decl context kinds all match, so now we need to
2423 // make sure the names match as well
Kate Stoneb9c1b512016-09-06 20:57:50 +00002424 lhs_decl_ctx = lhs_decl->getDeclContext();
2425 rhs_decl_ctx = rhs_decl->getDeclContext();
Jonas Devlieghere09ad8c82019-05-24 00:44:33 +00002426 while (true) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002427 switch (lhs_decl_ctx->getDeclKind()) {
2428 case clang::Decl::TranslationUnit:
2429 // We don't care about the translation unit names
2430 return true;
2431 default: {
2432 clang::NamedDecl *lhs_named_decl =
2433 llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx);
2434 clang::NamedDecl *rhs_named_decl =
2435 llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx);
2436 if (lhs_named_decl && rhs_named_decl) {
2437 clang::DeclarationName lhs_decl_name =
2438 lhs_named_decl->getDeclName();
2439 clang::DeclarationName rhs_decl_name =
2440 rhs_named_decl->getDeclName();
2441 if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
2442 if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
2443 return false;
2444 } else
2445 return false;
2446 } else
2447 return false;
2448 } break;
2449 }
2450 lhs_decl_ctx = lhs_decl_ctx->getParent();
2451 rhs_decl_ctx = rhs_decl_ctx->getParent();
Greg Claytond8d4a572015-08-11 21:38:15 +00002452 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002453 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002454 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002455 }
2456 return false;
2457}
2458bool ClangASTContext::GetCompleteDecl(clang::ASTContext *ast,
2459 clang::Decl *decl) {
2460 if (!decl)
Greg Claytond8d4a572015-08-11 21:38:15 +00002461 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00002462
Kate Stoneb9c1b512016-09-06 20:57:50 +00002463 ExternalASTSource *ast_source = ast->getExternalSource();
Greg Claytond8d4a572015-08-11 21:38:15 +00002464
Kate Stoneb9c1b512016-09-06 20:57:50 +00002465 if (!ast_source)
Greg Claytond8d4a572015-08-11 21:38:15 +00002466 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002467
2468 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) {
2469 if (tag_decl->isCompleteDefinition())
2470 return true;
2471
2472 if (!tag_decl->hasExternalLexicalStorage())
2473 return false;
2474
2475 ast_source->CompleteType(tag_decl);
2476
2477 return !tag_decl->getTypeForDecl()->isIncompleteType();
2478 } else if (clang::ObjCInterfaceDecl *objc_interface_decl =
2479 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) {
2480 if (objc_interface_decl->getDefinition())
2481 return true;
2482
2483 if (!objc_interface_decl->hasExternalLexicalStorage())
2484 return false;
2485
2486 ast_source->CompleteType(objc_interface_decl);
2487
2488 return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
2489 } else {
2490 return false;
2491 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002492}
2493
Kate Stoneb9c1b512016-09-06 20:57:50 +00002494void ClangASTContext::SetMetadataAsUserID(const void *object,
2495 user_id_t user_id) {
2496 ClangASTMetadata meta_data;
2497 meta_data.SetUserID(user_id);
2498 SetMetadata(object, meta_data);
Greg Clayton99558cc42015-08-24 23:46:31 +00002499}
2500
Kate Stoneb9c1b512016-09-06 20:57:50 +00002501void ClangASTContext::SetMetadata(clang::ASTContext *ast, const void *object,
2502 ClangASTMetadata &metadata) {
2503 ClangExternalASTSourceCommon *external_source =
2504 ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
2505
2506 if (external_source)
2507 external_source->SetMetadata(object, metadata);
2508}
2509
2510ClangASTMetadata *ClangASTContext::GetMetadata(clang::ASTContext *ast,
2511 const void *object) {
2512 ClangExternalASTSourceCommon *external_source =
2513 ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
2514
2515 if (external_source && external_source->HasMetadata(object))
2516 return external_source->GetMetadata(object);
2517 else
Greg Claytond8d4a572015-08-11 21:38:15 +00002518 return nullptr;
2519}
2520
Kate Stoneb9c1b512016-09-06 20:57:50 +00002521clang::DeclContext *
2522ClangASTContext::GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl) {
2523 return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
2524}
Greg Claytone6b36cd2015-12-08 01:02:08 +00002525
Kate Stoneb9c1b512016-09-06 20:57:50 +00002526clang::DeclContext *
2527ClangASTContext::GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl) {
2528 return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
2529}
Greg Claytone6b36cd2015-12-08 01:02:08 +00002530
Kate Stoneb9c1b512016-09-06 20:57:50 +00002531bool ClangASTContext::SetTagTypeKind(clang::QualType tag_qual_type,
2532 int kind) const {
2533 const clang::Type *clang_type = tag_qual_type.getTypePtr();
2534 if (clang_type) {
2535 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
2536 if (tag_type) {
2537 clang::TagDecl *tag_decl =
2538 llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
2539 if (tag_decl) {
2540 tag_decl->setTagKind((clang::TagDecl::TagKind)kind);
2541 return true;
2542 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002543 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002544 }
2545 return false;
2546}
2547
2548bool ClangASTContext::SetDefaultAccessForRecordFields(
2549 clang::RecordDecl *record_decl, int default_accessibility,
2550 int *assigned_accessibilities, size_t num_assigned_accessibilities) {
2551 if (record_decl) {
2552 uint32_t field_idx;
2553 clang::RecordDecl::field_iterator field, field_end;
2554 for (field = record_decl->field_begin(),
2555 field_end = record_decl->field_end(), field_idx = 0;
2556 field != field_end; ++field, ++field_idx) {
2557 // If no accessibility was assigned, assign the correct one
2558 if (field_idx < num_assigned_accessibilities &&
2559 assigned_accessibilities[field_idx] == clang::AS_none)
2560 field->setAccess((clang::AccessSpecifier)default_accessibility);
2561 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002562 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002563 }
2564 return false;
2565}
2566
2567clang::DeclContext *
2568ClangASTContext::GetDeclContextForType(const CompilerType &type) {
2569 return GetDeclContextForType(ClangUtil::GetQualType(type));
2570}
2571
2572clang::DeclContext *
2573ClangASTContext::GetDeclContextForType(clang::QualType type) {
2574 if (type.isNull())
2575 return nullptr;
2576
2577 clang::QualType qual_type = type.getCanonicalType();
2578 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2579 switch (type_class) {
2580 case clang::Type::ObjCInterface:
2581 return llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr())
2582 ->getInterface();
2583 case clang::Type::ObjCObjectPointer:
2584 return GetDeclContextForType(
2585 llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
2586 ->getPointeeType());
2587 case clang::Type::Record:
2588 return llvm::cast<clang::RecordType>(qual_type)->getDecl();
2589 case clang::Type::Enum:
2590 return llvm::cast<clang::EnumType>(qual_type)->getDecl();
2591 case clang::Type::Typedef:
2592 return GetDeclContextForType(llvm::cast<clang::TypedefType>(qual_type)
2593 ->getDecl()
2594 ->getUnderlyingType());
2595 case clang::Type::Auto:
2596 return GetDeclContextForType(
2597 llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
2598 case clang::Type::Elaborated:
2599 return GetDeclContextForType(
2600 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
2601 case clang::Type::Paren:
2602 return GetDeclContextForType(
2603 llvm::cast<clang::ParenType>(qual_type)->desugar());
2604 default:
2605 break;
2606 }
2607 // No DeclContext in this type...
2608 return nullptr;
2609}
2610
2611static bool GetCompleteQualType(clang::ASTContext *ast,
2612 clang::QualType qual_type,
2613 bool allow_completion = true) {
2614 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2615 switch (type_class) {
2616 case clang::Type::ConstantArray:
2617 case clang::Type::IncompleteArray:
2618 case clang::Type::VariableArray: {
2619 const clang::ArrayType *array_type =
2620 llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
2621
2622 if (array_type)
2623 return GetCompleteQualType(ast, array_type->getElementType(),
2624 allow_completion);
2625 } break;
2626 case clang::Type::Record: {
2627 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2628 if (cxx_record_decl) {
2629 if (cxx_record_decl->hasExternalLexicalStorage()) {
2630 const bool is_complete = cxx_record_decl->isCompleteDefinition();
2631 const bool fields_loaded =
2632 cxx_record_decl->hasLoadedFieldsFromExternalStorage();
2633 if (is_complete && fields_loaded)
2634 return true;
2635
2636 if (!allow_completion)
2637 return false;
2638
2639 // Call the field_begin() accessor to for it to use the external source
2640 // to load the fields...
2641 clang::ExternalASTSource *external_ast_source =
2642 ast->getExternalSource();
2643 if (external_ast_source) {
2644 external_ast_source->CompleteType(cxx_record_decl);
2645 if (cxx_record_decl->isCompleteDefinition()) {
2646 cxx_record_decl->field_begin();
2647 cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
2648 }
2649 }
2650 }
2651 }
2652 const clang::TagType *tag_type =
2653 llvm::cast<clang::TagType>(qual_type.getTypePtr());
2654 return !tag_type->isIncompleteType();
2655 } break;
2656
2657 case clang::Type::Enum: {
2658 const clang::TagType *tag_type =
2659 llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
2660 if (tag_type) {
2661 clang::TagDecl *tag_decl = tag_type->getDecl();
2662 if (tag_decl) {
2663 if (tag_decl->getDefinition())
2664 return true;
2665
2666 if (!allow_completion)
2667 return false;
2668
2669 if (tag_decl->hasExternalLexicalStorage()) {
2670 if (ast) {
2671 clang::ExternalASTSource *external_ast_source =
2672 ast->getExternalSource();
2673 if (external_ast_source) {
2674 external_ast_source->CompleteType(tag_decl);
2675 return !tag_type->isIncompleteType();
2676 }
2677 }
2678 }
2679 return false;
2680 }
2681 }
2682
2683 } break;
2684 case clang::Type::ObjCObject:
2685 case clang::Type::ObjCInterface: {
2686 const clang::ObjCObjectType *objc_class_type =
2687 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
2688 if (objc_class_type) {
2689 clang::ObjCInterfaceDecl *class_interface_decl =
2690 objc_class_type->getInterface();
2691 // We currently can't complete objective C types through the newly added
Adrian Prantl05097242018-04-30 16:49:04 +00002692 // ASTContext because it only supports TagDecl objects right now...
Kate Stoneb9c1b512016-09-06 20:57:50 +00002693 if (class_interface_decl) {
2694 if (class_interface_decl->getDefinition())
2695 return true;
2696
2697 if (!allow_completion)
2698 return false;
2699
2700 if (class_interface_decl->hasExternalLexicalStorage()) {
2701 if (ast) {
2702 clang::ExternalASTSource *external_ast_source =
2703 ast->getExternalSource();
2704 if (external_ast_source) {
2705 external_ast_source->CompleteType(class_interface_decl);
2706 return !objc_class_type->isIncompleteType();
2707 }
2708 }
2709 }
2710 return false;
2711 }
2712 }
2713 } break;
2714
2715 case clang::Type::Typedef:
2716 return GetCompleteQualType(ast, llvm::cast<clang::TypedefType>(qual_type)
2717 ->getDecl()
2718 ->getUnderlyingType(),
2719 allow_completion);
2720
2721 case clang::Type::Auto:
2722 return GetCompleteQualType(
2723 ast, llvm::cast<clang::AutoType>(qual_type)->getDeducedType(),
2724 allow_completion);
2725
2726 case clang::Type::Elaborated:
2727 return GetCompleteQualType(
2728 ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(),
2729 allow_completion);
2730
2731 case clang::Type::Paren:
2732 return GetCompleteQualType(
2733 ast, llvm::cast<clang::ParenType>(qual_type)->desugar(),
2734 allow_completion);
2735
2736 case clang::Type::Attributed:
2737 return GetCompleteQualType(
2738 ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(),
2739 allow_completion);
2740
2741 default:
2742 break;
2743 }
2744
2745 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00002746}
2747
2748static clang::ObjCIvarDecl::AccessControl
Kate Stoneb9c1b512016-09-06 20:57:50 +00002749ConvertAccessTypeToObjCIvarAccessControl(AccessType access) {
2750 switch (access) {
2751 case eAccessNone:
Greg Claytond8d4a572015-08-11 21:38:15 +00002752 return clang::ObjCIvarDecl::None;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002753 case eAccessPublic:
2754 return clang::ObjCIvarDecl::Public;
2755 case eAccessPrivate:
2756 return clang::ObjCIvarDecl::Private;
2757 case eAccessProtected:
2758 return clang::ObjCIvarDecl::Protected;
2759 case eAccessPackage:
2760 return clang::ObjCIvarDecl::Package;
2761 }
2762 return clang::ObjCIvarDecl::None;
Greg Claytond8d4a572015-08-11 21:38:15 +00002763}
2764
Greg Claytond8d4a572015-08-11 21:38:15 +00002765// Tests
Greg Claytond8d4a572015-08-11 21:38:15 +00002766
Kate Stoneb9c1b512016-09-06 20:57:50 +00002767bool ClangASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
2768 clang::QualType qual_type(GetCanonicalQualType(type));
2769
2770 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2771 switch (type_class) {
2772 case clang::Type::IncompleteArray:
2773 case clang::Type::VariableArray:
2774 case clang::Type::ConstantArray:
2775 case clang::Type::ExtVector:
2776 case clang::Type::Vector:
2777 case clang::Type::Record:
2778 case clang::Type::ObjCObject:
2779 case clang::Type::ObjCInterface:
2780 return true;
2781 case clang::Type::Auto:
2782 return IsAggregateType(llvm::cast<clang::AutoType>(qual_type)
2783 ->getDeducedType()
2784 .getAsOpaquePtr());
2785 case clang::Type::Elaborated:
2786 return IsAggregateType(llvm::cast<clang::ElaboratedType>(qual_type)
2787 ->getNamedType()
2788 .getAsOpaquePtr());
2789 case clang::Type::Typedef:
2790 return IsAggregateType(llvm::cast<clang::TypedefType>(qual_type)
2791 ->getDecl()
2792 ->getUnderlyingType()
2793 .getAsOpaquePtr());
2794 case clang::Type::Paren:
2795 return IsAggregateType(
2796 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
2797 default:
2798 break;
2799 }
2800 // The clang type does have a value
2801 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00002802}
2803
Kate Stoneb9c1b512016-09-06 20:57:50 +00002804bool ClangASTContext::IsAnonymousType(lldb::opaque_compiler_type_t type) {
2805 clang::QualType qual_type(GetCanonicalQualType(type));
2806
2807 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2808 switch (type_class) {
2809 case clang::Type::Record: {
2810 if (const clang::RecordType *record_type =
2811 llvm::dyn_cast_or_null<clang::RecordType>(
2812 qual_type.getTypePtrOrNull())) {
2813 if (const clang::RecordDecl *record_decl = record_type->getDecl()) {
2814 return record_decl->isAnonymousStructOrUnion();
2815 }
Enrico Granata7123e2b2015-11-07 02:06:57 +00002816 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002817 break;
2818 }
2819 case clang::Type::Auto:
2820 return IsAnonymousType(llvm::cast<clang::AutoType>(qual_type)
2821 ->getDeducedType()
2822 .getAsOpaquePtr());
2823 case clang::Type::Elaborated:
2824 return IsAnonymousType(llvm::cast<clang::ElaboratedType>(qual_type)
2825 ->getNamedType()
2826 .getAsOpaquePtr());
2827 case clang::Type::Typedef:
2828 return IsAnonymousType(llvm::cast<clang::TypedefType>(qual_type)
2829 ->getDecl()
2830 ->getUnderlyingType()
2831 .getAsOpaquePtr());
2832 case clang::Type::Paren:
2833 return IsAnonymousType(
2834 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
2835 default:
2836 break;
2837 }
2838 // The clang type does have a value
2839 return false;
Enrico Granata7123e2b2015-11-07 02:06:57 +00002840}
2841
Kate Stoneb9c1b512016-09-06 20:57:50 +00002842bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
2843 CompilerType *element_type_ptr,
2844 uint64_t *size, bool *is_incomplete) {
2845 clang::QualType qual_type(GetCanonicalQualType(type));
Tamas Berghammer69d0b332015-10-09 12:43:08 +00002846
Kate Stoneb9c1b512016-09-06 20:57:50 +00002847 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2848 switch (type_class) {
2849 default:
2850 break;
Tamas Berghammer69d0b332015-10-09 12:43:08 +00002851
Kate Stoneb9c1b512016-09-06 20:57:50 +00002852 case clang::Type::ConstantArray:
Greg Claytond8d4a572015-08-11 21:38:15 +00002853 if (element_type_ptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002854 element_type_ptr->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00002855 this, llvm::cast<clang::ConstantArrayType>(qual_type)
2856 ->getElementType()
2857 .getAsOpaquePtr());
Greg Claytond8d4a572015-08-11 21:38:15 +00002858 if (size)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002859 *size = llvm::cast<clang::ConstantArrayType>(qual_type)
2860 ->getSize()
2861 .getLimitedValue(ULLONG_MAX);
Greg Claytond8d4a572015-08-11 21:38:15 +00002862 if (is_incomplete)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002863 *is_incomplete = false;
2864 return true;
2865
2866 case clang::Type::IncompleteArray:
2867 if (element_type_ptr)
2868 element_type_ptr->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00002869 this, llvm::cast<clang::IncompleteArrayType>(qual_type)
2870 ->getElementType()
2871 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002872 if (size)
2873 *size = 0;
2874 if (is_incomplete)
2875 *is_incomplete = true;
2876 return true;
2877
2878 case clang::Type::VariableArray:
2879 if (element_type_ptr)
2880 element_type_ptr->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00002881 this, llvm::cast<clang::VariableArrayType>(qual_type)
2882 ->getElementType()
2883 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002884 if (size)
2885 *size = 0;
2886 if (is_incomplete)
2887 *is_incomplete = false;
2888 return true;
2889
2890 case clang::Type::DependentSizedArray:
2891 if (element_type_ptr)
2892 element_type_ptr->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00002893 this, llvm::cast<clang::DependentSizedArrayType>(qual_type)
2894 ->getElementType()
2895 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002896 if (size)
2897 *size = 0;
2898 if (is_incomplete)
2899 *is_incomplete = false;
2900 return true;
2901
2902 case clang::Type::Typedef:
2903 return IsArrayType(llvm::cast<clang::TypedefType>(qual_type)
2904 ->getDecl()
2905 ->getUnderlyingType()
2906 .getAsOpaquePtr(),
2907 element_type_ptr, size, is_incomplete);
2908 case clang::Type::Auto:
2909 return IsArrayType(llvm::cast<clang::AutoType>(qual_type)
2910 ->getDeducedType()
2911 .getAsOpaquePtr(),
2912 element_type_ptr, size, is_incomplete);
2913 case clang::Type::Elaborated:
2914 return IsArrayType(llvm::cast<clang::ElaboratedType>(qual_type)
2915 ->getNamedType()
2916 .getAsOpaquePtr(),
2917 element_type_ptr, size, is_incomplete);
2918 case clang::Type::Paren:
2919 return IsArrayType(
2920 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
2921 element_type_ptr, size, is_incomplete);
2922 }
2923 if (element_type_ptr)
2924 element_type_ptr->Clear();
2925 if (size)
2926 *size = 0;
2927 if (is_incomplete)
2928 *is_incomplete = false;
2929 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00002930}
2931
Kate Stoneb9c1b512016-09-06 20:57:50 +00002932bool ClangASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
2933 CompilerType *element_type, uint64_t *size) {
2934 clang::QualType qual_type(GetCanonicalQualType(type));
2935
2936 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2937 switch (type_class) {
2938 case clang::Type::Vector: {
2939 const clang::VectorType *vector_type =
2940 qual_type->getAs<clang::VectorType>();
2941 if (vector_type) {
2942 if (size)
2943 *size = vector_type->getNumElements();
2944 if (element_type)
2945 *element_type =
Alex Langfordbddab072019-08-13 19:40:36 +00002946 CompilerType(this, vector_type->getElementType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002947 }
2948 return true;
2949 } break;
2950 case clang::Type::ExtVector: {
2951 const clang::ExtVectorType *ext_vector_type =
2952 qual_type->getAs<clang::ExtVectorType>();
2953 if (ext_vector_type) {
2954 if (size)
2955 *size = ext_vector_type->getNumElements();
2956 if (element_type)
2957 *element_type =
Alex Langfordbddab072019-08-13 19:40:36 +00002958 CompilerType(this, ext_vector_type->getElementType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002959 }
2960 return true;
2961 }
2962 default:
2963 break;
2964 }
2965 return false;
2966}
2967
2968bool ClangASTContext::IsRuntimeGeneratedType(
2969 lldb::opaque_compiler_type_t type) {
2970 clang::DeclContext *decl_ctx = ClangASTContext::GetASTContext(getASTContext())
2971 ->GetDeclContextForType(GetQualType(type));
2972 if (!decl_ctx)
2973 return false;
2974
2975 if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
2976 return false;
2977
2978 clang::ObjCInterfaceDecl *result_iface_decl =
2979 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
2980
2981 ClangASTMetadata *ast_metadata =
2982 ClangASTContext::GetMetadata(getASTContext(), result_iface_decl);
2983 if (!ast_metadata)
2984 return false;
2985 return (ast_metadata->GetISAPtr() != 0);
2986}
2987
2988bool ClangASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
2989 return GetQualType(type).getUnqualifiedType()->isCharType();
2990}
2991
2992bool ClangASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
2993 const bool allow_completion = false;
2994 return GetCompleteQualType(getASTContext(), GetQualType(type),
2995 allow_completion);
2996}
2997
2998bool ClangASTContext::IsConst(lldb::opaque_compiler_type_t type) {
2999 return GetQualType(type).isConstQualified();
3000}
3001
3002bool ClangASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
3003 uint32_t &length) {
3004 CompilerType pointee_or_element_clang_type;
3005 length = 0;
3006 Flags type_flags(GetTypeInfo(type, &pointee_or_element_clang_type));
3007
3008 if (!pointee_or_element_clang_type.IsValid())
3009 return false;
3010
3011 if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer)) {
3012 if (pointee_or_element_clang_type.IsCharType()) {
3013 if (type_flags.Test(eTypeIsArray)) {
Adrian Prantl05097242018-04-30 16:49:04 +00003014 // We know the size of the array and it could be a C string since it is
3015 // an array of characters
Kate Stoneb9c1b512016-09-06 20:57:50 +00003016 length = llvm::cast<clang::ConstantArrayType>(
3017 GetCanonicalQualType(type).getTypePtr())
3018 ->getSize()
3019 .getLimitedValue();
3020 }
3021 return true;
3022 }
3023 }
3024 return false;
3025}
3026
3027bool ClangASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
3028 bool *is_variadic_ptr) {
3029 if (type) {
3030 clang::QualType qual_type(GetCanonicalQualType(type));
3031
3032 if (qual_type->isFunctionType()) {
3033 if (is_variadic_ptr) {
3034 const clang::FunctionProtoType *function_proto_type =
3035 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
3036 if (function_proto_type)
3037 *is_variadic_ptr = function_proto_type->isVariadic();
3038 else
3039 *is_variadic_ptr = false;
3040 }
3041 return true;
3042 }
3043
Greg Claytond8d4a572015-08-11 21:38:15 +00003044 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00003045 switch (type_class) {
3046 default:
3047 break;
3048 case clang::Type::Typedef:
3049 return IsFunctionType(llvm::cast<clang::TypedefType>(qual_type)
3050 ->getDecl()
3051 ->getUnderlyingType()
3052 .getAsOpaquePtr(),
3053 nullptr);
3054 case clang::Type::Auto:
3055 return IsFunctionType(llvm::cast<clang::AutoType>(qual_type)
3056 ->getDeducedType()
3057 .getAsOpaquePtr(),
3058 nullptr);
3059 case clang::Type::Elaborated:
3060 return IsFunctionType(llvm::cast<clang::ElaboratedType>(qual_type)
3061 ->getNamedType()
3062 .getAsOpaquePtr(),
3063 nullptr);
3064 case clang::Type::Paren:
3065 return IsFunctionType(
3066 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3067 nullptr);
3068 case clang::Type::LValueReference:
3069 case clang::Type::RValueReference: {
3070 const clang::ReferenceType *reference_type =
3071 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
3072 if (reference_type)
3073 return IsFunctionType(reference_type->getPointeeType().getAsOpaquePtr(),
3074 nullptr);
3075 } break;
Greg Claytond8d4a572015-08-11 21:38:15 +00003076 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003077 }
3078 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00003079}
3080
3081// Used to detect "Homogeneous Floating-point Aggregates"
3082uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00003083ClangASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
3084 CompilerType *base_type_ptr) {
3085 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00003086 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003087
3088 clang::QualType qual_type(GetCanonicalQualType(type));
3089 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3090 switch (type_class) {
3091 case clang::Type::Record:
3092 if (GetCompleteType(type)) {
3093 const clang::CXXRecordDecl *cxx_record_decl =
3094 qual_type->getAsCXXRecordDecl();
3095 if (cxx_record_decl) {
3096 if (cxx_record_decl->getNumBases() || cxx_record_decl->isDynamicClass())
3097 return 0;
3098 }
3099 const clang::RecordType *record_type =
3100 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
3101 if (record_type) {
3102 const clang::RecordDecl *record_decl = record_type->getDecl();
3103 if (record_decl) {
3104 // We are looking for a structure that contains only floating point
3105 // types
3106 clang::RecordDecl::field_iterator field_pos,
3107 field_end = record_decl->field_end();
3108 uint32_t num_fields = 0;
3109 bool is_hva = false;
3110 bool is_hfa = false;
3111 clang::QualType base_qual_type;
3112 uint64_t base_bitwidth = 0;
3113 for (field_pos = record_decl->field_begin(); field_pos != field_end;
3114 ++field_pos) {
3115 clang::QualType field_qual_type = field_pos->getType();
3116 uint64_t field_bitwidth = getASTContext()->getTypeSize(qual_type);
3117 if (field_qual_type->isFloatingType()) {
3118 if (field_qual_type->isComplexType())
3119 return 0;
3120 else {
3121 if (num_fields == 0)
3122 base_qual_type = field_qual_type;
3123 else {
3124 if (is_hva)
3125 return 0;
3126 is_hfa = true;
3127 if (field_qual_type.getTypePtr() !=
3128 base_qual_type.getTypePtr())
3129 return 0;
3130 }
3131 }
3132 } else if (field_qual_type->isVectorType() ||
3133 field_qual_type->isExtVectorType()) {
3134 if (num_fields == 0) {
3135 base_qual_type = field_qual_type;
3136 base_bitwidth = field_bitwidth;
3137 } else {
3138 if (is_hfa)
3139 return 0;
3140 is_hva = true;
3141 if (base_bitwidth != field_bitwidth)
3142 return 0;
3143 if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
3144 return 0;
3145 }
3146 } else
3147 return 0;
3148 ++num_fields;
3149 }
3150 if (base_type_ptr)
Alex Langfordbddab072019-08-13 19:40:36 +00003151 *base_type_ptr = CompilerType(this, base_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003152 return num_fields;
3153 }
3154 }
3155 }
3156 break;
3157
3158 case clang::Type::Typedef:
3159 return IsHomogeneousAggregate(llvm::cast<clang::TypedefType>(qual_type)
3160 ->getDecl()
3161 ->getUnderlyingType()
3162 .getAsOpaquePtr(),
3163 base_type_ptr);
3164
3165 case clang::Type::Auto:
3166 return IsHomogeneousAggregate(llvm::cast<clang::AutoType>(qual_type)
3167 ->getDeducedType()
3168 .getAsOpaquePtr(),
3169 base_type_ptr);
3170
3171 case clang::Type::Elaborated:
3172 return IsHomogeneousAggregate(llvm::cast<clang::ElaboratedType>(qual_type)
3173 ->getNamedType()
3174 .getAsOpaquePtr(),
3175 base_type_ptr);
3176 default:
3177 break;
3178 }
3179 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00003180}
3181
Kate Stoneb9c1b512016-09-06 20:57:50 +00003182size_t ClangASTContext::GetNumberOfFunctionArguments(
3183 lldb::opaque_compiler_type_t type) {
3184 if (type) {
3185 clang::QualType qual_type(GetCanonicalQualType(type));
3186 const clang::FunctionProtoType *func =
3187 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
3188 if (func)
3189 return func->getNumParams();
3190 }
3191 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00003192}
3193
Greg Claytona1e5dc82015-08-11 22:53:00 +00003194CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00003195ClangASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
3196 const size_t index) {
3197 if (type) {
Greg Claytond8d4a572015-08-11 21:38:15 +00003198 clang::QualType qual_type(GetQualType(type));
Kate Stoneb9c1b512016-09-06 20:57:50 +00003199 const clang::FunctionProtoType *func =
3200 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
3201 if (func) {
3202 if (index < func->getNumParams())
Alex Langfordbddab072019-08-13 19:40:36 +00003203 return CompilerType(this, func->getParamType(index).getAsOpaquePtr());
Greg Claytond8d4a572015-08-11 21:38:15 +00003204 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003205 }
3206 return CompilerType();
3207}
3208
3209bool ClangASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
3210 if (type) {
3211 clang::QualType qual_type(GetCanonicalQualType(type));
3212
3213 if (qual_type->isFunctionPointerType())
3214 return true;
3215
3216 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3217 switch (type_class) {
3218 default:
3219 break;
3220 case clang::Type::Typedef:
3221 return IsFunctionPointerType(llvm::cast<clang::TypedefType>(qual_type)
3222 ->getDecl()
3223 ->getUnderlyingType()
3224 .getAsOpaquePtr());
3225 case clang::Type::Auto:
3226 return IsFunctionPointerType(llvm::cast<clang::AutoType>(qual_type)
3227 ->getDeducedType()
3228 .getAsOpaquePtr());
3229 case clang::Type::Elaborated:
3230 return IsFunctionPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
3231 ->getNamedType()
3232 .getAsOpaquePtr());
3233 case clang::Type::Paren:
3234 return IsFunctionPointerType(
3235 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
3236
3237 case clang::Type::LValueReference:
3238 case clang::Type::RValueReference: {
3239 const clang::ReferenceType *reference_type =
3240 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
3241 if (reference_type)
3242 return IsFunctionPointerType(
3243 reference_type->getPointeeType().getAsOpaquePtr());
3244 } break;
3245 }
3246 }
3247 return false;
3248}
3249
3250bool ClangASTContext::IsBlockPointerType(
3251 lldb::opaque_compiler_type_t type,
3252 CompilerType *function_pointer_type_ptr) {
3253 if (type) {
3254 clang::QualType qual_type(GetCanonicalQualType(type));
3255
3256 if (qual_type->isBlockPointerType()) {
3257 if (function_pointer_type_ptr) {
3258 const clang::BlockPointerType *block_pointer_type =
3259 qual_type->getAs<clang::BlockPointerType>();
3260 QualType pointee_type = block_pointer_type->getPointeeType();
Jonas Devlieghered5b44032019-02-13 06:25:41 +00003261 QualType function_pointer_type = m_ast_up->getPointerType(pointee_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003262 *function_pointer_type_ptr =
Alex Langfordbddab072019-08-13 19:40:36 +00003263 CompilerType(this, function_pointer_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003264 }
3265 return true;
3266 }
3267
3268 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3269 switch (type_class) {
3270 default:
3271 break;
3272 case clang::Type::Typedef:
3273 return IsBlockPointerType(llvm::cast<clang::TypedefType>(qual_type)
3274 ->getDecl()
3275 ->getUnderlyingType()
3276 .getAsOpaquePtr(),
3277 function_pointer_type_ptr);
3278 case clang::Type::Auto:
3279 return IsBlockPointerType(llvm::cast<clang::AutoType>(qual_type)
3280 ->getDeducedType()
3281 .getAsOpaquePtr(),
3282 function_pointer_type_ptr);
3283 case clang::Type::Elaborated:
3284 return IsBlockPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
3285 ->getNamedType()
3286 .getAsOpaquePtr(),
3287 function_pointer_type_ptr);
3288 case clang::Type::Paren:
3289 return IsBlockPointerType(
3290 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3291 function_pointer_type_ptr);
3292
3293 case clang::Type::LValueReference:
3294 case clang::Type::RValueReference: {
3295 const clang::ReferenceType *reference_type =
3296 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
3297 if (reference_type)
3298 return IsBlockPointerType(
3299 reference_type->getPointeeType().getAsOpaquePtr(),
3300 function_pointer_type_ptr);
3301 } break;
3302 }
3303 }
3304 return false;
3305}
3306
3307bool ClangASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
3308 bool &is_signed) {
3309 if (!type)
3310 return false;
3311
3312 clang::QualType qual_type(GetCanonicalQualType(type));
3313 const clang::BuiltinType *builtin_type =
3314 llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
3315
3316 if (builtin_type) {
3317 if (builtin_type->isInteger()) {
3318 is_signed = builtin_type->isSignedInteger();
3319 return true;
3320 }
3321 }
3322
3323 return false;
3324}
3325
3326bool ClangASTContext::IsEnumerationType(lldb::opaque_compiler_type_t type,
3327 bool &is_signed) {
3328 if (type) {
3329 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
3330 GetCanonicalQualType(type)->getCanonicalTypeInternal());
3331
3332 if (enum_type) {
3333 IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(),
3334 is_signed);
3335 return true;
3336 }
3337 }
3338
3339 return false;
3340}
3341
3342bool ClangASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
3343 CompilerType *pointee_type) {
3344 if (type) {
3345 clang::QualType qual_type(GetCanonicalQualType(type));
3346 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3347 switch (type_class) {
3348 case clang::Type::Builtin:
3349 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
3350 default:
3351 break;
3352 case clang::BuiltinType::ObjCId:
3353 case clang::BuiltinType::ObjCClass:
3354 return true;
3355 }
3356 return false;
3357 case clang::Type::ObjCObjectPointer:
3358 if (pointee_type)
3359 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003360 this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
3361 ->getPointeeType()
3362 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003363 return true;
3364 case clang::Type::BlockPointer:
3365 if (pointee_type)
3366 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003367 this, llvm::cast<clang::BlockPointerType>(qual_type)
3368 ->getPointeeType()
3369 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003370 return true;
3371 case clang::Type::Pointer:
3372 if (pointee_type)
Alex Langfordbddab072019-08-13 19:40:36 +00003373 pointee_type->SetCompilerType(this,
3374 llvm::cast<clang::PointerType>(qual_type)
3375 ->getPointeeType()
3376 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003377 return true;
3378 case clang::Type::MemberPointer:
3379 if (pointee_type)
3380 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003381 this, llvm::cast<clang::MemberPointerType>(qual_type)
3382 ->getPointeeType()
3383 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003384 return true;
3385 case clang::Type::Typedef:
3386 return IsPointerType(llvm::cast<clang::TypedefType>(qual_type)
3387 ->getDecl()
3388 ->getUnderlyingType()
3389 .getAsOpaquePtr(),
3390 pointee_type);
3391 case clang::Type::Auto:
3392 return IsPointerType(llvm::cast<clang::AutoType>(qual_type)
3393 ->getDeducedType()
3394 .getAsOpaquePtr(),
3395 pointee_type);
3396 case clang::Type::Elaborated:
3397 return IsPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
3398 ->getNamedType()
3399 .getAsOpaquePtr(),
3400 pointee_type);
3401 case clang::Type::Paren:
3402 return IsPointerType(
3403 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3404 pointee_type);
3405 default:
3406 break;
3407 }
3408 }
3409 if (pointee_type)
3410 pointee_type->Clear();
3411 return false;
3412}
3413
3414bool ClangASTContext::IsPointerOrReferenceType(
3415 lldb::opaque_compiler_type_t type, CompilerType *pointee_type) {
3416 if (type) {
3417 clang::QualType qual_type(GetCanonicalQualType(type));
3418 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3419 switch (type_class) {
3420 case clang::Type::Builtin:
3421 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
3422 default:
3423 break;
3424 case clang::BuiltinType::ObjCId:
3425 case clang::BuiltinType::ObjCClass:
3426 return true;
3427 }
3428 return false;
3429 case clang::Type::ObjCObjectPointer:
3430 if (pointee_type)
3431 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003432 this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
3433 ->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003434 return true;
3435 case clang::Type::BlockPointer:
3436 if (pointee_type)
3437 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003438 this, llvm::cast<clang::BlockPointerType>(qual_type)
3439 ->getPointeeType()
3440 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003441 return true;
3442 case clang::Type::Pointer:
3443 if (pointee_type)
Alex Langfordbddab072019-08-13 19:40:36 +00003444 pointee_type->SetCompilerType(this,
3445 llvm::cast<clang::PointerType>(qual_type)
3446 ->getPointeeType()
3447 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003448 return true;
3449 case clang::Type::MemberPointer:
3450 if (pointee_type)
3451 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003452 this, llvm::cast<clang::MemberPointerType>(qual_type)
3453 ->getPointeeType()
3454 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003455 return true;
3456 case clang::Type::LValueReference:
3457 if (pointee_type)
3458 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003459 this, llvm::cast<clang::LValueReferenceType>(qual_type)
3460 ->desugar()
3461 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003462 return true;
3463 case clang::Type::RValueReference:
3464 if (pointee_type)
3465 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003466 this, llvm::cast<clang::RValueReferenceType>(qual_type)
3467 ->desugar()
3468 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003469 return true;
3470 case clang::Type::Typedef:
3471 return IsPointerOrReferenceType(llvm::cast<clang::TypedefType>(qual_type)
3472 ->getDecl()
3473 ->getUnderlyingType()
3474 .getAsOpaquePtr(),
3475 pointee_type);
3476 case clang::Type::Auto:
3477 return IsPointerOrReferenceType(llvm::cast<clang::AutoType>(qual_type)
3478 ->getDeducedType()
3479 .getAsOpaquePtr(),
3480 pointee_type);
3481 case clang::Type::Elaborated:
3482 return IsPointerOrReferenceType(
3483 llvm::cast<clang::ElaboratedType>(qual_type)
3484 ->getNamedType()
3485 .getAsOpaquePtr(),
3486 pointee_type);
3487 case clang::Type::Paren:
3488 return IsPointerOrReferenceType(
3489 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3490 pointee_type);
3491 default:
3492 break;
3493 }
3494 }
3495 if (pointee_type)
3496 pointee_type->Clear();
3497 return false;
3498}
3499
3500bool ClangASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
3501 CompilerType *pointee_type,
3502 bool *is_rvalue) {
3503 if (type) {
3504 clang::QualType qual_type(GetCanonicalQualType(type));
3505 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3506
3507 switch (type_class) {
3508 case clang::Type::LValueReference:
3509 if (pointee_type)
3510 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003511 this, llvm::cast<clang::LValueReferenceType>(qual_type)
3512 ->desugar()
3513 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003514 if (is_rvalue)
3515 *is_rvalue = false;
3516 return true;
3517 case clang::Type::RValueReference:
3518 if (pointee_type)
3519 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003520 this, llvm::cast<clang::RValueReferenceType>(qual_type)
3521 ->desugar()
3522 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003523 if (is_rvalue)
3524 *is_rvalue = true;
3525 return true;
3526 case clang::Type::Typedef:
3527 return IsReferenceType(llvm::cast<clang::TypedefType>(qual_type)
3528 ->getDecl()
3529 ->getUnderlyingType()
3530 .getAsOpaquePtr(),
3531 pointee_type, is_rvalue);
3532 case clang::Type::Auto:
3533 return IsReferenceType(llvm::cast<clang::AutoType>(qual_type)
3534 ->getDeducedType()
3535 .getAsOpaquePtr(),
3536 pointee_type, is_rvalue);
3537 case clang::Type::Elaborated:
3538 return IsReferenceType(llvm::cast<clang::ElaboratedType>(qual_type)
3539 ->getNamedType()
3540 .getAsOpaquePtr(),
3541 pointee_type, is_rvalue);
3542 case clang::Type::Paren:
3543 return IsReferenceType(
3544 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3545 pointee_type, is_rvalue);
3546
3547 default:
3548 break;
3549 }
3550 }
3551 if (pointee_type)
3552 pointee_type->Clear();
3553 return false;
3554}
3555
3556bool ClangASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
3557 uint32_t &count, bool &is_complex) {
3558 if (type) {
3559 clang::QualType qual_type(GetCanonicalQualType(type));
3560
3561 if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(
3562 qual_type->getCanonicalTypeInternal())) {
3563 clang::BuiltinType::Kind kind = BT->getKind();
3564 if (kind >= clang::BuiltinType::Float &&
3565 kind <= clang::BuiltinType::LongDouble) {
3566 count = 1;
3567 is_complex = false;
3568 return true;
3569 }
3570 } else if (const clang::ComplexType *CT =
3571 llvm::dyn_cast<clang::ComplexType>(
3572 qual_type->getCanonicalTypeInternal())) {
3573 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count,
3574 is_complex)) {
3575 count = 2;
3576 is_complex = true;
3577 return true;
3578 }
3579 } else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(
3580 qual_type->getCanonicalTypeInternal())) {
3581 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count,
3582 is_complex)) {
3583 count = VT->getNumElements();
3584 is_complex = false;
3585 return true;
3586 }
3587 }
3588 }
3589 count = 0;
3590 is_complex = false;
3591 return false;
3592}
3593
3594bool ClangASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
3595 if (!type)
3596 return false;
3597
3598 clang::QualType qual_type(GetQualType(type));
3599 const clang::TagType *tag_type =
3600 llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
3601 if (tag_type) {
3602 clang::TagDecl *tag_decl = tag_type->getDecl();
3603 if (tag_decl)
3604 return tag_decl->isCompleteDefinition();
3605 return false;
3606 } else {
3607 const clang::ObjCObjectType *objc_class_type =
3608 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
3609 if (objc_class_type) {
3610 clang::ObjCInterfaceDecl *class_interface_decl =
3611 objc_class_type->getInterface();
3612 if (class_interface_decl)
3613 return class_interface_decl->getDefinition() != nullptr;
3614 return false;
3615 }
3616 }
3617 return true;
3618}
3619
3620bool ClangASTContext::IsObjCClassType(const CompilerType &type) {
3621 if (type) {
3622 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3623
3624 const clang::ObjCObjectPointerType *obj_pointer_type =
3625 llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
3626
3627 if (obj_pointer_type)
3628 return obj_pointer_type->isObjCClassType();
3629 }
3630 return false;
3631}
3632
3633bool ClangASTContext::IsObjCObjectOrInterfaceType(const CompilerType &type) {
3634 if (ClangUtil::IsClangType(type))
3635 return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
3636 return false;
3637}
3638
3639bool ClangASTContext::IsClassType(lldb::opaque_compiler_type_t type) {
3640 if (!type)
3641 return false;
3642 clang::QualType qual_type(GetCanonicalQualType(type));
3643 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3644 return (type_class == clang::Type::Record);
3645}
3646
3647bool ClangASTContext::IsEnumType(lldb::opaque_compiler_type_t type) {
3648 if (!type)
3649 return false;
3650 clang::QualType qual_type(GetCanonicalQualType(type));
3651 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3652 return (type_class == clang::Type::Enum);
3653}
3654
3655bool ClangASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
3656 if (type) {
3657 clang::QualType qual_type(GetCanonicalQualType(type));
3658 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3659 switch (type_class) {
3660 case clang::Type::Record:
3661 if (GetCompleteType(type)) {
3662 const clang::RecordType *record_type =
3663 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
3664 const clang::RecordDecl *record_decl = record_type->getDecl();
3665 if (record_decl) {
3666 const clang::CXXRecordDecl *cxx_record_decl =
3667 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
3668 if (cxx_record_decl)
3669 return cxx_record_decl->isPolymorphic();
Greg Claytond8d4a572015-08-11 21:38:15 +00003670 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003671 }
3672 break;
3673
3674 default:
3675 break;
3676 }
3677 }
3678 return false;
3679}
3680
3681bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
3682 CompilerType *dynamic_pointee_type,
3683 bool check_cplusplus,
3684 bool check_objc) {
3685 clang::QualType pointee_qual_type;
3686 if (type) {
3687 clang::QualType qual_type(GetCanonicalQualType(type));
3688 bool success = false;
3689 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3690 switch (type_class) {
3691 case clang::Type::Builtin:
3692 if (check_objc &&
3693 llvm::cast<clang::BuiltinType>(qual_type)->getKind() ==
3694 clang::BuiltinType::ObjCId) {
3695 if (dynamic_pointee_type)
3696 dynamic_pointee_type->SetCompilerType(this, type);
3697 return true;
3698 }
3699 break;
3700
3701 case clang::Type::ObjCObjectPointer:
3702 if (check_objc) {
3703 if (auto objc_pointee_type =
3704 qual_type->getPointeeType().getTypePtrOrNull()) {
3705 if (auto objc_object_type =
3706 llvm::dyn_cast_or_null<clang::ObjCObjectType>(
3707 objc_pointee_type)) {
3708 if (objc_object_type->isObjCClass())
3709 return false;
3710 }
3711 }
3712 if (dynamic_pointee_type)
3713 dynamic_pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003714 this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
3715 ->getPointeeType()
3716 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003717 return true;
3718 }
3719 break;
3720
3721 case clang::Type::Pointer:
3722 pointee_qual_type =
3723 llvm::cast<clang::PointerType>(qual_type)->getPointeeType();
3724 success = true;
3725 break;
3726
3727 case clang::Type::LValueReference:
3728 case clang::Type::RValueReference:
3729 pointee_qual_type =
3730 llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType();
3731 success = true;
3732 break;
3733
3734 case clang::Type::Typedef:
3735 return IsPossibleDynamicType(llvm::cast<clang::TypedefType>(qual_type)
3736 ->getDecl()
3737 ->getUnderlyingType()
3738 .getAsOpaquePtr(),
3739 dynamic_pointee_type, check_cplusplus,
3740 check_objc);
3741
3742 case clang::Type::Auto:
3743 return IsPossibleDynamicType(llvm::cast<clang::AutoType>(qual_type)
3744 ->getDeducedType()
3745 .getAsOpaquePtr(),
3746 dynamic_pointee_type, check_cplusplus,
3747 check_objc);
3748
3749 case clang::Type::Elaborated:
3750 return IsPossibleDynamicType(llvm::cast<clang::ElaboratedType>(qual_type)
3751 ->getNamedType()
3752 .getAsOpaquePtr(),
3753 dynamic_pointee_type, check_cplusplus,
3754 check_objc);
3755
3756 case clang::Type::Paren:
3757 return IsPossibleDynamicType(
3758 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3759 dynamic_pointee_type, check_cplusplus, check_objc);
3760 default:
3761 break;
3762 }
3763
3764 if (success) {
3765 // Check to make sure what we are pointing too is a possible dynamic C++
Adrian Prantl05097242018-04-30 16:49:04 +00003766 // type We currently accept any "void *" (in case we have a class that
3767 // has been watered down to an opaque pointer) and virtual C++ classes.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003768 const clang::Type::TypeClass pointee_type_class =
3769 pointee_qual_type.getCanonicalType()->getTypeClass();
3770 switch (pointee_type_class) {
3771 case clang::Type::Builtin:
3772 switch (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind()) {
3773 case clang::BuiltinType::UnknownAny:
3774 case clang::BuiltinType::Void:
3775 if (dynamic_pointee_type)
Alex Langfordbddab072019-08-13 19:40:36 +00003776 dynamic_pointee_type->SetCompilerType(
3777 this, pointee_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003778 return true;
3779 default:
3780 break;
3781 }
3782 break;
3783
3784 case clang::Type::Record:
3785 if (check_cplusplus) {
3786 clang::CXXRecordDecl *cxx_record_decl =
3787 pointee_qual_type->getAsCXXRecordDecl();
3788 if (cxx_record_decl) {
3789 bool is_complete = cxx_record_decl->isCompleteDefinition();
3790
3791 if (is_complete)
3792 success = cxx_record_decl->isDynamicClass();
3793 else {
3794 ClangASTMetadata *metadata = ClangASTContext::GetMetadata(
3795 getASTContext(), cxx_record_decl);
3796 if (metadata)
3797 success = metadata->GetIsDynamicCXXType();
3798 else {
Alex Langfordbddab072019-08-13 19:40:36 +00003799 is_complete =
3800 CompilerType(this, pointee_qual_type.getAsOpaquePtr())
3801 .GetCompleteType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00003802 if (is_complete)
3803 success = cxx_record_decl->isDynamicClass();
3804 else
3805 success = false;
3806 }
3807 }
3808
3809 if (success) {
3810 if (dynamic_pointee_type)
Alex Langfordbddab072019-08-13 19:40:36 +00003811 dynamic_pointee_type->SetCompilerType(
3812 this, pointee_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003813 return true;
3814 }
3815 }
3816 }
3817 break;
3818
3819 case clang::Type::ObjCObject:
3820 case clang::Type::ObjCInterface:
3821 if (check_objc) {
3822 if (dynamic_pointee_type)
Alex Langfordbddab072019-08-13 19:40:36 +00003823 dynamic_pointee_type->SetCompilerType(
3824 this, pointee_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003825 return true;
3826 }
3827 break;
3828
3829 default:
3830 break;
3831 }
3832 }
3833 }
3834 if (dynamic_pointee_type)
3835 dynamic_pointee_type->Clear();
3836 return false;
3837}
3838
3839bool ClangASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
3840 if (!type)
3841 return false;
3842
3843 return (GetTypeInfo(type, nullptr) & eTypeIsScalar) != 0;
3844}
3845
3846bool ClangASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
3847 if (!type)
3848 return false;
3849 return GetQualType(type)->getTypeClass() == clang::Type::Typedef;
3850}
3851
3852bool ClangASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
3853 if (!type)
3854 return false;
3855 return GetCanonicalQualType(type)->isVoidType();
3856}
3857
Alex Langforda03e2b22019-06-04 19:29:59 +00003858bool ClangASTContext::CanPassInRegisters(const CompilerType &type) {
3859 if (auto *record_decl =
3860 ClangASTContext::GetAsRecordDecl(type)) {
3861 return record_decl->canPassInRegisters();
3862 }
3863 return false;
3864}
3865
Kate Stoneb9c1b512016-09-06 20:57:50 +00003866bool ClangASTContext::SupportsLanguage(lldb::LanguageType language) {
3867 return ClangASTContextSupportsLanguage(language);
3868}
3869
3870bool ClangASTContext::GetCXXClassName(const CompilerType &type,
3871 std::string &class_name) {
3872 if (type) {
3873 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3874 if (!qual_type.isNull()) {
3875 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3876 if (cxx_record_decl) {
3877 class_name.assign(cxx_record_decl->getIdentifier()->getNameStart());
3878 return true;
3879 }
3880 }
3881 }
3882 class_name.clear();
3883 return false;
3884}
3885
3886bool ClangASTContext::IsCXXClassType(const CompilerType &type) {
3887 if (!type)
3888 return false;
3889
3890 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
Jonas Devliegherea6682a42018-12-15 00:15:33 +00003891 return !qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003892}
3893
3894bool ClangASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
3895 if (!type)
3896 return false;
3897 clang::QualType qual_type(GetCanonicalQualType(type));
3898 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type);
3899 if (tag_type)
3900 return tag_type->isBeingDefined();
3901 return false;
3902}
3903
3904bool ClangASTContext::IsObjCObjectPointerType(const CompilerType &type,
3905 CompilerType *class_type_ptr) {
3906 if (!type)
3907 return false;
3908
3909 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3910
3911 if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) {
3912 if (class_type_ptr) {
3913 if (!qual_type->isObjCClassType() && !qual_type->isObjCIdType()) {
3914 const clang::ObjCObjectPointerType *obj_pointer_type =
3915 llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
3916 if (obj_pointer_type == nullptr)
3917 class_type_ptr->Clear();
3918 else
3919 class_type_ptr->SetCompilerType(
3920 type.GetTypeSystem(),
3921 clang::QualType(obj_pointer_type->getInterfaceType(), 0)
3922 .getAsOpaquePtr());
3923 }
Greg Claytond8d4a572015-08-11 21:38:15 +00003924 }
3925 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003926 }
3927 if (class_type_ptr)
3928 class_type_ptr->Clear();
3929 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00003930}
3931
Kate Stoneb9c1b512016-09-06 20:57:50 +00003932bool ClangASTContext::GetObjCClassName(const CompilerType &type,
3933 std::string &class_name) {
3934 if (!type)
3935 return false;
Zachary Turnerd133f6a2016-03-28 22:53:41 +00003936
Kate Stoneb9c1b512016-09-06 20:57:50 +00003937 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3938
3939 const clang::ObjCObjectType *object_type =
3940 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
3941 if (object_type) {
3942 const clang::ObjCInterfaceDecl *interface = object_type->getInterface();
3943 if (interface) {
3944 class_name = interface->getNameAsString();
3945 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00003946 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003947 }
3948 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00003949}
3950
Greg Claytond8d4a572015-08-11 21:38:15 +00003951// Type Completion
Greg Claytond8d4a572015-08-11 21:38:15 +00003952
Kate Stoneb9c1b512016-09-06 20:57:50 +00003953bool ClangASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
3954 if (!type)
3955 return false;
3956 const bool allow_completion = true;
3957 return GetCompleteQualType(getASTContext(), GetQualType(type),
3958 allow_completion);
Greg Claytond8d4a572015-08-11 21:38:15 +00003959}
3960
Kate Stoneb9c1b512016-09-06 20:57:50 +00003961ConstString ClangASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
3962 std::string type_name;
3963 if (type) {
3964 clang::PrintingPolicy printing_policy(getASTContext()->getPrintingPolicy());
3965 clang::QualType qual_type(GetQualType(type));
3966 printing_policy.SuppressTagKeyword = true;
3967 const clang::TypedefType *typedef_type =
3968 qual_type->getAs<clang::TypedefType>();
3969 if (typedef_type) {
3970 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
3971 type_name = typedef_decl->getQualifiedNameAsString();
3972 } else {
3973 type_name = qual_type.getAsString(printing_policy);
Greg Claytond8d4a572015-08-11 21:38:15 +00003974 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003975 }
3976 return ConstString(type_name);
Greg Claytond8d4a572015-08-11 21:38:15 +00003977}
3978
3979uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00003980ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
3981 CompilerType *pointee_or_element_clang_type) {
3982 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00003983 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003984
3985 if (pointee_or_element_clang_type)
3986 pointee_or_element_clang_type->Clear();
3987
3988 clang::QualType qual_type(GetQualType(type));
3989
3990 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3991 switch (type_class) {
Sean Callananddf802a2017-06-02 01:24:18 +00003992 case clang::Type::Attributed:
3993 return GetTypeInfo(
3994 qual_type->getAs<clang::AttributedType>()
3995 ->getModifiedType().getAsOpaquePtr(),
3996 pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003997 case clang::Type::Builtin: {
3998 const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(
3999 qual_type->getCanonicalTypeInternal());
4000
4001 uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
4002 switch (builtin_type->getKind()) {
4003 case clang::BuiltinType::ObjCId:
4004 case clang::BuiltinType::ObjCClass:
4005 if (pointee_or_element_clang_type)
4006 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004007 this, getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004008 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
4009 break;
4010
4011 case clang::BuiltinType::ObjCSel:
4012 if (pointee_or_element_clang_type)
Alex Langfordbddab072019-08-13 19:40:36 +00004013 pointee_or_element_clang_type->SetCompilerType(
4014 this, getASTContext()->CharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004015 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
4016 break;
4017
4018 case clang::BuiltinType::Bool:
4019 case clang::BuiltinType::Char_U:
4020 case clang::BuiltinType::UChar:
4021 case clang::BuiltinType::WChar_U:
4022 case clang::BuiltinType::Char16:
4023 case clang::BuiltinType::Char32:
4024 case clang::BuiltinType::UShort:
4025 case clang::BuiltinType::UInt:
4026 case clang::BuiltinType::ULong:
4027 case clang::BuiltinType::ULongLong:
4028 case clang::BuiltinType::UInt128:
4029 case clang::BuiltinType::Char_S:
4030 case clang::BuiltinType::SChar:
4031 case clang::BuiltinType::WChar_S:
4032 case clang::BuiltinType::Short:
4033 case clang::BuiltinType::Int:
4034 case clang::BuiltinType::Long:
4035 case clang::BuiltinType::LongLong:
4036 case clang::BuiltinType::Int128:
4037 case clang::BuiltinType::Float:
4038 case clang::BuiltinType::Double:
4039 case clang::BuiltinType::LongDouble:
4040 builtin_type_flags |= eTypeIsScalar;
4041 if (builtin_type->isInteger()) {
4042 builtin_type_flags |= eTypeIsInteger;
4043 if (builtin_type->isSignedInteger())
4044 builtin_type_flags |= eTypeIsSigned;
4045 } else if (builtin_type->isFloatingPoint())
4046 builtin_type_flags |= eTypeIsFloat;
4047 break;
4048 default:
4049 break;
4050 }
4051 return builtin_type_flags;
4052 }
4053
4054 case clang::Type::BlockPointer:
4055 if (pointee_or_element_clang_type)
4056 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004057 this, qual_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004058 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
4059
4060 case clang::Type::Complex: {
4061 uint32_t complex_type_flags =
4062 eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
4063 const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(
4064 qual_type->getCanonicalTypeInternal());
4065 if (complex_type) {
4066 clang::QualType complex_element_type(complex_type->getElementType());
4067 if (complex_element_type->isIntegerType())
4068 complex_type_flags |= eTypeIsFloat;
4069 else if (complex_element_type->isFloatingType())
4070 complex_type_flags |= eTypeIsInteger;
4071 }
4072 return complex_type_flags;
4073 } break;
4074
4075 case clang::Type::ConstantArray:
4076 case clang::Type::DependentSizedArray:
4077 case clang::Type::IncompleteArray:
4078 case clang::Type::VariableArray:
4079 if (pointee_or_element_clang_type)
4080 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004081 this, llvm::cast<clang::ArrayType>(qual_type.getTypePtr())
4082 ->getElementType()
4083 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004084 return eTypeHasChildren | eTypeIsArray;
4085
4086 case clang::Type::DependentName:
4087 return 0;
4088 case clang::Type::DependentSizedExtVector:
4089 return eTypeHasChildren | eTypeIsVector;
4090 case clang::Type::DependentTemplateSpecialization:
4091 return eTypeIsTemplate;
4092 case clang::Type::Decltype:
Alex Langfordbddab072019-08-13 19:40:36 +00004093 return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type)
4094 ->getUnderlyingType()
4095 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004096 .GetTypeInfo(pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004097
4098 case clang::Type::Enum:
4099 if (pointee_or_element_clang_type)
4100 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004101 this, llvm::cast<clang::EnumType>(qual_type)
4102 ->getDecl()
4103 ->getIntegerType()
4104 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004105 return eTypeIsEnumeration | eTypeHasValue;
4106
4107 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00004108 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
4109 ->getDeducedType()
4110 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004111 .GetTypeInfo(pointee_or_element_clang_type);
4112 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00004113 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
4114 ->getNamedType()
4115 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004116 .GetTypeInfo(pointee_or_element_clang_type);
4117 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00004118 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
4119 ->desugar()
4120 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004121 .GetTypeInfo(pointee_or_element_clang_type);
4122
4123 case clang::Type::FunctionProto:
4124 return eTypeIsFuncPrototype | eTypeHasValue;
4125 case clang::Type::FunctionNoProto:
4126 return eTypeIsFuncPrototype | eTypeHasValue;
4127 case clang::Type::InjectedClassName:
4128 return 0;
4129
4130 case clang::Type::LValueReference:
4131 case clang::Type::RValueReference:
4132 if (pointee_or_element_clang_type)
4133 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004134 this, llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())
4135 ->getPointeeType()
4136 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004137 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
4138
4139 case clang::Type::MemberPointer:
4140 return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
4141
4142 case clang::Type::ObjCObjectPointer:
4143 if (pointee_or_element_clang_type)
4144 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004145 this, qual_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004146 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer |
4147 eTypeHasValue;
4148
4149 case clang::Type::ObjCObject:
4150 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
4151 case clang::Type::ObjCInterface:
4152 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
4153
4154 case clang::Type::Pointer:
4155 if (pointee_or_element_clang_type)
4156 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004157 this, qual_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004158 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
4159
4160 case clang::Type::Record:
4161 if (qual_type->getAsCXXRecordDecl())
4162 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
4163 else
4164 return eTypeHasChildren | eTypeIsStructUnion;
4165 break;
4166 case clang::Type::SubstTemplateTypeParm:
4167 return eTypeIsTemplate;
4168 case clang::Type::TemplateTypeParm:
4169 return eTypeIsTemplate;
4170 case clang::Type::TemplateSpecialization:
4171 return eTypeIsTemplate;
4172
4173 case clang::Type::Typedef:
4174 return eTypeIsTypedef |
Alex Langfordbddab072019-08-13 19:40:36 +00004175 CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
4176 ->getDecl()
4177 ->getUnderlyingType()
4178 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004179 .GetTypeInfo(pointee_or_element_clang_type);
4180 case clang::Type::TypeOfExpr:
Alex Langfordbddab072019-08-13 19:40:36 +00004181 return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
4182 ->getUnderlyingExpr()
4183 ->getType()
4184 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004185 .GetTypeInfo(pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004186 case clang::Type::TypeOf:
Alex Langfordbddab072019-08-13 19:40:36 +00004187 return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
4188 ->getUnderlyingType()
4189 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004190 .GetTypeInfo(pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004191 case clang::Type::UnresolvedUsing:
4192 return 0;
4193
4194 case clang::Type::ExtVector:
4195 case clang::Type::Vector: {
4196 uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
4197 const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>(
4198 qual_type->getCanonicalTypeInternal());
4199 if (vector_type) {
4200 if (vector_type->isIntegerType())
4201 vector_type_flags |= eTypeIsFloat;
4202 else if (vector_type->isFloatingType())
4203 vector_type_flags |= eTypeIsInteger;
4204 }
4205 return vector_type_flags;
4206 }
4207 default:
4208 return 0;
4209 }
4210 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00004211}
4212
Greg Claytond8d4a572015-08-11 21:38:15 +00004213lldb::LanguageType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004214ClangASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
4215 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00004216 return lldb::eLanguageTypeC;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004217
4218 // If the type is a reference, then resolve it to what it refers to first:
4219 clang::QualType qual_type(GetCanonicalQualType(type).getNonReferenceType());
4220 if (qual_type->isAnyPointerType()) {
4221 if (qual_type->isObjCObjectPointerType())
4222 return lldb::eLanguageTypeObjC;
Adrian Prantl1db0f0c2019-05-02 23:07:23 +00004223 if (qual_type->getPointeeCXXRecordDecl())
4224 return lldb::eLanguageTypeC_plus_plus;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004225
4226 clang::QualType pointee_type(qual_type->getPointeeType());
Adrian Prantl1db0f0c2019-05-02 23:07:23 +00004227 if (pointee_type->getPointeeCXXRecordDecl())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004228 return lldb::eLanguageTypeC_plus_plus;
4229 if (pointee_type->isObjCObjectOrInterfaceType())
4230 return lldb::eLanguageTypeObjC;
4231 if (pointee_type->isObjCClassType())
4232 return lldb::eLanguageTypeObjC;
4233 if (pointee_type.getTypePtr() ==
4234 getASTContext()->ObjCBuiltinIdTy.getTypePtr())
4235 return lldb::eLanguageTypeObjC;
4236 } else {
4237 if (qual_type->isObjCObjectOrInterfaceType())
4238 return lldb::eLanguageTypeObjC;
4239 if (qual_type->getAsCXXRecordDecl())
4240 return lldb::eLanguageTypeC_plus_plus;
4241 switch (qual_type->getTypeClass()) {
4242 default:
4243 break;
4244 case clang::Type::Builtin:
4245 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
4246 default:
4247 case clang::BuiltinType::Void:
4248 case clang::BuiltinType::Bool:
4249 case clang::BuiltinType::Char_U:
4250 case clang::BuiltinType::UChar:
4251 case clang::BuiltinType::WChar_U:
4252 case clang::BuiltinType::Char16:
4253 case clang::BuiltinType::Char32:
4254 case clang::BuiltinType::UShort:
4255 case clang::BuiltinType::UInt:
4256 case clang::BuiltinType::ULong:
4257 case clang::BuiltinType::ULongLong:
4258 case clang::BuiltinType::UInt128:
4259 case clang::BuiltinType::Char_S:
4260 case clang::BuiltinType::SChar:
4261 case clang::BuiltinType::WChar_S:
4262 case clang::BuiltinType::Short:
4263 case clang::BuiltinType::Int:
4264 case clang::BuiltinType::Long:
4265 case clang::BuiltinType::LongLong:
4266 case clang::BuiltinType::Int128:
4267 case clang::BuiltinType::Float:
4268 case clang::BuiltinType::Double:
4269 case clang::BuiltinType::LongDouble:
4270 break;
4271
4272 case clang::BuiltinType::NullPtr:
4273 return eLanguageTypeC_plus_plus;
4274
4275 case clang::BuiltinType::ObjCId:
4276 case clang::BuiltinType::ObjCClass:
4277 case clang::BuiltinType::ObjCSel:
4278 return eLanguageTypeObjC;
4279
4280 case clang::BuiltinType::Dependent:
4281 case clang::BuiltinType::Overload:
4282 case clang::BuiltinType::BoundMember:
4283 case clang::BuiltinType::UnknownAny:
4284 break;
4285 }
4286 break;
4287 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00004288 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
4289 ->getDecl()
4290 ->getUnderlyingType()
4291 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004292 .GetMinimumLanguage();
4293 }
4294 }
4295 return lldb::eLanguageTypeC;
Greg Claytond8d4a572015-08-11 21:38:15 +00004296}
4297
4298lldb::TypeClass
Kate Stoneb9c1b512016-09-06 20:57:50 +00004299ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
4300 if (!type)
4301 return lldb::eTypeClassInvalid;
4302
4303 clang::QualType qual_type(GetQualType(type));
4304
4305 switch (qual_type->getTypeClass()) {
4306 case clang::Type::UnaryTransform:
4307 break;
4308 case clang::Type::FunctionNoProto:
4309 return lldb::eTypeClassFunction;
4310 case clang::Type::FunctionProto:
4311 return lldb::eTypeClassFunction;
4312 case clang::Type::IncompleteArray:
4313 return lldb::eTypeClassArray;
4314 case clang::Type::VariableArray:
4315 return lldb::eTypeClassArray;
4316 case clang::Type::ConstantArray:
4317 return lldb::eTypeClassArray;
4318 case clang::Type::DependentSizedArray:
4319 return lldb::eTypeClassArray;
4320 case clang::Type::DependentSizedExtVector:
4321 return lldb::eTypeClassVector;
Fangrui Song8f284882018-07-13 22:40:40 +00004322 case clang::Type::DependentVector:
4323 return lldb::eTypeClassVector;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004324 case clang::Type::ExtVector:
4325 return lldb::eTypeClassVector;
4326 case clang::Type::Vector:
4327 return lldb::eTypeClassVector;
4328 case clang::Type::Builtin:
4329 return lldb::eTypeClassBuiltin;
4330 case clang::Type::ObjCObjectPointer:
4331 return lldb::eTypeClassObjCObjectPointer;
4332 case clang::Type::BlockPointer:
4333 return lldb::eTypeClassBlockPointer;
4334 case clang::Type::Pointer:
4335 return lldb::eTypeClassPointer;
4336 case clang::Type::LValueReference:
4337 return lldb::eTypeClassReference;
4338 case clang::Type::RValueReference:
4339 return lldb::eTypeClassReference;
4340 case clang::Type::MemberPointer:
4341 return lldb::eTypeClassMemberPointer;
4342 case clang::Type::Complex:
4343 if (qual_type->isComplexType())
4344 return lldb::eTypeClassComplexFloat;
4345 else
4346 return lldb::eTypeClassComplexInteger;
4347 case clang::Type::ObjCObject:
4348 return lldb::eTypeClassObjCObject;
4349 case clang::Type::ObjCInterface:
4350 return lldb::eTypeClassObjCInterface;
4351 case clang::Type::Record: {
4352 const clang::RecordType *record_type =
4353 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4354 const clang::RecordDecl *record_decl = record_type->getDecl();
4355 if (record_decl->isUnion())
4356 return lldb::eTypeClassUnion;
4357 else if (record_decl->isStruct())
4358 return lldb::eTypeClassStruct;
4359 else
4360 return lldb::eTypeClassClass;
4361 } break;
4362 case clang::Type::Enum:
4363 return lldb::eTypeClassEnumeration;
4364 case clang::Type::Typedef:
4365 return lldb::eTypeClassTypedef;
4366 case clang::Type::UnresolvedUsing:
4367 break;
4368 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00004369 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
4370 ->desugar()
4371 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004372 .GetTypeClass();
4373 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00004374 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
4375 ->getDeducedType()
4376 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004377 .GetTypeClass();
4378 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00004379 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
4380 ->getNamedType()
4381 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004382 .GetTypeClass();
4383
4384 case clang::Type::Attributed:
4385 break;
4386 case clang::Type::TemplateTypeParm:
4387 break;
4388 case clang::Type::SubstTemplateTypeParm:
4389 break;
4390 case clang::Type::SubstTemplateTypeParmPack:
4391 break;
4392 case clang::Type::InjectedClassName:
4393 break;
4394 case clang::Type::DependentName:
4395 break;
4396 case clang::Type::DependentTemplateSpecialization:
4397 break;
4398 case clang::Type::PackExpansion:
4399 break;
4400
4401 case clang::Type::TypeOfExpr:
Alex Langfordbddab072019-08-13 19:40:36 +00004402 return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
4403 ->getUnderlyingExpr()
4404 ->getType()
4405 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004406 .GetTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00004407 case clang::Type::TypeOf:
Alex Langfordbddab072019-08-13 19:40:36 +00004408 return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
4409 ->getUnderlyingType()
4410 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004411 .GetTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00004412 case clang::Type::Decltype:
Alex Langfordbddab072019-08-13 19:40:36 +00004413 return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
4414 ->getUnderlyingType()
4415 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004416 .GetTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00004417 case clang::Type::TemplateSpecialization:
4418 break;
Pavel Labath4f19fce22017-02-17 13:39:50 +00004419 case clang::Type::DeducedTemplateSpecialization:
4420 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004421 case clang::Type::Atomic:
4422 break;
4423 case clang::Type::Pipe:
4424 break;
4425
4426 // pointer type decayed from an array or function type.
4427 case clang::Type::Decayed:
4428 break;
4429 case clang::Type::Adjusted:
4430 break;
Zachary Turner5a8ad4592016-10-05 17:07:34 +00004431 case clang::Type::ObjCTypeParam:
4432 break;
Ted Woodward66060cf2017-10-11 22:42:21 +00004433
4434 case clang::Type::DependentAddressSpace:
4435 break;
Krasimir Georgiev435e76a2019-05-07 13:59:30 +00004436 case clang::Type::MacroQualified:
4437 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004438 }
4439 // We don't know hot to display this type...
4440 return lldb::eTypeClassOther;
Greg Claytond8d4a572015-08-11 21:38:15 +00004441}
4442
Kate Stoneb9c1b512016-09-06 20:57:50 +00004443unsigned ClangASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
4444 if (type)
4445 return GetQualType(type).getQualifiers().getCVRQualifiers();
4446 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00004447}
4448
Greg Claytond8d4a572015-08-11 21:38:15 +00004449// Creating related types
Greg Claytond8d4a572015-08-11 21:38:15 +00004450
Greg Claytona1e5dc82015-08-11 22:53:00 +00004451CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004452ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
4453 uint64_t *stride) {
4454 if (type) {
4455 clang::QualType qual_type(GetCanonicalQualType(type));
4456
4457 const clang::Type *array_eletype =
4458 qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
4459
4460 if (!array_eletype)
4461 return CompilerType();
4462
Alex Langfordbddab072019-08-13 19:40:36 +00004463 CompilerType element_type(
4464 this, array_eletype->getCanonicalTypeUnqualified().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004465
4466 // TODO: the real stride will be >= this value.. find the real one!
4467 if (stride)
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00004468 if (Optional<uint64_t> size = element_type.GetByteSize(nullptr))
Adrian Prantld963a7c2019-01-15 18:07:52 +00004469 *stride = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004470
4471 return element_type;
4472 }
4473 return CompilerType();
4474}
4475
4476CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type,
4477 uint64_t size) {
4478 if (type) {
4479 clang::QualType qual_type(GetCanonicalQualType(type));
4480 if (clang::ASTContext *ast_ctx = getASTContext()) {
4481 if (size != 0)
4482 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004483 this, ast_ctx
4484 ->getConstantArrayType(
4485 qual_type, llvm::APInt(64, size),
4486 clang::ArrayType::ArraySizeModifier::Normal, 0)
4487 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004488 else
4489 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004490 this,
4491 ast_ctx
4492 ->getIncompleteArrayType(
4493 qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0)
4494 .getAsOpaquePtr());
Greg Claytond8d4a572015-08-11 21:38:15 +00004495 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004496 }
4497
4498 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004499}
4500
Greg Claytona1e5dc82015-08-11 22:53:00 +00004501CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004502ClangASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
4503 if (type)
Alex Langfordbddab072019-08-13 19:40:36 +00004504 return CompilerType(this, GetCanonicalQualType(type).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004505 return CompilerType();
4506}
4507
4508static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast,
4509 clang::QualType qual_type) {
4510 if (qual_type->isPointerType())
4511 qual_type = ast->getPointerType(
4512 GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType()));
4513 else
4514 qual_type = qual_type.getUnqualifiedType();
4515 qual_type.removeLocalConst();
4516 qual_type.removeLocalRestrict();
4517 qual_type.removeLocalVolatile();
4518 return qual_type;
Enrico Granata639392f2016-08-30 20:39:58 +00004519}
4520
4521CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004522ClangASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
4523 if (type)
4524 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004525 this,
4526 GetFullyUnqualifiedType_Impl(getASTContext(), GetQualType(type)).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004527 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004528}
4529
Kate Stoneb9c1b512016-09-06 20:57:50 +00004530int ClangASTContext::GetFunctionArgumentCount(
4531 lldb::opaque_compiler_type_t type) {
4532 if (type) {
4533 const clang::FunctionProtoType *func =
4534 llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType(type));
4535 if (func)
4536 return func->getNumParams();
4537 }
4538 return -1;
4539}
4540
4541CompilerType ClangASTContext::GetFunctionArgumentTypeAtIndex(
4542 lldb::opaque_compiler_type_t type, size_t idx) {
4543 if (type) {
4544 const clang::FunctionProtoType *func =
4545 llvm::dyn_cast<clang::FunctionProtoType>(GetQualType(type));
4546 if (func) {
4547 const uint32_t num_args = func->getNumParams();
4548 if (idx < num_args)
Alex Langfordbddab072019-08-13 19:40:36 +00004549 return CompilerType(this, func->getParamType(idx).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004550 }
4551 }
4552 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004553}
4554
Greg Claytona1e5dc82015-08-11 22:53:00 +00004555CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004556ClangASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
4557 if (type) {
4558 clang::QualType qual_type(GetQualType(type));
4559 const clang::FunctionProtoType *func =
4560 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
4561 if (func)
Alex Langfordbddab072019-08-13 19:40:36 +00004562 return CompilerType(this, func->getReturnType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004563 }
4564 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004565}
4566
4567size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00004568ClangASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
4569 size_t num_functions = 0;
4570 if (type) {
4571 clang::QualType qual_type(GetCanonicalQualType(type));
4572 switch (qual_type->getTypeClass()) {
4573 case clang::Type::Record:
4574 if (GetCompleteQualType(getASTContext(), qual_type)) {
4575 const clang::RecordType *record_type =
4576 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4577 const clang::RecordDecl *record_decl = record_type->getDecl();
4578 assert(record_decl);
4579 const clang::CXXRecordDecl *cxx_record_decl =
4580 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
4581 if (cxx_record_decl)
4582 num_functions = std::distance(cxx_record_decl->method_begin(),
4583 cxx_record_decl->method_end());
4584 }
4585 break;
Enrico Granata36f51e42015-12-18 22:41:25 +00004586
Sean Callananf9c622a2016-09-30 18:44:43 +00004587 case clang::Type::ObjCObjectPointer: {
4588 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00004589 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00004590 const clang::ObjCInterfaceType *objc_interface_type =
4591 objc_class_type->getInterfaceType();
4592 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00004593 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
4594 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00004595 clang::ObjCInterfaceDecl *class_interface_decl =
4596 objc_interface_type->getDecl();
4597 if (class_interface_decl) {
4598 num_functions = std::distance(class_interface_decl->meth_begin(),
4599 class_interface_decl->meth_end());
Greg Claytond8d4a572015-08-11 21:38:15 +00004600 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004601 }
4602 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00004603 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004604
4605 case clang::Type::ObjCObject:
4606 case clang::Type::ObjCInterface:
4607 if (GetCompleteType(type)) {
4608 const clang::ObjCObjectType *objc_class_type =
4609 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
4610 if (objc_class_type) {
4611 clang::ObjCInterfaceDecl *class_interface_decl =
4612 objc_class_type->getInterface();
4613 if (class_interface_decl)
4614 num_functions = std::distance(class_interface_decl->meth_begin(),
4615 class_interface_decl->meth_end());
4616 }
4617 }
4618 break;
4619
4620 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00004621 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
4622 ->getDecl()
4623 ->getUnderlyingType()
4624 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004625 .GetNumMemberFunctions();
4626
4627 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00004628 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
4629 ->getDeducedType()
4630 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004631 .GetNumMemberFunctions();
4632
4633 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00004634 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
4635 ->getNamedType()
4636 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004637 .GetNumMemberFunctions();
4638
4639 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00004640 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
4641 ->desugar()
4642 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004643 .GetNumMemberFunctions();
4644
4645 default:
4646 break;
Greg Claytond8d4a572015-08-11 21:38:15 +00004647 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004648 }
4649 return num_functions;
Greg Claytond8d4a572015-08-11 21:38:15 +00004650}
4651
4652TypeMemberFunctionImpl
Kate Stoneb9c1b512016-09-06 20:57:50 +00004653ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
4654 size_t idx) {
4655 std::string name;
4656 MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
4657 CompilerType clang_type;
4658 CompilerDecl clang_decl;
4659 if (type) {
4660 clang::QualType qual_type(GetCanonicalQualType(type));
4661 switch (qual_type->getTypeClass()) {
4662 case clang::Type::Record:
4663 if (GetCompleteQualType(getASTContext(), qual_type)) {
4664 const clang::RecordType *record_type =
4665 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4666 const clang::RecordDecl *record_decl = record_type->getDecl();
4667 assert(record_decl);
4668 const clang::CXXRecordDecl *cxx_record_decl =
4669 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
4670 if (cxx_record_decl) {
4671 auto method_iter = cxx_record_decl->method_begin();
4672 auto method_end = cxx_record_decl->method_end();
4673 if (idx <
4674 static_cast<size_t>(std::distance(method_iter, method_end))) {
4675 std::advance(method_iter, idx);
4676 clang::CXXMethodDecl *cxx_method_decl =
4677 method_iter->getCanonicalDecl();
4678 if (cxx_method_decl) {
4679 name = cxx_method_decl->getDeclName().getAsString();
4680 if (cxx_method_decl->isStatic())
4681 kind = lldb::eMemberFunctionKindStaticMethod;
4682 else if (llvm::isa<clang::CXXConstructorDecl>(cxx_method_decl))
4683 kind = lldb::eMemberFunctionKindConstructor;
4684 else if (llvm::isa<clang::CXXDestructorDecl>(cxx_method_decl))
4685 kind = lldb::eMemberFunctionKindDestructor;
4686 else
4687 kind = lldb::eMemberFunctionKindInstanceMethod;
4688 clang_type = CompilerType(
4689 this, cxx_method_decl->getType().getAsOpaquePtr());
4690 clang_decl = CompilerDecl(this, cxx_method_decl);
4691 }
4692 }
Greg Claytond8d4a572015-08-11 21:38:15 +00004693 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004694 }
4695 break;
Greg Claytond8d4a572015-08-11 21:38:15 +00004696
Sean Callananf9c622a2016-09-30 18:44:43 +00004697 case clang::Type::ObjCObjectPointer: {
4698 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00004699 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00004700 const clang::ObjCInterfaceType *objc_interface_type =
4701 objc_class_type->getInterfaceType();
4702 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00004703 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
4704 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00004705 clang::ObjCInterfaceDecl *class_interface_decl =
4706 objc_interface_type->getDecl();
4707 if (class_interface_decl) {
4708 auto method_iter = class_interface_decl->meth_begin();
4709 auto method_end = class_interface_decl->meth_end();
4710 if (idx <
4711 static_cast<size_t>(std::distance(method_iter, method_end))) {
4712 std::advance(method_iter, idx);
4713 clang::ObjCMethodDecl *objc_method_decl =
4714 method_iter->getCanonicalDecl();
4715 if (objc_method_decl) {
4716 clang_decl = CompilerDecl(this, objc_method_decl);
4717 name = objc_method_decl->getSelector().getAsString();
4718 if (objc_method_decl->isClassMethod())
4719 kind = lldb::eMemberFunctionKindStaticMethod;
4720 else
4721 kind = lldb::eMemberFunctionKindInstanceMethod;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004722 }
4723 }
Greg Claytond8d4a572015-08-11 21:38:15 +00004724 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004725 }
4726 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00004727 }
Greg Claytond8d4a572015-08-11 21:38:15 +00004728
Kate Stoneb9c1b512016-09-06 20:57:50 +00004729 case clang::Type::ObjCObject:
4730 case clang::Type::ObjCInterface:
4731 if (GetCompleteType(type)) {
4732 const clang::ObjCObjectType *objc_class_type =
4733 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
4734 if (objc_class_type) {
4735 clang::ObjCInterfaceDecl *class_interface_decl =
4736 objc_class_type->getInterface();
4737 if (class_interface_decl) {
4738 auto method_iter = class_interface_decl->meth_begin();
4739 auto method_end = class_interface_decl->meth_end();
4740 if (idx <
4741 static_cast<size_t>(std::distance(method_iter, method_end))) {
4742 std::advance(method_iter, idx);
4743 clang::ObjCMethodDecl *objc_method_decl =
4744 method_iter->getCanonicalDecl();
4745 if (objc_method_decl) {
4746 clang_decl = CompilerDecl(this, objc_method_decl);
4747 name = objc_method_decl->getSelector().getAsString();
4748 if (objc_method_decl->isClassMethod())
4749 kind = lldb::eMemberFunctionKindStaticMethod;
4750 else
4751 kind = lldb::eMemberFunctionKindInstanceMethod;
4752 }
4753 }
4754 }
Ewan Crawford27fc7a72016-03-15 09:50:16 +00004755 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004756 }
4757 break;
Ewan Crawford27fc7a72016-03-15 09:50:16 +00004758
Kate Stoneb9c1b512016-09-06 20:57:50 +00004759 case clang::Type::Typedef:
4760 return GetMemberFunctionAtIndex(llvm::cast<clang::TypedefType>(qual_type)
4761 ->getDecl()
4762 ->getUnderlyingType()
4763 .getAsOpaquePtr(),
4764 idx);
Ewan Crawford27fc7a72016-03-15 09:50:16 +00004765
Kate Stoneb9c1b512016-09-06 20:57:50 +00004766 case clang::Type::Auto:
4767 return GetMemberFunctionAtIndex(llvm::cast<clang::AutoType>(qual_type)
4768 ->getDeducedType()
4769 .getAsOpaquePtr(),
4770 idx);
Greg Clayton56939cb2015-09-17 22:23:34 +00004771
Kate Stoneb9c1b512016-09-06 20:57:50 +00004772 case clang::Type::Elaborated:
4773 return GetMemberFunctionAtIndex(
4774 llvm::cast<clang::ElaboratedType>(qual_type)
4775 ->getNamedType()
4776 .getAsOpaquePtr(),
4777 idx);
Greg Clayton56939cb2015-09-17 22:23:34 +00004778
Kate Stoneb9c1b512016-09-06 20:57:50 +00004779 case clang::Type::Paren:
4780 return GetMemberFunctionAtIndex(
4781 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
4782 idx);
4783
4784 default:
4785 break;
Greg Clayton56939cb2015-09-17 22:23:34 +00004786 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004787 }
Greg Clayton56939cb2015-09-17 22:23:34 +00004788
Kate Stoneb9c1b512016-09-06 20:57:50 +00004789 if (kind == eMemberFunctionKindUnknown)
4790 return TypeMemberFunctionImpl();
4791 else
4792 return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
Greg Clayton56939cb2015-09-17 22:23:34 +00004793}
4794
Greg Claytona1e5dc82015-08-11 22:53:00 +00004795CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004796ClangASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
4797 if (type)
Alex Langfordbddab072019-08-13 19:40:36 +00004798 return CompilerType(
4799 this, GetQualType(type).getNonReferenceType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004800 return CompilerType();
4801}
4802
4803CompilerType ClangASTContext::CreateTypedefType(
4804 const CompilerType &type, const char *typedef_name,
4805 const CompilerDeclContext &compiler_decl_ctx) {
4806 if (type && typedef_name && typedef_name[0]) {
4807 ClangASTContext *ast =
4808 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
4809 if (!ast)
4810 return CompilerType();
4811 clang::ASTContext *clang_ast = ast->getASTContext();
4812 clang::QualType qual_type(ClangUtil::GetQualType(type));
4813
4814 clang::DeclContext *decl_ctx =
4815 ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
4816 if (decl_ctx == nullptr)
4817 decl_ctx = ast->getASTContext()->getTranslationUnitDecl();
4818
4819 clang::TypedefDecl *decl = clang::TypedefDecl::Create(
4820 *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
4821 &clang_ast->Idents.get(typedef_name),
4822 clang_ast->getTrivialTypeSourceInfo(qual_type));
4823
4824 decl->setAccess(clang::AS_public); // TODO respect proper access specifier
4825
Aleksandr Urakov709426b2018-09-10 08:08:43 +00004826 decl_ctx->addDecl(decl);
4827
Kate Stoneb9c1b512016-09-06 20:57:50 +00004828 // Get a uniqued clang::QualType for the typedef decl type
Alex Langfordbddab072019-08-13 19:40:36 +00004829 return CompilerType(ast, clang_ast->getTypedefType(decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004830 }
4831 return CompilerType();
4832}
4833
4834CompilerType
4835ClangASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
4836 if (type) {
4837 clang::QualType qual_type(GetQualType(type));
Alex Langfordbddab072019-08-13 19:40:36 +00004838 return CompilerType(
4839 this, qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004840 }
4841 return CompilerType();
4842}
4843
4844CompilerType
4845ClangASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
4846 if (type) {
4847 clang::QualType qual_type(GetQualType(type));
4848
4849 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4850 switch (type_class) {
4851 case clang::Type::ObjCObject:
4852 case clang::Type::ObjCInterface:
Alex Langfordbddab072019-08-13 19:40:36 +00004853 return CompilerType(this, getASTContext()
4854 ->getObjCObjectPointerType(qual_type)
4855 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004856
4857 default:
Alex Langfordbddab072019-08-13 19:40:36 +00004858 return CompilerType(
4859 this, getASTContext()->getPointerType(qual_type).getAsOpaquePtr());
Greg Claytond8d4a572015-08-11 21:38:15 +00004860 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004861 }
4862 return CompilerType();
4863}
4864
4865CompilerType
4866ClangASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
4867 if (type)
4868 return CompilerType(this, getASTContext()
4869 ->getLValueReferenceType(GetQualType(type))
4870 .getAsOpaquePtr());
4871 else
Greg Claytona1e5dc82015-08-11 22:53:00 +00004872 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004873}
4874
Kate Stoneb9c1b512016-09-06 20:57:50 +00004875CompilerType
4876ClangASTContext::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
4877 if (type)
4878 return CompilerType(this, getASTContext()
4879 ->getRValueReferenceType(GetQualType(type))
4880 .getAsOpaquePtr());
4881 else
4882 return CompilerType();
4883}
4884
4885CompilerType
4886ClangASTContext::AddConstModifier(lldb::opaque_compiler_type_t type) {
4887 if (type) {
4888 clang::QualType result(GetQualType(type));
4889 result.addConst();
4890 return CompilerType(this, result.getAsOpaquePtr());
4891 }
4892 return CompilerType();
4893}
4894
4895CompilerType
4896ClangASTContext::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
4897 if (type) {
4898 clang::QualType result(GetQualType(type));
4899 result.addVolatile();
4900 return CompilerType(this, result.getAsOpaquePtr());
4901 }
4902 return CompilerType();
4903}
4904
4905CompilerType
4906ClangASTContext::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
4907 if (type) {
4908 clang::QualType result(GetQualType(type));
4909 result.addRestrict();
4910 return CompilerType(this, result.getAsOpaquePtr());
4911 }
4912 return CompilerType();
4913}
4914
4915CompilerType
4916ClangASTContext::CreateTypedef(lldb::opaque_compiler_type_t type,
4917 const char *typedef_name,
4918 const CompilerDeclContext &compiler_decl_ctx) {
4919 if (type) {
4920 clang::ASTContext *clang_ast = getASTContext();
4921 clang::QualType qual_type(GetQualType(type));
4922
4923 clang::DeclContext *decl_ctx =
4924 ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
4925 if (decl_ctx == nullptr)
4926 decl_ctx = getASTContext()->getTranslationUnitDecl();
4927
4928 clang::TypedefDecl *decl = clang::TypedefDecl::Create(
4929 *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
4930 &clang_ast->Idents.get(typedef_name),
4931 clang_ast->getTrivialTypeSourceInfo(qual_type));
4932
4933 clang::TagDecl *tdecl = nullptr;
4934 if (!qual_type.isNull()) {
4935 if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
4936 tdecl = rt->getDecl();
4937 if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
4938 tdecl = et->getDecl();
4939 }
4940
4941 // Check whether this declaration is an anonymous struct, union, or enum,
Adrian Prantl05097242018-04-30 16:49:04 +00004942 // hidden behind a typedef. If so, we try to check whether we have a
4943 // typedef tag to attach to the original record declaration
Kate Stoneb9c1b512016-09-06 20:57:50 +00004944 if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
4945 tdecl->setTypedefNameForAnonDecl(decl);
4946
4947 decl->setAccess(clang::AS_public); // TODO respect proper access specifier
4948
4949 // Get a uniqued clang::QualType for the typedef decl type
4950 return CompilerType(this, clang_ast->getTypedefType(decl).getAsOpaquePtr());
4951 }
4952 return CompilerType();
4953}
4954
4955CompilerType
4956ClangASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
4957 if (type) {
4958 const clang::TypedefType *typedef_type =
4959 llvm::dyn_cast<clang::TypedefType>(GetQualType(type));
4960 if (typedef_type)
Alex Langfordbddab072019-08-13 19:40:36 +00004961 return CompilerType(
4962 this, typedef_type->getDecl()->getUnderlyingType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004963 }
4964 return CompilerType();
4965}
Greg Claytond8d4a572015-08-11 21:38:15 +00004966
Greg Claytond8d4a572015-08-11 21:38:15 +00004967// Create related types using the current type's AST
Greg Claytond8d4a572015-08-11 21:38:15 +00004968
Kate Stoneb9c1b512016-09-06 20:57:50 +00004969CompilerType ClangASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
4970 return ClangASTContext::GetBasicType(getASTContext(), basic_type);
Greg Claytond8d4a572015-08-11 21:38:15 +00004971}
Greg Claytond8d4a572015-08-11 21:38:15 +00004972// Exploring the type
Greg Claytond8d4a572015-08-11 21:38:15 +00004973
Alex Langfordb482db62019-09-06 21:05:21 +00004974const llvm::fltSemantics &
4975ClangASTContext::GetFloatTypeSemantics(size_t byte_size) {
4976 if (auto *ast = getASTContext()) {
4977 const size_t bit_size = byte_size * 8;
4978 if (bit_size == ast->getTypeSize(ast->FloatTy))
4979 return ast->getFloatTypeSemantics(ast->FloatTy);
4980 else if (bit_size == ast->getTypeSize(ast->DoubleTy))
4981 return ast->getFloatTypeSemantics(ast->DoubleTy);
4982 else if (bit_size == ast->getTypeSize(ast->LongDoubleTy))
4983 return ast->getFloatTypeSemantics(ast->LongDoubleTy);
4984 else if (bit_size == ast->getTypeSize(ast->HalfTy))
4985 return ast->getFloatTypeSemantics(ast->HalfTy);
4986 }
4987 return llvm::APFloatBase::Bogus();
4988}
4989
Adrian Prantl2ee7b882019-01-16 21:19:20 +00004990Optional<uint64_t>
4991ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
4992 ExecutionContextScope *exe_scope) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00004993 if (GetCompleteType(type)) {
Greg Claytond8d4a572015-08-11 21:38:15 +00004994 clang::QualType qual_type(GetCanonicalQualType(type));
Greg Claytond8d4a572015-08-11 21:38:15 +00004995 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00004996 switch (type_class) {
4997 case clang::Type::Record:
4998 if (GetCompleteType(type))
4999 return getASTContext()->getTypeSize(qual_type);
5000 else
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005001 return None;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005002 break;
Enrico Granata36f51e42015-12-18 22:41:25 +00005003
Kate Stoneb9c1b512016-09-06 20:57:50 +00005004 case clang::Type::ObjCInterface:
5005 case clang::Type::ObjCObject: {
5006 ExecutionContext exe_ctx(exe_scope);
5007 Process *process = exe_ctx.GetProcessPtr();
5008 if (process) {
Alex Langforde823bbe2019-06-10 20:53:23 +00005009 ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005010 if (objc_runtime) {
5011 uint64_t bit_size = 0;
5012 if (objc_runtime->GetTypeBitSize(
Alex Langfordbddab072019-08-13 19:40:36 +00005013 CompilerType(this, qual_type.getAsOpaquePtr()), bit_size))
Kate Stoneb9c1b512016-09-06 20:57:50 +00005014 return bit_size;
5015 }
5016 } else {
5017 static bool g_printed = false;
5018 if (!g_printed) {
5019 StreamString s;
5020 DumpTypeDescription(type, &s);
5021
5022 llvm::outs() << "warning: trying to determine the size of type ";
5023 llvm::outs() << s.GetString() << "\n";
5024 llvm::outs() << "without a valid ExecutionContext. this is not "
5025 "reliable. please file a bug against LLDB.\n";
5026 llvm::outs() << "backtrace:\n";
5027 llvm::sys::PrintStackTrace(llvm::outs());
5028 llvm::outs() << "\n";
5029 g_printed = true;
5030 }
5031 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005032 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005033 LLVM_FALLTHROUGH;
5034 default:
5035 const uint32_t bit_size = getASTContext()->getTypeSize(qual_type);
5036 if (bit_size == 0) {
5037 if (qual_type->isIncompleteArrayType())
5038 return getASTContext()->getTypeSize(
5039 qual_type->getArrayElementTypeNoTypeQual()
5040 ->getCanonicalTypeUnqualified());
5041 }
5042 if (qual_type->isObjCObjectOrInterfaceType())
5043 return bit_size +
5044 getASTContext()->getTypeSize(
5045 getASTContext()->ObjCBuiltinClassTy);
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005046 // Function types actually have a size of 0, that's not an error.
5047 if (qual_type->isFunctionProtoType())
5048 return bit_size;
5049 if (bit_size)
5050 return bit_size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005051 }
5052 }
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005053 return None;
Greg Claytond8d4a572015-08-11 21:38:15 +00005054}
5055
Davide Italiano36f13e42019-08-12 20:03:19 +00005056llvm::Optional<size_t>
Davide Italiano7f9bbe02019-08-12 21:49:54 +00005057ClangASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type,
5058 ExecutionContextScope *exe_scope) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005059 if (GetCompleteType(type))
5060 return getASTContext()->getTypeAlign(GetQualType(type));
Davide Italiano36f13e42019-08-12 20:03:19 +00005061 return {};
Kate Stoneb9c1b512016-09-06 20:57:50 +00005062}
5063
5064lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
5065 uint64_t &count) {
5066 if (!type)
5067 return lldb::eEncodingInvalid;
5068
5069 count = 1;
5070 clang::QualType qual_type(GetCanonicalQualType(type));
5071
5072 switch (qual_type->getTypeClass()) {
5073 case clang::Type::UnaryTransform:
5074 break;
5075
5076 case clang::Type::FunctionNoProto:
5077 case clang::Type::FunctionProto:
5078 break;
5079
5080 case clang::Type::IncompleteArray:
5081 case clang::Type::VariableArray:
5082 break;
5083
5084 case clang::Type::ConstantArray:
5085 break;
5086
Fangrui Song8f284882018-07-13 22:40:40 +00005087 case clang::Type::DependentVector:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005088 case clang::Type::ExtVector:
5089 case clang::Type::Vector:
5090 // TODO: Set this to more than one???
5091 break;
5092
5093 case clang::Type::Builtin:
5094 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5095 case clang::BuiltinType::Void:
5096 break;
5097
5098 case clang::BuiltinType::Bool:
5099 case clang::BuiltinType::Char_S:
5100 case clang::BuiltinType::SChar:
5101 case clang::BuiltinType::WChar_S:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005102 case clang::BuiltinType::Short:
5103 case clang::BuiltinType::Int:
5104 case clang::BuiltinType::Long:
5105 case clang::BuiltinType::LongLong:
5106 case clang::BuiltinType::Int128:
5107 return lldb::eEncodingSint;
5108
5109 case clang::BuiltinType::Char_U:
5110 case clang::BuiltinType::UChar:
5111 case clang::BuiltinType::WChar_U:
Richard Smith51d12d82018-05-02 02:43:22 +00005112 case clang::BuiltinType::Char8:
5113 case clang::BuiltinType::Char16:
5114 case clang::BuiltinType::Char32:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005115 case clang::BuiltinType::UShort:
5116 case clang::BuiltinType::UInt:
5117 case clang::BuiltinType::ULong:
5118 case clang::BuiltinType::ULongLong:
5119 case clang::BuiltinType::UInt128:
5120 return lldb::eEncodingUint;
5121
Ilya Biryukovfc48ac62018-06-05 10:07:07 +00005122 // Fixed point types. Note that they are currently ignored.
5123 case clang::BuiltinType::ShortAccum:
5124 case clang::BuiltinType::Accum:
5125 case clang::BuiltinType::LongAccum:
5126 case clang::BuiltinType::UShortAccum:
5127 case clang::BuiltinType::UAccum:
5128 case clang::BuiltinType::ULongAccum:
Fangrui Songa5e59c52018-06-14 18:19:40 +00005129 case clang::BuiltinType::ShortFract:
Fangrui Songa5e59c52018-06-14 18:19:40 +00005130 case clang::BuiltinType::Fract:
5131 case clang::BuiltinType::LongFract:
5132 case clang::BuiltinType::UShortFract:
5133 case clang::BuiltinType::UFract:
5134 case clang::BuiltinType::ULongFract:
5135 case clang::BuiltinType::SatShortAccum:
5136 case clang::BuiltinType::SatAccum:
5137 case clang::BuiltinType::SatLongAccum:
5138 case clang::BuiltinType::SatUShortAccum:
5139 case clang::BuiltinType::SatUAccum:
5140 case clang::BuiltinType::SatULongAccum:
5141 case clang::BuiltinType::SatShortFract:
5142 case clang::BuiltinType::SatFract:
5143 case clang::BuiltinType::SatLongFract:
5144 case clang::BuiltinType::SatUShortFract:
5145 case clang::BuiltinType::SatUFract:
5146 case clang::BuiltinType::SatULongFract:
Ilya Biryukovfc48ac62018-06-05 10:07:07 +00005147 break;
5148
Kate Stoneb9c1b512016-09-06 20:57:50 +00005149 case clang::BuiltinType::Half:
5150 case clang::BuiltinType::Float:
Ted Woodward4355c7c2017-09-20 19:16:53 +00005151 case clang::BuiltinType::Float16:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005152 case clang::BuiltinType::Float128:
5153 case clang::BuiltinType::Double:
5154 case clang::BuiltinType::LongDouble:
5155 return lldb::eEncodingIEEE754;
5156
5157 case clang::BuiltinType::ObjCClass:
5158 case clang::BuiltinType::ObjCId:
5159 case clang::BuiltinType::ObjCSel:
5160 return lldb::eEncodingUint;
5161
5162 case clang::BuiltinType::NullPtr:
5163 return lldb::eEncodingUint;
5164
5165 case clang::BuiltinType::Kind::ARCUnbridgedCast:
5166 case clang::BuiltinType::Kind::BoundMember:
5167 case clang::BuiltinType::Kind::BuiltinFn:
5168 case clang::BuiltinType::Kind::Dependent:
5169 case clang::BuiltinType::Kind::OCLClkEvent:
5170 case clang::BuiltinType::Kind::OCLEvent:
5171 case clang::BuiltinType::Kind::OCLImage1dRO:
5172 case clang::BuiltinType::Kind::OCLImage1dWO:
5173 case clang::BuiltinType::Kind::OCLImage1dRW:
5174 case clang::BuiltinType::Kind::OCLImage1dArrayRO:
5175 case clang::BuiltinType::Kind::OCLImage1dArrayWO:
5176 case clang::BuiltinType::Kind::OCLImage1dArrayRW:
5177 case clang::BuiltinType::Kind::OCLImage1dBufferRO:
5178 case clang::BuiltinType::Kind::OCLImage1dBufferWO:
5179 case clang::BuiltinType::Kind::OCLImage1dBufferRW:
5180 case clang::BuiltinType::Kind::OCLImage2dRO:
5181 case clang::BuiltinType::Kind::OCLImage2dWO:
5182 case clang::BuiltinType::Kind::OCLImage2dRW:
5183 case clang::BuiltinType::Kind::OCLImage2dArrayRO:
5184 case clang::BuiltinType::Kind::OCLImage2dArrayWO:
5185 case clang::BuiltinType::Kind::OCLImage2dArrayRW:
5186 case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
5187 case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
5188 case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
5189 case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
5190 case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
5191 case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
5192 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
5193 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
5194 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
5195 case clang::BuiltinType::Kind::OCLImage2dDepthRO:
5196 case clang::BuiltinType::Kind::OCLImage2dDepthWO:
5197 case clang::BuiltinType::Kind::OCLImage2dDepthRW:
5198 case clang::BuiltinType::Kind::OCLImage2dMSAARO:
5199 case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
5200 case clang::BuiltinType::Kind::OCLImage2dMSAARW:
5201 case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
5202 case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
5203 case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
5204 case clang::BuiltinType::Kind::OCLImage3dRO:
5205 case clang::BuiltinType::Kind::OCLImage3dWO:
5206 case clang::BuiltinType::Kind::OCLImage3dRW:
5207 case clang::BuiltinType::Kind::OCLQueue:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005208 case clang::BuiltinType::Kind::OCLReserveID:
5209 case clang::BuiltinType::Kind::OCLSampler:
5210 case clang::BuiltinType::Kind::OMPArraySection:
5211 case clang::BuiltinType::Kind::Overload:
5212 case clang::BuiltinType::Kind::PseudoObject:
5213 case clang::BuiltinType::Kind::UnknownAny:
5214 break;
Jorge Gorbe Moyaa6e6c182018-11-08 22:04:58 +00005215
5216 case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload:
5217 case clang::BuiltinType::OCLIntelSubgroupAVCImePayload:
5218 case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload:
5219 case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload:
5220 case clang::BuiltinType::OCLIntelSubgroupAVCMceResult:
5221 case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
5222 case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
5223 case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
5224 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout:
5225 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout:
5226 case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin:
5227 case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
5228 break;
Raphael Isemann339b5d12019-08-09 09:58:47 +00005229
5230 case clang::BuiltinType::SveBool:
5231 case clang::BuiltinType::SveInt8:
5232 case clang::BuiltinType::SveInt16:
5233 case clang::BuiltinType::SveInt32:
5234 case clang::BuiltinType::SveInt64:
5235 case clang::BuiltinType::SveUint8:
5236 case clang::BuiltinType::SveUint16:
5237 case clang::BuiltinType::SveUint32:
5238 case clang::BuiltinType::SveUint64:
5239 case clang::BuiltinType::SveFloat16:
5240 case clang::BuiltinType::SveFloat32:
5241 case clang::BuiltinType::SveFloat64:
5242 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005243 }
5244 break;
Adrian Prantl05097242018-04-30 16:49:04 +00005245 // All pointer types are represented as unsigned integer encodings. We may
5246 // nee to add a eEncodingPointer if we ever need to know the difference
Kate Stoneb9c1b512016-09-06 20:57:50 +00005247 case clang::Type::ObjCObjectPointer:
5248 case clang::Type::BlockPointer:
5249 case clang::Type::Pointer:
5250 case clang::Type::LValueReference:
5251 case clang::Type::RValueReference:
5252 case clang::Type::MemberPointer:
5253 return lldb::eEncodingUint;
5254 case clang::Type::Complex: {
5255 lldb::Encoding encoding = lldb::eEncodingIEEE754;
5256 if (qual_type->isComplexType())
5257 encoding = lldb::eEncodingIEEE754;
5258 else {
5259 const clang::ComplexType *complex_type =
5260 qual_type->getAsComplexIntegerType();
5261 if (complex_type)
Alex Langfordbddab072019-08-13 19:40:36 +00005262 encoding =
5263 CompilerType(this, complex_type->getElementType().getAsOpaquePtr())
5264 .GetEncoding(count);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005265 else
5266 encoding = lldb::eEncodingSint;
5267 }
5268 count = 2;
5269 return encoding;
5270 }
5271
5272 case clang::Type::ObjCInterface:
5273 break;
5274 case clang::Type::Record:
5275 break;
5276 case clang::Type::Enum:
5277 return lldb::eEncodingSint;
5278 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00005279 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
5280 ->getDecl()
5281 ->getUnderlyingType()
5282 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005283 .GetEncoding(count);
5284
5285 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00005286 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
5287 ->getDeducedType()
5288 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005289 .GetEncoding(count);
5290
5291 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00005292 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
5293 ->getNamedType()
5294 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005295 .GetEncoding(count);
5296
5297 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00005298 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
5299 ->desugar()
5300 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005301 .GetEncoding(count);
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005302 case clang::Type::TypeOfExpr:
Alex Langfordbddab072019-08-13 19:40:36 +00005303 return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
5304 ->getUnderlyingExpr()
5305 ->getType()
5306 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005307 .GetEncoding(count);
5308 case clang::Type::TypeOf:
Alex Langfordbddab072019-08-13 19:40:36 +00005309 return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
5310 ->getUnderlyingType()
5311 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005312 .GetEncoding(count);
5313 case clang::Type::Decltype:
Alex Langfordbddab072019-08-13 19:40:36 +00005314 return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type)
5315 ->getUnderlyingType()
5316 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005317 .GetEncoding(count);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005318 case clang::Type::DependentSizedArray:
5319 case clang::Type::DependentSizedExtVector:
5320 case clang::Type::UnresolvedUsing:
5321 case clang::Type::Attributed:
5322 case clang::Type::TemplateTypeParm:
5323 case clang::Type::SubstTemplateTypeParm:
5324 case clang::Type::SubstTemplateTypeParmPack:
5325 case clang::Type::InjectedClassName:
5326 case clang::Type::DependentName:
5327 case clang::Type::DependentTemplateSpecialization:
5328 case clang::Type::PackExpansion:
5329 case clang::Type::ObjCObject:
5330
Kate Stoneb9c1b512016-09-06 20:57:50 +00005331 case clang::Type::TemplateSpecialization:
Pavel Labath4f19fce22017-02-17 13:39:50 +00005332 case clang::Type::DeducedTemplateSpecialization:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005333 case clang::Type::Atomic:
5334 case clang::Type::Adjusted:
5335 case clang::Type::Pipe:
5336 break;
5337
5338 // pointer type decayed from an array or function type.
5339 case clang::Type::Decayed:
5340 break;
Zachary Turner5a8ad4592016-10-05 17:07:34 +00005341 case clang::Type::ObjCTypeParam:
5342 break;
Ted Woodward66060cf2017-10-11 22:42:21 +00005343
5344 case clang::Type::DependentAddressSpace:
5345 break;
Krasimir Georgiev435e76a2019-05-07 13:59:30 +00005346 case clang::Type::MacroQualified:
5347 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005348 }
5349 count = 0;
5350 return lldb::eEncodingInvalid;
5351}
5352
5353lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
5354 if (!type)
5355 return lldb::eFormatDefault;
5356
5357 clang::QualType qual_type(GetCanonicalQualType(type));
5358
5359 switch (qual_type->getTypeClass()) {
5360 case clang::Type::UnaryTransform:
5361 break;
5362
5363 case clang::Type::FunctionNoProto:
5364 case clang::Type::FunctionProto:
5365 break;
5366
5367 case clang::Type::IncompleteArray:
5368 case clang::Type::VariableArray:
5369 break;
5370
5371 case clang::Type::ConstantArray:
5372 return lldb::eFormatVoid; // no value
5373
Fangrui Song8f284882018-07-13 22:40:40 +00005374 case clang::Type::DependentVector:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005375 case clang::Type::ExtVector:
5376 case clang::Type::Vector:
5377 break;
5378
5379 case clang::Type::Builtin:
5380 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5381 // default: assert(0 && "Unknown builtin type!");
5382 case clang::BuiltinType::UnknownAny:
5383 case clang::BuiltinType::Void:
5384 case clang::BuiltinType::BoundMember:
5385 break;
5386
5387 case clang::BuiltinType::Bool:
5388 return lldb::eFormatBoolean;
5389 case clang::BuiltinType::Char_S:
5390 case clang::BuiltinType::SChar:
5391 case clang::BuiltinType::WChar_S:
5392 case clang::BuiltinType::Char_U:
5393 case clang::BuiltinType::UChar:
5394 case clang::BuiltinType::WChar_U:
5395 return lldb::eFormatChar;
5396 case clang::BuiltinType::Char16:
5397 return lldb::eFormatUnicode16;
5398 case clang::BuiltinType::Char32:
5399 return lldb::eFormatUnicode32;
5400 case clang::BuiltinType::UShort:
5401 return lldb::eFormatUnsigned;
5402 case clang::BuiltinType::Short:
5403 return lldb::eFormatDecimal;
5404 case clang::BuiltinType::UInt:
5405 return lldb::eFormatUnsigned;
5406 case clang::BuiltinType::Int:
5407 return lldb::eFormatDecimal;
5408 case clang::BuiltinType::ULong:
5409 return lldb::eFormatUnsigned;
5410 case clang::BuiltinType::Long:
5411 return lldb::eFormatDecimal;
5412 case clang::BuiltinType::ULongLong:
5413 return lldb::eFormatUnsigned;
5414 case clang::BuiltinType::LongLong:
5415 return lldb::eFormatDecimal;
5416 case clang::BuiltinType::UInt128:
5417 return lldb::eFormatUnsigned;
5418 case clang::BuiltinType::Int128:
5419 return lldb::eFormatDecimal;
5420 case clang::BuiltinType::Half:
5421 case clang::BuiltinType::Float:
5422 case clang::BuiltinType::Double:
5423 case clang::BuiltinType::LongDouble:
5424 return lldb::eFormatFloat;
5425 default:
5426 return lldb::eFormatHex;
5427 }
5428 break;
5429 case clang::Type::ObjCObjectPointer:
5430 return lldb::eFormatHex;
5431 case clang::Type::BlockPointer:
5432 return lldb::eFormatHex;
5433 case clang::Type::Pointer:
5434 return lldb::eFormatHex;
5435 case clang::Type::LValueReference:
5436 case clang::Type::RValueReference:
5437 return lldb::eFormatHex;
5438 case clang::Type::MemberPointer:
5439 break;
5440 case clang::Type::Complex: {
5441 if (qual_type->isComplexType())
5442 return lldb::eFormatComplex;
5443 else
5444 return lldb::eFormatComplexInteger;
5445 }
5446 case clang::Type::ObjCInterface:
5447 break;
5448 case clang::Type::Record:
5449 break;
5450 case clang::Type::Enum:
5451 return lldb::eFormatEnum;
5452 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00005453 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
5454 ->getDecl()
5455 ->getUnderlyingType()
5456 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005457 .GetFormat();
5458 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00005459 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
5460 ->desugar()
5461 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005462 .GetFormat();
5463 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00005464 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
5465 ->desugar()
5466 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005467 .GetFormat();
5468 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00005469 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
5470 ->getNamedType()
5471 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005472 .GetFormat();
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005473 case clang::Type::TypeOfExpr:
Alex Langfordbddab072019-08-13 19:40:36 +00005474 return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
5475 ->getUnderlyingExpr()
5476 ->getType()
5477 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005478 .GetFormat();
5479 case clang::Type::TypeOf:
Alex Langfordbddab072019-08-13 19:40:36 +00005480 return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
5481 ->getUnderlyingType()
5482 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005483 .GetFormat();
5484 case clang::Type::Decltype:
Alex Langfordbddab072019-08-13 19:40:36 +00005485 return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type)
5486 ->getUnderlyingType()
5487 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005488 .GetFormat();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005489 case clang::Type::DependentSizedArray:
5490 case clang::Type::DependentSizedExtVector:
5491 case clang::Type::UnresolvedUsing:
5492 case clang::Type::Attributed:
5493 case clang::Type::TemplateTypeParm:
5494 case clang::Type::SubstTemplateTypeParm:
5495 case clang::Type::SubstTemplateTypeParmPack:
5496 case clang::Type::InjectedClassName:
5497 case clang::Type::DependentName:
5498 case clang::Type::DependentTemplateSpecialization:
5499 case clang::Type::PackExpansion:
5500 case clang::Type::ObjCObject:
5501
Kate Stoneb9c1b512016-09-06 20:57:50 +00005502 case clang::Type::TemplateSpecialization:
Pavel Labath4f19fce22017-02-17 13:39:50 +00005503 case clang::Type::DeducedTemplateSpecialization:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005504 case clang::Type::Atomic:
5505 case clang::Type::Adjusted:
5506 case clang::Type::Pipe:
5507 break;
5508
5509 // pointer type decayed from an array or function type.
5510 case clang::Type::Decayed:
5511 break;
Zachary Turner5a8ad4592016-10-05 17:07:34 +00005512 case clang::Type::ObjCTypeParam:
5513 break;
Ted Woodward66060cf2017-10-11 22:42:21 +00005514
5515 case clang::Type::DependentAddressSpace:
5516 break;
Krasimir Georgiev435e76a2019-05-07 13:59:30 +00005517 case clang::Type::MacroQualified:
5518 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005519 }
5520 // We don't know hot to display this type...
5521 return lldb::eFormatBytes;
5522}
5523
5524static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl,
5525 bool check_superclass) {
5526 while (class_interface_decl) {
5527 if (class_interface_decl->ivar_size() > 0)
5528 return true;
5529
5530 if (check_superclass)
5531 class_interface_decl = class_interface_decl->getSuperClass();
5532 else
5533 break;
5534 }
5535 return false;
5536}
5537
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00005538static Optional<SymbolFile::ArrayInfo>
Adrian Prantleca07c52018-11-05 20:49:07 +00005539GetDynamicArrayInfo(ClangASTContext &ast, SymbolFile *sym_file,
5540 clang::QualType qual_type,
5541 const ExecutionContext *exe_ctx) {
5542 if (qual_type->isIncompleteArrayType())
5543 if (auto *metadata = ast.GetMetadata(qual_type.getAsOpaquePtr()))
Pavel Labathffec31e2018-12-28 13:34:44 +00005544 return sym_file->GetDynamicArrayInfoForUID(metadata->GetUserID(),
5545 exe_ctx);
Adrian Prantleca07c52018-11-05 20:49:07 +00005546 return llvm::None;
5547}
5548
Kate Stoneb9c1b512016-09-06 20:57:50 +00005549uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
Adrian Prantleca07c52018-11-05 20:49:07 +00005550 bool omit_empty_base_classes,
5551 const ExecutionContext *exe_ctx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005552 if (!type)
5553 return 0;
5554
5555 uint32_t num_children = 0;
5556 clang::QualType qual_type(GetQualType(type));
5557 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5558 switch (type_class) {
5559 case clang::Type::Builtin:
5560 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5561 case clang::BuiltinType::ObjCId: // child is Class
5562 case clang::BuiltinType::ObjCClass: // child is Class
5563 num_children = 1;
5564 break;
5565
5566 default:
5567 break;
5568 }
5569 break;
5570
5571 case clang::Type::Complex:
5572 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005573 case clang::Type::Record:
5574 if (GetCompleteQualType(getASTContext(), qual_type)) {
5575 const clang::RecordType *record_type =
5576 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
5577 const clang::RecordDecl *record_decl = record_type->getDecl();
5578 assert(record_decl);
5579 const clang::CXXRecordDecl *cxx_record_decl =
5580 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
5581 if (cxx_record_decl) {
5582 if (omit_empty_base_classes) {
Adrian Prantl05097242018-04-30 16:49:04 +00005583 // Check each base classes to see if it or any of its base classes
5584 // contain any fields. This can help limit the noise in variable
5585 // views by not having to show base classes that contain no members.
Kate Stoneb9c1b512016-09-06 20:57:50 +00005586 clang::CXXRecordDecl::base_class_const_iterator base_class,
5587 base_class_end;
5588 for (base_class = cxx_record_decl->bases_begin(),
5589 base_class_end = cxx_record_decl->bases_end();
5590 base_class != base_class_end; ++base_class) {
5591 const clang::CXXRecordDecl *base_class_decl =
5592 llvm::cast<clang::CXXRecordDecl>(
5593 base_class->getType()
5594 ->getAs<clang::RecordType>()
5595 ->getDecl());
5596
5597 // Skip empty base classes
Jonas Devliegherea6682a42018-12-15 00:15:33 +00005598 if (!ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00005599 continue;
5600
5601 num_children++;
5602 }
5603 } else {
5604 // Include all base classes
5605 num_children += cxx_record_decl->getNumBases();
5606 }
5607 }
5608 clang::RecordDecl::field_iterator field, field_end;
5609 for (field = record_decl->field_begin(),
5610 field_end = record_decl->field_end();
5611 field != field_end; ++field)
5612 ++num_children;
5613 }
5614 break;
5615
5616 case clang::Type::ObjCObject:
5617 case clang::Type::ObjCInterface:
5618 if (GetCompleteQualType(getASTContext(), qual_type)) {
5619 const clang::ObjCObjectType *objc_class_type =
5620 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
5621 assert(objc_class_type);
5622 if (objc_class_type) {
5623 clang::ObjCInterfaceDecl *class_interface_decl =
5624 objc_class_type->getInterface();
5625
5626 if (class_interface_decl) {
5627
5628 clang::ObjCInterfaceDecl *superclass_interface_decl =
5629 class_interface_decl->getSuperClass();
5630 if (superclass_interface_decl) {
5631 if (omit_empty_base_classes) {
5632 if (ObjCDeclHasIVars(superclass_interface_decl, true))
5633 ++num_children;
5634 } else
5635 ++num_children;
5636 }
5637
5638 num_children += class_interface_decl->ivar_size();
5639 }
5640 }
5641 }
5642 break;
5643
5644 case clang::Type::ObjCObjectPointer: {
5645 const clang::ObjCObjectPointerType *pointer_type =
5646 llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
5647 clang::QualType pointee_type = pointer_type->getPointeeType();
5648 uint32_t num_pointee_children =
Alex Langfordbddab072019-08-13 19:40:36 +00005649 CompilerType(this, pointee_type.getAsOpaquePtr())
Adrian Prantleca07c52018-11-05 20:49:07 +00005650 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005651 // If this type points to a simple type, then it has 1 child
5652 if (num_pointee_children == 0)
5653 num_children = 1;
5654 else
5655 num_children = num_pointee_children;
5656 } break;
5657
5658 case clang::Type::Vector:
5659 case clang::Type::ExtVector:
5660 num_children =
5661 llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements();
5662 break;
5663
5664 case clang::Type::ConstantArray:
5665 num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr())
5666 ->getSize()
5667 .getLimitedValue();
5668 break;
Adrian Prantleca07c52018-11-05 20:49:07 +00005669 case clang::Type::IncompleteArray:
5670 if (auto array_info =
5671 GetDynamicArrayInfo(*this, GetSymbolFile(), qual_type, exe_ctx))
5672 // Only 1-dimensional arrays are supported.
5673 num_children = array_info->element_orders.size()
5674 ? array_info->element_orders.back()
5675 : 0;
5676 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005677
5678 case clang::Type::Pointer: {
5679 const clang::PointerType *pointer_type =
5680 llvm::cast<clang::PointerType>(qual_type.getTypePtr());
5681 clang::QualType pointee_type(pointer_type->getPointeeType());
5682 uint32_t num_pointee_children =
Alex Langfordbddab072019-08-13 19:40:36 +00005683 CompilerType(this, pointee_type.getAsOpaquePtr())
Adrian Prantleca07c52018-11-05 20:49:07 +00005684 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005685 if (num_pointee_children == 0) {
Adrian Prantl05097242018-04-30 16:49:04 +00005686 // We have a pointer to a pointee type that claims it has no children. We
5687 // will want to look at
Kate Stoneb9c1b512016-09-06 20:57:50 +00005688 num_children = GetNumPointeeChildren(pointee_type);
5689 } else
5690 num_children = num_pointee_children;
5691 } break;
5692
5693 case clang::Type::LValueReference:
5694 case clang::Type::RValueReference: {
5695 const clang::ReferenceType *reference_type =
5696 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
5697 clang::QualType pointee_type = reference_type->getPointeeType();
5698 uint32_t num_pointee_children =
Alex Langfordbddab072019-08-13 19:40:36 +00005699 CompilerType(this, pointee_type.getAsOpaquePtr())
Adrian Prantleca07c52018-11-05 20:49:07 +00005700 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005701 // If this type points to a simple type, then it has 1 child
5702 if (num_pointee_children == 0)
5703 num_children = 1;
5704 else
5705 num_children = num_pointee_children;
5706 } break;
5707
5708 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00005709 num_children = CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
Kate Stoneb9c1b512016-09-06 20:57:50 +00005710 ->getDecl()
Alex Langfordbddab072019-08-13 19:40:36 +00005711 ->getUnderlyingType()
5712 .getAsOpaquePtr())
5713 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005714 break;
5715
5716 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00005717 num_children = CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
5718 ->getDeducedType()
5719 .getAsOpaquePtr())
5720 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005721 break;
5722
5723 case clang::Type::Elaborated:
5724 num_children =
Alex Langfordbddab072019-08-13 19:40:36 +00005725 CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
5726 ->getNamedType()
5727 .getAsOpaquePtr())
Adrian Prantleca07c52018-11-05 20:49:07 +00005728 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005729 break;
5730
5731 case clang::Type::Paren:
5732 num_children =
Alex Langfordbddab072019-08-13 19:40:36 +00005733 CompilerType(
5734 this,
5735 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())
Adrian Prantleca07c52018-11-05 20:49:07 +00005736 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005737 break;
5738 default:
5739 break;
5740 }
5741 return num_children;
5742}
5743
Adrian Prantl0e4c4822019-03-06 21:22:25 +00005744CompilerType ClangASTContext::GetBuiltinTypeByName(ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005745 return GetBasicType(GetBasicTypeEnumeration(name));
Greg Clayton56939cb2015-09-17 22:23:34 +00005746}
5747
Greg Claytond8d4a572015-08-11 21:38:15 +00005748lldb::BasicType
Kate Stoneb9c1b512016-09-06 20:57:50 +00005749ClangASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
5750 if (type) {
5751 clang::QualType qual_type(GetQualType(type));
5752 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5753 if (type_class == clang::Type::Builtin) {
5754 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5755 case clang::BuiltinType::Void:
5756 return eBasicTypeVoid;
5757 case clang::BuiltinType::Bool:
5758 return eBasicTypeBool;
5759 case clang::BuiltinType::Char_S:
5760 return eBasicTypeSignedChar;
5761 case clang::BuiltinType::Char_U:
5762 return eBasicTypeUnsignedChar;
5763 case clang::BuiltinType::Char16:
5764 return eBasicTypeChar16;
5765 case clang::BuiltinType::Char32:
5766 return eBasicTypeChar32;
5767 case clang::BuiltinType::UChar:
5768 return eBasicTypeUnsignedChar;
5769 case clang::BuiltinType::SChar:
5770 return eBasicTypeSignedChar;
5771 case clang::BuiltinType::WChar_S:
5772 return eBasicTypeSignedWChar;
5773 case clang::BuiltinType::WChar_U:
5774 return eBasicTypeUnsignedWChar;
5775 case clang::BuiltinType::Short:
5776 return eBasicTypeShort;
5777 case clang::BuiltinType::UShort:
5778 return eBasicTypeUnsignedShort;
5779 case clang::BuiltinType::Int:
5780 return eBasicTypeInt;
5781 case clang::BuiltinType::UInt:
5782 return eBasicTypeUnsignedInt;
5783 case clang::BuiltinType::Long:
5784 return eBasicTypeLong;
5785 case clang::BuiltinType::ULong:
5786 return eBasicTypeUnsignedLong;
5787 case clang::BuiltinType::LongLong:
5788 return eBasicTypeLongLong;
5789 case clang::BuiltinType::ULongLong:
5790 return eBasicTypeUnsignedLongLong;
5791 case clang::BuiltinType::Int128:
5792 return eBasicTypeInt128;
5793 case clang::BuiltinType::UInt128:
5794 return eBasicTypeUnsignedInt128;
5795
5796 case clang::BuiltinType::Half:
5797 return eBasicTypeHalf;
5798 case clang::BuiltinType::Float:
5799 return eBasicTypeFloat;
5800 case clang::BuiltinType::Double:
5801 return eBasicTypeDouble;
5802 case clang::BuiltinType::LongDouble:
5803 return eBasicTypeLongDouble;
5804
5805 case clang::BuiltinType::NullPtr:
5806 return eBasicTypeNullPtr;
5807 case clang::BuiltinType::ObjCId:
5808 return eBasicTypeObjCID;
5809 case clang::BuiltinType::ObjCClass:
5810 return eBasicTypeObjCClass;
5811 case clang::BuiltinType::ObjCSel:
5812 return eBasicTypeObjCSel;
5813 default:
5814 return eBasicTypeOther;
5815 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005816 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005817 }
5818 return eBasicTypeInvalid;
Greg Claytond8d4a572015-08-11 21:38:15 +00005819}
5820
Kate Stoneb9c1b512016-09-06 20:57:50 +00005821void ClangASTContext::ForEachEnumerator(
5822 lldb::opaque_compiler_type_t type,
5823 std::function<bool(const CompilerType &integer_type,
Adrian Prantl0e4c4822019-03-06 21:22:25 +00005824 ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00005825 const llvm::APSInt &value)> const &callback) {
5826 const clang::EnumType *enum_type =
5827 llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
5828 if (enum_type) {
5829 const clang::EnumDecl *enum_decl = enum_type->getDecl();
5830 if (enum_decl) {
5831 CompilerType integer_type(this,
5832 enum_decl->getIntegerType().getAsOpaquePtr());
Greg Clayton99558cc42015-08-24 23:46:31 +00005833
Kate Stoneb9c1b512016-09-06 20:57:50 +00005834 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
5835 for (enum_pos = enum_decl->enumerator_begin(),
5836 enum_end_pos = enum_decl->enumerator_end();
5837 enum_pos != enum_end_pos; ++enum_pos) {
5838 ConstString name(enum_pos->getNameAsString().c_str());
5839 if (!callback(integer_type, name, enum_pos->getInitVal()))
5840 break;
5841 }
Greg Clayton99558cc42015-08-24 23:46:31 +00005842 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005843 }
Greg Clayton99558cc42015-08-24 23:46:31 +00005844}
5845
Greg Claytond8d4a572015-08-11 21:38:15 +00005846#pragma mark Aggregate Types
5847
Kate Stoneb9c1b512016-09-06 20:57:50 +00005848uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
5849 if (!type)
5850 return 0;
Enrico Granata36f51e42015-12-18 22:41:25 +00005851
Kate Stoneb9c1b512016-09-06 20:57:50 +00005852 uint32_t count = 0;
5853 clang::QualType qual_type(GetCanonicalQualType(type));
5854 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5855 switch (type_class) {
5856 case clang::Type::Record:
5857 if (GetCompleteType(type)) {
5858 const clang::RecordType *record_type =
5859 llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
5860 if (record_type) {
5861 clang::RecordDecl *record_decl = record_type->getDecl();
5862 if (record_decl) {
5863 uint32_t field_idx = 0;
5864 clang::RecordDecl::field_iterator field, field_end;
5865 for (field = record_decl->field_begin(),
5866 field_end = record_decl->field_end();
5867 field != field_end; ++field)
5868 ++field_idx;
5869 count = field_idx;
5870 }
5871 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005872 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005873 break;
5874
5875 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00005876 count = CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
5877 ->getDecl()
5878 ->getUnderlyingType()
5879 .getAsOpaquePtr())
5880 .GetNumFields();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005881 break;
5882
5883 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00005884 count = CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
5885 ->getDeducedType()
5886 .getAsOpaquePtr())
5887 .GetNumFields();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005888 break;
5889
5890 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00005891 count = CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
5892 ->getNamedType()
5893 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005894 .GetNumFields();
5895 break;
5896
5897 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00005898 count =
5899 CompilerType(
5900 this,
5901 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())
5902 .GetNumFields();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005903 break;
5904
Sean Callananf9c622a2016-09-30 18:44:43 +00005905 case clang::Type::ObjCObjectPointer: {
5906 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00005907 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00005908 const clang::ObjCInterfaceType *objc_interface_type =
5909 objc_class_type->getInterfaceType();
5910 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00005911 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
5912 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00005913 clang::ObjCInterfaceDecl *class_interface_decl =
5914 objc_interface_type->getDecl();
5915 if (class_interface_decl) {
5916 count = class_interface_decl->ivar_size();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005917 }
5918 }
5919 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00005920 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005921
5922 case clang::Type::ObjCObject:
5923 case clang::Type::ObjCInterface:
5924 if (GetCompleteType(type)) {
5925 const clang::ObjCObjectType *objc_class_type =
5926 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
5927 if (objc_class_type) {
5928 clang::ObjCInterfaceDecl *class_interface_decl =
5929 objc_class_type->getInterface();
5930
5931 if (class_interface_decl)
5932 count = class_interface_decl->ivar_size();
5933 }
5934 }
5935 break;
5936
5937 default:
5938 break;
5939 }
5940 return count;
Greg Claytond8d4a572015-08-11 21:38:15 +00005941}
5942
Bruce Mitchener48ea9002015-09-23 00:18:24 +00005943static lldb::opaque_compiler_type_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00005944GetObjCFieldAtIndex(clang::ASTContext *ast,
5945 clang::ObjCInterfaceDecl *class_interface_decl, size_t idx,
5946 std::string &name, uint64_t *bit_offset_ptr,
5947 uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) {
5948 if (class_interface_decl) {
5949 if (idx < (class_interface_decl->ivar_size())) {
5950 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
5951 ivar_end = class_interface_decl->ivar_end();
5952 uint32_t ivar_idx = 0;
5953
5954 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end;
5955 ++ivar_pos, ++ivar_idx) {
5956 if (ivar_idx == idx) {
5957 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
5958
5959 clang::QualType ivar_qual_type(ivar_decl->getType());
5960
5961 name.assign(ivar_decl->getNameAsString());
5962
5963 if (bit_offset_ptr) {
5964 const clang::ASTRecordLayout &interface_layout =
5965 ast->getASTObjCInterfaceLayout(class_interface_decl);
5966 *bit_offset_ptr = interface_layout.getFieldOffset(ivar_idx);
5967 }
5968
5969 const bool is_bitfield = ivar_pos->isBitField();
5970
5971 if (bitfield_bit_size_ptr) {
5972 *bitfield_bit_size_ptr = 0;
5973
5974 if (is_bitfield && ast) {
5975 clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
Hans Wennborg30ce9622018-11-28 14:30:18 +00005976 clang::Expr::EvalResult result;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005977 if (bitfield_bit_size_expr &&
Hans Wennborg30ce9622018-11-28 14:30:18 +00005978 bitfield_bit_size_expr->EvaluateAsInt(result, *ast)) {
5979 llvm::APSInt bitfield_apsint = result.Val.getInt();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005980 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
5981 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005982 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005983 }
5984 if (is_bitfield_ptr)
5985 *is_bitfield_ptr = is_bitfield;
5986
5987 return ivar_qual_type.getAsOpaquePtr();
Greg Claytond8d4a572015-08-11 21:38:15 +00005988 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005989 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005990 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005991 }
5992 return nullptr;
Greg Claytond8d4a572015-08-11 21:38:15 +00005993}
5994
Kate Stoneb9c1b512016-09-06 20:57:50 +00005995CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
5996 size_t idx, std::string &name,
5997 uint64_t *bit_offset_ptr,
5998 uint32_t *bitfield_bit_size_ptr,
5999 bool *is_bitfield_ptr) {
6000 if (!type)
Greg Claytona1e5dc82015-08-11 22:53:00 +00006001 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006002
6003 clang::QualType qual_type(GetCanonicalQualType(type));
6004 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6005 switch (type_class) {
6006 case clang::Type::Record:
6007 if (GetCompleteType(type)) {
6008 const clang::RecordType *record_type =
6009 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
6010 const clang::RecordDecl *record_decl = record_type->getDecl();
6011 uint32_t field_idx = 0;
6012 clang::RecordDecl::field_iterator field, field_end;
6013 for (field = record_decl->field_begin(),
6014 field_end = record_decl->field_end();
6015 field != field_end; ++field, ++field_idx) {
6016 if (idx == field_idx) {
6017 // Print the member type if requested
6018 // Print the member name and equal sign
6019 name.assign(field->getNameAsString());
6020
6021 // Figure out the type byte size (field_type_info.first) and
6022 // alignment (field_type_info.second) from the AST context.
6023 if (bit_offset_ptr) {
6024 const clang::ASTRecordLayout &record_layout =
6025 getASTContext()->getASTRecordLayout(record_decl);
6026 *bit_offset_ptr = record_layout.getFieldOffset(field_idx);
6027 }
6028
6029 const bool is_bitfield = field->isBitField();
6030
6031 if (bitfield_bit_size_ptr) {
6032 *bitfield_bit_size_ptr = 0;
6033
6034 if (is_bitfield) {
6035 clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
Hans Wennborg30ce9622018-11-28 14:30:18 +00006036 clang::Expr::EvalResult result;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006037 if (bitfield_bit_size_expr &&
Hans Wennborg30ce9622018-11-28 14:30:18 +00006038 bitfield_bit_size_expr->EvaluateAsInt(result,
Kate Stoneb9c1b512016-09-06 20:57:50 +00006039 *getASTContext())) {
Hans Wennborg30ce9622018-11-28 14:30:18 +00006040 llvm::APSInt bitfield_apsint = result.Val.getInt();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006041 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
6042 }
6043 }
6044 }
6045 if (is_bitfield_ptr)
6046 *is_bitfield_ptr = is_bitfield;
6047
Alex Langfordbddab072019-08-13 19:40:36 +00006048 return CompilerType(this, field->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006049 }
6050 }
6051 }
6052 break;
6053
Sean Callananf9c622a2016-09-30 18:44:43 +00006054 case clang::Type::ObjCObjectPointer: {
6055 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00006056 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00006057 const clang::ObjCInterfaceType *objc_interface_type =
6058 objc_class_type->getInterfaceType();
6059 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00006060 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
6061 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00006062 clang::ObjCInterfaceDecl *class_interface_decl =
6063 objc_interface_type->getDecl();
6064 if (class_interface_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00006065 return CompilerType(
6066 this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl,
6067 idx, name, bit_offset_ptr,
6068 bitfield_bit_size_ptr, is_bitfield_ptr));
6069 }
6070 }
6071 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00006072 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006073
6074 case clang::Type::ObjCObject:
6075 case clang::Type::ObjCInterface:
6076 if (GetCompleteType(type)) {
6077 const clang::ObjCObjectType *objc_class_type =
6078 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
6079 assert(objc_class_type);
6080 if (objc_class_type) {
6081 clang::ObjCInterfaceDecl *class_interface_decl =
6082 objc_class_type->getInterface();
6083 return CompilerType(
6084 this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl,
6085 idx, name, bit_offset_ptr,
6086 bitfield_bit_size_ptr, is_bitfield_ptr));
6087 }
6088 }
6089 break;
6090
6091 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00006092 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
6093 ->getDecl()
6094 ->getUnderlyingType()
6095 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00006096 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6097 is_bitfield_ptr);
6098
6099 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00006100 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
6101 ->getDeducedType()
6102 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00006103 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6104 is_bitfield_ptr);
6105
6106 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00006107 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
6108 ->getNamedType()
6109 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00006110 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6111 is_bitfield_ptr);
6112
6113 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00006114 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
6115 ->desugar()
6116 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00006117 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6118 is_bitfield_ptr);
6119
6120 default:
6121 break;
6122 }
6123 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00006124}
6125
Greg Clayton99558cc42015-08-24 23:46:31 +00006126uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00006127ClangASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) {
6128 uint32_t count = 0;
6129 clang::QualType qual_type(GetCanonicalQualType(type));
6130 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6131 switch (type_class) {
6132 case clang::Type::Record:
6133 if (GetCompleteType(type)) {
6134 const clang::CXXRecordDecl *cxx_record_decl =
6135 qual_type->getAsCXXRecordDecl();
6136 if (cxx_record_decl)
6137 count = cxx_record_decl->getNumBases();
Greg Clayton99558cc42015-08-24 23:46:31 +00006138 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006139 break;
Greg Clayton99558cc42015-08-24 23:46:31 +00006140
Kate Stoneb9c1b512016-09-06 20:57:50 +00006141 case clang::Type::ObjCObjectPointer:
6142 count = GetPointeeType(type).GetNumDirectBaseClasses();
6143 break;
6144
6145 case clang::Type::ObjCObject:
6146 if (GetCompleteType(type)) {
6147 const clang::ObjCObjectType *objc_class_type =
6148 qual_type->getAsObjCQualifiedInterfaceType();
6149 if (objc_class_type) {
6150 clang::ObjCInterfaceDecl *class_interface_decl =
6151 objc_class_type->getInterface();
6152
6153 if (class_interface_decl && class_interface_decl->getSuperClass())
6154 count = 1;
6155 }
6156 }
6157 break;
6158 case clang::Type::ObjCInterface:
6159 if (GetCompleteType(type)) {
6160 const clang::ObjCInterfaceType *objc_interface_type =
6161 qual_type->getAs<clang::ObjCInterfaceType>();
6162 if (objc_interface_type) {
6163 clang::ObjCInterfaceDecl *class_interface_decl =
6164 objc_interface_type->getInterface();
6165
6166 if (class_interface_decl && class_interface_decl->getSuperClass())
6167 count = 1;
6168 }
6169 }
6170 break;
6171
6172 case clang::Type::Typedef:
6173 count = GetNumDirectBaseClasses(llvm::cast<clang::TypedefType>(qual_type)
6174 ->getDecl()
6175 ->getUnderlyingType()
6176 .getAsOpaquePtr());
6177 break;
6178
6179 case clang::Type::Auto:
6180 count = GetNumDirectBaseClasses(llvm::cast<clang::AutoType>(qual_type)
6181 ->getDeducedType()
6182 .getAsOpaquePtr());
6183 break;
6184
6185 case clang::Type::Elaborated:
6186 count = GetNumDirectBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)
6187 ->getNamedType()
6188 .getAsOpaquePtr());
6189 break;
6190
6191 case clang::Type::Paren:
6192 return GetNumDirectBaseClasses(
6193 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
6194
6195 default:
6196 break;
6197 }
6198 return count;
Greg Clayton99558cc42015-08-24 23:46:31 +00006199}
6200
6201uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00006202ClangASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) {
6203 uint32_t count = 0;
6204 clang::QualType qual_type(GetCanonicalQualType(type));
6205 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6206 switch (type_class) {
6207 case clang::Type::Record:
6208 if (GetCompleteType(type)) {
6209 const clang::CXXRecordDecl *cxx_record_decl =
6210 qual_type->getAsCXXRecordDecl();
6211 if (cxx_record_decl)
6212 count = cxx_record_decl->getNumVBases();
Greg Clayton99558cc42015-08-24 23:46:31 +00006213 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006214 break;
Greg Clayton99558cc42015-08-24 23:46:31 +00006215
Kate Stoneb9c1b512016-09-06 20:57:50 +00006216 case clang::Type::Typedef:
6217 count = GetNumVirtualBaseClasses(llvm::cast<clang::TypedefType>(qual_type)
6218 ->getDecl()
6219 ->getUnderlyingType()
6220 .getAsOpaquePtr());
6221 break;
6222
6223 case clang::Type::Auto:
6224 count = GetNumVirtualBaseClasses(llvm::cast<clang::AutoType>(qual_type)
6225 ->getDeducedType()
6226 .getAsOpaquePtr());
6227 break;
6228
6229 case clang::Type::Elaborated:
6230 count =
6231 GetNumVirtualBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)
6232 ->getNamedType()
6233 .getAsOpaquePtr());
6234 break;
6235
6236 case clang::Type::Paren:
6237 count = GetNumVirtualBaseClasses(
6238 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
6239 break;
6240
6241 default:
6242 break;
6243 }
6244 return count;
Greg Clayton99558cc42015-08-24 23:46:31 +00006245}
6246
Kate Stoneb9c1b512016-09-06 20:57:50 +00006247CompilerType ClangASTContext::GetDirectBaseClassAtIndex(
6248 lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
6249 clang::QualType qual_type(GetCanonicalQualType(type));
6250 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6251 switch (type_class) {
6252 case clang::Type::Record:
6253 if (GetCompleteType(type)) {
6254 const clang::CXXRecordDecl *cxx_record_decl =
6255 qual_type->getAsCXXRecordDecl();
6256 if (cxx_record_decl) {
6257 uint32_t curr_idx = 0;
6258 clang::CXXRecordDecl::base_class_const_iterator base_class,
6259 base_class_end;
6260 for (base_class = cxx_record_decl->bases_begin(),
6261 base_class_end = cxx_record_decl->bases_end();
6262 base_class != base_class_end; ++base_class, ++curr_idx) {
6263 if (curr_idx == idx) {
6264 if (bit_offset_ptr) {
6265 const clang::ASTRecordLayout &record_layout =
6266 getASTContext()->getASTRecordLayout(cxx_record_decl);
6267 const clang::CXXRecordDecl *base_class_decl =
6268 llvm::cast<clang::CXXRecordDecl>(
6269 base_class->getType()
6270 ->getAs<clang::RecordType>()
6271 ->getDecl());
6272 if (base_class->isVirtual())
6273 *bit_offset_ptr =
6274 record_layout.getVBaseClassOffset(base_class_decl)
6275 .getQuantity() *
6276 8;
6277 else
6278 *bit_offset_ptr =
6279 record_layout.getBaseClassOffset(base_class_decl)
6280 .getQuantity() *
6281 8;
Greg Clayton99558cc42015-08-24 23:46:31 +00006282 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006283 return CompilerType(this, base_class->getType().getAsOpaquePtr());
6284 }
6285 }
6286 }
Greg Clayton99558cc42015-08-24 23:46:31 +00006287 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006288 break;
6289
6290 case clang::Type::ObjCObjectPointer:
6291 return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr);
6292
6293 case clang::Type::ObjCObject:
6294 if (idx == 0 && GetCompleteType(type)) {
6295 const clang::ObjCObjectType *objc_class_type =
6296 qual_type->getAsObjCQualifiedInterfaceType();
6297 if (objc_class_type) {
6298 clang::ObjCInterfaceDecl *class_interface_decl =
6299 objc_class_type->getInterface();
6300
6301 if (class_interface_decl) {
6302 clang::ObjCInterfaceDecl *superclass_interface_decl =
6303 class_interface_decl->getSuperClass();
6304 if (superclass_interface_decl) {
6305 if (bit_offset_ptr)
6306 *bit_offset_ptr = 0;
Alex Langfordbddab072019-08-13 19:40:36 +00006307 return CompilerType(this,
Kate Stoneb9c1b512016-09-06 20:57:50 +00006308 getASTContext()->getObjCInterfaceType(
Alex Langfordbddab072019-08-13 19:40:36 +00006309 superclass_interface_decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006310 }
6311 }
6312 }
6313 }
6314 break;
6315 case clang::Type::ObjCInterface:
6316 if (idx == 0 && GetCompleteType(type)) {
6317 const clang::ObjCObjectType *objc_interface_type =
6318 qual_type->getAs<clang::ObjCInterfaceType>();
6319 if (objc_interface_type) {
6320 clang::ObjCInterfaceDecl *class_interface_decl =
6321 objc_interface_type->getInterface();
6322
6323 if (class_interface_decl) {
6324 clang::ObjCInterfaceDecl *superclass_interface_decl =
6325 class_interface_decl->getSuperClass();
6326 if (superclass_interface_decl) {
6327 if (bit_offset_ptr)
6328 *bit_offset_ptr = 0;
Alex Langfordbddab072019-08-13 19:40:36 +00006329 return CompilerType(
6330 this, getASTContext()
6331 ->getObjCInterfaceType(superclass_interface_decl)
6332 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006333 }
6334 }
6335 }
6336 }
6337 break;
6338
6339 case clang::Type::Typedef:
6340 return GetDirectBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type)
6341 ->getDecl()
6342 ->getUnderlyingType()
6343 .getAsOpaquePtr(),
6344 idx, bit_offset_ptr);
6345
6346 case clang::Type::Auto:
6347 return GetDirectBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type)
6348 ->getDeducedType()
6349 .getAsOpaquePtr(),
6350 idx, bit_offset_ptr);
6351
6352 case clang::Type::Elaborated:
6353 return GetDirectBaseClassAtIndex(
6354 llvm::cast<clang::ElaboratedType>(qual_type)
6355 ->getNamedType()
6356 .getAsOpaquePtr(),
6357 idx, bit_offset_ptr);
6358
6359 case clang::Type::Paren:
6360 return GetDirectBaseClassAtIndex(
6361 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
6362 idx, bit_offset_ptr);
6363
6364 default:
6365 break;
6366 }
6367 return CompilerType();
Greg Clayton99558cc42015-08-24 23:46:31 +00006368}
6369
Kate Stoneb9c1b512016-09-06 20:57:50 +00006370CompilerType ClangASTContext::GetVirtualBaseClassAtIndex(
6371 lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
6372 clang::QualType qual_type(GetCanonicalQualType(type));
6373 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6374 switch (type_class) {
6375 case clang::Type::Record:
6376 if (GetCompleteType(type)) {
6377 const clang::CXXRecordDecl *cxx_record_decl =
6378 qual_type->getAsCXXRecordDecl();
6379 if (cxx_record_decl) {
6380 uint32_t curr_idx = 0;
6381 clang::CXXRecordDecl::base_class_const_iterator base_class,
6382 base_class_end;
6383 for (base_class = cxx_record_decl->vbases_begin(),
6384 base_class_end = cxx_record_decl->vbases_end();
6385 base_class != base_class_end; ++base_class, ++curr_idx) {
6386 if (curr_idx == idx) {
6387 if (bit_offset_ptr) {
6388 const clang::ASTRecordLayout &record_layout =
6389 getASTContext()->getASTRecordLayout(cxx_record_decl);
6390 const clang::CXXRecordDecl *base_class_decl =
6391 llvm::cast<clang::CXXRecordDecl>(
6392 base_class->getType()
6393 ->getAs<clang::RecordType>()
6394 ->getDecl());
6395 *bit_offset_ptr =
6396 record_layout.getVBaseClassOffset(base_class_decl)
6397 .getQuantity() *
6398 8;
Greg Clayton99558cc42015-08-24 23:46:31 +00006399 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006400 return CompilerType(this, base_class->getType().getAsOpaquePtr());
6401 }
6402 }
6403 }
Greg Clayton99558cc42015-08-24 23:46:31 +00006404 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006405 break;
Greg Clayton99558cc42015-08-24 23:46:31 +00006406
Kate Stoneb9c1b512016-09-06 20:57:50 +00006407 case clang::Type::Typedef:
6408 return GetVirtualBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type)
6409 ->getDecl()
6410 ->getUnderlyingType()
6411 .getAsOpaquePtr(),
6412 idx, bit_offset_ptr);
6413
6414 case clang::Type::Auto:
6415 return GetVirtualBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type)
6416 ->getDeducedType()
6417 .getAsOpaquePtr(),
6418 idx, bit_offset_ptr);
6419
6420 case clang::Type::Elaborated:
6421 return GetVirtualBaseClassAtIndex(
6422 llvm::cast<clang::ElaboratedType>(qual_type)
6423 ->getNamedType()
6424 .getAsOpaquePtr(),
6425 idx, bit_offset_ptr);
6426
6427 case clang::Type::Paren:
6428 return GetVirtualBaseClassAtIndex(
6429 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
6430 idx, bit_offset_ptr);
6431
6432 default:
6433 break;
6434 }
6435 return CompilerType();
Greg Clayton99558cc42015-08-24 23:46:31 +00006436}
6437
Greg Claytond8d4a572015-08-11 21:38:15 +00006438// If a pointer to a pointee type (the clang_type arg) says that it has no
6439// children, then we either need to trust it, or override it and return a
6440// different result. For example, an "int *" has one child that is an integer,
6441// but a function pointer doesn't have any children. Likewise if a Record type
6442// claims it has no children, then there really is nothing to show.
Kate Stoneb9c1b512016-09-06 20:57:50 +00006443uint32_t ClangASTContext::GetNumPointeeChildren(clang::QualType type) {
6444 if (type.isNull())
Greg Claytond8d4a572015-08-11 21:38:15 +00006445 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006446
6447 clang::QualType qual_type(type.getCanonicalType());
6448 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6449 switch (type_class) {
6450 case clang::Type::Builtin:
6451 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
6452 case clang::BuiltinType::UnknownAny:
6453 case clang::BuiltinType::Void:
6454 case clang::BuiltinType::NullPtr:
6455 case clang::BuiltinType::OCLEvent:
6456 case clang::BuiltinType::OCLImage1dRO:
6457 case clang::BuiltinType::OCLImage1dWO:
6458 case clang::BuiltinType::OCLImage1dRW:
6459 case clang::BuiltinType::OCLImage1dArrayRO:
6460 case clang::BuiltinType::OCLImage1dArrayWO:
6461 case clang::BuiltinType::OCLImage1dArrayRW:
6462 case clang::BuiltinType::OCLImage1dBufferRO:
6463 case clang::BuiltinType::OCLImage1dBufferWO:
6464 case clang::BuiltinType::OCLImage1dBufferRW:
6465 case clang::BuiltinType::OCLImage2dRO:
6466 case clang::BuiltinType::OCLImage2dWO:
6467 case clang::BuiltinType::OCLImage2dRW:
6468 case clang::BuiltinType::OCLImage2dArrayRO:
6469 case clang::BuiltinType::OCLImage2dArrayWO:
6470 case clang::BuiltinType::OCLImage2dArrayRW:
6471 case clang::BuiltinType::OCLImage3dRO:
6472 case clang::BuiltinType::OCLImage3dWO:
6473 case clang::BuiltinType::OCLImage3dRW:
6474 case clang::BuiltinType::OCLSampler:
6475 return 0;
6476 case clang::BuiltinType::Bool:
6477 case clang::BuiltinType::Char_U:
6478 case clang::BuiltinType::UChar:
6479 case clang::BuiltinType::WChar_U:
6480 case clang::BuiltinType::Char16:
6481 case clang::BuiltinType::Char32:
6482 case clang::BuiltinType::UShort:
6483 case clang::BuiltinType::UInt:
6484 case clang::BuiltinType::ULong:
6485 case clang::BuiltinType::ULongLong:
6486 case clang::BuiltinType::UInt128:
6487 case clang::BuiltinType::Char_S:
6488 case clang::BuiltinType::SChar:
6489 case clang::BuiltinType::WChar_S:
6490 case clang::BuiltinType::Short:
6491 case clang::BuiltinType::Int:
6492 case clang::BuiltinType::Long:
6493 case clang::BuiltinType::LongLong:
6494 case clang::BuiltinType::Int128:
6495 case clang::BuiltinType::Float:
6496 case clang::BuiltinType::Double:
6497 case clang::BuiltinType::LongDouble:
6498 case clang::BuiltinType::Dependent:
6499 case clang::BuiltinType::Overload:
6500 case clang::BuiltinType::ObjCId:
6501 case clang::BuiltinType::ObjCClass:
6502 case clang::BuiltinType::ObjCSel:
6503 case clang::BuiltinType::BoundMember:
6504 case clang::BuiltinType::Half:
6505 case clang::BuiltinType::ARCUnbridgedCast:
6506 case clang::BuiltinType::PseudoObject:
6507 case clang::BuiltinType::BuiltinFn:
6508 case clang::BuiltinType::OMPArraySection:
6509 return 1;
6510 default:
6511 return 0;
6512 }
6513 break;
6514
6515 case clang::Type::Complex:
6516 return 1;
6517 case clang::Type::Pointer:
6518 return 1;
6519 case clang::Type::BlockPointer:
6520 return 0; // If block pointers don't have debug info, then no children for
6521 // them
6522 case clang::Type::LValueReference:
6523 return 1;
6524 case clang::Type::RValueReference:
6525 return 1;
6526 case clang::Type::MemberPointer:
6527 return 0;
6528 case clang::Type::ConstantArray:
6529 return 0;
6530 case clang::Type::IncompleteArray:
6531 return 0;
6532 case clang::Type::VariableArray:
6533 return 0;
6534 case clang::Type::DependentSizedArray:
6535 return 0;
6536 case clang::Type::DependentSizedExtVector:
6537 return 0;
6538 case clang::Type::Vector:
6539 return 0;
6540 case clang::Type::ExtVector:
6541 return 0;
6542 case clang::Type::FunctionProto:
6543 return 0; // When we function pointers, they have no children...
6544 case clang::Type::FunctionNoProto:
6545 return 0; // When we function pointers, they have no children...
6546 case clang::Type::UnresolvedUsing:
6547 return 0;
6548 case clang::Type::Paren:
6549 return GetNumPointeeChildren(
6550 llvm::cast<clang::ParenType>(qual_type)->desugar());
6551 case clang::Type::Typedef:
6552 return GetNumPointeeChildren(llvm::cast<clang::TypedefType>(qual_type)
6553 ->getDecl()
6554 ->getUnderlyingType());
6555 case clang::Type::Auto:
6556 return GetNumPointeeChildren(
6557 llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
6558 case clang::Type::Elaborated:
6559 return GetNumPointeeChildren(
6560 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
6561 case clang::Type::TypeOfExpr:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00006562 return GetNumPointeeChildren(llvm::cast<clang::TypeOfExprType>(qual_type)
6563 ->getUnderlyingExpr()
6564 ->getType());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006565 case clang::Type::TypeOf:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00006566 return GetNumPointeeChildren(
6567 llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006568 case clang::Type::Decltype:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00006569 return GetNumPointeeChildren(
6570 llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006571 case clang::Type::Record:
6572 return 0;
6573 case clang::Type::Enum:
6574 return 1;
6575 case clang::Type::TemplateTypeParm:
6576 return 1;
6577 case clang::Type::SubstTemplateTypeParm:
6578 return 1;
6579 case clang::Type::TemplateSpecialization:
6580 return 1;
6581 case clang::Type::InjectedClassName:
6582 return 0;
6583 case clang::Type::DependentName:
6584 return 1;
6585 case clang::Type::DependentTemplateSpecialization:
6586 return 1;
6587 case clang::Type::ObjCObject:
6588 return 0;
6589 case clang::Type::ObjCInterface:
6590 return 0;
6591 case clang::Type::ObjCObjectPointer:
6592 return 1;
6593 default:
6594 break;
6595 }
6596 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00006597}
6598
Kate Stoneb9c1b512016-09-06 20:57:50 +00006599CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
6600 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
6601 bool transparent_pointers, bool omit_empty_base_classes,
6602 bool ignore_array_bounds, std::string &child_name,
6603 uint32_t &child_byte_size, int32_t &child_byte_offset,
6604 uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
6605 bool &child_is_base_class, bool &child_is_deref_of_parent,
6606 ValueObject *valobj, uint64_t &language_flags) {
6607 if (!type)
Greg Claytona1e5dc82015-08-11 22:53:00 +00006608 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00006609
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006610 auto get_exe_scope = [&exe_ctx]() {
6611 return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
6612 };
6613
Kate Stoneb9c1b512016-09-06 20:57:50 +00006614 clang::QualType parent_qual_type(GetCanonicalQualType(type));
6615 const clang::Type::TypeClass parent_type_class =
6616 parent_qual_type->getTypeClass();
6617 child_bitfield_bit_size = 0;
6618 child_bitfield_bit_offset = 0;
6619 child_is_base_class = false;
6620 language_flags = 0;
6621
Adrian Prantleca07c52018-11-05 20:49:07 +00006622 const bool idx_is_valid =
6623 idx < GetNumChildren(type, omit_empty_base_classes, exe_ctx);
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00006624 int32_t bit_offset;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006625 switch (parent_type_class) {
6626 case clang::Type::Builtin:
6627 if (idx_is_valid) {
6628 switch (llvm::cast<clang::BuiltinType>(parent_qual_type)->getKind()) {
6629 case clang::BuiltinType::ObjCId:
6630 case clang::BuiltinType::ObjCClass:
6631 child_name = "isa";
6632 child_byte_size =
6633 getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy) /
6634 CHAR_BIT;
Alex Langfordbddab072019-08-13 19:40:36 +00006635 return CompilerType(
6636 this, getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006637
6638 default:
6639 break;
6640 }
6641 }
6642 break;
6643
6644 case clang::Type::Record:
6645 if (idx_is_valid && GetCompleteType(type)) {
6646 const clang::RecordType *record_type =
6647 llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr());
6648 const clang::RecordDecl *record_decl = record_type->getDecl();
6649 assert(record_decl);
6650 const clang::ASTRecordLayout &record_layout =
6651 getASTContext()->getASTRecordLayout(record_decl);
6652 uint32_t child_idx = 0;
6653
6654 const clang::CXXRecordDecl *cxx_record_decl =
6655 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
6656 if (cxx_record_decl) {
6657 // We might have base classes to print out first
6658 clang::CXXRecordDecl::base_class_const_iterator base_class,
6659 base_class_end;
6660 for (base_class = cxx_record_decl->bases_begin(),
6661 base_class_end = cxx_record_decl->bases_end();
6662 base_class != base_class_end; ++base_class) {
6663 const clang::CXXRecordDecl *base_class_decl = nullptr;
6664
6665 // Skip empty base classes
6666 if (omit_empty_base_classes) {
6667 base_class_decl = llvm::cast<clang::CXXRecordDecl>(
6668 base_class->getType()->getAs<clang::RecordType>()->getDecl());
Jonas Devliegherea6682a42018-12-15 00:15:33 +00006669 if (!ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00006670 continue;
6671 }
6672
6673 if (idx == child_idx) {
6674 if (base_class_decl == nullptr)
6675 base_class_decl = llvm::cast<clang::CXXRecordDecl>(
6676 base_class->getType()->getAs<clang::RecordType>()->getDecl());
6677
6678 if (base_class->isVirtual()) {
6679 bool handled = false;
6680 if (valobj) {
Aleksandr Urakov1dc51db2018-11-12 16:23:50 +00006681 clang::VTableContextBase *vtable_ctx =
6682 getASTContext()->getVTableContext();
6683 if (vtable_ctx)
6684 handled = GetVBaseBitOffset(*vtable_ctx, *valobj,
6685 record_layout, cxx_record_decl,
6686 base_class_decl, bit_offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00006687 }
6688 if (!handled)
6689 bit_offset = record_layout.getVBaseClassOffset(base_class_decl)
6690 .getQuantity() *
6691 8;
6692 } else
6693 bit_offset = record_layout.getBaseClassOffset(base_class_decl)
6694 .getQuantity() *
6695 8;
6696
6697 // Base classes should be a multiple of 8 bits in size
6698 child_byte_offset = bit_offset / 8;
Alex Langfordbddab072019-08-13 19:40:36 +00006699 CompilerType base_class_clang_type(
6700 this, base_class->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006701 child_name = base_class_clang_type.GetTypeName().AsCString("");
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006702 Optional<uint64_t> size =
6703 base_class_clang_type.GetBitSize(get_exe_scope());
Adrian Prantld963a7c2019-01-15 18:07:52 +00006704 if (!size)
6705 return {};
6706 uint64_t base_class_clang_type_bit_size = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006707
6708 // Base classes bit sizes should be a multiple of 8 bits in size
6709 assert(base_class_clang_type_bit_size % 8 == 0);
6710 child_byte_size = base_class_clang_type_bit_size / 8;
6711 child_is_base_class = true;
6712 return base_class_clang_type;
6713 }
6714 // We don't increment the child index in the for loop since we might
6715 // be skipping empty base classes
6716 ++child_idx;
Greg Claytond8d4a572015-08-11 21:38:15 +00006717 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006718 }
6719 // Make sure index is in range...
6720 uint32_t field_idx = 0;
6721 clang::RecordDecl::field_iterator field, field_end;
6722 for (field = record_decl->field_begin(),
6723 field_end = record_decl->field_end();
6724 field != field_end; ++field, ++field_idx, ++child_idx) {
6725 if (idx == child_idx) {
6726 // Print the member type if requested
6727 // Print the member name and equal sign
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00006728 child_name.assign(field->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006729
6730 // Figure out the type byte size (field_type_info.first) and
6731 // alignment (field_type_info.second) from the AST context.
Alex Langfordbddab072019-08-13 19:40:36 +00006732 CompilerType field_clang_type(this,
6733 field->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006734 assert(field_idx < record_layout.getFieldCount());
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006735 Optional<uint64_t> size =
6736 field_clang_type.GetByteSize(get_exe_scope());
Adrian Prantld963a7c2019-01-15 18:07:52 +00006737 if (!size)
6738 return {};
6739 child_byte_size = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006740 const uint32_t child_bit_size = child_byte_size * 8;
6741
6742 // Figure out the field offset within the current struct/union/class
6743 // type
6744 bit_offset = record_layout.getFieldOffset(field_idx);
6745 if (ClangASTContext::FieldIsBitfield(getASTContext(), *field,
6746 child_bitfield_bit_size)) {
6747 child_bitfield_bit_offset = bit_offset % child_bit_size;
6748 const uint32_t child_bit_offset =
6749 bit_offset - child_bitfield_bit_offset;
6750 child_byte_offset = child_bit_offset / 8;
6751 } else {
6752 child_byte_offset = bit_offset / 8;
6753 }
6754
6755 return field_clang_type;
6756 }
6757 }
Greg Claytond8d4a572015-08-11 21:38:15 +00006758 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006759 break;
6760
6761 case clang::Type::ObjCObject:
6762 case clang::Type::ObjCInterface:
6763 if (idx_is_valid && GetCompleteType(type)) {
6764 const clang::ObjCObjectType *objc_class_type =
6765 llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr());
6766 assert(objc_class_type);
6767 if (objc_class_type) {
6768 uint32_t child_idx = 0;
6769 clang::ObjCInterfaceDecl *class_interface_decl =
6770 objc_class_type->getInterface();
6771
6772 if (class_interface_decl) {
6773
6774 const clang::ASTRecordLayout &interface_layout =
6775 getASTContext()->getASTObjCInterfaceLayout(class_interface_decl);
6776 clang::ObjCInterfaceDecl *superclass_interface_decl =
6777 class_interface_decl->getSuperClass();
6778 if (superclass_interface_decl) {
6779 if (omit_empty_base_classes) {
6780 CompilerType base_class_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00006781 this, getASTContext()
6782 ->getObjCInterfaceType(superclass_interface_decl)
6783 .getAsOpaquePtr());
Adrian Prantleca07c52018-11-05 20:49:07 +00006784 if (base_class_clang_type.GetNumChildren(omit_empty_base_classes,
6785 exe_ctx) > 0) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00006786 if (idx == 0) {
6787 clang::QualType ivar_qual_type(
6788 getASTContext()->getObjCInterfaceType(
6789 superclass_interface_decl));
6790
6791 child_name.assign(
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00006792 superclass_interface_decl->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006793
6794 clang::TypeInfo ivar_type_info =
6795 getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
6796
6797 child_byte_size = ivar_type_info.Width / 8;
6798 child_byte_offset = 0;
6799 child_is_base_class = true;
6800
Alex Langfordbddab072019-08-13 19:40:36 +00006801 return CompilerType(this, ivar_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006802 }
6803
6804 ++child_idx;
6805 }
6806 } else
6807 ++child_idx;
6808 }
6809
6810 const uint32_t superclass_idx = child_idx;
6811
6812 if (idx < (child_idx + class_interface_decl->ivar_size())) {
6813 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
6814 ivar_end = class_interface_decl->ivar_end();
6815
6816 for (ivar_pos = class_interface_decl->ivar_begin();
6817 ivar_pos != ivar_end; ++ivar_pos) {
6818 if (child_idx == idx) {
6819 clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
6820
6821 clang::QualType ivar_qual_type(ivar_decl->getType());
6822
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00006823 child_name.assign(ivar_decl->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006824
6825 clang::TypeInfo ivar_type_info =
6826 getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
6827
6828 child_byte_size = ivar_type_info.Width / 8;
6829
6830 // Figure out the field offset within the current
Adrian Prantl05097242018-04-30 16:49:04 +00006831 // struct/union/class type For ObjC objects, we can't trust the
6832 // bit offset we get from the Clang AST, since that doesn't
6833 // account for the space taken up by unbacked properties, or
6834 // from the changing size of base classes that are newer than
6835 // this class. So if we have a process around that we can ask
6836 // about this object, do so.
Kate Stoneb9c1b512016-09-06 20:57:50 +00006837 child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
6838 Process *process = nullptr;
6839 if (exe_ctx)
6840 process = exe_ctx->GetProcessPtr();
6841 if (process) {
6842 ObjCLanguageRuntime *objc_runtime =
Alex Langforde823bbe2019-06-10 20:53:23 +00006843 ObjCLanguageRuntime::Get(*process);
Kate Stoneb9c1b512016-09-06 20:57:50 +00006844 if (objc_runtime != nullptr) {
Alex Langfordbddab072019-08-13 19:40:36 +00006845 CompilerType parent_ast_type(
6846 this, parent_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006847 child_byte_offset = objc_runtime->GetByteOffsetForIvar(
6848 parent_ast_type, ivar_decl->getNameAsString().c_str());
6849 }
6850 }
6851
Aleksandr Urakovff701722018-08-20 05:59:27 +00006852 // Setting this to INT32_MAX to make sure we don't compute it
Kate Stoneb9c1b512016-09-06 20:57:50 +00006853 // twice...
Aleksandr Urakov53459482018-08-17 07:28:24 +00006854 bit_offset = INT32_MAX;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006855
6856 if (child_byte_offset ==
6857 static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET)) {
6858 bit_offset = interface_layout.getFieldOffset(child_idx -
6859 superclass_idx);
6860 child_byte_offset = bit_offset / 8;
6861 }
6862
6863 // Note, the ObjC Ivar Byte offset is just that, it doesn't
Adrian Prantl05097242018-04-30 16:49:04 +00006864 // account for the bit offset of a bitfield within its
6865 // containing object. So regardless of where we get the byte
Kate Stoneb9c1b512016-09-06 20:57:50 +00006866 // offset from, we still need to get the bit offset for
6867 // bitfields from the layout.
6868
6869 if (ClangASTContext::FieldIsBitfield(getASTContext(), ivar_decl,
6870 child_bitfield_bit_size)) {
Aleksandr Urakov53459482018-08-17 07:28:24 +00006871 if (bit_offset == INT32_MAX)
Kate Stoneb9c1b512016-09-06 20:57:50 +00006872 bit_offset = interface_layout.getFieldOffset(
6873 child_idx - superclass_idx);
6874
6875 child_bitfield_bit_offset = bit_offset % 8;
6876 }
Alex Langfordbddab072019-08-13 19:40:36 +00006877 return CompilerType(this, ivar_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006878 }
6879 ++child_idx;
6880 }
6881 }
6882 }
6883 }
6884 }
6885 break;
6886
6887 case clang::Type::ObjCObjectPointer:
6888 if (idx_is_valid) {
6889 CompilerType pointee_clang_type(GetPointeeType(type));
6890
6891 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6892 child_is_deref_of_parent = false;
6893 bool tmp_child_is_deref_of_parent = false;
6894 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6895 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6896 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6897 child_bitfield_bit_size, child_bitfield_bit_offset,
6898 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
6899 language_flags);
6900 } else {
6901 child_is_deref_of_parent = true;
6902 const char *parent_name =
Konrad Kleine248a1302019-05-23 11:14:47 +00006903 valobj ? valobj->GetName().GetCString() : nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006904 if (parent_name) {
6905 child_name.assign(1, '*');
6906 child_name += parent_name;
6907 }
6908
6909 // We have a pointer to an simple type
6910 if (idx == 0 && pointee_clang_type.GetCompleteType()) {
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006911 if (Optional<uint64_t> size =
6912 pointee_clang_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00006913 child_byte_size = *size;
6914 child_byte_offset = 0;
6915 return pointee_clang_type;
6916 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006917 }
6918 }
6919 }
6920 break;
6921
6922 case clang::Type::Vector:
6923 case clang::Type::ExtVector:
6924 if (idx_is_valid) {
6925 const clang::VectorType *array =
6926 llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr());
6927 if (array) {
Alex Langfordbddab072019-08-13 19:40:36 +00006928 CompilerType element_type(this,
6929 array->getElementType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006930 if (element_type.GetCompleteType()) {
6931 char element_name[64];
6932 ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]",
6933 static_cast<uint64_t>(idx));
6934 child_name.assign(element_name);
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006935 if (Optional<uint64_t> size =
6936 element_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00006937 child_byte_size = *size;
6938 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
6939 return element_type;
6940 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006941 }
6942 }
6943 }
6944 break;
6945
6946 case clang::Type::ConstantArray:
6947 case clang::Type::IncompleteArray:
6948 if (ignore_array_bounds || idx_is_valid) {
6949 const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
6950 if (array) {
Alex Langfordbddab072019-08-13 19:40:36 +00006951 CompilerType element_type(this,
6952 array->getElementType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006953 if (element_type.GetCompleteType()) {
Zachary Turner827d5d72016-12-16 04:27:00 +00006954 child_name = llvm::formatv("[{0}]", idx);
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006955 if (Optional<uint64_t> size =
6956 element_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00006957 child_byte_size = *size;
6958 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
6959 return element_type;
6960 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006961 }
6962 }
6963 }
6964 break;
6965
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006966 case clang::Type::Pointer: {
6967 CompilerType pointee_clang_type(GetPointeeType(type));
Kate Stoneb9c1b512016-09-06 20:57:50 +00006968
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006969 // Don't dereference "void *" pointers
6970 if (pointee_clang_type.IsVoidType())
6971 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006972
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006973 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6974 child_is_deref_of_parent = false;
6975 bool tmp_child_is_deref_of_parent = false;
6976 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6977 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6978 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6979 child_bitfield_bit_size, child_bitfield_bit_offset,
6980 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
6981 language_flags);
6982 } else {
6983 child_is_deref_of_parent = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006984
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006985 const char *parent_name =
Konrad Kleine248a1302019-05-23 11:14:47 +00006986 valobj ? valobj->GetName().GetCString() : nullptr;
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006987 if (parent_name) {
6988 child_name.assign(1, '*');
6989 child_name += parent_name;
6990 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006991
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006992 // We have a pointer to an simple type
6993 if (idx == 0) {
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006994 if (Optional<uint64_t> size =
6995 pointee_clang_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00006996 child_byte_size = *size;
6997 child_byte_offset = 0;
6998 return pointee_clang_type;
6999 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007000 }
7001 }
7002 break;
Tamas Berghammer1c62e032017-01-07 16:39:07 +00007003 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007004
7005 case clang::Type::LValueReference:
7006 case clang::Type::RValueReference:
7007 if (idx_is_valid) {
7008 const clang::ReferenceType *reference_type =
7009 llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
Alex Langfordbddab072019-08-13 19:40:36 +00007010 CompilerType pointee_clang_type(
7011 this, reference_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007012 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
7013 child_is_deref_of_parent = false;
7014 bool tmp_child_is_deref_of_parent = false;
7015 return pointee_clang_type.GetChildCompilerTypeAtIndex(
7016 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7017 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7018 child_bitfield_bit_size, child_bitfield_bit_offset,
7019 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
7020 language_flags);
7021 } else {
7022 const char *parent_name =
Konrad Kleine248a1302019-05-23 11:14:47 +00007023 valobj ? valobj->GetName().GetCString() : nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007024 if (parent_name) {
7025 child_name.assign(1, '&');
7026 child_name += parent_name;
7027 }
7028
7029 // We have a pointer to an simple type
7030 if (idx == 0) {
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00007031 if (Optional<uint64_t> size =
7032 pointee_clang_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00007033 child_byte_size = *size;
7034 child_byte_offset = 0;
7035 return pointee_clang_type;
7036 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007037 }
7038 }
7039 }
7040 break;
7041
7042 case clang::Type::Typedef: {
7043 CompilerType typedefed_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007044 this, llvm::cast<clang::TypedefType>(parent_qual_type)
7045 ->getDecl()
7046 ->getUnderlyingType()
7047 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007048 return typedefed_clang_type.GetChildCompilerTypeAtIndex(
7049 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7050 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7051 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7052 child_is_deref_of_parent, valobj, language_flags);
7053 } break;
7054
7055 case clang::Type::Auto: {
7056 CompilerType elaborated_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007057 this, llvm::cast<clang::AutoType>(parent_qual_type)
7058 ->getDeducedType()
7059 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007060 return elaborated_clang_type.GetChildCompilerTypeAtIndex(
7061 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7062 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7063 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7064 child_is_deref_of_parent, valobj, language_flags);
7065 }
7066
7067 case clang::Type::Elaborated: {
7068 CompilerType elaborated_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007069 this, llvm::cast<clang::ElaboratedType>(parent_qual_type)
7070 ->getNamedType()
7071 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007072 return elaborated_clang_type.GetChildCompilerTypeAtIndex(
7073 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7074 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7075 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7076 child_is_deref_of_parent, valobj, language_flags);
7077 }
7078
7079 case clang::Type::Paren: {
Alex Langfordbddab072019-08-13 19:40:36 +00007080 CompilerType paren_clang_type(this,
7081 llvm::cast<clang::ParenType>(parent_qual_type)
7082 ->desugar()
7083 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007084 return paren_clang_type.GetChildCompilerTypeAtIndex(
7085 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7086 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7087 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7088 child_is_deref_of_parent, valobj, language_flags);
7089 }
7090
7091 default:
7092 break;
7093 }
7094 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00007095}
7096
Kate Stoneb9c1b512016-09-06 20:57:50 +00007097static uint32_t GetIndexForRecordBase(const clang::RecordDecl *record_decl,
7098 const clang::CXXBaseSpecifier *base_spec,
7099 bool omit_empty_base_classes) {
7100 uint32_t child_idx = 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00007101
Kate Stoneb9c1b512016-09-06 20:57:50 +00007102 const clang::CXXRecordDecl *cxx_record_decl =
7103 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
7104
7105 // const char *super_name = record_decl->getNameAsCString();
7106 // const char *base_name =
7107 // base_spec->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString();
7108 // printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
7109 //
7110 if (cxx_record_decl) {
7111 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
7112 for (base_class = cxx_record_decl->bases_begin(),
7113 base_class_end = cxx_record_decl->bases_end();
7114 base_class != base_class_end; ++base_class) {
7115 if (omit_empty_base_classes) {
7116 if (BaseSpecifierIsEmpty(base_class))
7117 continue;
7118 }
7119
7120 // printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
7121 // super_name, base_name,
7122 // child_idx,
7123 // base_class->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString());
7124 //
7125 //
7126 if (base_class == base_spec)
7127 return child_idx;
7128 ++child_idx;
Greg Claytond8d4a572015-08-11 21:38:15 +00007129 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007130 }
7131
7132 return UINT32_MAX;
7133}
7134
7135static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl,
7136 clang::NamedDecl *canonical_decl,
7137 bool omit_empty_base_classes) {
7138 uint32_t child_idx = ClangASTContext::GetNumBaseClasses(
7139 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
7140 omit_empty_base_classes);
7141
7142 clang::RecordDecl::field_iterator field, field_end;
7143 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
7144 field != field_end; ++field, ++child_idx) {
7145 if (field->getCanonicalDecl() == canonical_decl)
7146 return child_idx;
7147 }
7148
7149 return UINT32_MAX;
Greg Claytond8d4a572015-08-11 21:38:15 +00007150}
7151
7152// Look for a child member (doesn't include base classes, but it does include
Adrian Prantl05097242018-04-30 16:49:04 +00007153// their members) in the type hierarchy. Returns an index path into
7154// "clang_type" on how to reach the appropriate member.
Greg Claytond8d4a572015-08-11 21:38:15 +00007155//
7156// class A
7157// {
7158// public:
7159// int m_a;
7160// int m_b;
7161// };
7162//
7163// class B
7164// {
7165// };
7166//
7167// class C :
7168// public B,
7169// public A
7170// {
7171// };
7172//
7173// If we have a clang type that describes "class C", and we wanted to looked
7174// "m_b" in it:
7175//
Kate Stoneb9c1b512016-09-06 20:57:50 +00007176// With omit_empty_base_classes == false we would get an integer array back
Adrian Prantl05097242018-04-30 16:49:04 +00007177// with: { 1, 1 } The first index 1 is the child index for "class A" within
7178// class C The second index 1 is the child index for "m_b" within class A
Greg Claytond8d4a572015-08-11 21:38:15 +00007179//
Adrian Prantl05097242018-04-30 16:49:04 +00007180// With omit_empty_base_classes == true we would get an integer array back
7181// with: { 0, 1 } The first index 0 is the child index for "class A" within
7182// class C (since class B doesn't have any members it doesn't count) The second
7183// index 1 is the child index for "m_b" within class A
Greg Claytond8d4a572015-08-11 21:38:15 +00007184
Kate Stoneb9c1b512016-09-06 20:57:50 +00007185size_t ClangASTContext::GetIndexOfChildMemberWithName(
7186 lldb::opaque_compiler_type_t type, const char *name,
7187 bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
7188 if (type && name && name[0]) {
7189 clang::QualType qual_type(GetCanonicalQualType(type));
7190 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7191 switch (type_class) {
7192 case clang::Type::Record:
7193 if (GetCompleteType(type)) {
7194 const clang::RecordType *record_type =
7195 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
7196 const clang::RecordDecl *record_decl = record_type->getDecl();
Enrico Granata36f51e42015-12-18 22:41:25 +00007197
Kate Stoneb9c1b512016-09-06 20:57:50 +00007198 assert(record_decl);
7199 uint32_t child_idx = 0;
7200
7201 const clang::CXXRecordDecl *cxx_record_decl =
7202 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
7203
7204 // Try and find a field that matches NAME
7205 clang::RecordDecl::field_iterator field, field_end;
7206 llvm::StringRef name_sref(name);
7207 for (field = record_decl->field_begin(),
7208 field_end = record_decl->field_end();
7209 field != field_end; ++field, ++child_idx) {
7210 llvm::StringRef field_name = field->getName();
7211 if (field_name.empty()) {
Alex Langfordbddab072019-08-13 19:40:36 +00007212 CompilerType field_type(this, field->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007213 child_indexes.push_back(child_idx);
7214 if (field_type.GetIndexOfChildMemberWithName(
7215 name, omit_empty_base_classes, child_indexes))
7216 return child_indexes.size();
7217 child_indexes.pop_back();
7218
7219 } else if (field_name.equals(name_sref)) {
7220 // We have to add on the number of base classes to this index!
7221 child_indexes.push_back(
7222 child_idx + ClangASTContext::GetNumBaseClasses(
7223 cxx_record_decl, omit_empty_base_classes));
7224 return child_indexes.size();
7225 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007226 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007227
Kate Stoneb9c1b512016-09-06 20:57:50 +00007228 if (cxx_record_decl) {
7229 const clang::RecordDecl *parent_record_decl = cxx_record_decl;
7230
7231 // printf ("parent = %s\n", parent_record_decl->getNameAsCString());
7232
7233 // const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
7234 // Didn't find things easily, lets let clang do its thang...
7235 clang::IdentifierInfo &ident_ref =
7236 getASTContext()->Idents.get(name_sref);
7237 clang::DeclarationName decl_name(&ident_ref);
7238
7239 clang::CXXBasePaths paths;
7240 if (cxx_record_decl->lookupInBases(
7241 [decl_name](const clang::CXXBaseSpecifier *specifier,
7242 clang::CXXBasePath &path) {
7243 return clang::CXXRecordDecl::FindOrdinaryMember(
7244 specifier, path, decl_name);
7245 },
7246 paths)) {
7247 clang::CXXBasePaths::const_paths_iterator path,
7248 path_end = paths.end();
7249 for (path = paths.begin(); path != path_end; ++path) {
7250 const size_t num_path_elements = path->size();
7251 for (size_t e = 0; e < num_path_elements; ++e) {
7252 clang::CXXBasePathElement elem = (*path)[e];
7253
7254 child_idx = GetIndexForRecordBase(parent_record_decl, elem.Base,
7255 omit_empty_base_classes);
7256 if (child_idx == UINT32_MAX) {
7257 child_indexes.clear();
7258 return 0;
7259 } else {
7260 child_indexes.push_back(child_idx);
7261 parent_record_decl = llvm::cast<clang::RecordDecl>(
7262 elem.Base->getType()
7263 ->getAs<clang::RecordType>()
7264 ->getDecl());
7265 }
7266 }
7267 for (clang::NamedDecl *path_decl : path->Decls) {
7268 child_idx = GetIndexForRecordChild(
7269 parent_record_decl, path_decl, omit_empty_base_classes);
7270 if (child_idx == UINT32_MAX) {
7271 child_indexes.clear();
7272 return 0;
7273 } else {
7274 child_indexes.push_back(child_idx);
7275 }
7276 }
7277 }
7278 return child_indexes.size();
7279 }
7280 }
7281 }
7282 break;
7283
7284 case clang::Type::ObjCObject:
7285 case clang::Type::ObjCInterface:
7286 if (GetCompleteType(type)) {
7287 llvm::StringRef name_sref(name);
7288 const clang::ObjCObjectType *objc_class_type =
7289 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
7290 assert(objc_class_type);
7291 if (objc_class_type) {
7292 uint32_t child_idx = 0;
7293 clang::ObjCInterfaceDecl *class_interface_decl =
7294 objc_class_type->getInterface();
7295
7296 if (class_interface_decl) {
7297 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
7298 ivar_end = class_interface_decl->ivar_end();
7299 clang::ObjCInterfaceDecl *superclass_interface_decl =
7300 class_interface_decl->getSuperClass();
7301
7302 for (ivar_pos = class_interface_decl->ivar_begin();
7303 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
7304 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
7305
7306 if (ivar_decl->getName().equals(name_sref)) {
7307 if ((!omit_empty_base_classes && superclass_interface_decl) ||
7308 (omit_empty_base_classes &&
7309 ObjCDeclHasIVars(superclass_interface_decl, true)))
7310 ++child_idx;
7311
7312 child_indexes.push_back(child_idx);
7313 return child_indexes.size();
7314 }
7315 }
7316
7317 if (superclass_interface_decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00007318 // The super class index is always zero for ObjC classes, so we
7319 // push it onto the child indexes in case we find an ivar in our
7320 // superclass...
Kate Stoneb9c1b512016-09-06 20:57:50 +00007321 child_indexes.push_back(0);
7322
7323 CompilerType superclass_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007324 this, getASTContext()
7325 ->getObjCInterfaceType(superclass_interface_decl)
7326 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007327 if (superclass_clang_type.GetIndexOfChildMemberWithName(
7328 name, omit_empty_base_classes, child_indexes)) {
Adrian Prantl05097242018-04-30 16:49:04 +00007329 // We did find an ivar in a superclass so just return the
7330 // results!
Kate Stoneb9c1b512016-09-06 20:57:50 +00007331 return child_indexes.size();
7332 }
7333
Adrian Prantl05097242018-04-30 16:49:04 +00007334 // We didn't find an ivar matching "name" in our superclass, pop
7335 // the superclass zero index that we pushed on above.
Kate Stoneb9c1b512016-09-06 20:57:50 +00007336 child_indexes.pop_back();
7337 }
7338 }
7339 }
7340 }
7341 break;
7342
7343 case clang::Type::ObjCObjectPointer: {
7344 CompilerType objc_object_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007345 this, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
7346 ->getPointeeType()
7347 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007348 return objc_object_clang_type.GetIndexOfChildMemberWithName(
7349 name, omit_empty_base_classes, child_indexes);
7350 } break;
7351
7352 case clang::Type::ConstantArray: {
7353 // const clang::ConstantArrayType *array =
7354 // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
7355 // const uint64_t element_count =
7356 // array->getSize().getLimitedValue();
7357 //
7358 // if (idx < element_count)
7359 // {
7360 // std::pair<uint64_t, unsigned> field_type_info =
7361 // ast->getTypeInfo(array->getElementType());
7362 //
7363 // char element_name[32];
7364 // ::snprintf (element_name, sizeof (element_name),
7365 // "%s[%u]", parent_name ? parent_name : "", idx);
7366 //
7367 // child_name.assign(element_name);
7368 // assert(field_type_info.first % 8 == 0);
7369 // child_byte_size = field_type_info.first / 8;
7370 // child_byte_offset = idx * child_byte_size;
7371 // return array->getElementType().getAsOpaquePtr();
7372 // }
7373 } break;
7374
7375 // case clang::Type::MemberPointerType:
7376 // {
7377 // MemberPointerType *mem_ptr_type =
7378 // llvm::cast<MemberPointerType>(qual_type.getTypePtr());
7379 // clang::QualType pointee_type =
7380 // mem_ptr_type->getPointeeType();
7381 //
7382 // if (ClangASTContext::IsAggregateType
7383 // (pointee_type.getAsOpaquePtr()))
7384 // {
7385 // return GetIndexOfChildWithName (ast,
7386 // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
7387 // name);
7388 // }
7389 // }
7390 // break;
7391 //
7392 case clang::Type::LValueReference:
7393 case clang::Type::RValueReference: {
7394 const clang::ReferenceType *reference_type =
7395 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
7396 clang::QualType pointee_type(reference_type->getPointeeType());
Alex Langfordbddab072019-08-13 19:40:36 +00007397 CompilerType pointee_clang_type(this, pointee_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007398
7399 if (pointee_clang_type.IsAggregateType()) {
7400 return pointee_clang_type.GetIndexOfChildMemberWithName(
7401 name, omit_empty_base_classes, child_indexes);
7402 }
7403 } break;
7404
7405 case clang::Type::Pointer: {
7406 CompilerType pointee_clang_type(GetPointeeType(type));
7407
7408 if (pointee_clang_type.IsAggregateType()) {
7409 return pointee_clang_type.GetIndexOfChildMemberWithName(
7410 name, omit_empty_base_classes, child_indexes);
7411 }
7412 } break;
7413
7414 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00007415 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
7416 ->getDecl()
7417 ->getUnderlyingType()
7418 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007419 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7420 child_indexes);
7421
7422 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00007423 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
7424 ->getDeducedType()
7425 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007426 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7427 child_indexes);
7428
7429 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00007430 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
7431 ->getNamedType()
7432 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007433 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7434 child_indexes);
7435
7436 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00007437 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
7438 ->desugar()
7439 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007440 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7441 child_indexes);
7442
7443 default:
7444 break;
7445 }
7446 }
7447 return 0;
7448}
Greg Claytond8d4a572015-08-11 21:38:15 +00007449
7450// Get the index of the child of "clang_type" whose name matches. This function
7451// doesn't descend into the children, but only looks one level deep and name
7452// matches can include base class names.
7453
7454uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00007455ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
7456 const char *name,
7457 bool omit_empty_base_classes) {
7458 if (type && name && name[0]) {
7459 clang::QualType qual_type(GetCanonicalQualType(type));
Enrico Granata36f51e42015-12-18 22:41:25 +00007460
Kate Stoneb9c1b512016-09-06 20:57:50 +00007461 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7462
7463 switch (type_class) {
7464 case clang::Type::Record:
7465 if (GetCompleteType(type)) {
7466 const clang::RecordType *record_type =
7467 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
7468 const clang::RecordDecl *record_decl = record_type->getDecl();
7469
7470 assert(record_decl);
7471 uint32_t child_idx = 0;
7472
7473 const clang::CXXRecordDecl *cxx_record_decl =
7474 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
7475
7476 if (cxx_record_decl) {
7477 clang::CXXRecordDecl::base_class_const_iterator base_class,
7478 base_class_end;
7479 for (base_class = cxx_record_decl->bases_begin(),
7480 base_class_end = cxx_record_decl->bases_end();
7481 base_class != base_class_end; ++base_class) {
7482 // Skip empty base classes
7483 clang::CXXRecordDecl *base_class_decl =
7484 llvm::cast<clang::CXXRecordDecl>(
7485 base_class->getType()
7486 ->getAs<clang::RecordType>()
7487 ->getDecl());
7488 if (omit_empty_base_classes &&
Jonas Devliegherea6682a42018-12-15 00:15:33 +00007489 !ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00007490 continue;
7491
Alex Langfordbddab072019-08-13 19:40:36 +00007492 CompilerType base_class_clang_type(
7493 this, base_class->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007494 std::string base_class_type_name(
7495 base_class_clang_type.GetTypeName().AsCString(""));
Jonas Devlieghere8d20cfd2018-12-21 22:46:10 +00007496 if (base_class_type_name == name)
Kate Stoneb9c1b512016-09-06 20:57:50 +00007497 return child_idx;
7498 ++child_idx;
7499 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007500 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007501
Kate Stoneb9c1b512016-09-06 20:57:50 +00007502 // Try and find a field that matches NAME
7503 clang::RecordDecl::field_iterator field, field_end;
7504 llvm::StringRef name_sref(name);
7505 for (field = record_decl->field_begin(),
7506 field_end = record_decl->field_end();
7507 field != field_end; ++field, ++child_idx) {
7508 if (field->getName().equals(name_sref))
7509 return child_idx;
7510 }
7511 }
7512 break;
7513
7514 case clang::Type::ObjCObject:
7515 case clang::Type::ObjCInterface:
7516 if (GetCompleteType(type)) {
7517 llvm::StringRef name_sref(name);
7518 const clang::ObjCObjectType *objc_class_type =
7519 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
7520 assert(objc_class_type);
7521 if (objc_class_type) {
7522 uint32_t child_idx = 0;
7523 clang::ObjCInterfaceDecl *class_interface_decl =
7524 objc_class_type->getInterface();
7525
7526 if (class_interface_decl) {
7527 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
7528 ivar_end = class_interface_decl->ivar_end();
7529 clang::ObjCInterfaceDecl *superclass_interface_decl =
7530 class_interface_decl->getSuperClass();
7531
7532 for (ivar_pos = class_interface_decl->ivar_begin();
7533 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
7534 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
7535
7536 if (ivar_decl->getName().equals(name_sref)) {
7537 if ((!omit_empty_base_classes && superclass_interface_decl) ||
7538 (omit_empty_base_classes &&
7539 ObjCDeclHasIVars(superclass_interface_decl, true)))
7540 ++child_idx;
7541
7542 return child_idx;
7543 }
7544 }
7545
7546 if (superclass_interface_decl) {
7547 if (superclass_interface_decl->getName().equals(name_sref))
7548 return 0;
7549 }
7550 }
7551 }
7552 }
7553 break;
7554
7555 case clang::Type::ObjCObjectPointer: {
7556 CompilerType pointee_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007557 this, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
7558 ->getPointeeType()
7559 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007560 return pointee_clang_type.GetIndexOfChildWithName(
7561 name, omit_empty_base_classes);
7562 } break;
7563
7564 case clang::Type::ConstantArray: {
7565 // const clang::ConstantArrayType *array =
7566 // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
7567 // const uint64_t element_count =
7568 // array->getSize().getLimitedValue();
7569 //
7570 // if (idx < element_count)
7571 // {
7572 // std::pair<uint64_t, unsigned> field_type_info =
7573 // ast->getTypeInfo(array->getElementType());
7574 //
7575 // char element_name[32];
7576 // ::snprintf (element_name, sizeof (element_name),
7577 // "%s[%u]", parent_name ? parent_name : "", idx);
7578 //
7579 // child_name.assign(element_name);
7580 // assert(field_type_info.first % 8 == 0);
7581 // child_byte_size = field_type_info.first / 8;
7582 // child_byte_offset = idx * child_byte_size;
7583 // return array->getElementType().getAsOpaquePtr();
7584 // }
7585 } break;
7586
7587 // case clang::Type::MemberPointerType:
7588 // {
7589 // MemberPointerType *mem_ptr_type =
7590 // llvm::cast<MemberPointerType>(qual_type.getTypePtr());
7591 // clang::QualType pointee_type =
7592 // mem_ptr_type->getPointeeType();
7593 //
7594 // if (ClangASTContext::IsAggregateType
7595 // (pointee_type.getAsOpaquePtr()))
7596 // {
7597 // return GetIndexOfChildWithName (ast,
7598 // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
7599 // name);
7600 // }
7601 // }
7602 // break;
7603 //
7604 case clang::Type::LValueReference:
7605 case clang::Type::RValueReference: {
7606 const clang::ReferenceType *reference_type =
7607 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
Alex Langfordbddab072019-08-13 19:40:36 +00007608 CompilerType pointee_type(
7609 this, reference_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007610
7611 if (pointee_type.IsAggregateType()) {
7612 return pointee_type.GetIndexOfChildWithName(name,
7613 omit_empty_base_classes);
7614 }
7615 } break;
7616
7617 case clang::Type::Pointer: {
7618 const clang::PointerType *pointer_type =
7619 llvm::cast<clang::PointerType>(qual_type.getTypePtr());
Alex Langfordbddab072019-08-13 19:40:36 +00007620 CompilerType pointee_type(
7621 this, pointer_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007622
7623 if (pointee_type.IsAggregateType()) {
7624 return pointee_type.GetIndexOfChildWithName(name,
7625 omit_empty_base_classes);
7626 } else {
7627 // if (parent_name)
7628 // {
7629 // child_name.assign(1, '*');
7630 // child_name += parent_name;
7631 // }
7632 //
7633 // // We have a pointer to an simple type
7634 // if (idx == 0)
7635 // {
7636 // std::pair<uint64_t, unsigned> clang_type_info
7637 // = ast->getTypeInfo(pointee_type);
7638 // assert(clang_type_info.first % 8 == 0);
7639 // child_byte_size = clang_type_info.first / 8;
7640 // child_byte_offset = 0;
7641 // return pointee_type.getAsOpaquePtr();
7642 // }
7643 }
7644 } break;
7645
7646 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00007647 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
7648 ->getDeducedType()
7649 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007650 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7651
7652 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00007653 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
7654 ->getNamedType()
7655 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007656 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7657
7658 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00007659 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
7660 ->desugar()
7661 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007662 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7663
7664 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00007665 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
7666 ->getDecl()
7667 ->getUnderlyingType()
7668 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007669 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7670
7671 default:
7672 break;
7673 }
7674 }
7675 return UINT32_MAX;
7676}
Greg Claytond8d4a572015-08-11 21:38:15 +00007677
7678size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00007679ClangASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
7680 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00007681 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00007682
Kate Stoneb9c1b512016-09-06 20:57:50 +00007683 clang::QualType qual_type(GetCanonicalQualType(type));
7684 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7685 switch (type_class) {
7686 case clang::Type::Record:
7687 if (GetCompleteType(type)) {
7688 const clang::CXXRecordDecl *cxx_record_decl =
7689 qual_type->getAsCXXRecordDecl();
7690 if (cxx_record_decl) {
7691 const clang::ClassTemplateSpecializationDecl *template_decl =
7692 llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
7693 cxx_record_decl);
7694 if (template_decl)
7695 return template_decl->getTemplateArgs().size();
7696 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007697 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007698 break;
7699
7700 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00007701 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
7702 ->getDecl()
7703 ->getUnderlyingType()
7704 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007705 .GetNumTemplateArguments();
7706
7707 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00007708 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
7709 ->getDeducedType()
7710 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007711 .GetNumTemplateArguments();
7712
7713 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00007714 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
7715 ->getNamedType()
7716 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007717 .GetNumTemplateArguments();
7718
7719 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00007720 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
7721 ->desugar()
7722 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007723 .GetNumTemplateArguments();
7724
7725 default:
7726 break;
7727 }
7728
7729 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00007730}
7731
Pavel Labath769b21e2017-11-13 14:26:21 +00007732const clang::ClassTemplateSpecializationDecl *
7733ClangASTContext::GetAsTemplateSpecialization(
7734 lldb::opaque_compiler_type_t type) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00007735 if (!type)
Pavel Labath769b21e2017-11-13 14:26:21 +00007736 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007737
7738 clang::QualType qual_type(GetCanonicalQualType(type));
7739 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7740 switch (type_class) {
Pavel Labath769b21e2017-11-13 14:26:21 +00007741 case clang::Type::Record: {
7742 if (! GetCompleteType(type))
7743 return nullptr;
7744 const clang::CXXRecordDecl *cxx_record_decl =
7745 qual_type->getAsCXXRecordDecl();
7746 if (!cxx_record_decl)
7747 return nullptr;
7748 return llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
7749 cxx_record_decl);
7750 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007751
7752 case clang::Type::Typedef:
Pavel Labath769b21e2017-11-13 14:26:21 +00007753 return GetAsTemplateSpecialization(llvm::cast<clang::TypedefType>(qual_type)
7754 ->getDecl()
7755 ->getUnderlyingType()
7756 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007757
7758 case clang::Type::Auto:
Pavel Labath769b21e2017-11-13 14:26:21 +00007759 return GetAsTemplateSpecialization(llvm::cast<clang::AutoType>(qual_type)
7760 ->getDeducedType()
7761 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007762
7763 case clang::Type::Elaborated:
Pavel Labath769b21e2017-11-13 14:26:21 +00007764 return GetAsTemplateSpecialization(
7765 llvm::cast<clang::ElaboratedType>(qual_type)
7766 ->getNamedType()
7767 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007768
7769 case clang::Type::Paren:
Pavel Labath769b21e2017-11-13 14:26:21 +00007770 return GetAsTemplateSpecialization(
7771 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007772
7773 default:
Pavel Labath769b21e2017-11-13 14:26:21 +00007774 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007775 }
Pavel Labath769b21e2017-11-13 14:26:21 +00007776}
7777
7778lldb::TemplateArgumentKind
7779ClangASTContext::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
7780 size_t arg_idx) {
7781 const clang::ClassTemplateSpecializationDecl *template_decl =
7782 GetAsTemplateSpecialization(type);
7783 if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size())
7784 return eTemplateArgumentKindNull;
7785
7786 switch (template_decl->getTemplateArgs()[arg_idx].getKind()) {
7787 case clang::TemplateArgument::Null:
7788 return eTemplateArgumentKindNull;
7789
7790 case clang::TemplateArgument::NullPtr:
7791 return eTemplateArgumentKindNullPtr;
7792
7793 case clang::TemplateArgument::Type:
7794 return eTemplateArgumentKindType;
7795
7796 case clang::TemplateArgument::Declaration:
7797 return eTemplateArgumentKindDeclaration;
7798
7799 case clang::TemplateArgument::Integral:
7800 return eTemplateArgumentKindIntegral;
7801
7802 case clang::TemplateArgument::Template:
7803 return eTemplateArgumentKindTemplate;
7804
7805 case clang::TemplateArgument::TemplateExpansion:
7806 return eTemplateArgumentKindTemplateExpansion;
7807
7808 case clang::TemplateArgument::Expression:
7809 return eTemplateArgumentKindExpression;
7810
7811 case clang::TemplateArgument::Pack:
7812 return eTemplateArgumentKindPack;
7813 }
7814 llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind");
7815}
7816
7817CompilerType
7818ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
7819 size_t idx) {
7820 const clang::ClassTemplateSpecializationDecl *template_decl =
7821 GetAsTemplateSpecialization(type);
7822 if (!template_decl || idx >= template_decl->getTemplateArgs().size())
7823 return CompilerType();
7824
7825 const clang::TemplateArgument &template_arg =
7826 template_decl->getTemplateArgs()[idx];
7827 if (template_arg.getKind() != clang::TemplateArgument::Type)
7828 return CompilerType();
7829
Alex Langfordbddab072019-08-13 19:40:36 +00007830 return CompilerType(this, template_arg.getAsType().getAsOpaquePtr());
Pavel Labath769b21e2017-11-13 14:26:21 +00007831}
7832
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00007833Optional<CompilerType::IntegralTemplateArgument>
Pavel Labath769b21e2017-11-13 14:26:21 +00007834ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
7835 size_t idx) {
7836 const clang::ClassTemplateSpecializationDecl *template_decl =
7837 GetAsTemplateSpecialization(type);
7838 if (! template_decl || idx >= template_decl->getTemplateArgs().size())
Pavel Labathf59056f2017-11-30 10:16:54 +00007839 return llvm::None;
Pavel Labath769b21e2017-11-13 14:26:21 +00007840
7841 const clang::TemplateArgument &template_arg =
7842 template_decl->getTemplateArgs()[idx];
7843 if (template_arg.getKind() != clang::TemplateArgument::Integral)
Pavel Labathf59056f2017-11-30 10:16:54 +00007844 return llvm::None;
Pavel Labath769b21e2017-11-13 14:26:21 +00007845
Alex Langfordbddab072019-08-13 19:40:36 +00007846 return {
7847 {template_arg.getAsIntegral(),
7848 CompilerType(this, template_arg.getIntegralType().getAsOpaquePtr())}};
Enrico Granatac6bf2e22015-09-23 01:39:46 +00007849}
7850
Kate Stoneb9c1b512016-09-06 20:57:50 +00007851CompilerType ClangASTContext::GetTypeForFormatters(void *type) {
7852 if (type)
7853 return ClangUtil::RemoveFastQualifiers(CompilerType(this, type));
7854 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00007855}
7856
Kate Stoneb9c1b512016-09-06 20:57:50 +00007857clang::EnumDecl *ClangASTContext::GetAsEnumDecl(const CompilerType &type) {
7858 const clang::EnumType *enutype =
7859 llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type));
7860 if (enutype)
7861 return enutype->getDecl();
Konrad Kleine248a1302019-05-23 11:14:47 +00007862 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007863}
7864
7865clang::RecordDecl *ClangASTContext::GetAsRecordDecl(const CompilerType &type) {
7866 const clang::RecordType *record_type =
7867 llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type));
7868 if (record_type)
7869 return record_type->getDecl();
7870 return nullptr;
7871}
7872
7873clang::TagDecl *ClangASTContext::GetAsTagDecl(const CompilerType &type) {
Zachary Turner1639c6b2018-12-17 16:15:13 +00007874 return ClangUtil::GetAsTagDecl(type);
Greg Claytone6b36cd2015-12-08 01:02:08 +00007875}
7876
Aleksandr Urakov709426b2018-09-10 08:08:43 +00007877clang::TypedefNameDecl *
7878ClangASTContext::GetAsTypedefDecl(const CompilerType &type) {
7879 const clang::TypedefType *typedef_type =
7880 llvm::dyn_cast<clang::TypedefType>(ClangUtil::GetQualType(type));
7881 if (typedef_type)
7882 return typedef_type->getDecl();
7883 return nullptr;
7884}
7885
Greg Claytond8d4a572015-08-11 21:38:15 +00007886clang::CXXRecordDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00007887ClangASTContext::GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type) {
7888 return GetCanonicalQualType(type)->getAsCXXRecordDecl();
Greg Claytond8d4a572015-08-11 21:38:15 +00007889}
7890
7891clang::ObjCInterfaceDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00007892ClangASTContext::GetAsObjCInterfaceDecl(const CompilerType &type) {
7893 const clang::ObjCObjectType *objc_class_type =
7894 llvm::dyn_cast<clang::ObjCObjectType>(
7895 ClangUtil::GetCanonicalQualType(type));
7896 if (objc_class_type)
7897 return objc_class_type->getInterface();
7898 return nullptr;
7899}
7900
7901clang::FieldDecl *ClangASTContext::AddFieldToRecordType(
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007902 const CompilerType &type, llvm::StringRef name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00007903 const CompilerType &field_clang_type, AccessType access,
7904 uint32_t bitfield_bit_size) {
7905 if (!type.IsValid() || !field_clang_type.IsValid())
Greg Claytond8d4a572015-08-11 21:38:15 +00007906 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007907 ClangASTContext *ast =
7908 llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
7909 if (!ast)
7910 return nullptr;
7911 clang::ASTContext *clang_ast = ast->getASTContext();
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007912 clang::IdentifierInfo *ident = nullptr;
7913 if (!name.empty())
7914 ident = &clang_ast->Idents.get(name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00007915
7916 clang::FieldDecl *field = nullptr;
7917
7918 clang::Expr *bit_width = nullptr;
7919 if (bitfield_bit_size != 0) {
7920 llvm::APInt bitfield_bit_size_apint(
7921 clang_ast->getTypeSize(clang_ast->IntTy), bitfield_bit_size);
7922 bit_width = new (*clang_ast)
7923 clang::IntegerLiteral(*clang_ast, bitfield_bit_size_apint,
7924 clang_ast->IntTy, clang::SourceLocation());
7925 }
7926
7927 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
7928 if (record_decl) {
7929 field = clang::FieldDecl::Create(
7930 *clang_ast, record_decl, clang::SourceLocation(),
7931 clang::SourceLocation(),
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007932 ident, // Identifier
7933 ClangUtil::GetQualType(field_clang_type), // Field type
7934 nullptr, // TInfo *
7935 bit_width, // BitWidth
7936 false, // Mutable
7937 clang::ICIS_NoInit); // HasInit
Kate Stoneb9c1b512016-09-06 20:57:50 +00007938
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007939 if (name.empty()) {
Adrian Prantl05097242018-04-30 16:49:04 +00007940 // Determine whether this field corresponds to an anonymous struct or
7941 // union.
Kate Stoneb9c1b512016-09-06 20:57:50 +00007942 if (const clang::TagType *TagT =
7943 field->getType()->getAs<clang::TagType>()) {
7944 if (clang::RecordDecl *Rec =
7945 llvm::dyn_cast<clang::RecordDecl>(TagT->getDecl()))
7946 if (!Rec->getDeclName()) {
7947 Rec->setAnonymousStructOrUnion(true);
7948 field->setImplicit();
7949 }
7950 }
7951 }
7952
7953 if (field) {
7954 field->setAccess(
7955 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access));
7956
7957 record_decl->addDecl(field);
7958
7959#ifdef LLDB_CONFIGURATION_DEBUG
7960 VerifyDecl(field);
7961#endif
7962 }
7963 } else {
7964 clang::ObjCInterfaceDecl *class_interface_decl =
7965 ast->GetAsObjCInterfaceDecl(type);
7966
7967 if (class_interface_decl) {
7968 const bool is_synthesized = false;
7969
7970 field_clang_type.GetCompleteType();
7971
7972 field = clang::ObjCIvarDecl::Create(
7973 *clang_ast, class_interface_decl, clang::SourceLocation(),
7974 clang::SourceLocation(),
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007975 ident, // Identifier
7976 ClangUtil::GetQualType(field_clang_type), // Field type
7977 nullptr, // TypeSourceInfo *
Kate Stoneb9c1b512016-09-06 20:57:50 +00007978 ConvertAccessTypeToObjCIvarAccessControl(access), bit_width,
7979 is_synthesized);
7980
7981 if (field) {
7982 class_interface_decl->addDecl(field);
7983
7984#ifdef LLDB_CONFIGURATION_DEBUG
7985 VerifyDecl(field);
7986#endif
7987 }
7988 }
7989 }
7990 return field;
Greg Claytond8d4a572015-08-11 21:38:15 +00007991}
7992
Kate Stoneb9c1b512016-09-06 20:57:50 +00007993void ClangASTContext::BuildIndirectFields(const CompilerType &type) {
7994 if (!type)
7995 return;
Zachary Turnerd133f6a2016-03-28 22:53:41 +00007996
Kate Stoneb9c1b512016-09-06 20:57:50 +00007997 ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
7998 if (!ast)
7999 return;
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008000
Kate Stoneb9c1b512016-09-06 20:57:50 +00008001 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008002
Kate Stoneb9c1b512016-09-06 20:57:50 +00008003 if (!record_decl)
8004 return;
8005
8006 typedef llvm::SmallVector<clang::IndirectFieldDecl *, 1> IndirectFieldVector;
8007
8008 IndirectFieldVector indirect_fields;
8009 clang::RecordDecl::field_iterator field_pos;
8010 clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end();
8011 clang::RecordDecl::field_iterator last_field_pos = field_end_pos;
8012 for (field_pos = record_decl->field_begin(); field_pos != field_end_pos;
8013 last_field_pos = field_pos++) {
8014 if (field_pos->isAnonymousStructOrUnion()) {
8015 clang::QualType field_qual_type = field_pos->getType();
8016
8017 const clang::RecordType *field_record_type =
8018 field_qual_type->getAs<clang::RecordType>();
8019
8020 if (!field_record_type)
8021 continue;
8022
8023 clang::RecordDecl *field_record_decl = field_record_type->getDecl();
8024
8025 if (!field_record_decl)
8026 continue;
8027
8028 for (clang::RecordDecl::decl_iterator
8029 di = field_record_decl->decls_begin(),
8030 de = field_record_decl->decls_end();
8031 di != de; ++di) {
8032 if (clang::FieldDecl *nested_field_decl =
8033 llvm::dyn_cast<clang::FieldDecl>(*di)) {
8034 clang::NamedDecl **chain =
8035 new (*ast->getASTContext()) clang::NamedDecl *[2];
8036 chain[0] = *field_pos;
8037 chain[1] = nested_field_decl;
8038 clang::IndirectFieldDecl *indirect_field =
8039 clang::IndirectFieldDecl::Create(
8040 *ast->getASTContext(), record_decl, clang::SourceLocation(),
8041 nested_field_decl->getIdentifier(),
8042 nested_field_decl->getType(), {chain, 2});
8043
8044 indirect_field->setImplicit();
8045
8046 indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(
8047 field_pos->getAccess(), nested_field_decl->getAccess()));
8048
8049 indirect_fields.push_back(indirect_field);
8050 } else if (clang::IndirectFieldDecl *nested_indirect_field_decl =
8051 llvm::dyn_cast<clang::IndirectFieldDecl>(*di)) {
8052 size_t nested_chain_size =
8053 nested_indirect_field_decl->getChainingSize();
8054 clang::NamedDecl **chain = new (*ast->getASTContext())
8055 clang::NamedDecl *[nested_chain_size + 1];
8056 chain[0] = *field_pos;
8057
8058 int chain_index = 1;
8059 for (clang::IndirectFieldDecl::chain_iterator
8060 nci = nested_indirect_field_decl->chain_begin(),
8061 nce = nested_indirect_field_decl->chain_end();
8062 nci < nce; ++nci) {
8063 chain[chain_index] = *nci;
8064 chain_index++;
8065 }
8066
8067 clang::IndirectFieldDecl *indirect_field =
8068 clang::IndirectFieldDecl::Create(
8069 *ast->getASTContext(), record_decl, clang::SourceLocation(),
8070 nested_indirect_field_decl->getIdentifier(),
8071 nested_indirect_field_decl->getType(),
8072 {chain, nested_chain_size + 1});
8073
8074 indirect_field->setImplicit();
8075
8076 indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(
8077 field_pos->getAccess(), nested_indirect_field_decl->getAccess()));
8078
8079 indirect_fields.push_back(indirect_field);
Greg Claytond8d4a572015-08-11 21:38:15 +00008080 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008081 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008082 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008083 }
8084
Adrian Prantl05097242018-04-30 16:49:04 +00008085 // Check the last field to see if it has an incomplete array type as its last
8086 // member and if it does, the tell the record decl about it
Kate Stoneb9c1b512016-09-06 20:57:50 +00008087 if (last_field_pos != field_end_pos) {
8088 if (last_field_pos->getType()->isIncompleteArrayType())
8089 record_decl->hasFlexibleArrayMember();
8090 }
8091
8092 for (IndirectFieldVector::iterator ifi = indirect_fields.begin(),
8093 ife = indirect_fields.end();
8094 ifi < ife; ++ifi) {
8095 record_decl->addDecl(*ifi);
8096 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008097}
8098
Kate Stoneb9c1b512016-09-06 20:57:50 +00008099void ClangASTContext::SetIsPacked(const CompilerType &type) {
8100 if (type) {
8101 ClangASTContext *ast =
8102 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8103 if (ast) {
8104 clang::RecordDecl *record_decl = GetAsRecordDecl(type);
8105
8106 if (!record_decl)
Greg Claytonf73034f2015-09-08 18:15:05 +00008107 return;
8108
Kate Stoneb9c1b512016-09-06 20:57:50 +00008109 record_decl->addAttr(
8110 clang::PackedAttr::CreateImplicit(*ast->getASTContext()));
Greg Claytond8d4a572015-08-11 21:38:15 +00008111 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008112 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008113}
8114
Kate Stoneb9c1b512016-09-06 20:57:50 +00008115clang::VarDecl *ClangASTContext::AddVariableToRecordType(
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008116 const CompilerType &type, llvm::StringRef name,
8117 const CompilerType &var_type, AccessType access) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00008118 if (!type.IsValid() || !var_type.IsValid())
8119 return nullptr;
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008120
Kate Stoneb9c1b512016-09-06 20:57:50 +00008121 ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8122 if (!ast)
8123 return nullptr;
8124
8125 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008126 if (!record_decl)
8127 return nullptr;
8128
8129 clang::VarDecl *var_decl = nullptr;
8130 clang::IdentifierInfo *ident = nullptr;
8131 if (!name.empty())
8132 ident = &ast->getASTContext()->Idents.get(name);
8133
8134 var_decl = clang::VarDecl::Create(
8135 *ast->getASTContext(), // ASTContext &
8136 record_decl, // DeclContext *
8137 clang::SourceLocation(), // clang::SourceLocation StartLoc
8138 clang::SourceLocation(), // clang::SourceLocation IdLoc
8139 ident, // clang::IdentifierInfo *
8140 ClangUtil::GetQualType(var_type), // Variable clang::QualType
8141 nullptr, // TypeSourceInfo *
8142 clang::SC_Static); // StorageClass
8143 if (!var_decl)
8144 return nullptr;
8145
8146 var_decl->setAccess(
8147 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access));
8148 record_decl->addDecl(var_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008149
Greg Claytond8d4a572015-08-11 21:38:15 +00008150#ifdef LLDB_CONFIGURATION_DEBUG
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008151 VerifyDecl(var_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008152#endif
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008153
Kate Stoneb9c1b512016-09-06 20:57:50 +00008154 return var_decl;
Greg Claytond8d4a572015-08-11 21:38:15 +00008155}
8156
Kate Stoneb9c1b512016-09-06 20:57:50 +00008157clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
Davide Italiano675767a2018-03-27 19:40:50 +00008158 lldb::opaque_compiler_type_t type, const char *name, const char *mangled_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00008159 const CompilerType &method_clang_type, lldb::AccessType access,
8160 bool is_virtual, bool is_static, bool is_inline, bool is_explicit,
8161 bool is_attr_used, bool is_artificial) {
8162 if (!type || !method_clang_type.IsValid() || name == nullptr ||
8163 name[0] == '\0')
8164 return nullptr;
Greg Claytond8d4a572015-08-11 21:38:15 +00008165
Kate Stoneb9c1b512016-09-06 20:57:50 +00008166 clang::QualType record_qual_type(GetCanonicalQualType(type));
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008167
Kate Stoneb9c1b512016-09-06 20:57:50 +00008168 clang::CXXRecordDecl *cxx_record_decl =
8169 record_qual_type->getAsCXXRecordDecl();
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008170
Kate Stoneb9c1b512016-09-06 20:57:50 +00008171 if (cxx_record_decl == nullptr)
8172 return nullptr;
8173
8174 clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
8175
8176 clang::CXXMethodDecl *cxx_method_decl = nullptr;
8177
8178 clang::DeclarationName decl_name(&getASTContext()->Idents.get(name));
8179
8180 const clang::FunctionType *function_type =
8181 llvm::dyn_cast<clang::FunctionType>(method_qual_type.getTypePtr());
8182
8183 if (function_type == nullptr)
8184 return nullptr;
8185
8186 const clang::FunctionProtoType *method_function_prototype(
8187 llvm::dyn_cast<clang::FunctionProtoType>(function_type));
8188
8189 if (!method_function_prototype)
8190 return nullptr;
8191
8192 unsigned int num_params = method_function_prototype->getNumParams();
8193
8194 clang::CXXDestructorDecl *cxx_dtor_decl(nullptr);
8195 clang::CXXConstructorDecl *cxx_ctor_decl(nullptr);
8196
8197 if (is_artificial)
8198 return nullptr; // skip everything artificial
8199
Richard Smith36851a62019-05-09 04:40:57 +00008200 const clang::ExplicitSpecifier explicit_spec(
8201 nullptr /*expr*/, is_explicit
8202 ? clang::ExplicitSpecKind::ResolvedTrue
8203 : clang::ExplicitSpecKind::ResolvedFalse);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008204 if (name[0] == '~') {
8205 cxx_dtor_decl = clang::CXXDestructorDecl::Create(
8206 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8207 clang::DeclarationNameInfo(
8208 getASTContext()->DeclarationNames.getCXXDestructorName(
8209 getASTContext()->getCanonicalType(record_qual_type)),
8210 clang::SourceLocation()),
Raphael Isemann15695cd2019-09-23 06:59:35 +00008211 method_qual_type, nullptr, is_inline, is_artificial,
8212 ConstexprSpecKind::CSK_unspecified);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008213 cxx_method_decl = cxx_dtor_decl;
8214 } else if (decl_name == cxx_record_decl->getDeclName()) {
8215 cxx_ctor_decl = clang::CXXConstructorDecl::Create(
8216 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8217 clang::DeclarationNameInfo(
8218 getASTContext()->DeclarationNames.getCXXConstructorName(
8219 getASTContext()->getCanonicalType(record_qual_type)),
8220 clang::SourceLocation()),
8221 method_qual_type,
8222 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008223 explicit_spec, is_inline, is_artificial, CSK_unspecified);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008224 cxx_method_decl = cxx_ctor_decl;
8225 } else {
8226 clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
8227 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
8228
8229 if (IsOperator(name, op_kind)) {
8230 if (op_kind != clang::NUM_OVERLOADED_OPERATORS) {
Adrian Prantl05097242018-04-30 16:49:04 +00008231 // Check the number of operator parameters. Sometimes we have seen bad
8232 // DWARF that doesn't correctly describe operators and if we try to
8233 // create a method and add it to the class, clang will assert and
8234 // crash, so we need to make sure things are acceptable.
Kate Stoneb9c1b512016-09-06 20:57:50 +00008235 const bool is_method = true;
8236 if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
8237 is_method, op_kind, num_params))
8238 return nullptr;
8239 cxx_method_decl = clang::CXXMethodDecl::Create(
8240 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8241 clang::DeclarationNameInfo(
8242 getASTContext()->DeclarationNames.getCXXOperatorName(op_kind),
8243 clang::SourceLocation()),
8244 method_qual_type,
8245 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008246 SC, is_inline, CSK_unspecified, clang::SourceLocation());
Kate Stoneb9c1b512016-09-06 20:57:50 +00008247 } else if (num_params == 0) {
8248 // Conversion operators don't take params...
8249 cxx_method_decl = clang::CXXConversionDecl::Create(
8250 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8251 clang::DeclarationNameInfo(
8252 getASTContext()->DeclarationNames.getCXXConversionFunctionName(
8253 getASTContext()->getCanonicalType(
8254 function_type->getReturnType())),
8255 clang::SourceLocation()),
8256 method_qual_type,
8257 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008258 is_inline, explicit_spec, CSK_unspecified,
Kate Stoneb9c1b512016-09-06 20:57:50 +00008259 clang::SourceLocation());
8260 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008261 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008262
8263 if (cxx_method_decl == nullptr) {
8264 cxx_method_decl = clang::CXXMethodDecl::Create(
8265 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8266 clang::DeclarationNameInfo(decl_name, clang::SourceLocation()),
8267 method_qual_type,
8268 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008269 SC, is_inline, CSK_unspecified, clang::SourceLocation());
Greg Claytond8d4a572015-08-11 21:38:15 +00008270 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008271 }
8272
8273 clang::AccessSpecifier access_specifier =
8274 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access);
8275
8276 cxx_method_decl->setAccess(access_specifier);
8277 cxx_method_decl->setVirtualAsWritten(is_virtual);
8278
8279 if (is_attr_used)
8280 cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*getASTContext()));
8281
Konrad Kleine248a1302019-05-23 11:14:47 +00008282 if (mangled_name != nullptr) {
Vedant Kumarf6bc2512019-09-25 18:00:31 +00008283 cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
8284 *getASTContext(), mangled_name, /*literal=*/false));
Davide Italiano675767a2018-03-27 19:40:50 +00008285 }
8286
Kate Stoneb9c1b512016-09-06 20:57:50 +00008287 // Populate the method decl with parameter decls
8288
8289 llvm::SmallVector<clang::ParmVarDecl *, 12> params;
8290
8291 for (unsigned param_index = 0; param_index < num_params; ++param_index) {
8292 params.push_back(clang::ParmVarDecl::Create(
8293 *getASTContext(), cxx_method_decl, clang::SourceLocation(),
8294 clang::SourceLocation(),
8295 nullptr, // anonymous
8296 method_function_prototype->getParamType(param_index), nullptr,
8297 clang::SC_None, nullptr));
8298 }
8299
8300 cxx_method_decl->setParams(llvm::ArrayRef<clang::ParmVarDecl *>(params));
8301
8302 cxx_record_decl->addDecl(cxx_method_decl);
8303
8304 // Sometimes the debug info will mention a constructor (default/copy/move),
8305 // destructor, or assignment operator (copy/move) but there won't be any
8306 // version of this in the code. So we check if the function was artificially
8307 // generated and if it is trivial and this lets the compiler/backend know
8308 // that it can inline the IR for these when it needs to and we can avoid a
8309 // "missing function" error when running expressions.
8310
8311 if (is_artificial) {
8312 if (cxx_ctor_decl && ((cxx_ctor_decl->isDefaultConstructor() &&
8313 cxx_record_decl->hasTrivialDefaultConstructor()) ||
8314 (cxx_ctor_decl->isCopyConstructor() &&
8315 cxx_record_decl->hasTrivialCopyConstructor()) ||
8316 (cxx_ctor_decl->isMoveConstructor() &&
8317 cxx_record_decl->hasTrivialMoveConstructor()))) {
8318 cxx_ctor_decl->setDefaulted();
8319 cxx_ctor_decl->setTrivial(true);
8320 } else if (cxx_dtor_decl) {
8321 if (cxx_record_decl->hasTrivialDestructor()) {
8322 cxx_dtor_decl->setDefaulted();
8323 cxx_dtor_decl->setTrivial(true);
8324 }
8325 } else if ((cxx_method_decl->isCopyAssignmentOperator() &&
8326 cxx_record_decl->hasTrivialCopyAssignment()) ||
8327 (cxx_method_decl->isMoveAssignmentOperator() &&
8328 cxx_record_decl->hasTrivialMoveAssignment())) {
8329 cxx_method_decl->setDefaulted();
8330 cxx_method_decl->setTrivial(true);
Greg Claytond8d4a572015-08-11 21:38:15 +00008331 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008332 }
8333
Greg Claytond8d4a572015-08-11 21:38:15 +00008334#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00008335 VerifyDecl(cxx_method_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008336#endif
Greg Claytond8d4a572015-08-11 21:38:15 +00008337
Kate Stoneb9c1b512016-09-06 20:57:50 +00008338 return cxx_method_decl;
8339}
Greg Claytond8d4a572015-08-11 21:38:15 +00008340
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00008341void ClangASTContext::AddMethodOverridesForCXXRecordType(
8342 lldb::opaque_compiler_type_t type) {
8343 if (auto *record = GetAsCXXRecordDecl(type))
8344 for (auto *method : record->methods())
8345 addOverridesForMethod(method);
8346}
8347
Greg Claytond8d4a572015-08-11 21:38:15 +00008348#pragma mark C++ Base Classes
8349
Zachary Turner970f38e2018-10-25 20:44:56 +00008350std::unique_ptr<clang::CXXBaseSpecifier>
Kate Stoneb9c1b512016-09-06 20:57:50 +00008351ClangASTContext::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
8352 AccessType access, bool is_virtual,
8353 bool base_of_class) {
Zachary Turner970f38e2018-10-25 20:44:56 +00008354 if (!type)
8355 return nullptr;
8356
Jonas Devliegherea8f3ae72019-08-14 22:19:23 +00008357 return std::make_unique<clang::CXXBaseSpecifier>(
Zachary Turner970f38e2018-10-25 20:44:56 +00008358 clang::SourceRange(), is_virtual, base_of_class,
8359 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access),
8360 getASTContext()->getTrivialTypeSourceInfo(GetQualType(type)),
8361 clang::SourceLocation());
Kate Stoneb9c1b512016-09-06 20:57:50 +00008362}
8363
Zachary Turner970f38e2018-10-25 20:44:56 +00008364bool ClangASTContext::TransferBaseClasses(
Kate Stoneb9c1b512016-09-06 20:57:50 +00008365 lldb::opaque_compiler_type_t type,
Zachary Turner970f38e2018-10-25 20:44:56 +00008366 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases) {
8367 if (!type)
8368 return false;
8369 clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type);
8370 if (!cxx_record_decl)
8371 return false;
8372 std::vector<clang::CXXBaseSpecifier *> raw_bases;
8373 raw_bases.reserve(bases.size());
8374
8375 // Clang will make a copy of them, so it's ok that we pass pointers that we're
8376 // about to destroy.
8377 for (auto &b : bases)
8378 raw_bases.push_back(b.get());
8379 cxx_record_decl->setBases(raw_bases.data(), raw_bases.size());
8380 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00008381}
8382
8383bool ClangASTContext::SetObjCSuperClass(
8384 const CompilerType &type, const CompilerType &superclass_clang_type) {
8385 ClangASTContext *ast =
8386 llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
8387 if (!ast)
8388 return false;
8389 clang::ASTContext *clang_ast = ast->getASTContext();
8390
8391 if (type && superclass_clang_type.IsValid() &&
8392 superclass_clang_type.GetTypeSystem() == type.GetTypeSystem()) {
8393 clang::ObjCInterfaceDecl *class_interface_decl =
8394 GetAsObjCInterfaceDecl(type);
8395 clang::ObjCInterfaceDecl *super_interface_decl =
8396 GetAsObjCInterfaceDecl(superclass_clang_type);
8397 if (class_interface_decl && super_interface_decl) {
8398 class_interface_decl->setSuperClass(clang_ast->getTrivialTypeSourceInfo(
8399 clang_ast->getObjCInterfaceType(super_interface_decl)));
8400 return true;
8401 }
8402 }
8403 return false;
8404}
8405
8406bool ClangASTContext::AddObjCClassProperty(
8407 const CompilerType &type, const char *property_name,
8408 const CompilerType &property_clang_type, clang::ObjCIvarDecl *ivar_decl,
8409 const char *property_setter_name, const char *property_getter_name,
8410 uint32_t property_attributes, ClangASTMetadata *metadata) {
8411 if (!type || !property_clang_type.IsValid() || property_name == nullptr ||
8412 property_name[0] == '\0')
8413 return false;
8414 ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8415 if (!ast)
8416 return false;
8417 clang::ASTContext *clang_ast = ast->getASTContext();
8418
8419 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8420
8421 if (class_interface_decl) {
8422 CompilerType property_clang_type_to_access;
8423
8424 if (property_clang_type.IsValid())
8425 property_clang_type_to_access = property_clang_type;
8426 else if (ivar_decl)
8427 property_clang_type_to_access =
Alex Langfordbddab072019-08-13 19:40:36 +00008428 CompilerType(ast, ivar_decl->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00008429
8430 if (class_interface_decl && property_clang_type_to_access.IsValid()) {
8431 clang::TypeSourceInfo *prop_type_source;
8432 if (ivar_decl)
8433 prop_type_source =
8434 clang_ast->getTrivialTypeSourceInfo(ivar_decl->getType());
8435 else
8436 prop_type_source = clang_ast->getTrivialTypeSourceInfo(
8437 ClangUtil::GetQualType(property_clang_type));
8438
8439 clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create(
8440 *clang_ast, class_interface_decl,
8441 clang::SourceLocation(), // Source Location
8442 &clang_ast->Idents.get(property_name),
8443 clang::SourceLocation(), // Source Location for AT
8444 clang::SourceLocation(), // Source location for (
8445 ivar_decl ? ivar_decl->getType()
8446 : ClangUtil::GetQualType(property_clang_type),
8447 prop_type_source);
8448
8449 if (property_decl) {
8450 if (metadata)
8451 ClangASTContext::SetMetadata(clang_ast, property_decl, *metadata);
8452
8453 class_interface_decl->addDecl(property_decl);
8454
8455 clang::Selector setter_sel, getter_sel;
8456
8457 if (property_setter_name != nullptr) {
8458 std::string property_setter_no_colon(
8459 property_setter_name, strlen(property_setter_name) - 1);
8460 clang::IdentifierInfo *setter_ident =
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00008461 &clang_ast->Idents.get(property_setter_no_colon);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008462 setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
8463 } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) {
8464 std::string setter_sel_string("set");
8465 setter_sel_string.push_back(::toupper(property_name[0]));
8466 setter_sel_string.append(&property_name[1]);
8467 clang::IdentifierInfo *setter_ident =
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00008468 &clang_ast->Idents.get(setter_sel_string);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008469 setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
8470 }
8471 property_decl->setSetterName(setter_sel);
8472 property_decl->setPropertyAttributes(
8473 clang::ObjCPropertyDecl::OBJC_PR_setter);
8474
8475 if (property_getter_name != nullptr) {
8476 clang::IdentifierInfo *getter_ident =
8477 &clang_ast->Idents.get(property_getter_name);
8478 getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
8479 } else {
8480 clang::IdentifierInfo *getter_ident =
8481 &clang_ast->Idents.get(property_name);
8482 getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
8483 }
8484 property_decl->setGetterName(getter_sel);
8485 property_decl->setPropertyAttributes(
8486 clang::ObjCPropertyDecl::OBJC_PR_getter);
8487
8488 if (ivar_decl)
8489 property_decl->setPropertyIvarDecl(ivar_decl);
8490
8491 if (property_attributes & DW_APPLE_PROPERTY_readonly)
8492 property_decl->setPropertyAttributes(
8493 clang::ObjCPropertyDecl::OBJC_PR_readonly);
8494 if (property_attributes & DW_APPLE_PROPERTY_readwrite)
8495 property_decl->setPropertyAttributes(
8496 clang::ObjCPropertyDecl::OBJC_PR_readwrite);
8497 if (property_attributes & DW_APPLE_PROPERTY_assign)
8498 property_decl->setPropertyAttributes(
8499 clang::ObjCPropertyDecl::OBJC_PR_assign);
8500 if (property_attributes & DW_APPLE_PROPERTY_retain)
8501 property_decl->setPropertyAttributes(
8502 clang::ObjCPropertyDecl::OBJC_PR_retain);
8503 if (property_attributes & DW_APPLE_PROPERTY_copy)
8504 property_decl->setPropertyAttributes(
8505 clang::ObjCPropertyDecl::OBJC_PR_copy);
8506 if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
8507 property_decl->setPropertyAttributes(
8508 clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
8509 if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_nullability)
8510 property_decl->setPropertyAttributes(
8511 clang::ObjCPropertyDecl::OBJC_PR_nullability);
8512 if (property_attributes &
8513 clang::ObjCPropertyDecl::OBJC_PR_null_resettable)
8514 property_decl->setPropertyAttributes(
8515 clang::ObjCPropertyDecl::OBJC_PR_null_resettable);
8516 if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class)
8517 property_decl->setPropertyAttributes(
8518 clang::ObjCPropertyDecl::OBJC_PR_class);
8519
8520 const bool isInstance =
8521 (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) == 0;
8522
8523 if (!getter_sel.isNull() &&
8524 !(isInstance
8525 ? class_interface_decl->lookupInstanceMethod(getter_sel)
8526 : class_interface_decl->lookupClassMethod(getter_sel))) {
8527 const bool isVariadic = false;
8528 const bool isSynthesized = false;
8529 const bool isImplicitlyDeclared = true;
8530 const bool isDefined = false;
8531 const clang::ObjCMethodDecl::ImplementationControl impControl =
8532 clang::ObjCMethodDecl::None;
8533 const bool HasRelatedResultType = false;
8534
8535 clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create(
8536 *clang_ast, clang::SourceLocation(), clang::SourceLocation(),
8537 getter_sel, ClangUtil::GetQualType(property_clang_type_to_access),
8538 nullptr, class_interface_decl, isInstance, isVariadic,
8539 isSynthesized, isImplicitlyDeclared, isDefined, impControl,
8540 HasRelatedResultType);
8541
8542 if (getter && metadata)
8543 ClangASTContext::SetMetadata(clang_ast, getter, *metadata);
8544
8545 if (getter) {
8546 getter->setMethodParams(*clang_ast,
8547 llvm::ArrayRef<clang::ParmVarDecl *>(),
8548 llvm::ArrayRef<clang::SourceLocation>());
8549
8550 class_interface_decl->addDecl(getter);
8551 }
8552 }
8553
8554 if (!setter_sel.isNull() &&
8555 !(isInstance
8556 ? class_interface_decl->lookupInstanceMethod(setter_sel)
8557 : class_interface_decl->lookupClassMethod(setter_sel))) {
8558 clang::QualType result_type = clang_ast->VoidTy;
8559 const bool isVariadic = false;
8560 const bool isSynthesized = false;
8561 const bool isImplicitlyDeclared = true;
8562 const bool isDefined = false;
8563 const clang::ObjCMethodDecl::ImplementationControl impControl =
8564 clang::ObjCMethodDecl::None;
8565 const bool HasRelatedResultType = false;
8566
8567 clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create(
8568 *clang_ast, clang::SourceLocation(), clang::SourceLocation(),
8569 setter_sel, result_type, nullptr, class_interface_decl,
8570 isInstance, isVariadic, isSynthesized, isImplicitlyDeclared,
8571 isDefined, impControl, HasRelatedResultType);
8572
8573 if (setter && metadata)
8574 ClangASTContext::SetMetadata(clang_ast, setter, *metadata);
8575
8576 llvm::SmallVector<clang::ParmVarDecl *, 1> params;
8577
8578 params.push_back(clang::ParmVarDecl::Create(
8579 *clang_ast, setter, clang::SourceLocation(),
8580 clang::SourceLocation(),
8581 nullptr, // anonymous
8582 ClangUtil::GetQualType(property_clang_type_to_access), nullptr,
8583 clang::SC_Auto, nullptr));
8584
8585 if (setter) {
8586 setter->setMethodParams(
8587 *clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(params),
8588 llvm::ArrayRef<clang::SourceLocation>());
8589
8590 class_interface_decl->addDecl(setter);
8591 }
8592 }
8593
8594 return true;
8595 }
8596 }
8597 }
8598 return false;
8599}
8600
8601bool ClangASTContext::IsObjCClassTypeAndHasIVars(const CompilerType &type,
8602 bool check_superclass) {
8603 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8604 if (class_interface_decl)
8605 return ObjCDeclHasIVars(class_interface_decl, check_superclass);
8606 return false;
8607}
8608
8609clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType(
8610 const CompilerType &type,
8611 const char *name, // the full symbol name as seen in the symbol table
8612 // (lldb::opaque_compiler_type_t type, "-[NString
8613 // stringWithCString:]")
8614 const CompilerType &method_clang_type, lldb::AccessType access,
8615 bool is_artificial, bool is_variadic) {
8616 if (!type || !method_clang_type.IsValid())
Greg Claytond8d4a572015-08-11 21:38:15 +00008617 return nullptr;
Greg Claytond8d4a572015-08-11 21:38:15 +00008618
Kate Stoneb9c1b512016-09-06 20:57:50 +00008619 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8620
8621 if (class_interface_decl == nullptr)
8622 return nullptr;
8623 ClangASTContext *lldb_ast =
8624 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8625 if (lldb_ast == nullptr)
8626 return nullptr;
8627 clang::ASTContext *ast = lldb_ast->getASTContext();
8628
8629 const char *selector_start = ::strchr(name, ' ');
8630 if (selector_start == nullptr)
8631 return nullptr;
8632
8633 selector_start++;
8634 llvm::SmallVector<clang::IdentifierInfo *, 12> selector_idents;
8635
8636 size_t len = 0;
8637 const char *start;
8638 // printf ("name = '%s'\n", name);
8639
8640 unsigned num_selectors_with_args = 0;
8641 for (start = selector_start; start && *start != '\0' && *start != ']';
8642 start += len) {
8643 len = ::strcspn(start, ":]");
8644 bool has_arg = (start[len] == ':');
8645 if (has_arg)
8646 ++num_selectors_with_args;
8647 selector_idents.push_back(&ast->Idents.get(llvm::StringRef(start, len)));
8648 if (has_arg)
8649 len += 1;
8650 }
8651
8652 if (selector_idents.size() == 0)
8653 return nullptr;
8654
8655 clang::Selector method_selector = ast->Selectors.getSelector(
8656 num_selectors_with_args ? selector_idents.size() : 0,
8657 selector_idents.data());
8658
8659 clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
8660
8661 // Populate the method decl with parameter decls
8662 const clang::Type *method_type(method_qual_type.getTypePtr());
8663
8664 if (method_type == nullptr)
8665 return nullptr;
8666
8667 const clang::FunctionProtoType *method_function_prototype(
8668 llvm::dyn_cast<clang::FunctionProtoType>(method_type));
8669
8670 if (!method_function_prototype)
8671 return nullptr;
8672
8673 bool is_synthesized = false;
8674 bool is_defined = false;
8675 clang::ObjCMethodDecl::ImplementationControl imp_control =
8676 clang::ObjCMethodDecl::None;
8677
8678 const unsigned num_args = method_function_prototype->getNumParams();
8679
8680 if (num_args != num_selectors_with_args)
8681 return nullptr; // some debug information is corrupt. We are not going to
8682 // deal with it.
8683
8684 clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create(
8685 *ast,
8686 clang::SourceLocation(), // beginLoc,
8687 clang::SourceLocation(), // endLoc,
8688 method_selector, method_function_prototype->getReturnType(),
8689 nullptr, // TypeSourceInfo *ResultTInfo,
8690 ClangASTContext::GetASTContext(ast)->GetDeclContextForType(
8691 ClangUtil::GetQualType(type)),
8692 name[0] == '-', is_variadic, is_synthesized,
8693 true, // is_implicitly_declared; we force this to true because we don't
8694 // have source locations
8695 is_defined, imp_control, false /*has_related_result_type*/);
8696
8697 if (objc_method_decl == nullptr)
8698 return nullptr;
8699
8700 if (num_args > 0) {
8701 llvm::SmallVector<clang::ParmVarDecl *, 12> params;
8702
8703 for (unsigned param_index = 0; param_index < num_args; ++param_index) {
8704 params.push_back(clang::ParmVarDecl::Create(
8705 *ast, objc_method_decl, clang::SourceLocation(),
8706 clang::SourceLocation(),
8707 nullptr, // anonymous
8708 method_function_prototype->getParamType(param_index), nullptr,
8709 clang::SC_Auto, nullptr));
Greg Claytond8d4a572015-08-11 21:38:15 +00008710 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008711
Kate Stoneb9c1b512016-09-06 20:57:50 +00008712 objc_method_decl->setMethodParams(
8713 *ast, llvm::ArrayRef<clang::ParmVarDecl *>(params),
8714 llvm::ArrayRef<clang::SourceLocation>());
8715 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008716
Kate Stoneb9c1b512016-09-06 20:57:50 +00008717 class_interface_decl->addDecl(objc_method_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008718
Greg Claytond8d4a572015-08-11 21:38:15 +00008719#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00008720 VerifyDecl(objc_method_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008721#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00008722
8723 return objc_method_decl;
Greg Claytond8d4a572015-08-11 21:38:15 +00008724}
8725
Kate Stoneb9c1b512016-09-06 20:57:50 +00008726bool ClangASTContext::SetHasExternalStorage(lldb::opaque_compiler_type_t type,
8727 bool has_extern) {
8728 if (!type)
8729 return false;
8730
8731 clang::QualType qual_type(GetCanonicalQualType(type));
8732
8733 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8734 switch (type_class) {
8735 case clang::Type::Record: {
8736 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
8737 if (cxx_record_decl) {
8738 cxx_record_decl->setHasExternalLexicalStorage(has_extern);
8739 cxx_record_decl->setHasExternalVisibleStorage(has_extern);
8740 return true;
8741 }
8742 } break;
8743
8744 case clang::Type::Enum: {
8745 clang::EnumDecl *enum_decl =
8746 llvm::cast<clang::EnumType>(qual_type)->getDecl();
8747 if (enum_decl) {
8748 enum_decl->setHasExternalLexicalStorage(has_extern);
8749 enum_decl->setHasExternalVisibleStorage(has_extern);
8750 return true;
8751 }
8752 } break;
8753
8754 case clang::Type::ObjCObject:
8755 case clang::Type::ObjCInterface: {
8756 const clang::ObjCObjectType *objc_class_type =
8757 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
8758 assert(objc_class_type);
8759 if (objc_class_type) {
8760 clang::ObjCInterfaceDecl *class_interface_decl =
8761 objc_class_type->getInterface();
8762
8763 if (class_interface_decl) {
8764 class_interface_decl->setHasExternalLexicalStorage(has_extern);
8765 class_interface_decl->setHasExternalVisibleStorage(has_extern);
8766 return true;
8767 }
8768 }
8769 } break;
8770
8771 case clang::Type::Typedef:
8772 return SetHasExternalStorage(llvm::cast<clang::TypedefType>(qual_type)
8773 ->getDecl()
8774 ->getUnderlyingType()
8775 .getAsOpaquePtr(),
8776 has_extern);
8777
8778 case clang::Type::Auto:
8779 return SetHasExternalStorage(llvm::cast<clang::AutoType>(qual_type)
8780 ->getDeducedType()
8781 .getAsOpaquePtr(),
8782 has_extern);
8783
8784 case clang::Type::Elaborated:
8785 return SetHasExternalStorage(llvm::cast<clang::ElaboratedType>(qual_type)
8786 ->getNamedType()
8787 .getAsOpaquePtr(),
8788 has_extern);
8789
8790 case clang::Type::Paren:
8791 return SetHasExternalStorage(
8792 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
8793 has_extern);
8794
8795 default:
8796 break;
8797 }
8798 return false;
8799}
Greg Claytond8d4a572015-08-11 21:38:15 +00008800
8801#pragma mark TagDecl
8802
Kate Stoneb9c1b512016-09-06 20:57:50 +00008803bool ClangASTContext::StartTagDeclarationDefinition(const CompilerType &type) {
8804 clang::QualType qual_type(ClangUtil::GetQualType(type));
8805 if (!qual_type.isNull()) {
8806 const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
8807 if (tag_type) {
8808 clang::TagDecl *tag_decl = tag_type->getDecl();
8809 if (tag_decl) {
8810 tag_decl->startDefinition();
8811 return true;
8812 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008813 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008814
8815 const clang::ObjCObjectType *object_type =
8816 qual_type->getAs<clang::ObjCObjectType>();
8817 if (object_type) {
8818 clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
8819 if (interface_decl) {
8820 interface_decl->startDefinition();
8821 return true;
8822 }
8823 }
8824 }
8825 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00008826}
8827
Kate Stoneb9c1b512016-09-06 20:57:50 +00008828bool ClangASTContext::CompleteTagDeclarationDefinition(
8829 const CompilerType &type) {
8830 clang::QualType qual_type(ClangUtil::GetQualType(type));
8831 if (!qual_type.isNull()) {
8832 // Make sure we use the same methodology as
Adrian Prantl05097242018-04-30 16:49:04 +00008833 // ClangASTContext::StartTagDeclarationDefinition() as to how we start/end
8834 // the definition. Previously we were calling
Kate Stoneb9c1b512016-09-06 20:57:50 +00008835 const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
8836 if (tag_type) {
8837 clang::TagDecl *tag_decl = tag_type->getDecl();
8838 if (tag_decl) {
8839 clang::CXXRecordDecl *cxx_record_decl =
8840 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(tag_decl);
8841
8842 if (cxx_record_decl) {
8843 if (!cxx_record_decl->isCompleteDefinition())
8844 cxx_record_decl->completeDefinition();
8845 cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
8846 cxx_record_decl->setHasExternalLexicalStorage(false);
8847 cxx_record_decl->setHasExternalVisibleStorage(false);
8848 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00008849 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008850 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008851 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008852
8853 const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>();
8854
8855 if (enutype) {
8856 clang::EnumDecl *enum_decl = enutype->getDecl();
8857
8858 if (enum_decl) {
8859 if (!enum_decl->isCompleteDefinition()) {
8860 ClangASTContext *lldb_ast =
8861 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8862 if (lldb_ast == nullptr)
8863 return false;
8864 clang::ASTContext *ast = lldb_ast->getASTContext();
8865
8866 /// TODO This really needs to be fixed.
8867
8868 QualType integer_type(enum_decl->getIntegerType());
8869 if (!integer_type.isNull()) {
8870 unsigned NumPositiveBits = 1;
8871 unsigned NumNegativeBits = 0;
8872
8873 clang::QualType promotion_qual_type;
8874 // If the enum integer type is less than an integer in bit width,
8875 // then we must promote it to an integer size.
8876 if (ast->getTypeSize(enum_decl->getIntegerType()) <
8877 ast->getTypeSize(ast->IntTy)) {
8878 if (enum_decl->getIntegerType()->isSignedIntegerType())
8879 promotion_qual_type = ast->IntTy;
8880 else
8881 promotion_qual_type = ast->UnsignedIntTy;
8882 } else
8883 promotion_qual_type = enum_decl->getIntegerType();
8884
8885 enum_decl->completeDefinition(enum_decl->getIntegerType(),
8886 promotion_qual_type, NumPositiveBits,
8887 NumNegativeBits);
8888 }
8889 }
8890 return true;
8891 }
8892 }
8893 }
8894 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00008895}
8896
Aleksandr Urakov709426b2018-09-10 08:08:43 +00008897clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType(
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008898 const CompilerType &enum_type, const Declaration &decl, const char *name,
Zachary Turner1639c6b2018-12-17 16:15:13 +00008899 const llvm::APSInt &value) {
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008900
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008901 if (!enum_type || ConstString(name).IsEmpty())
8902 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00008903
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008904 lldbassert(enum_type.GetTypeSystem() == static_cast<TypeSystem *>(this));
Kate Stoneb9c1b512016-09-06 20:57:50 +00008905
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008906 lldb::opaque_compiler_type_t enum_opaque_compiler_type =
8907 enum_type.GetOpaqueQualType();
8908
8909 if (!enum_opaque_compiler_type)
8910 return nullptr;
8911
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008912 clang::QualType enum_qual_type(
8913 GetCanonicalQualType(enum_opaque_compiler_type));
8914
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008915 const clang::Type *clang_type = enum_qual_type.getTypePtr();
8916
8917 if (!clang_type)
8918 return nullptr;
8919
8920 const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(clang_type);
8921
8922 if (!enutype)
8923 return nullptr;
8924
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008925 clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create(
8926 *getASTContext(), enutype->getDecl(), clang::SourceLocation(),
8927 name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier
Zachary Turner1639c6b2018-12-17 16:15:13 +00008928 clang::QualType(enutype, 0), nullptr, value);
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008929
8930 if (!enumerator_decl)
8931 return nullptr;
8932
8933 enutype->getDecl()->addDecl(enumerator_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008934
8935#ifdef LLDB_CONFIGURATION_DEBUG
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008936 VerifyDecl(enumerator_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008937#endif
8938
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008939 return enumerator_decl;
Greg Claytond8d4a572015-08-11 21:38:15 +00008940}
8941
Zachary Turner1639c6b2018-12-17 16:15:13 +00008942clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType(
8943 const CompilerType &enum_type, const Declaration &decl, const char *name,
8944 int64_t enum_value, uint32_t enum_value_bit_size) {
8945 CompilerType underlying_type =
8946 GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
8947 bool is_signed = false;
8948 underlying_type.IsIntegerType(is_signed);
8949
8950 llvm::APSInt value(enum_value_bit_size, is_signed);
8951 value = enum_value;
8952
8953 return AddEnumerationValueToEnumerationType(enum_type, decl, name, value);
8954}
8955
Greg Claytona1e5dc82015-08-11 22:53:00 +00008956CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00008957ClangASTContext::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) {
8958 clang::QualType enum_qual_type(GetCanonicalQualType(type));
8959 const clang::Type *clang_type = enum_qual_type.getTypePtr();
8960 if (clang_type) {
8961 const clang::EnumType *enutype =
8962 llvm::dyn_cast<clang::EnumType>(clang_type);
8963 if (enutype) {
8964 clang::EnumDecl *enum_decl = enutype->getDecl();
8965 if (enum_decl)
Alex Langfordbddab072019-08-13 19:40:36 +00008966 return CompilerType(this, enum_decl->getIntegerType().getAsOpaquePtr());
Greg Claytond8d4a572015-08-11 21:38:15 +00008967 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008968 }
8969 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00008970}
8971
Kate Stoneb9c1b512016-09-06 20:57:50 +00008972CompilerType
8973ClangASTContext::CreateMemberPointerType(const CompilerType &type,
8974 const CompilerType &pointee_type) {
8975 if (type && pointee_type.IsValid() &&
8976 type.GetTypeSystem() == pointee_type.GetTypeSystem()) {
8977 ClangASTContext *ast =
8978 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8979 if (!ast)
8980 return CompilerType();
Alex Langfordbddab072019-08-13 19:40:36 +00008981 return CompilerType(ast, ast->getASTContext()
8982 ->getMemberPointerType(
8983 ClangUtil::GetQualType(pointee_type),
8984 ClangUtil::GetQualType(type).getTypePtr())
8985 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00008986 }
8987 return CompilerType();
8988}
Greg Claytond8d4a572015-08-11 21:38:15 +00008989
Greg Claytond8d4a572015-08-11 21:38:15 +00008990// Dumping types
Greg Claytond8d4a572015-08-11 21:38:15 +00008991#define DEPTH_INCREMENT 2
8992
Adrian Prantl0c72a422019-03-07 20:20:02 +00008993#ifndef NDEBUG
8994LLVM_DUMP_METHOD void
8995ClangASTContext::dump(lldb::opaque_compiler_type_t type) const {
8996 if (!type)
8997 return;
8998 clang::QualType qual_type(GetQualType(type));
8999 qual_type.dump();
9000}
9001#endif
9002
Zachary Turner49110232018-11-05 17:40:28 +00009003void ClangASTContext::Dump(Stream &s) {
Zachary Turner115209e2018-11-05 19:25:39 +00009004 Decl *tu = Decl::castFromDeclContext(GetTranslationUnitDecl());
Zachary Turner49110232018-11-05 17:40:28 +00009005 tu->dump(s.AsRawOstream());
9006}
9007
Kate Stoneb9c1b512016-09-06 20:57:50 +00009008void ClangASTContext::DumpValue(
9009 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
Zachary Turner29cb8682017-03-03 20:57:05 +00009010 lldb::Format format, const DataExtractor &data,
Kate Stoneb9c1b512016-09-06 20:57:50 +00009011 lldb::offset_t data_byte_offset, size_t data_byte_size,
9012 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types,
9013 bool show_summary, bool verbose, uint32_t depth) {
9014 if (!type)
9015 return;
9016
9017 clang::QualType qual_type(GetQualType(type));
9018 switch (qual_type->getTypeClass()) {
9019 case clang::Type::Record:
9020 if (GetCompleteType(type)) {
9021 const clang::RecordType *record_type =
9022 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
9023 const clang::RecordDecl *record_decl = record_type->getDecl();
9024 assert(record_decl);
9025 uint32_t field_bit_offset = 0;
9026 uint32_t field_byte_offset = 0;
9027 const clang::ASTRecordLayout &record_layout =
9028 getASTContext()->getASTRecordLayout(record_decl);
9029 uint32_t child_idx = 0;
9030
9031 const clang::CXXRecordDecl *cxx_record_decl =
9032 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
9033 if (cxx_record_decl) {
9034 // We might have base classes to print out first
9035 clang::CXXRecordDecl::base_class_const_iterator base_class,
9036 base_class_end;
9037 for (base_class = cxx_record_decl->bases_begin(),
9038 base_class_end = cxx_record_decl->bases_end();
9039 base_class != base_class_end; ++base_class) {
9040 const clang::CXXRecordDecl *base_class_decl =
9041 llvm::cast<clang::CXXRecordDecl>(
9042 base_class->getType()->getAs<clang::RecordType>()->getDecl());
9043
9044 // Skip empty base classes
Jonas Devliegherea6682a42018-12-15 00:15:33 +00009045 if (!verbose && !ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00009046 continue;
9047
9048 if (base_class->isVirtual())
9049 field_bit_offset =
9050 record_layout.getVBaseClassOffset(base_class_decl)
9051 .getQuantity() *
9052 8;
9053 else
9054 field_bit_offset = record_layout.getBaseClassOffset(base_class_decl)
9055 .getQuantity() *
9056 8;
9057 field_byte_offset = field_bit_offset / 8;
9058 assert(field_bit_offset % 8 == 0);
9059 if (child_idx == 0)
9060 s->PutChar('{');
9061 else
9062 s->PutChar(',');
9063
9064 clang::QualType base_class_qual_type = base_class->getType();
9065 std::string base_class_type_name(base_class_qual_type.getAsString());
9066
9067 // Indent and print the base class type name
Zachary Turner827d5d72016-12-16 04:27:00 +00009068 s->Format("\n{0}{1}", llvm::fmt_repeat(" ", depth + DEPTH_INCREMENT),
9069 base_class_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009070
9071 clang::TypeInfo base_class_type_info =
9072 getASTContext()->getTypeInfo(base_class_qual_type);
9073
9074 // Dump the value of the member
Alex Langfordbddab072019-08-13 19:40:36 +00009075 CompilerType base_clang_type(this,
9076 base_class_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009077 base_clang_type.DumpValue(
9078 exe_ctx,
9079 s, // Stream to dump to
9080 base_clang_type
9081 .GetFormat(), // The format with which to display the member
9082 data, // Data buffer containing all bytes for this type
9083 data_byte_offset + field_byte_offset, // Offset into "data" where
9084 // to grab value from
9085 base_class_type_info.Width / 8, // Size of this type in bytes
9086 0, // Bitfield bit size
9087 0, // Bitfield bit offset
9088 show_types, // Boolean indicating if we should show the variable
9089 // types
9090 show_summary, // Boolean indicating if we should show a summary
9091 // for the current type
9092 verbose, // Verbose output?
9093 depth + DEPTH_INCREMENT); // Scope depth for any types that have
9094 // children
9095
9096 ++child_idx;
9097 }
9098 }
9099 uint32_t field_idx = 0;
9100 clang::RecordDecl::field_iterator field, field_end;
9101 for (field = record_decl->field_begin(),
9102 field_end = record_decl->field_end();
9103 field != field_end; ++field, ++field_idx, ++child_idx) {
Adrian Prantl05097242018-04-30 16:49:04 +00009104 // Print the starting squiggly bracket (if this is the first member) or
9105 // comma (for member 2 and beyond) for the struct/union/class member.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009106 if (child_idx == 0)
9107 s->PutChar('{');
9108 else
9109 s->PutChar(',');
9110
9111 // Indent
9112 s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
9113
9114 clang::QualType field_type = field->getType();
9115 // Print the member type if requested
Adrian Prantl05097242018-04-30 16:49:04 +00009116 // Figure out the type byte size (field_type_info.first) and alignment
9117 // (field_type_info.second) from the AST context.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009118 clang::TypeInfo field_type_info =
9119 getASTContext()->getTypeInfo(field_type);
9120 assert(field_idx < record_layout.getFieldCount());
9121 // Figure out the field offset within the current struct/union/class
9122 // type
9123 field_bit_offset = record_layout.getFieldOffset(field_idx);
9124 field_byte_offset = field_bit_offset / 8;
9125 uint32_t field_bitfield_bit_size = 0;
9126 uint32_t field_bitfield_bit_offset = 0;
9127 if (ClangASTContext::FieldIsBitfield(getASTContext(), *field,
9128 field_bitfield_bit_size))
9129 field_bitfield_bit_offset = field_bit_offset % 8;
9130
9131 if (show_types) {
9132 std::string field_type_name(field_type.getAsString());
9133 if (field_bitfield_bit_size > 0)
9134 s->Printf("(%s:%u) ", field_type_name.c_str(),
9135 field_bitfield_bit_size);
9136 else
9137 s->Printf("(%s) ", field_type_name.c_str());
9138 }
9139 // Print the member name and equal sign
9140 s->Printf("%s = ", field->getNameAsString().c_str());
9141
9142 // Dump the value of the member
Alex Langfordbddab072019-08-13 19:40:36 +00009143 CompilerType field_clang_type(this, field_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009144 field_clang_type.DumpValue(
9145 exe_ctx,
9146 s, // Stream to dump to
9147 field_clang_type
9148 .GetFormat(), // The format with which to display the member
9149 data, // Data buffer containing all bytes for this type
9150 data_byte_offset + field_byte_offset, // Offset into "data" where to
9151 // grab value from
9152 field_type_info.Width / 8, // Size of this type in bytes
9153 field_bitfield_bit_size, // Bitfield bit size
9154 field_bitfield_bit_offset, // Bitfield bit offset
9155 show_types, // Boolean indicating if we should show the variable
9156 // types
9157 show_summary, // Boolean indicating if we should show a summary for
9158 // the current type
9159 verbose, // Verbose output?
9160 depth + DEPTH_INCREMENT); // Scope depth for any types that have
9161 // children
9162 }
9163
9164 // Indent the trailing squiggly bracket
9165 if (child_idx > 0)
9166 s->Printf("\n%*s}", depth, "");
9167 }
9168 return;
9169
9170 case clang::Type::Enum:
9171 if (GetCompleteType(type)) {
9172 const clang::EnumType *enutype =
9173 llvm::cast<clang::EnumType>(qual_type.getTypePtr());
9174 const clang::EnumDecl *enum_decl = enutype->getDecl();
9175 assert(enum_decl);
9176 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
9177 lldb::offset_t offset = data_byte_offset;
9178 const int64_t enum_value = data.GetMaxU64Bitfield(
9179 &offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
9180 for (enum_pos = enum_decl->enumerator_begin(),
9181 enum_end_pos = enum_decl->enumerator_end();
9182 enum_pos != enum_end_pos; ++enum_pos) {
9183 if (enum_pos->getInitVal() == enum_value) {
9184 s->Printf("%s", enum_pos->getNameAsString().c_str());
9185 return;
9186 }
9187 }
Adrian Prantl05097242018-04-30 16:49:04 +00009188 // If we have gotten here we didn't get find the enumerator in the enum
9189 // decl, so just print the integer.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009190 s->Printf("%" PRIi64, enum_value);
9191 }
9192 return;
9193
9194 case clang::Type::ConstantArray: {
9195 const clang::ConstantArrayType *array =
9196 llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
9197 bool is_array_of_characters = false;
9198 clang::QualType element_qual_type = array->getElementType();
9199
9200 const clang::Type *canonical_type =
9201 element_qual_type->getCanonicalTypeInternal().getTypePtr();
9202 if (canonical_type)
9203 is_array_of_characters = canonical_type->isCharType();
9204
9205 const uint64_t element_count = array->getSize().getLimitedValue();
9206
9207 clang::TypeInfo field_type_info =
9208 getASTContext()->getTypeInfo(element_qual_type);
9209
9210 uint32_t element_idx = 0;
9211 uint32_t element_offset = 0;
9212 uint64_t element_byte_size = field_type_info.Width / 8;
9213 uint32_t element_stride = element_byte_size;
9214
9215 if (is_array_of_characters) {
9216 s->PutChar('"');
Zachary Turner29cb8682017-03-03 20:57:05 +00009217 DumpDataExtractor(data, s, data_byte_offset, lldb::eFormatChar,
9218 element_byte_size, element_count, UINT32_MAX,
9219 LLDB_INVALID_ADDRESS, 0, 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009220 s->PutChar('"');
9221 return;
9222 } else {
Alex Langfordbddab072019-08-13 19:40:36 +00009223 CompilerType element_clang_type(this, element_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009224 lldb::Format element_format = element_clang_type.GetFormat();
9225
9226 for (element_idx = 0; element_idx < element_count; ++element_idx) {
Adrian Prantl05097242018-04-30 16:49:04 +00009227 // Print the starting squiggly bracket (if this is the first member) or
9228 // comman (for member 2 and beyong) for the struct/union/class member.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009229 if (element_idx == 0)
9230 s->PutChar('{');
9231 else
9232 s->PutChar(',');
9233
9234 // Indent and print the index
9235 s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
9236
9237 // Figure out the field offset within the current struct/union/class
9238 // type
9239 element_offset = element_idx * element_stride;
9240
9241 // Dump the value of the member
9242 element_clang_type.DumpValue(
9243 exe_ctx,
9244 s, // Stream to dump to
9245 element_format, // The format with which to display the element
9246 data, // Data buffer containing all bytes for this type
9247 data_byte_offset +
9248 element_offset, // Offset into "data" where to grab value from
9249 element_byte_size, // Size of this type in bytes
9250 0, // Bitfield bit size
9251 0, // Bitfield bit offset
9252 show_types, // Boolean indicating if we should show the variable
9253 // types
9254 show_summary, // Boolean indicating if we should show a summary for
9255 // the current type
9256 verbose, // Verbose output?
9257 depth + DEPTH_INCREMENT); // Scope depth for any types that have
9258 // children
9259 }
9260
9261 // Indent the trailing squiggly bracket
9262 if (element_idx > 0)
9263 s->Printf("\n%*s}", depth, "");
9264 }
9265 }
9266 return;
9267
9268 case clang::Type::Typedef: {
9269 clang::QualType typedef_qual_type =
9270 llvm::cast<clang::TypedefType>(qual_type)
9271 ->getDecl()
9272 ->getUnderlyingType();
9273
Alex Langfordbddab072019-08-13 19:40:36 +00009274 CompilerType typedef_clang_type(this, typedef_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009275 lldb::Format typedef_format = typedef_clang_type.GetFormat();
9276 clang::TypeInfo typedef_type_info =
9277 getASTContext()->getTypeInfo(typedef_qual_type);
9278 uint64_t typedef_byte_size = typedef_type_info.Width / 8;
9279
9280 return typedef_clang_type.DumpValue(
9281 exe_ctx,
9282 s, // Stream to dump to
9283 typedef_format, // The format with which to display the element
9284 data, // Data buffer containing all bytes for this type
9285 data_byte_offset, // Offset into "data" where to grab value from
9286 typedef_byte_size, // Size of this type in bytes
9287 bitfield_bit_size, // Bitfield bit size
9288 bitfield_bit_offset, // Bitfield bit offset
9289 show_types, // Boolean indicating if we should show the variable types
9290 show_summary, // Boolean indicating if we should show a summary for the
9291 // current type
9292 verbose, // Verbose output?
9293 depth); // Scope depth for any types that have children
9294 } break;
9295
9296 case clang::Type::Auto: {
9297 clang::QualType elaborated_qual_type =
9298 llvm::cast<clang::AutoType>(qual_type)->getDeducedType();
Alex Langfordbddab072019-08-13 19:40:36 +00009299 CompilerType elaborated_clang_type(this,
9300 elaborated_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009301 lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
9302 clang::TypeInfo elaborated_type_info =
9303 getASTContext()->getTypeInfo(elaborated_qual_type);
9304 uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
9305
9306 return elaborated_clang_type.DumpValue(
9307 exe_ctx,
9308 s, // Stream to dump to
9309 elaborated_format, // The format with which to display the element
9310 data, // Data buffer containing all bytes for this type
9311 data_byte_offset, // Offset into "data" where to grab value from
9312 elaborated_byte_size, // Size of this type in bytes
9313 bitfield_bit_size, // Bitfield bit size
9314 bitfield_bit_offset, // Bitfield bit offset
9315 show_types, // Boolean indicating if we should show the variable types
9316 show_summary, // Boolean indicating if we should show a summary for the
9317 // current type
9318 verbose, // Verbose output?
9319 depth); // Scope depth for any types that have children
9320 } break;
9321
9322 case clang::Type::Elaborated: {
9323 clang::QualType elaborated_qual_type =
9324 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
Alex Langfordbddab072019-08-13 19:40:36 +00009325 CompilerType elaborated_clang_type(this,
9326 elaborated_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009327 lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
9328 clang::TypeInfo elaborated_type_info =
9329 getASTContext()->getTypeInfo(elaborated_qual_type);
9330 uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
9331
9332 return elaborated_clang_type.DumpValue(
9333 exe_ctx,
9334 s, // Stream to dump to
9335 elaborated_format, // The format with which to display the element
9336 data, // Data buffer containing all bytes for this type
9337 data_byte_offset, // Offset into "data" where to grab value from
9338 elaborated_byte_size, // Size of this type in bytes
9339 bitfield_bit_size, // Bitfield bit size
9340 bitfield_bit_offset, // Bitfield bit offset
9341 show_types, // Boolean indicating if we should show the variable types
9342 show_summary, // Boolean indicating if we should show a summary for the
9343 // current type
9344 verbose, // Verbose output?
9345 depth); // Scope depth for any types that have children
9346 } break;
9347
9348 case clang::Type::Paren: {
9349 clang::QualType desugar_qual_type =
9350 llvm::cast<clang::ParenType>(qual_type)->desugar();
Alex Langfordbddab072019-08-13 19:40:36 +00009351 CompilerType desugar_clang_type(this, desugar_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009352
9353 lldb::Format desugar_format = desugar_clang_type.GetFormat();
9354 clang::TypeInfo desugar_type_info =
9355 getASTContext()->getTypeInfo(desugar_qual_type);
9356 uint64_t desugar_byte_size = desugar_type_info.Width / 8;
9357
9358 return desugar_clang_type.DumpValue(
9359 exe_ctx,
9360 s, // Stream to dump to
9361 desugar_format, // The format with which to display the element
9362 data, // Data buffer containing all bytes for this type
9363 data_byte_offset, // Offset into "data" where to grab value from
9364 desugar_byte_size, // Size of this type in bytes
9365 bitfield_bit_size, // Bitfield bit size
9366 bitfield_bit_offset, // Bitfield bit offset
9367 show_types, // Boolean indicating if we should show the variable types
9368 show_summary, // Boolean indicating if we should show a summary for the
9369 // current type
9370 verbose, // Verbose output?
9371 depth); // Scope depth for any types that have children
9372 } break;
9373
9374 default:
9375 // We are down to a scalar type that we just need to display.
Zachary Turner29cb8682017-03-03 20:57:05 +00009376 DumpDataExtractor(data, s, data_byte_offset, format, data_byte_size, 1,
9377 UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
9378 bitfield_bit_offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009379
9380 if (show_summary)
9381 DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
9382 break;
9383 }
9384}
9385
9386bool ClangASTContext::DumpTypeValue(
9387 lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
Zachary Turner29cb8682017-03-03 20:57:05 +00009388 const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size,
9389 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
Kate Stoneb9c1b512016-09-06 20:57:50 +00009390 ExecutionContextScope *exe_scope) {
9391 if (!type)
9392 return false;
9393 if (IsAggregateType(type)) {
9394 return false;
9395 } else {
Greg Claytond8d4a572015-08-11 21:38:15 +00009396 clang::QualType qual_type(GetQualType(type));
Kate Stoneb9c1b512016-09-06 20:57:50 +00009397
9398 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
9399 switch (type_class) {
9400 case clang::Type::Typedef: {
9401 clang::QualType typedef_qual_type =
9402 llvm::cast<clang::TypedefType>(qual_type)
9403 ->getDecl()
9404 ->getUnderlyingType();
Alex Langfordbddab072019-08-13 19:40:36 +00009405 CompilerType typedef_clang_type(this, typedef_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009406 if (format == eFormatDefault)
9407 format = typedef_clang_type.GetFormat();
9408 clang::TypeInfo typedef_type_info =
9409 getASTContext()->getTypeInfo(typedef_qual_type);
9410 uint64_t typedef_byte_size = typedef_type_info.Width / 8;
9411
9412 return typedef_clang_type.DumpTypeValue(
9413 s,
9414 format, // The format with which to display the element
9415 data, // Data buffer containing all bytes for this type
9416 byte_offset, // Offset into "data" where to grab value from
9417 typedef_byte_size, // Size of this type in bytes
9418 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't
9419 // treat as a bitfield
9420 bitfield_bit_offset, // Offset in bits of a bitfield value if
9421 // bitfield_bit_size != 0
9422 exe_scope);
9423 } break;
9424
9425 case clang::Type::Enum:
Adrian Prantl05097242018-04-30 16:49:04 +00009426 // If our format is enum or default, show the enumeration value as its
9427 // enumeration string value, else just display it as requested.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009428 if ((format == eFormatEnum || format == eFormatDefault) &&
9429 GetCompleteType(type)) {
9430 const clang::EnumType *enutype =
9431 llvm::cast<clang::EnumType>(qual_type.getTypePtr());
9432 const clang::EnumDecl *enum_decl = enutype->getDecl();
9433 assert(enum_decl);
9434 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
9435 const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
9436 lldb::offset_t offset = byte_offset;
9437 if (is_signed) {
9438 const int64_t enum_svalue = data.GetMaxS64Bitfield(
9439 &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
9440 for (enum_pos = enum_decl->enumerator_begin(),
9441 enum_end_pos = enum_decl->enumerator_end();
9442 enum_pos != enum_end_pos; ++enum_pos) {
9443 if (enum_pos->getInitVal().getSExtValue() == enum_svalue) {
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009444 s->PutCString(enum_pos->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009445 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00009446 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009447 }
9448 // If we have gotten here we didn't get find the enumerator in the
9449 // enum decl, so just print the integer.
9450 s->Printf("%" PRIi64, enum_svalue);
9451 } else {
9452 const uint64_t enum_uvalue = data.GetMaxU64Bitfield(
9453 &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
9454 for (enum_pos = enum_decl->enumerator_begin(),
9455 enum_end_pos = enum_decl->enumerator_end();
9456 enum_pos != enum_end_pos; ++enum_pos) {
9457 if (enum_pos->getInitVal().getZExtValue() == enum_uvalue) {
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009458 s->PutCString(enum_pos->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009459 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00009460 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009461 }
9462 // If we have gotten here we didn't get find the enumerator in the
9463 // enum decl, so just print the integer.
9464 s->Printf("%" PRIu64, enum_uvalue);
Greg Claytond8d4a572015-08-11 21:38:15 +00009465 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009466 return true;
9467 }
9468 // format was not enum, just fall through and dump the value as
9469 // requested....
9470 LLVM_FALLTHROUGH;
9471
9472 default:
9473 // We are down to a scalar type that we just need to display.
9474 {
9475 uint32_t item_count = 1;
9476 // A few formats, we might need to modify our size and count for
9477 // depending
9478 // on how we are trying to display the value...
9479 switch (format) {
Greg Claytond8d4a572015-08-11 21:38:15 +00009480 default:
Kate Stoneb9c1b512016-09-06 20:57:50 +00009481 case eFormatBoolean:
9482 case eFormatBinary:
9483 case eFormatComplex:
9484 case eFormatCString: // NULL terminated C strings
9485 case eFormatDecimal:
9486 case eFormatEnum:
9487 case eFormatHex:
9488 case eFormatHexUppercase:
9489 case eFormatFloat:
9490 case eFormatOctal:
9491 case eFormatOSType:
9492 case eFormatUnsigned:
9493 case eFormatPointer:
9494 case eFormatVectorOfChar:
9495 case eFormatVectorOfSInt8:
9496 case eFormatVectorOfUInt8:
9497 case eFormatVectorOfSInt16:
9498 case eFormatVectorOfUInt16:
9499 case eFormatVectorOfSInt32:
9500 case eFormatVectorOfUInt32:
9501 case eFormatVectorOfSInt64:
9502 case eFormatVectorOfUInt64:
9503 case eFormatVectorOfFloat32:
9504 case eFormatVectorOfFloat64:
9505 case eFormatVectorOfUInt128:
9506 break;
9507
9508 case eFormatChar:
9509 case eFormatCharPrintable:
9510 case eFormatCharArray:
9511 case eFormatBytes:
9512 case eFormatBytesWithASCII:
9513 item_count = byte_size;
9514 byte_size = 1;
9515 break;
9516
9517 case eFormatUnicode16:
9518 item_count = byte_size / 2;
9519 byte_size = 2;
9520 break;
9521
9522 case eFormatUnicode32:
9523 item_count = byte_size / 4;
9524 byte_size = 4;
9525 break;
9526 }
Zachary Turner29cb8682017-03-03 20:57:05 +00009527 return DumpDataExtractor(data, s, byte_offset, format, byte_size,
9528 item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
9529 bitfield_bit_size, bitfield_bit_offset,
9530 exe_scope);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009531 }
9532 break;
9533 }
9534 }
Jonas Devlieghere09ad8c82019-05-24 00:44:33 +00009535 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00009536}
9537
9538void ClangASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
9539 ExecutionContext *exe_ctx, Stream *s,
9540 const lldb_private::DataExtractor &data,
9541 lldb::offset_t data_byte_offset,
9542 size_t data_byte_size) {
9543 uint32_t length = 0;
9544 if (IsCStringType(type, length)) {
9545 if (exe_ctx) {
9546 Process *process = exe_ctx->GetProcessPtr();
9547 if (process) {
9548 lldb::offset_t offset = data_byte_offset;
9549 lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size);
9550 std::vector<uint8_t> buf;
9551 if (length > 0)
9552 buf.resize(length);
9553 else
9554 buf.resize(256);
9555
Zachary Turner29cb8682017-03-03 20:57:05 +00009556 DataExtractor cstr_data(&buf.front(), buf.size(),
9557 process->GetByteOrder(), 4);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009558 buf.back() = '\0';
9559 size_t bytes_read;
9560 size_t total_cstr_len = 0;
Zachary Turner97206d52017-05-12 04:51:55 +00009561 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00009562 while ((bytes_read = process->ReadMemory(pointer_address, &buf.front(),
9563 buf.size(), error)) > 0) {
9564 const size_t len = strlen((const char *)&buf.front());
9565 if (len == 0)
Greg Claytond8d4a572015-08-11 21:38:15 +00009566 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00009567 if (total_cstr_len == 0)
9568 s->PutCString(" \"");
Zachary Turner29cb8682017-03-03 20:57:05 +00009569 DumpDataExtractor(cstr_data, s, 0, lldb::eFormatChar, 1, len,
9570 UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009571 total_cstr_len += len;
9572 if (len < buf.size())
9573 break;
9574 pointer_address += total_cstr_len;
Greg Claytond8d4a572015-08-11 21:38:15 +00009575 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009576 if (total_cstr_len > 0)
9577 s->PutChar('"');
9578 }
Greg Claytond8d4a572015-08-11 21:38:15 +00009579 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009580 }
Greg Claytond8d4a572015-08-11 21:38:15 +00009581}
9582
Kate Stoneb9c1b512016-09-06 20:57:50 +00009583void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) {
9584 StreamFile s(stdout, false);
9585 DumpTypeDescription(type, &s);
9586 ClangASTMetadata *metadata =
9587 ClangASTContext::GetMetadata(getASTContext(), type);
9588 if (metadata) {
9589 metadata->Dump(&s);
9590 }
9591}
Greg Claytond8d4a572015-08-11 21:38:15 +00009592
Kate Stoneb9c1b512016-09-06 20:57:50 +00009593void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
9594 Stream *s) {
9595 if (type) {
9596 clang::QualType qual_type(GetQualType(type));
Greg Claytond8d4a572015-08-11 21:38:15 +00009597
Kate Stoneb9c1b512016-09-06 20:57:50 +00009598 llvm::SmallVector<char, 1024> buf;
9599 llvm::raw_svector_ostream llvm_ostrm(buf);
9600
9601 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
9602 switch (type_class) {
9603 case clang::Type::ObjCObject:
9604 case clang::Type::ObjCInterface: {
9605 GetCompleteType(type);
9606
9607 const clang::ObjCObjectType *objc_class_type =
9608 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
9609 assert(objc_class_type);
9610 if (objc_class_type) {
9611 clang::ObjCInterfaceDecl *class_interface_decl =
9612 objc_class_type->getInterface();
9613 if (class_interface_decl) {
9614 clang::PrintingPolicy policy = getASTContext()->getPrintingPolicy();
9615 class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
Greg Claytond8d4a572015-08-11 21:38:15 +00009616 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009617 }
9618 } break;
Greg Claytond8d4a572015-08-11 21:38:15 +00009619
Kate Stoneb9c1b512016-09-06 20:57:50 +00009620 case clang::Type::Typedef: {
9621 const clang::TypedefType *typedef_type =
9622 qual_type->getAs<clang::TypedefType>();
9623 if (typedef_type) {
9624 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
9625 std::string clang_typedef_name(
9626 typedef_decl->getQualifiedNameAsString());
9627 if (!clang_typedef_name.empty()) {
9628 s->PutCString("typedef ");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009629 s->PutCString(clang_typedef_name);
Greg Claytond8d4a572015-08-11 21:38:15 +00009630 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009631 }
9632 } break;
9633
9634 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00009635 CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
9636 ->getDeducedType()
9637 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00009638 .DumpTypeDescription(s);
9639 return;
9640
9641 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00009642 CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
9643 ->getNamedType()
9644 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00009645 .DumpTypeDescription(s);
9646 return;
9647
9648 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00009649 CompilerType(
9650 this,
9651 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00009652 .DumpTypeDescription(s);
9653 return;
9654
9655 case clang::Type::Record: {
9656 GetCompleteType(type);
9657
9658 const clang::RecordType *record_type =
9659 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
9660 const clang::RecordDecl *record_decl = record_type->getDecl();
9661 const clang::CXXRecordDecl *cxx_record_decl =
9662 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
9663
9664 if (cxx_record_decl)
9665 cxx_record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(),
9666 s->GetIndentLevel());
9667 else
9668 record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(),
9669 s->GetIndentLevel());
9670 } break;
9671
9672 default: {
9673 const clang::TagType *tag_type =
9674 llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
9675 if (tag_type) {
9676 clang::TagDecl *tag_decl = tag_type->getDecl();
9677 if (tag_decl)
9678 tag_decl->print(llvm_ostrm, 0);
9679 } else {
9680 std::string clang_type_name(qual_type.getAsString());
9681 if (!clang_type_name.empty())
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009682 s->PutCString(clang_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009683 }
Greg Claytond8d4a572015-08-11 21:38:15 +00009684 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00009685 }
9686
Kate Stoneb9c1b512016-09-06 20:57:50 +00009687 if (buf.size() > 0) {
9688 s->Write(buf.data(), buf.size());
Greg Clayton8b4edba2015-08-14 20:02:05 +00009689 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009690 }
Greg Clayton8b4edba2015-08-14 20:02:05 +00009691}
9692
Kate Stoneb9c1b512016-09-06 20:57:50 +00009693void ClangASTContext::DumpTypeName(const CompilerType &type) {
9694 if (ClangUtil::IsClangType(type)) {
9695 clang::QualType qual_type(
9696 ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
9697
9698 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
9699 switch (type_class) {
9700 case clang::Type::Record: {
9701 const clang::CXXRecordDecl *cxx_record_decl =
9702 qual_type->getAsCXXRecordDecl();
9703 if (cxx_record_decl)
9704 printf("class %s", cxx_record_decl->getName().str().c_str());
9705 } break;
9706
9707 case clang::Type::Enum: {
9708 clang::EnumDecl *enum_decl =
9709 llvm::cast<clang::EnumType>(qual_type)->getDecl();
9710 if (enum_decl) {
9711 printf("enum %s", enum_decl->getName().str().c_str());
9712 }
9713 } break;
9714
9715 case clang::Type::ObjCObject:
9716 case clang::Type::ObjCInterface: {
9717 const clang::ObjCObjectType *objc_class_type =
9718 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
9719 if (objc_class_type) {
9720 clang::ObjCInterfaceDecl *class_interface_decl =
9721 objc_class_type->getInterface();
Adrian Prantl05097242018-04-30 16:49:04 +00009722 // We currently can't complete objective C types through the newly
9723 // added ASTContext because it only supports TagDecl objects right
9724 // now...
Kate Stoneb9c1b512016-09-06 20:57:50 +00009725 if (class_interface_decl)
9726 printf("@class %s", class_interface_decl->getName().str().c_str());
9727 }
9728 } break;
9729
9730 case clang::Type::Typedef:
9731 printf("typedef %s", llvm::cast<clang::TypedefType>(qual_type)
9732 ->getDecl()
9733 ->getName()
9734 .str()
9735 .c_str());
9736 break;
9737
9738 case clang::Type::Auto:
9739 printf("auto ");
9740 return DumpTypeName(CompilerType(type.GetTypeSystem(),
9741 llvm::cast<clang::AutoType>(qual_type)
9742 ->getDeducedType()
9743 .getAsOpaquePtr()));
9744
9745 case clang::Type::Elaborated:
9746 printf("elaborated ");
9747 return DumpTypeName(CompilerType(
9748 type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)
9749 ->getNamedType()
9750 .getAsOpaquePtr()));
9751
9752 case clang::Type::Paren:
9753 printf("paren ");
9754 return DumpTypeName(CompilerType(
9755 type.GetTypeSystem(),
9756 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
9757
9758 default:
9759 printf("ClangASTContext::DumpTypeName() type_class = %u", type_class);
9760 break;
Greg Clayton6dc8d582015-08-18 22:32:36 +00009761 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009762 }
Greg Clayton6dc8d582015-08-18 22:32:36 +00009763}
9764
Kate Stoneb9c1b512016-09-06 20:57:50 +00009765clang::ClassTemplateDecl *ClangASTContext::ParseClassTemplateDecl(
9766 clang::DeclContext *decl_ctx, lldb::AccessType access_type,
9767 const char *parent_name, int tag_decl_kind,
9768 const ClangASTContext::TemplateParameterInfos &template_param_infos) {
9769 if (template_param_infos.IsValid()) {
9770 std::string template_basename(parent_name);
9771 template_basename.erase(template_basename.find('<'));
9772
9773 return CreateClassTemplateDecl(decl_ctx, access_type,
9774 template_basename.c_str(), tag_decl_kind,
9775 template_param_infos);
9776 }
Konrad Kleine248a1302019-05-23 11:14:47 +00009777 return nullptr;
Greg Clayton6dc8d582015-08-18 22:32:36 +00009778}
Greg Clayton8b4edba2015-08-14 20:02:05 +00009779
Kate Stoneb9c1b512016-09-06 20:57:50 +00009780void ClangASTContext::CompleteTagDecl(void *baton, clang::TagDecl *decl) {
9781 ClangASTContext *ast = (ClangASTContext *)baton;
9782 SymbolFile *sym_file = ast->GetSymbolFile();
9783 if (sym_file) {
9784 CompilerType clang_type = GetTypeForDecl(decl);
9785 if (clang_type)
9786 sym_file->CompleteType(clang_type);
9787 }
Greg Clayton261ac3f2015-08-28 01:01:03 +00009788}
9789
Kate Stoneb9c1b512016-09-06 20:57:50 +00009790void ClangASTContext::CompleteObjCInterfaceDecl(
9791 void *baton, clang::ObjCInterfaceDecl *decl) {
9792 ClangASTContext *ast = (ClangASTContext *)baton;
9793 SymbolFile *sym_file = ast->GetSymbolFile();
9794 if (sym_file) {
9795 CompilerType clang_type = GetTypeForDecl(decl);
9796 if (clang_type)
9797 sym_file->CompleteType(clang_type);
9798 }
Zachary Turner42dff792016-04-15 00:21:26 +00009799}
Greg Clayton261ac3f2015-08-28 01:01:03 +00009800
Kate Stoneb9c1b512016-09-06 20:57:50 +00009801DWARFASTParser *ClangASTContext::GetDWARFParser() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +00009802 if (!m_dwarf_ast_parser_up)
9803 m_dwarf_ast_parser_up.reset(new DWARFASTParserClang(*this));
9804 return m_dwarf_ast_parser_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +00009805}
9806
9807PDBASTParser *ClangASTContext::GetPDBParser() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +00009808 if (!m_pdb_ast_parser_up)
9809 m_pdb_ast_parser_up.reset(new PDBASTParser(*this));
9810 return m_pdb_ast_parser_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +00009811}
9812
9813bool ClangASTContext::LayoutRecordType(
9814 void *baton, const clang::RecordDecl *record_decl, uint64_t &bit_size,
9815 uint64_t &alignment,
9816 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
9817 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
9818 &base_offsets,
9819 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
9820 &vbase_offsets) {
9821 ClangASTContext *ast = (ClangASTContext *)baton;
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00009822 lldb_private::ClangASTImporter *importer = nullptr;
Jonas Devlieghered5b44032019-02-13 06:25:41 +00009823 if (ast->m_dwarf_ast_parser_up)
9824 importer = &ast->m_dwarf_ast_parser_up->GetClangASTImporter();
9825 if (!importer && ast->m_pdb_ast_parser_up)
9826 importer = &ast->m_pdb_ast_parser_up->GetClangASTImporter();
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00009827 if (!importer)
9828 return false;
9829
9830 return importer->LayoutRecordType(record_decl, bit_size, alignment,
9831 field_offsets, base_offsets, vbase_offsets);
Greg Clayton8b4edba2015-08-14 20:02:05 +00009832}
9833
Paul Hermand628cbb2015-09-15 23:44:17 +00009834// CompilerDecl override functions
Paul Hermand628cbb2015-09-15 23:44:17 +00009835
Kate Stoneb9c1b512016-09-06 20:57:50 +00009836ConstString ClangASTContext::DeclGetName(void *opaque_decl) {
9837 if (opaque_decl) {
9838 clang::NamedDecl *nd =
9839 llvm::dyn_cast<NamedDecl>((clang::Decl *)opaque_decl);
9840 if (nd != nullptr)
9841 return ConstString(nd->getDeclName().getAsString());
9842 }
9843 return ConstString();
Paul Hermand628cbb2015-09-15 23:44:17 +00009844}
9845
Kate Stoneb9c1b512016-09-06 20:57:50 +00009846ConstString ClangASTContext::DeclGetMangledName(void *opaque_decl) {
9847 if (opaque_decl) {
9848 clang::NamedDecl *nd =
9849 llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)opaque_decl);
9850 if (nd != nullptr && !llvm::isa<clang::ObjCMethodDecl>(nd)) {
9851 clang::MangleContext *mc = getMangleContext();
9852 if (mc && mc->shouldMangleCXXName(nd)) {
9853 llvm::SmallVector<char, 1024> buf;
9854 llvm::raw_svector_ostream llvm_ostrm(buf);
9855 if (llvm::isa<clang::CXXConstructorDecl>(nd)) {
9856 mc->mangleCXXCtor(llvm::dyn_cast<clang::CXXConstructorDecl>(nd),
9857 Ctor_Complete, llvm_ostrm);
9858 } else if (llvm::isa<clang::CXXDestructorDecl>(nd)) {
9859 mc->mangleCXXDtor(llvm::dyn_cast<clang::CXXDestructorDecl>(nd),
9860 Dtor_Complete, llvm_ostrm);
9861 } else {
9862 mc->mangleName(nd, llvm_ostrm);
Greg Claytonfe689042015-11-10 17:47:04 +00009863 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009864 if (buf.size() > 0)
9865 return ConstString(buf.data(), buf.size());
9866 }
Greg Claytonfe689042015-11-10 17:47:04 +00009867 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009868 }
9869 return ConstString();
Greg Claytonfe689042015-11-10 17:47:04 +00009870}
9871
Kate Stoneb9c1b512016-09-06 20:57:50 +00009872CompilerDeclContext ClangASTContext::DeclGetDeclContext(void *opaque_decl) {
9873 if (opaque_decl)
9874 return CompilerDeclContext(this,
9875 ((clang::Decl *)opaque_decl)->getDeclContext());
9876 else
9877 return CompilerDeclContext();
Greg Claytonfe689042015-11-10 17:47:04 +00009878}
9879
Kate Stoneb9c1b512016-09-06 20:57:50 +00009880CompilerType ClangASTContext::DeclGetFunctionReturnType(void *opaque_decl) {
9881 if (clang::FunctionDecl *func_decl =
9882 llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl))
9883 return CompilerType(this, func_decl->getReturnType().getAsOpaquePtr());
9884 if (clang::ObjCMethodDecl *objc_method =
9885 llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl))
9886 return CompilerType(this, objc_method->getReturnType().getAsOpaquePtr());
9887 else
Greg Claytonfe689042015-11-10 17:47:04 +00009888 return CompilerType();
9889}
9890
Kate Stoneb9c1b512016-09-06 20:57:50 +00009891size_t ClangASTContext::DeclGetFunctionNumArguments(void *opaque_decl) {
9892 if (clang::FunctionDecl *func_decl =
9893 llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl))
9894 return func_decl->param_size();
9895 if (clang::ObjCMethodDecl *objc_method =
9896 llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl))
9897 return objc_method->param_size();
9898 else
9899 return 0;
9900}
9901
9902CompilerType ClangASTContext::DeclGetFunctionArgumentType(void *opaque_decl,
9903 size_t idx) {
9904 if (clang::FunctionDecl *func_decl =
9905 llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl)) {
9906 if (idx < func_decl->param_size()) {
9907 ParmVarDecl *var_decl = func_decl->getParamDecl(idx);
9908 if (var_decl)
9909 return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr());
9910 }
9911 } else if (clang::ObjCMethodDecl *objc_method =
9912 llvm::dyn_cast<clang::ObjCMethodDecl>(
9913 (clang::Decl *)opaque_decl)) {
9914 if (idx < objc_method->param_size())
9915 return CompilerType(
9916 this,
9917 objc_method->parameters()[idx]->getOriginalType().getAsOpaquePtr());
9918 }
9919 return CompilerType();
9920}
9921
Greg Clayton99558cc42015-08-24 23:46:31 +00009922// CompilerDeclContext functions
Greg Clayton99558cc42015-08-24 23:46:31 +00009923
Kate Stoneb9c1b512016-09-06 20:57:50 +00009924std::vector<CompilerDecl> ClangASTContext::DeclContextFindDeclByName(
9925 void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) {
9926 std::vector<CompilerDecl> found_decls;
9927 if (opaque_decl_ctx) {
9928 DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
9929 std::set<DeclContext *> searched;
9930 std::multimap<DeclContext *, DeclContext *> search_queue;
9931 SymbolFile *symbol_file = GetSymbolFile();
Paul Hermand628cbb2015-09-15 23:44:17 +00009932
Kate Stoneb9c1b512016-09-06 20:57:50 +00009933 for (clang::DeclContext *decl_context = root_decl_ctx;
9934 decl_context != nullptr && found_decls.empty();
9935 decl_context = decl_context->getParent()) {
9936 search_queue.insert(std::make_pair(decl_context, decl_context));
Paul Hermand628cbb2015-09-15 23:44:17 +00009937
Kate Stoneb9c1b512016-09-06 20:57:50 +00009938 for (auto it = search_queue.find(decl_context); it != search_queue.end();
9939 it++) {
9940 if (!searched.insert(it->second).second)
9941 continue;
9942 symbol_file->ParseDeclsForContext(
9943 CompilerDeclContext(this, it->second));
Paul Hermanea188fc2015-09-16 18:48:30 +00009944
Kate Stoneb9c1b512016-09-06 20:57:50 +00009945 for (clang::Decl *child : it->second->decls()) {
9946 if (clang::UsingDirectiveDecl *ud =
9947 llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) {
9948 if (ignore_using_decls)
9949 continue;
9950 clang::DeclContext *from = ud->getCommonAncestor();
9951 if (searched.find(ud->getNominatedNamespace()) == searched.end())
9952 search_queue.insert(
9953 std::make_pair(from, ud->getNominatedNamespace()));
9954 } else if (clang::UsingDecl *ud =
9955 llvm::dyn_cast<clang::UsingDecl>(child)) {
9956 if (ignore_using_decls)
9957 continue;
9958 for (clang::UsingShadowDecl *usd : ud->shadows()) {
9959 clang::Decl *target = usd->getTargetDecl();
9960 if (clang::NamedDecl *nd =
9961 llvm::dyn_cast<clang::NamedDecl>(target)) {
9962 IdentifierInfo *ii = nd->getIdentifier();
9963 if (ii != nullptr &&
9964 ii->getName().equals(name.AsCString(nullptr)))
9965 found_decls.push_back(CompilerDecl(this, nd));
9966 }
Paul Hermand628cbb2015-09-15 23:44:17 +00009967 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009968 } else if (clang::NamedDecl *nd =
9969 llvm::dyn_cast<clang::NamedDecl>(child)) {
9970 IdentifierInfo *ii = nd->getIdentifier();
9971 if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr)))
9972 found_decls.push_back(CompilerDecl(this, nd));
9973 }
Paul Hermand628cbb2015-09-15 23:44:17 +00009974 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009975 }
Paul Hermand628cbb2015-09-15 23:44:17 +00009976 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009977 }
9978 return found_decls;
Paul Hermand628cbb2015-09-15 23:44:17 +00009979}
9980
Dawn Perchikb5925782015-12-12 19:31:41 +00009981// Look for child_decl_ctx's lookup scope in frame_decl_ctx and its parents,
Kate Stoneb9c1b512016-09-06 20:57:50 +00009982// and return the number of levels it took to find it, or
Adrian Prantl05097242018-04-30 16:49:04 +00009983// LLDB_INVALID_DECL_LEVEL if not found. If the decl was imported via a using
9984// declaration, its name and/or type, if set, will be used to check that the
9985// decl found in the scope is a match.
Dawn Perchikb5925782015-12-12 19:31:41 +00009986//
Kate Stoneb9c1b512016-09-06 20:57:50 +00009987// The optional name is required by languages (like C++) to handle using
Adrian Prantl05097242018-04-30 16:49:04 +00009988// declarations like:
Dawn Perchikb5925782015-12-12 19:31:41 +00009989//
9990// void poo();
9991// namespace ns {
9992// void foo();
9993// void goo();
9994// }
9995// void bar() {
9996// using ns::foo;
9997// // CountDeclLevels returns 0 for 'foo', 1 for 'poo', and
9998// // LLDB_INVALID_DECL_LEVEL for 'goo'.
9999// }
10000//
10001// The optional type is useful in the case that there's a specific overload
10002// that we're looking for that might otherwise be shadowed, like:
10003//
10004// void foo(int);
10005// namespace ns {
10006// void foo();
10007// }
10008// void bar() {
10009// using ns::foo;
10010// // CountDeclLevels returns 0 for { 'foo', void() },
10011// // 1 for { 'foo', void(int) }, and
10012// // LLDB_INVALID_DECL_LEVEL for { 'foo', void(int, int) }.
10013// }
10014//
10015// NOTE: Because file statics are at the TranslationUnit along with globals, a
Kate Stoneb9c1b512016-09-06 20:57:50 +000010016// function at file scope will return the same level as a function at global
Adrian Prantl05097242018-04-30 16:49:04 +000010017// scope. Ideally we'd like to treat the file scope as an additional scope just
10018// below the global scope. More work needs to be done to recognise that, if
10019// the decl we're trying to look up is static, we should compare its source
10020// file with that of the current scope and return a lower number for it.
Kate Stoneb9c1b512016-09-06 20:57:50 +000010021uint32_t ClangASTContext::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
10022 clang::DeclContext *child_decl_ctx,
10023 ConstString *child_name,
10024 CompilerType *child_type) {
10025 if (frame_decl_ctx) {
10026 std::set<DeclContext *> searched;
10027 std::multimap<DeclContext *, DeclContext *> search_queue;
10028 SymbolFile *symbol_file = GetSymbolFile();
Dawn Perchikb5925782015-12-12 19:31:41 +000010029
Kate Stoneb9c1b512016-09-06 20:57:50 +000010030 // Get the lookup scope for the decl we're trying to find.
10031 clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent();
Dawn Perchikb5925782015-12-12 19:31:41 +000010032
Kate Stoneb9c1b512016-09-06 20:57:50 +000010033 // Look for it in our scope's decl context and its parents.
10034 uint32_t level = 0;
10035 for (clang::DeclContext *decl_ctx = frame_decl_ctx; decl_ctx != nullptr;
10036 decl_ctx = decl_ctx->getParent()) {
10037 if (!decl_ctx->isLookupContext())
10038 continue;
10039 if (decl_ctx == parent_decl_ctx)
10040 // Found it!
10041 return level;
10042 search_queue.insert(std::make_pair(decl_ctx, decl_ctx));
10043 for (auto it = search_queue.find(decl_ctx); it != search_queue.end();
10044 it++) {
10045 if (searched.find(it->second) != searched.end())
10046 continue;
10047
10048 // Currently DWARF has one shared translation unit for all Decls at top
Adrian Prantl05097242018-04-30 16:49:04 +000010049 // level, so this would erroneously find using statements anywhere. So
10050 // don't look at the top-level translation unit.
Kate Stoneb9c1b512016-09-06 20:57:50 +000010051 // TODO fix this and add a testcase that depends on it.
10052
10053 if (llvm::isa<clang::TranslationUnitDecl>(it->second))
10054 continue;
10055
10056 searched.insert(it->second);
10057 symbol_file->ParseDeclsForContext(
10058 CompilerDeclContext(this, it->second));
10059
10060 for (clang::Decl *child : it->second->decls()) {
10061 if (clang::UsingDirectiveDecl *ud =
10062 llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) {
10063 clang::DeclContext *ns = ud->getNominatedNamespace();
10064 if (ns == parent_decl_ctx)
10065 // Found it!
10066 return level;
10067 clang::DeclContext *from = ud->getCommonAncestor();
10068 if (searched.find(ns) == searched.end())
10069 search_queue.insert(std::make_pair(from, ns));
10070 } else if (child_name) {
10071 if (clang::UsingDecl *ud =
10072 llvm::dyn_cast<clang::UsingDecl>(child)) {
10073 for (clang::UsingShadowDecl *usd : ud->shadows()) {
10074 clang::Decl *target = usd->getTargetDecl();
10075 clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(target);
10076 if (!nd)
10077 continue;
10078 // Check names.
10079 IdentifierInfo *ii = nd->getIdentifier();
10080 if (ii == nullptr ||
10081 !ii->getName().equals(child_name->AsCString(nullptr)))
10082 continue;
10083 // Check types, if one was provided.
10084 if (child_type) {
10085 CompilerType clang_type = ClangASTContext::GetTypeForDecl(nd);
10086 if (!AreTypesSame(clang_type, *child_type,
10087 /*ignore_qualifiers=*/true))
10088 continue;
10089 }
Dawn Perchikb5925782015-12-12 19:31:41 +000010090 // Found it!
10091 return level;
Kate Stoneb9c1b512016-09-06 20:57:50 +000010092 }
Dawn Perchikb5925782015-12-12 19:31:41 +000010093 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010094 }
Dawn Perchikb5925782015-12-12 19:31:41 +000010095 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010096 }
10097 ++level;
Dawn Perchikb5925782015-12-12 19:31:41 +000010098 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010099 }
10100 return LLDB_INVALID_DECL_LEVEL;
Dawn Perchikb5925782015-12-12 19:31:41 +000010101}
10102
Kate Stoneb9c1b512016-09-06 20:57:50 +000010103bool ClangASTContext::DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) {
10104 if (opaque_decl_ctx)
10105 return ((clang::DeclContext *)opaque_decl_ctx)->isRecord();
10106 else
Greg Clayton99558cc42015-08-24 23:46:31 +000010107 return false;
10108}
10109
Kate Stoneb9c1b512016-09-06 20:57:50 +000010110ConstString ClangASTContext::DeclContextGetName(void *opaque_decl_ctx) {
10111 if (opaque_decl_ctx) {
10112 clang::NamedDecl *named_decl =
10113 llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
10114 if (named_decl)
10115 return ConstString(named_decl->getName());
10116 }
10117 return ConstString();
Greg Clayton99558cc42015-08-24 23:46:31 +000010118}
10119
Kate Stoneb9c1b512016-09-06 20:57:50 +000010120ConstString
10121ClangASTContext::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) {
10122 if (opaque_decl_ctx) {
10123 clang::NamedDecl *named_decl =
10124 llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
10125 if (named_decl)
10126 return ConstString(
10127 llvm::StringRef(named_decl->getQualifiedNameAsString()));
10128 }
10129 return ConstString();
10130}
10131
10132bool ClangASTContext::DeclContextIsClassMethod(
10133 void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
10134 bool *is_instance_method_ptr, ConstString *language_object_name_ptr) {
10135 if (opaque_decl_ctx) {
10136 clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
10137 if (ObjCMethodDecl *objc_method =
10138 llvm::dyn_cast<clang::ObjCMethodDecl>(decl_ctx)) {
10139 if (is_instance_method_ptr)
10140 *is_instance_method_ptr = objc_method->isInstanceMethod();
10141 if (language_ptr)
10142 *language_ptr = eLanguageTypeObjC;
10143 if (language_object_name_ptr)
10144 language_object_name_ptr->SetCString("self");
10145 return true;
10146 } else if (CXXMethodDecl *cxx_method =
10147 llvm::dyn_cast<clang::CXXMethodDecl>(decl_ctx)) {
10148 if (is_instance_method_ptr)
10149 *is_instance_method_ptr = cxx_method->isInstance();
10150 if (language_ptr)
10151 *language_ptr = eLanguageTypeC_plus_plus;
10152 if (language_object_name_ptr)
10153 language_object_name_ptr->SetCString("this");
10154 return true;
10155 } else if (clang::FunctionDecl *function_decl =
10156 llvm::dyn_cast<clang::FunctionDecl>(decl_ctx)) {
10157 ClangASTMetadata *metadata =
10158 GetMetadata(&decl_ctx->getParentASTContext(), function_decl);
10159 if (metadata && metadata->HasObjectPtr()) {
10160 if (is_instance_method_ptr)
10161 *is_instance_method_ptr = true;
10162 if (language_ptr)
10163 *language_ptr = eLanguageTypeObjC;
10164 if (language_object_name_ptr)
10165 language_object_name_ptr->SetCString(metadata->GetObjectPtrName());
10166 return true;
10167 }
10168 }
10169 }
10170 return false;
10171}
10172
Raphael Isemanna9469972019-03-12 07:45:04 +000010173bool ClangASTContext::DeclContextIsContainedInLookup(
10174 void *opaque_decl_ctx, void *other_opaque_decl_ctx) {
10175 auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
10176 auto *other = (clang::DeclContext *)other_opaque_decl_ctx;
10177
10178 do {
10179 // A decl context always includes its own contents in its lookup.
10180 if (decl_ctx == other)
10181 return true;
10182
10183 // If we have an inline namespace, then the lookup of the parent context
10184 // also includes the inline namespace contents.
10185 } while (other->isInlineNamespace() && (other = other->getParent()));
10186
10187 return false;
10188}
10189
Kate Stoneb9c1b512016-09-06 20:57:50 +000010190clang::DeclContext *
10191ClangASTContext::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) {
10192 if (dc.IsClang())
10193 return (clang::DeclContext *)dc.GetOpaqueDeclContext();
10194 return nullptr;
10195}
Greg Clayton99558cc42015-08-24 23:46:31 +000010196
10197ObjCMethodDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010198ClangASTContext::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) {
10199 if (dc.IsClang())
10200 return llvm::dyn_cast<clang::ObjCMethodDecl>(
10201 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10202 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010203}
10204
10205CXXMethodDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010206ClangASTContext::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) {
10207 if (dc.IsClang())
10208 return llvm::dyn_cast<clang::CXXMethodDecl>(
10209 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10210 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010211}
10212
10213clang::FunctionDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010214ClangASTContext::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) {
10215 if (dc.IsClang())
10216 return llvm::dyn_cast<clang::FunctionDecl>(
10217 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10218 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010219}
10220
10221clang::NamespaceDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010222ClangASTContext::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) {
10223 if (dc.IsClang())
10224 return llvm::dyn_cast<clang::NamespaceDecl>(
10225 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10226 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010227}
10228
10229ClangASTMetadata *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010230ClangASTContext::DeclContextGetMetaData(const CompilerDeclContext &dc,
10231 const void *object) {
10232 clang::ASTContext *ast = DeclContextGetClangASTContext(dc);
10233 if (ast)
10234 return ClangASTContext::GetMetadata(ast, object);
10235 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010236}
10237
10238clang::ASTContext *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010239ClangASTContext::DeclContextGetClangASTContext(const CompilerDeclContext &dc) {
10240 ClangASTContext *ast =
10241 llvm::dyn_cast_or_null<ClangASTContext>(dc.GetTypeSystem());
10242 if (ast)
10243 return ast->getASTContext();
10244 return nullptr;
10245}
10246
Raphael Isemann2eb963a2019-10-02 12:26:08 +000010247ClangASTContextForExpressions::ClangASTContextForExpressions(Target &target,
10248 ArchSpec arch)
10249 : ClangASTContext(arch), m_target_wp(target.shared_from_this()),
Kate Stoneb9c1b512016-09-06 20:57:50 +000010250 m_persistent_variables(new ClangPersistentVariables) {}
10251
10252UserExpression *ClangASTContextForExpressions::GetUserExpression(
Zachary Turnerc5d7df92016-11-08 04:52:16 +000010253 llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
Kate Stoneb9c1b512016-09-06 20:57:50 +000010254 Expression::ResultType desired_type,
Aleksandr Urakov40624a02019-02-05 09:14:36 +000010255 const EvaluateExpressionOptions &options,
10256 ValueObject *ctx_obj) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000010257 TargetSP target_sp = m_target_wp.lock();
10258 if (!target_sp)
Greg Clayton99558cc42015-08-24 23:46:31 +000010259 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +000010260
Zachary Turnerc5d7df92016-11-08 04:52:16 +000010261 return new ClangUserExpression(*target_sp.get(), expr, prefix, language,
Aleksandr Urakov40624a02019-02-05 09:14:36 +000010262 desired_type, options, ctx_obj);
Greg Clayton8b4edba2015-08-14 20:02:05 +000010263}
10264
Kate Stoneb9c1b512016-09-06 20:57:50 +000010265FunctionCaller *ClangASTContextForExpressions::GetFunctionCaller(
10266 const CompilerType &return_type, const Address &function_address,
10267 const ValueList &arg_value_list, const char *name) {
10268 TargetSP target_sp = m_target_wp.lock();
10269 if (!target_sp)
10270 return nullptr;
Jim Ingham151c0322015-09-15 21:13:50 +000010271
Kate Stoneb9c1b512016-09-06 20:57:50 +000010272 Process *process = target_sp->GetProcessSP().get();
10273 if (!process)
10274 return nullptr;
Jim Ingham151c0322015-09-15 21:13:50 +000010275
Kate Stoneb9c1b512016-09-06 20:57:50 +000010276 return new ClangFunctionCaller(*process, return_type, function_address,
10277 arg_value_list, name);
Jim Ingham151c0322015-09-15 21:13:50 +000010278}
10279
10280UtilityFunction *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010281ClangASTContextForExpressions::GetUtilityFunction(const char *text,
10282 const char *name) {
10283 TargetSP target_sp = m_target_wp.lock();
10284 if (!target_sp)
10285 return nullptr;
10286
10287 return new ClangUtilityFunction(*target_sp.get(), text, name);
Jim Ingham151c0322015-09-15 21:13:50 +000010288}
Sean Callanan8f1f9a12015-09-30 19:57:57 +000010289
10290PersistentExpressionState *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010291ClangASTContextForExpressions::GetPersistentExpressionState() {
10292 return m_persistent_variables.get();
Sean Callanan8f1f9a12015-09-30 19:57:57 +000010293}
Sean Callanan68e44232017-09-28 20:20:25 +000010294
10295clang::ExternalASTMerger &
10296ClangASTContextForExpressions::GetMergerUnchecked() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +000010297 lldbassert(m_scratch_ast_source_up != nullptr);
10298 return m_scratch_ast_source_up->GetMergerUnchecked();
Sean Callanan68e44232017-09-28 20:20:25 +000010299}