blob: a80a9c75188fc8d4e740b6d3ed461a4a6ba8eb2c [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;
106using namespace llvm;
107using namespace clang;
108
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
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525ClangASTContext::ClangASTContext(const char *target_triple)
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000526 : TypeSystem(TypeSystem::eKindClang), m_target_triple(), m_ast_up(),
527 m_language_options_up(), m_source_manager_up(), m_diagnostics_engine_up(),
528 m_target_options_rp(), m_target_info_up(), m_identifier_table_up(),
529 m_selector_table_up(), m_builtins_up(), m_callback_tag_decl(nullptr),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530 m_callback_objc_decl(nullptr), m_callback_baton(nullptr),
531 m_pointer_byte_size(0), m_ast_owned(false) {
532 if (target_triple && target_triple[0])
533 SetTargetTriple(target_triple);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534}
535
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536// Destructor
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537ClangASTContext::~ClangASTContext() { Finalize(); }
538
539ConstString ClangASTContext::GetPluginNameStatic() {
540 return ConstString("clang");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000541}
542
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543ConstString ClangASTContext::GetPluginName() {
544 return ClangASTContext::GetPluginNameStatic();
Greg Clayton56939cb2015-09-17 22:23:34 +0000545}
546
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547uint32_t ClangASTContext::GetPluginVersion() { return 1; }
Greg Clayton56939cb2015-09-17 22:23:34 +0000548
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language,
550 lldb_private::Module *module,
551 Target *target) {
552 if (ClangASTContextSupportsLanguage(language)) {
553 ArchSpec arch;
554 if (module)
555 arch = module->GetArchitecture();
556 else if (target)
557 arch = target->GetArchitecture();
Greg Clayton56939cb2015-09-17 22:23:34 +0000558
Kate Stoneb9c1b512016-09-06 20:57:50 +0000559 if (arch.IsValid()) {
560 ArchSpec fixed_arch = arch;
561 // LLVM wants this to be set to iOS or MacOSX; if we're working on
562 // a bare-boards type image, change the triple for llvm's benefit.
563 if (fixed_arch.GetTriple().getVendor() == llvm::Triple::Apple &&
564 fixed_arch.GetTriple().getOS() == llvm::Triple::UnknownOS) {
565 if (fixed_arch.GetTriple().getArch() == llvm::Triple::arm ||
566 fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
567 fixed_arch.GetTriple().getArch() == llvm::Triple::thumb) {
568 fixed_arch.GetTriple().setOS(llvm::Triple::IOS);
569 } else {
570 fixed_arch.GetTriple().setOS(llvm::Triple::MacOSX);
Greg Clayton56939cb2015-09-17 22:23:34 +0000571 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000572 }
Greg Clayton56939cb2015-09-17 22:23:34 +0000573
Kate Stoneb9c1b512016-09-06 20:57:50 +0000574 if (module) {
575 std::shared_ptr<ClangASTContext> ast_sp(new ClangASTContext);
576 if (ast_sp) {
577 ast_sp->SetArchitecture(fixed_arch);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000578 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579 return ast_sp;
580 } else if (target && target->IsValid()) {
581 std::shared_ptr<ClangASTContextForExpressions> ast_sp(
582 new ClangASTContextForExpressions(*target));
583 if (ast_sp) {
584 ast_sp->SetArchitecture(fixed_arch);
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000585 ast_sp->m_scratch_ast_source_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000586 new ClangASTSource(target->shared_from_this()));
Sean Callanan68e44232017-09-28 20:20:25 +0000587 lldbassert(ast_sp->getFileManager());
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000588 ast_sp->m_scratch_ast_source_up->InstallASTContext(
Sean Callanan68e44232017-09-28 20:20:25 +0000589 *ast_sp->getASTContext(), *ast_sp->getFileManager(), true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000590 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000591 ast_sp->m_scratch_ast_source_up->CreateProxy());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000592 ast_sp->SetExternalSource(proxy_ast_source);
593 return ast_sp;
594 }
595 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000597 }
598 return lldb::TypeSystemSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000599}
600
Adrian Prantlaa97a892019-08-22 21:45:58 +0000601LanguageSet ClangASTContext::GetSupportedLanguagesForTypes() {
602 LanguageSet languages;
603 languages.Insert(lldb::eLanguageTypeC89);
604 languages.Insert(lldb::eLanguageTypeC);
605 languages.Insert(lldb::eLanguageTypeC11);
606 languages.Insert(lldb::eLanguageTypeC_plus_plus);
607 languages.Insert(lldb::eLanguageTypeC99);
608 languages.Insert(lldb::eLanguageTypeObjC);
609 languages.Insert(lldb::eLanguageTypeObjC_plus_plus);
610 languages.Insert(lldb::eLanguageTypeC_plus_plus_03);
611 languages.Insert(lldb::eLanguageTypeC_plus_plus_11);
612 languages.Insert(lldb::eLanguageTypeC11);
613 languages.Insert(lldb::eLanguageTypeC_plus_plus_14);
614 return languages;
615}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000616
Adrian Prantlaa97a892019-08-22 21:45:58 +0000617LanguageSet ClangASTContext::GetSupportedLanguagesForExpressions() {
618 LanguageSet languages;
619 languages.Insert(lldb::eLanguageTypeC_plus_plus);
620 languages.Insert(lldb::eLanguageTypeObjC_plus_plus);
621 languages.Insert(lldb::eLanguageTypeC_plus_plus_03);
622 languages.Insert(lldb::eLanguageTypeC_plus_plus_11);
623 languages.Insert(lldb::eLanguageTypeC_plus_plus_14);
624 return languages;
Enrico Granata5d84a692014-08-19 21:46:37 +0000625}
626
Kate Stoneb9c1b512016-09-06 20:57:50 +0000627void ClangASTContext::Initialize() {
Adrian Prantlaa97a892019-08-22 21:45:58 +0000628 PluginManager::RegisterPlugin(
629 GetPluginNameStatic(), "clang base AST context plug-in", CreateInstance,
630 GetSupportedLanguagesForTypes(), GetSupportedLanguagesForExpressions());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000631}
632
Kate Stoneb9c1b512016-09-06 20:57:50 +0000633void ClangASTContext::Terminate() {
634 PluginManager::UnregisterPlugin(CreateInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000635}
636
Kate Stoneb9c1b512016-09-06 20:57:50 +0000637void ClangASTContext::Finalize() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000638 if (m_ast_up) {
639 GetASTMap().Erase(m_ast_up.get());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000640 if (!m_ast_owned)
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000641 m_ast_up.release();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000642 }
643
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000644 m_builtins_up.reset();
645 m_selector_table_up.reset();
646 m_identifier_table_up.reset();
647 m_target_info_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000648 m_target_options_rp.reset();
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000649 m_diagnostics_engine_up.reset();
650 m_source_manager_up.reset();
651 m_language_options_up.reset();
652 m_ast_up.reset();
653 m_scratch_ast_source_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000654}
655
656void ClangASTContext::Clear() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000657 m_ast_up.reset();
658 m_language_options_up.reset();
659 m_source_manager_up.reset();
660 m_diagnostics_engine_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000661 m_target_options_rp.reset();
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000662 m_target_info_up.reset();
663 m_identifier_table_up.reset();
664 m_selector_table_up.reset();
665 m_builtins_up.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000666 m_pointer_byte_size = 0;
667}
668
Raphael Isemannf74a4c12019-04-30 08:41:35 +0000669void ClangASTContext::setSema(Sema *s) {
670 // Ensure that the new sema actually belongs to our ASTContext.
671 assert(s == nullptr || &s->getASTContext() == m_ast_up.get());
672 m_sema = s;
673}
674
Kate Stoneb9c1b512016-09-06 20:57:50 +0000675const char *ClangASTContext::GetTargetTriple() {
676 return m_target_triple.c_str();
677}
678
679void ClangASTContext::SetTargetTriple(const char *target_triple) {
680 Clear();
681 m_target_triple.assign(target_triple);
682}
683
684void ClangASTContext::SetArchitecture(const ArchSpec &arch) {
685 SetTargetTriple(arch.GetTriple().str().c_str());
686}
687
688bool ClangASTContext::HasExternalSource() {
689 ASTContext *ast = getASTContext();
690 if (ast)
691 return ast->getExternalSource() != nullptr;
692 return false;
693}
694
695void ClangASTContext::SetExternalSource(
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000696 llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000697 ASTContext *ast = getASTContext();
698 if (ast) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000699 ast->setExternalSource(ast_source_up);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000700 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000701 }
702}
703
704void ClangASTContext::RemoveExternalSource() {
705 ASTContext *ast = getASTContext();
706
707 if (ast) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000708 llvm::IntrusiveRefCntPtr<ExternalASTSource> empty_ast_source_up;
709 ast->setExternalSource(empty_ast_source_up);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000710 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711 }
712}
713
714void ClangASTContext::setASTContext(clang::ASTContext *ast_ctx) {
715 if (!m_ast_owned) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000716 m_ast_up.release();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000717 }
718 m_ast_owned = false;
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000719 m_ast_up.reset(ast_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000720 GetASTMap().Insert(ast_ctx, this);
721}
722
723ASTContext *ClangASTContext::getASTContext() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000724 if (m_ast_up == nullptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000725 m_ast_owned = true;
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000726 m_ast_up.reset(new ASTContext(*getLanguageOptions(), *getSourceManager(),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727 *getIdentifierTable(), *getSelectorTable(),
728 *getBuiltinContext()));
729
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000730 m_ast_up->getDiagnostics().setClient(getDiagnosticConsumer(), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000731
732 // This can be NULL if we don't know anything about the architecture or if
Adrian Prantl05097242018-04-30 16:49:04 +0000733 // the target for an architecture isn't enabled in the llvm/clang that we
734 // built
Kate Stoneb9c1b512016-09-06 20:57:50 +0000735 TargetInfo *target_info = getTargetInfo();
736 if (target_info)
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000737 m_ast_up->InitBuiltinTypes(*target_info);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000738
739 if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000740 m_ast_up->getTranslationUnitDecl()->setHasExternalLexicalStorage();
741 // m_ast_up->getTranslationUnitDecl()->setHasExternalVisibleStorage();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000742 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000743
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000744 GetASTMap().Insert(m_ast_up.get(), this);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000745
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000746 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_up(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000747 new ClangExternalASTSourceCallbacks(
748 ClangASTContext::CompleteTagDecl,
749 ClangASTContext::CompleteObjCInterfaceDecl, nullptr,
750 ClangASTContext::LayoutRecordType, this));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000751 SetExternalSource(ast_source_up);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000752 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000753 return m_ast_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754}
755
Kate Stoneb9c1b512016-09-06 20:57:50 +0000756ClangASTContext *ClangASTContext::GetASTContext(clang::ASTContext *ast) {
757 ClangASTContext *clang_ast = GetASTMap().Lookup(ast);
758 return clang_ast;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000759}
760
Kate Stoneb9c1b512016-09-06 20:57:50 +0000761Builtin::Context *ClangASTContext::getBuiltinContext() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000762 if (m_builtins_up == nullptr)
763 m_builtins_up.reset(new Builtin::Context());
764 return m_builtins_up.get();
Sean Callanan79439e82010-11-18 02:56:27 +0000765}
766
Kate Stoneb9c1b512016-09-06 20:57:50 +0000767IdentifierTable *ClangASTContext::getIdentifierTable() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000768 if (m_identifier_table_up == nullptr)
769 m_identifier_table_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000770 new IdentifierTable(*ClangASTContext::getLanguageOptions(), nullptr));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000771 return m_identifier_table_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000772}
773
Kate Stoneb9c1b512016-09-06 20:57:50 +0000774LangOptions *ClangASTContext::getLanguageOptions() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000775 if (m_language_options_up == nullptr) {
776 m_language_options_up.reset(new LangOptions());
Rainer Orth6ca17072019-08-05 14:00:43 +0000777 ParseLangArgs(*m_language_options_up, clang::Language::ObjCXX,
778 GetTargetTriple());
779 // InitializeLangOptions(*m_language_options_up, Language::ObjCXX);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000780 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000781 return m_language_options_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782}
783
Kate Stoneb9c1b512016-09-06 20:57:50 +0000784SelectorTable *ClangASTContext::getSelectorTable() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000785 if (m_selector_table_up == nullptr)
786 m_selector_table_up.reset(new SelectorTable());
787 return m_selector_table_up.get();
Greg Claytonfe689042015-11-10 17:47:04 +0000788}
789
Kate Stoneb9c1b512016-09-06 20:57:50 +0000790clang::FileManager *ClangASTContext::getFileManager() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000791 if (m_file_manager_up == nullptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000792 clang::FileSystemOptions file_system_options;
Jonas Devlieghere9764b652019-02-18 20:31:18 +0000793 m_file_manager_up.reset(new clang::FileManager(
794 file_system_options, FileSystem::Instance().GetVirtualFileSystem()));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000795 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000796 return m_file_manager_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000797}
798
799clang::SourceManager *ClangASTContext::getSourceManager() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000800 if (m_source_manager_up == nullptr)
801 m_source_manager_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000802 new clang::SourceManager(*getDiagnosticsEngine(), *getFileManager()));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000803 return m_source_manager_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000804}
805
806clang::DiagnosticsEngine *ClangASTContext::getDiagnosticsEngine() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000807 if (m_diagnostics_engine_up == nullptr) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000808 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000809 m_diagnostics_engine_up.reset(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000810 new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions()));
811 }
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000812 return m_diagnostics_engine_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000813}
814
815clang::MangleContext *ClangASTContext::getMangleContext() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000816 if (m_mangle_ctx_up == nullptr)
817 m_mangle_ctx_up.reset(getASTContext()->createMangleContext());
818 return m_mangle_ctx_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000819}
820
821class NullDiagnosticConsumer : public DiagnosticConsumer {
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000822public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000823 NullDiagnosticConsumer() {
824 m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
825 }
Sean Callanan579e70c2016-03-19 00:03:59 +0000826
Kate Stoneb9c1b512016-09-06 20:57:50 +0000827 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
Raphael Isemann17566302019-05-03 10:03:28 +0000828 const clang::Diagnostic &info) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000829 if (m_log) {
830 llvm::SmallVector<char, 32> diag_str(10);
831 info.FormatDiagnostic(diag_str);
832 diag_str.push_back('\0');
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000833 LLDB_LOGF(m_log, "Compiler diagnostic: %s\n", diag_str.data());
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000834 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000835 }
836
837 DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
838 return new NullDiagnosticConsumer();
839 }
840
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000841private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000842 Log *m_log;
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000843};
844
Kate Stoneb9c1b512016-09-06 20:57:50 +0000845DiagnosticConsumer *ClangASTContext::getDiagnosticConsumer() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000846 if (m_diagnostic_consumer_up == nullptr)
847 m_diagnostic_consumer_up.reset(new NullDiagnosticConsumer);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000848
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000849 return m_diagnostic_consumer_up.get();
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000850}
851
Kate Stoneb9c1b512016-09-06 20:57:50 +0000852std::shared_ptr<clang::TargetOptions> &ClangASTContext::getTargetOptions() {
Jonas Devlieghere70355ac2019-02-12 03:47:39 +0000853 if (m_target_options_rp == nullptr && !m_target_triple.empty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000854 m_target_options_rp = std::make_shared<clang::TargetOptions>();
Jonas Devlieghere70355ac2019-02-12 03:47:39 +0000855 if (m_target_options_rp != nullptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000856 m_target_options_rp->Triple = m_target_triple;
857 }
858 return m_target_options_rp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000859}
860
Kate Stoneb9c1b512016-09-06 20:57:50 +0000861TargetInfo *ClangASTContext::getTargetInfo() {
862 // target_triple should be something like "x86_64-apple-macosx"
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000863 if (m_target_info_up == nullptr && !m_target_triple.empty())
864 m_target_info_up.reset(TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000865 getTargetOptions()));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000866 return m_target_info_up.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000867}
868
869#pragma mark Basic Types
870
Kate Stoneb9c1b512016-09-06 20:57:50 +0000871static inline bool QualTypeMatchesBitSize(const uint64_t bit_size,
872 ASTContext *ast, QualType qual_type) {
873 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000874 return qual_type_bit_size == bit_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000875}
Greg Clayton56939cb2015-09-17 22:23:34 +0000876
Greg Claytona1e5dc82015-08-11 22:53:00 +0000877CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000878ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
879 size_t bit_size) {
880 return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
881 getASTContext(), encoding, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000882}
883
Kate Stoneb9c1b512016-09-06 20:57:50 +0000884CompilerType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
885 ASTContext *ast, Encoding encoding, uint32_t bit_size) {
Alex Langfordbddab072019-08-13 19:40:36 +0000886 auto *clang_ast_context = ClangASTContext::GetASTContext(ast);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000887 if (!ast)
Greg Claytona1e5dc82015-08-11 22:53:00 +0000888 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000889 switch (encoding) {
890 case eEncodingInvalid:
891 if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000892 return CompilerType(clang_ast_context, ast->VoidPtrTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000893 break;
894
895 case eEncodingUint:
896 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000897 return CompilerType(clang_ast_context,
898 ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000899 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000900 return CompilerType(clang_ast_context,
901 ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000902 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000903 return CompilerType(clang_ast_context,
904 ast->UnsignedIntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000905 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000906 return CompilerType(clang_ast_context,
907 ast->UnsignedLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000908 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000909 return CompilerType(clang_ast_context,
910 ast->UnsignedLongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000911 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +0000912 return CompilerType(clang_ast_context,
913 ast->UnsignedInt128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000914 break;
915
916 case eEncodingSint:
917 if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000918 return CompilerType(clang_ast_context,
919 ast->SignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000920 if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000921 return CompilerType(clang_ast_context, ast->ShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000922 if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000923 return CompilerType(clang_ast_context, ast->IntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000924 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000925 return CompilerType(clang_ast_context, ast->LongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000926 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000927 return CompilerType(clang_ast_context, ast->LongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000928 if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +0000929 return CompilerType(clang_ast_context, ast->Int128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000930 break;
931
932 case eEncodingIEEE754:
933 if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000934 return CompilerType(clang_ast_context, ast->FloatTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935 if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000936 return CompilerType(clang_ast_context, ast->DoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000937 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000938 return CompilerType(clang_ast_context,
939 ast->LongDoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940 if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
Alex Langfordbddab072019-08-13 19:40:36 +0000941 return CompilerType(clang_ast_context, ast->HalfTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000942 break;
943
944 case eEncodingVector:
945 // Sanity check that bit_size is a multiple of 8's.
946 if (bit_size && !(bit_size & 0x7u))
947 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +0000948 clang_ast_context,
949 ast->getExtVectorType(ast->UnsignedCharTy, bit_size / 8)
950 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000951 break;
952 }
953
954 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000955}
956
Greg Clayton57ee3062013-07-11 22:46:58 +0000957lldb::BasicType
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000958ClangASTContext::GetBasicTypeEnumeration(ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000959 if (name) {
960 typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
961 static TypeNameToBasicTypeMap g_type_map;
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000962 static llvm::once_flag g_once_flag;
963 llvm::call_once(g_once_flag, []() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000964 // "void"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000965 g_type_map.Append(ConstString("void"), eBasicTypeVoid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000966
967 // "char"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000968 g_type_map.Append(ConstString("char"), eBasicTypeChar);
969 g_type_map.Append(ConstString("signed char"), eBasicTypeSignedChar);
970 g_type_map.Append(ConstString("unsigned char"), eBasicTypeUnsignedChar);
971 g_type_map.Append(ConstString("wchar_t"), eBasicTypeWChar);
972 g_type_map.Append(ConstString("signed wchar_t"), eBasicTypeSignedWChar);
973 g_type_map.Append(ConstString("unsigned wchar_t"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000974 eBasicTypeUnsignedWChar);
975 // "short"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000976 g_type_map.Append(ConstString("short"), eBasicTypeShort);
977 g_type_map.Append(ConstString("short int"), eBasicTypeShort);
978 g_type_map.Append(ConstString("unsigned short"), eBasicTypeUnsignedShort);
979 g_type_map.Append(ConstString("unsigned short int"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000980 eBasicTypeUnsignedShort);
981
982 // "int"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000983 g_type_map.Append(ConstString("int"), eBasicTypeInt);
984 g_type_map.Append(ConstString("signed int"), eBasicTypeInt);
985 g_type_map.Append(ConstString("unsigned int"), eBasicTypeUnsignedInt);
986 g_type_map.Append(ConstString("unsigned"), eBasicTypeUnsignedInt);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000987
988 // "long"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000989 g_type_map.Append(ConstString("long"), eBasicTypeLong);
990 g_type_map.Append(ConstString("long int"), eBasicTypeLong);
991 g_type_map.Append(ConstString("unsigned long"), eBasicTypeUnsignedLong);
992 g_type_map.Append(ConstString("unsigned long int"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000993 eBasicTypeUnsignedLong);
994
995 // "long long"
Pavel Labath4d35d6b2017-05-02 10:17:30 +0000996 g_type_map.Append(ConstString("long long"), eBasicTypeLongLong);
997 g_type_map.Append(ConstString("long long int"), eBasicTypeLongLong);
998 g_type_map.Append(ConstString("unsigned long long"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000999 eBasicTypeUnsignedLongLong);
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001000 g_type_map.Append(ConstString("unsigned long long int"),
Kate Stoneb9c1b512016-09-06 20:57:50 +00001001 eBasicTypeUnsignedLongLong);
1002
1003 // "int128"
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001004 g_type_map.Append(ConstString("__int128_t"), eBasicTypeInt128);
1005 g_type_map.Append(ConstString("__uint128_t"), eBasicTypeUnsignedInt128);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001006
1007 // Miscellaneous
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001008 g_type_map.Append(ConstString("bool"), eBasicTypeBool);
1009 g_type_map.Append(ConstString("float"), eBasicTypeFloat);
1010 g_type_map.Append(ConstString("double"), eBasicTypeDouble);
1011 g_type_map.Append(ConstString("long double"), eBasicTypeLongDouble);
1012 g_type_map.Append(ConstString("id"), eBasicTypeObjCID);
1013 g_type_map.Append(ConstString("SEL"), eBasicTypeObjCSel);
1014 g_type_map.Append(ConstString("nullptr"), eBasicTypeNullPtr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 g_type_map.Sort();
1016 });
1017
Pavel Labath4d35d6b2017-05-02 10:17:30 +00001018 return g_type_map.Find(name, eBasicTypeInvalid);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001019 }
1020 return eBasicTypeInvalid;
Greg Clayton57ee3062013-07-11 22:46:58 +00001021}
1022
Kate Stoneb9c1b512016-09-06 20:57:50 +00001023CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
Adrian Prantl0e4c4822019-03-06 21:22:25 +00001024 ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001025 if (ast) {
1026 lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration(name);
1027 return ClangASTContext::GetBasicType(ast, basic_type);
1028 }
1029 return CompilerType();
1030}
1031
1032uint32_t ClangASTContext::GetPointerByteSize() {
1033 if (m_pointer_byte_size == 0)
Adrian Prantld963a7c2019-01-15 18:07:52 +00001034 if (auto size = GetBasicType(lldb::eBasicTypeVoid)
1035 .GetPointerType()
1036 .GetByteSize(nullptr))
1037 m_pointer_byte_size = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001038 return m_pointer_byte_size;
1039}
1040
1041CompilerType ClangASTContext::GetBasicType(lldb::BasicType basic_type) {
1042 return GetBasicType(getASTContext(), basic_type);
1043}
1044
1045CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
1046 lldb::BasicType basic_type) {
1047 if (!ast)
Greg Claytona1e5dc82015-08-11 22:53:00 +00001048 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001049 lldb::opaque_compiler_type_t clang_type =
1050 GetOpaqueCompilerType(ast, basic_type);
1051
1052 if (clang_type)
1053 return CompilerType(GetASTContext(ast), clang_type);
1054 return CompilerType();
Greg Clayton57ee3062013-07-11 22:46:58 +00001055}
1056
Kate Stoneb9c1b512016-09-06 20:57:50 +00001057CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
1058 const char *type_name, uint32_t dw_ate, uint32_t bit_size) {
1059 ASTContext *ast = getASTContext();
Greg Clayton57ee3062013-07-11 22:46:58 +00001060
Kate Stoneb9c1b512016-09-06 20:57:50 +00001061#define streq(a, b) strcmp(a, b) == 0
1062 assert(ast != nullptr);
1063 if (ast) {
1064 switch (dw_ate) {
1065 default:
1066 break;
Greg Clayton57ee3062013-07-11 22:46:58 +00001067
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068 case DW_ATE_address:
1069 if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001070 return CompilerType(this, ast->VoidPtrTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001071 break;
Zachary Turner9d8a97e2016-04-01 23:20:35 +00001072
Kate Stoneb9c1b512016-09-06 20:57:50 +00001073 case DW_ATE_boolean:
1074 if (QualTypeMatchesBitSize(bit_size, ast, ast->BoolTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001075 return CompilerType(this, ast->BoolTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001076 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001077 return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001078 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001079 return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001080 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001081 return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001082 break;
Greg Clayton57ee3062013-07-11 22:46:58 +00001083
Kate Stoneb9c1b512016-09-06 20:57:50 +00001084 case DW_ATE_lo_user:
1085 // This has been seen to mean DW_AT_complex_integer
1086 if (type_name) {
1087 if (::strstr(type_name, "complex")) {
1088 CompilerType complex_int_clang_type =
1089 GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed,
1090 bit_size / 2);
Alex Langfordbddab072019-08-13 19:40:36 +00001091 return CompilerType(
1092 this, ast->getComplexType(
1093 ClangUtil::GetQualType(complex_int_clang_type))
1094 .getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001095 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001096 }
1097 break;
1098
1099 case DW_ATE_complex_float:
1100 if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatComplexTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001101 return CompilerType(this, ast->FloatComplexTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001102 else if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleComplexTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001103 return CompilerType(this, ast->DoubleComplexTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001104 else if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleComplexTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001105 return CompilerType(this, ast->LongDoubleComplexTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001106 else {
1107 CompilerType complex_float_clang_type =
1108 GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float,
1109 bit_size / 2);
Alex Langfordbddab072019-08-13 19:40:36 +00001110 return CompilerType(
1111 this, ast->getComplexType(
1112 ClangUtil::GetQualType(complex_float_clang_type))
1113 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001114 }
1115 break;
1116
1117 case DW_ATE_float:
1118 if (streq(type_name, "float") &&
1119 QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001120 return CompilerType(this, ast->FloatTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001121 if (streq(type_name, "double") &&
1122 QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001123 return CompilerType(this, ast->DoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001124 if (streq(type_name, "long double") &&
1125 QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001126 return CompilerType(this, ast->LongDoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001127 // Fall back to not requiring a name match
1128 if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001129 return CompilerType(this, ast->FloatTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001130 if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001131 return CompilerType(this, ast->DoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001133 return CompilerType(this, ast->LongDoubleTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001134 if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001135 return CompilerType(this, ast->HalfTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136 break;
1137
1138 case DW_ATE_signed:
1139 if (type_name) {
1140 if (streq(type_name, "wchar_t") &&
1141 QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy) &&
1142 (getTargetInfo() &&
1143 TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
Alex Langfordbddab072019-08-13 19:40:36 +00001144 return CompilerType(this, ast->WCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145 if (streq(type_name, "void") &&
1146 QualTypeMatchesBitSize(bit_size, ast, ast->VoidTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001147 return CompilerType(this, ast->VoidTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001148 if (strstr(type_name, "long long") &&
1149 QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001150 return CompilerType(this, ast->LongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001151 if (strstr(type_name, "long") &&
1152 QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001153 return CompilerType(this, ast->LongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154 if (strstr(type_name, "short") &&
1155 QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001156 return CompilerType(this, ast->ShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001157 if (strstr(type_name, "char")) {
1158 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001159 return CompilerType(this, ast->CharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001160 if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001161 return CompilerType(this, ast->SignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001162 }
1163 if (strstr(type_name, "int")) {
1164 if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001165 return CompilerType(this, ast->IntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001166 if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00001167 return CompilerType(this, ast->Int128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001168 }
1169 }
1170 // We weren't able to match up a type name, just search by size
1171 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001172 return CompilerType(this, ast->CharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001173 if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001174 return CompilerType(this, ast->ShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001175 if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001176 return CompilerType(this, ast->IntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001177 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001178 return CompilerType(this, ast->LongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001179 if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001180 return CompilerType(this, ast->LongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001181 if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00001182 return CompilerType(this, ast->Int128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001183 break;
1184
1185 case DW_ATE_signed_char:
1186 if (ast->getLangOpts().CharIsSigned && type_name &&
1187 streq(type_name, "char")) {
1188 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001189 return CompilerType(this, ast->CharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001190 }
1191 if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001192 return CompilerType(this, ast->SignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001193 break;
1194
1195 case DW_ATE_unsigned:
1196 if (type_name) {
1197 if (streq(type_name, "wchar_t")) {
1198 if (QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy)) {
1199 if (!(getTargetInfo() &&
1200 TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
Alex Langfordbddab072019-08-13 19:40:36 +00001201 return CompilerType(this, ast->WCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001202 }
1203 }
1204 if (strstr(type_name, "long long")) {
1205 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001206 return CompilerType(this, ast->UnsignedLongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001207 } else if (strstr(type_name, "long")) {
1208 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001209 return CompilerType(this, ast->UnsignedLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001210 } else if (strstr(type_name, "short")) {
1211 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001212 return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001213 } else if (strstr(type_name, "char")) {
1214 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001215 return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001216 } else if (strstr(type_name, "int")) {
1217 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001218 return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001219 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00001220 return CompilerType(this, ast->UnsignedInt128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001221 }
1222 }
1223 // We weren't able to match up a type name, just search by size
1224 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001225 return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001226 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001227 return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001228 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001229 return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001231 return CompilerType(this, ast->UnsignedLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001232 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001233 return CompilerType(this, ast->UnsignedLongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001234 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00001235 return CompilerType(this, ast->UnsignedInt128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001236 break;
1237
1238 case DW_ATE_unsigned_char:
1239 if (!ast->getLangOpts().CharIsSigned && type_name &&
1240 streq(type_name, "char")) {
1241 if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001242 return CompilerType(this, ast->CharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001243 }
1244 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001245 return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001246 if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00001247 return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001248 break;
1249
1250 case DW_ATE_imaginary_float:
1251 break;
1252
1253 case DW_ATE_UTF:
1254 if (type_name) {
Jonas Devliegherec46d39b2019-08-21 21:30:55 +00001255 if (streq(type_name, "char16_t"))
Alex Langfordbddab072019-08-13 19:40:36 +00001256 return CompilerType(this, ast->Char16Ty.getAsOpaquePtr());
Jonas Devlieghere6c9dc122019-08-23 04:11:38 +00001257 if (streq(type_name, "char32_t"))
Alex Langfordbddab072019-08-13 19:40:36 +00001258 return CompilerType(this, ast->Char32Ty.getAsOpaquePtr());
Jonas Devlieghere6c9dc122019-08-23 04:11:38 +00001259 if (streq(type_name, "char8_t"))
Jonas Devliegherec46d39b2019-08-21 21:30:55 +00001260 return CompilerType(this, ast->Char8Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001261 }
1262 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001263 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001264 }
1265 // This assert should fire for anything that we don't catch above so we know
1266 // to fix any issues we run into.
1267 if (type_name) {
1268 Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
1269 "DW_TAG_base_type '%s' encoded with "
1270 "DW_ATE = 0x%x, bit_size = %u\n",
1271 type_name, dw_ate, bit_size);
1272 } else {
1273 Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
1274 "DW_TAG_base_type encoded with "
1275 "DW_ATE = 0x%x, bit_size = %u\n",
1276 dw_ate, bit_size);
1277 }
1278 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001279}
1280
Kate Stoneb9c1b512016-09-06 20:57:50 +00001281CompilerType ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast) {
1282 if (ast)
Alex Langfordbddab072019-08-13 19:40:36 +00001283 return CompilerType(ClangASTContext::GetASTContext(ast),
1284 ast->UnknownAnyTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001285 return CompilerType();
Sean Callanan77502262011-05-12 23:54:16 +00001286}
1287
Kate Stoneb9c1b512016-09-06 20:57:50 +00001288CompilerType ClangASTContext::GetCStringType(bool is_const) {
1289 ASTContext *ast = getASTContext();
1290 QualType char_type(ast->CharTy);
1291
1292 if (is_const)
1293 char_type.addConst();
1294
Alex Langfordbddab072019-08-13 19:40:36 +00001295 return CompilerType(this, ast->getPointerType(char_type).getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296}
1297
Zachary Turner115209e2018-11-05 19:25:39 +00001298clang::DeclContext *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001299ClangASTContext::GetTranslationUnitDecl(clang::ASTContext *ast) {
1300 return ast->getTranslationUnitDecl();
Sean Callanan09ab4b72011-11-30 22:11:59 +00001301}
1302
Kate Stoneb9c1b512016-09-06 20:57:50 +00001303clang::Decl *ClangASTContext::CopyDecl(ASTContext *dst_ast, ASTContext *src_ast,
1304 clang::Decl *source_decl) {
1305 FileSystemOptions file_system_options;
1306 FileManager file_manager(file_system_options);
1307 ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager, false);
1308
Gabor Marton5ac6d492019-05-15 10:29:48 +00001309 if (llvm::Expected<clang::Decl *> ret_or_error =
1310 importer.Import(source_decl)) {
1311 return *ret_or_error;
1312 } else {
1313 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
1314 LLDB_LOG_ERROR(log, ret_or_error.takeError(), "Couldn't import decl: {0}");
1315 return nullptr;
1316 }
Greg Clayton526e5af2010-11-13 03:52:47 +00001317}
1318
Kate Stoneb9c1b512016-09-06 20:57:50 +00001319bool ClangASTContext::AreTypesSame(CompilerType type1, CompilerType type2,
1320 bool ignore_qualifiers) {
1321 ClangASTContext *ast =
1322 llvm::dyn_cast_or_null<ClangASTContext>(type1.GetTypeSystem());
1323 if (!ast || ast != type2.GetTypeSystem())
1324 return false;
Greg Clayton57ee3062013-07-11 22:46:58 +00001325
Kate Stoneb9c1b512016-09-06 20:57:50 +00001326 if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
1327 return true;
Greg Clayton55995eb2012-04-06 17:38:55 +00001328
Kate Stoneb9c1b512016-09-06 20:57:50 +00001329 QualType type1_qual = ClangUtil::GetQualType(type1);
1330 QualType type2_qual = ClangUtil::GetQualType(type2);
Zachary Turnerd133f6a2016-03-28 22:53:41 +00001331
Kate Stoneb9c1b512016-09-06 20:57:50 +00001332 if (ignore_qualifiers) {
1333 type1_qual = type1_qual.getUnqualifiedType();
1334 type2_qual = type2_qual.getUnqualifiedType();
1335 }
1336
1337 return ast->getASTContext()->hasSameType(type1_qual, type2_qual);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001338}
1339
Alex Langfordcb68bd72019-08-23 06:11:32 +00001340CompilerType ClangASTContext::GetTypeForDecl(void *opaque_decl) {
1341 if (!opaque_decl)
1342 return CompilerType();
1343
1344 clang::Decl *decl = static_cast<clang::Decl *>(opaque_decl);
1345 if (auto *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl))
1346 return GetTypeForDecl(named_decl);
1347 return CompilerType();
1348}
1349
Kate Stoneb9c1b512016-09-06 20:57:50 +00001350CompilerType ClangASTContext::GetTypeForDecl(clang::NamedDecl *decl) {
1351 if (clang::ObjCInterfaceDecl *interface_decl =
1352 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
1353 return GetTypeForDecl(interface_decl);
1354 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
1355 return GetTypeForDecl(tag_decl);
1356 return CompilerType();
Sean Callanan9998acd2014-12-05 01:21:59 +00001357}
1358
Kate Stoneb9c1b512016-09-06 20:57:50 +00001359CompilerType ClangASTContext::GetTypeForDecl(TagDecl *decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00001360 // No need to call the getASTContext() accessor (which can create the AST if
1361 // it isn't created yet, because we can't have created a decl in this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001362 // AST if our AST didn't already exist...
1363 ASTContext *ast = &decl->getASTContext();
1364 if (ast)
Alex Langfordbddab072019-08-13 19:40:36 +00001365 return CompilerType(ClangASTContext::GetASTContext(ast),
1366 ast->getTagDeclType(decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001367 return CompilerType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00001368}
1369
Kate Stoneb9c1b512016-09-06 20:57:50 +00001370CompilerType ClangASTContext::GetTypeForDecl(ObjCInterfaceDecl *decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00001371 // No need to call the getASTContext() accessor (which can create the AST if
1372 // it isn't created yet, because we can't have created a decl in this
Kate Stoneb9c1b512016-09-06 20:57:50 +00001373 // AST if our AST didn't already exist...
1374 ASTContext *ast = &decl->getASTContext();
1375 if (ast)
Alex Langfordbddab072019-08-13 19:40:36 +00001376 return CompilerType(ClangASTContext::GetASTContext(ast),
1377 ast->getObjCInterfaceType(decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001378 return CompilerType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00001379}
1380
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001381#pragma mark Structure, Unions, Classes
1382
Kate Stoneb9c1b512016-09-06 20:57:50 +00001383CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx,
1384 AccessType access_type,
1385 const char *name, int kind,
1386 LanguageType language,
1387 ClangASTMetadata *metadata) {
1388 ASTContext *ast = getASTContext();
1389 assert(ast != nullptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001390
Kate Stoneb9c1b512016-09-06 20:57:50 +00001391 if (decl_ctx == nullptr)
1392 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton9e409562010-07-28 02:04:09 +00001393
Kate Stoneb9c1b512016-09-06 20:57:50 +00001394 if (language == eLanguageTypeObjC ||
1395 language == eLanguageTypeObjC_plus_plus) {
1396 bool isForwardDecl = true;
1397 bool isInternal = false;
1398 return CreateObjCClass(name, decl_ctx, isForwardDecl, isInternal, metadata);
1399 }
Greg Clayton9e409562010-07-28 02:04:09 +00001400
Kate Stoneb9c1b512016-09-06 20:57:50 +00001401 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
Adrian Prantl05097242018-04-30 16:49:04 +00001402 // we will need to update this code. I was told to currently always use the
1403 // CXXRecordDecl class since we often don't know from debug information if
1404 // something is struct or a class, so we default to always use the more
Kate Stoneb9c1b512016-09-06 20:57:50 +00001405 // complete definition just in case.
Greg Claytonc4ffd662013-03-08 01:37:30 +00001406
Shafik Yaghmour62abe492019-08-14 22:30:29 +00001407 bool has_name = name && name[0];
Greg Claytonc4ffd662013-03-08 01:37:30 +00001408
Kate Stoneb9c1b512016-09-06 20:57:50 +00001409 CXXRecordDecl *decl = CXXRecordDecl::Create(
1410 *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
Shafik Yaghmour62abe492019-08-14 22:30:29 +00001411 SourceLocation(), has_name ? &ast->Idents.get(name) : nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001412
Shafik Yaghmour62abe492019-08-14 22:30:29 +00001413 if (!has_name) {
1414 // In C++ a lambda is also represented as an unnamed class. This is
1415 // different from an *anonymous class* that the user wrote:
1416 //
1417 // struct A {
1418 // // anonymous class (GNU/MSVC extension)
1419 // struct {
1420 // int x;
1421 // };
1422 // // unnamed class within a class
1423 // struct {
1424 // int y;
1425 // } B;
1426 // };
1427 //
1428 // void f() {
1429 // // unammed class outside of a class
1430 // struct {
1431 // int z;
1432 // } C;
1433 // }
1434 //
1435 // Anonymous classes is a GNU/MSVC extension that clang supports. It
1436 // requires the anonymous class be embedded within a class. So the new
1437 // heuristic verifies this condition.
1438 //
1439 // FIXME: An unnamed class within a class is also wrongly recognized as an
1440 // anonymous struct.
Pavel Labath9cb31792019-08-21 08:22:19 +00001441 if (isa<CXXRecordDecl>(decl_ctx))
Shafik Yaghmour62abe492019-08-14 22:30:29 +00001442 decl->setAnonymousStructOrUnion(true);
Shafik Yaghmour62abe492019-08-14 22:30:29 +00001443 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001444
1445 if (decl) {
1446 if (metadata)
1447 SetMetadata(ast, decl, *metadata);
1448
1449 if (access_type != eAccessNone)
1450 decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type));
1451
1452 if (decl_ctx)
1453 decl_ctx->addDecl(decl);
1454
Alex Langfordbddab072019-08-13 19:40:36 +00001455 return CompilerType(this, ast->getTagDeclType(decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001456 }
1457 return CompilerType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00001458}
1459
Sean Callanan09e91ac2017-05-11 22:08:05 +00001460namespace {
1461 bool IsValueParam(const clang::TemplateArgument &argument) {
1462 return argument.getKind() == TemplateArgument::Integral;
1463 }
1464}
1465
Kate Stoneb9c1b512016-09-06 20:57:50 +00001466static TemplateParameterList *CreateTemplateParameterList(
1467 ASTContext *ast,
1468 const ClangASTContext::TemplateParameterInfos &template_param_infos,
1469 llvm::SmallVector<NamedDecl *, 8> &template_param_decls) {
1470 const bool parameter_pack = false;
1471 const bool is_typename = false;
1472 const unsigned depth = 0;
Sean Callanan09e91ac2017-05-11 22:08:05 +00001473 const size_t num_template_params = template_param_infos.args.size();
1474 DeclContext *const decl_context =
1475 ast->getTranslationUnitDecl(); // Is this the right decl context?,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001476 for (size_t i = 0; i < num_template_params; ++i) {
1477 const char *name = template_param_infos.names[i];
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001478
Kate Stoneb9c1b512016-09-06 20:57:50 +00001479 IdentifierInfo *identifier_info = nullptr;
1480 if (name && name[0])
1481 identifier_info = &ast->Idents.get(name);
Sean Callanan09e91ac2017-05-11 22:08:05 +00001482 if (IsValueParam(template_param_infos.args[i])) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001483 template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
Sean Callanan09e91ac2017-05-11 22:08:05 +00001484 *ast, decl_context,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001485 SourceLocation(), SourceLocation(), depth, i, identifier_info,
1486 template_param_infos.args[i].getIntegralType(), parameter_pack,
1487 nullptr));
1488
1489 } else {
1490 template_param_decls.push_back(TemplateTypeParmDecl::Create(
Sean Callanan09e91ac2017-05-11 22:08:05 +00001491 *ast, decl_context,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001492 SourceLocation(), SourceLocation(), depth, i, identifier_info,
1493 is_typename, parameter_pack));
1494 }
1495 }
Eugene Zemtsova9d928c2017-09-29 03:15:08 +00001496
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001497 if (template_param_infos.packed_args) {
Sean Callanan09e91ac2017-05-11 22:08:05 +00001498 IdentifierInfo *identifier_info = nullptr;
1499 if (template_param_infos.pack_name && template_param_infos.pack_name[0])
1500 identifier_info = &ast->Idents.get(template_param_infos.pack_name);
1501 const bool parameter_pack_true = true;
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001502
1503 if (!template_param_infos.packed_args->args.empty() &&
1504 IsValueParam(template_param_infos.packed_args->args[0])) {
Sean Callanan09e91ac2017-05-11 22:08:05 +00001505 template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001506 *ast, decl_context, SourceLocation(), SourceLocation(), depth,
1507 num_template_params, identifier_info,
Sean Callanan09e91ac2017-05-11 22:08:05 +00001508 template_param_infos.packed_args->args[0].getIntegralType(),
1509 parameter_pack_true, nullptr));
1510 } else {
1511 template_param_decls.push_back(TemplateTypeParmDecl::Create(
Shafik Yaghmour1849dd42019-01-30 21:48:56 +00001512 *ast, decl_context, SourceLocation(), SourceLocation(), depth,
1513 num_template_params, identifier_info, is_typename,
1514 parameter_pack_true));
Sean Callanan09e91ac2017-05-11 22:08:05 +00001515 }
1516 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001517 clang::Expr *const requires_clause = nullptr; // TODO: Concepts
1518 TemplateParameterList *template_param_list = TemplateParameterList::Create(
1519 *ast, SourceLocation(), SourceLocation(), template_param_decls,
1520 SourceLocation(), requires_clause);
1521 return template_param_list;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001522}
1523
Kate Stoneb9c1b512016-09-06 20:57:50 +00001524clang::FunctionTemplateDecl *ClangASTContext::CreateFunctionTemplateDecl(
1525 clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl,
1526 const char *name, const TemplateParameterInfos &template_param_infos) {
Adrian Prantld8f460e2018-05-02 16:55:16 +00001527 // /// Create a function template node.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001528 ASTContext *ast = getASTContext();
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001529
Kate Stoneb9c1b512016-09-06 20:57:50 +00001530 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001531
Kate Stoneb9c1b512016-09-06 20:57:50 +00001532 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1533 ast, template_param_infos, template_param_decls);
1534 FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create(
1535 *ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(),
1536 template_param_list, func_decl);
1537
1538 for (size_t i = 0, template_param_decl_count = template_param_decls.size();
1539 i < template_param_decl_count; ++i) {
1540 // TODO: verify which decl context we should put template_param_decls into..
1541 template_param_decls[i]->setDeclContext(func_decl);
1542 }
1543
1544 return func_tmpl_decl;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001545}
1546
Kate Stoneb9c1b512016-09-06 20:57:50 +00001547void ClangASTContext::CreateFunctionTemplateSpecializationInfo(
1548 FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl,
1549 const TemplateParameterInfos &infos) {
Shafik Yaghmoura0858e22019-07-17 20:16:13 +00001550 TemplateArgumentList *template_args_ptr =
1551 TemplateArgumentList::CreateCopy(func_decl->getASTContext(), infos.args);
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001552
Shafik Yaghmoura0858e22019-07-17 20:16:13 +00001553 func_decl->setFunctionTemplateSpecialization(func_tmpl_decl,
1554 template_args_ptr, nullptr);
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001555}
1556
Kate Stoneb9c1b512016-09-06 20:57:50 +00001557ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl(
1558 DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name,
1559 int kind, const TemplateParameterInfos &template_param_infos) {
1560 ASTContext *ast = getASTContext();
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001561
Kate Stoneb9c1b512016-09-06 20:57:50 +00001562 ClassTemplateDecl *class_template_decl = nullptr;
1563 if (decl_ctx == nullptr)
1564 decl_ctx = ast->getTranslationUnitDecl();
Greg Claytonf0705c82011-10-22 03:33:13 +00001565
Kate Stoneb9c1b512016-09-06 20:57:50 +00001566 IdentifierInfo &identifier_info = ast->Idents.get(class_name);
1567 DeclarationName decl_name(&identifier_info);
Greg Claytonf0705c82011-10-22 03:33:13 +00001568
Kate Stoneb9c1b512016-09-06 20:57:50 +00001569 clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
Greg Claytonf0705c82011-10-22 03:33:13 +00001570
Kate Stoneb9c1b512016-09-06 20:57:50 +00001571 for (NamedDecl *decl : result) {
1572 class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
Greg Claytonf0705c82011-10-22 03:33:13 +00001573 if (class_template_decl)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001574 return class_template_decl;
1575 }
1576
1577 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
1578
1579 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1580 ast, template_param_infos, template_param_decls);
1581
1582 CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create(
1583 *ast, (TagDecl::TagKind)kind,
1584 decl_ctx, // What decl context do we use here? TU? The actual decl
1585 // context?
1586 SourceLocation(), SourceLocation(), &identifier_info);
1587
1588 for (size_t i = 0, template_param_decl_count = template_param_decls.size();
1589 i < template_param_decl_count; ++i) {
1590 template_param_decls[i]->setDeclContext(template_cxx_decl);
1591 }
1592
1593 // With templated classes, we say that a class is templated with
1594 // specializations, but that the bare class has no functions.
1595 // template_cxx_decl->startDefinition();
1596 // template_cxx_decl->completeDefinition();
1597
1598 class_template_decl = ClassTemplateDecl::Create(
1599 *ast,
1600 decl_ctx, // What decl context do we use here? TU? The actual decl
1601 // context?
Pavel Labath4294de32017-01-12 10:44:16 +00001602 SourceLocation(), decl_name, template_param_list, template_cxx_decl);
Richard Smith35b007e2019-02-15 21:48:09 +00001603 template_cxx_decl->setDescribedClassTemplate(class_template_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001604
1605 if (class_template_decl) {
1606 if (access_type != eAccessNone)
1607 class_template_decl->setAccess(
1608 ConvertAccessTypeToAccessSpecifier(access_type));
1609
1610 // if (TagDecl *ctx_tag_decl = dyn_cast<TagDecl>(decl_ctx))
1611 // CompleteTagDeclarationDefinition(GetTypeForDecl(ctx_tag_decl));
1612
1613 decl_ctx->addDecl(class_template_decl);
1614
Sean Callanan5e9e1992011-10-26 01:06:27 +00001615#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00001616 VerifyDecl(class_template_decl);
Sean Callanan5e9e1992011-10-26 01:06:27 +00001617#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00001618 }
Greg Claytonf0705c82011-10-22 03:33:13 +00001619
Kate Stoneb9c1b512016-09-06 20:57:50 +00001620 return class_template_decl;
Greg Claytonf0705c82011-10-22 03:33:13 +00001621}
1622
Frederic Rissf4e7e522018-04-02 16:18:32 +00001623TemplateTemplateParmDecl *
1624ClangASTContext::CreateTemplateTemplateParmDecl(const char *template_name) {
1625 ASTContext *ast = getASTContext();
1626
1627 auto *decl_ctx = ast->getTranslationUnitDecl();
1628
1629 IdentifierInfo &identifier_info = ast->Idents.get(template_name);
1630 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
1631
1632 ClangASTContext::TemplateParameterInfos template_param_infos;
1633 TemplateParameterList *template_param_list = CreateTemplateParameterList(
1634 ast, template_param_infos, template_param_decls);
1635
1636 // LLDB needs to create those decls only to be able to display a
Adrian Prantl05097242018-04-30 16:49:04 +00001637 // type that includes a template template argument. Only the name matters for
1638 // this purpose, so we use dummy values for the other characterisitcs of the
1639 // type.
Frederic Rissf4e7e522018-04-02 16:18:32 +00001640 return TemplateTemplateParmDecl::Create(
1641 *ast, decl_ctx, SourceLocation(),
1642 /*Depth*/ 0, /*Position*/ 0,
1643 /*IsParameterPack*/ false, &identifier_info, template_param_list);
1644}
1645
Greg Claytonf0705c82011-10-22 03:33:13 +00001646ClassTemplateSpecializationDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001647ClangASTContext::CreateClassTemplateSpecializationDecl(
1648 DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
1649 const TemplateParameterInfos &template_param_infos) {
1650 ASTContext *ast = getASTContext();
Sean Callanan09e91ac2017-05-11 22:08:05 +00001651 llvm::SmallVector<clang::TemplateArgument, 2> args(
1652 template_param_infos.args.size() +
1653 (template_param_infos.packed_args ? 1 : 0));
1654 std::copy(template_param_infos.args.begin(), template_param_infos.args.end(),
1655 args.begin());
1656 if (template_param_infos.packed_args) {
1657 args[args.size() - 1] = TemplateArgument::CreatePackCopy(
1658 *ast, template_param_infos.packed_args->args);
1659 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001660 ClassTemplateSpecializationDecl *class_template_specialization_decl =
1661 ClassTemplateSpecializationDecl::Create(
1662 *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
Sean Callanan09e91ac2017-05-11 22:08:05 +00001663 SourceLocation(), class_template_decl, args,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001664 nullptr);
1665
1666 class_template_specialization_decl->setSpecializationKind(
1667 TSK_ExplicitSpecialization);
1668
1669 return class_template_specialization_decl;
1670}
1671
1672CompilerType ClangASTContext::CreateClassTemplateSpecializationType(
1673 ClassTemplateSpecializationDecl *class_template_specialization_decl) {
1674 if (class_template_specialization_decl) {
Greg Claytonf0705c82011-10-22 03:33:13 +00001675 ASTContext *ast = getASTContext();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001676 if (ast)
1677 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00001678 this, ast->getTagDeclType(class_template_specialization_decl)
1679 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001680 }
1681 return CompilerType();
Greg Claytonf0705c82011-10-22 03:33:13 +00001682}
1683
Kate Stoneb9c1b512016-09-06 20:57:50 +00001684static inline bool check_op_param(bool is_method,
1685 clang::OverloadedOperatorKind op_kind,
1686 bool unary, bool binary,
1687 uint32_t num_params) {
1688 // Special-case call since it can take any number of operands
1689 if (op_kind == OO_Call)
1690 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001691
Kate Stoneb9c1b512016-09-06 20:57:50 +00001692 // The parameter count doesn't include "this"
1693 if (is_method)
1694 ++num_params;
1695 if (num_params == 1)
1696 return unary;
1697 if (num_params == 2)
1698 return binary;
1699 else
Greg Clayton090d0982011-06-19 03:43:27 +00001700 return false;
1701}
Daniel Dunbardacdfb52011-10-31 22:50:57 +00001702
Kate Stoneb9c1b512016-09-06 20:57:50 +00001703bool ClangASTContext::CheckOverloadedOperatorKindParameterCount(
1704 bool is_method, clang::OverloadedOperatorKind op_kind,
1705 uint32_t num_params) {
1706 switch (op_kind) {
1707 default:
1708 break;
1709 // C++ standard allows any number of arguments to new/delete
1710 case OO_New:
1711 case OO_Array_New:
1712 case OO_Delete:
1713 case OO_Array_Delete:
1714 return true;
1715 }
Pavel Labath1ac2b202016-08-15 14:32:32 +00001716
Kate Stoneb9c1b512016-09-06 20:57:50 +00001717#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
1718 case OO_##Name: \
1719 return check_op_param(is_method, op_kind, Unary, Binary, num_params);
1720 switch (op_kind) {
Greg Clayton090d0982011-06-19 03:43:27 +00001721#include "clang/Basic/OperatorKinds.def"
Kate Stoneb9c1b512016-09-06 20:57:50 +00001722 default:
1723 break;
1724 }
1725 return false;
Greg Clayton090d0982011-06-19 03:43:27 +00001726}
1727
Greg Clayton57ee3062013-07-11 22:46:58 +00001728clang::AccessSpecifier
Kate Stoneb9c1b512016-09-06 20:57:50 +00001729ClangASTContext::UnifyAccessSpecifiers(clang::AccessSpecifier lhs,
1730 clang::AccessSpecifier rhs) {
1731 // Make the access equal to the stricter of the field and the nested field's
1732 // access
1733 if (lhs == AS_none || rhs == AS_none)
1734 return AS_none;
1735 if (lhs == AS_private || rhs == AS_private)
1736 return AS_private;
1737 if (lhs == AS_protected || rhs == AS_protected)
1738 return AS_protected;
1739 return AS_public;
Sean Callanane8c0cfb2012-03-02 01:03:45 +00001740}
1741
Kate Stoneb9c1b512016-09-06 20:57:50 +00001742bool ClangASTContext::FieldIsBitfield(FieldDecl *field,
1743 uint32_t &bitfield_bit_size) {
1744 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001745}
1746
Kate Stoneb9c1b512016-09-06 20:57:50 +00001747bool ClangASTContext::FieldIsBitfield(ASTContext *ast, FieldDecl *field,
1748 uint32_t &bitfield_bit_size) {
1749 if (ast == nullptr || field == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001750 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001751
Kate Stoneb9c1b512016-09-06 20:57:50 +00001752 if (field->isBitField()) {
1753 Expr *bit_width_expr = field->getBitWidth();
1754 if (bit_width_expr) {
1755 llvm::APSInt bit_width_apsint;
1756 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast)) {
1757 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001758 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001759 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001760 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001761 }
1762 return false;
1763}
1764
1765bool ClangASTContext::RecordHasFields(const RecordDecl *record_decl) {
1766 if (record_decl == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001767 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001768
1769 if (!record_decl->field_empty())
1770 return true;
1771
1772 // No fields, lets check this is a CXX record and check the base classes
1773 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1774 if (cxx_record_decl) {
1775 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1776 for (base_class = cxx_record_decl->bases_begin(),
1777 base_class_end = cxx_record_decl->bases_end();
1778 base_class != base_class_end; ++base_class) {
1779 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(
1780 base_class->getType()->getAs<RecordType>()->getDecl());
1781 if (RecordHasFields(base_class_decl))
1782 return true;
1783 }
1784 }
1785 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001786}
1787
Adrian Prantl4e8be2c2018-06-13 16:21:24 +00001788#pragma mark Objective-C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001789
Kate Stoneb9c1b512016-09-06 20:57:50 +00001790CompilerType ClangASTContext::CreateObjCClass(const char *name,
1791 DeclContext *decl_ctx,
1792 bool isForwardDecl,
1793 bool isInternal,
1794 ClangASTMetadata *metadata) {
1795 ASTContext *ast = getASTContext();
1796 assert(ast != nullptr);
1797 assert(name && name[0]);
1798 if (decl_ctx == nullptr)
1799 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001800
Kate Stoneb9c1b512016-09-06 20:57:50 +00001801 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create(
1802 *ast, decl_ctx, SourceLocation(), &ast->Idents.get(name), nullptr,
1803 nullptr, SourceLocation(),
1804 /*isForwardDecl,*/
1805 isInternal);
1806
1807 if (decl && metadata)
1808 SetMetadata(ast, decl, *metadata);
1809
Alex Langfordbddab072019-08-13 19:40:36 +00001810 return CompilerType(this, ast->getObjCInterfaceType(decl).getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001811}
1812
Kate Stoneb9c1b512016-09-06 20:57:50 +00001813static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) {
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001814 return !ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001815}
1816
Greg Clayton57ee3062013-07-11 22:46:58 +00001817uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001818ClangASTContext::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl,
1819 bool omit_empty_base_classes) {
1820 uint32_t num_bases = 0;
1821 if (cxx_record_decl) {
1822 if (omit_empty_base_classes) {
1823 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1824 for (base_class = cxx_record_decl->bases_begin(),
1825 base_class_end = cxx_record_decl->bases_end();
1826 base_class != base_class_end; ++base_class) {
1827 // Skip empty base classes
1828 if (omit_empty_base_classes) {
1829 if (BaseSpecifierIsEmpty(base_class))
1830 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001831 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001832 ++num_bases;
1833 }
1834 } else
1835 num_bases = cxx_record_decl->getNumBases();
1836 }
1837 return num_bases;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001838}
1839
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001840#pragma mark Namespace Declarations
1841
Raphael Isemanna9469972019-03-12 07:45:04 +00001842NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration(
1843 const char *name, DeclContext *decl_ctx, bool is_inline) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001844 NamespaceDecl *namespace_decl = nullptr;
1845 ASTContext *ast = getASTContext();
1846 TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl();
1847 if (decl_ctx == nullptr)
1848 decl_ctx = translation_unit_decl;
Greg Clayton030a2042011-10-14 21:34:45 +00001849
Kate Stoneb9c1b512016-09-06 20:57:50 +00001850 if (name) {
1851 IdentifierInfo &identifier_info = ast->Idents.get(name);
1852 DeclarationName decl_name(&identifier_info);
1853 clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
1854 for (NamedDecl *decl : result) {
1855 namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
1856 if (namespace_decl)
1857 return namespace_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001858 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001859
1860 namespace_decl =
Raphael Isemanna9469972019-03-12 07:45:04 +00001861 NamespaceDecl::Create(*ast, decl_ctx, is_inline, SourceLocation(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00001862 SourceLocation(), &identifier_info, nullptr);
1863
1864 decl_ctx->addDecl(namespace_decl);
1865 } else {
1866 if (decl_ctx == translation_unit_decl) {
1867 namespace_decl = translation_unit_decl->getAnonymousNamespace();
1868 if (namespace_decl)
1869 return namespace_decl;
1870
1871 namespace_decl =
1872 NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
1873 SourceLocation(), nullptr, nullptr);
1874 translation_unit_decl->setAnonymousNamespace(namespace_decl);
1875 translation_unit_decl->addDecl(namespace_decl);
1876 assert(namespace_decl == translation_unit_decl->getAnonymousNamespace());
1877 } else {
1878 NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
1879 if (parent_namespace_decl) {
1880 namespace_decl = parent_namespace_decl->getAnonymousNamespace();
1881 if (namespace_decl)
1882 return namespace_decl;
1883 namespace_decl =
1884 NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
1885 SourceLocation(), nullptr, nullptr);
1886 parent_namespace_decl->setAnonymousNamespace(namespace_decl);
1887 parent_namespace_decl->addDecl(namespace_decl);
1888 assert(namespace_decl ==
1889 parent_namespace_decl->getAnonymousNamespace());
1890 } else {
Raphael Isemannc4944812019-07-04 19:49:31 +00001891 assert(false && "GetUniqueNamespaceDeclaration called with no name and "
1892 "no namespace as decl_ctx");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001893 }
Greg Clayton9d3d6882011-10-31 23:51:19 +00001894 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001895 }
Greg Clayton9d3d6882011-10-31 23:51:19 +00001896#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00001897 VerifyDecl(namespace_decl);
Greg Clayton9d3d6882011-10-31 23:51:19 +00001898#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00001899 return namespace_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001900}
1901
Kate Stoneb9c1b512016-09-06 20:57:50 +00001902NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration(
Raphael Isemanna9469972019-03-12 07:45:04 +00001903 clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx,
1904 bool is_inline) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001905 ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast);
1906 if (ast_ctx == nullptr)
1907 return nullptr;
Siva Chandra03ff5c82016-02-05 19:10:04 +00001908
Raphael Isemanna9469972019-03-12 07:45:04 +00001909 return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx, is_inline);
Siva Chandra03ff5c82016-02-05 19:10:04 +00001910}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001911
Paul Hermand628cbb2015-09-15 23:44:17 +00001912clang::BlockDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001913ClangASTContext::CreateBlockDeclaration(clang::DeclContext *ctx) {
1914 if (ctx != nullptr) {
1915 clang::BlockDecl *decl = clang::BlockDecl::Create(*getASTContext(), ctx,
1916 clang::SourceLocation());
1917 ctx->addDecl(decl);
1918 return decl;
1919 }
1920 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00001921}
1922
Kate Stoneb9c1b512016-09-06 20:57:50 +00001923clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left,
1924 clang::DeclContext *right,
1925 clang::DeclContext *root) {
1926 if (root == nullptr)
Paul Hermanea188fc2015-09-16 18:48:30 +00001927 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001928
1929 std::set<clang::DeclContext *> path_left;
1930 for (clang::DeclContext *d = left; d != nullptr; d = d->getParent())
1931 path_left.insert(d);
1932
1933 for (clang::DeclContext *d = right; d != nullptr; d = d->getParent())
1934 if (path_left.find(d) != path_left.end())
1935 return d;
1936
1937 return nullptr;
Paul Hermanea188fc2015-09-16 18:48:30 +00001938}
1939
Kate Stoneb9c1b512016-09-06 20:57:50 +00001940clang::UsingDirectiveDecl *ClangASTContext::CreateUsingDirectiveDeclaration(
1941 clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) {
1942 if (decl_ctx != nullptr && ns_decl != nullptr) {
1943 clang::TranslationUnitDecl *translation_unit =
1944 (clang::TranslationUnitDecl *)GetTranslationUnitDecl(getASTContext());
1945 clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
1946 *getASTContext(), decl_ctx, clang::SourceLocation(),
1947 clang::SourceLocation(), clang::NestedNameSpecifierLoc(),
1948 clang::SourceLocation(), ns_decl,
1949 FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit));
1950 decl_ctx->addDecl(using_decl);
1951 return using_decl;
1952 }
1953 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00001954}
1955
1956clang::UsingDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00001957ClangASTContext::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
1958 clang::NamedDecl *target) {
1959 if (current_decl_ctx != nullptr && target != nullptr) {
1960 clang::UsingDecl *using_decl = clang::UsingDecl::Create(
1961 *getASTContext(), current_decl_ctx, clang::SourceLocation(),
1962 clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
1963 clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
1964 *getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
1965 target);
1966 using_decl->addShadowDecl(shadow_decl);
1967 current_decl_ctx->addDecl(using_decl);
1968 return using_decl;
1969 }
1970 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00001971}
1972
Kate Stoneb9c1b512016-09-06 20:57:50 +00001973clang::VarDecl *ClangASTContext::CreateVariableDeclaration(
1974 clang::DeclContext *decl_context, const char *name, clang::QualType type) {
1975 if (decl_context != nullptr) {
1976 clang::VarDecl *var_decl = clang::VarDecl::Create(
1977 *getASTContext(), decl_context, clang::SourceLocation(),
1978 clang::SourceLocation(),
1979 name && name[0] ? &getASTContext()->Idents.getOwn(name) : nullptr, type,
1980 nullptr, clang::SC_None);
1981 var_decl->setAccess(clang::AS_public);
1982 decl_context->addDecl(var_decl);
1983 return var_decl;
1984 }
1985 return nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00001986}
1987
Zachary Turner9d8a97e2016-04-01 23:20:35 +00001988lldb::opaque_compiler_type_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001989ClangASTContext::GetOpaqueCompilerType(clang::ASTContext *ast,
1990 lldb::BasicType basic_type) {
1991 switch (basic_type) {
1992 case eBasicTypeVoid:
1993 return ast->VoidTy.getAsOpaquePtr();
1994 case eBasicTypeChar:
1995 return ast->CharTy.getAsOpaquePtr();
1996 case eBasicTypeSignedChar:
1997 return ast->SignedCharTy.getAsOpaquePtr();
1998 case eBasicTypeUnsignedChar:
1999 return ast->UnsignedCharTy.getAsOpaquePtr();
2000 case eBasicTypeWChar:
2001 return ast->getWCharType().getAsOpaquePtr();
2002 case eBasicTypeSignedWChar:
2003 return ast->getSignedWCharType().getAsOpaquePtr();
2004 case eBasicTypeUnsignedWChar:
2005 return ast->getUnsignedWCharType().getAsOpaquePtr();
2006 case eBasicTypeChar16:
2007 return ast->Char16Ty.getAsOpaquePtr();
2008 case eBasicTypeChar32:
2009 return ast->Char32Ty.getAsOpaquePtr();
2010 case eBasicTypeShort:
2011 return ast->ShortTy.getAsOpaquePtr();
2012 case eBasicTypeUnsignedShort:
2013 return ast->UnsignedShortTy.getAsOpaquePtr();
2014 case eBasicTypeInt:
2015 return ast->IntTy.getAsOpaquePtr();
2016 case eBasicTypeUnsignedInt:
2017 return ast->UnsignedIntTy.getAsOpaquePtr();
2018 case eBasicTypeLong:
2019 return ast->LongTy.getAsOpaquePtr();
2020 case eBasicTypeUnsignedLong:
2021 return ast->UnsignedLongTy.getAsOpaquePtr();
2022 case eBasicTypeLongLong:
2023 return ast->LongLongTy.getAsOpaquePtr();
2024 case eBasicTypeUnsignedLongLong:
2025 return ast->UnsignedLongLongTy.getAsOpaquePtr();
2026 case eBasicTypeInt128:
2027 return ast->Int128Ty.getAsOpaquePtr();
2028 case eBasicTypeUnsignedInt128:
2029 return ast->UnsignedInt128Ty.getAsOpaquePtr();
2030 case eBasicTypeBool:
2031 return ast->BoolTy.getAsOpaquePtr();
2032 case eBasicTypeHalf:
2033 return ast->HalfTy.getAsOpaquePtr();
2034 case eBasicTypeFloat:
2035 return ast->FloatTy.getAsOpaquePtr();
2036 case eBasicTypeDouble:
2037 return ast->DoubleTy.getAsOpaquePtr();
2038 case eBasicTypeLongDouble:
2039 return ast->LongDoubleTy.getAsOpaquePtr();
2040 case eBasicTypeFloatComplex:
2041 return ast->FloatComplexTy.getAsOpaquePtr();
2042 case eBasicTypeDoubleComplex:
2043 return ast->DoubleComplexTy.getAsOpaquePtr();
2044 case eBasicTypeLongDoubleComplex:
2045 return ast->LongDoubleComplexTy.getAsOpaquePtr();
2046 case eBasicTypeObjCID:
2047 return ast->getObjCIdType().getAsOpaquePtr();
2048 case eBasicTypeObjCClass:
2049 return ast->getObjCClassType().getAsOpaquePtr();
2050 case eBasicTypeObjCSel:
2051 return ast->getObjCSelType().getAsOpaquePtr();
2052 case eBasicTypeNullPtr:
2053 return ast->NullPtrTy.getAsOpaquePtr();
2054 default:
2055 return nullptr;
2056 }
Zachary Turner9d8a97e2016-04-01 23:20:35 +00002057}
2058
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002059#pragma mark Function Types
2060
Pavel Labath1ac2b202016-08-15 14:32:32 +00002061clang::DeclarationName
Kate Stoneb9c1b512016-09-06 20:57:50 +00002062ClangASTContext::GetDeclarationName(const char *name,
2063 const CompilerType &function_clang_type) {
2064 if (!name || !name[0])
2065 return clang::DeclarationName();
Pavel Labath1ac2b202016-08-15 14:32:32 +00002066
Kate Stoneb9c1b512016-09-06 20:57:50 +00002067 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
2068 if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS)
2069 return DeclarationName(&getASTContext()->Idents.get(
2070 name)); // Not operator, but a regular function.
Pavel Labath1ac2b202016-08-15 14:32:32 +00002071
Adrian Prantl05097242018-04-30 16:49:04 +00002072 // Check the number of operator parameters. Sometimes we have seen bad DWARF
2073 // that doesn't correctly describe operators and if we try to create a method
2074 // and add it to the class, clang will assert and crash, so we need to make
2075 // sure things are acceptable.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002076 clang::QualType method_qual_type(ClangUtil::GetQualType(function_clang_type));
2077 const clang::FunctionProtoType *function_type =
2078 llvm::dyn_cast<clang::FunctionProtoType>(method_qual_type.getTypePtr());
2079 if (function_type == nullptr)
2080 return clang::DeclarationName();
Pavel Labath1ac2b202016-08-15 14:32:32 +00002081
Kate Stoneb9c1b512016-09-06 20:57:50 +00002082 const bool is_method = false;
2083 const unsigned int num_params = function_type->getNumParams();
2084 if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
2085 is_method, op_kind, num_params))
2086 return clang::DeclarationName();
Pavel Labath1ac2b202016-08-15 14:32:32 +00002087
Kate Stoneb9c1b512016-09-06 20:57:50 +00002088 return getASTContext()->DeclarationNames.getCXXOperatorName(op_kind);
Pavel Labath1ac2b202016-08-15 14:32:32 +00002089}
2090
Kate Stoneb9c1b512016-09-06 20:57:50 +00002091FunctionDecl *ClangASTContext::CreateFunctionDeclaration(
2092 DeclContext *decl_ctx, const char *name,
2093 const CompilerType &function_clang_type, int storage, bool is_inline) {
2094 FunctionDecl *func_decl = nullptr;
2095 ASTContext *ast = getASTContext();
2096 if (decl_ctx == nullptr)
2097 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002098
Kate Stoneb9c1b512016-09-06 20:57:50 +00002099 const bool hasWrittenPrototype = true;
2100 const bool isConstexprSpecified = false;
Greg Clayton0d551042013-06-28 21:08:47 +00002101
Kate Stoneb9c1b512016-09-06 20:57:50 +00002102 clang::DeclarationName declarationName =
2103 GetDeclarationName(name, function_clang_type);
2104 func_decl = FunctionDecl::Create(
2105 *ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName,
2106 ClangUtil::GetQualType(function_clang_type), nullptr,
2107 (clang::StorageClass)storage, is_inline, hasWrittenPrototype,
Gauthier Harnisch796ed032019-06-14 08:56:20 +00002108 isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002109 if (func_decl)
2110 decl_ctx->addDecl(func_decl);
2111
Sean Callanan5e9e1992011-10-26 01:06:27 +00002112#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00002113 VerifyDecl(func_decl);
Sean Callanan5e9e1992011-10-26 01:06:27 +00002114#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00002115
2116 return func_decl;
2117}
2118
2119CompilerType ClangASTContext::CreateFunctionType(
2120 ASTContext *ast, const CompilerType &result_type, const CompilerType *args,
Aleksandr Urakovbc4707c2018-09-26 09:03:34 +00002121 unsigned num_args, bool is_variadic, unsigned type_quals,
2122 clang::CallingConv cc) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002123 if (ast == nullptr)
2124 return CompilerType(); // invalid AST
2125
2126 if (!result_type || !ClangUtil::IsClangType(result_type))
2127 return CompilerType(); // invalid return type
2128
2129 std::vector<QualType> qual_type_args;
2130 if (num_args > 0 && args == nullptr)
2131 return CompilerType(); // invalid argument array passed in
2132
2133 // Verify that all arguments are valid and the right type
2134 for (unsigned i = 0; i < num_args; ++i) {
2135 if (args[i]) {
2136 // Make sure we have a clang type in args[i] and not a type from another
2137 // language whose name might match
2138 const bool is_clang_type = ClangUtil::IsClangType(args[i]);
2139 lldbassert(is_clang_type);
2140 if (is_clang_type)
2141 qual_type_args.push_back(ClangUtil::GetQualType(args[i]));
2142 else
2143 return CompilerType(); // invalid argument type (must be a clang type)
2144 } else
2145 return CompilerType(); // invalid argument type (empty)
2146 }
2147
2148 // TODO: Detect calling convention in DWARF?
2149 FunctionProtoType::ExtProtoInfo proto_info;
Aleksandr Urakovbc4707c2018-09-26 09:03:34 +00002150 proto_info.ExtInfo = cc;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002151 proto_info.Variadic = is_variadic;
2152 proto_info.ExceptionSpec = EST_None;
Mikael Nilsson8b3bf6c2018-12-13 10:17:26 +00002153 proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002154 proto_info.RefQualifier = RQ_None;
2155
Alex Langfordbddab072019-08-13 19:40:36 +00002156 return CompilerType(ClangASTContext::GetASTContext(ast),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002157 ast->getFunctionType(ClangUtil::GetQualType(result_type),
Alex Langfordbddab072019-08-13 19:40:36 +00002158 qual_type_args, proto_info).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002159}
2160
2161ParmVarDecl *ClangASTContext::CreateParameterDeclaration(
Zachary Turner6753d2d2018-12-12 17:17:53 +00002162 clang::DeclContext *decl_ctx, const char *name,
Shafik Yaghmourfa5c3402019-08-02 21:41:50 +00002163 const CompilerType &param_type, int storage, bool add_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002164 ASTContext *ast = getASTContext();
2165 assert(ast != nullptr);
Zachary Turnerd3d2b9b2018-12-13 18:17:51 +00002166 auto *decl =
2167 ParmVarDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(),
2168 name && name[0] ? &ast->Idents.get(name) : nullptr,
2169 ClangUtil::GetQualType(param_type), nullptr,
2170 (clang::StorageClass)storage, nullptr);
Shafik Yaghmourfa5c3402019-08-02 21:41:50 +00002171 if (add_decl)
2172 decl_ctx->addDecl(decl);
2173
Zachary Turnerd3d2b9b2018-12-13 18:17:51 +00002174 return decl;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002175}
2176
2177void ClangASTContext::SetFunctionParameters(FunctionDecl *function_decl,
2178 ParmVarDecl **params,
2179 unsigned num_params) {
2180 if (function_decl)
2181 function_decl->setParams(ArrayRef<ParmVarDecl *>(params, num_params));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002182}
2183
Greg Claytona1e5dc82015-08-11 22:53:00 +00002184CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00002185ClangASTContext::CreateBlockPointerType(const CompilerType &function_type) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +00002186 QualType block_type = m_ast_up->getBlockPointerType(
Kate Stoneb9c1b512016-09-06 20:57:50 +00002187 clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType()));
Greg Claytonceeb5212016-05-26 22:33:25 +00002188
Kate Stoneb9c1b512016-09-06 20:57:50 +00002189 return CompilerType(this, block_type.getAsOpaquePtr());
Sean Callananc530ba92016-05-02 21:15:31 +00002190}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002191
2192#pragma mark Array Types
2193
Kate Stoneb9c1b512016-09-06 20:57:50 +00002194CompilerType ClangASTContext::CreateArrayType(const CompilerType &element_type,
2195 size_t element_count,
2196 bool is_vector) {
2197 if (element_type.IsValid()) {
2198 ASTContext *ast = getASTContext();
2199 assert(ast != nullptr);
Greg Clayton4ef877f2012-12-06 02:33:54 +00002200
Kate Stoneb9c1b512016-09-06 20:57:50 +00002201 if (is_vector) {
2202 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00002203 this, ast->getExtVectorType(ClangUtil::GetQualType(element_type),
2204 element_count)
2205 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002206 } else {
2207
2208 llvm::APInt ap_element_count(64, element_count);
2209 if (element_count == 0) {
Alex Langfordbddab072019-08-13 19:40:36 +00002210 return CompilerType(this, ast->getIncompleteArrayType(
2211 ClangUtil::GetQualType(element_type),
2212 clang::ArrayType::Normal, 0)
2213 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002214 } else {
Alex Langfordbddab072019-08-13 19:40:36 +00002215 return CompilerType(this, ast->getConstantArrayType(
2216 ClangUtil::GetQualType(element_type),
2217 ap_element_count,
2218 clang::ArrayType::Normal, 0)
2219 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002220 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002221 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002222 }
2223 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002224}
2225
Kate Stoneb9c1b512016-09-06 20:57:50 +00002226CompilerType ClangASTContext::CreateStructForIdentifier(
Adrian Prantl0e4c4822019-03-06 21:22:25 +00002227 ConstString type_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002228 const std::initializer_list<std::pair<const char *, CompilerType>>
2229 &type_fields,
2230 bool packed) {
2231 CompilerType type;
2232 if (!type_name.IsEmpty() &&
2233 (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name))
2234 .IsValid()) {
Pavel Labathf31c9d22017-01-05 13:18:42 +00002235 lldbassert(0 && "Trying to create a type for an existing name");
Enrico Granata76b08d52014-10-29 23:08:02 +00002236 return type;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002237 }
2238
2239 type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(),
2240 clang::TTK_Struct, lldb::eLanguageTypeC);
2241 StartTagDeclarationDefinition(type);
2242 for (const auto &field : type_fields)
2243 AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic,
2244 0);
2245 if (packed)
2246 SetIsPacked(type);
2247 CompleteTagDeclarationDefinition(type);
2248 return type;
Enrico Granata76b08d52014-10-29 23:08:02 +00002249}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002250
Kate Stoneb9c1b512016-09-06 20:57:50 +00002251CompilerType ClangASTContext::GetOrCreateStructForIdentifier(
Adrian Prantl0e4c4822019-03-06 21:22:25 +00002252 ConstString type_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002253 const std::initializer_list<std::pair<const char *, CompilerType>>
2254 &type_fields,
2255 bool packed) {
2256 CompilerType type;
2257 if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
2258 return type;
Sean Callananc530ba92016-05-02 21:15:31 +00002259
Kate Stoneb9c1b512016-09-06 20:57:50 +00002260 return CreateStructForIdentifier(type_name, type_fields, packed);
Sean Callananc530ba92016-05-02 21:15:31 +00002261}
2262
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002263#pragma mark Enumeration Types
2264
Greg Claytona1e5dc82015-08-11 22:53:00 +00002265CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00002266ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
2267 const Declaration &decl,
Tamas Berghammer59765832017-11-07 10:39:22 +00002268 const CompilerType &integer_clang_type,
2269 bool is_scoped) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002270 // TODO: Do something intelligent with the Declaration object passed in
2271 // like maybe filling in the SourceLocation with it...
2272 ASTContext *ast = getASTContext();
Zachary Turnerd133f6a2016-03-28 22:53:41 +00002273
Kate Stoneb9c1b512016-09-06 20:57:50 +00002274 // TODO: ask about these...
Kate Stoneb9c1b512016-09-06 20:57:50 +00002275 // const bool IsFixed = false;
2276
2277 EnumDecl *enum_decl = EnumDecl::Create(
2278 *ast, decl_ctx, SourceLocation(), SourceLocation(),
2279 name && name[0] ? &ast->Idents.get(name) : nullptr, nullptr,
Tamas Berghammercf6bf4c2017-11-07 13:43:55 +00002280 is_scoped, // IsScoped
2281 is_scoped, // IsScopedUsingClassTag
2282 false); // IsFixed
Kate Stoneb9c1b512016-09-06 20:57:50 +00002283
2284 if (enum_decl) {
Aleksandr Urakov709426b2018-09-10 08:08:43 +00002285 if (decl_ctx)
2286 decl_ctx->addDecl(enum_decl);
2287
Kate Stoneb9c1b512016-09-06 20:57:50 +00002288 // TODO: check if we should be setting the promotion type too?
2289 enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
2290
2291 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
2292
Alex Langfordbddab072019-08-13 19:40:36 +00002293 return CompilerType(this, ast->getTagDeclType(enum_decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002294 }
2295 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002296}
2297
Kate Stoneb9c1b512016-09-06 20:57:50 +00002298CompilerType ClangASTContext::GetIntTypeFromBitSize(clang::ASTContext *ast,
2299 size_t bit_size,
2300 bool is_signed) {
2301 if (ast) {
Alex Langfordbddab072019-08-13 19:40:36 +00002302 auto *clang_ast_context = ClangASTContext::GetASTContext(ast);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002303 if (is_signed) {
2304 if (bit_size == ast->getTypeSize(ast->SignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002305 return CompilerType(clang_ast_context,
2306 ast->SignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002307
2308 if (bit_size == ast->getTypeSize(ast->ShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002309 return CompilerType(clang_ast_context, ast->ShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002310
2311 if (bit_size == ast->getTypeSize(ast->IntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002312 return CompilerType(clang_ast_context, ast->IntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002313
2314 if (bit_size == ast->getTypeSize(ast->LongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002315 return CompilerType(clang_ast_context, ast->LongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002316
2317 if (bit_size == ast->getTypeSize(ast->LongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002318 return CompilerType(clang_ast_context,
2319 ast->LongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002320
2321 if (bit_size == ast->getTypeSize(ast->Int128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00002322 return CompilerType(clang_ast_context, ast->Int128Ty.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002323 } else {
2324 if (bit_size == ast->getTypeSize(ast->UnsignedCharTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002325 return CompilerType(clang_ast_context,
2326 ast->UnsignedCharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002327
2328 if (bit_size == ast->getTypeSize(ast->UnsignedShortTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002329 return CompilerType(clang_ast_context,
2330 ast->UnsignedShortTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002331
2332 if (bit_size == ast->getTypeSize(ast->UnsignedIntTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002333 return CompilerType(clang_ast_context,
2334 ast->UnsignedIntTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002335
2336 if (bit_size == ast->getTypeSize(ast->UnsignedLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002337 return CompilerType(clang_ast_context,
2338 ast->UnsignedLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002339
2340 if (bit_size == ast->getTypeSize(ast->UnsignedLongLongTy))
Alex Langfordbddab072019-08-13 19:40:36 +00002341 return CompilerType(clang_ast_context,
2342 ast->UnsignedLongLongTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002343
2344 if (bit_size == ast->getTypeSize(ast->UnsignedInt128Ty))
Alex Langfordbddab072019-08-13 19:40:36 +00002345 return CompilerType(clang_ast_context,
2346 ast->UnsignedInt128Ty.getAsOpaquePtr());
Enrico Granatae8bf7492014-08-15 23:00:02 +00002347 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002348 }
2349 return CompilerType();
Enrico Granatae8bf7492014-08-15 23:00:02 +00002350}
2351
Kate Stoneb9c1b512016-09-06 20:57:50 +00002352CompilerType ClangASTContext::GetPointerSizedIntType(clang::ASTContext *ast,
2353 bool is_signed) {
2354 if (ast)
2355 return GetIntTypeFromBitSize(ast, ast->getTypeSize(ast->VoidPtrTy),
2356 is_signed);
2357 return CompilerType();
Enrico Granatae8bf7492014-08-15 23:00:02 +00002358}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002359
Kate Stoneb9c1b512016-09-06 20:57:50 +00002360void ClangASTContext::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) {
2361 if (decl_ctx) {
2362 DumpDeclContextHiearchy(decl_ctx->getParent());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002363
Kate Stoneb9c1b512016-09-06 20:57:50 +00002364 clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl_ctx);
2365 if (named_decl) {
2366 printf("%20s: %s\n", decl_ctx->getDeclKindName(),
2367 named_decl->getDeclName().getAsString().c_str());
2368 } else {
2369 printf("%20s\n", decl_ctx->getDeclKindName());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002370 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002371 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00002372}
2373
Kate Stoneb9c1b512016-09-06 20:57:50 +00002374void ClangASTContext::DumpDeclHiearchy(clang::Decl *decl) {
2375 if (decl == nullptr)
2376 return;
2377 DumpDeclContextHiearchy(decl->getDeclContext());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002378
Kate Stoneb9c1b512016-09-06 20:57:50 +00002379 clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl);
2380 if (record_decl) {
2381 printf("%20s: %s%s\n", decl->getDeclKindName(),
2382 record_decl->getDeclName().getAsString().c_str(),
2383 record_decl->isInjectedClassName() ? " (injected class name)" : "");
Greg Claytone6b36cd2015-12-08 01:02:08 +00002384
Kate Stoneb9c1b512016-09-06 20:57:50 +00002385 } else {
2386 clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl);
2387 if (named_decl) {
2388 printf("%20s: %s\n", decl->getDeclKindName(),
2389 named_decl->getDeclName().getAsString().c_str());
2390 } else {
2391 printf("%20s\n", decl->getDeclKindName());
Greg Claytone6b36cd2015-12-08 01:02:08 +00002392 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002393 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00002394}
2395
Kate Stoneb9c1b512016-09-06 20:57:50 +00002396bool ClangASTContext::DeclsAreEquivalent(clang::Decl *lhs_decl,
2397 clang::Decl *rhs_decl) {
2398 if (lhs_decl && rhs_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002399 // Make sure the decl kinds match first
Kate Stoneb9c1b512016-09-06 20:57:50 +00002400 const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind();
2401 const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind();
Greg Claytone6b36cd2015-12-08 01:02:08 +00002402
Kate Stoneb9c1b512016-09-06 20:57:50 +00002403 if (lhs_decl_kind == rhs_decl_kind) {
Adrian Prantl05097242018-04-30 16:49:04 +00002404 // Now check that the decl contexts kinds are all equivalent before we
2405 // have to check any names of the decl contexts...
Kate Stoneb9c1b512016-09-06 20:57:50 +00002406 clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
2407 clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
2408 if (lhs_decl_ctx && rhs_decl_ctx) {
Jonas Devlieghere09ad8c82019-05-24 00:44:33 +00002409 while (true) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002410 if (lhs_decl_ctx && rhs_decl_ctx) {
2411 const clang::Decl::Kind lhs_decl_ctx_kind =
2412 lhs_decl_ctx->getDeclKind();
2413 const clang::Decl::Kind rhs_decl_ctx_kind =
2414 rhs_decl_ctx->getDeclKind();
2415 if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) {
2416 lhs_decl_ctx = lhs_decl_ctx->getParent();
2417 rhs_decl_ctx = rhs_decl_ctx->getParent();
Greg Claytone6b36cd2015-12-08 01:02:08 +00002418
Kate Stoneb9c1b512016-09-06 20:57:50 +00002419 if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr)
2420 break;
2421 } else
2422 return false;
2423 } else
Tamas Berghammerfcf334b2015-12-02 11:35:54 +00002424 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002425 }
2426
Kate Stoneb9c1b512016-09-06 20:57:50 +00002427 // Now make sure the name of the decls match
Kate Stoneb9c1b512016-09-06 20:57:50 +00002428 clang::NamedDecl *lhs_named_decl =
2429 llvm::dyn_cast<clang::NamedDecl>(lhs_decl);
2430 clang::NamedDecl *rhs_named_decl =
2431 llvm::dyn_cast<clang::NamedDecl>(rhs_decl);
2432 if (lhs_named_decl && rhs_named_decl) {
2433 clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
2434 clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
2435 if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
2436 if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
2437 return false;
2438 } else
Greg Claytona2721472011-06-25 00:44:06 +00002439 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002440 } else
2441 return false;
Greg Claytona2721472011-06-25 00:44:06 +00002442
Adrian Prantl05097242018-04-30 16:49:04 +00002443 // We know that the decl context kinds all match, so now we need to
2444 // make sure the names match as well
Kate Stoneb9c1b512016-09-06 20:57:50 +00002445 lhs_decl_ctx = lhs_decl->getDeclContext();
2446 rhs_decl_ctx = rhs_decl->getDeclContext();
Jonas Devlieghere09ad8c82019-05-24 00:44:33 +00002447 while (true) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002448 switch (lhs_decl_ctx->getDeclKind()) {
2449 case clang::Decl::TranslationUnit:
2450 // We don't care about the translation unit names
2451 return true;
2452 default: {
2453 clang::NamedDecl *lhs_named_decl =
2454 llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx);
2455 clang::NamedDecl *rhs_named_decl =
2456 llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx);
2457 if (lhs_named_decl && rhs_named_decl) {
2458 clang::DeclarationName lhs_decl_name =
2459 lhs_named_decl->getDeclName();
2460 clang::DeclarationName rhs_decl_name =
2461 rhs_named_decl->getDeclName();
2462 if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
2463 if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
2464 return false;
2465 } else
2466 return false;
2467 } else
2468 return false;
2469 } break;
2470 }
2471 lhs_decl_ctx = lhs_decl_ctx->getParent();
2472 rhs_decl_ctx = rhs_decl_ctx->getParent();
Greg Claytond8d4a572015-08-11 21:38:15 +00002473 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002474 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002475 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002476 }
2477 return false;
2478}
2479bool ClangASTContext::GetCompleteDecl(clang::ASTContext *ast,
2480 clang::Decl *decl) {
2481 if (!decl)
Greg Claytond8d4a572015-08-11 21:38:15 +00002482 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00002483
Kate Stoneb9c1b512016-09-06 20:57:50 +00002484 ExternalASTSource *ast_source = ast->getExternalSource();
Greg Claytond8d4a572015-08-11 21:38:15 +00002485
Kate Stoneb9c1b512016-09-06 20:57:50 +00002486 if (!ast_source)
Greg Claytond8d4a572015-08-11 21:38:15 +00002487 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002488
2489 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) {
2490 if (tag_decl->isCompleteDefinition())
2491 return true;
2492
2493 if (!tag_decl->hasExternalLexicalStorage())
2494 return false;
2495
2496 ast_source->CompleteType(tag_decl);
2497
2498 return !tag_decl->getTypeForDecl()->isIncompleteType();
2499 } else if (clang::ObjCInterfaceDecl *objc_interface_decl =
2500 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) {
2501 if (objc_interface_decl->getDefinition())
2502 return true;
2503
2504 if (!objc_interface_decl->hasExternalLexicalStorage())
2505 return false;
2506
2507 ast_source->CompleteType(objc_interface_decl);
2508
2509 return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
2510 } else {
2511 return false;
2512 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002513}
2514
Kate Stoneb9c1b512016-09-06 20:57:50 +00002515void ClangASTContext::SetMetadataAsUserID(const void *object,
2516 user_id_t user_id) {
2517 ClangASTMetadata meta_data;
2518 meta_data.SetUserID(user_id);
2519 SetMetadata(object, meta_data);
Greg Clayton99558cc42015-08-24 23:46:31 +00002520}
2521
Kate Stoneb9c1b512016-09-06 20:57:50 +00002522void ClangASTContext::SetMetadata(clang::ASTContext *ast, const void *object,
2523 ClangASTMetadata &metadata) {
2524 ClangExternalASTSourceCommon *external_source =
2525 ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
2526
2527 if (external_source)
2528 external_source->SetMetadata(object, metadata);
2529}
2530
2531ClangASTMetadata *ClangASTContext::GetMetadata(clang::ASTContext *ast,
2532 const void *object) {
2533 ClangExternalASTSourceCommon *external_source =
2534 ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
2535
2536 if (external_source && external_source->HasMetadata(object))
2537 return external_source->GetMetadata(object);
2538 else
Greg Claytond8d4a572015-08-11 21:38:15 +00002539 return nullptr;
2540}
2541
Kate Stoneb9c1b512016-09-06 20:57:50 +00002542clang::DeclContext *
2543ClangASTContext::GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl) {
2544 return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
2545}
Greg Claytone6b36cd2015-12-08 01:02:08 +00002546
Kate Stoneb9c1b512016-09-06 20:57:50 +00002547clang::DeclContext *
2548ClangASTContext::GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl) {
2549 return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
2550}
Greg Claytone6b36cd2015-12-08 01:02:08 +00002551
Kate Stoneb9c1b512016-09-06 20:57:50 +00002552bool ClangASTContext::SetTagTypeKind(clang::QualType tag_qual_type,
2553 int kind) const {
2554 const clang::Type *clang_type = tag_qual_type.getTypePtr();
2555 if (clang_type) {
2556 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
2557 if (tag_type) {
2558 clang::TagDecl *tag_decl =
2559 llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
2560 if (tag_decl) {
2561 tag_decl->setTagKind((clang::TagDecl::TagKind)kind);
2562 return true;
2563 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002564 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002565 }
2566 return false;
2567}
2568
2569bool ClangASTContext::SetDefaultAccessForRecordFields(
2570 clang::RecordDecl *record_decl, int default_accessibility,
2571 int *assigned_accessibilities, size_t num_assigned_accessibilities) {
2572 if (record_decl) {
2573 uint32_t field_idx;
2574 clang::RecordDecl::field_iterator field, field_end;
2575 for (field = record_decl->field_begin(),
2576 field_end = record_decl->field_end(), field_idx = 0;
2577 field != field_end; ++field, ++field_idx) {
2578 // If no accessibility was assigned, assign the correct one
2579 if (field_idx < num_assigned_accessibilities &&
2580 assigned_accessibilities[field_idx] == clang::AS_none)
2581 field->setAccess((clang::AccessSpecifier)default_accessibility);
2582 }
Greg Claytond8d4a572015-08-11 21:38:15 +00002583 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002584 }
2585 return false;
2586}
2587
2588clang::DeclContext *
2589ClangASTContext::GetDeclContextForType(const CompilerType &type) {
2590 return GetDeclContextForType(ClangUtil::GetQualType(type));
2591}
2592
2593clang::DeclContext *
2594ClangASTContext::GetDeclContextForType(clang::QualType type) {
2595 if (type.isNull())
2596 return nullptr;
2597
2598 clang::QualType qual_type = type.getCanonicalType();
2599 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2600 switch (type_class) {
2601 case clang::Type::ObjCInterface:
2602 return llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr())
2603 ->getInterface();
2604 case clang::Type::ObjCObjectPointer:
2605 return GetDeclContextForType(
2606 llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
2607 ->getPointeeType());
2608 case clang::Type::Record:
2609 return llvm::cast<clang::RecordType>(qual_type)->getDecl();
2610 case clang::Type::Enum:
2611 return llvm::cast<clang::EnumType>(qual_type)->getDecl();
2612 case clang::Type::Typedef:
2613 return GetDeclContextForType(llvm::cast<clang::TypedefType>(qual_type)
2614 ->getDecl()
2615 ->getUnderlyingType());
2616 case clang::Type::Auto:
2617 return GetDeclContextForType(
2618 llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
2619 case clang::Type::Elaborated:
2620 return GetDeclContextForType(
2621 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
2622 case clang::Type::Paren:
2623 return GetDeclContextForType(
2624 llvm::cast<clang::ParenType>(qual_type)->desugar());
2625 default:
2626 break;
2627 }
2628 // No DeclContext in this type...
2629 return nullptr;
2630}
2631
2632static bool GetCompleteQualType(clang::ASTContext *ast,
2633 clang::QualType qual_type,
2634 bool allow_completion = true) {
2635 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2636 switch (type_class) {
2637 case clang::Type::ConstantArray:
2638 case clang::Type::IncompleteArray:
2639 case clang::Type::VariableArray: {
2640 const clang::ArrayType *array_type =
2641 llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
2642
2643 if (array_type)
2644 return GetCompleteQualType(ast, array_type->getElementType(),
2645 allow_completion);
2646 } break;
2647 case clang::Type::Record: {
2648 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2649 if (cxx_record_decl) {
2650 if (cxx_record_decl->hasExternalLexicalStorage()) {
2651 const bool is_complete = cxx_record_decl->isCompleteDefinition();
2652 const bool fields_loaded =
2653 cxx_record_decl->hasLoadedFieldsFromExternalStorage();
2654 if (is_complete && fields_loaded)
2655 return true;
2656
2657 if (!allow_completion)
2658 return false;
2659
2660 // Call the field_begin() accessor to for it to use the external source
2661 // to load the fields...
2662 clang::ExternalASTSource *external_ast_source =
2663 ast->getExternalSource();
2664 if (external_ast_source) {
2665 external_ast_source->CompleteType(cxx_record_decl);
2666 if (cxx_record_decl->isCompleteDefinition()) {
2667 cxx_record_decl->field_begin();
2668 cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
2669 }
2670 }
2671 }
2672 }
2673 const clang::TagType *tag_type =
2674 llvm::cast<clang::TagType>(qual_type.getTypePtr());
2675 return !tag_type->isIncompleteType();
2676 } break;
2677
2678 case clang::Type::Enum: {
2679 const clang::TagType *tag_type =
2680 llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
2681 if (tag_type) {
2682 clang::TagDecl *tag_decl = tag_type->getDecl();
2683 if (tag_decl) {
2684 if (tag_decl->getDefinition())
2685 return true;
2686
2687 if (!allow_completion)
2688 return false;
2689
2690 if (tag_decl->hasExternalLexicalStorage()) {
2691 if (ast) {
2692 clang::ExternalASTSource *external_ast_source =
2693 ast->getExternalSource();
2694 if (external_ast_source) {
2695 external_ast_source->CompleteType(tag_decl);
2696 return !tag_type->isIncompleteType();
2697 }
2698 }
2699 }
2700 return false;
2701 }
2702 }
2703
2704 } break;
2705 case clang::Type::ObjCObject:
2706 case clang::Type::ObjCInterface: {
2707 const clang::ObjCObjectType *objc_class_type =
2708 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
2709 if (objc_class_type) {
2710 clang::ObjCInterfaceDecl *class_interface_decl =
2711 objc_class_type->getInterface();
2712 // We currently can't complete objective C types through the newly added
Adrian Prantl05097242018-04-30 16:49:04 +00002713 // ASTContext because it only supports TagDecl objects right now...
Kate Stoneb9c1b512016-09-06 20:57:50 +00002714 if (class_interface_decl) {
2715 if (class_interface_decl->getDefinition())
2716 return true;
2717
2718 if (!allow_completion)
2719 return false;
2720
2721 if (class_interface_decl->hasExternalLexicalStorage()) {
2722 if (ast) {
2723 clang::ExternalASTSource *external_ast_source =
2724 ast->getExternalSource();
2725 if (external_ast_source) {
2726 external_ast_source->CompleteType(class_interface_decl);
2727 return !objc_class_type->isIncompleteType();
2728 }
2729 }
2730 }
2731 return false;
2732 }
2733 }
2734 } break;
2735
2736 case clang::Type::Typedef:
2737 return GetCompleteQualType(ast, llvm::cast<clang::TypedefType>(qual_type)
2738 ->getDecl()
2739 ->getUnderlyingType(),
2740 allow_completion);
2741
2742 case clang::Type::Auto:
2743 return GetCompleteQualType(
2744 ast, llvm::cast<clang::AutoType>(qual_type)->getDeducedType(),
2745 allow_completion);
2746
2747 case clang::Type::Elaborated:
2748 return GetCompleteQualType(
2749 ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(),
2750 allow_completion);
2751
2752 case clang::Type::Paren:
2753 return GetCompleteQualType(
2754 ast, llvm::cast<clang::ParenType>(qual_type)->desugar(),
2755 allow_completion);
2756
2757 case clang::Type::Attributed:
2758 return GetCompleteQualType(
2759 ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(),
2760 allow_completion);
2761
2762 default:
2763 break;
2764 }
2765
2766 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00002767}
2768
2769static clang::ObjCIvarDecl::AccessControl
Kate Stoneb9c1b512016-09-06 20:57:50 +00002770ConvertAccessTypeToObjCIvarAccessControl(AccessType access) {
2771 switch (access) {
2772 case eAccessNone:
Greg Claytond8d4a572015-08-11 21:38:15 +00002773 return clang::ObjCIvarDecl::None;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002774 case eAccessPublic:
2775 return clang::ObjCIvarDecl::Public;
2776 case eAccessPrivate:
2777 return clang::ObjCIvarDecl::Private;
2778 case eAccessProtected:
2779 return clang::ObjCIvarDecl::Protected;
2780 case eAccessPackage:
2781 return clang::ObjCIvarDecl::Package;
2782 }
2783 return clang::ObjCIvarDecl::None;
Greg Claytond8d4a572015-08-11 21:38:15 +00002784}
2785
Greg Claytond8d4a572015-08-11 21:38:15 +00002786// Tests
Greg Claytond8d4a572015-08-11 21:38:15 +00002787
Kate Stoneb9c1b512016-09-06 20:57:50 +00002788bool ClangASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
2789 clang::QualType qual_type(GetCanonicalQualType(type));
2790
2791 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2792 switch (type_class) {
2793 case clang::Type::IncompleteArray:
2794 case clang::Type::VariableArray:
2795 case clang::Type::ConstantArray:
2796 case clang::Type::ExtVector:
2797 case clang::Type::Vector:
2798 case clang::Type::Record:
2799 case clang::Type::ObjCObject:
2800 case clang::Type::ObjCInterface:
2801 return true;
2802 case clang::Type::Auto:
2803 return IsAggregateType(llvm::cast<clang::AutoType>(qual_type)
2804 ->getDeducedType()
2805 .getAsOpaquePtr());
2806 case clang::Type::Elaborated:
2807 return IsAggregateType(llvm::cast<clang::ElaboratedType>(qual_type)
2808 ->getNamedType()
2809 .getAsOpaquePtr());
2810 case clang::Type::Typedef:
2811 return IsAggregateType(llvm::cast<clang::TypedefType>(qual_type)
2812 ->getDecl()
2813 ->getUnderlyingType()
2814 .getAsOpaquePtr());
2815 case clang::Type::Paren:
2816 return IsAggregateType(
2817 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
2818 default:
2819 break;
2820 }
2821 // The clang type does have a value
2822 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00002823}
2824
Kate Stoneb9c1b512016-09-06 20:57:50 +00002825bool ClangASTContext::IsAnonymousType(lldb::opaque_compiler_type_t type) {
2826 clang::QualType qual_type(GetCanonicalQualType(type));
2827
2828 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2829 switch (type_class) {
2830 case clang::Type::Record: {
2831 if (const clang::RecordType *record_type =
2832 llvm::dyn_cast_or_null<clang::RecordType>(
2833 qual_type.getTypePtrOrNull())) {
2834 if (const clang::RecordDecl *record_decl = record_type->getDecl()) {
2835 return record_decl->isAnonymousStructOrUnion();
2836 }
Enrico Granata7123e2b2015-11-07 02:06:57 +00002837 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002838 break;
2839 }
2840 case clang::Type::Auto:
2841 return IsAnonymousType(llvm::cast<clang::AutoType>(qual_type)
2842 ->getDeducedType()
2843 .getAsOpaquePtr());
2844 case clang::Type::Elaborated:
2845 return IsAnonymousType(llvm::cast<clang::ElaboratedType>(qual_type)
2846 ->getNamedType()
2847 .getAsOpaquePtr());
2848 case clang::Type::Typedef:
2849 return IsAnonymousType(llvm::cast<clang::TypedefType>(qual_type)
2850 ->getDecl()
2851 ->getUnderlyingType()
2852 .getAsOpaquePtr());
2853 case clang::Type::Paren:
2854 return IsAnonymousType(
2855 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
2856 default:
2857 break;
2858 }
2859 // The clang type does have a value
2860 return false;
Enrico Granata7123e2b2015-11-07 02:06:57 +00002861}
2862
Kate Stoneb9c1b512016-09-06 20:57:50 +00002863bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
2864 CompilerType *element_type_ptr,
2865 uint64_t *size, bool *is_incomplete) {
2866 clang::QualType qual_type(GetCanonicalQualType(type));
Tamas Berghammer69d0b332015-10-09 12:43:08 +00002867
Kate Stoneb9c1b512016-09-06 20:57:50 +00002868 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2869 switch (type_class) {
2870 default:
2871 break;
Tamas Berghammer69d0b332015-10-09 12:43:08 +00002872
Kate Stoneb9c1b512016-09-06 20:57:50 +00002873 case clang::Type::ConstantArray:
Greg Claytond8d4a572015-08-11 21:38:15 +00002874 if (element_type_ptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002875 element_type_ptr->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00002876 this, llvm::cast<clang::ConstantArrayType>(qual_type)
2877 ->getElementType()
2878 .getAsOpaquePtr());
Greg Claytond8d4a572015-08-11 21:38:15 +00002879 if (size)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002880 *size = llvm::cast<clang::ConstantArrayType>(qual_type)
2881 ->getSize()
2882 .getLimitedValue(ULLONG_MAX);
Greg Claytond8d4a572015-08-11 21:38:15 +00002883 if (is_incomplete)
Kate Stoneb9c1b512016-09-06 20:57:50 +00002884 *is_incomplete = false;
2885 return true;
2886
2887 case clang::Type::IncompleteArray:
2888 if (element_type_ptr)
2889 element_type_ptr->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00002890 this, llvm::cast<clang::IncompleteArrayType>(qual_type)
2891 ->getElementType()
2892 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002893 if (size)
2894 *size = 0;
2895 if (is_incomplete)
2896 *is_incomplete = true;
2897 return true;
2898
2899 case clang::Type::VariableArray:
2900 if (element_type_ptr)
2901 element_type_ptr->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00002902 this, llvm::cast<clang::VariableArrayType>(qual_type)
2903 ->getElementType()
2904 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002905 if (size)
2906 *size = 0;
2907 if (is_incomplete)
2908 *is_incomplete = false;
2909 return true;
2910
2911 case clang::Type::DependentSizedArray:
2912 if (element_type_ptr)
2913 element_type_ptr->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00002914 this, llvm::cast<clang::DependentSizedArrayType>(qual_type)
2915 ->getElementType()
2916 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002917 if (size)
2918 *size = 0;
2919 if (is_incomplete)
2920 *is_incomplete = false;
2921 return true;
2922
2923 case clang::Type::Typedef:
2924 return IsArrayType(llvm::cast<clang::TypedefType>(qual_type)
2925 ->getDecl()
2926 ->getUnderlyingType()
2927 .getAsOpaquePtr(),
2928 element_type_ptr, size, is_incomplete);
2929 case clang::Type::Auto:
2930 return IsArrayType(llvm::cast<clang::AutoType>(qual_type)
2931 ->getDeducedType()
2932 .getAsOpaquePtr(),
2933 element_type_ptr, size, is_incomplete);
2934 case clang::Type::Elaborated:
2935 return IsArrayType(llvm::cast<clang::ElaboratedType>(qual_type)
2936 ->getNamedType()
2937 .getAsOpaquePtr(),
2938 element_type_ptr, size, is_incomplete);
2939 case clang::Type::Paren:
2940 return IsArrayType(
2941 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
2942 element_type_ptr, size, is_incomplete);
2943 }
2944 if (element_type_ptr)
2945 element_type_ptr->Clear();
2946 if (size)
2947 *size = 0;
2948 if (is_incomplete)
2949 *is_incomplete = false;
2950 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00002951}
2952
Kate Stoneb9c1b512016-09-06 20:57:50 +00002953bool ClangASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
2954 CompilerType *element_type, uint64_t *size) {
2955 clang::QualType qual_type(GetCanonicalQualType(type));
2956
2957 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2958 switch (type_class) {
2959 case clang::Type::Vector: {
2960 const clang::VectorType *vector_type =
2961 qual_type->getAs<clang::VectorType>();
2962 if (vector_type) {
2963 if (size)
2964 *size = vector_type->getNumElements();
2965 if (element_type)
2966 *element_type =
Alex Langfordbddab072019-08-13 19:40:36 +00002967 CompilerType(this, vector_type->getElementType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002968 }
2969 return true;
2970 } break;
2971 case clang::Type::ExtVector: {
2972 const clang::ExtVectorType *ext_vector_type =
2973 qual_type->getAs<clang::ExtVectorType>();
2974 if (ext_vector_type) {
2975 if (size)
2976 *size = ext_vector_type->getNumElements();
2977 if (element_type)
2978 *element_type =
Alex Langfordbddab072019-08-13 19:40:36 +00002979 CompilerType(this, ext_vector_type->getElementType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002980 }
2981 return true;
2982 }
2983 default:
2984 break;
2985 }
2986 return false;
2987}
2988
2989bool ClangASTContext::IsRuntimeGeneratedType(
2990 lldb::opaque_compiler_type_t type) {
2991 clang::DeclContext *decl_ctx = ClangASTContext::GetASTContext(getASTContext())
2992 ->GetDeclContextForType(GetQualType(type));
2993 if (!decl_ctx)
2994 return false;
2995
2996 if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
2997 return false;
2998
2999 clang::ObjCInterfaceDecl *result_iface_decl =
3000 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
3001
3002 ClangASTMetadata *ast_metadata =
3003 ClangASTContext::GetMetadata(getASTContext(), result_iface_decl);
3004 if (!ast_metadata)
3005 return false;
3006 return (ast_metadata->GetISAPtr() != 0);
3007}
3008
3009bool ClangASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
3010 return GetQualType(type).getUnqualifiedType()->isCharType();
3011}
3012
3013bool ClangASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
3014 const bool allow_completion = false;
3015 return GetCompleteQualType(getASTContext(), GetQualType(type),
3016 allow_completion);
3017}
3018
3019bool ClangASTContext::IsConst(lldb::opaque_compiler_type_t type) {
3020 return GetQualType(type).isConstQualified();
3021}
3022
3023bool ClangASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
3024 uint32_t &length) {
3025 CompilerType pointee_or_element_clang_type;
3026 length = 0;
3027 Flags type_flags(GetTypeInfo(type, &pointee_or_element_clang_type));
3028
3029 if (!pointee_or_element_clang_type.IsValid())
3030 return false;
3031
3032 if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer)) {
3033 if (pointee_or_element_clang_type.IsCharType()) {
3034 if (type_flags.Test(eTypeIsArray)) {
Adrian Prantl05097242018-04-30 16:49:04 +00003035 // We know the size of the array and it could be a C string since it is
3036 // an array of characters
Kate Stoneb9c1b512016-09-06 20:57:50 +00003037 length = llvm::cast<clang::ConstantArrayType>(
3038 GetCanonicalQualType(type).getTypePtr())
3039 ->getSize()
3040 .getLimitedValue();
3041 }
3042 return true;
3043 }
3044 }
3045 return false;
3046}
3047
3048bool ClangASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
3049 bool *is_variadic_ptr) {
3050 if (type) {
3051 clang::QualType qual_type(GetCanonicalQualType(type));
3052
3053 if (qual_type->isFunctionType()) {
3054 if (is_variadic_ptr) {
3055 const clang::FunctionProtoType *function_proto_type =
3056 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
3057 if (function_proto_type)
3058 *is_variadic_ptr = function_proto_type->isVariadic();
3059 else
3060 *is_variadic_ptr = false;
3061 }
3062 return true;
3063 }
3064
Greg Claytond8d4a572015-08-11 21:38:15 +00003065 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00003066 switch (type_class) {
3067 default:
3068 break;
3069 case clang::Type::Typedef:
3070 return IsFunctionType(llvm::cast<clang::TypedefType>(qual_type)
3071 ->getDecl()
3072 ->getUnderlyingType()
3073 .getAsOpaquePtr(),
3074 nullptr);
3075 case clang::Type::Auto:
3076 return IsFunctionType(llvm::cast<clang::AutoType>(qual_type)
3077 ->getDeducedType()
3078 .getAsOpaquePtr(),
3079 nullptr);
3080 case clang::Type::Elaborated:
3081 return IsFunctionType(llvm::cast<clang::ElaboratedType>(qual_type)
3082 ->getNamedType()
3083 .getAsOpaquePtr(),
3084 nullptr);
3085 case clang::Type::Paren:
3086 return IsFunctionType(
3087 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3088 nullptr);
3089 case clang::Type::LValueReference:
3090 case clang::Type::RValueReference: {
3091 const clang::ReferenceType *reference_type =
3092 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
3093 if (reference_type)
3094 return IsFunctionType(reference_type->getPointeeType().getAsOpaquePtr(),
3095 nullptr);
3096 } break;
Greg Claytond8d4a572015-08-11 21:38:15 +00003097 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003098 }
3099 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00003100}
3101
3102// Used to detect "Homogeneous Floating-point Aggregates"
3103uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00003104ClangASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
3105 CompilerType *base_type_ptr) {
3106 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00003107 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003108
3109 clang::QualType qual_type(GetCanonicalQualType(type));
3110 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3111 switch (type_class) {
3112 case clang::Type::Record:
3113 if (GetCompleteType(type)) {
3114 const clang::CXXRecordDecl *cxx_record_decl =
3115 qual_type->getAsCXXRecordDecl();
3116 if (cxx_record_decl) {
3117 if (cxx_record_decl->getNumBases() || cxx_record_decl->isDynamicClass())
3118 return 0;
3119 }
3120 const clang::RecordType *record_type =
3121 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
3122 if (record_type) {
3123 const clang::RecordDecl *record_decl = record_type->getDecl();
3124 if (record_decl) {
3125 // We are looking for a structure that contains only floating point
3126 // types
3127 clang::RecordDecl::field_iterator field_pos,
3128 field_end = record_decl->field_end();
3129 uint32_t num_fields = 0;
3130 bool is_hva = false;
3131 bool is_hfa = false;
3132 clang::QualType base_qual_type;
3133 uint64_t base_bitwidth = 0;
3134 for (field_pos = record_decl->field_begin(); field_pos != field_end;
3135 ++field_pos) {
3136 clang::QualType field_qual_type = field_pos->getType();
3137 uint64_t field_bitwidth = getASTContext()->getTypeSize(qual_type);
3138 if (field_qual_type->isFloatingType()) {
3139 if (field_qual_type->isComplexType())
3140 return 0;
3141 else {
3142 if (num_fields == 0)
3143 base_qual_type = field_qual_type;
3144 else {
3145 if (is_hva)
3146 return 0;
3147 is_hfa = true;
3148 if (field_qual_type.getTypePtr() !=
3149 base_qual_type.getTypePtr())
3150 return 0;
3151 }
3152 }
3153 } else if (field_qual_type->isVectorType() ||
3154 field_qual_type->isExtVectorType()) {
3155 if (num_fields == 0) {
3156 base_qual_type = field_qual_type;
3157 base_bitwidth = field_bitwidth;
3158 } else {
3159 if (is_hfa)
3160 return 0;
3161 is_hva = true;
3162 if (base_bitwidth != field_bitwidth)
3163 return 0;
3164 if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
3165 return 0;
3166 }
3167 } else
3168 return 0;
3169 ++num_fields;
3170 }
3171 if (base_type_ptr)
Alex Langfordbddab072019-08-13 19:40:36 +00003172 *base_type_ptr = CompilerType(this, base_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003173 return num_fields;
3174 }
3175 }
3176 }
3177 break;
3178
3179 case clang::Type::Typedef:
3180 return IsHomogeneousAggregate(llvm::cast<clang::TypedefType>(qual_type)
3181 ->getDecl()
3182 ->getUnderlyingType()
3183 .getAsOpaquePtr(),
3184 base_type_ptr);
3185
3186 case clang::Type::Auto:
3187 return IsHomogeneousAggregate(llvm::cast<clang::AutoType>(qual_type)
3188 ->getDeducedType()
3189 .getAsOpaquePtr(),
3190 base_type_ptr);
3191
3192 case clang::Type::Elaborated:
3193 return IsHomogeneousAggregate(llvm::cast<clang::ElaboratedType>(qual_type)
3194 ->getNamedType()
3195 .getAsOpaquePtr(),
3196 base_type_ptr);
3197 default:
3198 break;
3199 }
3200 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00003201}
3202
Kate Stoneb9c1b512016-09-06 20:57:50 +00003203size_t ClangASTContext::GetNumberOfFunctionArguments(
3204 lldb::opaque_compiler_type_t type) {
3205 if (type) {
3206 clang::QualType qual_type(GetCanonicalQualType(type));
3207 const clang::FunctionProtoType *func =
3208 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
3209 if (func)
3210 return func->getNumParams();
3211 }
3212 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00003213}
3214
Greg Claytona1e5dc82015-08-11 22:53:00 +00003215CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00003216ClangASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
3217 const size_t index) {
3218 if (type) {
Greg Claytond8d4a572015-08-11 21:38:15 +00003219 clang::QualType qual_type(GetQualType(type));
Kate Stoneb9c1b512016-09-06 20:57:50 +00003220 const clang::FunctionProtoType *func =
3221 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
3222 if (func) {
3223 if (index < func->getNumParams())
Alex Langfordbddab072019-08-13 19:40:36 +00003224 return CompilerType(this, func->getParamType(index).getAsOpaquePtr());
Greg Claytond8d4a572015-08-11 21:38:15 +00003225 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003226 }
3227 return CompilerType();
3228}
3229
3230bool ClangASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
3231 if (type) {
3232 clang::QualType qual_type(GetCanonicalQualType(type));
3233
3234 if (qual_type->isFunctionPointerType())
3235 return true;
3236
3237 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3238 switch (type_class) {
3239 default:
3240 break;
3241 case clang::Type::Typedef:
3242 return IsFunctionPointerType(llvm::cast<clang::TypedefType>(qual_type)
3243 ->getDecl()
3244 ->getUnderlyingType()
3245 .getAsOpaquePtr());
3246 case clang::Type::Auto:
3247 return IsFunctionPointerType(llvm::cast<clang::AutoType>(qual_type)
3248 ->getDeducedType()
3249 .getAsOpaquePtr());
3250 case clang::Type::Elaborated:
3251 return IsFunctionPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
3252 ->getNamedType()
3253 .getAsOpaquePtr());
3254 case clang::Type::Paren:
3255 return IsFunctionPointerType(
3256 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
3257
3258 case clang::Type::LValueReference:
3259 case clang::Type::RValueReference: {
3260 const clang::ReferenceType *reference_type =
3261 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
3262 if (reference_type)
3263 return IsFunctionPointerType(
3264 reference_type->getPointeeType().getAsOpaquePtr());
3265 } break;
3266 }
3267 }
3268 return false;
3269}
3270
3271bool ClangASTContext::IsBlockPointerType(
3272 lldb::opaque_compiler_type_t type,
3273 CompilerType *function_pointer_type_ptr) {
3274 if (type) {
3275 clang::QualType qual_type(GetCanonicalQualType(type));
3276
3277 if (qual_type->isBlockPointerType()) {
3278 if (function_pointer_type_ptr) {
3279 const clang::BlockPointerType *block_pointer_type =
3280 qual_type->getAs<clang::BlockPointerType>();
3281 QualType pointee_type = block_pointer_type->getPointeeType();
Jonas Devlieghered5b44032019-02-13 06:25:41 +00003282 QualType function_pointer_type = m_ast_up->getPointerType(pointee_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003283 *function_pointer_type_ptr =
Alex Langfordbddab072019-08-13 19:40:36 +00003284 CompilerType(this, function_pointer_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003285 }
3286 return true;
3287 }
3288
3289 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3290 switch (type_class) {
3291 default:
3292 break;
3293 case clang::Type::Typedef:
3294 return IsBlockPointerType(llvm::cast<clang::TypedefType>(qual_type)
3295 ->getDecl()
3296 ->getUnderlyingType()
3297 .getAsOpaquePtr(),
3298 function_pointer_type_ptr);
3299 case clang::Type::Auto:
3300 return IsBlockPointerType(llvm::cast<clang::AutoType>(qual_type)
3301 ->getDeducedType()
3302 .getAsOpaquePtr(),
3303 function_pointer_type_ptr);
3304 case clang::Type::Elaborated:
3305 return IsBlockPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
3306 ->getNamedType()
3307 .getAsOpaquePtr(),
3308 function_pointer_type_ptr);
3309 case clang::Type::Paren:
3310 return IsBlockPointerType(
3311 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3312 function_pointer_type_ptr);
3313
3314 case clang::Type::LValueReference:
3315 case clang::Type::RValueReference: {
3316 const clang::ReferenceType *reference_type =
3317 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
3318 if (reference_type)
3319 return IsBlockPointerType(
3320 reference_type->getPointeeType().getAsOpaquePtr(),
3321 function_pointer_type_ptr);
3322 } break;
3323 }
3324 }
3325 return false;
3326}
3327
3328bool ClangASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
3329 bool &is_signed) {
3330 if (!type)
3331 return false;
3332
3333 clang::QualType qual_type(GetCanonicalQualType(type));
3334 const clang::BuiltinType *builtin_type =
3335 llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
3336
3337 if (builtin_type) {
3338 if (builtin_type->isInteger()) {
3339 is_signed = builtin_type->isSignedInteger();
3340 return true;
3341 }
3342 }
3343
3344 return false;
3345}
3346
3347bool ClangASTContext::IsEnumerationType(lldb::opaque_compiler_type_t type,
3348 bool &is_signed) {
3349 if (type) {
3350 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
3351 GetCanonicalQualType(type)->getCanonicalTypeInternal());
3352
3353 if (enum_type) {
3354 IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(),
3355 is_signed);
3356 return true;
3357 }
3358 }
3359
3360 return false;
3361}
3362
3363bool ClangASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
3364 CompilerType *pointee_type) {
3365 if (type) {
3366 clang::QualType qual_type(GetCanonicalQualType(type));
3367 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3368 switch (type_class) {
3369 case clang::Type::Builtin:
3370 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
3371 default:
3372 break;
3373 case clang::BuiltinType::ObjCId:
3374 case clang::BuiltinType::ObjCClass:
3375 return true;
3376 }
3377 return false;
3378 case clang::Type::ObjCObjectPointer:
3379 if (pointee_type)
3380 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003381 this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
3382 ->getPointeeType()
3383 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003384 return true;
3385 case clang::Type::BlockPointer:
3386 if (pointee_type)
3387 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003388 this, llvm::cast<clang::BlockPointerType>(qual_type)
3389 ->getPointeeType()
3390 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003391 return true;
3392 case clang::Type::Pointer:
3393 if (pointee_type)
Alex Langfordbddab072019-08-13 19:40:36 +00003394 pointee_type->SetCompilerType(this,
3395 llvm::cast<clang::PointerType>(qual_type)
3396 ->getPointeeType()
3397 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003398 return true;
3399 case clang::Type::MemberPointer:
3400 if (pointee_type)
3401 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003402 this, llvm::cast<clang::MemberPointerType>(qual_type)
3403 ->getPointeeType()
3404 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003405 return true;
3406 case clang::Type::Typedef:
3407 return IsPointerType(llvm::cast<clang::TypedefType>(qual_type)
3408 ->getDecl()
3409 ->getUnderlyingType()
3410 .getAsOpaquePtr(),
3411 pointee_type);
3412 case clang::Type::Auto:
3413 return IsPointerType(llvm::cast<clang::AutoType>(qual_type)
3414 ->getDeducedType()
3415 .getAsOpaquePtr(),
3416 pointee_type);
3417 case clang::Type::Elaborated:
3418 return IsPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
3419 ->getNamedType()
3420 .getAsOpaquePtr(),
3421 pointee_type);
3422 case clang::Type::Paren:
3423 return IsPointerType(
3424 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3425 pointee_type);
3426 default:
3427 break;
3428 }
3429 }
3430 if (pointee_type)
3431 pointee_type->Clear();
3432 return false;
3433}
3434
3435bool ClangASTContext::IsPointerOrReferenceType(
3436 lldb::opaque_compiler_type_t type, CompilerType *pointee_type) {
3437 if (type) {
3438 clang::QualType qual_type(GetCanonicalQualType(type));
3439 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3440 switch (type_class) {
3441 case clang::Type::Builtin:
3442 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
3443 default:
3444 break;
3445 case clang::BuiltinType::ObjCId:
3446 case clang::BuiltinType::ObjCClass:
3447 return true;
3448 }
3449 return false;
3450 case clang::Type::ObjCObjectPointer:
3451 if (pointee_type)
3452 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003453 this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
3454 ->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003455 return true;
3456 case clang::Type::BlockPointer:
3457 if (pointee_type)
3458 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003459 this, llvm::cast<clang::BlockPointerType>(qual_type)
3460 ->getPointeeType()
3461 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003462 return true;
3463 case clang::Type::Pointer:
3464 if (pointee_type)
Alex Langfordbddab072019-08-13 19:40:36 +00003465 pointee_type->SetCompilerType(this,
3466 llvm::cast<clang::PointerType>(qual_type)
3467 ->getPointeeType()
3468 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003469 return true;
3470 case clang::Type::MemberPointer:
3471 if (pointee_type)
3472 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003473 this, llvm::cast<clang::MemberPointerType>(qual_type)
3474 ->getPointeeType()
3475 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003476 return true;
3477 case clang::Type::LValueReference:
3478 if (pointee_type)
3479 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003480 this, llvm::cast<clang::LValueReferenceType>(qual_type)
3481 ->desugar()
3482 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003483 return true;
3484 case clang::Type::RValueReference:
3485 if (pointee_type)
3486 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003487 this, llvm::cast<clang::RValueReferenceType>(qual_type)
3488 ->desugar()
3489 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003490 return true;
3491 case clang::Type::Typedef:
3492 return IsPointerOrReferenceType(llvm::cast<clang::TypedefType>(qual_type)
3493 ->getDecl()
3494 ->getUnderlyingType()
3495 .getAsOpaquePtr(),
3496 pointee_type);
3497 case clang::Type::Auto:
3498 return IsPointerOrReferenceType(llvm::cast<clang::AutoType>(qual_type)
3499 ->getDeducedType()
3500 .getAsOpaquePtr(),
3501 pointee_type);
3502 case clang::Type::Elaborated:
3503 return IsPointerOrReferenceType(
3504 llvm::cast<clang::ElaboratedType>(qual_type)
3505 ->getNamedType()
3506 .getAsOpaquePtr(),
3507 pointee_type);
3508 case clang::Type::Paren:
3509 return IsPointerOrReferenceType(
3510 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3511 pointee_type);
3512 default:
3513 break;
3514 }
3515 }
3516 if (pointee_type)
3517 pointee_type->Clear();
3518 return false;
3519}
3520
3521bool ClangASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
3522 CompilerType *pointee_type,
3523 bool *is_rvalue) {
3524 if (type) {
3525 clang::QualType qual_type(GetCanonicalQualType(type));
3526 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3527
3528 switch (type_class) {
3529 case clang::Type::LValueReference:
3530 if (pointee_type)
3531 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003532 this, llvm::cast<clang::LValueReferenceType>(qual_type)
3533 ->desugar()
3534 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003535 if (is_rvalue)
3536 *is_rvalue = false;
3537 return true;
3538 case clang::Type::RValueReference:
3539 if (pointee_type)
3540 pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003541 this, llvm::cast<clang::RValueReferenceType>(qual_type)
3542 ->desugar()
3543 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003544 if (is_rvalue)
3545 *is_rvalue = true;
3546 return true;
3547 case clang::Type::Typedef:
3548 return IsReferenceType(llvm::cast<clang::TypedefType>(qual_type)
3549 ->getDecl()
3550 ->getUnderlyingType()
3551 .getAsOpaquePtr(),
3552 pointee_type, is_rvalue);
3553 case clang::Type::Auto:
3554 return IsReferenceType(llvm::cast<clang::AutoType>(qual_type)
3555 ->getDeducedType()
3556 .getAsOpaquePtr(),
3557 pointee_type, is_rvalue);
3558 case clang::Type::Elaborated:
3559 return IsReferenceType(llvm::cast<clang::ElaboratedType>(qual_type)
3560 ->getNamedType()
3561 .getAsOpaquePtr(),
3562 pointee_type, is_rvalue);
3563 case clang::Type::Paren:
3564 return IsReferenceType(
3565 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3566 pointee_type, is_rvalue);
3567
3568 default:
3569 break;
3570 }
3571 }
3572 if (pointee_type)
3573 pointee_type->Clear();
3574 return false;
3575}
3576
3577bool ClangASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
3578 uint32_t &count, bool &is_complex) {
3579 if (type) {
3580 clang::QualType qual_type(GetCanonicalQualType(type));
3581
3582 if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(
3583 qual_type->getCanonicalTypeInternal())) {
3584 clang::BuiltinType::Kind kind = BT->getKind();
3585 if (kind >= clang::BuiltinType::Float &&
3586 kind <= clang::BuiltinType::LongDouble) {
3587 count = 1;
3588 is_complex = false;
3589 return true;
3590 }
3591 } else if (const clang::ComplexType *CT =
3592 llvm::dyn_cast<clang::ComplexType>(
3593 qual_type->getCanonicalTypeInternal())) {
3594 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count,
3595 is_complex)) {
3596 count = 2;
3597 is_complex = true;
3598 return true;
3599 }
3600 } else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(
3601 qual_type->getCanonicalTypeInternal())) {
3602 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count,
3603 is_complex)) {
3604 count = VT->getNumElements();
3605 is_complex = false;
3606 return true;
3607 }
3608 }
3609 }
3610 count = 0;
3611 is_complex = false;
3612 return false;
3613}
3614
3615bool ClangASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
3616 if (!type)
3617 return false;
3618
3619 clang::QualType qual_type(GetQualType(type));
3620 const clang::TagType *tag_type =
3621 llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
3622 if (tag_type) {
3623 clang::TagDecl *tag_decl = tag_type->getDecl();
3624 if (tag_decl)
3625 return tag_decl->isCompleteDefinition();
3626 return false;
3627 } else {
3628 const clang::ObjCObjectType *objc_class_type =
3629 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
3630 if (objc_class_type) {
3631 clang::ObjCInterfaceDecl *class_interface_decl =
3632 objc_class_type->getInterface();
3633 if (class_interface_decl)
3634 return class_interface_decl->getDefinition() != nullptr;
3635 return false;
3636 }
3637 }
3638 return true;
3639}
3640
3641bool ClangASTContext::IsObjCClassType(const CompilerType &type) {
3642 if (type) {
3643 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3644
3645 const clang::ObjCObjectPointerType *obj_pointer_type =
3646 llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
3647
3648 if (obj_pointer_type)
3649 return obj_pointer_type->isObjCClassType();
3650 }
3651 return false;
3652}
3653
3654bool ClangASTContext::IsObjCObjectOrInterfaceType(const CompilerType &type) {
3655 if (ClangUtil::IsClangType(type))
3656 return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
3657 return false;
3658}
3659
3660bool ClangASTContext::IsClassType(lldb::opaque_compiler_type_t type) {
3661 if (!type)
3662 return false;
3663 clang::QualType qual_type(GetCanonicalQualType(type));
3664 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3665 return (type_class == clang::Type::Record);
3666}
3667
3668bool ClangASTContext::IsEnumType(lldb::opaque_compiler_type_t type) {
3669 if (!type)
3670 return false;
3671 clang::QualType qual_type(GetCanonicalQualType(type));
3672 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3673 return (type_class == clang::Type::Enum);
3674}
3675
3676bool ClangASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
3677 if (type) {
3678 clang::QualType qual_type(GetCanonicalQualType(type));
3679 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3680 switch (type_class) {
3681 case clang::Type::Record:
3682 if (GetCompleteType(type)) {
3683 const clang::RecordType *record_type =
3684 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
3685 const clang::RecordDecl *record_decl = record_type->getDecl();
3686 if (record_decl) {
3687 const clang::CXXRecordDecl *cxx_record_decl =
3688 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
3689 if (cxx_record_decl)
3690 return cxx_record_decl->isPolymorphic();
Greg Claytond8d4a572015-08-11 21:38:15 +00003691 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003692 }
3693 break;
3694
3695 default:
3696 break;
3697 }
3698 }
3699 return false;
3700}
3701
3702bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
3703 CompilerType *dynamic_pointee_type,
3704 bool check_cplusplus,
3705 bool check_objc) {
3706 clang::QualType pointee_qual_type;
3707 if (type) {
3708 clang::QualType qual_type(GetCanonicalQualType(type));
3709 bool success = false;
3710 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3711 switch (type_class) {
3712 case clang::Type::Builtin:
3713 if (check_objc &&
3714 llvm::cast<clang::BuiltinType>(qual_type)->getKind() ==
3715 clang::BuiltinType::ObjCId) {
3716 if (dynamic_pointee_type)
3717 dynamic_pointee_type->SetCompilerType(this, type);
3718 return true;
3719 }
3720 break;
3721
3722 case clang::Type::ObjCObjectPointer:
3723 if (check_objc) {
3724 if (auto objc_pointee_type =
3725 qual_type->getPointeeType().getTypePtrOrNull()) {
3726 if (auto objc_object_type =
3727 llvm::dyn_cast_or_null<clang::ObjCObjectType>(
3728 objc_pointee_type)) {
3729 if (objc_object_type->isObjCClass())
3730 return false;
3731 }
3732 }
3733 if (dynamic_pointee_type)
3734 dynamic_pointee_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00003735 this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
3736 ->getPointeeType()
3737 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003738 return true;
3739 }
3740 break;
3741
3742 case clang::Type::Pointer:
3743 pointee_qual_type =
3744 llvm::cast<clang::PointerType>(qual_type)->getPointeeType();
3745 success = true;
3746 break;
3747
3748 case clang::Type::LValueReference:
3749 case clang::Type::RValueReference:
3750 pointee_qual_type =
3751 llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType();
3752 success = true;
3753 break;
3754
3755 case clang::Type::Typedef:
3756 return IsPossibleDynamicType(llvm::cast<clang::TypedefType>(qual_type)
3757 ->getDecl()
3758 ->getUnderlyingType()
3759 .getAsOpaquePtr(),
3760 dynamic_pointee_type, check_cplusplus,
3761 check_objc);
3762
3763 case clang::Type::Auto:
3764 return IsPossibleDynamicType(llvm::cast<clang::AutoType>(qual_type)
3765 ->getDeducedType()
3766 .getAsOpaquePtr(),
3767 dynamic_pointee_type, check_cplusplus,
3768 check_objc);
3769
3770 case clang::Type::Elaborated:
3771 return IsPossibleDynamicType(llvm::cast<clang::ElaboratedType>(qual_type)
3772 ->getNamedType()
3773 .getAsOpaquePtr(),
3774 dynamic_pointee_type, check_cplusplus,
3775 check_objc);
3776
3777 case clang::Type::Paren:
3778 return IsPossibleDynamicType(
3779 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
3780 dynamic_pointee_type, check_cplusplus, check_objc);
3781 default:
3782 break;
3783 }
3784
3785 if (success) {
3786 // Check to make sure what we are pointing too is a possible dynamic C++
Adrian Prantl05097242018-04-30 16:49:04 +00003787 // type We currently accept any "void *" (in case we have a class that
3788 // has been watered down to an opaque pointer) and virtual C++ classes.
Kate Stoneb9c1b512016-09-06 20:57:50 +00003789 const clang::Type::TypeClass pointee_type_class =
3790 pointee_qual_type.getCanonicalType()->getTypeClass();
3791 switch (pointee_type_class) {
3792 case clang::Type::Builtin:
3793 switch (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind()) {
3794 case clang::BuiltinType::UnknownAny:
3795 case clang::BuiltinType::Void:
3796 if (dynamic_pointee_type)
Alex Langfordbddab072019-08-13 19:40:36 +00003797 dynamic_pointee_type->SetCompilerType(
3798 this, pointee_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003799 return true;
3800 default:
3801 break;
3802 }
3803 break;
3804
3805 case clang::Type::Record:
3806 if (check_cplusplus) {
3807 clang::CXXRecordDecl *cxx_record_decl =
3808 pointee_qual_type->getAsCXXRecordDecl();
3809 if (cxx_record_decl) {
3810 bool is_complete = cxx_record_decl->isCompleteDefinition();
3811
3812 if (is_complete)
3813 success = cxx_record_decl->isDynamicClass();
3814 else {
3815 ClangASTMetadata *metadata = ClangASTContext::GetMetadata(
3816 getASTContext(), cxx_record_decl);
3817 if (metadata)
3818 success = metadata->GetIsDynamicCXXType();
3819 else {
Alex Langfordbddab072019-08-13 19:40:36 +00003820 is_complete =
3821 CompilerType(this, pointee_qual_type.getAsOpaquePtr())
3822 .GetCompleteType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00003823 if (is_complete)
3824 success = cxx_record_decl->isDynamicClass();
3825 else
3826 success = false;
3827 }
3828 }
3829
3830 if (success) {
3831 if (dynamic_pointee_type)
Alex Langfordbddab072019-08-13 19:40:36 +00003832 dynamic_pointee_type->SetCompilerType(
3833 this, pointee_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003834 return true;
3835 }
3836 }
3837 }
3838 break;
3839
3840 case clang::Type::ObjCObject:
3841 case clang::Type::ObjCInterface:
3842 if (check_objc) {
3843 if (dynamic_pointee_type)
Alex Langfordbddab072019-08-13 19:40:36 +00003844 dynamic_pointee_type->SetCompilerType(
3845 this, pointee_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003846 return true;
3847 }
3848 break;
3849
3850 default:
3851 break;
3852 }
3853 }
3854 }
3855 if (dynamic_pointee_type)
3856 dynamic_pointee_type->Clear();
3857 return false;
3858}
3859
3860bool ClangASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
3861 if (!type)
3862 return false;
3863
3864 return (GetTypeInfo(type, nullptr) & eTypeIsScalar) != 0;
3865}
3866
3867bool ClangASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
3868 if (!type)
3869 return false;
3870 return GetQualType(type)->getTypeClass() == clang::Type::Typedef;
3871}
3872
3873bool ClangASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
3874 if (!type)
3875 return false;
3876 return GetCanonicalQualType(type)->isVoidType();
3877}
3878
Alex Langforda03e2b22019-06-04 19:29:59 +00003879bool ClangASTContext::CanPassInRegisters(const CompilerType &type) {
3880 if (auto *record_decl =
3881 ClangASTContext::GetAsRecordDecl(type)) {
3882 return record_decl->canPassInRegisters();
3883 }
3884 return false;
3885}
3886
Kate Stoneb9c1b512016-09-06 20:57:50 +00003887bool ClangASTContext::SupportsLanguage(lldb::LanguageType language) {
3888 return ClangASTContextSupportsLanguage(language);
3889}
3890
3891bool ClangASTContext::GetCXXClassName(const CompilerType &type,
3892 std::string &class_name) {
3893 if (type) {
3894 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3895 if (!qual_type.isNull()) {
3896 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3897 if (cxx_record_decl) {
3898 class_name.assign(cxx_record_decl->getIdentifier()->getNameStart());
3899 return true;
3900 }
3901 }
3902 }
3903 class_name.clear();
3904 return false;
3905}
3906
3907bool ClangASTContext::IsCXXClassType(const CompilerType &type) {
3908 if (!type)
3909 return false;
3910
3911 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
Jonas Devliegherea6682a42018-12-15 00:15:33 +00003912 return !qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003913}
3914
3915bool ClangASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
3916 if (!type)
3917 return false;
3918 clang::QualType qual_type(GetCanonicalQualType(type));
3919 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type);
3920 if (tag_type)
3921 return tag_type->isBeingDefined();
3922 return false;
3923}
3924
3925bool ClangASTContext::IsObjCObjectPointerType(const CompilerType &type,
3926 CompilerType *class_type_ptr) {
3927 if (!type)
3928 return false;
3929
3930 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3931
3932 if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) {
3933 if (class_type_ptr) {
3934 if (!qual_type->isObjCClassType() && !qual_type->isObjCIdType()) {
3935 const clang::ObjCObjectPointerType *obj_pointer_type =
3936 llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
3937 if (obj_pointer_type == nullptr)
3938 class_type_ptr->Clear();
3939 else
3940 class_type_ptr->SetCompilerType(
3941 type.GetTypeSystem(),
3942 clang::QualType(obj_pointer_type->getInterfaceType(), 0)
3943 .getAsOpaquePtr());
3944 }
Greg Claytond8d4a572015-08-11 21:38:15 +00003945 }
3946 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00003947 }
3948 if (class_type_ptr)
3949 class_type_ptr->Clear();
3950 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00003951}
3952
Kate Stoneb9c1b512016-09-06 20:57:50 +00003953bool ClangASTContext::GetObjCClassName(const CompilerType &type,
3954 std::string &class_name) {
3955 if (!type)
3956 return false;
Zachary Turnerd133f6a2016-03-28 22:53:41 +00003957
Kate Stoneb9c1b512016-09-06 20:57:50 +00003958 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
3959
3960 const clang::ObjCObjectType *object_type =
3961 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
3962 if (object_type) {
3963 const clang::ObjCInterfaceDecl *interface = object_type->getInterface();
3964 if (interface) {
3965 class_name = interface->getNameAsString();
3966 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00003967 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003968 }
3969 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00003970}
3971
Greg Claytond8d4a572015-08-11 21:38:15 +00003972// Type Completion
Greg Claytond8d4a572015-08-11 21:38:15 +00003973
Kate Stoneb9c1b512016-09-06 20:57:50 +00003974bool ClangASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
3975 if (!type)
3976 return false;
3977 const bool allow_completion = true;
3978 return GetCompleteQualType(getASTContext(), GetQualType(type),
3979 allow_completion);
Greg Claytond8d4a572015-08-11 21:38:15 +00003980}
3981
Kate Stoneb9c1b512016-09-06 20:57:50 +00003982ConstString ClangASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
3983 std::string type_name;
3984 if (type) {
3985 clang::PrintingPolicy printing_policy(getASTContext()->getPrintingPolicy());
3986 clang::QualType qual_type(GetQualType(type));
3987 printing_policy.SuppressTagKeyword = true;
3988 const clang::TypedefType *typedef_type =
3989 qual_type->getAs<clang::TypedefType>();
3990 if (typedef_type) {
3991 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
3992 type_name = typedef_decl->getQualifiedNameAsString();
3993 } else {
3994 type_name = qual_type.getAsString(printing_policy);
Greg Claytond8d4a572015-08-11 21:38:15 +00003995 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003996 }
3997 return ConstString(type_name);
Greg Claytond8d4a572015-08-11 21:38:15 +00003998}
3999
4000uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00004001ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
4002 CompilerType *pointee_or_element_clang_type) {
4003 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00004004 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004005
4006 if (pointee_or_element_clang_type)
4007 pointee_or_element_clang_type->Clear();
4008
4009 clang::QualType qual_type(GetQualType(type));
4010
4011 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4012 switch (type_class) {
Sean Callananddf802a2017-06-02 01:24:18 +00004013 case clang::Type::Attributed:
4014 return GetTypeInfo(
4015 qual_type->getAs<clang::AttributedType>()
4016 ->getModifiedType().getAsOpaquePtr(),
4017 pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004018 case clang::Type::Builtin: {
4019 const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(
4020 qual_type->getCanonicalTypeInternal());
4021
4022 uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
4023 switch (builtin_type->getKind()) {
4024 case clang::BuiltinType::ObjCId:
4025 case clang::BuiltinType::ObjCClass:
4026 if (pointee_or_element_clang_type)
4027 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004028 this, getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004029 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
4030 break;
4031
4032 case clang::BuiltinType::ObjCSel:
4033 if (pointee_or_element_clang_type)
Alex Langfordbddab072019-08-13 19:40:36 +00004034 pointee_or_element_clang_type->SetCompilerType(
4035 this, getASTContext()->CharTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004036 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
4037 break;
4038
4039 case clang::BuiltinType::Bool:
4040 case clang::BuiltinType::Char_U:
4041 case clang::BuiltinType::UChar:
4042 case clang::BuiltinType::WChar_U:
4043 case clang::BuiltinType::Char16:
4044 case clang::BuiltinType::Char32:
4045 case clang::BuiltinType::UShort:
4046 case clang::BuiltinType::UInt:
4047 case clang::BuiltinType::ULong:
4048 case clang::BuiltinType::ULongLong:
4049 case clang::BuiltinType::UInt128:
4050 case clang::BuiltinType::Char_S:
4051 case clang::BuiltinType::SChar:
4052 case clang::BuiltinType::WChar_S:
4053 case clang::BuiltinType::Short:
4054 case clang::BuiltinType::Int:
4055 case clang::BuiltinType::Long:
4056 case clang::BuiltinType::LongLong:
4057 case clang::BuiltinType::Int128:
4058 case clang::BuiltinType::Float:
4059 case clang::BuiltinType::Double:
4060 case clang::BuiltinType::LongDouble:
4061 builtin_type_flags |= eTypeIsScalar;
4062 if (builtin_type->isInteger()) {
4063 builtin_type_flags |= eTypeIsInteger;
4064 if (builtin_type->isSignedInteger())
4065 builtin_type_flags |= eTypeIsSigned;
4066 } else if (builtin_type->isFloatingPoint())
4067 builtin_type_flags |= eTypeIsFloat;
4068 break;
4069 default:
4070 break;
4071 }
4072 return builtin_type_flags;
4073 }
4074
4075 case clang::Type::BlockPointer:
4076 if (pointee_or_element_clang_type)
4077 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004078 this, qual_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004079 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
4080
4081 case clang::Type::Complex: {
4082 uint32_t complex_type_flags =
4083 eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
4084 const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(
4085 qual_type->getCanonicalTypeInternal());
4086 if (complex_type) {
4087 clang::QualType complex_element_type(complex_type->getElementType());
4088 if (complex_element_type->isIntegerType())
4089 complex_type_flags |= eTypeIsFloat;
4090 else if (complex_element_type->isFloatingType())
4091 complex_type_flags |= eTypeIsInteger;
4092 }
4093 return complex_type_flags;
4094 } break;
4095
4096 case clang::Type::ConstantArray:
4097 case clang::Type::DependentSizedArray:
4098 case clang::Type::IncompleteArray:
4099 case clang::Type::VariableArray:
4100 if (pointee_or_element_clang_type)
4101 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004102 this, llvm::cast<clang::ArrayType>(qual_type.getTypePtr())
4103 ->getElementType()
4104 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004105 return eTypeHasChildren | eTypeIsArray;
4106
4107 case clang::Type::DependentName:
4108 return 0;
4109 case clang::Type::DependentSizedExtVector:
4110 return eTypeHasChildren | eTypeIsVector;
4111 case clang::Type::DependentTemplateSpecialization:
4112 return eTypeIsTemplate;
4113 case clang::Type::Decltype:
Alex Langfordbddab072019-08-13 19:40:36 +00004114 return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type)
4115 ->getUnderlyingType()
4116 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004117 .GetTypeInfo(pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004118
4119 case clang::Type::Enum:
4120 if (pointee_or_element_clang_type)
4121 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004122 this, llvm::cast<clang::EnumType>(qual_type)
4123 ->getDecl()
4124 ->getIntegerType()
4125 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004126 return eTypeIsEnumeration | eTypeHasValue;
4127
4128 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00004129 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
4130 ->getDeducedType()
4131 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004132 .GetTypeInfo(pointee_or_element_clang_type);
4133 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00004134 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
4135 ->getNamedType()
4136 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004137 .GetTypeInfo(pointee_or_element_clang_type);
4138 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00004139 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
4140 ->desugar()
4141 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004142 .GetTypeInfo(pointee_or_element_clang_type);
4143
4144 case clang::Type::FunctionProto:
4145 return eTypeIsFuncPrototype | eTypeHasValue;
4146 case clang::Type::FunctionNoProto:
4147 return eTypeIsFuncPrototype | eTypeHasValue;
4148 case clang::Type::InjectedClassName:
4149 return 0;
4150
4151 case clang::Type::LValueReference:
4152 case clang::Type::RValueReference:
4153 if (pointee_or_element_clang_type)
4154 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004155 this, llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())
4156 ->getPointeeType()
4157 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004158 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
4159
4160 case clang::Type::MemberPointer:
4161 return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
4162
4163 case clang::Type::ObjCObjectPointer:
4164 if (pointee_or_element_clang_type)
4165 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004166 this, qual_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004167 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer |
4168 eTypeHasValue;
4169
4170 case clang::Type::ObjCObject:
4171 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
4172 case clang::Type::ObjCInterface:
4173 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
4174
4175 case clang::Type::Pointer:
4176 if (pointee_or_element_clang_type)
4177 pointee_or_element_clang_type->SetCompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004178 this, qual_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004179 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
4180
4181 case clang::Type::Record:
4182 if (qual_type->getAsCXXRecordDecl())
4183 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
4184 else
4185 return eTypeHasChildren | eTypeIsStructUnion;
4186 break;
4187 case clang::Type::SubstTemplateTypeParm:
4188 return eTypeIsTemplate;
4189 case clang::Type::TemplateTypeParm:
4190 return eTypeIsTemplate;
4191 case clang::Type::TemplateSpecialization:
4192 return eTypeIsTemplate;
4193
4194 case clang::Type::Typedef:
4195 return eTypeIsTypedef |
Alex Langfordbddab072019-08-13 19:40:36 +00004196 CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
4197 ->getDecl()
4198 ->getUnderlyingType()
4199 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004200 .GetTypeInfo(pointee_or_element_clang_type);
4201 case clang::Type::TypeOfExpr:
Alex Langfordbddab072019-08-13 19:40:36 +00004202 return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
4203 ->getUnderlyingExpr()
4204 ->getType()
4205 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004206 .GetTypeInfo(pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004207 case clang::Type::TypeOf:
Alex Langfordbddab072019-08-13 19:40:36 +00004208 return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
4209 ->getUnderlyingType()
4210 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004211 .GetTypeInfo(pointee_or_element_clang_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004212 case clang::Type::UnresolvedUsing:
4213 return 0;
4214
4215 case clang::Type::ExtVector:
4216 case clang::Type::Vector: {
4217 uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
4218 const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>(
4219 qual_type->getCanonicalTypeInternal());
4220 if (vector_type) {
4221 if (vector_type->isIntegerType())
4222 vector_type_flags |= eTypeIsFloat;
4223 else if (vector_type->isFloatingType())
4224 vector_type_flags |= eTypeIsInteger;
4225 }
4226 return vector_type_flags;
4227 }
4228 default:
4229 return 0;
4230 }
4231 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00004232}
4233
Greg Claytond8d4a572015-08-11 21:38:15 +00004234lldb::LanguageType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004235ClangASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
4236 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00004237 return lldb::eLanguageTypeC;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004238
4239 // If the type is a reference, then resolve it to what it refers to first:
4240 clang::QualType qual_type(GetCanonicalQualType(type).getNonReferenceType());
4241 if (qual_type->isAnyPointerType()) {
4242 if (qual_type->isObjCObjectPointerType())
4243 return lldb::eLanguageTypeObjC;
Adrian Prantl1db0f0c2019-05-02 23:07:23 +00004244 if (qual_type->getPointeeCXXRecordDecl())
4245 return lldb::eLanguageTypeC_plus_plus;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004246
4247 clang::QualType pointee_type(qual_type->getPointeeType());
Adrian Prantl1db0f0c2019-05-02 23:07:23 +00004248 if (pointee_type->getPointeeCXXRecordDecl())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004249 return lldb::eLanguageTypeC_plus_plus;
4250 if (pointee_type->isObjCObjectOrInterfaceType())
4251 return lldb::eLanguageTypeObjC;
4252 if (pointee_type->isObjCClassType())
4253 return lldb::eLanguageTypeObjC;
4254 if (pointee_type.getTypePtr() ==
4255 getASTContext()->ObjCBuiltinIdTy.getTypePtr())
4256 return lldb::eLanguageTypeObjC;
4257 } else {
4258 if (qual_type->isObjCObjectOrInterfaceType())
4259 return lldb::eLanguageTypeObjC;
4260 if (qual_type->getAsCXXRecordDecl())
4261 return lldb::eLanguageTypeC_plus_plus;
4262 switch (qual_type->getTypeClass()) {
4263 default:
4264 break;
4265 case clang::Type::Builtin:
4266 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
4267 default:
4268 case clang::BuiltinType::Void:
4269 case clang::BuiltinType::Bool:
4270 case clang::BuiltinType::Char_U:
4271 case clang::BuiltinType::UChar:
4272 case clang::BuiltinType::WChar_U:
4273 case clang::BuiltinType::Char16:
4274 case clang::BuiltinType::Char32:
4275 case clang::BuiltinType::UShort:
4276 case clang::BuiltinType::UInt:
4277 case clang::BuiltinType::ULong:
4278 case clang::BuiltinType::ULongLong:
4279 case clang::BuiltinType::UInt128:
4280 case clang::BuiltinType::Char_S:
4281 case clang::BuiltinType::SChar:
4282 case clang::BuiltinType::WChar_S:
4283 case clang::BuiltinType::Short:
4284 case clang::BuiltinType::Int:
4285 case clang::BuiltinType::Long:
4286 case clang::BuiltinType::LongLong:
4287 case clang::BuiltinType::Int128:
4288 case clang::BuiltinType::Float:
4289 case clang::BuiltinType::Double:
4290 case clang::BuiltinType::LongDouble:
4291 break;
4292
4293 case clang::BuiltinType::NullPtr:
4294 return eLanguageTypeC_plus_plus;
4295
4296 case clang::BuiltinType::ObjCId:
4297 case clang::BuiltinType::ObjCClass:
4298 case clang::BuiltinType::ObjCSel:
4299 return eLanguageTypeObjC;
4300
4301 case clang::BuiltinType::Dependent:
4302 case clang::BuiltinType::Overload:
4303 case clang::BuiltinType::BoundMember:
4304 case clang::BuiltinType::UnknownAny:
4305 break;
4306 }
4307 break;
4308 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00004309 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
4310 ->getDecl()
4311 ->getUnderlyingType()
4312 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004313 .GetMinimumLanguage();
4314 }
4315 }
4316 return lldb::eLanguageTypeC;
Greg Claytond8d4a572015-08-11 21:38:15 +00004317}
4318
4319lldb::TypeClass
Kate Stoneb9c1b512016-09-06 20:57:50 +00004320ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
4321 if (!type)
4322 return lldb::eTypeClassInvalid;
4323
4324 clang::QualType qual_type(GetQualType(type));
4325
4326 switch (qual_type->getTypeClass()) {
4327 case clang::Type::UnaryTransform:
4328 break;
4329 case clang::Type::FunctionNoProto:
4330 return lldb::eTypeClassFunction;
4331 case clang::Type::FunctionProto:
4332 return lldb::eTypeClassFunction;
4333 case clang::Type::IncompleteArray:
4334 return lldb::eTypeClassArray;
4335 case clang::Type::VariableArray:
4336 return lldb::eTypeClassArray;
4337 case clang::Type::ConstantArray:
4338 return lldb::eTypeClassArray;
4339 case clang::Type::DependentSizedArray:
4340 return lldb::eTypeClassArray;
4341 case clang::Type::DependentSizedExtVector:
4342 return lldb::eTypeClassVector;
Fangrui Song8f284882018-07-13 22:40:40 +00004343 case clang::Type::DependentVector:
4344 return lldb::eTypeClassVector;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004345 case clang::Type::ExtVector:
4346 return lldb::eTypeClassVector;
4347 case clang::Type::Vector:
4348 return lldb::eTypeClassVector;
4349 case clang::Type::Builtin:
4350 return lldb::eTypeClassBuiltin;
4351 case clang::Type::ObjCObjectPointer:
4352 return lldb::eTypeClassObjCObjectPointer;
4353 case clang::Type::BlockPointer:
4354 return lldb::eTypeClassBlockPointer;
4355 case clang::Type::Pointer:
4356 return lldb::eTypeClassPointer;
4357 case clang::Type::LValueReference:
4358 return lldb::eTypeClassReference;
4359 case clang::Type::RValueReference:
4360 return lldb::eTypeClassReference;
4361 case clang::Type::MemberPointer:
4362 return lldb::eTypeClassMemberPointer;
4363 case clang::Type::Complex:
4364 if (qual_type->isComplexType())
4365 return lldb::eTypeClassComplexFloat;
4366 else
4367 return lldb::eTypeClassComplexInteger;
4368 case clang::Type::ObjCObject:
4369 return lldb::eTypeClassObjCObject;
4370 case clang::Type::ObjCInterface:
4371 return lldb::eTypeClassObjCInterface;
4372 case clang::Type::Record: {
4373 const clang::RecordType *record_type =
4374 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4375 const clang::RecordDecl *record_decl = record_type->getDecl();
4376 if (record_decl->isUnion())
4377 return lldb::eTypeClassUnion;
4378 else if (record_decl->isStruct())
4379 return lldb::eTypeClassStruct;
4380 else
4381 return lldb::eTypeClassClass;
4382 } break;
4383 case clang::Type::Enum:
4384 return lldb::eTypeClassEnumeration;
4385 case clang::Type::Typedef:
4386 return lldb::eTypeClassTypedef;
4387 case clang::Type::UnresolvedUsing:
4388 break;
4389 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00004390 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
4391 ->desugar()
4392 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004393 .GetTypeClass();
4394 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00004395 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
4396 ->getDeducedType()
4397 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004398 .GetTypeClass();
4399 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00004400 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
4401 ->getNamedType()
4402 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004403 .GetTypeClass();
4404
4405 case clang::Type::Attributed:
4406 break;
4407 case clang::Type::TemplateTypeParm:
4408 break;
4409 case clang::Type::SubstTemplateTypeParm:
4410 break;
4411 case clang::Type::SubstTemplateTypeParmPack:
4412 break;
4413 case clang::Type::InjectedClassName:
4414 break;
4415 case clang::Type::DependentName:
4416 break;
4417 case clang::Type::DependentTemplateSpecialization:
4418 break;
4419 case clang::Type::PackExpansion:
4420 break;
4421
4422 case clang::Type::TypeOfExpr:
Alex Langfordbddab072019-08-13 19:40:36 +00004423 return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
4424 ->getUnderlyingExpr()
4425 ->getType()
4426 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004427 .GetTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00004428 case clang::Type::TypeOf:
Alex Langfordbddab072019-08-13 19:40:36 +00004429 return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
4430 ->getUnderlyingType()
4431 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004432 .GetTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00004433 case clang::Type::Decltype:
Alex Langfordbddab072019-08-13 19:40:36 +00004434 return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
4435 ->getUnderlyingType()
4436 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00004437 .GetTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00004438 case clang::Type::TemplateSpecialization:
4439 break;
Pavel Labath4f19fce22017-02-17 13:39:50 +00004440 case clang::Type::DeducedTemplateSpecialization:
4441 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004442 case clang::Type::Atomic:
4443 break;
4444 case clang::Type::Pipe:
4445 break;
4446
4447 // pointer type decayed from an array or function type.
4448 case clang::Type::Decayed:
4449 break;
4450 case clang::Type::Adjusted:
4451 break;
Zachary Turner5a8ad4592016-10-05 17:07:34 +00004452 case clang::Type::ObjCTypeParam:
4453 break;
Ted Woodward66060cf2017-10-11 22:42:21 +00004454
4455 case clang::Type::DependentAddressSpace:
4456 break;
Krasimir Georgiev435e76a2019-05-07 13:59:30 +00004457 case clang::Type::MacroQualified:
4458 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004459 }
4460 // We don't know hot to display this type...
4461 return lldb::eTypeClassOther;
Greg Claytond8d4a572015-08-11 21:38:15 +00004462}
4463
Kate Stoneb9c1b512016-09-06 20:57:50 +00004464unsigned ClangASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
4465 if (type)
4466 return GetQualType(type).getQualifiers().getCVRQualifiers();
4467 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00004468}
4469
Greg Claytond8d4a572015-08-11 21:38:15 +00004470// Creating related types
Greg Claytond8d4a572015-08-11 21:38:15 +00004471
Greg Claytona1e5dc82015-08-11 22:53:00 +00004472CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004473ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
4474 uint64_t *stride) {
4475 if (type) {
4476 clang::QualType qual_type(GetCanonicalQualType(type));
4477
4478 const clang::Type *array_eletype =
4479 qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
4480
4481 if (!array_eletype)
4482 return CompilerType();
4483
Alex Langfordbddab072019-08-13 19:40:36 +00004484 CompilerType element_type(
4485 this, array_eletype->getCanonicalTypeUnqualified().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004486
4487 // TODO: the real stride will be >= this value.. find the real one!
4488 if (stride)
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00004489 if (Optional<uint64_t> size = element_type.GetByteSize(nullptr))
Adrian Prantld963a7c2019-01-15 18:07:52 +00004490 *stride = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004491
4492 return element_type;
4493 }
4494 return CompilerType();
4495}
4496
4497CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type,
4498 uint64_t size) {
4499 if (type) {
4500 clang::QualType qual_type(GetCanonicalQualType(type));
4501 if (clang::ASTContext *ast_ctx = getASTContext()) {
4502 if (size != 0)
4503 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004504 this, ast_ctx
4505 ->getConstantArrayType(
4506 qual_type, llvm::APInt(64, size),
4507 clang::ArrayType::ArraySizeModifier::Normal, 0)
4508 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004509 else
4510 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004511 this,
4512 ast_ctx
4513 ->getIncompleteArrayType(
4514 qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0)
4515 .getAsOpaquePtr());
Greg Claytond8d4a572015-08-11 21:38:15 +00004516 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004517 }
4518
4519 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004520}
4521
Greg Claytona1e5dc82015-08-11 22:53:00 +00004522CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004523ClangASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
4524 if (type)
Alex Langfordbddab072019-08-13 19:40:36 +00004525 return CompilerType(this, GetCanonicalQualType(type).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004526 return CompilerType();
4527}
4528
4529static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast,
4530 clang::QualType qual_type) {
4531 if (qual_type->isPointerType())
4532 qual_type = ast->getPointerType(
4533 GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType()));
4534 else
4535 qual_type = qual_type.getUnqualifiedType();
4536 qual_type.removeLocalConst();
4537 qual_type.removeLocalRestrict();
4538 qual_type.removeLocalVolatile();
4539 return qual_type;
Enrico Granata639392f2016-08-30 20:39:58 +00004540}
4541
4542CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004543ClangASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
4544 if (type)
4545 return CompilerType(
Alex Langfordbddab072019-08-13 19:40:36 +00004546 this,
4547 GetFullyUnqualifiedType_Impl(getASTContext(), GetQualType(type)).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004548 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004549}
4550
Kate Stoneb9c1b512016-09-06 20:57:50 +00004551int ClangASTContext::GetFunctionArgumentCount(
4552 lldb::opaque_compiler_type_t type) {
4553 if (type) {
4554 const clang::FunctionProtoType *func =
4555 llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType(type));
4556 if (func)
4557 return func->getNumParams();
4558 }
4559 return -1;
4560}
4561
4562CompilerType ClangASTContext::GetFunctionArgumentTypeAtIndex(
4563 lldb::opaque_compiler_type_t type, size_t idx) {
4564 if (type) {
4565 const clang::FunctionProtoType *func =
4566 llvm::dyn_cast<clang::FunctionProtoType>(GetQualType(type));
4567 if (func) {
4568 const uint32_t num_args = func->getNumParams();
4569 if (idx < num_args)
Alex Langfordbddab072019-08-13 19:40:36 +00004570 return CompilerType(this, func->getParamType(idx).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004571 }
4572 }
4573 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004574}
4575
Greg Claytona1e5dc82015-08-11 22:53:00 +00004576CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004577ClangASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
4578 if (type) {
4579 clang::QualType qual_type(GetQualType(type));
4580 const clang::FunctionProtoType *func =
4581 llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
4582 if (func)
Alex Langfordbddab072019-08-13 19:40:36 +00004583 return CompilerType(this, func->getReturnType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004584 }
4585 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004586}
4587
4588size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00004589ClangASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
4590 size_t num_functions = 0;
4591 if (type) {
4592 clang::QualType qual_type(GetCanonicalQualType(type));
4593 switch (qual_type->getTypeClass()) {
4594 case clang::Type::Record:
4595 if (GetCompleteQualType(getASTContext(), qual_type)) {
4596 const clang::RecordType *record_type =
4597 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4598 const clang::RecordDecl *record_decl = record_type->getDecl();
4599 assert(record_decl);
4600 const clang::CXXRecordDecl *cxx_record_decl =
4601 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
4602 if (cxx_record_decl)
4603 num_functions = std::distance(cxx_record_decl->method_begin(),
4604 cxx_record_decl->method_end());
4605 }
4606 break;
Enrico Granata36f51e42015-12-18 22:41:25 +00004607
Sean Callananf9c622a2016-09-30 18:44:43 +00004608 case clang::Type::ObjCObjectPointer: {
4609 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00004610 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00004611 const clang::ObjCInterfaceType *objc_interface_type =
4612 objc_class_type->getInterfaceType();
4613 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00004614 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
4615 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00004616 clang::ObjCInterfaceDecl *class_interface_decl =
4617 objc_interface_type->getDecl();
4618 if (class_interface_decl) {
4619 num_functions = std::distance(class_interface_decl->meth_begin(),
4620 class_interface_decl->meth_end());
Greg Claytond8d4a572015-08-11 21:38:15 +00004621 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004622 }
4623 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00004624 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004625
4626 case clang::Type::ObjCObject:
4627 case clang::Type::ObjCInterface:
4628 if (GetCompleteType(type)) {
4629 const clang::ObjCObjectType *objc_class_type =
4630 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
4631 if (objc_class_type) {
4632 clang::ObjCInterfaceDecl *class_interface_decl =
4633 objc_class_type->getInterface();
4634 if (class_interface_decl)
4635 num_functions = std::distance(class_interface_decl->meth_begin(),
4636 class_interface_decl->meth_end());
4637 }
4638 }
4639 break;
4640
4641 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00004642 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
4643 ->getDecl()
4644 ->getUnderlyingType()
4645 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004646 .GetNumMemberFunctions();
4647
4648 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00004649 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
4650 ->getDeducedType()
4651 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004652 .GetNumMemberFunctions();
4653
4654 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00004655 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
4656 ->getNamedType()
4657 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004658 .GetNumMemberFunctions();
4659
4660 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00004661 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
4662 ->desugar()
4663 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004664 .GetNumMemberFunctions();
4665
4666 default:
4667 break;
Greg Claytond8d4a572015-08-11 21:38:15 +00004668 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004669 }
4670 return num_functions;
Greg Claytond8d4a572015-08-11 21:38:15 +00004671}
4672
4673TypeMemberFunctionImpl
Kate Stoneb9c1b512016-09-06 20:57:50 +00004674ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
4675 size_t idx) {
4676 std::string name;
4677 MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
4678 CompilerType clang_type;
4679 CompilerDecl clang_decl;
4680 if (type) {
4681 clang::QualType qual_type(GetCanonicalQualType(type));
4682 switch (qual_type->getTypeClass()) {
4683 case clang::Type::Record:
4684 if (GetCompleteQualType(getASTContext(), qual_type)) {
4685 const clang::RecordType *record_type =
4686 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4687 const clang::RecordDecl *record_decl = record_type->getDecl();
4688 assert(record_decl);
4689 const clang::CXXRecordDecl *cxx_record_decl =
4690 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
4691 if (cxx_record_decl) {
4692 auto method_iter = cxx_record_decl->method_begin();
4693 auto method_end = cxx_record_decl->method_end();
4694 if (idx <
4695 static_cast<size_t>(std::distance(method_iter, method_end))) {
4696 std::advance(method_iter, idx);
4697 clang::CXXMethodDecl *cxx_method_decl =
4698 method_iter->getCanonicalDecl();
4699 if (cxx_method_decl) {
4700 name = cxx_method_decl->getDeclName().getAsString();
4701 if (cxx_method_decl->isStatic())
4702 kind = lldb::eMemberFunctionKindStaticMethod;
4703 else if (llvm::isa<clang::CXXConstructorDecl>(cxx_method_decl))
4704 kind = lldb::eMemberFunctionKindConstructor;
4705 else if (llvm::isa<clang::CXXDestructorDecl>(cxx_method_decl))
4706 kind = lldb::eMemberFunctionKindDestructor;
4707 else
4708 kind = lldb::eMemberFunctionKindInstanceMethod;
4709 clang_type = CompilerType(
4710 this, cxx_method_decl->getType().getAsOpaquePtr());
4711 clang_decl = CompilerDecl(this, cxx_method_decl);
4712 }
4713 }
Greg Claytond8d4a572015-08-11 21:38:15 +00004714 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004715 }
4716 break;
Greg Claytond8d4a572015-08-11 21:38:15 +00004717
Sean Callananf9c622a2016-09-30 18:44:43 +00004718 case clang::Type::ObjCObjectPointer: {
4719 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00004720 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00004721 const clang::ObjCInterfaceType *objc_interface_type =
4722 objc_class_type->getInterfaceType();
4723 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00004724 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
4725 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00004726 clang::ObjCInterfaceDecl *class_interface_decl =
4727 objc_interface_type->getDecl();
4728 if (class_interface_decl) {
4729 auto method_iter = class_interface_decl->meth_begin();
4730 auto method_end = class_interface_decl->meth_end();
4731 if (idx <
4732 static_cast<size_t>(std::distance(method_iter, method_end))) {
4733 std::advance(method_iter, idx);
4734 clang::ObjCMethodDecl *objc_method_decl =
4735 method_iter->getCanonicalDecl();
4736 if (objc_method_decl) {
4737 clang_decl = CompilerDecl(this, objc_method_decl);
4738 name = objc_method_decl->getSelector().getAsString();
4739 if (objc_method_decl->isClassMethod())
4740 kind = lldb::eMemberFunctionKindStaticMethod;
4741 else
4742 kind = lldb::eMemberFunctionKindInstanceMethod;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004743 }
4744 }
Greg Claytond8d4a572015-08-11 21:38:15 +00004745 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004746 }
4747 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00004748 }
Greg Claytond8d4a572015-08-11 21:38:15 +00004749
Kate Stoneb9c1b512016-09-06 20:57:50 +00004750 case clang::Type::ObjCObject:
4751 case clang::Type::ObjCInterface:
4752 if (GetCompleteType(type)) {
4753 const clang::ObjCObjectType *objc_class_type =
4754 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
4755 if (objc_class_type) {
4756 clang::ObjCInterfaceDecl *class_interface_decl =
4757 objc_class_type->getInterface();
4758 if (class_interface_decl) {
4759 auto method_iter = class_interface_decl->meth_begin();
4760 auto method_end = class_interface_decl->meth_end();
4761 if (idx <
4762 static_cast<size_t>(std::distance(method_iter, method_end))) {
4763 std::advance(method_iter, idx);
4764 clang::ObjCMethodDecl *objc_method_decl =
4765 method_iter->getCanonicalDecl();
4766 if (objc_method_decl) {
4767 clang_decl = CompilerDecl(this, objc_method_decl);
4768 name = objc_method_decl->getSelector().getAsString();
4769 if (objc_method_decl->isClassMethod())
4770 kind = lldb::eMemberFunctionKindStaticMethod;
4771 else
4772 kind = lldb::eMemberFunctionKindInstanceMethod;
4773 }
4774 }
4775 }
Ewan Crawford27fc7a72016-03-15 09:50:16 +00004776 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004777 }
4778 break;
Ewan Crawford27fc7a72016-03-15 09:50:16 +00004779
Kate Stoneb9c1b512016-09-06 20:57:50 +00004780 case clang::Type::Typedef:
4781 return GetMemberFunctionAtIndex(llvm::cast<clang::TypedefType>(qual_type)
4782 ->getDecl()
4783 ->getUnderlyingType()
4784 .getAsOpaquePtr(),
4785 idx);
Ewan Crawford27fc7a72016-03-15 09:50:16 +00004786
Kate Stoneb9c1b512016-09-06 20:57:50 +00004787 case clang::Type::Auto:
4788 return GetMemberFunctionAtIndex(llvm::cast<clang::AutoType>(qual_type)
4789 ->getDeducedType()
4790 .getAsOpaquePtr(),
4791 idx);
Greg Clayton56939cb2015-09-17 22:23:34 +00004792
Kate Stoneb9c1b512016-09-06 20:57:50 +00004793 case clang::Type::Elaborated:
4794 return GetMemberFunctionAtIndex(
4795 llvm::cast<clang::ElaboratedType>(qual_type)
4796 ->getNamedType()
4797 .getAsOpaquePtr(),
4798 idx);
Greg Clayton56939cb2015-09-17 22:23:34 +00004799
Kate Stoneb9c1b512016-09-06 20:57:50 +00004800 case clang::Type::Paren:
4801 return GetMemberFunctionAtIndex(
4802 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
4803 idx);
4804
4805 default:
4806 break;
Greg Clayton56939cb2015-09-17 22:23:34 +00004807 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004808 }
Greg Clayton56939cb2015-09-17 22:23:34 +00004809
Kate Stoneb9c1b512016-09-06 20:57:50 +00004810 if (kind == eMemberFunctionKindUnknown)
4811 return TypeMemberFunctionImpl();
4812 else
4813 return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
Greg Clayton56939cb2015-09-17 22:23:34 +00004814}
4815
Greg Claytona1e5dc82015-08-11 22:53:00 +00004816CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00004817ClangASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
4818 if (type)
Alex Langfordbddab072019-08-13 19:40:36 +00004819 return CompilerType(
4820 this, GetQualType(type).getNonReferenceType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004821 return CompilerType();
4822}
4823
4824CompilerType ClangASTContext::CreateTypedefType(
4825 const CompilerType &type, const char *typedef_name,
4826 const CompilerDeclContext &compiler_decl_ctx) {
4827 if (type && typedef_name && typedef_name[0]) {
4828 ClangASTContext *ast =
4829 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
4830 if (!ast)
4831 return CompilerType();
4832 clang::ASTContext *clang_ast = ast->getASTContext();
4833 clang::QualType qual_type(ClangUtil::GetQualType(type));
4834
4835 clang::DeclContext *decl_ctx =
4836 ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
4837 if (decl_ctx == nullptr)
4838 decl_ctx = ast->getASTContext()->getTranslationUnitDecl();
4839
4840 clang::TypedefDecl *decl = clang::TypedefDecl::Create(
4841 *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
4842 &clang_ast->Idents.get(typedef_name),
4843 clang_ast->getTrivialTypeSourceInfo(qual_type));
4844
4845 decl->setAccess(clang::AS_public); // TODO respect proper access specifier
4846
Aleksandr Urakov709426b2018-09-10 08:08:43 +00004847 decl_ctx->addDecl(decl);
4848
Kate Stoneb9c1b512016-09-06 20:57:50 +00004849 // Get a uniqued clang::QualType for the typedef decl type
Alex Langfordbddab072019-08-13 19:40:36 +00004850 return CompilerType(ast, clang_ast->getTypedefType(decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004851 }
4852 return CompilerType();
4853}
4854
4855CompilerType
4856ClangASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
4857 if (type) {
4858 clang::QualType qual_type(GetQualType(type));
Alex Langfordbddab072019-08-13 19:40:36 +00004859 return CompilerType(
4860 this, qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004861 }
4862 return CompilerType();
4863}
4864
4865CompilerType
4866ClangASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
4867 if (type) {
4868 clang::QualType qual_type(GetQualType(type));
4869
4870 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4871 switch (type_class) {
4872 case clang::Type::ObjCObject:
4873 case clang::Type::ObjCInterface:
Alex Langfordbddab072019-08-13 19:40:36 +00004874 return CompilerType(this, getASTContext()
4875 ->getObjCObjectPointerType(qual_type)
4876 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004877
4878 default:
Alex Langfordbddab072019-08-13 19:40:36 +00004879 return CompilerType(
4880 this, getASTContext()->getPointerType(qual_type).getAsOpaquePtr());
Greg Claytond8d4a572015-08-11 21:38:15 +00004881 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004882 }
4883 return CompilerType();
4884}
4885
4886CompilerType
4887ClangASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
4888 if (type)
4889 return CompilerType(this, getASTContext()
4890 ->getLValueReferenceType(GetQualType(type))
4891 .getAsOpaquePtr());
4892 else
Greg Claytona1e5dc82015-08-11 22:53:00 +00004893 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00004894}
4895
Kate Stoneb9c1b512016-09-06 20:57:50 +00004896CompilerType
4897ClangASTContext::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
4898 if (type)
4899 return CompilerType(this, getASTContext()
4900 ->getRValueReferenceType(GetQualType(type))
4901 .getAsOpaquePtr());
4902 else
4903 return CompilerType();
4904}
4905
4906CompilerType
4907ClangASTContext::AddConstModifier(lldb::opaque_compiler_type_t type) {
4908 if (type) {
4909 clang::QualType result(GetQualType(type));
4910 result.addConst();
4911 return CompilerType(this, result.getAsOpaquePtr());
4912 }
4913 return CompilerType();
4914}
4915
4916CompilerType
4917ClangASTContext::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
4918 if (type) {
4919 clang::QualType result(GetQualType(type));
4920 result.addVolatile();
4921 return CompilerType(this, result.getAsOpaquePtr());
4922 }
4923 return CompilerType();
4924}
4925
4926CompilerType
4927ClangASTContext::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
4928 if (type) {
4929 clang::QualType result(GetQualType(type));
4930 result.addRestrict();
4931 return CompilerType(this, result.getAsOpaquePtr());
4932 }
4933 return CompilerType();
4934}
4935
4936CompilerType
4937ClangASTContext::CreateTypedef(lldb::opaque_compiler_type_t type,
4938 const char *typedef_name,
4939 const CompilerDeclContext &compiler_decl_ctx) {
4940 if (type) {
4941 clang::ASTContext *clang_ast = getASTContext();
4942 clang::QualType qual_type(GetQualType(type));
4943
4944 clang::DeclContext *decl_ctx =
4945 ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
4946 if (decl_ctx == nullptr)
4947 decl_ctx = getASTContext()->getTranslationUnitDecl();
4948
4949 clang::TypedefDecl *decl = clang::TypedefDecl::Create(
4950 *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
4951 &clang_ast->Idents.get(typedef_name),
4952 clang_ast->getTrivialTypeSourceInfo(qual_type));
4953
4954 clang::TagDecl *tdecl = nullptr;
4955 if (!qual_type.isNull()) {
4956 if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
4957 tdecl = rt->getDecl();
4958 if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
4959 tdecl = et->getDecl();
4960 }
4961
4962 // Check whether this declaration is an anonymous struct, union, or enum,
Adrian Prantl05097242018-04-30 16:49:04 +00004963 // hidden behind a typedef. If so, we try to check whether we have a
4964 // typedef tag to attach to the original record declaration
Kate Stoneb9c1b512016-09-06 20:57:50 +00004965 if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
4966 tdecl->setTypedefNameForAnonDecl(decl);
4967
4968 decl->setAccess(clang::AS_public); // TODO respect proper access specifier
4969
4970 // Get a uniqued clang::QualType for the typedef decl type
4971 return CompilerType(this, clang_ast->getTypedefType(decl).getAsOpaquePtr());
4972 }
4973 return CompilerType();
4974}
4975
4976CompilerType
4977ClangASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
4978 if (type) {
4979 const clang::TypedefType *typedef_type =
4980 llvm::dyn_cast<clang::TypedefType>(GetQualType(type));
4981 if (typedef_type)
Alex Langfordbddab072019-08-13 19:40:36 +00004982 return CompilerType(
4983 this, typedef_type->getDecl()->getUnderlyingType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004984 }
4985 return CompilerType();
4986}
Greg Claytond8d4a572015-08-11 21:38:15 +00004987
Greg Claytond8d4a572015-08-11 21:38:15 +00004988// Create related types using the current type's AST
Greg Claytond8d4a572015-08-11 21:38:15 +00004989
Kate Stoneb9c1b512016-09-06 20:57:50 +00004990CompilerType ClangASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
4991 return ClangASTContext::GetBasicType(getASTContext(), basic_type);
Greg Claytond8d4a572015-08-11 21:38:15 +00004992}
Greg Claytond8d4a572015-08-11 21:38:15 +00004993// Exploring the type
Greg Claytond8d4a572015-08-11 21:38:15 +00004994
Alex Langfordb482db62019-09-06 21:05:21 +00004995const llvm::fltSemantics &
4996ClangASTContext::GetFloatTypeSemantics(size_t byte_size) {
4997 if (auto *ast = getASTContext()) {
4998 const size_t bit_size = byte_size * 8;
4999 if (bit_size == ast->getTypeSize(ast->FloatTy))
5000 return ast->getFloatTypeSemantics(ast->FloatTy);
5001 else if (bit_size == ast->getTypeSize(ast->DoubleTy))
5002 return ast->getFloatTypeSemantics(ast->DoubleTy);
5003 else if (bit_size == ast->getTypeSize(ast->LongDoubleTy))
5004 return ast->getFloatTypeSemantics(ast->LongDoubleTy);
5005 else if (bit_size == ast->getTypeSize(ast->HalfTy))
5006 return ast->getFloatTypeSemantics(ast->HalfTy);
5007 }
5008 return llvm::APFloatBase::Bogus();
5009}
5010
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005011Optional<uint64_t>
5012ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
5013 ExecutionContextScope *exe_scope) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005014 if (GetCompleteType(type)) {
Greg Claytond8d4a572015-08-11 21:38:15 +00005015 clang::QualType qual_type(GetCanonicalQualType(type));
Greg Claytond8d4a572015-08-11 21:38:15 +00005016 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005017 switch (type_class) {
5018 case clang::Type::Record:
5019 if (GetCompleteType(type))
5020 return getASTContext()->getTypeSize(qual_type);
5021 else
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005022 return None;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005023 break;
Enrico Granata36f51e42015-12-18 22:41:25 +00005024
Kate Stoneb9c1b512016-09-06 20:57:50 +00005025 case clang::Type::ObjCInterface:
5026 case clang::Type::ObjCObject: {
5027 ExecutionContext exe_ctx(exe_scope);
5028 Process *process = exe_ctx.GetProcessPtr();
5029 if (process) {
Alex Langforde823bbe2019-06-10 20:53:23 +00005030 ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005031 if (objc_runtime) {
5032 uint64_t bit_size = 0;
5033 if (objc_runtime->GetTypeBitSize(
Alex Langfordbddab072019-08-13 19:40:36 +00005034 CompilerType(this, qual_type.getAsOpaquePtr()), bit_size))
Kate Stoneb9c1b512016-09-06 20:57:50 +00005035 return bit_size;
5036 }
5037 } else {
5038 static bool g_printed = false;
5039 if (!g_printed) {
5040 StreamString s;
5041 DumpTypeDescription(type, &s);
5042
5043 llvm::outs() << "warning: trying to determine the size of type ";
5044 llvm::outs() << s.GetString() << "\n";
5045 llvm::outs() << "without a valid ExecutionContext. this is not "
5046 "reliable. please file a bug against LLDB.\n";
5047 llvm::outs() << "backtrace:\n";
5048 llvm::sys::PrintStackTrace(llvm::outs());
5049 llvm::outs() << "\n";
5050 g_printed = true;
5051 }
5052 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005053 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005054 LLVM_FALLTHROUGH;
5055 default:
5056 const uint32_t bit_size = getASTContext()->getTypeSize(qual_type);
5057 if (bit_size == 0) {
5058 if (qual_type->isIncompleteArrayType())
5059 return getASTContext()->getTypeSize(
5060 qual_type->getArrayElementTypeNoTypeQual()
5061 ->getCanonicalTypeUnqualified());
5062 }
5063 if (qual_type->isObjCObjectOrInterfaceType())
5064 return bit_size +
5065 getASTContext()->getTypeSize(
5066 getASTContext()->ObjCBuiltinClassTy);
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005067 // Function types actually have a size of 0, that's not an error.
5068 if (qual_type->isFunctionProtoType())
5069 return bit_size;
5070 if (bit_size)
5071 return bit_size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005072 }
5073 }
Adrian Prantl2ee7b882019-01-16 21:19:20 +00005074 return None;
Greg Claytond8d4a572015-08-11 21:38:15 +00005075}
5076
Davide Italiano36f13e42019-08-12 20:03:19 +00005077llvm::Optional<size_t>
Davide Italiano7f9bbe02019-08-12 21:49:54 +00005078ClangASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type,
5079 ExecutionContextScope *exe_scope) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005080 if (GetCompleteType(type))
5081 return getASTContext()->getTypeAlign(GetQualType(type));
Davide Italiano36f13e42019-08-12 20:03:19 +00005082 return {};
Kate Stoneb9c1b512016-09-06 20:57:50 +00005083}
5084
5085lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
5086 uint64_t &count) {
5087 if (!type)
5088 return lldb::eEncodingInvalid;
5089
5090 count = 1;
5091 clang::QualType qual_type(GetCanonicalQualType(type));
5092
5093 switch (qual_type->getTypeClass()) {
5094 case clang::Type::UnaryTransform:
5095 break;
5096
5097 case clang::Type::FunctionNoProto:
5098 case clang::Type::FunctionProto:
5099 break;
5100
5101 case clang::Type::IncompleteArray:
5102 case clang::Type::VariableArray:
5103 break;
5104
5105 case clang::Type::ConstantArray:
5106 break;
5107
Fangrui Song8f284882018-07-13 22:40:40 +00005108 case clang::Type::DependentVector:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005109 case clang::Type::ExtVector:
5110 case clang::Type::Vector:
5111 // TODO: Set this to more than one???
5112 break;
5113
5114 case clang::Type::Builtin:
5115 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5116 case clang::BuiltinType::Void:
5117 break;
5118
5119 case clang::BuiltinType::Bool:
5120 case clang::BuiltinType::Char_S:
5121 case clang::BuiltinType::SChar:
5122 case clang::BuiltinType::WChar_S:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005123 case clang::BuiltinType::Short:
5124 case clang::BuiltinType::Int:
5125 case clang::BuiltinType::Long:
5126 case clang::BuiltinType::LongLong:
5127 case clang::BuiltinType::Int128:
5128 return lldb::eEncodingSint;
5129
5130 case clang::BuiltinType::Char_U:
5131 case clang::BuiltinType::UChar:
5132 case clang::BuiltinType::WChar_U:
Richard Smith51d12d82018-05-02 02:43:22 +00005133 case clang::BuiltinType::Char8:
5134 case clang::BuiltinType::Char16:
5135 case clang::BuiltinType::Char32:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005136 case clang::BuiltinType::UShort:
5137 case clang::BuiltinType::UInt:
5138 case clang::BuiltinType::ULong:
5139 case clang::BuiltinType::ULongLong:
5140 case clang::BuiltinType::UInt128:
5141 return lldb::eEncodingUint;
5142
Ilya Biryukovfc48ac62018-06-05 10:07:07 +00005143 // Fixed point types. Note that they are currently ignored.
5144 case clang::BuiltinType::ShortAccum:
5145 case clang::BuiltinType::Accum:
5146 case clang::BuiltinType::LongAccum:
5147 case clang::BuiltinType::UShortAccum:
5148 case clang::BuiltinType::UAccum:
5149 case clang::BuiltinType::ULongAccum:
Fangrui Songa5e59c52018-06-14 18:19:40 +00005150 case clang::BuiltinType::ShortFract:
Fangrui Songa5e59c52018-06-14 18:19:40 +00005151 case clang::BuiltinType::Fract:
5152 case clang::BuiltinType::LongFract:
5153 case clang::BuiltinType::UShortFract:
5154 case clang::BuiltinType::UFract:
5155 case clang::BuiltinType::ULongFract:
5156 case clang::BuiltinType::SatShortAccum:
5157 case clang::BuiltinType::SatAccum:
5158 case clang::BuiltinType::SatLongAccum:
5159 case clang::BuiltinType::SatUShortAccum:
5160 case clang::BuiltinType::SatUAccum:
5161 case clang::BuiltinType::SatULongAccum:
5162 case clang::BuiltinType::SatShortFract:
5163 case clang::BuiltinType::SatFract:
5164 case clang::BuiltinType::SatLongFract:
5165 case clang::BuiltinType::SatUShortFract:
5166 case clang::BuiltinType::SatUFract:
5167 case clang::BuiltinType::SatULongFract:
Ilya Biryukovfc48ac62018-06-05 10:07:07 +00005168 break;
5169
Kate Stoneb9c1b512016-09-06 20:57:50 +00005170 case clang::BuiltinType::Half:
5171 case clang::BuiltinType::Float:
Ted Woodward4355c7c2017-09-20 19:16:53 +00005172 case clang::BuiltinType::Float16:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005173 case clang::BuiltinType::Float128:
5174 case clang::BuiltinType::Double:
5175 case clang::BuiltinType::LongDouble:
5176 return lldb::eEncodingIEEE754;
5177
5178 case clang::BuiltinType::ObjCClass:
5179 case clang::BuiltinType::ObjCId:
5180 case clang::BuiltinType::ObjCSel:
5181 return lldb::eEncodingUint;
5182
5183 case clang::BuiltinType::NullPtr:
5184 return lldb::eEncodingUint;
5185
5186 case clang::BuiltinType::Kind::ARCUnbridgedCast:
5187 case clang::BuiltinType::Kind::BoundMember:
5188 case clang::BuiltinType::Kind::BuiltinFn:
5189 case clang::BuiltinType::Kind::Dependent:
5190 case clang::BuiltinType::Kind::OCLClkEvent:
5191 case clang::BuiltinType::Kind::OCLEvent:
5192 case clang::BuiltinType::Kind::OCLImage1dRO:
5193 case clang::BuiltinType::Kind::OCLImage1dWO:
5194 case clang::BuiltinType::Kind::OCLImage1dRW:
5195 case clang::BuiltinType::Kind::OCLImage1dArrayRO:
5196 case clang::BuiltinType::Kind::OCLImage1dArrayWO:
5197 case clang::BuiltinType::Kind::OCLImage1dArrayRW:
5198 case clang::BuiltinType::Kind::OCLImage1dBufferRO:
5199 case clang::BuiltinType::Kind::OCLImage1dBufferWO:
5200 case clang::BuiltinType::Kind::OCLImage1dBufferRW:
5201 case clang::BuiltinType::Kind::OCLImage2dRO:
5202 case clang::BuiltinType::Kind::OCLImage2dWO:
5203 case clang::BuiltinType::Kind::OCLImage2dRW:
5204 case clang::BuiltinType::Kind::OCLImage2dArrayRO:
5205 case clang::BuiltinType::Kind::OCLImage2dArrayWO:
5206 case clang::BuiltinType::Kind::OCLImage2dArrayRW:
5207 case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
5208 case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
5209 case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
5210 case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
5211 case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
5212 case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
5213 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
5214 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
5215 case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
5216 case clang::BuiltinType::Kind::OCLImage2dDepthRO:
5217 case clang::BuiltinType::Kind::OCLImage2dDepthWO:
5218 case clang::BuiltinType::Kind::OCLImage2dDepthRW:
5219 case clang::BuiltinType::Kind::OCLImage2dMSAARO:
5220 case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
5221 case clang::BuiltinType::Kind::OCLImage2dMSAARW:
5222 case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
5223 case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
5224 case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
5225 case clang::BuiltinType::Kind::OCLImage3dRO:
5226 case clang::BuiltinType::Kind::OCLImage3dWO:
5227 case clang::BuiltinType::Kind::OCLImage3dRW:
5228 case clang::BuiltinType::Kind::OCLQueue:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005229 case clang::BuiltinType::Kind::OCLReserveID:
5230 case clang::BuiltinType::Kind::OCLSampler:
5231 case clang::BuiltinType::Kind::OMPArraySection:
5232 case clang::BuiltinType::Kind::Overload:
5233 case clang::BuiltinType::Kind::PseudoObject:
5234 case clang::BuiltinType::Kind::UnknownAny:
5235 break;
Jorge Gorbe Moyaa6e6c182018-11-08 22:04:58 +00005236
5237 case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload:
5238 case clang::BuiltinType::OCLIntelSubgroupAVCImePayload:
5239 case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload:
5240 case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload:
5241 case clang::BuiltinType::OCLIntelSubgroupAVCMceResult:
5242 case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
5243 case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
5244 case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
5245 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout:
5246 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout:
5247 case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin:
5248 case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
5249 break;
Raphael Isemann339b5d12019-08-09 09:58:47 +00005250
5251 case clang::BuiltinType::SveBool:
5252 case clang::BuiltinType::SveInt8:
5253 case clang::BuiltinType::SveInt16:
5254 case clang::BuiltinType::SveInt32:
5255 case clang::BuiltinType::SveInt64:
5256 case clang::BuiltinType::SveUint8:
5257 case clang::BuiltinType::SveUint16:
5258 case clang::BuiltinType::SveUint32:
5259 case clang::BuiltinType::SveUint64:
5260 case clang::BuiltinType::SveFloat16:
5261 case clang::BuiltinType::SveFloat32:
5262 case clang::BuiltinType::SveFloat64:
5263 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005264 }
5265 break;
Adrian Prantl05097242018-04-30 16:49:04 +00005266 // All pointer types are represented as unsigned integer encodings. We may
5267 // nee to add a eEncodingPointer if we ever need to know the difference
Kate Stoneb9c1b512016-09-06 20:57:50 +00005268 case clang::Type::ObjCObjectPointer:
5269 case clang::Type::BlockPointer:
5270 case clang::Type::Pointer:
5271 case clang::Type::LValueReference:
5272 case clang::Type::RValueReference:
5273 case clang::Type::MemberPointer:
5274 return lldb::eEncodingUint;
5275 case clang::Type::Complex: {
5276 lldb::Encoding encoding = lldb::eEncodingIEEE754;
5277 if (qual_type->isComplexType())
5278 encoding = lldb::eEncodingIEEE754;
5279 else {
5280 const clang::ComplexType *complex_type =
5281 qual_type->getAsComplexIntegerType();
5282 if (complex_type)
Alex Langfordbddab072019-08-13 19:40:36 +00005283 encoding =
5284 CompilerType(this, complex_type->getElementType().getAsOpaquePtr())
5285 .GetEncoding(count);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005286 else
5287 encoding = lldb::eEncodingSint;
5288 }
5289 count = 2;
5290 return encoding;
5291 }
5292
5293 case clang::Type::ObjCInterface:
5294 break;
5295 case clang::Type::Record:
5296 break;
5297 case clang::Type::Enum:
5298 return lldb::eEncodingSint;
5299 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00005300 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
5301 ->getDecl()
5302 ->getUnderlyingType()
5303 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005304 .GetEncoding(count);
5305
5306 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00005307 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
5308 ->getDeducedType()
5309 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005310 .GetEncoding(count);
5311
5312 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00005313 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
5314 ->getNamedType()
5315 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005316 .GetEncoding(count);
5317
5318 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00005319 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
5320 ->desugar()
5321 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005322 .GetEncoding(count);
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005323 case clang::Type::TypeOfExpr:
Alex Langfordbddab072019-08-13 19:40:36 +00005324 return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
5325 ->getUnderlyingExpr()
5326 ->getType()
5327 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005328 .GetEncoding(count);
5329 case clang::Type::TypeOf:
Alex Langfordbddab072019-08-13 19:40:36 +00005330 return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
5331 ->getUnderlyingType()
5332 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005333 .GetEncoding(count);
5334 case clang::Type::Decltype:
Alex Langfordbddab072019-08-13 19:40:36 +00005335 return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type)
5336 ->getUnderlyingType()
5337 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005338 .GetEncoding(count);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005339 case clang::Type::DependentSizedArray:
5340 case clang::Type::DependentSizedExtVector:
5341 case clang::Type::UnresolvedUsing:
5342 case clang::Type::Attributed:
5343 case clang::Type::TemplateTypeParm:
5344 case clang::Type::SubstTemplateTypeParm:
5345 case clang::Type::SubstTemplateTypeParmPack:
5346 case clang::Type::InjectedClassName:
5347 case clang::Type::DependentName:
5348 case clang::Type::DependentTemplateSpecialization:
5349 case clang::Type::PackExpansion:
5350 case clang::Type::ObjCObject:
5351
Kate Stoneb9c1b512016-09-06 20:57:50 +00005352 case clang::Type::TemplateSpecialization:
Pavel Labath4f19fce22017-02-17 13:39:50 +00005353 case clang::Type::DeducedTemplateSpecialization:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005354 case clang::Type::Atomic:
5355 case clang::Type::Adjusted:
5356 case clang::Type::Pipe:
5357 break;
5358
5359 // pointer type decayed from an array or function type.
5360 case clang::Type::Decayed:
5361 break;
Zachary Turner5a8ad4592016-10-05 17:07:34 +00005362 case clang::Type::ObjCTypeParam:
5363 break;
Ted Woodward66060cf2017-10-11 22:42:21 +00005364
5365 case clang::Type::DependentAddressSpace:
5366 break;
Krasimir Georgiev435e76a2019-05-07 13:59:30 +00005367 case clang::Type::MacroQualified:
5368 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005369 }
5370 count = 0;
5371 return lldb::eEncodingInvalid;
5372}
5373
5374lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
5375 if (!type)
5376 return lldb::eFormatDefault;
5377
5378 clang::QualType qual_type(GetCanonicalQualType(type));
5379
5380 switch (qual_type->getTypeClass()) {
5381 case clang::Type::UnaryTransform:
5382 break;
5383
5384 case clang::Type::FunctionNoProto:
5385 case clang::Type::FunctionProto:
5386 break;
5387
5388 case clang::Type::IncompleteArray:
5389 case clang::Type::VariableArray:
5390 break;
5391
5392 case clang::Type::ConstantArray:
5393 return lldb::eFormatVoid; // no value
5394
Fangrui Song8f284882018-07-13 22:40:40 +00005395 case clang::Type::DependentVector:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005396 case clang::Type::ExtVector:
5397 case clang::Type::Vector:
5398 break;
5399
5400 case clang::Type::Builtin:
5401 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5402 // default: assert(0 && "Unknown builtin type!");
5403 case clang::BuiltinType::UnknownAny:
5404 case clang::BuiltinType::Void:
5405 case clang::BuiltinType::BoundMember:
5406 break;
5407
5408 case clang::BuiltinType::Bool:
5409 return lldb::eFormatBoolean;
5410 case clang::BuiltinType::Char_S:
5411 case clang::BuiltinType::SChar:
5412 case clang::BuiltinType::WChar_S:
5413 case clang::BuiltinType::Char_U:
5414 case clang::BuiltinType::UChar:
5415 case clang::BuiltinType::WChar_U:
5416 return lldb::eFormatChar;
5417 case clang::BuiltinType::Char16:
5418 return lldb::eFormatUnicode16;
5419 case clang::BuiltinType::Char32:
5420 return lldb::eFormatUnicode32;
5421 case clang::BuiltinType::UShort:
5422 return lldb::eFormatUnsigned;
5423 case clang::BuiltinType::Short:
5424 return lldb::eFormatDecimal;
5425 case clang::BuiltinType::UInt:
5426 return lldb::eFormatUnsigned;
5427 case clang::BuiltinType::Int:
5428 return lldb::eFormatDecimal;
5429 case clang::BuiltinType::ULong:
5430 return lldb::eFormatUnsigned;
5431 case clang::BuiltinType::Long:
5432 return lldb::eFormatDecimal;
5433 case clang::BuiltinType::ULongLong:
5434 return lldb::eFormatUnsigned;
5435 case clang::BuiltinType::LongLong:
5436 return lldb::eFormatDecimal;
5437 case clang::BuiltinType::UInt128:
5438 return lldb::eFormatUnsigned;
5439 case clang::BuiltinType::Int128:
5440 return lldb::eFormatDecimal;
5441 case clang::BuiltinType::Half:
5442 case clang::BuiltinType::Float:
5443 case clang::BuiltinType::Double:
5444 case clang::BuiltinType::LongDouble:
5445 return lldb::eFormatFloat;
5446 default:
5447 return lldb::eFormatHex;
5448 }
5449 break;
5450 case clang::Type::ObjCObjectPointer:
5451 return lldb::eFormatHex;
5452 case clang::Type::BlockPointer:
5453 return lldb::eFormatHex;
5454 case clang::Type::Pointer:
5455 return lldb::eFormatHex;
5456 case clang::Type::LValueReference:
5457 case clang::Type::RValueReference:
5458 return lldb::eFormatHex;
5459 case clang::Type::MemberPointer:
5460 break;
5461 case clang::Type::Complex: {
5462 if (qual_type->isComplexType())
5463 return lldb::eFormatComplex;
5464 else
5465 return lldb::eFormatComplexInteger;
5466 }
5467 case clang::Type::ObjCInterface:
5468 break;
5469 case clang::Type::Record:
5470 break;
5471 case clang::Type::Enum:
5472 return lldb::eFormatEnum;
5473 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00005474 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
5475 ->getDecl()
5476 ->getUnderlyingType()
5477 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005478 .GetFormat();
5479 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00005480 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
5481 ->desugar()
5482 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005483 .GetFormat();
5484 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00005485 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
5486 ->desugar()
5487 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005488 .GetFormat();
5489 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00005490 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
5491 ->getNamedType()
5492 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005493 .GetFormat();
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005494 case clang::Type::TypeOfExpr:
Alex Langfordbddab072019-08-13 19:40:36 +00005495 return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
5496 ->getUnderlyingExpr()
5497 ->getType()
5498 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005499 .GetFormat();
5500 case clang::Type::TypeOf:
Alex Langfordbddab072019-08-13 19:40:36 +00005501 return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
5502 ->getUnderlyingType()
5503 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005504 .GetFormat();
5505 case clang::Type::Decltype:
Alex Langfordbddab072019-08-13 19:40:36 +00005506 return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type)
5507 ->getUnderlyingType()
5508 .getAsOpaquePtr())
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00005509 .GetFormat();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005510 case clang::Type::DependentSizedArray:
5511 case clang::Type::DependentSizedExtVector:
5512 case clang::Type::UnresolvedUsing:
5513 case clang::Type::Attributed:
5514 case clang::Type::TemplateTypeParm:
5515 case clang::Type::SubstTemplateTypeParm:
5516 case clang::Type::SubstTemplateTypeParmPack:
5517 case clang::Type::InjectedClassName:
5518 case clang::Type::DependentName:
5519 case clang::Type::DependentTemplateSpecialization:
5520 case clang::Type::PackExpansion:
5521 case clang::Type::ObjCObject:
5522
Kate Stoneb9c1b512016-09-06 20:57:50 +00005523 case clang::Type::TemplateSpecialization:
Pavel Labath4f19fce22017-02-17 13:39:50 +00005524 case clang::Type::DeducedTemplateSpecialization:
Kate Stoneb9c1b512016-09-06 20:57:50 +00005525 case clang::Type::Atomic:
5526 case clang::Type::Adjusted:
5527 case clang::Type::Pipe:
5528 break;
5529
5530 // pointer type decayed from an array or function type.
5531 case clang::Type::Decayed:
5532 break;
Zachary Turner5a8ad4592016-10-05 17:07:34 +00005533 case clang::Type::ObjCTypeParam:
5534 break;
Ted Woodward66060cf2017-10-11 22:42:21 +00005535
5536 case clang::Type::DependentAddressSpace:
5537 break;
Krasimir Georgiev435e76a2019-05-07 13:59:30 +00005538 case clang::Type::MacroQualified:
5539 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005540 }
5541 // We don't know hot to display this type...
5542 return lldb::eFormatBytes;
5543}
5544
5545static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl,
5546 bool check_superclass) {
5547 while (class_interface_decl) {
5548 if (class_interface_decl->ivar_size() > 0)
5549 return true;
5550
5551 if (check_superclass)
5552 class_interface_decl = class_interface_decl->getSuperClass();
5553 else
5554 break;
5555 }
5556 return false;
5557}
5558
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00005559static Optional<SymbolFile::ArrayInfo>
Adrian Prantleca07c52018-11-05 20:49:07 +00005560GetDynamicArrayInfo(ClangASTContext &ast, SymbolFile *sym_file,
5561 clang::QualType qual_type,
5562 const ExecutionContext *exe_ctx) {
5563 if (qual_type->isIncompleteArrayType())
5564 if (auto *metadata = ast.GetMetadata(qual_type.getAsOpaquePtr()))
Pavel Labathffec31e2018-12-28 13:34:44 +00005565 return sym_file->GetDynamicArrayInfoForUID(metadata->GetUserID(),
5566 exe_ctx);
Adrian Prantleca07c52018-11-05 20:49:07 +00005567 return llvm::None;
5568}
5569
Kate Stoneb9c1b512016-09-06 20:57:50 +00005570uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
Adrian Prantleca07c52018-11-05 20:49:07 +00005571 bool omit_empty_base_classes,
5572 const ExecutionContext *exe_ctx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005573 if (!type)
5574 return 0;
5575
5576 uint32_t num_children = 0;
5577 clang::QualType qual_type(GetQualType(type));
5578 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5579 switch (type_class) {
5580 case clang::Type::Builtin:
5581 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5582 case clang::BuiltinType::ObjCId: // child is Class
5583 case clang::BuiltinType::ObjCClass: // child is Class
5584 num_children = 1;
5585 break;
5586
5587 default:
5588 break;
5589 }
5590 break;
5591
5592 case clang::Type::Complex:
5593 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005594 case clang::Type::Record:
5595 if (GetCompleteQualType(getASTContext(), qual_type)) {
5596 const clang::RecordType *record_type =
5597 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
5598 const clang::RecordDecl *record_decl = record_type->getDecl();
5599 assert(record_decl);
5600 const clang::CXXRecordDecl *cxx_record_decl =
5601 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
5602 if (cxx_record_decl) {
5603 if (omit_empty_base_classes) {
Adrian Prantl05097242018-04-30 16:49:04 +00005604 // Check each base classes to see if it or any of its base classes
5605 // contain any fields. This can help limit the noise in variable
5606 // views by not having to show base classes that contain no members.
Kate Stoneb9c1b512016-09-06 20:57:50 +00005607 clang::CXXRecordDecl::base_class_const_iterator base_class,
5608 base_class_end;
5609 for (base_class = cxx_record_decl->bases_begin(),
5610 base_class_end = cxx_record_decl->bases_end();
5611 base_class != base_class_end; ++base_class) {
5612 const clang::CXXRecordDecl *base_class_decl =
5613 llvm::cast<clang::CXXRecordDecl>(
5614 base_class->getType()
5615 ->getAs<clang::RecordType>()
5616 ->getDecl());
5617
5618 // Skip empty base classes
Jonas Devliegherea6682a42018-12-15 00:15:33 +00005619 if (!ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00005620 continue;
5621
5622 num_children++;
5623 }
5624 } else {
5625 // Include all base classes
5626 num_children += cxx_record_decl->getNumBases();
5627 }
5628 }
5629 clang::RecordDecl::field_iterator field, field_end;
5630 for (field = record_decl->field_begin(),
5631 field_end = record_decl->field_end();
5632 field != field_end; ++field)
5633 ++num_children;
5634 }
5635 break;
5636
5637 case clang::Type::ObjCObject:
5638 case clang::Type::ObjCInterface:
5639 if (GetCompleteQualType(getASTContext(), qual_type)) {
5640 const clang::ObjCObjectType *objc_class_type =
5641 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
5642 assert(objc_class_type);
5643 if (objc_class_type) {
5644 clang::ObjCInterfaceDecl *class_interface_decl =
5645 objc_class_type->getInterface();
5646
5647 if (class_interface_decl) {
5648
5649 clang::ObjCInterfaceDecl *superclass_interface_decl =
5650 class_interface_decl->getSuperClass();
5651 if (superclass_interface_decl) {
5652 if (omit_empty_base_classes) {
5653 if (ObjCDeclHasIVars(superclass_interface_decl, true))
5654 ++num_children;
5655 } else
5656 ++num_children;
5657 }
5658
5659 num_children += class_interface_decl->ivar_size();
5660 }
5661 }
5662 }
5663 break;
5664
5665 case clang::Type::ObjCObjectPointer: {
5666 const clang::ObjCObjectPointerType *pointer_type =
5667 llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
5668 clang::QualType pointee_type = pointer_type->getPointeeType();
5669 uint32_t num_pointee_children =
Alex Langfordbddab072019-08-13 19:40:36 +00005670 CompilerType(this, pointee_type.getAsOpaquePtr())
Adrian Prantleca07c52018-11-05 20:49:07 +00005671 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005672 // If this type points to a simple type, then it has 1 child
5673 if (num_pointee_children == 0)
5674 num_children = 1;
5675 else
5676 num_children = num_pointee_children;
5677 } break;
5678
5679 case clang::Type::Vector:
5680 case clang::Type::ExtVector:
5681 num_children =
5682 llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements();
5683 break;
5684
5685 case clang::Type::ConstantArray:
5686 num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr())
5687 ->getSize()
5688 .getLimitedValue();
5689 break;
Adrian Prantleca07c52018-11-05 20:49:07 +00005690 case clang::Type::IncompleteArray:
5691 if (auto array_info =
5692 GetDynamicArrayInfo(*this, GetSymbolFile(), qual_type, exe_ctx))
5693 // Only 1-dimensional arrays are supported.
5694 num_children = array_info->element_orders.size()
5695 ? array_info->element_orders.back()
5696 : 0;
5697 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005698
5699 case clang::Type::Pointer: {
5700 const clang::PointerType *pointer_type =
5701 llvm::cast<clang::PointerType>(qual_type.getTypePtr());
5702 clang::QualType pointee_type(pointer_type->getPointeeType());
5703 uint32_t num_pointee_children =
Alex Langfordbddab072019-08-13 19:40:36 +00005704 CompilerType(this, pointee_type.getAsOpaquePtr())
Adrian Prantleca07c52018-11-05 20:49:07 +00005705 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005706 if (num_pointee_children == 0) {
Adrian Prantl05097242018-04-30 16:49:04 +00005707 // We have a pointer to a pointee type that claims it has no children. We
5708 // will want to look at
Kate Stoneb9c1b512016-09-06 20:57:50 +00005709 num_children = GetNumPointeeChildren(pointee_type);
5710 } else
5711 num_children = num_pointee_children;
5712 } break;
5713
5714 case clang::Type::LValueReference:
5715 case clang::Type::RValueReference: {
5716 const clang::ReferenceType *reference_type =
5717 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
5718 clang::QualType pointee_type = reference_type->getPointeeType();
5719 uint32_t num_pointee_children =
Alex Langfordbddab072019-08-13 19:40:36 +00005720 CompilerType(this, pointee_type.getAsOpaquePtr())
Adrian Prantleca07c52018-11-05 20:49:07 +00005721 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005722 // If this type points to a simple type, then it has 1 child
5723 if (num_pointee_children == 0)
5724 num_children = 1;
5725 else
5726 num_children = num_pointee_children;
5727 } break;
5728
5729 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00005730 num_children = CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
Kate Stoneb9c1b512016-09-06 20:57:50 +00005731 ->getDecl()
Alex Langfordbddab072019-08-13 19:40:36 +00005732 ->getUnderlyingType()
5733 .getAsOpaquePtr())
5734 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005735 break;
5736
5737 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00005738 num_children = CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
5739 ->getDeducedType()
5740 .getAsOpaquePtr())
5741 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005742 break;
5743
5744 case clang::Type::Elaborated:
5745 num_children =
Alex Langfordbddab072019-08-13 19:40:36 +00005746 CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
5747 ->getNamedType()
5748 .getAsOpaquePtr())
Adrian Prantleca07c52018-11-05 20:49:07 +00005749 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005750 break;
5751
5752 case clang::Type::Paren:
5753 num_children =
Alex Langfordbddab072019-08-13 19:40:36 +00005754 CompilerType(
5755 this,
5756 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())
Adrian Prantleca07c52018-11-05 20:49:07 +00005757 .GetNumChildren(omit_empty_base_classes, exe_ctx);
Kate Stoneb9c1b512016-09-06 20:57:50 +00005758 break;
5759 default:
5760 break;
5761 }
5762 return num_children;
5763}
5764
Adrian Prantl0e4c4822019-03-06 21:22:25 +00005765CompilerType ClangASTContext::GetBuiltinTypeByName(ConstString name) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00005766 return GetBasicType(GetBasicTypeEnumeration(name));
Greg Clayton56939cb2015-09-17 22:23:34 +00005767}
5768
Greg Claytond8d4a572015-08-11 21:38:15 +00005769lldb::BasicType
Kate Stoneb9c1b512016-09-06 20:57:50 +00005770ClangASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
5771 if (type) {
5772 clang::QualType qual_type(GetQualType(type));
5773 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5774 if (type_class == clang::Type::Builtin) {
5775 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
5776 case clang::BuiltinType::Void:
5777 return eBasicTypeVoid;
5778 case clang::BuiltinType::Bool:
5779 return eBasicTypeBool;
5780 case clang::BuiltinType::Char_S:
5781 return eBasicTypeSignedChar;
5782 case clang::BuiltinType::Char_U:
5783 return eBasicTypeUnsignedChar;
5784 case clang::BuiltinType::Char16:
5785 return eBasicTypeChar16;
5786 case clang::BuiltinType::Char32:
5787 return eBasicTypeChar32;
5788 case clang::BuiltinType::UChar:
5789 return eBasicTypeUnsignedChar;
5790 case clang::BuiltinType::SChar:
5791 return eBasicTypeSignedChar;
5792 case clang::BuiltinType::WChar_S:
5793 return eBasicTypeSignedWChar;
5794 case clang::BuiltinType::WChar_U:
5795 return eBasicTypeUnsignedWChar;
5796 case clang::BuiltinType::Short:
5797 return eBasicTypeShort;
5798 case clang::BuiltinType::UShort:
5799 return eBasicTypeUnsignedShort;
5800 case clang::BuiltinType::Int:
5801 return eBasicTypeInt;
5802 case clang::BuiltinType::UInt:
5803 return eBasicTypeUnsignedInt;
5804 case clang::BuiltinType::Long:
5805 return eBasicTypeLong;
5806 case clang::BuiltinType::ULong:
5807 return eBasicTypeUnsignedLong;
5808 case clang::BuiltinType::LongLong:
5809 return eBasicTypeLongLong;
5810 case clang::BuiltinType::ULongLong:
5811 return eBasicTypeUnsignedLongLong;
5812 case clang::BuiltinType::Int128:
5813 return eBasicTypeInt128;
5814 case clang::BuiltinType::UInt128:
5815 return eBasicTypeUnsignedInt128;
5816
5817 case clang::BuiltinType::Half:
5818 return eBasicTypeHalf;
5819 case clang::BuiltinType::Float:
5820 return eBasicTypeFloat;
5821 case clang::BuiltinType::Double:
5822 return eBasicTypeDouble;
5823 case clang::BuiltinType::LongDouble:
5824 return eBasicTypeLongDouble;
5825
5826 case clang::BuiltinType::NullPtr:
5827 return eBasicTypeNullPtr;
5828 case clang::BuiltinType::ObjCId:
5829 return eBasicTypeObjCID;
5830 case clang::BuiltinType::ObjCClass:
5831 return eBasicTypeObjCClass;
5832 case clang::BuiltinType::ObjCSel:
5833 return eBasicTypeObjCSel;
5834 default:
5835 return eBasicTypeOther;
5836 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005837 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005838 }
5839 return eBasicTypeInvalid;
Greg Claytond8d4a572015-08-11 21:38:15 +00005840}
5841
Kate Stoneb9c1b512016-09-06 20:57:50 +00005842void ClangASTContext::ForEachEnumerator(
5843 lldb::opaque_compiler_type_t type,
5844 std::function<bool(const CompilerType &integer_type,
Adrian Prantl0e4c4822019-03-06 21:22:25 +00005845 ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00005846 const llvm::APSInt &value)> const &callback) {
5847 const clang::EnumType *enum_type =
5848 llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
5849 if (enum_type) {
5850 const clang::EnumDecl *enum_decl = enum_type->getDecl();
5851 if (enum_decl) {
5852 CompilerType integer_type(this,
5853 enum_decl->getIntegerType().getAsOpaquePtr());
Greg Clayton99558cc42015-08-24 23:46:31 +00005854
Kate Stoneb9c1b512016-09-06 20:57:50 +00005855 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
5856 for (enum_pos = enum_decl->enumerator_begin(),
5857 enum_end_pos = enum_decl->enumerator_end();
5858 enum_pos != enum_end_pos; ++enum_pos) {
5859 ConstString name(enum_pos->getNameAsString().c_str());
5860 if (!callback(integer_type, name, enum_pos->getInitVal()))
5861 break;
5862 }
Greg Clayton99558cc42015-08-24 23:46:31 +00005863 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005864 }
Greg Clayton99558cc42015-08-24 23:46:31 +00005865}
5866
Greg Claytond8d4a572015-08-11 21:38:15 +00005867#pragma mark Aggregate Types
5868
Kate Stoneb9c1b512016-09-06 20:57:50 +00005869uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
5870 if (!type)
5871 return 0;
Enrico Granata36f51e42015-12-18 22:41:25 +00005872
Kate Stoneb9c1b512016-09-06 20:57:50 +00005873 uint32_t count = 0;
5874 clang::QualType qual_type(GetCanonicalQualType(type));
5875 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5876 switch (type_class) {
5877 case clang::Type::Record:
5878 if (GetCompleteType(type)) {
5879 const clang::RecordType *record_type =
5880 llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
5881 if (record_type) {
5882 clang::RecordDecl *record_decl = record_type->getDecl();
5883 if (record_decl) {
5884 uint32_t field_idx = 0;
5885 clang::RecordDecl::field_iterator field, field_end;
5886 for (field = record_decl->field_begin(),
5887 field_end = record_decl->field_end();
5888 field != field_end; ++field)
5889 ++field_idx;
5890 count = field_idx;
5891 }
5892 }
Greg Claytond8d4a572015-08-11 21:38:15 +00005893 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005894 break;
5895
5896 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00005897 count = CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
5898 ->getDecl()
5899 ->getUnderlyingType()
5900 .getAsOpaquePtr())
5901 .GetNumFields();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005902 break;
5903
5904 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00005905 count = CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
5906 ->getDeducedType()
5907 .getAsOpaquePtr())
5908 .GetNumFields();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005909 break;
5910
5911 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00005912 count = CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
5913 ->getNamedType()
5914 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00005915 .GetNumFields();
5916 break;
5917
5918 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00005919 count =
5920 CompilerType(
5921 this,
5922 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())
5923 .GetNumFields();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005924 break;
5925
Sean Callananf9c622a2016-09-30 18:44:43 +00005926 case clang::Type::ObjCObjectPointer: {
5927 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00005928 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00005929 const clang::ObjCInterfaceType *objc_interface_type =
5930 objc_class_type->getInterfaceType();
5931 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00005932 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
5933 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00005934 clang::ObjCInterfaceDecl *class_interface_decl =
5935 objc_interface_type->getDecl();
5936 if (class_interface_decl) {
5937 count = class_interface_decl->ivar_size();
Kate Stoneb9c1b512016-09-06 20:57:50 +00005938 }
5939 }
5940 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00005941 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00005942
5943 case clang::Type::ObjCObject:
5944 case clang::Type::ObjCInterface:
5945 if (GetCompleteType(type)) {
5946 const clang::ObjCObjectType *objc_class_type =
5947 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
5948 if (objc_class_type) {
5949 clang::ObjCInterfaceDecl *class_interface_decl =
5950 objc_class_type->getInterface();
5951
5952 if (class_interface_decl)
5953 count = class_interface_decl->ivar_size();
5954 }
5955 }
5956 break;
5957
5958 default:
5959 break;
5960 }
5961 return count;
Greg Claytond8d4a572015-08-11 21:38:15 +00005962}
5963
Bruce Mitchener48ea9002015-09-23 00:18:24 +00005964static lldb::opaque_compiler_type_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00005965GetObjCFieldAtIndex(clang::ASTContext *ast,
5966 clang::ObjCInterfaceDecl *class_interface_decl, size_t idx,
5967 std::string &name, uint64_t *bit_offset_ptr,
5968 uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) {
5969 if (class_interface_decl) {
5970 if (idx < (class_interface_decl->ivar_size())) {
5971 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
5972 ivar_end = class_interface_decl->ivar_end();
5973 uint32_t ivar_idx = 0;
5974
5975 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end;
5976 ++ivar_pos, ++ivar_idx) {
5977 if (ivar_idx == idx) {
5978 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
5979
5980 clang::QualType ivar_qual_type(ivar_decl->getType());
5981
5982 name.assign(ivar_decl->getNameAsString());
5983
5984 if (bit_offset_ptr) {
5985 const clang::ASTRecordLayout &interface_layout =
5986 ast->getASTObjCInterfaceLayout(class_interface_decl);
5987 *bit_offset_ptr = interface_layout.getFieldOffset(ivar_idx);
5988 }
5989
5990 const bool is_bitfield = ivar_pos->isBitField();
5991
5992 if (bitfield_bit_size_ptr) {
5993 *bitfield_bit_size_ptr = 0;
5994
5995 if (is_bitfield && ast) {
5996 clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
Hans Wennborg30ce9622018-11-28 14:30:18 +00005997 clang::Expr::EvalResult result;
Kate Stoneb9c1b512016-09-06 20:57:50 +00005998 if (bitfield_bit_size_expr &&
Hans Wennborg30ce9622018-11-28 14:30:18 +00005999 bitfield_bit_size_expr->EvaluateAsInt(result, *ast)) {
6000 llvm::APSInt bitfield_apsint = result.Val.getInt();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006001 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
6002 }
Greg Claytond8d4a572015-08-11 21:38:15 +00006003 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006004 }
6005 if (is_bitfield_ptr)
6006 *is_bitfield_ptr = is_bitfield;
6007
6008 return ivar_qual_type.getAsOpaquePtr();
Greg Claytond8d4a572015-08-11 21:38:15 +00006009 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006010 }
Greg Claytond8d4a572015-08-11 21:38:15 +00006011 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006012 }
6013 return nullptr;
Greg Claytond8d4a572015-08-11 21:38:15 +00006014}
6015
Kate Stoneb9c1b512016-09-06 20:57:50 +00006016CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
6017 size_t idx, std::string &name,
6018 uint64_t *bit_offset_ptr,
6019 uint32_t *bitfield_bit_size_ptr,
6020 bool *is_bitfield_ptr) {
6021 if (!type)
Greg Claytona1e5dc82015-08-11 22:53:00 +00006022 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006023
6024 clang::QualType qual_type(GetCanonicalQualType(type));
6025 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6026 switch (type_class) {
6027 case clang::Type::Record:
6028 if (GetCompleteType(type)) {
6029 const clang::RecordType *record_type =
6030 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
6031 const clang::RecordDecl *record_decl = record_type->getDecl();
6032 uint32_t field_idx = 0;
6033 clang::RecordDecl::field_iterator field, field_end;
6034 for (field = record_decl->field_begin(),
6035 field_end = record_decl->field_end();
6036 field != field_end; ++field, ++field_idx) {
6037 if (idx == field_idx) {
6038 // Print the member type if requested
6039 // Print the member name and equal sign
6040 name.assign(field->getNameAsString());
6041
6042 // Figure out the type byte size (field_type_info.first) and
6043 // alignment (field_type_info.second) from the AST context.
6044 if (bit_offset_ptr) {
6045 const clang::ASTRecordLayout &record_layout =
6046 getASTContext()->getASTRecordLayout(record_decl);
6047 *bit_offset_ptr = record_layout.getFieldOffset(field_idx);
6048 }
6049
6050 const bool is_bitfield = field->isBitField();
6051
6052 if (bitfield_bit_size_ptr) {
6053 *bitfield_bit_size_ptr = 0;
6054
6055 if (is_bitfield) {
6056 clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
Hans Wennborg30ce9622018-11-28 14:30:18 +00006057 clang::Expr::EvalResult result;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006058 if (bitfield_bit_size_expr &&
Hans Wennborg30ce9622018-11-28 14:30:18 +00006059 bitfield_bit_size_expr->EvaluateAsInt(result,
Kate Stoneb9c1b512016-09-06 20:57:50 +00006060 *getASTContext())) {
Hans Wennborg30ce9622018-11-28 14:30:18 +00006061 llvm::APSInt bitfield_apsint = result.Val.getInt();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006062 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
6063 }
6064 }
6065 }
6066 if (is_bitfield_ptr)
6067 *is_bitfield_ptr = is_bitfield;
6068
Alex Langfordbddab072019-08-13 19:40:36 +00006069 return CompilerType(this, field->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006070 }
6071 }
6072 }
6073 break;
6074
Sean Callananf9c622a2016-09-30 18:44:43 +00006075 case clang::Type::ObjCObjectPointer: {
6076 const clang::ObjCObjectPointerType *objc_class_type =
Sean Callanan732a6f42017-05-15 19:55:20 +00006077 qual_type->getAs<clang::ObjCObjectPointerType>();
Sean Callananf9c622a2016-09-30 18:44:43 +00006078 const clang::ObjCInterfaceType *objc_interface_type =
6079 objc_class_type->getInterfaceType();
6080 if (objc_interface_type &&
Davide Italiano52ffb532017-04-17 18:24:18 +00006081 GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
6082 const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
Sean Callananf9c622a2016-09-30 18:44:43 +00006083 clang::ObjCInterfaceDecl *class_interface_decl =
6084 objc_interface_type->getDecl();
6085 if (class_interface_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00006086 return CompilerType(
6087 this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl,
6088 idx, name, bit_offset_ptr,
6089 bitfield_bit_size_ptr, is_bitfield_ptr));
6090 }
6091 }
6092 break;
Sean Callananf9c622a2016-09-30 18:44:43 +00006093 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006094
6095 case clang::Type::ObjCObject:
6096 case clang::Type::ObjCInterface:
6097 if (GetCompleteType(type)) {
6098 const clang::ObjCObjectType *objc_class_type =
6099 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
6100 assert(objc_class_type);
6101 if (objc_class_type) {
6102 clang::ObjCInterfaceDecl *class_interface_decl =
6103 objc_class_type->getInterface();
6104 return CompilerType(
6105 this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl,
6106 idx, name, bit_offset_ptr,
6107 bitfield_bit_size_ptr, is_bitfield_ptr));
6108 }
6109 }
6110 break;
6111
6112 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00006113 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
6114 ->getDecl()
6115 ->getUnderlyingType()
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 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00006121 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
6122 ->getDeducedType()
6123 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00006124 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6125 is_bitfield_ptr);
6126
6127 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00006128 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
6129 ->getNamedType()
6130 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00006131 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6132 is_bitfield_ptr);
6133
6134 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00006135 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
6136 ->desugar()
6137 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00006138 .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
6139 is_bitfield_ptr);
6140
6141 default:
6142 break;
6143 }
6144 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00006145}
6146
Greg Clayton99558cc42015-08-24 23:46:31 +00006147uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00006148ClangASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) {
6149 uint32_t count = 0;
6150 clang::QualType qual_type(GetCanonicalQualType(type));
6151 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6152 switch (type_class) {
6153 case clang::Type::Record:
6154 if (GetCompleteType(type)) {
6155 const clang::CXXRecordDecl *cxx_record_decl =
6156 qual_type->getAsCXXRecordDecl();
6157 if (cxx_record_decl)
6158 count = cxx_record_decl->getNumBases();
Greg Clayton99558cc42015-08-24 23:46:31 +00006159 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006160 break;
Greg Clayton99558cc42015-08-24 23:46:31 +00006161
Kate Stoneb9c1b512016-09-06 20:57:50 +00006162 case clang::Type::ObjCObjectPointer:
6163 count = GetPointeeType(type).GetNumDirectBaseClasses();
6164 break;
6165
6166 case clang::Type::ObjCObject:
6167 if (GetCompleteType(type)) {
6168 const clang::ObjCObjectType *objc_class_type =
6169 qual_type->getAsObjCQualifiedInterfaceType();
6170 if (objc_class_type) {
6171 clang::ObjCInterfaceDecl *class_interface_decl =
6172 objc_class_type->getInterface();
6173
6174 if (class_interface_decl && class_interface_decl->getSuperClass())
6175 count = 1;
6176 }
6177 }
6178 break;
6179 case clang::Type::ObjCInterface:
6180 if (GetCompleteType(type)) {
6181 const clang::ObjCInterfaceType *objc_interface_type =
6182 qual_type->getAs<clang::ObjCInterfaceType>();
6183 if (objc_interface_type) {
6184 clang::ObjCInterfaceDecl *class_interface_decl =
6185 objc_interface_type->getInterface();
6186
6187 if (class_interface_decl && class_interface_decl->getSuperClass())
6188 count = 1;
6189 }
6190 }
6191 break;
6192
6193 case clang::Type::Typedef:
6194 count = GetNumDirectBaseClasses(llvm::cast<clang::TypedefType>(qual_type)
6195 ->getDecl()
6196 ->getUnderlyingType()
6197 .getAsOpaquePtr());
6198 break;
6199
6200 case clang::Type::Auto:
6201 count = GetNumDirectBaseClasses(llvm::cast<clang::AutoType>(qual_type)
6202 ->getDeducedType()
6203 .getAsOpaquePtr());
6204 break;
6205
6206 case clang::Type::Elaborated:
6207 count = GetNumDirectBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)
6208 ->getNamedType()
6209 .getAsOpaquePtr());
6210 break;
6211
6212 case clang::Type::Paren:
6213 return GetNumDirectBaseClasses(
6214 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
6215
6216 default:
6217 break;
6218 }
6219 return count;
Greg Clayton99558cc42015-08-24 23:46:31 +00006220}
6221
6222uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00006223ClangASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) {
6224 uint32_t count = 0;
6225 clang::QualType qual_type(GetCanonicalQualType(type));
6226 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6227 switch (type_class) {
6228 case clang::Type::Record:
6229 if (GetCompleteType(type)) {
6230 const clang::CXXRecordDecl *cxx_record_decl =
6231 qual_type->getAsCXXRecordDecl();
6232 if (cxx_record_decl)
6233 count = cxx_record_decl->getNumVBases();
Greg Clayton99558cc42015-08-24 23:46:31 +00006234 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006235 break;
Greg Clayton99558cc42015-08-24 23:46:31 +00006236
Kate Stoneb9c1b512016-09-06 20:57:50 +00006237 case clang::Type::Typedef:
6238 count = GetNumVirtualBaseClasses(llvm::cast<clang::TypedefType>(qual_type)
6239 ->getDecl()
6240 ->getUnderlyingType()
6241 .getAsOpaquePtr());
6242 break;
6243
6244 case clang::Type::Auto:
6245 count = GetNumVirtualBaseClasses(llvm::cast<clang::AutoType>(qual_type)
6246 ->getDeducedType()
6247 .getAsOpaquePtr());
6248 break;
6249
6250 case clang::Type::Elaborated:
6251 count =
6252 GetNumVirtualBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)
6253 ->getNamedType()
6254 .getAsOpaquePtr());
6255 break;
6256
6257 case clang::Type::Paren:
6258 count = GetNumVirtualBaseClasses(
6259 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
6260 break;
6261
6262 default:
6263 break;
6264 }
6265 return count;
Greg Clayton99558cc42015-08-24 23:46:31 +00006266}
6267
Kate Stoneb9c1b512016-09-06 20:57:50 +00006268CompilerType ClangASTContext::GetDirectBaseClassAtIndex(
6269 lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
6270 clang::QualType qual_type(GetCanonicalQualType(type));
6271 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6272 switch (type_class) {
6273 case clang::Type::Record:
6274 if (GetCompleteType(type)) {
6275 const clang::CXXRecordDecl *cxx_record_decl =
6276 qual_type->getAsCXXRecordDecl();
6277 if (cxx_record_decl) {
6278 uint32_t curr_idx = 0;
6279 clang::CXXRecordDecl::base_class_const_iterator base_class,
6280 base_class_end;
6281 for (base_class = cxx_record_decl->bases_begin(),
6282 base_class_end = cxx_record_decl->bases_end();
6283 base_class != base_class_end; ++base_class, ++curr_idx) {
6284 if (curr_idx == idx) {
6285 if (bit_offset_ptr) {
6286 const clang::ASTRecordLayout &record_layout =
6287 getASTContext()->getASTRecordLayout(cxx_record_decl);
6288 const clang::CXXRecordDecl *base_class_decl =
6289 llvm::cast<clang::CXXRecordDecl>(
6290 base_class->getType()
6291 ->getAs<clang::RecordType>()
6292 ->getDecl());
6293 if (base_class->isVirtual())
6294 *bit_offset_ptr =
6295 record_layout.getVBaseClassOffset(base_class_decl)
6296 .getQuantity() *
6297 8;
6298 else
6299 *bit_offset_ptr =
6300 record_layout.getBaseClassOffset(base_class_decl)
6301 .getQuantity() *
6302 8;
Greg Clayton99558cc42015-08-24 23:46:31 +00006303 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006304 return CompilerType(this, base_class->getType().getAsOpaquePtr());
6305 }
6306 }
6307 }
Greg Clayton99558cc42015-08-24 23:46:31 +00006308 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006309 break;
6310
6311 case clang::Type::ObjCObjectPointer:
6312 return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr);
6313
6314 case clang::Type::ObjCObject:
6315 if (idx == 0 && GetCompleteType(type)) {
6316 const clang::ObjCObjectType *objc_class_type =
6317 qual_type->getAsObjCQualifiedInterfaceType();
6318 if (objc_class_type) {
6319 clang::ObjCInterfaceDecl *class_interface_decl =
6320 objc_class_type->getInterface();
6321
6322 if (class_interface_decl) {
6323 clang::ObjCInterfaceDecl *superclass_interface_decl =
6324 class_interface_decl->getSuperClass();
6325 if (superclass_interface_decl) {
6326 if (bit_offset_ptr)
6327 *bit_offset_ptr = 0;
Alex Langfordbddab072019-08-13 19:40:36 +00006328 return CompilerType(this,
Kate Stoneb9c1b512016-09-06 20:57:50 +00006329 getASTContext()->getObjCInterfaceType(
Alex Langfordbddab072019-08-13 19:40:36 +00006330 superclass_interface_decl).getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006331 }
6332 }
6333 }
6334 }
6335 break;
6336 case clang::Type::ObjCInterface:
6337 if (idx == 0 && GetCompleteType(type)) {
6338 const clang::ObjCObjectType *objc_interface_type =
6339 qual_type->getAs<clang::ObjCInterfaceType>();
6340 if (objc_interface_type) {
6341 clang::ObjCInterfaceDecl *class_interface_decl =
6342 objc_interface_type->getInterface();
6343
6344 if (class_interface_decl) {
6345 clang::ObjCInterfaceDecl *superclass_interface_decl =
6346 class_interface_decl->getSuperClass();
6347 if (superclass_interface_decl) {
6348 if (bit_offset_ptr)
6349 *bit_offset_ptr = 0;
Alex Langfordbddab072019-08-13 19:40:36 +00006350 return CompilerType(
6351 this, getASTContext()
6352 ->getObjCInterfaceType(superclass_interface_decl)
6353 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006354 }
6355 }
6356 }
6357 }
6358 break;
6359
6360 case clang::Type::Typedef:
6361 return GetDirectBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type)
6362 ->getDecl()
6363 ->getUnderlyingType()
6364 .getAsOpaquePtr(),
6365 idx, bit_offset_ptr);
6366
6367 case clang::Type::Auto:
6368 return GetDirectBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type)
6369 ->getDeducedType()
6370 .getAsOpaquePtr(),
6371 idx, bit_offset_ptr);
6372
6373 case clang::Type::Elaborated:
6374 return GetDirectBaseClassAtIndex(
6375 llvm::cast<clang::ElaboratedType>(qual_type)
6376 ->getNamedType()
6377 .getAsOpaquePtr(),
6378 idx, bit_offset_ptr);
6379
6380 case clang::Type::Paren:
6381 return GetDirectBaseClassAtIndex(
6382 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
6383 idx, bit_offset_ptr);
6384
6385 default:
6386 break;
6387 }
6388 return CompilerType();
Greg Clayton99558cc42015-08-24 23:46:31 +00006389}
6390
Kate Stoneb9c1b512016-09-06 20:57:50 +00006391CompilerType ClangASTContext::GetVirtualBaseClassAtIndex(
6392 lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
6393 clang::QualType qual_type(GetCanonicalQualType(type));
6394 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6395 switch (type_class) {
6396 case clang::Type::Record:
6397 if (GetCompleteType(type)) {
6398 const clang::CXXRecordDecl *cxx_record_decl =
6399 qual_type->getAsCXXRecordDecl();
6400 if (cxx_record_decl) {
6401 uint32_t curr_idx = 0;
6402 clang::CXXRecordDecl::base_class_const_iterator base_class,
6403 base_class_end;
6404 for (base_class = cxx_record_decl->vbases_begin(),
6405 base_class_end = cxx_record_decl->vbases_end();
6406 base_class != base_class_end; ++base_class, ++curr_idx) {
6407 if (curr_idx == idx) {
6408 if (bit_offset_ptr) {
6409 const clang::ASTRecordLayout &record_layout =
6410 getASTContext()->getASTRecordLayout(cxx_record_decl);
6411 const clang::CXXRecordDecl *base_class_decl =
6412 llvm::cast<clang::CXXRecordDecl>(
6413 base_class->getType()
6414 ->getAs<clang::RecordType>()
6415 ->getDecl());
6416 *bit_offset_ptr =
6417 record_layout.getVBaseClassOffset(base_class_decl)
6418 .getQuantity() *
6419 8;
Greg Clayton99558cc42015-08-24 23:46:31 +00006420 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006421 return CompilerType(this, base_class->getType().getAsOpaquePtr());
6422 }
6423 }
6424 }
Greg Clayton99558cc42015-08-24 23:46:31 +00006425 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006426 break;
Greg Clayton99558cc42015-08-24 23:46:31 +00006427
Kate Stoneb9c1b512016-09-06 20:57:50 +00006428 case clang::Type::Typedef:
6429 return GetVirtualBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type)
6430 ->getDecl()
6431 ->getUnderlyingType()
6432 .getAsOpaquePtr(),
6433 idx, bit_offset_ptr);
6434
6435 case clang::Type::Auto:
6436 return GetVirtualBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type)
6437 ->getDeducedType()
6438 .getAsOpaquePtr(),
6439 idx, bit_offset_ptr);
6440
6441 case clang::Type::Elaborated:
6442 return GetVirtualBaseClassAtIndex(
6443 llvm::cast<clang::ElaboratedType>(qual_type)
6444 ->getNamedType()
6445 .getAsOpaquePtr(),
6446 idx, bit_offset_ptr);
6447
6448 case clang::Type::Paren:
6449 return GetVirtualBaseClassAtIndex(
6450 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
6451 idx, bit_offset_ptr);
6452
6453 default:
6454 break;
6455 }
6456 return CompilerType();
Greg Clayton99558cc42015-08-24 23:46:31 +00006457}
6458
Greg Claytond8d4a572015-08-11 21:38:15 +00006459// If a pointer to a pointee type (the clang_type arg) says that it has no
6460// children, then we either need to trust it, or override it and return a
6461// different result. For example, an "int *" has one child that is an integer,
6462// but a function pointer doesn't have any children. Likewise if a Record type
6463// claims it has no children, then there really is nothing to show.
Kate Stoneb9c1b512016-09-06 20:57:50 +00006464uint32_t ClangASTContext::GetNumPointeeChildren(clang::QualType type) {
6465 if (type.isNull())
Greg Claytond8d4a572015-08-11 21:38:15 +00006466 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006467
6468 clang::QualType qual_type(type.getCanonicalType());
6469 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6470 switch (type_class) {
6471 case clang::Type::Builtin:
6472 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
6473 case clang::BuiltinType::UnknownAny:
6474 case clang::BuiltinType::Void:
6475 case clang::BuiltinType::NullPtr:
6476 case clang::BuiltinType::OCLEvent:
6477 case clang::BuiltinType::OCLImage1dRO:
6478 case clang::BuiltinType::OCLImage1dWO:
6479 case clang::BuiltinType::OCLImage1dRW:
6480 case clang::BuiltinType::OCLImage1dArrayRO:
6481 case clang::BuiltinType::OCLImage1dArrayWO:
6482 case clang::BuiltinType::OCLImage1dArrayRW:
6483 case clang::BuiltinType::OCLImage1dBufferRO:
6484 case clang::BuiltinType::OCLImage1dBufferWO:
6485 case clang::BuiltinType::OCLImage1dBufferRW:
6486 case clang::BuiltinType::OCLImage2dRO:
6487 case clang::BuiltinType::OCLImage2dWO:
6488 case clang::BuiltinType::OCLImage2dRW:
6489 case clang::BuiltinType::OCLImage2dArrayRO:
6490 case clang::BuiltinType::OCLImage2dArrayWO:
6491 case clang::BuiltinType::OCLImage2dArrayRW:
6492 case clang::BuiltinType::OCLImage3dRO:
6493 case clang::BuiltinType::OCLImage3dWO:
6494 case clang::BuiltinType::OCLImage3dRW:
6495 case clang::BuiltinType::OCLSampler:
6496 return 0;
6497 case clang::BuiltinType::Bool:
6498 case clang::BuiltinType::Char_U:
6499 case clang::BuiltinType::UChar:
6500 case clang::BuiltinType::WChar_U:
6501 case clang::BuiltinType::Char16:
6502 case clang::BuiltinType::Char32:
6503 case clang::BuiltinType::UShort:
6504 case clang::BuiltinType::UInt:
6505 case clang::BuiltinType::ULong:
6506 case clang::BuiltinType::ULongLong:
6507 case clang::BuiltinType::UInt128:
6508 case clang::BuiltinType::Char_S:
6509 case clang::BuiltinType::SChar:
6510 case clang::BuiltinType::WChar_S:
6511 case clang::BuiltinType::Short:
6512 case clang::BuiltinType::Int:
6513 case clang::BuiltinType::Long:
6514 case clang::BuiltinType::LongLong:
6515 case clang::BuiltinType::Int128:
6516 case clang::BuiltinType::Float:
6517 case clang::BuiltinType::Double:
6518 case clang::BuiltinType::LongDouble:
6519 case clang::BuiltinType::Dependent:
6520 case clang::BuiltinType::Overload:
6521 case clang::BuiltinType::ObjCId:
6522 case clang::BuiltinType::ObjCClass:
6523 case clang::BuiltinType::ObjCSel:
6524 case clang::BuiltinType::BoundMember:
6525 case clang::BuiltinType::Half:
6526 case clang::BuiltinType::ARCUnbridgedCast:
6527 case clang::BuiltinType::PseudoObject:
6528 case clang::BuiltinType::BuiltinFn:
6529 case clang::BuiltinType::OMPArraySection:
6530 return 1;
6531 default:
6532 return 0;
6533 }
6534 break;
6535
6536 case clang::Type::Complex:
6537 return 1;
6538 case clang::Type::Pointer:
6539 return 1;
6540 case clang::Type::BlockPointer:
6541 return 0; // If block pointers don't have debug info, then no children for
6542 // them
6543 case clang::Type::LValueReference:
6544 return 1;
6545 case clang::Type::RValueReference:
6546 return 1;
6547 case clang::Type::MemberPointer:
6548 return 0;
6549 case clang::Type::ConstantArray:
6550 return 0;
6551 case clang::Type::IncompleteArray:
6552 return 0;
6553 case clang::Type::VariableArray:
6554 return 0;
6555 case clang::Type::DependentSizedArray:
6556 return 0;
6557 case clang::Type::DependentSizedExtVector:
6558 return 0;
6559 case clang::Type::Vector:
6560 return 0;
6561 case clang::Type::ExtVector:
6562 return 0;
6563 case clang::Type::FunctionProto:
6564 return 0; // When we function pointers, they have no children...
6565 case clang::Type::FunctionNoProto:
6566 return 0; // When we function pointers, they have no children...
6567 case clang::Type::UnresolvedUsing:
6568 return 0;
6569 case clang::Type::Paren:
6570 return GetNumPointeeChildren(
6571 llvm::cast<clang::ParenType>(qual_type)->desugar());
6572 case clang::Type::Typedef:
6573 return GetNumPointeeChildren(llvm::cast<clang::TypedefType>(qual_type)
6574 ->getDecl()
6575 ->getUnderlyingType());
6576 case clang::Type::Auto:
6577 return GetNumPointeeChildren(
6578 llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
6579 case clang::Type::Elaborated:
6580 return GetNumPointeeChildren(
6581 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
6582 case clang::Type::TypeOfExpr:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00006583 return GetNumPointeeChildren(llvm::cast<clang::TypeOfExprType>(qual_type)
6584 ->getUnderlyingExpr()
6585 ->getType());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006586 case clang::Type::TypeOf:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00006587 return GetNumPointeeChildren(
6588 llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006589 case clang::Type::Decltype:
Jonas Devlieghere65d2d5b2018-02-20 10:15:08 +00006590 return GetNumPointeeChildren(
6591 llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006592 case clang::Type::Record:
6593 return 0;
6594 case clang::Type::Enum:
6595 return 1;
6596 case clang::Type::TemplateTypeParm:
6597 return 1;
6598 case clang::Type::SubstTemplateTypeParm:
6599 return 1;
6600 case clang::Type::TemplateSpecialization:
6601 return 1;
6602 case clang::Type::InjectedClassName:
6603 return 0;
6604 case clang::Type::DependentName:
6605 return 1;
6606 case clang::Type::DependentTemplateSpecialization:
6607 return 1;
6608 case clang::Type::ObjCObject:
6609 return 0;
6610 case clang::Type::ObjCInterface:
6611 return 0;
6612 case clang::Type::ObjCObjectPointer:
6613 return 1;
6614 default:
6615 break;
6616 }
6617 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00006618}
6619
Kate Stoneb9c1b512016-09-06 20:57:50 +00006620CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
6621 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
6622 bool transparent_pointers, bool omit_empty_base_classes,
6623 bool ignore_array_bounds, std::string &child_name,
6624 uint32_t &child_byte_size, int32_t &child_byte_offset,
6625 uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
6626 bool &child_is_base_class, bool &child_is_deref_of_parent,
6627 ValueObject *valobj, uint64_t &language_flags) {
6628 if (!type)
Greg Claytona1e5dc82015-08-11 22:53:00 +00006629 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00006630
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006631 auto get_exe_scope = [&exe_ctx]() {
6632 return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
6633 };
6634
Kate Stoneb9c1b512016-09-06 20:57:50 +00006635 clang::QualType parent_qual_type(GetCanonicalQualType(type));
6636 const clang::Type::TypeClass parent_type_class =
6637 parent_qual_type->getTypeClass();
6638 child_bitfield_bit_size = 0;
6639 child_bitfield_bit_offset = 0;
6640 child_is_base_class = false;
6641 language_flags = 0;
6642
Adrian Prantleca07c52018-11-05 20:49:07 +00006643 const bool idx_is_valid =
6644 idx < GetNumChildren(type, omit_empty_base_classes, exe_ctx);
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00006645 int32_t bit_offset;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006646 switch (parent_type_class) {
6647 case clang::Type::Builtin:
6648 if (idx_is_valid) {
6649 switch (llvm::cast<clang::BuiltinType>(parent_qual_type)->getKind()) {
6650 case clang::BuiltinType::ObjCId:
6651 case clang::BuiltinType::ObjCClass:
6652 child_name = "isa";
6653 child_byte_size =
6654 getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy) /
6655 CHAR_BIT;
Alex Langfordbddab072019-08-13 19:40:36 +00006656 return CompilerType(
6657 this, getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006658
6659 default:
6660 break;
6661 }
6662 }
6663 break;
6664
6665 case clang::Type::Record:
6666 if (idx_is_valid && GetCompleteType(type)) {
6667 const clang::RecordType *record_type =
6668 llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr());
6669 const clang::RecordDecl *record_decl = record_type->getDecl();
6670 assert(record_decl);
6671 const clang::ASTRecordLayout &record_layout =
6672 getASTContext()->getASTRecordLayout(record_decl);
6673 uint32_t child_idx = 0;
6674
6675 const clang::CXXRecordDecl *cxx_record_decl =
6676 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
6677 if (cxx_record_decl) {
6678 // We might have base classes to print out first
6679 clang::CXXRecordDecl::base_class_const_iterator base_class,
6680 base_class_end;
6681 for (base_class = cxx_record_decl->bases_begin(),
6682 base_class_end = cxx_record_decl->bases_end();
6683 base_class != base_class_end; ++base_class) {
6684 const clang::CXXRecordDecl *base_class_decl = nullptr;
6685
6686 // Skip empty base classes
6687 if (omit_empty_base_classes) {
6688 base_class_decl = llvm::cast<clang::CXXRecordDecl>(
6689 base_class->getType()->getAs<clang::RecordType>()->getDecl());
Jonas Devliegherea6682a42018-12-15 00:15:33 +00006690 if (!ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00006691 continue;
6692 }
6693
6694 if (idx == child_idx) {
6695 if (base_class_decl == nullptr)
6696 base_class_decl = llvm::cast<clang::CXXRecordDecl>(
6697 base_class->getType()->getAs<clang::RecordType>()->getDecl());
6698
6699 if (base_class->isVirtual()) {
6700 bool handled = false;
6701 if (valobj) {
Aleksandr Urakov1dc51db2018-11-12 16:23:50 +00006702 clang::VTableContextBase *vtable_ctx =
6703 getASTContext()->getVTableContext();
6704 if (vtable_ctx)
6705 handled = GetVBaseBitOffset(*vtable_ctx, *valobj,
6706 record_layout, cxx_record_decl,
6707 base_class_decl, bit_offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00006708 }
6709 if (!handled)
6710 bit_offset = record_layout.getVBaseClassOffset(base_class_decl)
6711 .getQuantity() *
6712 8;
6713 } else
6714 bit_offset = record_layout.getBaseClassOffset(base_class_decl)
6715 .getQuantity() *
6716 8;
6717
6718 // Base classes should be a multiple of 8 bits in size
6719 child_byte_offset = bit_offset / 8;
Alex Langfordbddab072019-08-13 19:40:36 +00006720 CompilerType base_class_clang_type(
6721 this, base_class->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006722 child_name = base_class_clang_type.GetTypeName().AsCString("");
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006723 Optional<uint64_t> size =
6724 base_class_clang_type.GetBitSize(get_exe_scope());
Adrian Prantld963a7c2019-01-15 18:07:52 +00006725 if (!size)
6726 return {};
6727 uint64_t base_class_clang_type_bit_size = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006728
6729 // Base classes bit sizes should be a multiple of 8 bits in size
6730 assert(base_class_clang_type_bit_size % 8 == 0);
6731 child_byte_size = base_class_clang_type_bit_size / 8;
6732 child_is_base_class = true;
6733 return base_class_clang_type;
6734 }
6735 // We don't increment the child index in the for loop since we might
6736 // be skipping empty base classes
6737 ++child_idx;
Greg Claytond8d4a572015-08-11 21:38:15 +00006738 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006739 }
6740 // Make sure index is in range...
6741 uint32_t field_idx = 0;
6742 clang::RecordDecl::field_iterator field, field_end;
6743 for (field = record_decl->field_begin(),
6744 field_end = record_decl->field_end();
6745 field != field_end; ++field, ++field_idx, ++child_idx) {
6746 if (idx == child_idx) {
6747 // Print the member type if requested
6748 // Print the member name and equal sign
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00006749 child_name.assign(field->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006750
6751 // Figure out the type byte size (field_type_info.first) and
6752 // alignment (field_type_info.second) from the AST context.
Alex Langfordbddab072019-08-13 19:40:36 +00006753 CompilerType field_clang_type(this,
6754 field->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006755 assert(field_idx < record_layout.getFieldCount());
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006756 Optional<uint64_t> size =
6757 field_clang_type.GetByteSize(get_exe_scope());
Adrian Prantld963a7c2019-01-15 18:07:52 +00006758 if (!size)
6759 return {};
6760 child_byte_size = *size;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006761 const uint32_t child_bit_size = child_byte_size * 8;
6762
6763 // Figure out the field offset within the current struct/union/class
6764 // type
6765 bit_offset = record_layout.getFieldOffset(field_idx);
6766 if (ClangASTContext::FieldIsBitfield(getASTContext(), *field,
6767 child_bitfield_bit_size)) {
6768 child_bitfield_bit_offset = bit_offset % child_bit_size;
6769 const uint32_t child_bit_offset =
6770 bit_offset - child_bitfield_bit_offset;
6771 child_byte_offset = child_bit_offset / 8;
6772 } else {
6773 child_byte_offset = bit_offset / 8;
6774 }
6775
6776 return field_clang_type;
6777 }
6778 }
Greg Claytond8d4a572015-08-11 21:38:15 +00006779 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006780 break;
6781
6782 case clang::Type::ObjCObject:
6783 case clang::Type::ObjCInterface:
6784 if (idx_is_valid && GetCompleteType(type)) {
6785 const clang::ObjCObjectType *objc_class_type =
6786 llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr());
6787 assert(objc_class_type);
6788 if (objc_class_type) {
6789 uint32_t child_idx = 0;
6790 clang::ObjCInterfaceDecl *class_interface_decl =
6791 objc_class_type->getInterface();
6792
6793 if (class_interface_decl) {
6794
6795 const clang::ASTRecordLayout &interface_layout =
6796 getASTContext()->getASTObjCInterfaceLayout(class_interface_decl);
6797 clang::ObjCInterfaceDecl *superclass_interface_decl =
6798 class_interface_decl->getSuperClass();
6799 if (superclass_interface_decl) {
6800 if (omit_empty_base_classes) {
6801 CompilerType base_class_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00006802 this, getASTContext()
6803 ->getObjCInterfaceType(superclass_interface_decl)
6804 .getAsOpaquePtr());
Adrian Prantleca07c52018-11-05 20:49:07 +00006805 if (base_class_clang_type.GetNumChildren(omit_empty_base_classes,
6806 exe_ctx) > 0) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00006807 if (idx == 0) {
6808 clang::QualType ivar_qual_type(
6809 getASTContext()->getObjCInterfaceType(
6810 superclass_interface_decl));
6811
6812 child_name.assign(
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00006813 superclass_interface_decl->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006814
6815 clang::TypeInfo ivar_type_info =
6816 getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
6817
6818 child_byte_size = ivar_type_info.Width / 8;
6819 child_byte_offset = 0;
6820 child_is_base_class = true;
6821
Alex Langfordbddab072019-08-13 19:40:36 +00006822 return CompilerType(this, ivar_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006823 }
6824
6825 ++child_idx;
6826 }
6827 } else
6828 ++child_idx;
6829 }
6830
6831 const uint32_t superclass_idx = child_idx;
6832
6833 if (idx < (child_idx + class_interface_decl->ivar_size())) {
6834 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
6835 ivar_end = class_interface_decl->ivar_end();
6836
6837 for (ivar_pos = class_interface_decl->ivar_begin();
6838 ivar_pos != ivar_end; ++ivar_pos) {
6839 if (child_idx == idx) {
6840 clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
6841
6842 clang::QualType ivar_qual_type(ivar_decl->getType());
6843
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00006844 child_name.assign(ivar_decl->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006845
6846 clang::TypeInfo ivar_type_info =
6847 getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
6848
6849 child_byte_size = ivar_type_info.Width / 8;
6850
6851 // Figure out the field offset within the current
Adrian Prantl05097242018-04-30 16:49:04 +00006852 // struct/union/class type For ObjC objects, we can't trust the
6853 // bit offset we get from the Clang AST, since that doesn't
6854 // account for the space taken up by unbacked properties, or
6855 // from the changing size of base classes that are newer than
6856 // this class. So if we have a process around that we can ask
6857 // about this object, do so.
Kate Stoneb9c1b512016-09-06 20:57:50 +00006858 child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
6859 Process *process = nullptr;
6860 if (exe_ctx)
6861 process = exe_ctx->GetProcessPtr();
6862 if (process) {
6863 ObjCLanguageRuntime *objc_runtime =
Alex Langforde823bbe2019-06-10 20:53:23 +00006864 ObjCLanguageRuntime::Get(*process);
Kate Stoneb9c1b512016-09-06 20:57:50 +00006865 if (objc_runtime != nullptr) {
Alex Langfordbddab072019-08-13 19:40:36 +00006866 CompilerType parent_ast_type(
6867 this, parent_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006868 child_byte_offset = objc_runtime->GetByteOffsetForIvar(
6869 parent_ast_type, ivar_decl->getNameAsString().c_str());
6870 }
6871 }
6872
Aleksandr Urakovff701722018-08-20 05:59:27 +00006873 // Setting this to INT32_MAX to make sure we don't compute it
Kate Stoneb9c1b512016-09-06 20:57:50 +00006874 // twice...
Aleksandr Urakov53459482018-08-17 07:28:24 +00006875 bit_offset = INT32_MAX;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006876
6877 if (child_byte_offset ==
6878 static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET)) {
6879 bit_offset = interface_layout.getFieldOffset(child_idx -
6880 superclass_idx);
6881 child_byte_offset = bit_offset / 8;
6882 }
6883
6884 // Note, the ObjC Ivar Byte offset is just that, it doesn't
Adrian Prantl05097242018-04-30 16:49:04 +00006885 // account for the bit offset of a bitfield within its
6886 // containing object. So regardless of where we get the byte
Kate Stoneb9c1b512016-09-06 20:57:50 +00006887 // offset from, we still need to get the bit offset for
6888 // bitfields from the layout.
6889
6890 if (ClangASTContext::FieldIsBitfield(getASTContext(), ivar_decl,
6891 child_bitfield_bit_size)) {
Aleksandr Urakov53459482018-08-17 07:28:24 +00006892 if (bit_offset == INT32_MAX)
Kate Stoneb9c1b512016-09-06 20:57:50 +00006893 bit_offset = interface_layout.getFieldOffset(
6894 child_idx - superclass_idx);
6895
6896 child_bitfield_bit_offset = bit_offset % 8;
6897 }
Alex Langfordbddab072019-08-13 19:40:36 +00006898 return CompilerType(this, ivar_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006899 }
6900 ++child_idx;
6901 }
6902 }
6903 }
6904 }
6905 }
6906 break;
6907
6908 case clang::Type::ObjCObjectPointer:
6909 if (idx_is_valid) {
6910 CompilerType pointee_clang_type(GetPointeeType(type));
6911
6912 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6913 child_is_deref_of_parent = false;
6914 bool tmp_child_is_deref_of_parent = false;
6915 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6916 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6917 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
6918 child_bitfield_bit_size, child_bitfield_bit_offset,
6919 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
6920 language_flags);
6921 } else {
6922 child_is_deref_of_parent = true;
6923 const char *parent_name =
Konrad Kleine248a1302019-05-23 11:14:47 +00006924 valobj ? valobj->GetName().GetCString() : nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00006925 if (parent_name) {
6926 child_name.assign(1, '*');
6927 child_name += parent_name;
6928 }
6929
6930 // We have a pointer to an simple type
6931 if (idx == 0 && pointee_clang_type.GetCompleteType()) {
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006932 if (Optional<uint64_t> size =
6933 pointee_clang_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00006934 child_byte_size = *size;
6935 child_byte_offset = 0;
6936 return pointee_clang_type;
6937 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006938 }
6939 }
6940 }
6941 break;
6942
6943 case clang::Type::Vector:
6944 case clang::Type::ExtVector:
6945 if (idx_is_valid) {
6946 const clang::VectorType *array =
6947 llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr());
6948 if (array) {
Alex Langfordbddab072019-08-13 19:40:36 +00006949 CompilerType element_type(this,
6950 array->getElementType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006951 if (element_type.GetCompleteType()) {
6952 char element_name[64];
6953 ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]",
6954 static_cast<uint64_t>(idx));
6955 child_name.assign(element_name);
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006956 if (Optional<uint64_t> size =
6957 element_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00006958 child_byte_size = *size;
6959 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
6960 return element_type;
6961 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006962 }
6963 }
6964 }
6965 break;
6966
6967 case clang::Type::ConstantArray:
6968 case clang::Type::IncompleteArray:
6969 if (ignore_array_bounds || idx_is_valid) {
6970 const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
6971 if (array) {
Alex Langfordbddab072019-08-13 19:40:36 +00006972 CompilerType element_type(this,
6973 array->getElementType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00006974 if (element_type.GetCompleteType()) {
Zachary Turner827d5d72016-12-16 04:27:00 +00006975 child_name = llvm::formatv("[{0}]", idx);
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00006976 if (Optional<uint64_t> size =
6977 element_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00006978 child_byte_size = *size;
6979 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
6980 return element_type;
6981 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00006982 }
6983 }
6984 }
6985 break;
6986
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006987 case clang::Type::Pointer: {
6988 CompilerType pointee_clang_type(GetPointeeType(type));
Kate Stoneb9c1b512016-09-06 20:57:50 +00006989
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006990 // Don't dereference "void *" pointers
6991 if (pointee_clang_type.IsVoidType())
6992 return CompilerType();
Kate Stoneb9c1b512016-09-06 20:57:50 +00006993
Tamas Berghammer1c62e032017-01-07 16:39:07 +00006994 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
6995 child_is_deref_of_parent = false;
6996 bool tmp_child_is_deref_of_parent = false;
6997 return pointee_clang_type.GetChildCompilerTypeAtIndex(
6998 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
6999 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7000 child_bitfield_bit_size, child_bitfield_bit_offset,
7001 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
7002 language_flags);
7003 } else {
7004 child_is_deref_of_parent = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007005
Tamas Berghammer1c62e032017-01-07 16:39:07 +00007006 const char *parent_name =
Konrad Kleine248a1302019-05-23 11:14:47 +00007007 valobj ? valobj->GetName().GetCString() : nullptr;
Tamas Berghammer1c62e032017-01-07 16:39:07 +00007008 if (parent_name) {
7009 child_name.assign(1, '*');
7010 child_name += parent_name;
7011 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007012
Tamas Berghammer1c62e032017-01-07 16:39:07 +00007013 // We have a pointer to an simple type
7014 if (idx == 0) {
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00007015 if (Optional<uint64_t> size =
7016 pointee_clang_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00007017 child_byte_size = *size;
7018 child_byte_offset = 0;
7019 return pointee_clang_type;
7020 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007021 }
7022 }
7023 break;
Tamas Berghammer1c62e032017-01-07 16:39:07 +00007024 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007025
7026 case clang::Type::LValueReference:
7027 case clang::Type::RValueReference:
7028 if (idx_is_valid) {
7029 const clang::ReferenceType *reference_type =
7030 llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
Alex Langfordbddab072019-08-13 19:40:36 +00007031 CompilerType pointee_clang_type(
7032 this, reference_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007033 if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
7034 child_is_deref_of_parent = false;
7035 bool tmp_child_is_deref_of_parent = false;
7036 return pointee_clang_type.GetChildCompilerTypeAtIndex(
7037 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7038 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7039 child_bitfield_bit_size, child_bitfield_bit_offset,
7040 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
7041 language_flags);
7042 } else {
7043 const char *parent_name =
Konrad Kleine248a1302019-05-23 11:14:47 +00007044 valobj ? valobj->GetName().GetCString() : nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007045 if (parent_name) {
7046 child_name.assign(1, '&');
7047 child_name += parent_name;
7048 }
7049
7050 // We have a pointer to an simple type
7051 if (idx == 0) {
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00007052 if (Optional<uint64_t> size =
7053 pointee_clang_type.GetByteSize(get_exe_scope())) {
Adrian Prantld963a7c2019-01-15 18:07:52 +00007054 child_byte_size = *size;
7055 child_byte_offset = 0;
7056 return pointee_clang_type;
7057 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007058 }
7059 }
7060 }
7061 break;
7062
7063 case clang::Type::Typedef: {
7064 CompilerType typedefed_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007065 this, llvm::cast<clang::TypedefType>(parent_qual_type)
7066 ->getDecl()
7067 ->getUnderlyingType()
7068 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007069 return typedefed_clang_type.GetChildCompilerTypeAtIndex(
7070 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7071 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7072 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7073 child_is_deref_of_parent, valobj, language_flags);
7074 } break;
7075
7076 case clang::Type::Auto: {
7077 CompilerType elaborated_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007078 this, llvm::cast<clang::AutoType>(parent_qual_type)
7079 ->getDeducedType()
7080 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007081 return elaborated_clang_type.GetChildCompilerTypeAtIndex(
7082 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7083 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7084 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7085 child_is_deref_of_parent, valobj, language_flags);
7086 }
7087
7088 case clang::Type::Elaborated: {
7089 CompilerType elaborated_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007090 this, llvm::cast<clang::ElaboratedType>(parent_qual_type)
7091 ->getNamedType()
7092 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007093 return elaborated_clang_type.GetChildCompilerTypeAtIndex(
7094 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7095 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7096 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7097 child_is_deref_of_parent, valobj, language_flags);
7098 }
7099
7100 case clang::Type::Paren: {
Alex Langfordbddab072019-08-13 19:40:36 +00007101 CompilerType paren_clang_type(this,
7102 llvm::cast<clang::ParenType>(parent_qual_type)
7103 ->desugar()
7104 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007105 return paren_clang_type.GetChildCompilerTypeAtIndex(
7106 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
7107 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
7108 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
7109 child_is_deref_of_parent, valobj, language_flags);
7110 }
7111
7112 default:
7113 break;
7114 }
7115 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00007116}
7117
Kate Stoneb9c1b512016-09-06 20:57:50 +00007118static uint32_t GetIndexForRecordBase(const clang::RecordDecl *record_decl,
7119 const clang::CXXBaseSpecifier *base_spec,
7120 bool omit_empty_base_classes) {
7121 uint32_t child_idx = 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00007122
Kate Stoneb9c1b512016-09-06 20:57:50 +00007123 const clang::CXXRecordDecl *cxx_record_decl =
7124 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
7125
7126 // const char *super_name = record_decl->getNameAsCString();
7127 // const char *base_name =
7128 // base_spec->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString();
7129 // printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
7130 //
7131 if (cxx_record_decl) {
7132 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
7133 for (base_class = cxx_record_decl->bases_begin(),
7134 base_class_end = cxx_record_decl->bases_end();
7135 base_class != base_class_end; ++base_class) {
7136 if (omit_empty_base_classes) {
7137 if (BaseSpecifierIsEmpty(base_class))
7138 continue;
7139 }
7140
7141 // printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
7142 // super_name, base_name,
7143 // child_idx,
7144 // base_class->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString());
7145 //
7146 //
7147 if (base_class == base_spec)
7148 return child_idx;
7149 ++child_idx;
Greg Claytond8d4a572015-08-11 21:38:15 +00007150 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007151 }
7152
7153 return UINT32_MAX;
7154}
7155
7156static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl,
7157 clang::NamedDecl *canonical_decl,
7158 bool omit_empty_base_classes) {
7159 uint32_t child_idx = ClangASTContext::GetNumBaseClasses(
7160 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
7161 omit_empty_base_classes);
7162
7163 clang::RecordDecl::field_iterator field, field_end;
7164 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
7165 field != field_end; ++field, ++child_idx) {
7166 if (field->getCanonicalDecl() == canonical_decl)
7167 return child_idx;
7168 }
7169
7170 return UINT32_MAX;
Greg Claytond8d4a572015-08-11 21:38:15 +00007171}
7172
7173// Look for a child member (doesn't include base classes, but it does include
Adrian Prantl05097242018-04-30 16:49:04 +00007174// their members) in the type hierarchy. Returns an index path into
7175// "clang_type" on how to reach the appropriate member.
Greg Claytond8d4a572015-08-11 21:38:15 +00007176//
7177// class A
7178// {
7179// public:
7180// int m_a;
7181// int m_b;
7182// };
7183//
7184// class B
7185// {
7186// };
7187//
7188// class C :
7189// public B,
7190// public A
7191// {
7192// };
7193//
7194// If we have a clang type that describes "class C", and we wanted to looked
7195// "m_b" in it:
7196//
Kate Stoneb9c1b512016-09-06 20:57:50 +00007197// With omit_empty_base_classes == false we would get an integer array back
Adrian Prantl05097242018-04-30 16:49:04 +00007198// with: { 1, 1 } The first index 1 is the child index for "class A" within
7199// class C The second index 1 is the child index for "m_b" within class A
Greg Claytond8d4a572015-08-11 21:38:15 +00007200//
Adrian Prantl05097242018-04-30 16:49:04 +00007201// With omit_empty_base_classes == true we would get an integer array back
7202// with: { 0, 1 } The first index 0 is the child index for "class A" within
7203// class C (since class B doesn't have any members it doesn't count) The second
7204// index 1 is the child index for "m_b" within class A
Greg Claytond8d4a572015-08-11 21:38:15 +00007205
Kate Stoneb9c1b512016-09-06 20:57:50 +00007206size_t ClangASTContext::GetIndexOfChildMemberWithName(
7207 lldb::opaque_compiler_type_t type, const char *name,
7208 bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
7209 if (type && name && name[0]) {
7210 clang::QualType qual_type(GetCanonicalQualType(type));
7211 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7212 switch (type_class) {
7213 case clang::Type::Record:
7214 if (GetCompleteType(type)) {
7215 const clang::RecordType *record_type =
7216 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
7217 const clang::RecordDecl *record_decl = record_type->getDecl();
Enrico Granata36f51e42015-12-18 22:41:25 +00007218
Kate Stoneb9c1b512016-09-06 20:57:50 +00007219 assert(record_decl);
7220 uint32_t child_idx = 0;
7221
7222 const clang::CXXRecordDecl *cxx_record_decl =
7223 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
7224
7225 // Try and find a field that matches NAME
7226 clang::RecordDecl::field_iterator field, field_end;
7227 llvm::StringRef name_sref(name);
7228 for (field = record_decl->field_begin(),
7229 field_end = record_decl->field_end();
7230 field != field_end; ++field, ++child_idx) {
7231 llvm::StringRef field_name = field->getName();
7232 if (field_name.empty()) {
Alex Langfordbddab072019-08-13 19:40:36 +00007233 CompilerType field_type(this, field->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007234 child_indexes.push_back(child_idx);
7235 if (field_type.GetIndexOfChildMemberWithName(
7236 name, omit_empty_base_classes, child_indexes))
7237 return child_indexes.size();
7238 child_indexes.pop_back();
7239
7240 } else if (field_name.equals(name_sref)) {
7241 // We have to add on the number of base classes to this index!
7242 child_indexes.push_back(
7243 child_idx + ClangASTContext::GetNumBaseClasses(
7244 cxx_record_decl, omit_empty_base_classes));
7245 return child_indexes.size();
7246 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007247 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007248
Kate Stoneb9c1b512016-09-06 20:57:50 +00007249 if (cxx_record_decl) {
7250 const clang::RecordDecl *parent_record_decl = cxx_record_decl;
7251
7252 // printf ("parent = %s\n", parent_record_decl->getNameAsCString());
7253
7254 // const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
7255 // Didn't find things easily, lets let clang do its thang...
7256 clang::IdentifierInfo &ident_ref =
7257 getASTContext()->Idents.get(name_sref);
7258 clang::DeclarationName decl_name(&ident_ref);
7259
7260 clang::CXXBasePaths paths;
7261 if (cxx_record_decl->lookupInBases(
7262 [decl_name](const clang::CXXBaseSpecifier *specifier,
7263 clang::CXXBasePath &path) {
7264 return clang::CXXRecordDecl::FindOrdinaryMember(
7265 specifier, path, decl_name);
7266 },
7267 paths)) {
7268 clang::CXXBasePaths::const_paths_iterator path,
7269 path_end = paths.end();
7270 for (path = paths.begin(); path != path_end; ++path) {
7271 const size_t num_path_elements = path->size();
7272 for (size_t e = 0; e < num_path_elements; ++e) {
7273 clang::CXXBasePathElement elem = (*path)[e];
7274
7275 child_idx = GetIndexForRecordBase(parent_record_decl, elem.Base,
7276 omit_empty_base_classes);
7277 if (child_idx == UINT32_MAX) {
7278 child_indexes.clear();
7279 return 0;
7280 } else {
7281 child_indexes.push_back(child_idx);
7282 parent_record_decl = llvm::cast<clang::RecordDecl>(
7283 elem.Base->getType()
7284 ->getAs<clang::RecordType>()
7285 ->getDecl());
7286 }
7287 }
7288 for (clang::NamedDecl *path_decl : path->Decls) {
7289 child_idx = GetIndexForRecordChild(
7290 parent_record_decl, path_decl, omit_empty_base_classes);
7291 if (child_idx == UINT32_MAX) {
7292 child_indexes.clear();
7293 return 0;
7294 } else {
7295 child_indexes.push_back(child_idx);
7296 }
7297 }
7298 }
7299 return child_indexes.size();
7300 }
7301 }
7302 }
7303 break;
7304
7305 case clang::Type::ObjCObject:
7306 case clang::Type::ObjCInterface:
7307 if (GetCompleteType(type)) {
7308 llvm::StringRef name_sref(name);
7309 const clang::ObjCObjectType *objc_class_type =
7310 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
7311 assert(objc_class_type);
7312 if (objc_class_type) {
7313 uint32_t child_idx = 0;
7314 clang::ObjCInterfaceDecl *class_interface_decl =
7315 objc_class_type->getInterface();
7316
7317 if (class_interface_decl) {
7318 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
7319 ivar_end = class_interface_decl->ivar_end();
7320 clang::ObjCInterfaceDecl *superclass_interface_decl =
7321 class_interface_decl->getSuperClass();
7322
7323 for (ivar_pos = class_interface_decl->ivar_begin();
7324 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
7325 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
7326
7327 if (ivar_decl->getName().equals(name_sref)) {
7328 if ((!omit_empty_base_classes && superclass_interface_decl) ||
7329 (omit_empty_base_classes &&
7330 ObjCDeclHasIVars(superclass_interface_decl, true)))
7331 ++child_idx;
7332
7333 child_indexes.push_back(child_idx);
7334 return child_indexes.size();
7335 }
7336 }
7337
7338 if (superclass_interface_decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00007339 // The super class index is always zero for ObjC classes, so we
7340 // push it onto the child indexes in case we find an ivar in our
7341 // superclass...
Kate Stoneb9c1b512016-09-06 20:57:50 +00007342 child_indexes.push_back(0);
7343
7344 CompilerType superclass_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007345 this, getASTContext()
7346 ->getObjCInterfaceType(superclass_interface_decl)
7347 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007348 if (superclass_clang_type.GetIndexOfChildMemberWithName(
7349 name, omit_empty_base_classes, child_indexes)) {
Adrian Prantl05097242018-04-30 16:49:04 +00007350 // We did find an ivar in a superclass so just return the
7351 // results!
Kate Stoneb9c1b512016-09-06 20:57:50 +00007352 return child_indexes.size();
7353 }
7354
Adrian Prantl05097242018-04-30 16:49:04 +00007355 // We didn't find an ivar matching "name" in our superclass, pop
7356 // the superclass zero index that we pushed on above.
Kate Stoneb9c1b512016-09-06 20:57:50 +00007357 child_indexes.pop_back();
7358 }
7359 }
7360 }
7361 }
7362 break;
7363
7364 case clang::Type::ObjCObjectPointer: {
7365 CompilerType objc_object_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007366 this, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
7367 ->getPointeeType()
7368 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007369 return objc_object_clang_type.GetIndexOfChildMemberWithName(
7370 name, omit_empty_base_classes, child_indexes);
7371 } break;
7372
7373 case clang::Type::ConstantArray: {
7374 // const clang::ConstantArrayType *array =
7375 // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
7376 // const uint64_t element_count =
7377 // array->getSize().getLimitedValue();
7378 //
7379 // if (idx < element_count)
7380 // {
7381 // std::pair<uint64_t, unsigned> field_type_info =
7382 // ast->getTypeInfo(array->getElementType());
7383 //
7384 // char element_name[32];
7385 // ::snprintf (element_name, sizeof (element_name),
7386 // "%s[%u]", parent_name ? parent_name : "", idx);
7387 //
7388 // child_name.assign(element_name);
7389 // assert(field_type_info.first % 8 == 0);
7390 // child_byte_size = field_type_info.first / 8;
7391 // child_byte_offset = idx * child_byte_size;
7392 // return array->getElementType().getAsOpaquePtr();
7393 // }
7394 } break;
7395
7396 // case clang::Type::MemberPointerType:
7397 // {
7398 // MemberPointerType *mem_ptr_type =
7399 // llvm::cast<MemberPointerType>(qual_type.getTypePtr());
7400 // clang::QualType pointee_type =
7401 // mem_ptr_type->getPointeeType();
7402 //
7403 // if (ClangASTContext::IsAggregateType
7404 // (pointee_type.getAsOpaquePtr()))
7405 // {
7406 // return GetIndexOfChildWithName (ast,
7407 // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
7408 // name);
7409 // }
7410 // }
7411 // break;
7412 //
7413 case clang::Type::LValueReference:
7414 case clang::Type::RValueReference: {
7415 const clang::ReferenceType *reference_type =
7416 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
7417 clang::QualType pointee_type(reference_type->getPointeeType());
Alex Langfordbddab072019-08-13 19:40:36 +00007418 CompilerType pointee_clang_type(this, pointee_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007419
7420 if (pointee_clang_type.IsAggregateType()) {
7421 return pointee_clang_type.GetIndexOfChildMemberWithName(
7422 name, omit_empty_base_classes, child_indexes);
7423 }
7424 } break;
7425
7426 case clang::Type::Pointer: {
7427 CompilerType pointee_clang_type(GetPointeeType(type));
7428
7429 if (pointee_clang_type.IsAggregateType()) {
7430 return pointee_clang_type.GetIndexOfChildMemberWithName(
7431 name, omit_empty_base_classes, child_indexes);
7432 }
7433 } break;
7434
7435 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00007436 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
7437 ->getDecl()
7438 ->getUnderlyingType()
7439 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007440 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7441 child_indexes);
7442
7443 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00007444 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
7445 ->getDeducedType()
7446 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007447 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7448 child_indexes);
7449
7450 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00007451 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
7452 ->getNamedType()
7453 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007454 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7455 child_indexes);
7456
7457 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00007458 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
7459 ->desugar()
7460 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007461 .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7462 child_indexes);
7463
7464 default:
7465 break;
7466 }
7467 }
7468 return 0;
7469}
Greg Claytond8d4a572015-08-11 21:38:15 +00007470
7471// Get the index of the child of "clang_type" whose name matches. This function
7472// doesn't descend into the children, but only looks one level deep and name
7473// matches can include base class names.
7474
7475uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00007476ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
7477 const char *name,
7478 bool omit_empty_base_classes) {
7479 if (type && name && name[0]) {
7480 clang::QualType qual_type(GetCanonicalQualType(type));
Enrico Granata36f51e42015-12-18 22:41:25 +00007481
Kate Stoneb9c1b512016-09-06 20:57:50 +00007482 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7483
7484 switch (type_class) {
7485 case clang::Type::Record:
7486 if (GetCompleteType(type)) {
7487 const clang::RecordType *record_type =
7488 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
7489 const clang::RecordDecl *record_decl = record_type->getDecl();
7490
7491 assert(record_decl);
7492 uint32_t child_idx = 0;
7493
7494 const clang::CXXRecordDecl *cxx_record_decl =
7495 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
7496
7497 if (cxx_record_decl) {
7498 clang::CXXRecordDecl::base_class_const_iterator base_class,
7499 base_class_end;
7500 for (base_class = cxx_record_decl->bases_begin(),
7501 base_class_end = cxx_record_decl->bases_end();
7502 base_class != base_class_end; ++base_class) {
7503 // Skip empty base classes
7504 clang::CXXRecordDecl *base_class_decl =
7505 llvm::cast<clang::CXXRecordDecl>(
7506 base_class->getType()
7507 ->getAs<clang::RecordType>()
7508 ->getDecl());
7509 if (omit_empty_base_classes &&
Jonas Devliegherea6682a42018-12-15 00:15:33 +00007510 !ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00007511 continue;
7512
Alex Langfordbddab072019-08-13 19:40:36 +00007513 CompilerType base_class_clang_type(
7514 this, base_class->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007515 std::string base_class_type_name(
7516 base_class_clang_type.GetTypeName().AsCString(""));
Jonas Devlieghere8d20cfd2018-12-21 22:46:10 +00007517 if (base_class_type_name == name)
Kate Stoneb9c1b512016-09-06 20:57:50 +00007518 return child_idx;
7519 ++child_idx;
7520 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007521 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007522
Kate Stoneb9c1b512016-09-06 20:57:50 +00007523 // Try and find a field that matches NAME
7524 clang::RecordDecl::field_iterator field, field_end;
7525 llvm::StringRef name_sref(name);
7526 for (field = record_decl->field_begin(),
7527 field_end = record_decl->field_end();
7528 field != field_end; ++field, ++child_idx) {
7529 if (field->getName().equals(name_sref))
7530 return child_idx;
7531 }
7532 }
7533 break;
7534
7535 case clang::Type::ObjCObject:
7536 case clang::Type::ObjCInterface:
7537 if (GetCompleteType(type)) {
7538 llvm::StringRef name_sref(name);
7539 const clang::ObjCObjectType *objc_class_type =
7540 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
7541 assert(objc_class_type);
7542 if (objc_class_type) {
7543 uint32_t child_idx = 0;
7544 clang::ObjCInterfaceDecl *class_interface_decl =
7545 objc_class_type->getInterface();
7546
7547 if (class_interface_decl) {
7548 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
7549 ivar_end = class_interface_decl->ivar_end();
7550 clang::ObjCInterfaceDecl *superclass_interface_decl =
7551 class_interface_decl->getSuperClass();
7552
7553 for (ivar_pos = class_interface_decl->ivar_begin();
7554 ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
7555 const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
7556
7557 if (ivar_decl->getName().equals(name_sref)) {
7558 if ((!omit_empty_base_classes && superclass_interface_decl) ||
7559 (omit_empty_base_classes &&
7560 ObjCDeclHasIVars(superclass_interface_decl, true)))
7561 ++child_idx;
7562
7563 return child_idx;
7564 }
7565 }
7566
7567 if (superclass_interface_decl) {
7568 if (superclass_interface_decl->getName().equals(name_sref))
7569 return 0;
7570 }
7571 }
7572 }
7573 }
7574 break;
7575
7576 case clang::Type::ObjCObjectPointer: {
7577 CompilerType pointee_clang_type(
Alex Langfordbddab072019-08-13 19:40:36 +00007578 this, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
7579 ->getPointeeType()
7580 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007581 return pointee_clang_type.GetIndexOfChildWithName(
7582 name, omit_empty_base_classes);
7583 } break;
7584
7585 case clang::Type::ConstantArray: {
7586 // const clang::ConstantArrayType *array =
7587 // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
7588 // const uint64_t element_count =
7589 // array->getSize().getLimitedValue();
7590 //
7591 // if (idx < element_count)
7592 // {
7593 // std::pair<uint64_t, unsigned> field_type_info =
7594 // ast->getTypeInfo(array->getElementType());
7595 //
7596 // char element_name[32];
7597 // ::snprintf (element_name, sizeof (element_name),
7598 // "%s[%u]", parent_name ? parent_name : "", idx);
7599 //
7600 // child_name.assign(element_name);
7601 // assert(field_type_info.first % 8 == 0);
7602 // child_byte_size = field_type_info.first / 8;
7603 // child_byte_offset = idx * child_byte_size;
7604 // return array->getElementType().getAsOpaquePtr();
7605 // }
7606 } break;
7607
7608 // case clang::Type::MemberPointerType:
7609 // {
7610 // MemberPointerType *mem_ptr_type =
7611 // llvm::cast<MemberPointerType>(qual_type.getTypePtr());
7612 // clang::QualType pointee_type =
7613 // mem_ptr_type->getPointeeType();
7614 //
7615 // if (ClangASTContext::IsAggregateType
7616 // (pointee_type.getAsOpaquePtr()))
7617 // {
7618 // return GetIndexOfChildWithName (ast,
7619 // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
7620 // name);
7621 // }
7622 // }
7623 // break;
7624 //
7625 case clang::Type::LValueReference:
7626 case clang::Type::RValueReference: {
7627 const clang::ReferenceType *reference_type =
7628 llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
Alex Langfordbddab072019-08-13 19:40:36 +00007629 CompilerType pointee_type(
7630 this, reference_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007631
7632 if (pointee_type.IsAggregateType()) {
7633 return pointee_type.GetIndexOfChildWithName(name,
7634 omit_empty_base_classes);
7635 }
7636 } break;
7637
7638 case clang::Type::Pointer: {
7639 const clang::PointerType *pointer_type =
7640 llvm::cast<clang::PointerType>(qual_type.getTypePtr());
Alex Langfordbddab072019-08-13 19:40:36 +00007641 CompilerType pointee_type(
7642 this, pointer_type->getPointeeType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007643
7644 if (pointee_type.IsAggregateType()) {
7645 return pointee_type.GetIndexOfChildWithName(name,
7646 omit_empty_base_classes);
7647 } else {
7648 // if (parent_name)
7649 // {
7650 // child_name.assign(1, '*');
7651 // child_name += parent_name;
7652 // }
7653 //
7654 // // We have a pointer to an simple type
7655 // if (idx == 0)
7656 // {
7657 // std::pair<uint64_t, unsigned> clang_type_info
7658 // = ast->getTypeInfo(pointee_type);
7659 // assert(clang_type_info.first % 8 == 0);
7660 // child_byte_size = clang_type_info.first / 8;
7661 // child_byte_offset = 0;
7662 // return pointee_type.getAsOpaquePtr();
7663 // }
7664 }
7665 } break;
7666
7667 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00007668 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
7669 ->getDeducedType()
7670 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007671 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7672
7673 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00007674 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
7675 ->getNamedType()
7676 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007677 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7678
7679 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00007680 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
7681 ->desugar()
7682 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007683 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7684
7685 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00007686 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
7687 ->getDecl()
7688 ->getUnderlyingType()
7689 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007690 .GetIndexOfChildWithName(name, omit_empty_base_classes);
7691
7692 default:
7693 break;
7694 }
7695 }
7696 return UINT32_MAX;
7697}
Greg Claytond8d4a572015-08-11 21:38:15 +00007698
7699size_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00007700ClangASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
7701 if (!type)
Greg Claytond8d4a572015-08-11 21:38:15 +00007702 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00007703
Kate Stoneb9c1b512016-09-06 20:57:50 +00007704 clang::QualType qual_type(GetCanonicalQualType(type));
7705 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7706 switch (type_class) {
7707 case clang::Type::Record:
7708 if (GetCompleteType(type)) {
7709 const clang::CXXRecordDecl *cxx_record_decl =
7710 qual_type->getAsCXXRecordDecl();
7711 if (cxx_record_decl) {
7712 const clang::ClassTemplateSpecializationDecl *template_decl =
7713 llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
7714 cxx_record_decl);
7715 if (template_decl)
7716 return template_decl->getTemplateArgs().size();
7717 }
Greg Claytond8d4a572015-08-11 21:38:15 +00007718 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007719 break;
7720
7721 case clang::Type::Typedef:
Alex Langfordbddab072019-08-13 19:40:36 +00007722 return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
7723 ->getDecl()
7724 ->getUnderlyingType()
7725 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007726 .GetNumTemplateArguments();
7727
7728 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00007729 return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
7730 ->getDeducedType()
7731 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007732 .GetNumTemplateArguments();
7733
7734 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00007735 return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
7736 ->getNamedType()
7737 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007738 .GetNumTemplateArguments();
7739
7740 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00007741 return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
7742 ->desugar()
7743 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00007744 .GetNumTemplateArguments();
7745
7746 default:
7747 break;
7748 }
7749
7750 return 0;
Greg Claytond8d4a572015-08-11 21:38:15 +00007751}
7752
Pavel Labath769b21e2017-11-13 14:26:21 +00007753const clang::ClassTemplateSpecializationDecl *
7754ClangASTContext::GetAsTemplateSpecialization(
7755 lldb::opaque_compiler_type_t type) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00007756 if (!type)
Pavel Labath769b21e2017-11-13 14:26:21 +00007757 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007758
7759 clang::QualType qual_type(GetCanonicalQualType(type));
7760 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
7761 switch (type_class) {
Pavel Labath769b21e2017-11-13 14:26:21 +00007762 case clang::Type::Record: {
7763 if (! GetCompleteType(type))
7764 return nullptr;
7765 const clang::CXXRecordDecl *cxx_record_decl =
7766 qual_type->getAsCXXRecordDecl();
7767 if (!cxx_record_decl)
7768 return nullptr;
7769 return llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
7770 cxx_record_decl);
7771 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00007772
7773 case clang::Type::Typedef:
Pavel Labath769b21e2017-11-13 14:26:21 +00007774 return GetAsTemplateSpecialization(llvm::cast<clang::TypedefType>(qual_type)
7775 ->getDecl()
7776 ->getUnderlyingType()
7777 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007778
7779 case clang::Type::Auto:
Pavel Labath769b21e2017-11-13 14:26:21 +00007780 return GetAsTemplateSpecialization(llvm::cast<clang::AutoType>(qual_type)
7781 ->getDeducedType()
7782 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007783
7784 case clang::Type::Elaborated:
Pavel Labath769b21e2017-11-13 14:26:21 +00007785 return GetAsTemplateSpecialization(
7786 llvm::cast<clang::ElaboratedType>(qual_type)
7787 ->getNamedType()
7788 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007789
7790 case clang::Type::Paren:
Pavel Labath769b21e2017-11-13 14:26:21 +00007791 return GetAsTemplateSpecialization(
7792 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00007793
7794 default:
Pavel Labath769b21e2017-11-13 14:26:21 +00007795 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007796 }
Pavel Labath769b21e2017-11-13 14:26:21 +00007797}
7798
7799lldb::TemplateArgumentKind
7800ClangASTContext::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
7801 size_t arg_idx) {
7802 const clang::ClassTemplateSpecializationDecl *template_decl =
7803 GetAsTemplateSpecialization(type);
7804 if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size())
7805 return eTemplateArgumentKindNull;
7806
7807 switch (template_decl->getTemplateArgs()[arg_idx].getKind()) {
7808 case clang::TemplateArgument::Null:
7809 return eTemplateArgumentKindNull;
7810
7811 case clang::TemplateArgument::NullPtr:
7812 return eTemplateArgumentKindNullPtr;
7813
7814 case clang::TemplateArgument::Type:
7815 return eTemplateArgumentKindType;
7816
7817 case clang::TemplateArgument::Declaration:
7818 return eTemplateArgumentKindDeclaration;
7819
7820 case clang::TemplateArgument::Integral:
7821 return eTemplateArgumentKindIntegral;
7822
7823 case clang::TemplateArgument::Template:
7824 return eTemplateArgumentKindTemplate;
7825
7826 case clang::TemplateArgument::TemplateExpansion:
7827 return eTemplateArgumentKindTemplateExpansion;
7828
7829 case clang::TemplateArgument::Expression:
7830 return eTemplateArgumentKindExpression;
7831
7832 case clang::TemplateArgument::Pack:
7833 return eTemplateArgumentKindPack;
7834 }
7835 llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind");
7836}
7837
7838CompilerType
7839ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
7840 size_t idx) {
7841 const clang::ClassTemplateSpecializationDecl *template_decl =
7842 GetAsTemplateSpecialization(type);
7843 if (!template_decl || idx >= template_decl->getTemplateArgs().size())
7844 return CompilerType();
7845
7846 const clang::TemplateArgument &template_arg =
7847 template_decl->getTemplateArgs()[idx];
7848 if (template_arg.getKind() != clang::TemplateArgument::Type)
7849 return CompilerType();
7850
Alex Langfordbddab072019-08-13 19:40:36 +00007851 return CompilerType(this, template_arg.getAsType().getAsOpaquePtr());
Pavel Labath769b21e2017-11-13 14:26:21 +00007852}
7853
Adrian Prantl2f1fa7a2019-01-15 21:04:19 +00007854Optional<CompilerType::IntegralTemplateArgument>
Pavel Labath769b21e2017-11-13 14:26:21 +00007855ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
7856 size_t idx) {
7857 const clang::ClassTemplateSpecializationDecl *template_decl =
7858 GetAsTemplateSpecialization(type);
7859 if (! template_decl || idx >= template_decl->getTemplateArgs().size())
Pavel Labathf59056f2017-11-30 10:16:54 +00007860 return llvm::None;
Pavel Labath769b21e2017-11-13 14:26:21 +00007861
7862 const clang::TemplateArgument &template_arg =
7863 template_decl->getTemplateArgs()[idx];
7864 if (template_arg.getKind() != clang::TemplateArgument::Integral)
Pavel Labathf59056f2017-11-30 10:16:54 +00007865 return llvm::None;
Pavel Labath769b21e2017-11-13 14:26:21 +00007866
Alex Langfordbddab072019-08-13 19:40:36 +00007867 return {
7868 {template_arg.getAsIntegral(),
7869 CompilerType(this, template_arg.getIntegralType().getAsOpaquePtr())}};
Enrico Granatac6bf2e22015-09-23 01:39:46 +00007870}
7871
Kate Stoneb9c1b512016-09-06 20:57:50 +00007872CompilerType ClangASTContext::GetTypeForFormatters(void *type) {
7873 if (type)
7874 return ClangUtil::RemoveFastQualifiers(CompilerType(this, type));
7875 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00007876}
7877
Kate Stoneb9c1b512016-09-06 20:57:50 +00007878clang::EnumDecl *ClangASTContext::GetAsEnumDecl(const CompilerType &type) {
7879 const clang::EnumType *enutype =
7880 llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type));
7881 if (enutype)
7882 return enutype->getDecl();
Konrad Kleine248a1302019-05-23 11:14:47 +00007883 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007884}
7885
7886clang::RecordDecl *ClangASTContext::GetAsRecordDecl(const CompilerType &type) {
7887 const clang::RecordType *record_type =
7888 llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type));
7889 if (record_type)
7890 return record_type->getDecl();
7891 return nullptr;
7892}
7893
7894clang::TagDecl *ClangASTContext::GetAsTagDecl(const CompilerType &type) {
Zachary Turner1639c6b2018-12-17 16:15:13 +00007895 return ClangUtil::GetAsTagDecl(type);
Greg Claytone6b36cd2015-12-08 01:02:08 +00007896}
7897
Aleksandr Urakov709426b2018-09-10 08:08:43 +00007898clang::TypedefNameDecl *
7899ClangASTContext::GetAsTypedefDecl(const CompilerType &type) {
7900 const clang::TypedefType *typedef_type =
7901 llvm::dyn_cast<clang::TypedefType>(ClangUtil::GetQualType(type));
7902 if (typedef_type)
7903 return typedef_type->getDecl();
7904 return nullptr;
7905}
7906
Greg Claytond8d4a572015-08-11 21:38:15 +00007907clang::CXXRecordDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00007908ClangASTContext::GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type) {
7909 return GetCanonicalQualType(type)->getAsCXXRecordDecl();
Greg Claytond8d4a572015-08-11 21:38:15 +00007910}
7911
7912clang::ObjCInterfaceDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +00007913ClangASTContext::GetAsObjCInterfaceDecl(const CompilerType &type) {
7914 const clang::ObjCObjectType *objc_class_type =
7915 llvm::dyn_cast<clang::ObjCObjectType>(
7916 ClangUtil::GetCanonicalQualType(type));
7917 if (objc_class_type)
7918 return objc_class_type->getInterface();
7919 return nullptr;
7920}
7921
7922clang::FieldDecl *ClangASTContext::AddFieldToRecordType(
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007923 const CompilerType &type, llvm::StringRef name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00007924 const CompilerType &field_clang_type, AccessType access,
7925 uint32_t bitfield_bit_size) {
7926 if (!type.IsValid() || !field_clang_type.IsValid())
Greg Claytond8d4a572015-08-11 21:38:15 +00007927 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00007928 ClangASTContext *ast =
7929 llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
7930 if (!ast)
7931 return nullptr;
7932 clang::ASTContext *clang_ast = ast->getASTContext();
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007933 clang::IdentifierInfo *ident = nullptr;
7934 if (!name.empty())
7935 ident = &clang_ast->Idents.get(name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00007936
7937 clang::FieldDecl *field = nullptr;
7938
7939 clang::Expr *bit_width = nullptr;
7940 if (bitfield_bit_size != 0) {
7941 llvm::APInt bitfield_bit_size_apint(
7942 clang_ast->getTypeSize(clang_ast->IntTy), bitfield_bit_size);
7943 bit_width = new (*clang_ast)
7944 clang::IntegerLiteral(*clang_ast, bitfield_bit_size_apint,
7945 clang_ast->IntTy, clang::SourceLocation());
7946 }
7947
7948 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
7949 if (record_decl) {
7950 field = clang::FieldDecl::Create(
7951 *clang_ast, record_decl, clang::SourceLocation(),
7952 clang::SourceLocation(),
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007953 ident, // Identifier
7954 ClangUtil::GetQualType(field_clang_type), // Field type
7955 nullptr, // TInfo *
7956 bit_width, // BitWidth
7957 false, // Mutable
7958 clang::ICIS_NoInit); // HasInit
Kate Stoneb9c1b512016-09-06 20:57:50 +00007959
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007960 if (name.empty()) {
Adrian Prantl05097242018-04-30 16:49:04 +00007961 // Determine whether this field corresponds to an anonymous struct or
7962 // union.
Kate Stoneb9c1b512016-09-06 20:57:50 +00007963 if (const clang::TagType *TagT =
7964 field->getType()->getAs<clang::TagType>()) {
7965 if (clang::RecordDecl *Rec =
7966 llvm::dyn_cast<clang::RecordDecl>(TagT->getDecl()))
7967 if (!Rec->getDeclName()) {
7968 Rec->setAnonymousStructOrUnion(true);
7969 field->setImplicit();
7970 }
7971 }
7972 }
7973
7974 if (field) {
7975 field->setAccess(
7976 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access));
7977
7978 record_decl->addDecl(field);
7979
7980#ifdef LLDB_CONFIGURATION_DEBUG
7981 VerifyDecl(field);
7982#endif
7983 }
7984 } else {
7985 clang::ObjCInterfaceDecl *class_interface_decl =
7986 ast->GetAsObjCInterfaceDecl(type);
7987
7988 if (class_interface_decl) {
7989 const bool is_synthesized = false;
7990
7991 field_clang_type.GetCompleteType();
7992
7993 field = clang::ObjCIvarDecl::Create(
7994 *clang_ast, class_interface_decl, clang::SourceLocation(),
7995 clang::SourceLocation(),
Zachary Turnera3e2ea12018-10-23 17:22:02 +00007996 ident, // Identifier
7997 ClangUtil::GetQualType(field_clang_type), // Field type
7998 nullptr, // TypeSourceInfo *
Kate Stoneb9c1b512016-09-06 20:57:50 +00007999 ConvertAccessTypeToObjCIvarAccessControl(access), bit_width,
8000 is_synthesized);
8001
8002 if (field) {
8003 class_interface_decl->addDecl(field);
8004
8005#ifdef LLDB_CONFIGURATION_DEBUG
8006 VerifyDecl(field);
8007#endif
8008 }
8009 }
8010 }
8011 return field;
Greg Claytond8d4a572015-08-11 21:38:15 +00008012}
8013
Kate Stoneb9c1b512016-09-06 20:57:50 +00008014void ClangASTContext::BuildIndirectFields(const CompilerType &type) {
8015 if (!type)
8016 return;
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008017
Kate Stoneb9c1b512016-09-06 20:57:50 +00008018 ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8019 if (!ast)
8020 return;
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008021
Kate Stoneb9c1b512016-09-06 20:57:50 +00008022 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008023
Kate Stoneb9c1b512016-09-06 20:57:50 +00008024 if (!record_decl)
8025 return;
8026
8027 typedef llvm::SmallVector<clang::IndirectFieldDecl *, 1> IndirectFieldVector;
8028
8029 IndirectFieldVector indirect_fields;
8030 clang::RecordDecl::field_iterator field_pos;
8031 clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end();
8032 clang::RecordDecl::field_iterator last_field_pos = field_end_pos;
8033 for (field_pos = record_decl->field_begin(); field_pos != field_end_pos;
8034 last_field_pos = field_pos++) {
8035 if (field_pos->isAnonymousStructOrUnion()) {
8036 clang::QualType field_qual_type = field_pos->getType();
8037
8038 const clang::RecordType *field_record_type =
8039 field_qual_type->getAs<clang::RecordType>();
8040
8041 if (!field_record_type)
8042 continue;
8043
8044 clang::RecordDecl *field_record_decl = field_record_type->getDecl();
8045
8046 if (!field_record_decl)
8047 continue;
8048
8049 for (clang::RecordDecl::decl_iterator
8050 di = field_record_decl->decls_begin(),
8051 de = field_record_decl->decls_end();
8052 di != de; ++di) {
8053 if (clang::FieldDecl *nested_field_decl =
8054 llvm::dyn_cast<clang::FieldDecl>(*di)) {
8055 clang::NamedDecl **chain =
8056 new (*ast->getASTContext()) clang::NamedDecl *[2];
8057 chain[0] = *field_pos;
8058 chain[1] = nested_field_decl;
8059 clang::IndirectFieldDecl *indirect_field =
8060 clang::IndirectFieldDecl::Create(
8061 *ast->getASTContext(), record_decl, clang::SourceLocation(),
8062 nested_field_decl->getIdentifier(),
8063 nested_field_decl->getType(), {chain, 2});
8064
8065 indirect_field->setImplicit();
8066
8067 indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(
8068 field_pos->getAccess(), nested_field_decl->getAccess()));
8069
8070 indirect_fields.push_back(indirect_field);
8071 } else if (clang::IndirectFieldDecl *nested_indirect_field_decl =
8072 llvm::dyn_cast<clang::IndirectFieldDecl>(*di)) {
8073 size_t nested_chain_size =
8074 nested_indirect_field_decl->getChainingSize();
8075 clang::NamedDecl **chain = new (*ast->getASTContext())
8076 clang::NamedDecl *[nested_chain_size + 1];
8077 chain[0] = *field_pos;
8078
8079 int chain_index = 1;
8080 for (clang::IndirectFieldDecl::chain_iterator
8081 nci = nested_indirect_field_decl->chain_begin(),
8082 nce = nested_indirect_field_decl->chain_end();
8083 nci < nce; ++nci) {
8084 chain[chain_index] = *nci;
8085 chain_index++;
8086 }
8087
8088 clang::IndirectFieldDecl *indirect_field =
8089 clang::IndirectFieldDecl::Create(
8090 *ast->getASTContext(), record_decl, clang::SourceLocation(),
8091 nested_indirect_field_decl->getIdentifier(),
8092 nested_indirect_field_decl->getType(),
8093 {chain, nested_chain_size + 1});
8094
8095 indirect_field->setImplicit();
8096
8097 indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(
8098 field_pos->getAccess(), nested_indirect_field_decl->getAccess()));
8099
8100 indirect_fields.push_back(indirect_field);
Greg Claytond8d4a572015-08-11 21:38:15 +00008101 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008102 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008103 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008104 }
8105
Adrian Prantl05097242018-04-30 16:49:04 +00008106 // Check the last field to see if it has an incomplete array type as its last
8107 // member and if it does, the tell the record decl about it
Kate Stoneb9c1b512016-09-06 20:57:50 +00008108 if (last_field_pos != field_end_pos) {
8109 if (last_field_pos->getType()->isIncompleteArrayType())
8110 record_decl->hasFlexibleArrayMember();
8111 }
8112
8113 for (IndirectFieldVector::iterator ifi = indirect_fields.begin(),
8114 ife = indirect_fields.end();
8115 ifi < ife; ++ifi) {
8116 record_decl->addDecl(*ifi);
8117 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008118}
8119
Kate Stoneb9c1b512016-09-06 20:57:50 +00008120void ClangASTContext::SetIsPacked(const CompilerType &type) {
8121 if (type) {
8122 ClangASTContext *ast =
8123 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8124 if (ast) {
8125 clang::RecordDecl *record_decl = GetAsRecordDecl(type);
8126
8127 if (!record_decl)
Greg Claytonf73034f2015-09-08 18:15:05 +00008128 return;
8129
Kate Stoneb9c1b512016-09-06 20:57:50 +00008130 record_decl->addAttr(
8131 clang::PackedAttr::CreateImplicit(*ast->getASTContext()));
Greg Claytond8d4a572015-08-11 21:38:15 +00008132 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008133 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008134}
8135
Kate Stoneb9c1b512016-09-06 20:57:50 +00008136clang::VarDecl *ClangASTContext::AddVariableToRecordType(
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008137 const CompilerType &type, llvm::StringRef name,
8138 const CompilerType &var_type, AccessType access) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00008139 if (!type.IsValid() || !var_type.IsValid())
8140 return nullptr;
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008141
Kate Stoneb9c1b512016-09-06 20:57:50 +00008142 ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8143 if (!ast)
8144 return nullptr;
8145
8146 clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008147 if (!record_decl)
8148 return nullptr;
8149
8150 clang::VarDecl *var_decl = nullptr;
8151 clang::IdentifierInfo *ident = nullptr;
8152 if (!name.empty())
8153 ident = &ast->getASTContext()->Idents.get(name);
8154
8155 var_decl = clang::VarDecl::Create(
8156 *ast->getASTContext(), // ASTContext &
8157 record_decl, // DeclContext *
8158 clang::SourceLocation(), // clang::SourceLocation StartLoc
8159 clang::SourceLocation(), // clang::SourceLocation IdLoc
8160 ident, // clang::IdentifierInfo *
8161 ClangUtil::GetQualType(var_type), // Variable clang::QualType
8162 nullptr, // TypeSourceInfo *
8163 clang::SC_Static); // StorageClass
8164 if (!var_decl)
8165 return nullptr;
8166
8167 var_decl->setAccess(
8168 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access));
8169 record_decl->addDecl(var_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008170
Greg Claytond8d4a572015-08-11 21:38:15 +00008171#ifdef LLDB_CONFIGURATION_DEBUG
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008172 VerifyDecl(var_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008173#endif
Zachary Turnera3e2ea12018-10-23 17:22:02 +00008174
Kate Stoneb9c1b512016-09-06 20:57:50 +00008175 return var_decl;
Greg Claytond8d4a572015-08-11 21:38:15 +00008176}
8177
Kate Stoneb9c1b512016-09-06 20:57:50 +00008178clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
Davide Italiano675767a2018-03-27 19:40:50 +00008179 lldb::opaque_compiler_type_t type, const char *name, const char *mangled_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +00008180 const CompilerType &method_clang_type, lldb::AccessType access,
8181 bool is_virtual, bool is_static, bool is_inline, bool is_explicit,
8182 bool is_attr_used, bool is_artificial) {
8183 if (!type || !method_clang_type.IsValid() || name == nullptr ||
8184 name[0] == '\0')
8185 return nullptr;
Greg Claytond8d4a572015-08-11 21:38:15 +00008186
Kate Stoneb9c1b512016-09-06 20:57:50 +00008187 clang::QualType record_qual_type(GetCanonicalQualType(type));
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008188
Kate Stoneb9c1b512016-09-06 20:57:50 +00008189 clang::CXXRecordDecl *cxx_record_decl =
8190 record_qual_type->getAsCXXRecordDecl();
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008191
Kate Stoneb9c1b512016-09-06 20:57:50 +00008192 if (cxx_record_decl == nullptr)
8193 return nullptr;
8194
8195 clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
8196
8197 clang::CXXMethodDecl *cxx_method_decl = nullptr;
8198
8199 clang::DeclarationName decl_name(&getASTContext()->Idents.get(name));
8200
8201 const clang::FunctionType *function_type =
8202 llvm::dyn_cast<clang::FunctionType>(method_qual_type.getTypePtr());
8203
8204 if (function_type == nullptr)
8205 return nullptr;
8206
8207 const clang::FunctionProtoType *method_function_prototype(
8208 llvm::dyn_cast<clang::FunctionProtoType>(function_type));
8209
8210 if (!method_function_prototype)
8211 return nullptr;
8212
8213 unsigned int num_params = method_function_prototype->getNumParams();
8214
8215 clang::CXXDestructorDecl *cxx_dtor_decl(nullptr);
8216 clang::CXXConstructorDecl *cxx_ctor_decl(nullptr);
8217
8218 if (is_artificial)
8219 return nullptr; // skip everything artificial
8220
Richard Smith36851a62019-05-09 04:40:57 +00008221 const clang::ExplicitSpecifier explicit_spec(
8222 nullptr /*expr*/, is_explicit
8223 ? clang::ExplicitSpecKind::ResolvedTrue
8224 : clang::ExplicitSpecKind::ResolvedFalse);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008225 if (name[0] == '~') {
8226 cxx_dtor_decl = clang::CXXDestructorDecl::Create(
8227 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8228 clang::DeclarationNameInfo(
8229 getASTContext()->DeclarationNames.getCXXDestructorName(
8230 getASTContext()->getCanonicalType(record_qual_type)),
8231 clang::SourceLocation()),
Raphael Isemann15695cd2019-09-23 06:59:35 +00008232 method_qual_type, nullptr, is_inline, is_artificial,
8233 ConstexprSpecKind::CSK_unspecified);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008234 cxx_method_decl = cxx_dtor_decl;
8235 } else if (decl_name == cxx_record_decl->getDeclName()) {
8236 cxx_ctor_decl = clang::CXXConstructorDecl::Create(
8237 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8238 clang::DeclarationNameInfo(
8239 getASTContext()->DeclarationNames.getCXXConstructorName(
8240 getASTContext()->getCanonicalType(record_qual_type)),
8241 clang::SourceLocation()),
8242 method_qual_type,
8243 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008244 explicit_spec, is_inline, is_artificial, CSK_unspecified);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008245 cxx_method_decl = cxx_ctor_decl;
8246 } else {
8247 clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
8248 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
8249
8250 if (IsOperator(name, op_kind)) {
8251 if (op_kind != clang::NUM_OVERLOADED_OPERATORS) {
Adrian Prantl05097242018-04-30 16:49:04 +00008252 // Check the number of operator parameters. Sometimes we have seen bad
8253 // DWARF that doesn't correctly describe operators and if we try to
8254 // create a method and add it to the class, clang will assert and
8255 // crash, so we need to make sure things are acceptable.
Kate Stoneb9c1b512016-09-06 20:57:50 +00008256 const bool is_method = true;
8257 if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
8258 is_method, op_kind, num_params))
8259 return nullptr;
8260 cxx_method_decl = clang::CXXMethodDecl::Create(
8261 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8262 clang::DeclarationNameInfo(
8263 getASTContext()->DeclarationNames.getCXXOperatorName(op_kind),
8264 clang::SourceLocation()),
8265 method_qual_type,
8266 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008267 SC, is_inline, CSK_unspecified, clang::SourceLocation());
Kate Stoneb9c1b512016-09-06 20:57:50 +00008268 } else if (num_params == 0) {
8269 // Conversion operators don't take params...
8270 cxx_method_decl = clang::CXXConversionDecl::Create(
8271 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8272 clang::DeclarationNameInfo(
8273 getASTContext()->DeclarationNames.getCXXConversionFunctionName(
8274 getASTContext()->getCanonicalType(
8275 function_type->getReturnType())),
8276 clang::SourceLocation()),
8277 method_qual_type,
8278 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008279 is_inline, explicit_spec, CSK_unspecified,
Kate Stoneb9c1b512016-09-06 20:57:50 +00008280 clang::SourceLocation());
8281 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008282 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008283
8284 if (cxx_method_decl == nullptr) {
8285 cxx_method_decl = clang::CXXMethodDecl::Create(
8286 *getASTContext(), cxx_record_decl, clang::SourceLocation(),
8287 clang::DeclarationNameInfo(decl_name, clang::SourceLocation()),
8288 method_qual_type,
8289 nullptr, // TypeSourceInfo *
Gauthier Harnisch796ed032019-06-14 08:56:20 +00008290 SC, is_inline, CSK_unspecified, clang::SourceLocation());
Greg Claytond8d4a572015-08-11 21:38:15 +00008291 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008292 }
8293
8294 clang::AccessSpecifier access_specifier =
8295 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access);
8296
8297 cxx_method_decl->setAccess(access_specifier);
8298 cxx_method_decl->setVirtualAsWritten(is_virtual);
8299
8300 if (is_attr_used)
8301 cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*getASTContext()));
8302
Konrad Kleine248a1302019-05-23 11:14:47 +00008303 if (mangled_name != nullptr) {
Davide Italiano675767a2018-03-27 19:40:50 +00008304 cxx_method_decl->addAttr(
8305 clang::AsmLabelAttr::CreateImplicit(*getASTContext(), mangled_name));
8306 }
8307
Kate Stoneb9c1b512016-09-06 20:57:50 +00008308 // Populate the method decl with parameter decls
8309
8310 llvm::SmallVector<clang::ParmVarDecl *, 12> params;
8311
8312 for (unsigned param_index = 0; param_index < num_params; ++param_index) {
8313 params.push_back(clang::ParmVarDecl::Create(
8314 *getASTContext(), cxx_method_decl, clang::SourceLocation(),
8315 clang::SourceLocation(),
8316 nullptr, // anonymous
8317 method_function_prototype->getParamType(param_index), nullptr,
8318 clang::SC_None, nullptr));
8319 }
8320
8321 cxx_method_decl->setParams(llvm::ArrayRef<clang::ParmVarDecl *>(params));
8322
8323 cxx_record_decl->addDecl(cxx_method_decl);
8324
8325 // Sometimes the debug info will mention a constructor (default/copy/move),
8326 // destructor, or assignment operator (copy/move) but there won't be any
8327 // version of this in the code. So we check if the function was artificially
8328 // generated and if it is trivial and this lets the compiler/backend know
8329 // that it can inline the IR for these when it needs to and we can avoid a
8330 // "missing function" error when running expressions.
8331
8332 if (is_artificial) {
8333 if (cxx_ctor_decl && ((cxx_ctor_decl->isDefaultConstructor() &&
8334 cxx_record_decl->hasTrivialDefaultConstructor()) ||
8335 (cxx_ctor_decl->isCopyConstructor() &&
8336 cxx_record_decl->hasTrivialCopyConstructor()) ||
8337 (cxx_ctor_decl->isMoveConstructor() &&
8338 cxx_record_decl->hasTrivialMoveConstructor()))) {
8339 cxx_ctor_decl->setDefaulted();
8340 cxx_ctor_decl->setTrivial(true);
8341 } else if (cxx_dtor_decl) {
8342 if (cxx_record_decl->hasTrivialDestructor()) {
8343 cxx_dtor_decl->setDefaulted();
8344 cxx_dtor_decl->setTrivial(true);
8345 }
8346 } else if ((cxx_method_decl->isCopyAssignmentOperator() &&
8347 cxx_record_decl->hasTrivialCopyAssignment()) ||
8348 (cxx_method_decl->isMoveAssignmentOperator() &&
8349 cxx_record_decl->hasTrivialMoveAssignment())) {
8350 cxx_method_decl->setDefaulted();
8351 cxx_method_decl->setTrivial(true);
Greg Claytond8d4a572015-08-11 21:38:15 +00008352 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008353 }
8354
Greg Claytond8d4a572015-08-11 21:38:15 +00008355#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00008356 VerifyDecl(cxx_method_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008357#endif
Greg Claytond8d4a572015-08-11 21:38:15 +00008358
Kate Stoneb9c1b512016-09-06 20:57:50 +00008359 return cxx_method_decl;
8360}
Greg Claytond8d4a572015-08-11 21:38:15 +00008361
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00008362void ClangASTContext::AddMethodOverridesForCXXRecordType(
8363 lldb::opaque_compiler_type_t type) {
8364 if (auto *record = GetAsCXXRecordDecl(type))
8365 for (auto *method : record->methods())
8366 addOverridesForMethod(method);
8367}
8368
Greg Claytond8d4a572015-08-11 21:38:15 +00008369#pragma mark C++ Base Classes
8370
Zachary Turner970f38e2018-10-25 20:44:56 +00008371std::unique_ptr<clang::CXXBaseSpecifier>
Kate Stoneb9c1b512016-09-06 20:57:50 +00008372ClangASTContext::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
8373 AccessType access, bool is_virtual,
8374 bool base_of_class) {
Zachary Turner970f38e2018-10-25 20:44:56 +00008375 if (!type)
8376 return nullptr;
8377
Jonas Devliegherea8f3ae72019-08-14 22:19:23 +00008378 return std::make_unique<clang::CXXBaseSpecifier>(
Zachary Turner970f38e2018-10-25 20:44:56 +00008379 clang::SourceRange(), is_virtual, base_of_class,
8380 ClangASTContext::ConvertAccessTypeToAccessSpecifier(access),
8381 getASTContext()->getTrivialTypeSourceInfo(GetQualType(type)),
8382 clang::SourceLocation());
Kate Stoneb9c1b512016-09-06 20:57:50 +00008383}
8384
Zachary Turner970f38e2018-10-25 20:44:56 +00008385bool ClangASTContext::TransferBaseClasses(
Kate Stoneb9c1b512016-09-06 20:57:50 +00008386 lldb::opaque_compiler_type_t type,
Zachary Turner970f38e2018-10-25 20:44:56 +00008387 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases) {
8388 if (!type)
8389 return false;
8390 clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type);
8391 if (!cxx_record_decl)
8392 return false;
8393 std::vector<clang::CXXBaseSpecifier *> raw_bases;
8394 raw_bases.reserve(bases.size());
8395
8396 // Clang will make a copy of them, so it's ok that we pass pointers that we're
8397 // about to destroy.
8398 for (auto &b : bases)
8399 raw_bases.push_back(b.get());
8400 cxx_record_decl->setBases(raw_bases.data(), raw_bases.size());
8401 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00008402}
8403
8404bool ClangASTContext::SetObjCSuperClass(
8405 const CompilerType &type, const CompilerType &superclass_clang_type) {
8406 ClangASTContext *ast =
8407 llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
8408 if (!ast)
8409 return false;
8410 clang::ASTContext *clang_ast = ast->getASTContext();
8411
8412 if (type && superclass_clang_type.IsValid() &&
8413 superclass_clang_type.GetTypeSystem() == type.GetTypeSystem()) {
8414 clang::ObjCInterfaceDecl *class_interface_decl =
8415 GetAsObjCInterfaceDecl(type);
8416 clang::ObjCInterfaceDecl *super_interface_decl =
8417 GetAsObjCInterfaceDecl(superclass_clang_type);
8418 if (class_interface_decl && super_interface_decl) {
8419 class_interface_decl->setSuperClass(clang_ast->getTrivialTypeSourceInfo(
8420 clang_ast->getObjCInterfaceType(super_interface_decl)));
8421 return true;
8422 }
8423 }
8424 return false;
8425}
8426
8427bool ClangASTContext::AddObjCClassProperty(
8428 const CompilerType &type, const char *property_name,
8429 const CompilerType &property_clang_type, clang::ObjCIvarDecl *ivar_decl,
8430 const char *property_setter_name, const char *property_getter_name,
8431 uint32_t property_attributes, ClangASTMetadata *metadata) {
8432 if (!type || !property_clang_type.IsValid() || property_name == nullptr ||
8433 property_name[0] == '\0')
8434 return false;
8435 ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8436 if (!ast)
8437 return false;
8438 clang::ASTContext *clang_ast = ast->getASTContext();
8439
8440 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8441
8442 if (class_interface_decl) {
8443 CompilerType property_clang_type_to_access;
8444
8445 if (property_clang_type.IsValid())
8446 property_clang_type_to_access = property_clang_type;
8447 else if (ivar_decl)
8448 property_clang_type_to_access =
Alex Langfordbddab072019-08-13 19:40:36 +00008449 CompilerType(ast, ivar_decl->getType().getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00008450
8451 if (class_interface_decl && property_clang_type_to_access.IsValid()) {
8452 clang::TypeSourceInfo *prop_type_source;
8453 if (ivar_decl)
8454 prop_type_source =
8455 clang_ast->getTrivialTypeSourceInfo(ivar_decl->getType());
8456 else
8457 prop_type_source = clang_ast->getTrivialTypeSourceInfo(
8458 ClangUtil::GetQualType(property_clang_type));
8459
8460 clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create(
8461 *clang_ast, class_interface_decl,
8462 clang::SourceLocation(), // Source Location
8463 &clang_ast->Idents.get(property_name),
8464 clang::SourceLocation(), // Source Location for AT
8465 clang::SourceLocation(), // Source location for (
8466 ivar_decl ? ivar_decl->getType()
8467 : ClangUtil::GetQualType(property_clang_type),
8468 prop_type_source);
8469
8470 if (property_decl) {
8471 if (metadata)
8472 ClangASTContext::SetMetadata(clang_ast, property_decl, *metadata);
8473
8474 class_interface_decl->addDecl(property_decl);
8475
8476 clang::Selector setter_sel, getter_sel;
8477
8478 if (property_setter_name != nullptr) {
8479 std::string property_setter_no_colon(
8480 property_setter_name, strlen(property_setter_name) - 1);
8481 clang::IdentifierInfo *setter_ident =
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00008482 &clang_ast->Idents.get(property_setter_no_colon);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008483 setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
8484 } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) {
8485 std::string setter_sel_string("set");
8486 setter_sel_string.push_back(::toupper(property_name[0]));
8487 setter_sel_string.append(&property_name[1]);
8488 clang::IdentifierInfo *setter_ident =
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00008489 &clang_ast->Idents.get(setter_sel_string);
Kate Stoneb9c1b512016-09-06 20:57:50 +00008490 setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
8491 }
8492 property_decl->setSetterName(setter_sel);
8493 property_decl->setPropertyAttributes(
8494 clang::ObjCPropertyDecl::OBJC_PR_setter);
8495
8496 if (property_getter_name != nullptr) {
8497 clang::IdentifierInfo *getter_ident =
8498 &clang_ast->Idents.get(property_getter_name);
8499 getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
8500 } else {
8501 clang::IdentifierInfo *getter_ident =
8502 &clang_ast->Idents.get(property_name);
8503 getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
8504 }
8505 property_decl->setGetterName(getter_sel);
8506 property_decl->setPropertyAttributes(
8507 clang::ObjCPropertyDecl::OBJC_PR_getter);
8508
8509 if (ivar_decl)
8510 property_decl->setPropertyIvarDecl(ivar_decl);
8511
8512 if (property_attributes & DW_APPLE_PROPERTY_readonly)
8513 property_decl->setPropertyAttributes(
8514 clang::ObjCPropertyDecl::OBJC_PR_readonly);
8515 if (property_attributes & DW_APPLE_PROPERTY_readwrite)
8516 property_decl->setPropertyAttributes(
8517 clang::ObjCPropertyDecl::OBJC_PR_readwrite);
8518 if (property_attributes & DW_APPLE_PROPERTY_assign)
8519 property_decl->setPropertyAttributes(
8520 clang::ObjCPropertyDecl::OBJC_PR_assign);
8521 if (property_attributes & DW_APPLE_PROPERTY_retain)
8522 property_decl->setPropertyAttributes(
8523 clang::ObjCPropertyDecl::OBJC_PR_retain);
8524 if (property_attributes & DW_APPLE_PROPERTY_copy)
8525 property_decl->setPropertyAttributes(
8526 clang::ObjCPropertyDecl::OBJC_PR_copy);
8527 if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
8528 property_decl->setPropertyAttributes(
8529 clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
8530 if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_nullability)
8531 property_decl->setPropertyAttributes(
8532 clang::ObjCPropertyDecl::OBJC_PR_nullability);
8533 if (property_attributes &
8534 clang::ObjCPropertyDecl::OBJC_PR_null_resettable)
8535 property_decl->setPropertyAttributes(
8536 clang::ObjCPropertyDecl::OBJC_PR_null_resettable);
8537 if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class)
8538 property_decl->setPropertyAttributes(
8539 clang::ObjCPropertyDecl::OBJC_PR_class);
8540
8541 const bool isInstance =
8542 (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) == 0;
8543
8544 if (!getter_sel.isNull() &&
8545 !(isInstance
8546 ? class_interface_decl->lookupInstanceMethod(getter_sel)
8547 : class_interface_decl->lookupClassMethod(getter_sel))) {
8548 const bool isVariadic = false;
8549 const bool isSynthesized = false;
8550 const bool isImplicitlyDeclared = true;
8551 const bool isDefined = false;
8552 const clang::ObjCMethodDecl::ImplementationControl impControl =
8553 clang::ObjCMethodDecl::None;
8554 const bool HasRelatedResultType = false;
8555
8556 clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create(
8557 *clang_ast, clang::SourceLocation(), clang::SourceLocation(),
8558 getter_sel, ClangUtil::GetQualType(property_clang_type_to_access),
8559 nullptr, class_interface_decl, isInstance, isVariadic,
8560 isSynthesized, isImplicitlyDeclared, isDefined, impControl,
8561 HasRelatedResultType);
8562
8563 if (getter && metadata)
8564 ClangASTContext::SetMetadata(clang_ast, getter, *metadata);
8565
8566 if (getter) {
8567 getter->setMethodParams(*clang_ast,
8568 llvm::ArrayRef<clang::ParmVarDecl *>(),
8569 llvm::ArrayRef<clang::SourceLocation>());
8570
8571 class_interface_decl->addDecl(getter);
8572 }
8573 }
8574
8575 if (!setter_sel.isNull() &&
8576 !(isInstance
8577 ? class_interface_decl->lookupInstanceMethod(setter_sel)
8578 : class_interface_decl->lookupClassMethod(setter_sel))) {
8579 clang::QualType result_type = clang_ast->VoidTy;
8580 const bool isVariadic = false;
8581 const bool isSynthesized = false;
8582 const bool isImplicitlyDeclared = true;
8583 const bool isDefined = false;
8584 const clang::ObjCMethodDecl::ImplementationControl impControl =
8585 clang::ObjCMethodDecl::None;
8586 const bool HasRelatedResultType = false;
8587
8588 clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create(
8589 *clang_ast, clang::SourceLocation(), clang::SourceLocation(),
8590 setter_sel, result_type, nullptr, class_interface_decl,
8591 isInstance, isVariadic, isSynthesized, isImplicitlyDeclared,
8592 isDefined, impControl, HasRelatedResultType);
8593
8594 if (setter && metadata)
8595 ClangASTContext::SetMetadata(clang_ast, setter, *metadata);
8596
8597 llvm::SmallVector<clang::ParmVarDecl *, 1> params;
8598
8599 params.push_back(clang::ParmVarDecl::Create(
8600 *clang_ast, setter, clang::SourceLocation(),
8601 clang::SourceLocation(),
8602 nullptr, // anonymous
8603 ClangUtil::GetQualType(property_clang_type_to_access), nullptr,
8604 clang::SC_Auto, nullptr));
8605
8606 if (setter) {
8607 setter->setMethodParams(
8608 *clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(params),
8609 llvm::ArrayRef<clang::SourceLocation>());
8610
8611 class_interface_decl->addDecl(setter);
8612 }
8613 }
8614
8615 return true;
8616 }
8617 }
8618 }
8619 return false;
8620}
8621
8622bool ClangASTContext::IsObjCClassTypeAndHasIVars(const CompilerType &type,
8623 bool check_superclass) {
8624 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8625 if (class_interface_decl)
8626 return ObjCDeclHasIVars(class_interface_decl, check_superclass);
8627 return false;
8628}
8629
8630clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType(
8631 const CompilerType &type,
8632 const char *name, // the full symbol name as seen in the symbol table
8633 // (lldb::opaque_compiler_type_t type, "-[NString
8634 // stringWithCString:]")
8635 const CompilerType &method_clang_type, lldb::AccessType access,
8636 bool is_artificial, bool is_variadic) {
8637 if (!type || !method_clang_type.IsValid())
Greg Claytond8d4a572015-08-11 21:38:15 +00008638 return nullptr;
Greg Claytond8d4a572015-08-11 21:38:15 +00008639
Kate Stoneb9c1b512016-09-06 20:57:50 +00008640 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
8641
8642 if (class_interface_decl == nullptr)
8643 return nullptr;
8644 ClangASTContext *lldb_ast =
8645 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8646 if (lldb_ast == nullptr)
8647 return nullptr;
8648 clang::ASTContext *ast = lldb_ast->getASTContext();
8649
8650 const char *selector_start = ::strchr(name, ' ');
8651 if (selector_start == nullptr)
8652 return nullptr;
8653
8654 selector_start++;
8655 llvm::SmallVector<clang::IdentifierInfo *, 12> selector_idents;
8656
8657 size_t len = 0;
8658 const char *start;
8659 // printf ("name = '%s'\n", name);
8660
8661 unsigned num_selectors_with_args = 0;
8662 for (start = selector_start; start && *start != '\0' && *start != ']';
8663 start += len) {
8664 len = ::strcspn(start, ":]");
8665 bool has_arg = (start[len] == ':');
8666 if (has_arg)
8667 ++num_selectors_with_args;
8668 selector_idents.push_back(&ast->Idents.get(llvm::StringRef(start, len)));
8669 if (has_arg)
8670 len += 1;
8671 }
8672
8673 if (selector_idents.size() == 0)
8674 return nullptr;
8675
8676 clang::Selector method_selector = ast->Selectors.getSelector(
8677 num_selectors_with_args ? selector_idents.size() : 0,
8678 selector_idents.data());
8679
8680 clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
8681
8682 // Populate the method decl with parameter decls
8683 const clang::Type *method_type(method_qual_type.getTypePtr());
8684
8685 if (method_type == nullptr)
8686 return nullptr;
8687
8688 const clang::FunctionProtoType *method_function_prototype(
8689 llvm::dyn_cast<clang::FunctionProtoType>(method_type));
8690
8691 if (!method_function_prototype)
8692 return nullptr;
8693
8694 bool is_synthesized = false;
8695 bool is_defined = false;
8696 clang::ObjCMethodDecl::ImplementationControl imp_control =
8697 clang::ObjCMethodDecl::None;
8698
8699 const unsigned num_args = method_function_prototype->getNumParams();
8700
8701 if (num_args != num_selectors_with_args)
8702 return nullptr; // some debug information is corrupt. We are not going to
8703 // deal with it.
8704
8705 clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create(
8706 *ast,
8707 clang::SourceLocation(), // beginLoc,
8708 clang::SourceLocation(), // endLoc,
8709 method_selector, method_function_prototype->getReturnType(),
8710 nullptr, // TypeSourceInfo *ResultTInfo,
8711 ClangASTContext::GetASTContext(ast)->GetDeclContextForType(
8712 ClangUtil::GetQualType(type)),
8713 name[0] == '-', is_variadic, is_synthesized,
8714 true, // is_implicitly_declared; we force this to true because we don't
8715 // have source locations
8716 is_defined, imp_control, false /*has_related_result_type*/);
8717
8718 if (objc_method_decl == nullptr)
8719 return nullptr;
8720
8721 if (num_args > 0) {
8722 llvm::SmallVector<clang::ParmVarDecl *, 12> params;
8723
8724 for (unsigned param_index = 0; param_index < num_args; ++param_index) {
8725 params.push_back(clang::ParmVarDecl::Create(
8726 *ast, objc_method_decl, clang::SourceLocation(),
8727 clang::SourceLocation(),
8728 nullptr, // anonymous
8729 method_function_prototype->getParamType(param_index), nullptr,
8730 clang::SC_Auto, nullptr));
Greg Claytond8d4a572015-08-11 21:38:15 +00008731 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008732
Kate Stoneb9c1b512016-09-06 20:57:50 +00008733 objc_method_decl->setMethodParams(
8734 *ast, llvm::ArrayRef<clang::ParmVarDecl *>(params),
8735 llvm::ArrayRef<clang::SourceLocation>());
8736 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008737
Kate Stoneb9c1b512016-09-06 20:57:50 +00008738 class_interface_decl->addDecl(objc_method_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008739
Greg Claytond8d4a572015-08-11 21:38:15 +00008740#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +00008741 VerifyDecl(objc_method_decl);
Greg Claytond8d4a572015-08-11 21:38:15 +00008742#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +00008743
8744 return objc_method_decl;
Greg Claytond8d4a572015-08-11 21:38:15 +00008745}
8746
Kate Stoneb9c1b512016-09-06 20:57:50 +00008747bool ClangASTContext::GetHasExternalStorage(const CompilerType &type) {
8748 if (ClangUtil::IsClangType(type))
Greg Claytone6b36cd2015-12-08 01:02:08 +00008749 return false;
Greg Claytone6b36cd2015-12-08 01:02:08 +00008750
Kate Stoneb9c1b512016-09-06 20:57:50 +00008751 clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
Greg Claytone6b36cd2015-12-08 01:02:08 +00008752
Kate Stoneb9c1b512016-09-06 20:57:50 +00008753 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8754 switch (type_class) {
8755 case clang::Type::Record: {
8756 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
8757 if (cxx_record_decl)
8758 return cxx_record_decl->hasExternalLexicalStorage() ||
8759 cxx_record_decl->hasExternalVisibleStorage();
8760 } break;
Enrico Granata36f51e42015-12-18 22:41:25 +00008761
Kate Stoneb9c1b512016-09-06 20:57:50 +00008762 case clang::Type::Enum: {
8763 clang::EnumDecl *enum_decl =
8764 llvm::cast<clang::EnumType>(qual_type)->getDecl();
8765 if (enum_decl)
8766 return enum_decl->hasExternalLexicalStorage() ||
8767 enum_decl->hasExternalVisibleStorage();
8768 } break;
8769
8770 case clang::Type::ObjCObject:
8771 case clang::Type::ObjCInterface: {
8772 const clang::ObjCObjectType *objc_class_type =
8773 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
8774 assert(objc_class_type);
8775 if (objc_class_type) {
8776 clang::ObjCInterfaceDecl *class_interface_decl =
8777 objc_class_type->getInterface();
8778
8779 if (class_interface_decl)
8780 return class_interface_decl->hasExternalLexicalStorage() ||
8781 class_interface_decl->hasExternalVisibleStorage();
Greg Claytond8d4a572015-08-11 21:38:15 +00008782 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008783 } break;
8784
8785 case clang::Type::Typedef:
8786 return GetHasExternalStorage(CompilerType(
8787 type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)
8788 ->getDecl()
8789 ->getUnderlyingType()
8790 .getAsOpaquePtr()));
8791
8792 case clang::Type::Auto:
8793 return GetHasExternalStorage(CompilerType(
8794 type.GetTypeSystem(), llvm::cast<clang::AutoType>(qual_type)
8795 ->getDeducedType()
8796 .getAsOpaquePtr()));
8797
8798 case clang::Type::Elaborated:
8799 return GetHasExternalStorage(CompilerType(
8800 type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)
8801 ->getNamedType()
8802 .getAsOpaquePtr()));
8803
8804 case clang::Type::Paren:
8805 return GetHasExternalStorage(CompilerType(
8806 type.GetTypeSystem(),
8807 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
8808
8809 default:
8810 break;
8811 }
8812 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00008813}
8814
Kate Stoneb9c1b512016-09-06 20:57:50 +00008815bool ClangASTContext::SetHasExternalStorage(lldb::opaque_compiler_type_t type,
8816 bool has_extern) {
8817 if (!type)
8818 return false;
8819
8820 clang::QualType qual_type(GetCanonicalQualType(type));
8821
8822 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
8823 switch (type_class) {
8824 case clang::Type::Record: {
8825 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
8826 if (cxx_record_decl) {
8827 cxx_record_decl->setHasExternalLexicalStorage(has_extern);
8828 cxx_record_decl->setHasExternalVisibleStorage(has_extern);
8829 return true;
8830 }
8831 } break;
8832
8833 case clang::Type::Enum: {
8834 clang::EnumDecl *enum_decl =
8835 llvm::cast<clang::EnumType>(qual_type)->getDecl();
8836 if (enum_decl) {
8837 enum_decl->setHasExternalLexicalStorage(has_extern);
8838 enum_decl->setHasExternalVisibleStorage(has_extern);
8839 return true;
8840 }
8841 } break;
8842
8843 case clang::Type::ObjCObject:
8844 case clang::Type::ObjCInterface: {
8845 const clang::ObjCObjectType *objc_class_type =
8846 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
8847 assert(objc_class_type);
8848 if (objc_class_type) {
8849 clang::ObjCInterfaceDecl *class_interface_decl =
8850 objc_class_type->getInterface();
8851
8852 if (class_interface_decl) {
8853 class_interface_decl->setHasExternalLexicalStorage(has_extern);
8854 class_interface_decl->setHasExternalVisibleStorage(has_extern);
8855 return true;
8856 }
8857 }
8858 } break;
8859
8860 case clang::Type::Typedef:
8861 return SetHasExternalStorage(llvm::cast<clang::TypedefType>(qual_type)
8862 ->getDecl()
8863 ->getUnderlyingType()
8864 .getAsOpaquePtr(),
8865 has_extern);
8866
8867 case clang::Type::Auto:
8868 return SetHasExternalStorage(llvm::cast<clang::AutoType>(qual_type)
8869 ->getDeducedType()
8870 .getAsOpaquePtr(),
8871 has_extern);
8872
8873 case clang::Type::Elaborated:
8874 return SetHasExternalStorage(llvm::cast<clang::ElaboratedType>(qual_type)
8875 ->getNamedType()
8876 .getAsOpaquePtr(),
8877 has_extern);
8878
8879 case clang::Type::Paren:
8880 return SetHasExternalStorage(
8881 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
8882 has_extern);
8883
8884 default:
8885 break;
8886 }
8887 return false;
8888}
Greg Claytond8d4a572015-08-11 21:38:15 +00008889
8890#pragma mark TagDecl
8891
Kate Stoneb9c1b512016-09-06 20:57:50 +00008892bool ClangASTContext::StartTagDeclarationDefinition(const CompilerType &type) {
8893 clang::QualType qual_type(ClangUtil::GetQualType(type));
8894 if (!qual_type.isNull()) {
8895 const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
8896 if (tag_type) {
8897 clang::TagDecl *tag_decl = tag_type->getDecl();
8898 if (tag_decl) {
8899 tag_decl->startDefinition();
8900 return true;
8901 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008902 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008903
8904 const clang::ObjCObjectType *object_type =
8905 qual_type->getAs<clang::ObjCObjectType>();
8906 if (object_type) {
8907 clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
8908 if (interface_decl) {
8909 interface_decl->startDefinition();
8910 return true;
8911 }
8912 }
8913 }
8914 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00008915}
8916
Kate Stoneb9c1b512016-09-06 20:57:50 +00008917bool ClangASTContext::CompleteTagDeclarationDefinition(
8918 const CompilerType &type) {
8919 clang::QualType qual_type(ClangUtil::GetQualType(type));
8920 if (!qual_type.isNull()) {
8921 // Make sure we use the same methodology as
Adrian Prantl05097242018-04-30 16:49:04 +00008922 // ClangASTContext::StartTagDeclarationDefinition() as to how we start/end
8923 // the definition. Previously we were calling
Kate Stoneb9c1b512016-09-06 20:57:50 +00008924 const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
8925 if (tag_type) {
8926 clang::TagDecl *tag_decl = tag_type->getDecl();
8927 if (tag_decl) {
8928 clang::CXXRecordDecl *cxx_record_decl =
8929 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(tag_decl);
8930
8931 if (cxx_record_decl) {
8932 if (!cxx_record_decl->isCompleteDefinition())
8933 cxx_record_decl->completeDefinition();
8934 cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
8935 cxx_record_decl->setHasExternalLexicalStorage(false);
8936 cxx_record_decl->setHasExternalVisibleStorage(false);
8937 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00008938 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008939 }
Greg Claytond8d4a572015-08-11 21:38:15 +00008940 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00008941
8942 const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>();
8943
8944 if (enutype) {
8945 clang::EnumDecl *enum_decl = enutype->getDecl();
8946
8947 if (enum_decl) {
8948 if (!enum_decl->isCompleteDefinition()) {
8949 ClangASTContext *lldb_ast =
8950 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
8951 if (lldb_ast == nullptr)
8952 return false;
8953 clang::ASTContext *ast = lldb_ast->getASTContext();
8954
8955 /// TODO This really needs to be fixed.
8956
8957 QualType integer_type(enum_decl->getIntegerType());
8958 if (!integer_type.isNull()) {
8959 unsigned NumPositiveBits = 1;
8960 unsigned NumNegativeBits = 0;
8961
8962 clang::QualType promotion_qual_type;
8963 // If the enum integer type is less than an integer in bit width,
8964 // then we must promote it to an integer size.
8965 if (ast->getTypeSize(enum_decl->getIntegerType()) <
8966 ast->getTypeSize(ast->IntTy)) {
8967 if (enum_decl->getIntegerType()->isSignedIntegerType())
8968 promotion_qual_type = ast->IntTy;
8969 else
8970 promotion_qual_type = ast->UnsignedIntTy;
8971 } else
8972 promotion_qual_type = enum_decl->getIntegerType();
8973
8974 enum_decl->completeDefinition(enum_decl->getIntegerType(),
8975 promotion_qual_type, NumPositiveBits,
8976 NumNegativeBits);
8977 }
8978 }
8979 return true;
8980 }
8981 }
8982 }
8983 return false;
Greg Claytond8d4a572015-08-11 21:38:15 +00008984}
8985
Aleksandr Urakov709426b2018-09-10 08:08:43 +00008986clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType(
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008987 const CompilerType &enum_type, const Declaration &decl, const char *name,
Zachary Turner1639c6b2018-12-17 16:15:13 +00008988 const llvm::APSInt &value) {
Zachary Turnerd133f6a2016-03-28 22:53:41 +00008989
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008990 if (!enum_type || ConstString(name).IsEmpty())
8991 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00008992
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008993 lldbassert(enum_type.GetTypeSystem() == static_cast<TypeSystem *>(this));
Kate Stoneb9c1b512016-09-06 20:57:50 +00008994
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00008995 lldb::opaque_compiler_type_t enum_opaque_compiler_type =
8996 enum_type.GetOpaqueQualType();
8997
8998 if (!enum_opaque_compiler_type)
8999 return nullptr;
9000
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00009001 clang::QualType enum_qual_type(
9002 GetCanonicalQualType(enum_opaque_compiler_type));
9003
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00009004 const clang::Type *clang_type = enum_qual_type.getTypePtr();
9005
9006 if (!clang_type)
9007 return nullptr;
9008
9009 const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(clang_type);
9010
9011 if (!enutype)
9012 return nullptr;
9013
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00009014 clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create(
9015 *getASTContext(), enutype->getDecl(), clang::SourceLocation(),
9016 name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier
Zachary Turner1639c6b2018-12-17 16:15:13 +00009017 clang::QualType(enutype, 0), nullptr, value);
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00009018
9019 if (!enumerator_decl)
9020 return nullptr;
9021
9022 enutype->getDecl()->addDecl(enumerator_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009023
9024#ifdef LLDB_CONFIGURATION_DEBUG
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00009025 VerifyDecl(enumerator_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009026#endif
9027
Shafik Yaghmour8c5ec1f2018-11-08 18:42:00 +00009028 return enumerator_decl;
Greg Claytond8d4a572015-08-11 21:38:15 +00009029}
9030
Zachary Turner1639c6b2018-12-17 16:15:13 +00009031clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType(
9032 const CompilerType &enum_type, const Declaration &decl, const char *name,
9033 int64_t enum_value, uint32_t enum_value_bit_size) {
9034 CompilerType underlying_type =
9035 GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
9036 bool is_signed = false;
9037 underlying_type.IsIntegerType(is_signed);
9038
9039 llvm::APSInt value(enum_value_bit_size, is_signed);
9040 value = enum_value;
9041
9042 return AddEnumerationValueToEnumerationType(enum_type, decl, name, value);
9043}
9044
Greg Claytona1e5dc82015-08-11 22:53:00 +00009045CompilerType
Kate Stoneb9c1b512016-09-06 20:57:50 +00009046ClangASTContext::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) {
9047 clang::QualType enum_qual_type(GetCanonicalQualType(type));
9048 const clang::Type *clang_type = enum_qual_type.getTypePtr();
9049 if (clang_type) {
9050 const clang::EnumType *enutype =
9051 llvm::dyn_cast<clang::EnumType>(clang_type);
9052 if (enutype) {
9053 clang::EnumDecl *enum_decl = enutype->getDecl();
9054 if (enum_decl)
Alex Langfordbddab072019-08-13 19:40:36 +00009055 return CompilerType(this, enum_decl->getIntegerType().getAsOpaquePtr());
Greg Claytond8d4a572015-08-11 21:38:15 +00009056 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009057 }
9058 return CompilerType();
Greg Claytond8d4a572015-08-11 21:38:15 +00009059}
9060
Kate Stoneb9c1b512016-09-06 20:57:50 +00009061CompilerType
9062ClangASTContext::CreateMemberPointerType(const CompilerType &type,
9063 const CompilerType &pointee_type) {
9064 if (type && pointee_type.IsValid() &&
9065 type.GetTypeSystem() == pointee_type.GetTypeSystem()) {
9066 ClangASTContext *ast =
9067 llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
9068 if (!ast)
9069 return CompilerType();
Alex Langfordbddab072019-08-13 19:40:36 +00009070 return CompilerType(ast, ast->getASTContext()
9071 ->getMemberPointerType(
9072 ClangUtil::GetQualType(pointee_type),
9073 ClangUtil::GetQualType(type).getTypePtr())
9074 .getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009075 }
9076 return CompilerType();
9077}
Greg Claytond8d4a572015-08-11 21:38:15 +00009078
Greg Claytond8d4a572015-08-11 21:38:15 +00009079// Dumping types
Greg Claytond8d4a572015-08-11 21:38:15 +00009080#define DEPTH_INCREMENT 2
9081
Adrian Prantl0c72a422019-03-07 20:20:02 +00009082#ifndef NDEBUG
9083LLVM_DUMP_METHOD void
9084ClangASTContext::dump(lldb::opaque_compiler_type_t type) const {
9085 if (!type)
9086 return;
9087 clang::QualType qual_type(GetQualType(type));
9088 qual_type.dump();
9089}
9090#endif
9091
Zachary Turner49110232018-11-05 17:40:28 +00009092void ClangASTContext::Dump(Stream &s) {
Zachary Turner115209e2018-11-05 19:25:39 +00009093 Decl *tu = Decl::castFromDeclContext(GetTranslationUnitDecl());
Zachary Turner49110232018-11-05 17:40:28 +00009094 tu->dump(s.AsRawOstream());
9095}
9096
Kate Stoneb9c1b512016-09-06 20:57:50 +00009097void ClangASTContext::DumpValue(
9098 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
Zachary Turner29cb8682017-03-03 20:57:05 +00009099 lldb::Format format, const DataExtractor &data,
Kate Stoneb9c1b512016-09-06 20:57:50 +00009100 lldb::offset_t data_byte_offset, size_t data_byte_size,
9101 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types,
9102 bool show_summary, bool verbose, uint32_t depth) {
9103 if (!type)
9104 return;
9105
9106 clang::QualType qual_type(GetQualType(type));
9107 switch (qual_type->getTypeClass()) {
9108 case clang::Type::Record:
9109 if (GetCompleteType(type)) {
9110 const clang::RecordType *record_type =
9111 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
9112 const clang::RecordDecl *record_decl = record_type->getDecl();
9113 assert(record_decl);
9114 uint32_t field_bit_offset = 0;
9115 uint32_t field_byte_offset = 0;
9116 const clang::ASTRecordLayout &record_layout =
9117 getASTContext()->getASTRecordLayout(record_decl);
9118 uint32_t child_idx = 0;
9119
9120 const clang::CXXRecordDecl *cxx_record_decl =
9121 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
9122 if (cxx_record_decl) {
9123 // We might have base classes to print out first
9124 clang::CXXRecordDecl::base_class_const_iterator base_class,
9125 base_class_end;
9126 for (base_class = cxx_record_decl->bases_begin(),
9127 base_class_end = cxx_record_decl->bases_end();
9128 base_class != base_class_end; ++base_class) {
9129 const clang::CXXRecordDecl *base_class_decl =
9130 llvm::cast<clang::CXXRecordDecl>(
9131 base_class->getType()->getAs<clang::RecordType>()->getDecl());
9132
9133 // Skip empty base classes
Jonas Devliegherea6682a42018-12-15 00:15:33 +00009134 if (!verbose && !ClangASTContext::RecordHasFields(base_class_decl))
Kate Stoneb9c1b512016-09-06 20:57:50 +00009135 continue;
9136
9137 if (base_class->isVirtual())
9138 field_bit_offset =
9139 record_layout.getVBaseClassOffset(base_class_decl)
9140 .getQuantity() *
9141 8;
9142 else
9143 field_bit_offset = record_layout.getBaseClassOffset(base_class_decl)
9144 .getQuantity() *
9145 8;
9146 field_byte_offset = field_bit_offset / 8;
9147 assert(field_bit_offset % 8 == 0);
9148 if (child_idx == 0)
9149 s->PutChar('{');
9150 else
9151 s->PutChar(',');
9152
9153 clang::QualType base_class_qual_type = base_class->getType();
9154 std::string base_class_type_name(base_class_qual_type.getAsString());
9155
9156 // Indent and print the base class type name
Zachary Turner827d5d72016-12-16 04:27:00 +00009157 s->Format("\n{0}{1}", llvm::fmt_repeat(" ", depth + DEPTH_INCREMENT),
9158 base_class_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009159
9160 clang::TypeInfo base_class_type_info =
9161 getASTContext()->getTypeInfo(base_class_qual_type);
9162
9163 // Dump the value of the member
Alex Langfordbddab072019-08-13 19:40:36 +00009164 CompilerType base_clang_type(this,
9165 base_class_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009166 base_clang_type.DumpValue(
9167 exe_ctx,
9168 s, // Stream to dump to
9169 base_clang_type
9170 .GetFormat(), // The format with which to display the member
9171 data, // Data buffer containing all bytes for this type
9172 data_byte_offset + field_byte_offset, // Offset into "data" where
9173 // to grab value from
9174 base_class_type_info.Width / 8, // Size of this type in bytes
9175 0, // Bitfield bit size
9176 0, // Bitfield bit offset
9177 show_types, // Boolean indicating if we should show the variable
9178 // types
9179 show_summary, // Boolean indicating if we should show a summary
9180 // for the current type
9181 verbose, // Verbose output?
9182 depth + DEPTH_INCREMENT); // Scope depth for any types that have
9183 // children
9184
9185 ++child_idx;
9186 }
9187 }
9188 uint32_t field_idx = 0;
9189 clang::RecordDecl::field_iterator field, field_end;
9190 for (field = record_decl->field_begin(),
9191 field_end = record_decl->field_end();
9192 field != field_end; ++field, ++field_idx, ++child_idx) {
Adrian Prantl05097242018-04-30 16:49:04 +00009193 // Print the starting squiggly bracket (if this is the first member) or
9194 // comma (for member 2 and beyond) for the struct/union/class member.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009195 if (child_idx == 0)
9196 s->PutChar('{');
9197 else
9198 s->PutChar(',');
9199
9200 // Indent
9201 s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
9202
9203 clang::QualType field_type = field->getType();
9204 // Print the member type if requested
Adrian Prantl05097242018-04-30 16:49:04 +00009205 // Figure out the type byte size (field_type_info.first) and alignment
9206 // (field_type_info.second) from the AST context.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009207 clang::TypeInfo field_type_info =
9208 getASTContext()->getTypeInfo(field_type);
9209 assert(field_idx < record_layout.getFieldCount());
9210 // Figure out the field offset within the current struct/union/class
9211 // type
9212 field_bit_offset = record_layout.getFieldOffset(field_idx);
9213 field_byte_offset = field_bit_offset / 8;
9214 uint32_t field_bitfield_bit_size = 0;
9215 uint32_t field_bitfield_bit_offset = 0;
9216 if (ClangASTContext::FieldIsBitfield(getASTContext(), *field,
9217 field_bitfield_bit_size))
9218 field_bitfield_bit_offset = field_bit_offset % 8;
9219
9220 if (show_types) {
9221 std::string field_type_name(field_type.getAsString());
9222 if (field_bitfield_bit_size > 0)
9223 s->Printf("(%s:%u) ", field_type_name.c_str(),
9224 field_bitfield_bit_size);
9225 else
9226 s->Printf("(%s) ", field_type_name.c_str());
9227 }
9228 // Print the member name and equal sign
9229 s->Printf("%s = ", field->getNameAsString().c_str());
9230
9231 // Dump the value of the member
Alex Langfordbddab072019-08-13 19:40:36 +00009232 CompilerType field_clang_type(this, field_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009233 field_clang_type.DumpValue(
9234 exe_ctx,
9235 s, // Stream to dump to
9236 field_clang_type
9237 .GetFormat(), // The format with which to display the member
9238 data, // Data buffer containing all bytes for this type
9239 data_byte_offset + field_byte_offset, // Offset into "data" where to
9240 // grab value from
9241 field_type_info.Width / 8, // Size of this type in bytes
9242 field_bitfield_bit_size, // Bitfield bit size
9243 field_bitfield_bit_offset, // Bitfield bit offset
9244 show_types, // Boolean indicating if we should show the variable
9245 // types
9246 show_summary, // Boolean indicating if we should show a summary for
9247 // the current type
9248 verbose, // Verbose output?
9249 depth + DEPTH_INCREMENT); // Scope depth for any types that have
9250 // children
9251 }
9252
9253 // Indent the trailing squiggly bracket
9254 if (child_idx > 0)
9255 s->Printf("\n%*s}", depth, "");
9256 }
9257 return;
9258
9259 case clang::Type::Enum:
9260 if (GetCompleteType(type)) {
9261 const clang::EnumType *enutype =
9262 llvm::cast<clang::EnumType>(qual_type.getTypePtr());
9263 const clang::EnumDecl *enum_decl = enutype->getDecl();
9264 assert(enum_decl);
9265 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
9266 lldb::offset_t offset = data_byte_offset;
9267 const int64_t enum_value = data.GetMaxU64Bitfield(
9268 &offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
9269 for (enum_pos = enum_decl->enumerator_begin(),
9270 enum_end_pos = enum_decl->enumerator_end();
9271 enum_pos != enum_end_pos; ++enum_pos) {
9272 if (enum_pos->getInitVal() == enum_value) {
9273 s->Printf("%s", enum_pos->getNameAsString().c_str());
9274 return;
9275 }
9276 }
Adrian Prantl05097242018-04-30 16:49:04 +00009277 // If we have gotten here we didn't get find the enumerator in the enum
9278 // decl, so just print the integer.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009279 s->Printf("%" PRIi64, enum_value);
9280 }
9281 return;
9282
9283 case clang::Type::ConstantArray: {
9284 const clang::ConstantArrayType *array =
9285 llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
9286 bool is_array_of_characters = false;
9287 clang::QualType element_qual_type = array->getElementType();
9288
9289 const clang::Type *canonical_type =
9290 element_qual_type->getCanonicalTypeInternal().getTypePtr();
9291 if (canonical_type)
9292 is_array_of_characters = canonical_type->isCharType();
9293
9294 const uint64_t element_count = array->getSize().getLimitedValue();
9295
9296 clang::TypeInfo field_type_info =
9297 getASTContext()->getTypeInfo(element_qual_type);
9298
9299 uint32_t element_idx = 0;
9300 uint32_t element_offset = 0;
9301 uint64_t element_byte_size = field_type_info.Width / 8;
9302 uint32_t element_stride = element_byte_size;
9303
9304 if (is_array_of_characters) {
9305 s->PutChar('"');
Zachary Turner29cb8682017-03-03 20:57:05 +00009306 DumpDataExtractor(data, s, data_byte_offset, lldb::eFormatChar,
9307 element_byte_size, element_count, UINT32_MAX,
9308 LLDB_INVALID_ADDRESS, 0, 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009309 s->PutChar('"');
9310 return;
9311 } else {
Alex Langfordbddab072019-08-13 19:40:36 +00009312 CompilerType element_clang_type(this, element_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009313 lldb::Format element_format = element_clang_type.GetFormat();
9314
9315 for (element_idx = 0; element_idx < element_count; ++element_idx) {
Adrian Prantl05097242018-04-30 16:49:04 +00009316 // Print the starting squiggly bracket (if this is the first member) or
9317 // comman (for member 2 and beyong) for the struct/union/class member.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009318 if (element_idx == 0)
9319 s->PutChar('{');
9320 else
9321 s->PutChar(',');
9322
9323 // Indent and print the index
9324 s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
9325
9326 // Figure out the field offset within the current struct/union/class
9327 // type
9328 element_offset = element_idx * element_stride;
9329
9330 // Dump the value of the member
9331 element_clang_type.DumpValue(
9332 exe_ctx,
9333 s, // Stream to dump to
9334 element_format, // The format with which to display the element
9335 data, // Data buffer containing all bytes for this type
9336 data_byte_offset +
9337 element_offset, // Offset into "data" where to grab value from
9338 element_byte_size, // Size of this type in bytes
9339 0, // Bitfield bit size
9340 0, // Bitfield bit offset
9341 show_types, // Boolean indicating if we should show the variable
9342 // types
9343 show_summary, // Boolean indicating if we should show a summary for
9344 // the current type
9345 verbose, // Verbose output?
9346 depth + DEPTH_INCREMENT); // Scope depth for any types that have
9347 // children
9348 }
9349
9350 // Indent the trailing squiggly bracket
9351 if (element_idx > 0)
9352 s->Printf("\n%*s}", depth, "");
9353 }
9354 }
9355 return;
9356
9357 case clang::Type::Typedef: {
9358 clang::QualType typedef_qual_type =
9359 llvm::cast<clang::TypedefType>(qual_type)
9360 ->getDecl()
9361 ->getUnderlyingType();
9362
Alex Langfordbddab072019-08-13 19:40:36 +00009363 CompilerType typedef_clang_type(this, typedef_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009364 lldb::Format typedef_format = typedef_clang_type.GetFormat();
9365 clang::TypeInfo typedef_type_info =
9366 getASTContext()->getTypeInfo(typedef_qual_type);
9367 uint64_t typedef_byte_size = typedef_type_info.Width / 8;
9368
9369 return typedef_clang_type.DumpValue(
9370 exe_ctx,
9371 s, // Stream to dump to
9372 typedef_format, // The format with which to display the element
9373 data, // Data buffer containing all bytes for this type
9374 data_byte_offset, // Offset into "data" where to grab value from
9375 typedef_byte_size, // Size of this type in bytes
9376 bitfield_bit_size, // Bitfield bit size
9377 bitfield_bit_offset, // Bitfield bit offset
9378 show_types, // Boolean indicating if we should show the variable types
9379 show_summary, // Boolean indicating if we should show a summary for the
9380 // current type
9381 verbose, // Verbose output?
9382 depth); // Scope depth for any types that have children
9383 } break;
9384
9385 case clang::Type::Auto: {
9386 clang::QualType elaborated_qual_type =
9387 llvm::cast<clang::AutoType>(qual_type)->getDeducedType();
Alex Langfordbddab072019-08-13 19:40:36 +00009388 CompilerType elaborated_clang_type(this,
9389 elaborated_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009390 lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
9391 clang::TypeInfo elaborated_type_info =
9392 getASTContext()->getTypeInfo(elaborated_qual_type);
9393 uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
9394
9395 return elaborated_clang_type.DumpValue(
9396 exe_ctx,
9397 s, // Stream to dump to
9398 elaborated_format, // The format with which to display the element
9399 data, // Data buffer containing all bytes for this type
9400 data_byte_offset, // Offset into "data" where to grab value from
9401 elaborated_byte_size, // Size of this type in bytes
9402 bitfield_bit_size, // Bitfield bit size
9403 bitfield_bit_offset, // Bitfield bit offset
9404 show_types, // Boolean indicating if we should show the variable types
9405 show_summary, // Boolean indicating if we should show a summary for the
9406 // current type
9407 verbose, // Verbose output?
9408 depth); // Scope depth for any types that have children
9409 } break;
9410
9411 case clang::Type::Elaborated: {
9412 clang::QualType elaborated_qual_type =
9413 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
Alex Langfordbddab072019-08-13 19:40:36 +00009414 CompilerType elaborated_clang_type(this,
9415 elaborated_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009416 lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
9417 clang::TypeInfo elaborated_type_info =
9418 getASTContext()->getTypeInfo(elaborated_qual_type);
9419 uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
9420
9421 return elaborated_clang_type.DumpValue(
9422 exe_ctx,
9423 s, // Stream to dump to
9424 elaborated_format, // The format with which to display the element
9425 data, // Data buffer containing all bytes for this type
9426 data_byte_offset, // Offset into "data" where to grab value from
9427 elaborated_byte_size, // Size of this type in bytes
9428 bitfield_bit_size, // Bitfield bit size
9429 bitfield_bit_offset, // Bitfield bit offset
9430 show_types, // Boolean indicating if we should show the variable types
9431 show_summary, // Boolean indicating if we should show a summary for the
9432 // current type
9433 verbose, // Verbose output?
9434 depth); // Scope depth for any types that have children
9435 } break;
9436
9437 case clang::Type::Paren: {
9438 clang::QualType desugar_qual_type =
9439 llvm::cast<clang::ParenType>(qual_type)->desugar();
Alex Langfordbddab072019-08-13 19:40:36 +00009440 CompilerType desugar_clang_type(this, desugar_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009441
9442 lldb::Format desugar_format = desugar_clang_type.GetFormat();
9443 clang::TypeInfo desugar_type_info =
9444 getASTContext()->getTypeInfo(desugar_qual_type);
9445 uint64_t desugar_byte_size = desugar_type_info.Width / 8;
9446
9447 return desugar_clang_type.DumpValue(
9448 exe_ctx,
9449 s, // Stream to dump to
9450 desugar_format, // The format with which to display the element
9451 data, // Data buffer containing all bytes for this type
9452 data_byte_offset, // Offset into "data" where to grab value from
9453 desugar_byte_size, // Size of this type in bytes
9454 bitfield_bit_size, // Bitfield bit size
9455 bitfield_bit_offset, // Bitfield bit offset
9456 show_types, // Boolean indicating if we should show the variable types
9457 show_summary, // Boolean indicating if we should show a summary for the
9458 // current type
9459 verbose, // Verbose output?
9460 depth); // Scope depth for any types that have children
9461 } break;
9462
9463 default:
9464 // We are down to a scalar type that we just need to display.
Zachary Turner29cb8682017-03-03 20:57:05 +00009465 DumpDataExtractor(data, s, data_byte_offset, format, data_byte_size, 1,
9466 UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
9467 bitfield_bit_offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009468
9469 if (show_summary)
9470 DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
9471 break;
9472 }
9473}
9474
9475bool ClangASTContext::DumpTypeValue(
9476 lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
Zachary Turner29cb8682017-03-03 20:57:05 +00009477 const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size,
9478 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
Kate Stoneb9c1b512016-09-06 20:57:50 +00009479 ExecutionContextScope *exe_scope) {
9480 if (!type)
9481 return false;
9482 if (IsAggregateType(type)) {
9483 return false;
9484 } else {
Greg Claytond8d4a572015-08-11 21:38:15 +00009485 clang::QualType qual_type(GetQualType(type));
Kate Stoneb9c1b512016-09-06 20:57:50 +00009486
9487 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
9488 switch (type_class) {
9489 case clang::Type::Typedef: {
9490 clang::QualType typedef_qual_type =
9491 llvm::cast<clang::TypedefType>(qual_type)
9492 ->getDecl()
9493 ->getUnderlyingType();
Alex Langfordbddab072019-08-13 19:40:36 +00009494 CompilerType typedef_clang_type(this, typedef_qual_type.getAsOpaquePtr());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009495 if (format == eFormatDefault)
9496 format = typedef_clang_type.GetFormat();
9497 clang::TypeInfo typedef_type_info =
9498 getASTContext()->getTypeInfo(typedef_qual_type);
9499 uint64_t typedef_byte_size = typedef_type_info.Width / 8;
9500
9501 return typedef_clang_type.DumpTypeValue(
9502 s,
9503 format, // The format with which to display the element
9504 data, // Data buffer containing all bytes for this type
9505 byte_offset, // Offset into "data" where to grab value from
9506 typedef_byte_size, // Size of this type in bytes
9507 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't
9508 // treat as a bitfield
9509 bitfield_bit_offset, // Offset in bits of a bitfield value if
9510 // bitfield_bit_size != 0
9511 exe_scope);
9512 } break;
9513
9514 case clang::Type::Enum:
Adrian Prantl05097242018-04-30 16:49:04 +00009515 // If our format is enum or default, show the enumeration value as its
9516 // enumeration string value, else just display it as requested.
Kate Stoneb9c1b512016-09-06 20:57:50 +00009517 if ((format == eFormatEnum || format == eFormatDefault) &&
9518 GetCompleteType(type)) {
9519 const clang::EnumType *enutype =
9520 llvm::cast<clang::EnumType>(qual_type.getTypePtr());
9521 const clang::EnumDecl *enum_decl = enutype->getDecl();
9522 assert(enum_decl);
9523 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
9524 const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
9525 lldb::offset_t offset = byte_offset;
9526 if (is_signed) {
9527 const int64_t enum_svalue = data.GetMaxS64Bitfield(
9528 &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
9529 for (enum_pos = enum_decl->enumerator_begin(),
9530 enum_end_pos = enum_decl->enumerator_end();
9531 enum_pos != enum_end_pos; ++enum_pos) {
9532 if (enum_pos->getInitVal().getSExtValue() == enum_svalue) {
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009533 s->PutCString(enum_pos->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009534 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00009535 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009536 }
9537 // If we have gotten here we didn't get find the enumerator in the
9538 // enum decl, so just print the integer.
9539 s->Printf("%" PRIi64, enum_svalue);
9540 } else {
9541 const uint64_t enum_uvalue = data.GetMaxU64Bitfield(
9542 &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
9543 for (enum_pos = enum_decl->enumerator_begin(),
9544 enum_end_pos = enum_decl->enumerator_end();
9545 enum_pos != enum_end_pos; ++enum_pos) {
9546 if (enum_pos->getInitVal().getZExtValue() == enum_uvalue) {
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009547 s->PutCString(enum_pos->getNameAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00009548 return true;
Greg Claytond8d4a572015-08-11 21:38:15 +00009549 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009550 }
9551 // If we have gotten here we didn't get find the enumerator in the
9552 // enum decl, so just print the integer.
9553 s->Printf("%" PRIu64, enum_uvalue);
Greg Claytond8d4a572015-08-11 21:38:15 +00009554 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009555 return true;
9556 }
9557 // format was not enum, just fall through and dump the value as
9558 // requested....
9559 LLVM_FALLTHROUGH;
9560
9561 default:
9562 // We are down to a scalar type that we just need to display.
9563 {
9564 uint32_t item_count = 1;
9565 // A few formats, we might need to modify our size and count for
9566 // depending
9567 // on how we are trying to display the value...
9568 switch (format) {
Greg Claytond8d4a572015-08-11 21:38:15 +00009569 default:
Kate Stoneb9c1b512016-09-06 20:57:50 +00009570 case eFormatBoolean:
9571 case eFormatBinary:
9572 case eFormatComplex:
9573 case eFormatCString: // NULL terminated C strings
9574 case eFormatDecimal:
9575 case eFormatEnum:
9576 case eFormatHex:
9577 case eFormatHexUppercase:
9578 case eFormatFloat:
9579 case eFormatOctal:
9580 case eFormatOSType:
9581 case eFormatUnsigned:
9582 case eFormatPointer:
9583 case eFormatVectorOfChar:
9584 case eFormatVectorOfSInt8:
9585 case eFormatVectorOfUInt8:
9586 case eFormatVectorOfSInt16:
9587 case eFormatVectorOfUInt16:
9588 case eFormatVectorOfSInt32:
9589 case eFormatVectorOfUInt32:
9590 case eFormatVectorOfSInt64:
9591 case eFormatVectorOfUInt64:
9592 case eFormatVectorOfFloat32:
9593 case eFormatVectorOfFloat64:
9594 case eFormatVectorOfUInt128:
9595 break;
9596
9597 case eFormatChar:
9598 case eFormatCharPrintable:
9599 case eFormatCharArray:
9600 case eFormatBytes:
9601 case eFormatBytesWithASCII:
9602 item_count = byte_size;
9603 byte_size = 1;
9604 break;
9605
9606 case eFormatUnicode16:
9607 item_count = byte_size / 2;
9608 byte_size = 2;
9609 break;
9610
9611 case eFormatUnicode32:
9612 item_count = byte_size / 4;
9613 byte_size = 4;
9614 break;
9615 }
Zachary Turner29cb8682017-03-03 20:57:05 +00009616 return DumpDataExtractor(data, s, byte_offset, format, byte_size,
9617 item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
9618 bitfield_bit_size, bitfield_bit_offset,
9619 exe_scope);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009620 }
9621 break;
9622 }
9623 }
Jonas Devlieghere09ad8c82019-05-24 00:44:33 +00009624 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00009625}
9626
9627void ClangASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
9628 ExecutionContext *exe_ctx, Stream *s,
9629 const lldb_private::DataExtractor &data,
9630 lldb::offset_t data_byte_offset,
9631 size_t data_byte_size) {
9632 uint32_t length = 0;
9633 if (IsCStringType(type, length)) {
9634 if (exe_ctx) {
9635 Process *process = exe_ctx->GetProcessPtr();
9636 if (process) {
9637 lldb::offset_t offset = data_byte_offset;
9638 lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size);
9639 std::vector<uint8_t> buf;
9640 if (length > 0)
9641 buf.resize(length);
9642 else
9643 buf.resize(256);
9644
Zachary Turner29cb8682017-03-03 20:57:05 +00009645 DataExtractor cstr_data(&buf.front(), buf.size(),
9646 process->GetByteOrder(), 4);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009647 buf.back() = '\0';
9648 size_t bytes_read;
9649 size_t total_cstr_len = 0;
Zachary Turner97206d52017-05-12 04:51:55 +00009650 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00009651 while ((bytes_read = process->ReadMemory(pointer_address, &buf.front(),
9652 buf.size(), error)) > 0) {
9653 const size_t len = strlen((const char *)&buf.front());
9654 if (len == 0)
Greg Claytond8d4a572015-08-11 21:38:15 +00009655 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00009656 if (total_cstr_len == 0)
9657 s->PutCString(" \"");
Zachary Turner29cb8682017-03-03 20:57:05 +00009658 DumpDataExtractor(cstr_data, s, 0, lldb::eFormatChar, 1, len,
9659 UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009660 total_cstr_len += len;
9661 if (len < buf.size())
9662 break;
9663 pointer_address += total_cstr_len;
Greg Claytond8d4a572015-08-11 21:38:15 +00009664 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009665 if (total_cstr_len > 0)
9666 s->PutChar('"');
9667 }
Greg Claytond8d4a572015-08-11 21:38:15 +00009668 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009669 }
Greg Claytond8d4a572015-08-11 21:38:15 +00009670}
9671
Kate Stoneb9c1b512016-09-06 20:57:50 +00009672void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) {
9673 StreamFile s(stdout, false);
9674 DumpTypeDescription(type, &s);
9675 ClangASTMetadata *metadata =
9676 ClangASTContext::GetMetadata(getASTContext(), type);
9677 if (metadata) {
9678 metadata->Dump(&s);
9679 }
9680}
Greg Claytond8d4a572015-08-11 21:38:15 +00009681
Kate Stoneb9c1b512016-09-06 20:57:50 +00009682void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
9683 Stream *s) {
9684 if (type) {
9685 clang::QualType qual_type(GetQualType(type));
Greg Claytond8d4a572015-08-11 21:38:15 +00009686
Kate Stoneb9c1b512016-09-06 20:57:50 +00009687 llvm::SmallVector<char, 1024> buf;
9688 llvm::raw_svector_ostream llvm_ostrm(buf);
9689
9690 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
9691 switch (type_class) {
9692 case clang::Type::ObjCObject:
9693 case clang::Type::ObjCInterface: {
9694 GetCompleteType(type);
9695
9696 const clang::ObjCObjectType *objc_class_type =
9697 llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
9698 assert(objc_class_type);
9699 if (objc_class_type) {
9700 clang::ObjCInterfaceDecl *class_interface_decl =
9701 objc_class_type->getInterface();
9702 if (class_interface_decl) {
9703 clang::PrintingPolicy policy = getASTContext()->getPrintingPolicy();
9704 class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
Greg Claytond8d4a572015-08-11 21:38:15 +00009705 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009706 }
9707 } break;
Greg Claytond8d4a572015-08-11 21:38:15 +00009708
Kate Stoneb9c1b512016-09-06 20:57:50 +00009709 case clang::Type::Typedef: {
9710 const clang::TypedefType *typedef_type =
9711 qual_type->getAs<clang::TypedefType>();
9712 if (typedef_type) {
9713 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
9714 std::string clang_typedef_name(
9715 typedef_decl->getQualifiedNameAsString());
9716 if (!clang_typedef_name.empty()) {
9717 s->PutCString("typedef ");
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009718 s->PutCString(clang_typedef_name);
Greg Claytond8d4a572015-08-11 21:38:15 +00009719 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009720 }
9721 } break;
9722
9723 case clang::Type::Auto:
Alex Langfordbddab072019-08-13 19:40:36 +00009724 CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
9725 ->getDeducedType()
9726 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00009727 .DumpTypeDescription(s);
9728 return;
9729
9730 case clang::Type::Elaborated:
Alex Langfordbddab072019-08-13 19:40:36 +00009731 CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
9732 ->getNamedType()
9733 .getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00009734 .DumpTypeDescription(s);
9735 return;
9736
9737 case clang::Type::Paren:
Alex Langfordbddab072019-08-13 19:40:36 +00009738 CompilerType(
9739 this,
9740 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())
Kate Stoneb9c1b512016-09-06 20:57:50 +00009741 .DumpTypeDescription(s);
9742 return;
9743
9744 case clang::Type::Record: {
9745 GetCompleteType(type);
9746
9747 const clang::RecordType *record_type =
9748 llvm::cast<clang::RecordType>(qual_type.getTypePtr());
9749 const clang::RecordDecl *record_decl = record_type->getDecl();
9750 const clang::CXXRecordDecl *cxx_record_decl =
9751 llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
9752
9753 if (cxx_record_decl)
9754 cxx_record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(),
9755 s->GetIndentLevel());
9756 else
9757 record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(),
9758 s->GetIndentLevel());
9759 } break;
9760
9761 default: {
9762 const clang::TagType *tag_type =
9763 llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
9764 if (tag_type) {
9765 clang::TagDecl *tag_decl = tag_type->getDecl();
9766 if (tag_decl)
9767 tag_decl->print(llvm_ostrm, 0);
9768 } else {
9769 std::string clang_type_name(qual_type.getAsString());
9770 if (!clang_type_name.empty())
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00009771 s->PutCString(clang_type_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00009772 }
Greg Claytond8d4a572015-08-11 21:38:15 +00009773 }
Greg Claytone6b36cd2015-12-08 01:02:08 +00009774 }
9775
Kate Stoneb9c1b512016-09-06 20:57:50 +00009776 if (buf.size() > 0) {
9777 s->Write(buf.data(), buf.size());
Greg Clayton8b4edba2015-08-14 20:02:05 +00009778 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009779 }
Greg Clayton8b4edba2015-08-14 20:02:05 +00009780}
9781
Kate Stoneb9c1b512016-09-06 20:57:50 +00009782void ClangASTContext::DumpTypeName(const CompilerType &type) {
9783 if (ClangUtil::IsClangType(type)) {
9784 clang::QualType qual_type(
9785 ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
9786
9787 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
9788 switch (type_class) {
9789 case clang::Type::Record: {
9790 const clang::CXXRecordDecl *cxx_record_decl =
9791 qual_type->getAsCXXRecordDecl();
9792 if (cxx_record_decl)
9793 printf("class %s", cxx_record_decl->getName().str().c_str());
9794 } break;
9795
9796 case clang::Type::Enum: {
9797 clang::EnumDecl *enum_decl =
9798 llvm::cast<clang::EnumType>(qual_type)->getDecl();
9799 if (enum_decl) {
9800 printf("enum %s", enum_decl->getName().str().c_str());
9801 }
9802 } break;
9803
9804 case clang::Type::ObjCObject:
9805 case clang::Type::ObjCInterface: {
9806 const clang::ObjCObjectType *objc_class_type =
9807 llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
9808 if (objc_class_type) {
9809 clang::ObjCInterfaceDecl *class_interface_decl =
9810 objc_class_type->getInterface();
Adrian Prantl05097242018-04-30 16:49:04 +00009811 // We currently can't complete objective C types through the newly
9812 // added ASTContext because it only supports TagDecl objects right
9813 // now...
Kate Stoneb9c1b512016-09-06 20:57:50 +00009814 if (class_interface_decl)
9815 printf("@class %s", class_interface_decl->getName().str().c_str());
9816 }
9817 } break;
9818
9819 case clang::Type::Typedef:
9820 printf("typedef %s", llvm::cast<clang::TypedefType>(qual_type)
9821 ->getDecl()
9822 ->getName()
9823 .str()
9824 .c_str());
9825 break;
9826
9827 case clang::Type::Auto:
9828 printf("auto ");
9829 return DumpTypeName(CompilerType(type.GetTypeSystem(),
9830 llvm::cast<clang::AutoType>(qual_type)
9831 ->getDeducedType()
9832 .getAsOpaquePtr()));
9833
9834 case clang::Type::Elaborated:
9835 printf("elaborated ");
9836 return DumpTypeName(CompilerType(
9837 type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)
9838 ->getNamedType()
9839 .getAsOpaquePtr()));
9840
9841 case clang::Type::Paren:
9842 printf("paren ");
9843 return DumpTypeName(CompilerType(
9844 type.GetTypeSystem(),
9845 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
9846
9847 default:
9848 printf("ClangASTContext::DumpTypeName() type_class = %u", type_class);
9849 break;
Greg Clayton6dc8d582015-08-18 22:32:36 +00009850 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009851 }
Greg Clayton6dc8d582015-08-18 22:32:36 +00009852}
9853
Kate Stoneb9c1b512016-09-06 20:57:50 +00009854clang::ClassTemplateDecl *ClangASTContext::ParseClassTemplateDecl(
9855 clang::DeclContext *decl_ctx, lldb::AccessType access_type,
9856 const char *parent_name, int tag_decl_kind,
9857 const ClangASTContext::TemplateParameterInfos &template_param_infos) {
9858 if (template_param_infos.IsValid()) {
9859 std::string template_basename(parent_name);
9860 template_basename.erase(template_basename.find('<'));
9861
9862 return CreateClassTemplateDecl(decl_ctx, access_type,
9863 template_basename.c_str(), tag_decl_kind,
9864 template_param_infos);
9865 }
Konrad Kleine248a1302019-05-23 11:14:47 +00009866 return nullptr;
Greg Clayton6dc8d582015-08-18 22:32:36 +00009867}
Greg Clayton8b4edba2015-08-14 20:02:05 +00009868
Kate Stoneb9c1b512016-09-06 20:57:50 +00009869void ClangASTContext::CompleteTagDecl(void *baton, clang::TagDecl *decl) {
9870 ClangASTContext *ast = (ClangASTContext *)baton;
9871 SymbolFile *sym_file = ast->GetSymbolFile();
9872 if (sym_file) {
9873 CompilerType clang_type = GetTypeForDecl(decl);
9874 if (clang_type)
9875 sym_file->CompleteType(clang_type);
9876 }
Greg Clayton261ac3f2015-08-28 01:01:03 +00009877}
9878
Kate Stoneb9c1b512016-09-06 20:57:50 +00009879void ClangASTContext::CompleteObjCInterfaceDecl(
9880 void *baton, clang::ObjCInterfaceDecl *decl) {
9881 ClangASTContext *ast = (ClangASTContext *)baton;
9882 SymbolFile *sym_file = ast->GetSymbolFile();
9883 if (sym_file) {
9884 CompilerType clang_type = GetTypeForDecl(decl);
9885 if (clang_type)
9886 sym_file->CompleteType(clang_type);
9887 }
Zachary Turner42dff792016-04-15 00:21:26 +00009888}
Greg Clayton261ac3f2015-08-28 01:01:03 +00009889
Kate Stoneb9c1b512016-09-06 20:57:50 +00009890DWARFASTParser *ClangASTContext::GetDWARFParser() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +00009891 if (!m_dwarf_ast_parser_up)
9892 m_dwarf_ast_parser_up.reset(new DWARFASTParserClang(*this));
9893 return m_dwarf_ast_parser_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +00009894}
9895
9896PDBASTParser *ClangASTContext::GetPDBParser() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +00009897 if (!m_pdb_ast_parser_up)
9898 m_pdb_ast_parser_up.reset(new PDBASTParser(*this));
9899 return m_pdb_ast_parser_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +00009900}
9901
9902bool ClangASTContext::LayoutRecordType(
9903 void *baton, const clang::RecordDecl *record_decl, uint64_t &bit_size,
9904 uint64_t &alignment,
9905 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
9906 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
9907 &base_offsets,
9908 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
9909 &vbase_offsets) {
9910 ClangASTContext *ast = (ClangASTContext *)baton;
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00009911 lldb_private::ClangASTImporter *importer = nullptr;
Jonas Devlieghered5b44032019-02-13 06:25:41 +00009912 if (ast->m_dwarf_ast_parser_up)
9913 importer = &ast->m_dwarf_ast_parser_up->GetClangASTImporter();
9914 if (!importer && ast->m_pdb_ast_parser_up)
9915 importer = &ast->m_pdb_ast_parser_up->GetClangASTImporter();
Aleksandr Urakov7d2a74f2018-08-14 07:57:44 +00009916 if (!importer)
9917 return false;
9918
9919 return importer->LayoutRecordType(record_decl, bit_size, alignment,
9920 field_offsets, base_offsets, vbase_offsets);
Greg Clayton8b4edba2015-08-14 20:02:05 +00009921}
9922
Paul Hermand628cbb2015-09-15 23:44:17 +00009923// CompilerDecl override functions
Paul Hermand628cbb2015-09-15 23:44:17 +00009924
Kate Stoneb9c1b512016-09-06 20:57:50 +00009925ConstString ClangASTContext::DeclGetName(void *opaque_decl) {
9926 if (opaque_decl) {
9927 clang::NamedDecl *nd =
9928 llvm::dyn_cast<NamedDecl>((clang::Decl *)opaque_decl);
9929 if (nd != nullptr)
9930 return ConstString(nd->getDeclName().getAsString());
9931 }
9932 return ConstString();
Paul Hermand628cbb2015-09-15 23:44:17 +00009933}
9934
Kate Stoneb9c1b512016-09-06 20:57:50 +00009935ConstString ClangASTContext::DeclGetMangledName(void *opaque_decl) {
9936 if (opaque_decl) {
9937 clang::NamedDecl *nd =
9938 llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)opaque_decl);
9939 if (nd != nullptr && !llvm::isa<clang::ObjCMethodDecl>(nd)) {
9940 clang::MangleContext *mc = getMangleContext();
9941 if (mc && mc->shouldMangleCXXName(nd)) {
9942 llvm::SmallVector<char, 1024> buf;
9943 llvm::raw_svector_ostream llvm_ostrm(buf);
9944 if (llvm::isa<clang::CXXConstructorDecl>(nd)) {
9945 mc->mangleCXXCtor(llvm::dyn_cast<clang::CXXConstructorDecl>(nd),
9946 Ctor_Complete, llvm_ostrm);
9947 } else if (llvm::isa<clang::CXXDestructorDecl>(nd)) {
9948 mc->mangleCXXDtor(llvm::dyn_cast<clang::CXXDestructorDecl>(nd),
9949 Dtor_Complete, llvm_ostrm);
9950 } else {
9951 mc->mangleName(nd, llvm_ostrm);
Greg Claytonfe689042015-11-10 17:47:04 +00009952 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009953 if (buf.size() > 0)
9954 return ConstString(buf.data(), buf.size());
9955 }
Greg Claytonfe689042015-11-10 17:47:04 +00009956 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00009957 }
9958 return ConstString();
Greg Claytonfe689042015-11-10 17:47:04 +00009959}
9960
Kate Stoneb9c1b512016-09-06 20:57:50 +00009961CompilerDeclContext ClangASTContext::DeclGetDeclContext(void *opaque_decl) {
9962 if (opaque_decl)
9963 return CompilerDeclContext(this,
9964 ((clang::Decl *)opaque_decl)->getDeclContext());
9965 else
9966 return CompilerDeclContext();
Greg Claytonfe689042015-11-10 17:47:04 +00009967}
9968
Kate Stoneb9c1b512016-09-06 20:57:50 +00009969CompilerType ClangASTContext::DeclGetFunctionReturnType(void *opaque_decl) {
9970 if (clang::FunctionDecl *func_decl =
9971 llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl))
9972 return CompilerType(this, func_decl->getReturnType().getAsOpaquePtr());
9973 if (clang::ObjCMethodDecl *objc_method =
9974 llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl))
9975 return CompilerType(this, objc_method->getReturnType().getAsOpaquePtr());
9976 else
Greg Claytonfe689042015-11-10 17:47:04 +00009977 return CompilerType();
9978}
9979
Kate Stoneb9c1b512016-09-06 20:57:50 +00009980size_t ClangASTContext::DeclGetFunctionNumArguments(void *opaque_decl) {
9981 if (clang::FunctionDecl *func_decl =
9982 llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl))
9983 return func_decl->param_size();
9984 if (clang::ObjCMethodDecl *objc_method =
9985 llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl))
9986 return objc_method->param_size();
9987 else
9988 return 0;
9989}
9990
9991CompilerType ClangASTContext::DeclGetFunctionArgumentType(void *opaque_decl,
9992 size_t idx) {
9993 if (clang::FunctionDecl *func_decl =
9994 llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl)) {
9995 if (idx < func_decl->param_size()) {
9996 ParmVarDecl *var_decl = func_decl->getParamDecl(idx);
9997 if (var_decl)
9998 return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr());
9999 }
10000 } else if (clang::ObjCMethodDecl *objc_method =
10001 llvm::dyn_cast<clang::ObjCMethodDecl>(
10002 (clang::Decl *)opaque_decl)) {
10003 if (idx < objc_method->param_size())
10004 return CompilerType(
10005 this,
10006 objc_method->parameters()[idx]->getOriginalType().getAsOpaquePtr());
10007 }
10008 return CompilerType();
10009}
10010
Greg Clayton99558cc42015-08-24 23:46:31 +000010011// CompilerDeclContext functions
Greg Clayton99558cc42015-08-24 23:46:31 +000010012
Kate Stoneb9c1b512016-09-06 20:57:50 +000010013std::vector<CompilerDecl> ClangASTContext::DeclContextFindDeclByName(
10014 void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) {
10015 std::vector<CompilerDecl> found_decls;
10016 if (opaque_decl_ctx) {
10017 DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
10018 std::set<DeclContext *> searched;
10019 std::multimap<DeclContext *, DeclContext *> search_queue;
10020 SymbolFile *symbol_file = GetSymbolFile();
Paul Hermand628cbb2015-09-15 23:44:17 +000010021
Kate Stoneb9c1b512016-09-06 20:57:50 +000010022 for (clang::DeclContext *decl_context = root_decl_ctx;
10023 decl_context != nullptr && found_decls.empty();
10024 decl_context = decl_context->getParent()) {
10025 search_queue.insert(std::make_pair(decl_context, decl_context));
Paul Hermand628cbb2015-09-15 23:44:17 +000010026
Kate Stoneb9c1b512016-09-06 20:57:50 +000010027 for (auto it = search_queue.find(decl_context); it != search_queue.end();
10028 it++) {
10029 if (!searched.insert(it->second).second)
10030 continue;
10031 symbol_file->ParseDeclsForContext(
10032 CompilerDeclContext(this, it->second));
Paul Hermanea188fc2015-09-16 18:48:30 +000010033
Kate Stoneb9c1b512016-09-06 20:57:50 +000010034 for (clang::Decl *child : it->second->decls()) {
10035 if (clang::UsingDirectiveDecl *ud =
10036 llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) {
10037 if (ignore_using_decls)
10038 continue;
10039 clang::DeclContext *from = ud->getCommonAncestor();
10040 if (searched.find(ud->getNominatedNamespace()) == searched.end())
10041 search_queue.insert(
10042 std::make_pair(from, ud->getNominatedNamespace()));
10043 } else if (clang::UsingDecl *ud =
10044 llvm::dyn_cast<clang::UsingDecl>(child)) {
10045 if (ignore_using_decls)
10046 continue;
10047 for (clang::UsingShadowDecl *usd : ud->shadows()) {
10048 clang::Decl *target = usd->getTargetDecl();
10049 if (clang::NamedDecl *nd =
10050 llvm::dyn_cast<clang::NamedDecl>(target)) {
10051 IdentifierInfo *ii = nd->getIdentifier();
10052 if (ii != nullptr &&
10053 ii->getName().equals(name.AsCString(nullptr)))
10054 found_decls.push_back(CompilerDecl(this, nd));
10055 }
Paul Hermand628cbb2015-09-15 23:44:17 +000010056 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010057 } else if (clang::NamedDecl *nd =
10058 llvm::dyn_cast<clang::NamedDecl>(child)) {
10059 IdentifierInfo *ii = nd->getIdentifier();
10060 if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr)))
10061 found_decls.push_back(CompilerDecl(this, nd));
10062 }
Paul Hermand628cbb2015-09-15 23:44:17 +000010063 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010064 }
Paul Hermand628cbb2015-09-15 23:44:17 +000010065 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010066 }
10067 return found_decls;
Paul Hermand628cbb2015-09-15 23:44:17 +000010068}
10069
Dawn Perchikb5925782015-12-12 19:31:41 +000010070// Look for child_decl_ctx's lookup scope in frame_decl_ctx and its parents,
Kate Stoneb9c1b512016-09-06 20:57:50 +000010071// and return the number of levels it took to find it, or
Adrian Prantl05097242018-04-30 16:49:04 +000010072// LLDB_INVALID_DECL_LEVEL if not found. If the decl was imported via a using
10073// declaration, its name and/or type, if set, will be used to check that the
10074// decl found in the scope is a match.
Dawn Perchikb5925782015-12-12 19:31:41 +000010075//
Kate Stoneb9c1b512016-09-06 20:57:50 +000010076// The optional name is required by languages (like C++) to handle using
Adrian Prantl05097242018-04-30 16:49:04 +000010077// declarations like:
Dawn Perchikb5925782015-12-12 19:31:41 +000010078//
10079// void poo();
10080// namespace ns {
10081// void foo();
10082// void goo();
10083// }
10084// void bar() {
10085// using ns::foo;
10086// // CountDeclLevels returns 0 for 'foo', 1 for 'poo', and
10087// // LLDB_INVALID_DECL_LEVEL for 'goo'.
10088// }
10089//
10090// The optional type is useful in the case that there's a specific overload
10091// that we're looking for that might otherwise be shadowed, like:
10092//
10093// void foo(int);
10094// namespace ns {
10095// void foo();
10096// }
10097// void bar() {
10098// using ns::foo;
10099// // CountDeclLevels returns 0 for { 'foo', void() },
10100// // 1 for { 'foo', void(int) }, and
10101// // LLDB_INVALID_DECL_LEVEL for { 'foo', void(int, int) }.
10102// }
10103//
10104// NOTE: Because file statics are at the TranslationUnit along with globals, a
Kate Stoneb9c1b512016-09-06 20:57:50 +000010105// function at file scope will return the same level as a function at global
Adrian Prantl05097242018-04-30 16:49:04 +000010106// scope. Ideally we'd like to treat the file scope as an additional scope just
10107// below the global scope. More work needs to be done to recognise that, if
10108// the decl we're trying to look up is static, we should compare its source
10109// file with that of the current scope and return a lower number for it.
Kate Stoneb9c1b512016-09-06 20:57:50 +000010110uint32_t ClangASTContext::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
10111 clang::DeclContext *child_decl_ctx,
10112 ConstString *child_name,
10113 CompilerType *child_type) {
10114 if (frame_decl_ctx) {
10115 std::set<DeclContext *> searched;
10116 std::multimap<DeclContext *, DeclContext *> search_queue;
10117 SymbolFile *symbol_file = GetSymbolFile();
Dawn Perchikb5925782015-12-12 19:31:41 +000010118
Kate Stoneb9c1b512016-09-06 20:57:50 +000010119 // Get the lookup scope for the decl we're trying to find.
10120 clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent();
Dawn Perchikb5925782015-12-12 19:31:41 +000010121
Kate Stoneb9c1b512016-09-06 20:57:50 +000010122 // Look for it in our scope's decl context and its parents.
10123 uint32_t level = 0;
10124 for (clang::DeclContext *decl_ctx = frame_decl_ctx; decl_ctx != nullptr;
10125 decl_ctx = decl_ctx->getParent()) {
10126 if (!decl_ctx->isLookupContext())
10127 continue;
10128 if (decl_ctx == parent_decl_ctx)
10129 // Found it!
10130 return level;
10131 search_queue.insert(std::make_pair(decl_ctx, decl_ctx));
10132 for (auto it = search_queue.find(decl_ctx); it != search_queue.end();
10133 it++) {
10134 if (searched.find(it->second) != searched.end())
10135 continue;
10136
10137 // Currently DWARF has one shared translation unit for all Decls at top
Adrian Prantl05097242018-04-30 16:49:04 +000010138 // level, so this would erroneously find using statements anywhere. So
10139 // don't look at the top-level translation unit.
Kate Stoneb9c1b512016-09-06 20:57:50 +000010140 // TODO fix this and add a testcase that depends on it.
10141
10142 if (llvm::isa<clang::TranslationUnitDecl>(it->second))
10143 continue;
10144
10145 searched.insert(it->second);
10146 symbol_file->ParseDeclsForContext(
10147 CompilerDeclContext(this, it->second));
10148
10149 for (clang::Decl *child : it->second->decls()) {
10150 if (clang::UsingDirectiveDecl *ud =
10151 llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) {
10152 clang::DeclContext *ns = ud->getNominatedNamespace();
10153 if (ns == parent_decl_ctx)
10154 // Found it!
10155 return level;
10156 clang::DeclContext *from = ud->getCommonAncestor();
10157 if (searched.find(ns) == searched.end())
10158 search_queue.insert(std::make_pair(from, ns));
10159 } else if (child_name) {
10160 if (clang::UsingDecl *ud =
10161 llvm::dyn_cast<clang::UsingDecl>(child)) {
10162 for (clang::UsingShadowDecl *usd : ud->shadows()) {
10163 clang::Decl *target = usd->getTargetDecl();
10164 clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(target);
10165 if (!nd)
10166 continue;
10167 // Check names.
10168 IdentifierInfo *ii = nd->getIdentifier();
10169 if (ii == nullptr ||
10170 !ii->getName().equals(child_name->AsCString(nullptr)))
10171 continue;
10172 // Check types, if one was provided.
10173 if (child_type) {
10174 CompilerType clang_type = ClangASTContext::GetTypeForDecl(nd);
10175 if (!AreTypesSame(clang_type, *child_type,
10176 /*ignore_qualifiers=*/true))
10177 continue;
10178 }
Dawn Perchikb5925782015-12-12 19:31:41 +000010179 // Found it!
10180 return level;
Kate Stoneb9c1b512016-09-06 20:57:50 +000010181 }
Dawn Perchikb5925782015-12-12 19:31:41 +000010182 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010183 }
Dawn Perchikb5925782015-12-12 19:31:41 +000010184 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010185 }
10186 ++level;
Dawn Perchikb5925782015-12-12 19:31:41 +000010187 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000010188 }
10189 return LLDB_INVALID_DECL_LEVEL;
Dawn Perchikb5925782015-12-12 19:31:41 +000010190}
10191
Kate Stoneb9c1b512016-09-06 20:57:50 +000010192bool ClangASTContext::DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) {
10193 if (opaque_decl_ctx)
10194 return ((clang::DeclContext *)opaque_decl_ctx)->isRecord();
10195 else
Greg Clayton99558cc42015-08-24 23:46:31 +000010196 return false;
10197}
10198
Kate Stoneb9c1b512016-09-06 20:57:50 +000010199ConstString ClangASTContext::DeclContextGetName(void *opaque_decl_ctx) {
10200 if (opaque_decl_ctx) {
10201 clang::NamedDecl *named_decl =
10202 llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
10203 if (named_decl)
10204 return ConstString(named_decl->getName());
10205 }
10206 return ConstString();
Greg Clayton99558cc42015-08-24 23:46:31 +000010207}
10208
Kate Stoneb9c1b512016-09-06 20:57:50 +000010209ConstString
10210ClangASTContext::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) {
10211 if (opaque_decl_ctx) {
10212 clang::NamedDecl *named_decl =
10213 llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
10214 if (named_decl)
10215 return ConstString(
10216 llvm::StringRef(named_decl->getQualifiedNameAsString()));
10217 }
10218 return ConstString();
10219}
10220
10221bool ClangASTContext::DeclContextIsClassMethod(
10222 void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
10223 bool *is_instance_method_ptr, ConstString *language_object_name_ptr) {
10224 if (opaque_decl_ctx) {
10225 clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
10226 if (ObjCMethodDecl *objc_method =
10227 llvm::dyn_cast<clang::ObjCMethodDecl>(decl_ctx)) {
10228 if (is_instance_method_ptr)
10229 *is_instance_method_ptr = objc_method->isInstanceMethod();
10230 if (language_ptr)
10231 *language_ptr = eLanguageTypeObjC;
10232 if (language_object_name_ptr)
10233 language_object_name_ptr->SetCString("self");
10234 return true;
10235 } else if (CXXMethodDecl *cxx_method =
10236 llvm::dyn_cast<clang::CXXMethodDecl>(decl_ctx)) {
10237 if (is_instance_method_ptr)
10238 *is_instance_method_ptr = cxx_method->isInstance();
10239 if (language_ptr)
10240 *language_ptr = eLanguageTypeC_plus_plus;
10241 if (language_object_name_ptr)
10242 language_object_name_ptr->SetCString("this");
10243 return true;
10244 } else if (clang::FunctionDecl *function_decl =
10245 llvm::dyn_cast<clang::FunctionDecl>(decl_ctx)) {
10246 ClangASTMetadata *metadata =
10247 GetMetadata(&decl_ctx->getParentASTContext(), function_decl);
10248 if (metadata && metadata->HasObjectPtr()) {
10249 if (is_instance_method_ptr)
10250 *is_instance_method_ptr = true;
10251 if (language_ptr)
10252 *language_ptr = eLanguageTypeObjC;
10253 if (language_object_name_ptr)
10254 language_object_name_ptr->SetCString(metadata->GetObjectPtrName());
10255 return true;
10256 }
10257 }
10258 }
10259 return false;
10260}
10261
Raphael Isemanna9469972019-03-12 07:45:04 +000010262bool ClangASTContext::DeclContextIsContainedInLookup(
10263 void *opaque_decl_ctx, void *other_opaque_decl_ctx) {
10264 auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
10265 auto *other = (clang::DeclContext *)other_opaque_decl_ctx;
10266
10267 do {
10268 // A decl context always includes its own contents in its lookup.
10269 if (decl_ctx == other)
10270 return true;
10271
10272 // If we have an inline namespace, then the lookup of the parent context
10273 // also includes the inline namespace contents.
10274 } while (other->isInlineNamespace() && (other = other->getParent()));
10275
10276 return false;
10277}
10278
Kate Stoneb9c1b512016-09-06 20:57:50 +000010279clang::DeclContext *
10280ClangASTContext::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) {
10281 if (dc.IsClang())
10282 return (clang::DeclContext *)dc.GetOpaqueDeclContext();
10283 return nullptr;
10284}
Greg Clayton99558cc42015-08-24 23:46:31 +000010285
10286ObjCMethodDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010287ClangASTContext::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) {
10288 if (dc.IsClang())
10289 return llvm::dyn_cast<clang::ObjCMethodDecl>(
10290 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10291 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010292}
10293
10294CXXMethodDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010295ClangASTContext::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) {
10296 if (dc.IsClang())
10297 return llvm::dyn_cast<clang::CXXMethodDecl>(
10298 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10299 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010300}
10301
10302clang::FunctionDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010303ClangASTContext::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) {
10304 if (dc.IsClang())
10305 return llvm::dyn_cast<clang::FunctionDecl>(
10306 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10307 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010308}
10309
10310clang::NamespaceDecl *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010311ClangASTContext::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) {
10312 if (dc.IsClang())
10313 return llvm::dyn_cast<clang::NamespaceDecl>(
10314 (clang::DeclContext *)dc.GetOpaqueDeclContext());
10315 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010316}
10317
10318ClangASTMetadata *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010319ClangASTContext::DeclContextGetMetaData(const CompilerDeclContext &dc,
10320 const void *object) {
10321 clang::ASTContext *ast = DeclContextGetClangASTContext(dc);
10322 if (ast)
10323 return ClangASTContext::GetMetadata(ast, object);
10324 return nullptr;
Greg Clayton99558cc42015-08-24 23:46:31 +000010325}
10326
10327clang::ASTContext *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010328ClangASTContext::DeclContextGetClangASTContext(const CompilerDeclContext &dc) {
10329 ClangASTContext *ast =
10330 llvm::dyn_cast_or_null<ClangASTContext>(dc.GetTypeSystem());
10331 if (ast)
10332 return ast->getASTContext();
10333 return nullptr;
10334}
10335
10336ClangASTContextForExpressions::ClangASTContextForExpressions(Target &target)
10337 : ClangASTContext(target.GetArchitecture().GetTriple().getTriple().c_str()),
10338 m_target_wp(target.shared_from_this()),
10339 m_persistent_variables(new ClangPersistentVariables) {}
10340
10341UserExpression *ClangASTContextForExpressions::GetUserExpression(
Zachary Turnerc5d7df92016-11-08 04:52:16 +000010342 llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
Kate Stoneb9c1b512016-09-06 20:57:50 +000010343 Expression::ResultType desired_type,
Aleksandr Urakov40624a02019-02-05 09:14:36 +000010344 const EvaluateExpressionOptions &options,
10345 ValueObject *ctx_obj) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000010346 TargetSP target_sp = m_target_wp.lock();
10347 if (!target_sp)
Greg Clayton99558cc42015-08-24 23:46:31 +000010348 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +000010349
Zachary Turnerc5d7df92016-11-08 04:52:16 +000010350 return new ClangUserExpression(*target_sp.get(), expr, prefix, language,
Aleksandr Urakov40624a02019-02-05 09:14:36 +000010351 desired_type, options, ctx_obj);
Greg Clayton8b4edba2015-08-14 20:02:05 +000010352}
10353
Kate Stoneb9c1b512016-09-06 20:57:50 +000010354FunctionCaller *ClangASTContextForExpressions::GetFunctionCaller(
10355 const CompilerType &return_type, const Address &function_address,
10356 const ValueList &arg_value_list, const char *name) {
10357 TargetSP target_sp = m_target_wp.lock();
10358 if (!target_sp)
10359 return nullptr;
Jim Ingham151c0322015-09-15 21:13:50 +000010360
Kate Stoneb9c1b512016-09-06 20:57:50 +000010361 Process *process = target_sp->GetProcessSP().get();
10362 if (!process)
10363 return nullptr;
Jim Ingham151c0322015-09-15 21:13:50 +000010364
Kate Stoneb9c1b512016-09-06 20:57:50 +000010365 return new ClangFunctionCaller(*process, return_type, function_address,
10366 arg_value_list, name);
Jim Ingham151c0322015-09-15 21:13:50 +000010367}
10368
10369UtilityFunction *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010370ClangASTContextForExpressions::GetUtilityFunction(const char *text,
10371 const char *name) {
10372 TargetSP target_sp = m_target_wp.lock();
10373 if (!target_sp)
10374 return nullptr;
10375
10376 return new ClangUtilityFunction(*target_sp.get(), text, name);
Jim Ingham151c0322015-09-15 21:13:50 +000010377}
Sean Callanan8f1f9a12015-09-30 19:57:57 +000010378
10379PersistentExpressionState *
Kate Stoneb9c1b512016-09-06 20:57:50 +000010380ClangASTContextForExpressions::GetPersistentExpressionState() {
10381 return m_persistent_variables.get();
Sean Callanan8f1f9a12015-09-30 19:57:57 +000010382}
Sean Callanan68e44232017-09-28 20:20:25 +000010383
10384clang::ExternalASTMerger &
10385ClangASTContextForExpressions::GetMergerUnchecked() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +000010386 lldbassert(m_scratch_ast_source_up != nullptr);
10387 return m_scratch_ast_source_up->GetMergerUnchecked();
Sean Callanan68e44232017-09-28 20:20:25 +000010388}