Bug Summary

File:tools/lldb/source/Symbol/ClangASTContext.cpp
Warning:line 7912, column 16
Forming reference to null pointer

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ClangASTContext.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lldb/source/Symbol -I /build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Symbol -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/include -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn338205/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-7~svn338205/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/lib/gcc/x86_64-linux-gnu/8/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lldb/source/Symbol -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-07-29-043837-17923-1 -x c++ /build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Symbol/ClangASTContext.cpp -faddrsig

/build/llvm-toolchain-snapshot-7~svn338205/tools/lldb/source/Symbol/ClangASTContext.cpp

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

/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/unique_ptr.h

1// unique_ptr implementation -*- C++ -*-
2
3// Copyright (C) 2008-2018 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/unique_ptr.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30#ifndef _UNIQUE_PTR_H1
31#define _UNIQUE_PTR_H1 1
32
33#include <bits/c++config.h>
34#include <debug/assertions.h>
35#include <type_traits>
36#include <utility>
37#include <tuple>
38#include <bits/stl_function.h>
39#include <bits/functional_hash.h>
40
41namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
42{
43_GLIBCXX_BEGIN_NAMESPACE_VERSION
44
45 /**
46 * @addtogroup pointer_abstractions
47 * @{
48 */
49
50#if _GLIBCXX_USE_DEPRECATED1
51#pragma GCC diagnostic push
52#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
53 template<typename> class auto_ptr;
54#pragma GCC diagnostic pop
55#endif
56
57 /// Primary template of default_delete, used by unique_ptr
58 template<typename _Tp>
59 struct default_delete
60 {
61 /// Default constructor
62 constexpr default_delete() noexcept = default;
63
64 /** @brief Converting constructor.
65 *
66 * Allows conversion from a deleter for arrays of another type, @p _Up,
67 * only if @p _Up* is convertible to @p _Tp*.
68 */
69 template<typename _Up, typename = typename
70 enable_if<is_convertible<_Up*, _Tp*>::value>::type>
71 default_delete(const default_delete<_Up>&) noexcept { }
72
73 /// Calls @c delete @p __ptr
74 void
75 operator()(_Tp* __ptr) const
76 {
77 static_assert(!is_void<_Tp>::value,
78 "can't delete pointer to incomplete type");
79 static_assert(sizeof(_Tp)>0,
80 "can't delete pointer to incomplete type");
81 delete __ptr;
82 }
83 };
84
85 // _GLIBCXX_RESOLVE_LIB_DEFECTS
86 // DR 740 - omit specialization for array objects with a compile time length
87 /// Specialization for arrays, default_delete.
88 template<typename _Tp>
89 struct default_delete<_Tp[]>
90 {
91 public:
92 /// Default constructor
93 constexpr default_delete() noexcept = default;
94
95 /** @brief Converting constructor.
96 *
97 * Allows conversion from a deleter for arrays of another type, such as
98 * a const-qualified version of @p _Tp.
99 *
100 * Conversions from types derived from @c _Tp are not allowed because
101 * it is unsafe to @c delete[] an array of derived types through a
102 * pointer to the base type.
103 */
104 template<typename _Up, typename = typename
105 enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
106 default_delete(const default_delete<_Up[]>&) noexcept { }
107
108 /// Calls @c delete[] @p __ptr
109 template<typename _Up>
110 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
111 operator()(_Up* __ptr) const
112 {
113 static_assert(sizeof(_Tp)>0,
114 "can't delete pointer to incomplete type");
115 delete [] __ptr;
116 }
117 };
118
119 template <typename _Tp, typename _Dp>
120 class __uniq_ptr_impl
121 {
122 template <typename _Up, typename _Ep, typename = void>
123 struct _Ptr
124 {
125 using type = _Up*;
126 };
127
128 template <typename _Up, typename _Ep>
129 struct
130 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
131 {
132 using type = typename remove_reference<_Ep>::type::pointer;
133 };
134
135 public:
136 using _DeleterConstraint = enable_if<
137 __and_<__not_<is_pointer<_Dp>>,
138 is_default_constructible<_Dp>>::value>;
139
140 using pointer = typename _Ptr<_Tp, _Dp>::type;
141
142 __uniq_ptr_impl() = default;
143 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
144
145 template<typename _Del>
146 __uniq_ptr_impl(pointer __p, _Del&& __d)
147 : _M_t(__p, std::forward<_Del>(__d)) { }
148
149 pointer& _M_ptr() { return std::get<0>(_M_t); }
150 pointer _M_ptr() const { return std::get<0>(_M_t); }
14
Calling 'get<0, clang::ASTContext *, std::default_delete<clang::ASTContext>>'
21
Returning from 'get<0, clang::ASTContext *, std::default_delete<clang::ASTContext>>'
151 _Dp& _M_deleter() { return std::get<1>(_M_t); }
152 const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
153
154 private:
155 tuple<pointer, _Dp> _M_t;
156 };
157
158 /// 20.7.1.2 unique_ptr for single objects.
159 template <typename _Tp, typename _Dp = default_delete<_Tp>>
160 class unique_ptr
161 {
162 template <class _Up>
163 using _DeleterConstraint =
164 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
165
166 __uniq_ptr_impl<_Tp, _Dp> _M_t;
167
168 public:
169 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
170 using element_type = _Tp;
171 using deleter_type = _Dp;
172
173 // helper template for detecting a safe conversion from another
174 // unique_ptr
175 template<typename _Up, typename _Ep>
176 using __safe_conversion_up = __and_<
177 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
178 __not_<is_array<_Up>>,
179 __or_<__and_<is_reference<deleter_type>,
180 is_same<deleter_type, _Ep>>,
181 __and_<__not_<is_reference<deleter_type>>,
182 is_convertible<_Ep, deleter_type>>
183 >
184 >;
185
186 // Constructors.
187
188 /// Default constructor, creates a unique_ptr that owns nothing.
189 template <typename _Up = _Dp,
190 typename = _DeleterConstraint<_Up>>
191 constexpr unique_ptr() noexcept
192 : _M_t()
193 { }
194
195 /** Takes ownership of a pointer.
196 *
197 * @param __p A pointer to an object of @c element_type
198 *
199 * The deleter will be value-initialized.
200 */
201 template <typename _Up = _Dp,
202 typename = _DeleterConstraint<_Up>>
203 explicit
204 unique_ptr(pointer __p) noexcept
205 : _M_t(__p)
206 { }
207
208 /** Takes ownership of a pointer.
209 *
210 * @param __p A pointer to an object of @c element_type
211 * @param __d A reference to a deleter.
212 *
213 * The deleter will be initialized with @p __d
214 */
215 unique_ptr(pointer __p,
216 typename conditional<is_reference<deleter_type>::value,
217 deleter_type, const deleter_type&>::type __d) noexcept
218 : _M_t(__p, __d) { }
219
220 /** Takes ownership of a pointer.
221 *
222 * @param __p A pointer to an object of @c element_type
223 * @param __d An rvalue reference to a deleter.
224 *
225 * The deleter will be initialized with @p std::move(__d)
226 */
227 unique_ptr(pointer __p,
228 typename remove_reference<deleter_type>::type&& __d) noexcept
229 : _M_t(std::move(__p), std::move(__d))
230 { static_assert(!std::is_reference<deleter_type>::value,
231 "rvalue deleter bound to reference"); }
232
233 /// Creates a unique_ptr that owns nothing.
234 template <typename _Up = _Dp,
235 typename = _DeleterConstraint<_Up>>
236 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
237
238 // Move constructors.
239
240 /// Move constructor.
241 unique_ptr(unique_ptr&& __u) noexcept
242 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
243
244 /** @brief Converting constructor from another type
245 *
246 * Requires that the pointer owned by @p __u is convertible to the
247 * type of pointer owned by this object, @p __u does not own an array,
248 * and @p __u has a compatible deleter type.
249 */
250 template<typename _Up, typename _Ep, typename = _Require<
251 __safe_conversion_up<_Up, _Ep>,
252 typename conditional<is_reference<_Dp>::value,
253 is_same<_Ep, _Dp>,
254 is_convertible<_Ep, _Dp>>::type>>
255 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
256 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
257 { }
258
259#if _GLIBCXX_USE_DEPRECATED1
260#pragma GCC diagnostic push
261#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
262 /// Converting constructor from @c auto_ptr
263 template<typename _Up, typename = _Require<
264 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
265 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
266#pragma GCC diagnostic pop
267#endif
268
269 /// Destructor, invokes the deleter if the stored pointer is not null.
270 ~unique_ptr() noexcept
271 {
272 auto& __ptr = _M_t._M_ptr();
273 if (__ptr != nullptr)
274 get_deleter()(__ptr);
275 __ptr = pointer();
276 }
277
278 // Assignment.
279
280 /** @brief Move assignment operator.
281 *
282 * @param __u The object to transfer ownership from.
283 *
284 * Invokes the deleter first if this object owns a pointer.
285 */
286 unique_ptr&
287 operator=(unique_ptr&& __u) noexcept
288 {
289 reset(__u.release());
290 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
291 return *this;
292 }
293
294 /** @brief Assignment from another type.
295 *
296 * @param __u The object to transfer ownership from, which owns a
297 * convertible pointer to a non-array object.
298 *
299 * Invokes the deleter first if this object owns a pointer.
300 */
301 template<typename _Up, typename _Ep>
302 typename enable_if< __and_<
303 __safe_conversion_up<_Up, _Ep>,
304 is_assignable<deleter_type&, _Ep&&>
305 >::value,
306 unique_ptr&>::type
307 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
308 {
309 reset(__u.release());
310 get_deleter() = std::forward<_Ep>(__u.get_deleter());
311 return *this;
312 }
313
314 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
315 unique_ptr&
316 operator=(nullptr_t) noexcept
317 {
318 reset();
319 return *this;
320 }
321
322 // Observers.
323
324 /// Dereference the stored pointer.
325 typename add_lvalue_reference<element_type>::type
326 operator*() const
327 {
328 __glibcxx_assert(get() != pointer());
329 return *get();
330 }
331
332 /// Return the stored pointer.
333 pointer
334 operator->() const noexcept
335 {
336 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
337 return get();
338 }
339
340 /// Return the stored pointer.
341 pointer
342 get() const noexcept
343 { return _M_t._M_ptr(); }
13
Calling '__uniq_ptr_impl::_M_ptr'
22
Returning from '__uniq_ptr_impl::_M_ptr'
344
345 /// Return a reference to the stored deleter.
346 deleter_type&
347 get_deleter() noexcept
348 { return _M_t._M_deleter(); }
349
350 /// Return a reference to the stored deleter.
351 const deleter_type&
352 get_deleter() const noexcept
353 { return _M_t._M_deleter(); }
354
355 /// Return @c true if the stored pointer is not null.
356 explicit operator bool() const noexcept
357 { return get() == pointer() ? false : true; }
358
359 // Modifiers.
360
361 /// Release ownership of any stored pointer.
362 pointer
363 release() noexcept
364 {
365 pointer __p = get();
366 _M_t._M_ptr() = pointer();
367 return __p;
368 }
369
370 /** @brief Replace the stored pointer.
371 *
372 * @param __p The new pointer to store.
373 *
374 * The deleter will be invoked if a pointer is already owned.
375 */
376 void
377 reset(pointer __p = pointer()) noexcept
378 {
379 using std::swap;
380 swap(_M_t._M_ptr(), __p);
381 if (__p != pointer())
382 get_deleter()(__p);
383 }
384
385 /// Exchange the pointer and deleter with another object.
386 void
387 swap(unique_ptr& __u) noexcept
388 {
389 using std::swap;
390 swap(_M_t, __u._M_t);
391 }
392
393 // Disable copy from lvalue.
394 unique_ptr(const unique_ptr&) = delete;
395 unique_ptr& operator=(const unique_ptr&) = delete;
396 };
397
398 /// 20.7.1.3 unique_ptr for array objects with a runtime length
399 // [unique.ptr.runtime]
400 // _GLIBCXX_RESOLVE_LIB_DEFECTS
401 // DR 740 - omit specialization for array objects with a compile time length
402 template<typename _Tp, typename _Dp>
403 class unique_ptr<_Tp[], _Dp>
404 {
405 template <typename _Up>
406 using _DeleterConstraint =
407 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
408
409 __uniq_ptr_impl<_Tp, _Dp> _M_t;
410
411 template<typename _Up>
412 using __remove_cv = typename remove_cv<_Up>::type;
413
414 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
415 template<typename _Up>
416 using __is_derived_Tp
417 = __and_< is_base_of<_Tp, _Up>,
418 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
419
420 public:
421 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
422 using element_type = _Tp;
423 using deleter_type = _Dp;
424
425 // helper template for detecting a safe conversion from another
426 // unique_ptr
427 template<typename _Up, typename _Ep,
428 typename _Up_up = unique_ptr<_Up, _Ep>,
429 typename _Up_element_type = typename _Up_up::element_type>
430 using __safe_conversion_up = __and_<
431 is_array<_Up>,
432 is_same<pointer, element_type*>,
433 is_same<typename _Up_up::pointer, _Up_element_type*>,
434 is_convertible<_Up_element_type(*)[], element_type(*)[]>,
435 __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>,
436 __and_<__not_<is_reference<deleter_type>>,
437 is_convertible<_Ep, deleter_type>>>
438 >;
439
440 // helper template for detecting a safe conversion from a raw pointer
441 template<typename _Up>
442 using __safe_conversion_raw = __and_<
443 __or_<__or_<is_same<_Up, pointer>,
444 is_same<_Up, nullptr_t>>,
445 __and_<is_pointer<_Up>,
446 is_same<pointer, element_type*>,
447 is_convertible<
448 typename remove_pointer<_Up>::type(*)[],
449 element_type(*)[]>
450 >
451 >
452 >;
453
454 // Constructors.
455
456 /// Default constructor, creates a unique_ptr that owns nothing.
457 template <typename _Up = _Dp,
458 typename = _DeleterConstraint<_Up>>
459 constexpr unique_ptr() noexcept
460 : _M_t()
461 { }
462
463 /** Takes ownership of a pointer.
464 *
465 * @param __p A pointer to an array of a type safely convertible
466 * to an array of @c element_type
467 *
468 * The deleter will be value-initialized.
469 */
470 template<typename _Up,
471 typename _Vp = _Dp,
472 typename = _DeleterConstraint<_Vp>,
473 typename = typename enable_if<
474 __safe_conversion_raw<_Up>::value, bool>::type>
475 explicit
476 unique_ptr(_Up __p) noexcept
477 : _M_t(__p)
478 { }
479
480 /** Takes ownership of a pointer.
481 *
482 * @param __p A pointer to an array of a type safely convertible
483 * to an array of @c element_type
484 * @param __d A reference to a deleter.
485 *
486 * The deleter will be initialized with @p __d
487 */
488 template<typename _Up,
489 typename = typename enable_if<
490 __safe_conversion_raw<_Up>::value, bool>::type>
491 unique_ptr(_Up __p,
492 typename conditional<is_reference<deleter_type>::value,
493 deleter_type, const deleter_type&>::type __d) noexcept
494 : _M_t(__p, __d) { }
495
496 /** Takes ownership of a pointer.
497 *
498 * @param __p A pointer to an array of a type safely convertible
499 * to an array of @c element_type
500 * @param __d A reference to a deleter.
501 *
502 * The deleter will be initialized with @p std::move(__d)
503 */
504 template<typename _Up,
505 typename = typename enable_if<
506 __safe_conversion_raw<_Up>::value, bool>::type>
507 unique_ptr(_Up __p, typename
508 remove_reference<deleter_type>::type&& __d) noexcept
509 : _M_t(std::move(__p), std::move(__d))
510 { static_assert(!is_reference<deleter_type>::value,
511 "rvalue deleter bound to reference"); }
512
513 /// Move constructor.
514 unique_ptr(unique_ptr&& __u) noexcept
515 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
516
517 /// Creates a unique_ptr that owns nothing.
518 template <typename _Up = _Dp,
519 typename = _DeleterConstraint<_Up>>
520 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
521
522 template<typename _Up, typename _Ep,
523 typename = _Require<__safe_conversion_up<_Up, _Ep>>>
524 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
525 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
526 { }
527
528 /// Destructor, invokes the deleter if the stored pointer is not null.
529 ~unique_ptr()
530 {
531 auto& __ptr = _M_t._M_ptr();
532 if (__ptr != nullptr)
533 get_deleter()(__ptr);
534 __ptr = pointer();
535 }
536
537 // Assignment.
538
539 /** @brief Move assignment operator.
540 *
541 * @param __u The object to transfer ownership from.
542 *
543 * Invokes the deleter first if this object owns a pointer.
544 */
545 unique_ptr&
546 operator=(unique_ptr&& __u) noexcept
547 {
548 reset(__u.release());
549 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
550 return *this;
551 }
552
553 /** @brief Assignment from another type.
554 *
555 * @param __u The object to transfer ownership from, which owns a
556 * convertible pointer to an array object.
557 *
558 * Invokes the deleter first if this object owns a pointer.
559 */
560 template<typename _Up, typename _Ep>
561 typename
562 enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
563 is_assignable<deleter_type&, _Ep&&>
564 >::value,
565 unique_ptr&>::type
566 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
567 {
568 reset(__u.release());
569 get_deleter() = std::forward<_Ep>(__u.get_deleter());
570 return *this;
571 }
572
573 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
574 unique_ptr&
575 operator=(nullptr_t) noexcept
576 {
577 reset();
578 return *this;
579 }
580
581 // Observers.
582
583 /// Access an element of owned array.
584 typename std::add_lvalue_reference<element_type>::type
585 operator[](size_t __i) const
586 {
587 __glibcxx_assert(get() != pointer());
588 return get()[__i];
589 }
590
591 /// Return the stored pointer.
592 pointer
593 get() const noexcept
594 { return _M_t._M_ptr(); }
595
596 /// Return a reference to the stored deleter.
597 deleter_type&
598 get_deleter() noexcept
599 { return _M_t._M_deleter(); }
600
601 /// Return a reference to the stored deleter.
602 const deleter_type&
603 get_deleter() const noexcept
604 { return _M_t._M_deleter(); }
605
606 /// Return @c true if the stored pointer is not null.
607 explicit operator bool() const noexcept
608 { return get() == pointer() ? false : true; }
609
610 // Modifiers.
611
612 /// Release ownership of any stored pointer.
613 pointer
614 release() noexcept
615 {
616 pointer __p = get();
617 _M_t._M_ptr() = pointer();
618 return __p;
619 }
620
621 /** @brief Replace the stored pointer.
622 *
623 * @param __p The new pointer to store.
624 *
625 * The deleter will be invoked if a pointer is already owned.
626 */
627 template <typename _Up,
628 typename = _Require<
629 __or_<is_same<_Up, pointer>,
630 __and_<is_same<pointer, element_type*>,
631 is_pointer<_Up>,
632 is_convertible<
633 typename remove_pointer<_Up>::type(*)[],
634 element_type(*)[]
635 >
636 >
637 >
638 >>
639 void
640 reset(_Up __p) noexcept
641 {
642 pointer __ptr = __p;
643 using std::swap;
644 swap(_M_t._M_ptr(), __ptr);
645 if (__ptr != nullptr)
646 get_deleter()(__ptr);
647 }
648
649 void reset(nullptr_t = nullptr) noexcept
650 {
651 reset(pointer());
652 }
653
654 /// Exchange the pointer and deleter with another object.
655 void
656 swap(unique_ptr& __u) noexcept
657 {
658 using std::swap;
659 swap(_M_t, __u._M_t);
660 }
661
662 // Disable copy from lvalue.
663 unique_ptr(const unique_ptr&) = delete;
664 unique_ptr& operator=(const unique_ptr&) = delete;
665 };
666
667 template<typename _Tp, typename _Dp>
668 inline
669#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
670 // Constrained free swap overload, see p0185r1
671 typename enable_if<__is_swappable<_Dp>::value>::type
672#else
673 void
674#endif
675 swap(unique_ptr<_Tp, _Dp>& __x,
676 unique_ptr<_Tp, _Dp>& __y) noexcept
677 { __x.swap(__y); }
678
679#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
680 template<typename _Tp, typename _Dp>
681 typename enable_if<!__is_swappable<_Dp>::value>::type
682 swap(unique_ptr<_Tp, _Dp>&,
683 unique_ptr<_Tp, _Dp>&) = delete;
684#endif
685
686 template<typename _Tp, typename _Dp,
687 typename _Up, typename _Ep>
688 inline bool
689 operator==(const unique_ptr<_Tp, _Dp>& __x,
690 const unique_ptr<_Up, _Ep>& __y)
691 { return __x.get() == __y.get(); }
692
693 template<typename _Tp, typename _Dp>
694 inline bool
695 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
696 { return !__x; }
697
698 template<typename _Tp, typename _Dp>
699 inline bool
700 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
701 { return !__x; }
702
703 template<typename _Tp, typename _Dp,
704 typename _Up, typename _Ep>
705 inline bool
706 operator!=(const unique_ptr<_Tp, _Dp>& __x,
707 const unique_ptr<_Up, _Ep>& __y)
708 { return __x.get() != __y.get(); }
709
710 template<typename _Tp, typename _Dp>
711 inline bool
712 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
713 { return (bool)__x; }
714
715 template<typename _Tp, typename _Dp>
716 inline bool
717 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
718 { return (bool)__x; }
719
720 template<typename _Tp, typename _Dp,
721 typename _Up, typename _Ep>
722 inline bool
723 operator<(const unique_ptr<_Tp, _Dp>& __x,
724 const unique_ptr<_Up, _Ep>& __y)
725 {
726 typedef typename
727 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
728 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
729 return std::less<_CT>()(__x.get(), __y.get());
730 }
731
732 template<typename _Tp, typename _Dp>
733 inline bool
734 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
735 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
736 nullptr); }
737
738 template<typename _Tp, typename _Dp>
739 inline bool
740 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
741 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
742 __x.get()); }
743
744 template<typename _Tp, typename _Dp,
745 typename _Up, typename _Ep>
746 inline bool
747 operator<=(const unique_ptr<_Tp, _Dp>& __x,
748 const unique_ptr<_Up, _Ep>& __y)
749 { return !(__y < __x); }
750
751 template<typename _Tp, typename _Dp>
752 inline bool
753 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
754 { return !(nullptr < __x); }
755
756 template<typename _Tp, typename _Dp>
757 inline bool
758 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
759 { return !(__x < nullptr); }
760
761 template<typename _Tp, typename _Dp,
762 typename _Up, typename _Ep>
763 inline bool
764 operator>(const unique_ptr<_Tp, _Dp>& __x,
765 const unique_ptr<_Up, _Ep>& __y)
766 { return (__y < __x); }
767
768 template<typename _Tp, typename _Dp>
769 inline bool
770 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
771 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
772 __x.get()); }
773
774 template<typename _Tp, typename _Dp>
775 inline bool
776 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
777 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
778 nullptr); }
779
780 template<typename _Tp, typename _Dp,
781 typename _Up, typename _Ep>
782 inline bool
783 operator>=(const unique_ptr<_Tp, _Dp>& __x,
784 const unique_ptr<_Up, _Ep>& __y)
785 { return !(__x < __y); }
786
787 template<typename _Tp, typename _Dp>
788 inline bool
789 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
790 { return !(__x < nullptr); }
791
792 template<typename _Tp, typename _Dp>
793 inline bool
794 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
795 { return !(nullptr < __x); }
796
797 /// std::hash specialization for unique_ptr.
798 template<typename _Tp, typename _Dp>
799 struct hash<unique_ptr<_Tp, _Dp>>
800 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
801 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
802 {
803 size_t
804 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
805 {
806 typedef unique_ptr<_Tp, _Dp> _UP;
807 return std::hash<typename _UP::pointer>()(__u.get());
808 }
809 };
810
811#if __cplusplus201103L > 201103L
812
813#define __cpp_lib_make_unique 201304
814
815 template<typename _Tp>
816 struct _MakeUniq
817 { typedef unique_ptr<_Tp> __single_object; };
818
819 template<typename _Tp>
820 struct _MakeUniq<_Tp[]>
821 { typedef unique_ptr<_Tp[]> __array; };
822
823 template<typename _Tp, size_t _Bound>
824 struct _MakeUniq<_Tp[_Bound]>
825 { struct __invalid_type { }; };
826
827 /// std::make_unique for single objects
828 template<typename _Tp, typename... _Args>
829 inline typename _MakeUniq<_Tp>::__single_object
830 make_unique(_Args&&... __args)
831 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
832
833 /// std::make_unique for arrays of unknown bound
834 template<typename _Tp>
835 inline typename _MakeUniq<_Tp>::__array
836 make_unique(size_t __num)
837 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
838
839 /// Disable std::make_unique for arrays of known bound
840 template<typename _Tp, typename... _Args>
841 inline typename _MakeUniq<_Tp>::__invalid_type
842 make_unique(_Args&&...) = delete;
843#endif
844
845 // @} group pointer_abstractions
846
847_GLIBCXX_END_NAMESPACE_VERSION
848} // namespace
849
850#endif /* _UNIQUE_PTR_H */

/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/tuple

1// <tuple> -*- C++ -*-
2
3// Copyright (C) 2007-2018 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/tuple
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_TUPLE1
30#define _GLIBCXX_TUPLE1 1
31
32#pragma GCC system_header
33
34#if __cplusplus201103L < 201103L
35# include <bits/c++0x_warning.h>
36#else
37
38#include <utility>
39#include <array>
40#include <bits/uses_allocator.h>
41#include <bits/invoke.h>
42
43namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
44{
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
46
47 /**
48 * @addtogroup utilities
49 * @{
50 */
51
52 template<typename... _Elements>
53 class tuple;
54
55 template<typename _Tp>
56 struct __is_empty_non_tuple : is_empty<_Tp> { };
57
58 // Using EBO for elements that are tuples causes ambiguous base errors.
59 template<typename _El0, typename... _El>
60 struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
61
62 // Use the Empty Base-class Optimization for empty, non-final types.
63 template<typename _Tp>
64 using __empty_not_final
65 = typename conditional<__is_final(_Tp), false_type,
66 __is_empty_non_tuple<_Tp>>::type;
67
68 template<std::size_t _Idx, typename _Head,
69 bool = __empty_not_final<_Head>::value>
70 struct _Head_base;
71
72 template<std::size_t _Idx, typename _Head>
73 struct _Head_base<_Idx, _Head, true>
74 : public _Head
75 {
76 constexpr _Head_base()
77 : _Head() { }
78
79 constexpr _Head_base(const _Head& __h)
80 : _Head(__h) { }
81
82 constexpr _Head_base(const _Head_base&) = default;
83 constexpr _Head_base(_Head_base&&) = default;
84
85 template<typename _UHead>
86 constexpr _Head_base(_UHead&& __h)
87 : _Head(std::forward<_UHead>(__h)) { }
88
89 _Head_base(allocator_arg_t, __uses_alloc0)
90 : _Head() { }
91
92 template<typename _Alloc>
93 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
94 : _Head(allocator_arg, *__a._M_a) { }
95
96 template<typename _Alloc>
97 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
98 : _Head(*__a._M_a) { }
99
100 template<typename _UHead>
101 _Head_base(__uses_alloc0, _UHead&& __uhead)
102 : _Head(std::forward<_UHead>(__uhead)) { }
103
104 template<typename _Alloc, typename _UHead>
105 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
106 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
107
108 template<typename _Alloc, typename _UHead>
109 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
110 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
111
112 static constexpr _Head&
113 _M_head(_Head_base& __b) noexcept { return __b; }
114
115 static constexpr const _Head&
116 _M_head(const _Head_base& __b) noexcept { return __b; }
117 };
118
119 template<std::size_t _Idx, typename _Head>
120 struct _Head_base<_Idx, _Head, false>
121 {
122 constexpr _Head_base()
123 : _M_head_impl() { }
124
125 constexpr _Head_base(const _Head& __h)
126 : _M_head_impl(__h) { }
127
128 constexpr _Head_base(const _Head_base&) = default;
129 constexpr _Head_base(_Head_base&&) = default;
130
131 template<typename _UHead>
132 constexpr _Head_base(_UHead&& __h)
133 : _M_head_impl(std::forward<_UHead>(__h)) { }
134
135 _Head_base(allocator_arg_t, __uses_alloc0)
136 : _M_head_impl() { }
137
138 template<typename _Alloc>
139 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
140 : _M_head_impl(allocator_arg, *__a._M_a) { }
141
142 template<typename _Alloc>
143 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
144 : _M_head_impl(*__a._M_a) { }
145
146 template<typename _UHead>
147 _Head_base(__uses_alloc0, _UHead&& __uhead)
148 : _M_head_impl(std::forward<_UHead>(__uhead)) { }
149
150 template<typename _Alloc, typename _UHead>
151 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
152 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
153 { }
154
155 template<typename _Alloc, typename _UHead>
156 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
157 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
158
159 static constexpr _Head&
160 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
161
162 static constexpr const _Head&
163 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
164
165 _Head _M_head_impl;
166 };
167
168 /**
169 * Contains the actual implementation of the @c tuple template, stored
170 * as a recursive inheritance hierarchy from the first element (most
171 * derived class) to the last (least derived class). The @c Idx
172 * parameter gives the 0-based index of the element stored at this
173 * point in the hierarchy; we use it to implement a constant-time
174 * get() operation.
175 */
176 template<std::size_t _Idx, typename... _Elements>
177 struct _Tuple_impl;
178
179 /**
180 * Recursive tuple implementation. Here we store the @c Head element
181 * and derive from a @c Tuple_impl containing the remaining elements
182 * (which contains the @c Tail).
183 */
184 template<std::size_t _Idx, typename _Head, typename... _Tail>
185 struct _Tuple_impl<_Idx, _Head, _Tail...>
186 : public _Tuple_impl<_Idx + 1, _Tail...>,
187 private _Head_base<_Idx, _Head>
188 {
189 template<std::size_t, typename...> friend class _Tuple_impl;
190
191 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
192 typedef _Head_base<_Idx, _Head> _Base;
193
194 static constexpr _Head&
195 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
196
197 static constexpr const _Head&
198 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
17
Calling '_Head_base::_M_head'
18
Returning from '_Head_base::_M_head'
199
200 static constexpr _Inherited&
201 _M_tail(_Tuple_impl& __t) noexcept { return __t; }
202
203 static constexpr const _Inherited&
204 _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
205
206 constexpr _Tuple_impl()
207 : _Inherited(), _Base() { }
208
209 explicit
210 constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
211 : _Inherited(__tail...), _Base(__head) { }
212
213 template<typename _UHead, typename... _UTail, typename = typename
214 enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
215 explicit
216 constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
217 : _Inherited(std::forward<_UTail>(__tail)...),
218 _Base(std::forward<_UHead>(__head)) { }
219
220 constexpr _Tuple_impl(const _Tuple_impl&) = default;
221
222 constexpr
223 _Tuple_impl(_Tuple_impl&& __in)
224 noexcept(__and_<is_nothrow_move_constructible<_Head>,
225 is_nothrow_move_constructible<_Inherited>>::value)
226 : _Inherited(std::move(_M_tail(__in))),
227 _Base(std::forward<_Head>(_M_head(__in))) { }
228
229 template<typename... _UElements>
230 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
231 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
232 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
233
234 template<typename _UHead, typename... _UTails>
235 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
236 : _Inherited(std::move
237 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
238 _Base(std::forward<_UHead>
239 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
240
241 template<typename _Alloc>
242 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
243 : _Inherited(__tag, __a),
244 _Base(__tag, __use_alloc<_Head>(__a)) { }
245
246 template<typename _Alloc>
247 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
248 const _Head& __head, const _Tail&... __tail)
249 : _Inherited(__tag, __a, __tail...),
250 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
251
252 template<typename _Alloc, typename _UHead, typename... _UTail,
253 typename = typename enable_if<sizeof...(_Tail)
254 == sizeof...(_UTail)>::type>
255 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
256 _UHead&& __head, _UTail&&... __tail)
257 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
258 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
259 std::forward<_UHead>(__head)) { }
260
261 template<typename _Alloc>
262 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
263 const _Tuple_impl& __in)
264 : _Inherited(__tag, __a, _M_tail(__in)),
265 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
266
267 template<typename _Alloc>
268 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
269 _Tuple_impl&& __in)
270 : _Inherited(__tag, __a, std::move(_M_tail(__in))),
271 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
272 std::forward<_Head>(_M_head(__in))) { }
273
274 template<typename _Alloc, typename... _UElements>
275 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
276 const _Tuple_impl<_Idx, _UElements...>& __in)
277 : _Inherited(__tag, __a,
278 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
279 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
280 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
281
282 template<typename _Alloc, typename _UHead, typename... _UTails>
283 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
284 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
285 : _Inherited(__tag, __a, std::move
286 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
287 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
288 std::forward<_UHead>
289 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
290
291 _Tuple_impl&
292 operator=(const _Tuple_impl& __in)
293 {
294 _M_head(*this) = _M_head(__in);
295 _M_tail(*this) = _M_tail(__in);
296 return *this;
297 }
298
299 _Tuple_impl&
300 operator=(_Tuple_impl&& __in)
301 noexcept(__and_<is_nothrow_move_assignable<_Head>,
302 is_nothrow_move_assignable<_Inherited>>::value)
303 {
304 _M_head(*this) = std::forward<_Head>(_M_head(__in));
305 _M_tail(*this) = std::move(_M_tail(__in));
306 return *this;
307 }
308
309 template<typename... _UElements>
310 _Tuple_impl&
311 operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
312 {
313 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
314 _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
315 return *this;
316 }
317
318 template<typename _UHead, typename... _UTails>
319 _Tuple_impl&
320 operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
321 {
322 _M_head(*this) = std::forward<_UHead>
323 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
324 _M_tail(*this) = std::move
325 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
326 return *this;
327 }
328
329 protected:
330 void
331 _M_swap(_Tuple_impl& __in)
332 noexcept(__is_nothrow_swappable<_Head>::value
333 && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
334 {
335 using std::swap;
336 swap(_M_head(*this), _M_head(__in));
337 _Inherited::_M_swap(_M_tail(__in));
338 }
339 };
340
341 // Basis case of inheritance recursion.
342 template<std::size_t _Idx, typename _Head>
343 struct _Tuple_impl<_Idx, _Head>
344 : private _Head_base<_Idx, _Head>
345 {
346 template<std::size_t, typename...> friend class _Tuple_impl;
347
348 typedef _Head_base<_Idx, _Head> _Base;
349
350 static constexpr _Head&
351 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
352
353 static constexpr const _Head&
354 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
355
356 constexpr _Tuple_impl()
357 : _Base() { }
358
359 explicit
360 constexpr _Tuple_impl(const _Head& __head)
361 : _Base(__head) { }
362
363 template<typename _UHead>
364 explicit
365 constexpr _Tuple_impl(_UHead&& __head)
366 : _Base(std::forward<_UHead>(__head)) { }
367
368 constexpr _Tuple_impl(const _Tuple_impl&) = default;
369
370 constexpr
371 _Tuple_impl(_Tuple_impl&& __in)
372 noexcept(is_nothrow_move_constructible<_Head>::value)
373 : _Base(std::forward<_Head>(_M_head(__in))) { }
374
375 template<typename _UHead>
376 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
377 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
378
379 template<typename _UHead>
380 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
381 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
382 { }
383
384 template<typename _Alloc>
385 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
386 : _Base(__tag, __use_alloc<_Head>(__a)) { }
387
388 template<typename _Alloc>
389 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
390 const _Head& __head)
391 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
392
393 template<typename _Alloc, typename _UHead>
394 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
395 _UHead&& __head)
396 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
397 std::forward<_UHead>(__head)) { }
398
399 template<typename _Alloc>
400 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
401 const _Tuple_impl& __in)
402 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
403
404 template<typename _Alloc>
405 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
406 _Tuple_impl&& __in)
407 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
408 std::forward<_Head>(_M_head(__in))) { }
409
410 template<typename _Alloc, typename _UHead>
411 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
412 const _Tuple_impl<_Idx, _UHead>& __in)
413 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
414 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
415
416 template<typename _Alloc, typename _UHead>
417 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
418 _Tuple_impl<_Idx, _UHead>&& __in)
419 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
420 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
421 { }
422
423 _Tuple_impl&
424 operator=(const _Tuple_impl& __in)
425 {
426 _M_head(*this) = _M_head(__in);
427 return *this;
428 }
429
430 _Tuple_impl&
431 operator=(_Tuple_impl&& __in)
432 noexcept(is_nothrow_move_assignable<_Head>::value)
433 {
434 _M_head(*this) = std::forward<_Head>(_M_head(__in));
435 return *this;
436 }
437
438 template<typename _UHead>
439 _Tuple_impl&
440 operator=(const _Tuple_impl<_Idx, _UHead>& __in)
441 {
442 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
443 return *this;
444 }
445
446 template<typename _UHead>
447 _Tuple_impl&
448 operator=(_Tuple_impl<_Idx, _UHead>&& __in)
449 {
450 _M_head(*this)
451 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
452 return *this;
453 }
454
455 protected:
456 void
457 _M_swap(_Tuple_impl& __in)
458 noexcept(__is_nothrow_swappable<_Head>::value)
459 {
460 using std::swap;
461 swap(_M_head(*this), _M_head(__in));
462 }
463 };
464
465 // Concept utility functions, reused in conditionally-explicit
466 // constructors.
467 template<bool, typename... _Elements>
468 struct _TC
469 {
470 template<typename... _UElements>
471 static constexpr bool _ConstructibleTuple()
472 {
473 return __and_<is_constructible<_Elements, const _UElements&>...>::value;
474 }
475
476 template<typename... _UElements>
477 static constexpr bool _ImplicitlyConvertibleTuple()
478 {
479 return __and_<is_convertible<const _UElements&, _Elements>...>::value;
480 }
481
482 template<typename... _UElements>
483 static constexpr bool _MoveConstructibleTuple()
484 {
485 return __and_<is_constructible<_Elements, _UElements&&>...>::value;
486 }
487
488 template<typename... _UElements>
489 static constexpr bool _ImplicitlyMoveConvertibleTuple()
490 {
491 return __and_<is_convertible<_UElements&&, _Elements>...>::value;
492 }
493
494 template<typename _SrcTuple>
495 static constexpr bool _NonNestedTuple()
496 {
497 return __and_<__not_<is_same<tuple<_Elements...>,
498 typename remove_cv<
499 typename remove_reference<_SrcTuple>::type
500 >::type>>,
501 __not_<is_convertible<_SrcTuple, _Elements...>>,
502 __not_<is_constructible<_Elements..., _SrcTuple>>
503 >::value;
504 }
505 template<typename... _UElements>
506 static constexpr bool _NotSameTuple()
507 {
508 return __not_<is_same<tuple<_Elements...>,
509 typename remove_const<
510 typename remove_reference<_UElements...>::type
511 >::type>>::value;
512 }
513 };
514
515 template<typename... _Elements>
516 struct _TC<false, _Elements...>
517 {
518 template<typename... _UElements>
519 static constexpr bool _ConstructibleTuple()
520 {
521 return false;
522 }
523
524 template<typename... _UElements>
525 static constexpr bool _ImplicitlyConvertibleTuple()
526 {
527 return false;
528 }
529
530 template<typename... _UElements>
531 static constexpr bool _MoveConstructibleTuple()
532 {
533 return false;
534 }
535
536 template<typename... _UElements>
537 static constexpr bool _ImplicitlyMoveConvertibleTuple()
538 {
539 return false;
540 }
541
542 template<typename... _UElements>
543 static constexpr bool _NonNestedTuple()
544 {
545 return true;
546 }
547 template<typename... _UElements>
548 static constexpr bool _NotSameTuple()
549 {
550 return true;
551 }
552 };
553
554 /// Primary class template, tuple
555 template<typename... _Elements>
556 class tuple : public _Tuple_impl<0, _Elements...>
557 {
558 typedef _Tuple_impl<0, _Elements...> _Inherited;
559
560 // Used for constraining the default constructor so
561 // that it becomes dependent on the constraints.
562 template<typename _Dummy>
563 struct _TC2
564 {
565 static constexpr bool _DefaultConstructibleTuple()
566 {
567 return __and_<is_default_constructible<_Elements>...>::value;
568 }
569 static constexpr bool _ImplicitlyDefaultConstructibleTuple()
570 {
571 return __and_<__is_implicitly_default_constructible<_Elements>...>
572 ::value;
573 }
574 };
575
576 public:
577 template<typename _Dummy = void,
578 typename enable_if<_TC2<_Dummy>::
579 _ImplicitlyDefaultConstructibleTuple(),
580 bool>::type = true>
581 constexpr tuple()
582 : _Inherited() { }
583
584 template<typename _Dummy = void,
585 typename enable_if<_TC2<_Dummy>::
586 _DefaultConstructibleTuple()
587 &&
588 !_TC2<_Dummy>::
589 _ImplicitlyDefaultConstructibleTuple(),
590 bool>::type = false>
591 explicit constexpr tuple()
592 : _Inherited() { }
593
594 // Shortcut for the cases where constructors taking _Elements...
595 // need to be constrained.
596 template<typename _Dummy> using _TCC =
597 _TC<is_same<_Dummy, void>::value,
598 _Elements...>;
599
600 template<typename _Dummy = void,
601 typename enable_if<
602 _TCC<_Dummy>::template
603 _ConstructibleTuple<_Elements...>()
604 && _TCC<_Dummy>::template
605 _ImplicitlyConvertibleTuple<_Elements...>()
606 && (sizeof...(_Elements) >= 1),
607 bool>::type=true>
608 constexpr tuple(const _Elements&... __elements)
609 : _Inherited(__elements...) { }
610
611 template<typename _Dummy = void,
612 typename enable_if<
613 _TCC<_Dummy>::template
614 _ConstructibleTuple<_Elements...>()
615 && !_TCC<_Dummy>::template
616 _ImplicitlyConvertibleTuple<_Elements...>()
617 && (sizeof...(_Elements) >= 1),
618 bool>::type=false>
619 explicit constexpr tuple(const _Elements&... __elements)
620 : _Inherited(__elements...) { }
621
622 // Shortcut for the cases where constructors taking _UElements...
623 // need to be constrained.
624 template<typename... _UElements> using _TMC =
625 _TC<(sizeof...(_Elements) == sizeof...(_UElements))
626 && (_TC<(sizeof...(_UElements)==1), _Elements...>::
627 template _NotSameTuple<_UElements...>()),
628 _Elements...>;
629
630 // Shortcut for the cases where constructors taking tuple<_UElements...>
631 // need to be constrained.
632 template<typename... _UElements> using _TMCT =
633 _TC<(sizeof...(_Elements) == sizeof...(_UElements))
634 && !is_same<tuple<_Elements...>,
635 tuple<_UElements...>>::value,
636 _Elements...>;
637
638 template<typename... _UElements, typename
639 enable_if<
640 _TMC<_UElements...>::template
641 _MoveConstructibleTuple<_UElements...>()
642 && _TMC<_UElements...>::template
643 _ImplicitlyMoveConvertibleTuple<_UElements...>()
644 && (sizeof...(_Elements) >= 1),
645 bool>::type=true>
646 constexpr tuple(_UElements&&... __elements)
647 : _Inherited(std::forward<_UElements>(__elements)...) { }
648
649 template<typename... _UElements, typename
650 enable_if<
651 _TMC<_UElements...>::template
652 _MoveConstructibleTuple<_UElements...>()
653 && !_TMC<_UElements...>::template
654 _ImplicitlyMoveConvertibleTuple<_UElements...>()
655 && (sizeof...(_Elements) >= 1),
656 bool>::type=false>
657 explicit constexpr tuple(_UElements&&... __elements)
658 : _Inherited(std::forward<_UElements>(__elements)...) { }
659
660 constexpr tuple(const tuple&) = default;
661
662 constexpr tuple(tuple&&) = default;
663
664 // Shortcut for the cases where constructors taking tuples
665 // must avoid creating temporaries.
666 template<typename _Dummy> using _TNTC =
667 _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1,
668 _Elements...>;
669
670 template<typename... _UElements, typename _Dummy = void, typename
671 enable_if<_TMCT<_UElements...>::template
672 _ConstructibleTuple<_UElements...>()
673 && _TMCT<_UElements...>::template
674 _ImplicitlyConvertibleTuple<_UElements...>()
675 && _TNTC<_Dummy>::template
676 _NonNestedTuple<const tuple<_UElements...>&>(),
677 bool>::type=true>
678 constexpr tuple(const tuple<_UElements...>& __in)
679 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
680 { }
681
682 template<typename... _UElements, typename _Dummy = void, typename
683 enable_if<_TMCT<_UElements...>::template
684 _ConstructibleTuple<_UElements...>()
685 && !_TMCT<_UElements...>::template
686 _ImplicitlyConvertibleTuple<_UElements...>()
687 && _TNTC<_Dummy>::template
688 _NonNestedTuple<const tuple<_UElements...>&>(),
689 bool>::type=false>
690 explicit constexpr tuple(const tuple<_UElements...>& __in)
691 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
692 { }
693
694 template<typename... _UElements, typename _Dummy = void, typename
695 enable_if<_TMCT<_UElements...>::template
696 _MoveConstructibleTuple<_UElements...>()
697 && _TMCT<_UElements...>::template
698 _ImplicitlyMoveConvertibleTuple<_UElements...>()
699 && _TNTC<_Dummy>::template
700 _NonNestedTuple<tuple<_UElements...>&&>(),
701 bool>::type=true>
702 constexpr tuple(tuple<_UElements...>&& __in)
703 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
704
705 template<typename... _UElements, typename _Dummy = void, typename
706 enable_if<_TMCT<_UElements...>::template
707 _MoveConstructibleTuple<_UElements...>()
708 && !_TMCT<_UElements...>::template
709 _ImplicitlyMoveConvertibleTuple<_UElements...>()
710 && _TNTC<_Dummy>::template
711 _NonNestedTuple<tuple<_UElements...>&&>(),
712 bool>::type=false>
713 explicit constexpr tuple(tuple<_UElements...>&& __in)
714 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
715
716 // Allocator-extended constructors.
717
718 template<typename _Alloc>
719 tuple(allocator_arg_t __tag, const _Alloc& __a)
720 : _Inherited(__tag, __a) { }
721
722 template<typename _Alloc, typename _Dummy = void,
723 typename enable_if<
724 _TCC<_Dummy>::template
725 _ConstructibleTuple<_Elements...>()
726 && _TCC<_Dummy>::template
727 _ImplicitlyConvertibleTuple<_Elements...>(),
728 bool>::type=true>
729 tuple(allocator_arg_t __tag, const _Alloc& __a,
730 const _Elements&... __elements)
731 : _Inherited(__tag, __a, __elements...) { }
732
733 template<typename _Alloc, typename _Dummy = void,
734 typename enable_if<
735 _TCC<_Dummy>::template
736 _ConstructibleTuple<_Elements...>()
737 && !_TCC<_Dummy>::template
738 _ImplicitlyConvertibleTuple<_Elements...>(),
739 bool>::type=false>
740 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
741 const _Elements&... __elements)
742 : _Inherited(__tag, __a, __elements...) { }
743
744 template<typename _Alloc, typename... _UElements, typename
745 enable_if<_TMC<_UElements...>::template
746 _MoveConstructibleTuple<_UElements...>()
747 && _TMC<_UElements...>::template
748 _ImplicitlyMoveConvertibleTuple<_UElements...>(),
749 bool>::type=true>
750 tuple(allocator_arg_t __tag, const _Alloc& __a,
751 _UElements&&... __elements)
752 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
753 { }
754
755 template<typename _Alloc, typename... _UElements, typename
756 enable_if<_TMC<_UElements...>::template
757 _MoveConstructibleTuple<_UElements...>()
758 && !_TMC<_UElements...>::template
759 _ImplicitlyMoveConvertibleTuple<_UElements...>(),
760 bool>::type=false>
761 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
762 _UElements&&... __elements)
763 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
764 { }
765
766 template<typename _Alloc>
767 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
768 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
769
770 template<typename _Alloc>
771 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
772 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
773
774 template<typename _Alloc, typename _Dummy = void,
775 typename... _UElements, typename
776 enable_if<_TMCT<_UElements...>::template
777 _ConstructibleTuple<_UElements...>()
778 && _TMCT<_UElements...>::template
779 _ImplicitlyConvertibleTuple<_UElements...>()
780 && _TNTC<_Dummy>::template
781 _NonNestedTuple<tuple<_UElements...>&&>(),
782 bool>::type=true>
783 tuple(allocator_arg_t __tag, const _Alloc& __a,
784 const tuple<_UElements...>& __in)
785 : _Inherited(__tag, __a,
786 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
787 { }
788
789 template<typename _Alloc, typename _Dummy = void,
790 typename... _UElements, typename
791 enable_if<_TMCT<_UElements...>::template
792 _ConstructibleTuple<_UElements...>()
793 && !_TMCT<_UElements...>::template
794 _ImplicitlyConvertibleTuple<_UElements...>()
795 && _TNTC<_Dummy>::template
796 _NonNestedTuple<tuple<_UElements...>&&>(),
797 bool>::type=false>
798 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
799 const tuple<_UElements...>& __in)
800 : _Inherited(__tag, __a,
801 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
802 { }
803
804 template<typename _Alloc, typename _Dummy = void,
805 typename... _UElements, typename
806 enable_if<_TMCT<_UElements...>::template
807 _MoveConstructibleTuple<_UElements...>()
808 && _TMCT<_UElements...>::template
809 _ImplicitlyMoveConvertibleTuple<_UElements...>()
810 && _TNTC<_Dummy>::template
811 _NonNestedTuple<tuple<_UElements...>&&>(),
812 bool>::type=true>
813 tuple(allocator_arg_t __tag, const _Alloc& __a,
814 tuple<_UElements...>&& __in)
815 : _Inherited(__tag, __a,
816 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
817 { }
818
819 template<typename _Alloc, typename _Dummy = void,
820 typename... _UElements, typename
821 enable_if<_TMCT<_UElements...>::template
822 _MoveConstructibleTuple<_UElements...>()
823 && !_TMCT<_UElements...>::template
824 _ImplicitlyMoveConvertibleTuple<_UElements...>()
825 && _TNTC<_Dummy>::template
826 _NonNestedTuple<tuple<_UElements...>&&>(),
827 bool>::type=false>
828 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
829 tuple<_UElements...>&& __in)
830 : _Inherited(__tag, __a,
831 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
832 { }
833
834 tuple&
835 operator=(const tuple& __in)
836 {
837 static_cast<_Inherited&>(*this) = __in;
838 return *this;
839 }
840
841 tuple&
842 operator=(tuple&& __in)
843 noexcept(is_nothrow_move_assignable<_Inherited>::value)
844 {
845 static_cast<_Inherited&>(*this) = std::move(__in);
846 return *this;
847 }
848
849 template<typename... _UElements>
850 typename
851 enable_if<sizeof...(_UElements)
852 == sizeof...(_Elements), tuple&>::type
853 operator=(const tuple<_UElements...>& __in)
854 {
855 static_cast<_Inherited&>(*this) = __in;
856 return *this;
857 }
858
859 template<typename... _UElements>
860 typename
861 enable_if<sizeof...(_UElements)
862 == sizeof...(_Elements), tuple&>::type
863 operator=(tuple<_UElements...>&& __in)
864 {
865 static_cast<_Inherited&>(*this) = std::move(__in);
866 return *this;
867 }
868
869 void
870 swap(tuple& __in)
871 noexcept(noexcept(__in._M_swap(__in)))
872 { _Inherited::_M_swap(__in); }
873 };
874
875#if __cpp_deduction_guides >= 201606
876 template<typename... _UTypes>
877 tuple(_UTypes...) -> tuple<_UTypes...>;
878 template<typename _T1, typename _T2>
879 tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
880 template<typename _Alloc, typename... _UTypes>
881 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
882 template<typename _Alloc, typename _T1, typename _T2>
883 tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
884 template<typename _Alloc, typename... _UTypes>
885 tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
886#endif
887
888 // Explicit specialization, zero-element tuple.
889 template<>
890 class tuple<>
891 {
892 public:
893 void swap(tuple&) noexcept { /* no-op */ }
894 // We need the default since we're going to define no-op
895 // allocator constructors.
896 tuple() = default;
897 // No-op allocator constructors.
898 template<typename _Alloc>
899 tuple(allocator_arg_t, const _Alloc&) { }
900 template<typename _Alloc>
901 tuple(allocator_arg_t, const _Alloc&, const tuple&) { }
902 };
903
904 /// Partial specialization, 2-element tuple.
905 /// Includes construction and assignment from a pair.
906 template<typename _T1, typename _T2>
907 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
908 {
909 typedef _Tuple_impl<0, _T1, _T2> _Inherited;
910
911 public:
912 template <typename _U1 = _T1,
913 typename _U2 = _T2,
914 typename enable_if<__and_<
915 __is_implicitly_default_constructible<_U1>,
916 __is_implicitly_default_constructible<_U2>>
917 ::value, bool>::type = true>
918
919 constexpr tuple()
920 : _Inherited() { }
921
922 template <typename _U1 = _T1,
923 typename _U2 = _T2,
924 typename enable_if<
925 __and_<
926 is_default_constructible<_U1>,
927 is_default_constructible<_U2>,
928 __not_<
929 __and_<__is_implicitly_default_constructible<_U1>,
930 __is_implicitly_default_constructible<_U2>>>>
931 ::value, bool>::type = false>
932
933 explicit constexpr tuple()
934 : _Inherited() { }
935
936 // Shortcut for the cases where constructors taking _T1, _T2
937 // need to be constrained.
938 template<typename _Dummy> using _TCC =
939 _TC<is_same<_Dummy, void>::value, _T1, _T2>;
940
941 template<typename _Dummy = void, typename
942 enable_if<_TCC<_Dummy>::template
943 _ConstructibleTuple<_T1, _T2>()
944 && _TCC<_Dummy>::template
945 _ImplicitlyConvertibleTuple<_T1, _T2>(),
946 bool>::type = true>
947 constexpr tuple(const _T1& __a1, const _T2& __a2)
948 : _Inherited(__a1, __a2) { }
949
950 template<typename _Dummy = void, typename
951 enable_if<_TCC<_Dummy>::template
952 _ConstructibleTuple<_T1, _T2>()
953 && !_TCC<_Dummy>::template
954 _ImplicitlyConvertibleTuple<_T1, _T2>(),
955 bool>::type = false>
956 explicit constexpr tuple(const _T1& __a1, const _T2& __a2)
957 : _Inherited(__a1, __a2) { }
958
959 // Shortcut for the cases where constructors taking _U1, _U2
960 // need to be constrained.
961 using _TMC = _TC<true, _T1, _T2>;
962
963 template<typename _U1, typename _U2, typename
964 enable_if<_TMC::template
965 _MoveConstructibleTuple<_U1, _U2>()
966 && _TMC::template
967 _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
968 && !is_same<typename decay<_U1>::type,
969 allocator_arg_t>::value,
970 bool>::type = true>
971 constexpr tuple(_U1&& __a1, _U2&& __a2)
972 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
973
974 template<typename _U1, typename _U2, typename
975 enable_if<_TMC::template
976 _MoveConstructibleTuple<_U1, _U2>()
977 && !_TMC::template
978 _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
979 && !is_same<typename decay<_U1>::type,
980 allocator_arg_t>::value,
981 bool>::type = false>
982 explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
983 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
984
985 constexpr tuple(const tuple&) = default;
986
987 constexpr tuple(tuple&&) = default;
988
989 template<typename _U1, typename _U2, typename
990 enable_if<_TMC::template
991 _ConstructibleTuple<_U1, _U2>()
992 && _TMC::template
993 _ImplicitlyConvertibleTuple<_U1, _U2>(),
994 bool>::type = true>
995 constexpr tuple(const tuple<_U1, _U2>& __in)
996 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
997
998 template<typename _U1, typename _U2, typename
999 enable_if<_TMC::template
1000 _ConstructibleTuple<_U1, _U2>()
1001 && !_TMC::template
1002 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1003 bool>::type = false>
1004 explicit constexpr tuple(const tuple<_U1, _U2>& __in)
1005 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1006
1007 template<typename _U1, typename _U2, typename
1008 enable_if<_TMC::template
1009 _MoveConstructibleTuple<_U1, _U2>()
1010 && _TMC::template
1011 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1012 bool>::type = true>
1013 constexpr tuple(tuple<_U1, _U2>&& __in)
1014 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1015
1016 template<typename _U1, typename _U2, typename
1017 enable_if<_TMC::template
1018 _MoveConstructibleTuple<_U1, _U2>()
1019 && !_TMC::template
1020 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1021 bool>::type = false>
1022 explicit constexpr tuple(tuple<_U1, _U2>&& __in)
1023 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1024
1025 template<typename _U1, typename _U2, typename
1026 enable_if<_TMC::template
1027 _ConstructibleTuple<_U1, _U2>()
1028 && _TMC::template
1029 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1030 bool>::type = true>
1031 constexpr tuple(const pair<_U1, _U2>& __in)
1032 : _Inherited(__in.first, __in.second) { }
1033
1034 template<typename _U1, typename _U2, typename
1035 enable_if<_TMC::template
1036 _ConstructibleTuple<_U1, _U2>()
1037 && !_TMC::template
1038 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1039 bool>::type = false>
1040 explicit constexpr tuple(const pair<_U1, _U2>& __in)
1041 : _Inherited(__in.first, __in.second) { }
1042
1043 template<typename _U1, typename _U2, typename
1044 enable_if<_TMC::template
1045 _MoveConstructibleTuple<_U1, _U2>()
1046 && _TMC::template
1047 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1048 bool>::type = true>
1049 constexpr tuple(pair<_U1, _U2>&& __in)
1050 : _Inherited(std::forward<_U1>(__in.first),
1051 std::forward<_U2>(__in.second)) { }
1052
1053 template<typename _U1, typename _U2, typename
1054 enable_if<_TMC::template
1055 _MoveConstructibleTuple<_U1, _U2>()
1056 && !_TMC::template
1057 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1058 bool>::type = false>
1059 explicit constexpr tuple(pair<_U1, _U2>&& __in)
1060 : _Inherited(std::forward<_U1>(__in.first),
1061 std::forward<_U2>(__in.second)) { }
1062
1063 // Allocator-extended constructors.
1064
1065 template<typename _Alloc>
1066 tuple(allocator_arg_t __tag, const _Alloc& __a)
1067 : _Inherited(__tag, __a) { }
1068
1069 template<typename _Alloc, typename _Dummy = void,
1070 typename enable_if<
1071 _TCC<_Dummy>::template
1072 _ConstructibleTuple<_T1, _T2>()
1073 && _TCC<_Dummy>::template
1074 _ImplicitlyConvertibleTuple<_T1, _T2>(),
1075 bool>::type=true>
1076
1077 tuple(allocator_arg_t __tag, const _Alloc& __a,
1078 const _T1& __a1, const _T2& __a2)
1079 : _Inherited(__tag, __a, __a1, __a2) { }
1080
1081 template<typename _Alloc, typename _Dummy = void,
1082 typename enable_if<
1083 _TCC<_Dummy>::template
1084 _ConstructibleTuple<_T1, _T2>()
1085 && !_TCC<_Dummy>::template
1086 _ImplicitlyConvertibleTuple<_T1, _T2>(),
1087 bool>::type=false>
1088
1089 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1090 const _T1& __a1, const _T2& __a2)
1091 : _Inherited(__tag, __a, __a1, __a2) { }
1092
1093 template<typename _Alloc, typename _U1, typename _U2, typename
1094 enable_if<_TMC::template
1095 _MoveConstructibleTuple<_U1, _U2>()
1096 && _TMC::template
1097 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1098 bool>::type = true>
1099 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1100 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1101 std::forward<_U2>(__a2)) { }
1102
1103 template<typename _Alloc, typename _U1, typename _U2, typename
1104 enable_if<_TMC::template
1105 _MoveConstructibleTuple<_U1, _U2>()
1106 && !_TMC::template
1107 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1108 bool>::type = false>
1109 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1110 _U1&& __a1, _U2&& __a2)
1111 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1112 std::forward<_U2>(__a2)) { }
1113
1114 template<typename _Alloc>
1115 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1116 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1117
1118 template<typename _Alloc>
1119 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1120 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1121
1122 template<typename _Alloc, typename _U1, typename _U2, typename
1123 enable_if<_TMC::template
1124 _ConstructibleTuple<_U1, _U2>()
1125 && _TMC::template
1126 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1127 bool>::type = true>
1128 tuple(allocator_arg_t __tag, const _Alloc& __a,
1129 const tuple<_U1, _U2>& __in)
1130 : _Inherited(__tag, __a,
1131 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1132 { }
1133
1134 template<typename _Alloc, typename _U1, typename _U2, typename
1135 enable_if<_TMC::template
1136 _ConstructibleTuple<_U1, _U2>()
1137 && !_TMC::template
1138 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1139 bool>::type = false>
1140 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1141 const tuple<_U1, _U2>& __in)
1142 : _Inherited(__tag, __a,
1143 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1144 { }
1145
1146 template<typename _Alloc, typename _U1, typename _U2, typename
1147 enable_if<_TMC::template
1148 _MoveConstructibleTuple<_U1, _U2>()
1149 && _TMC::template
1150 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1151 bool>::type = true>
1152 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1153 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1154 { }
1155
1156 template<typename _Alloc, typename _U1, typename _U2, typename
1157 enable_if<_TMC::template
1158 _MoveConstructibleTuple<_U1, _U2>()
1159 && !_TMC::template
1160 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1161 bool>::type = false>
1162 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1163 tuple<_U1, _U2>&& __in)
1164 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1165 { }
1166
1167 template<typename _Alloc, typename _U1, typename _U2, typename
1168 enable_if<_TMC::template
1169 _ConstructibleTuple<_U1, _U2>()
1170 && _TMC::template
1171 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1172 bool>::type = true>
1173 tuple(allocator_arg_t __tag, const _Alloc& __a,
1174 const pair<_U1, _U2>& __in)
1175 : _Inherited(__tag, __a, __in.first, __in.second) { }
1176
1177 template<typename _Alloc, typename _U1, typename _U2, typename
1178 enable_if<_TMC::template
1179 _ConstructibleTuple<_U1, _U2>()
1180 && !_TMC::template
1181 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1182 bool>::type = false>
1183 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1184 const pair<_U1, _U2>& __in)
1185 : _Inherited(__tag, __a, __in.first, __in.second) { }
1186
1187 template<typename _Alloc, typename _U1, typename _U2, typename
1188 enable_if<_TMC::template
1189 _MoveConstructibleTuple<_U1, _U2>()
1190 && _TMC::template
1191 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1192 bool>::type = true>
1193 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1194 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1195 std::forward<_U2>(__in.second)) { }
1196
1197 template<typename _Alloc, typename _U1, typename _U2, typename
1198 enable_if<_TMC::template
1199 _MoveConstructibleTuple<_U1, _U2>()
1200 && !_TMC::template
1201 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1202 bool>::type = false>
1203 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1204 pair<_U1, _U2>&& __in)
1205 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1206 std::forward<_U2>(__in.second)) { }
1207
1208 tuple&
1209 operator=(const tuple& __in)
1210 {
1211 static_cast<_Inherited&>(*this) = __in;
1212 return *this;
1213 }
1214
1215 tuple&
1216 operator=(tuple&& __in)
1217 noexcept(is_nothrow_move_assignable<_Inherited>::value)
1218 {
1219 static_cast<_Inherited&>(*this) = std::move(__in);
1220 return *this;
1221 }
1222
1223 template<typename _U1, typename _U2>
1224 tuple&
1225 operator=(const tuple<_U1, _U2>& __in)
1226 {
1227 static_cast<_Inherited&>(*this) = __in;
1228 return *this;
1229 }
1230
1231 template<typename _U1, typename _U2>
1232 tuple&
1233 operator=(tuple<_U1, _U2>&& __in)
1234 {
1235 static_cast<_Inherited&>(*this) = std::move(__in);
1236 return *this;
1237 }
1238
1239 template<typename _U1, typename _U2>
1240 tuple&
1241 operator=(const pair<_U1, _U2>& __in)
1242 {
1243 this->_M_head(*this) = __in.first;
1244 this->_M_tail(*this)._M_head(*this) = __in.second;
1245 return *this;
1246 }
1247
1248 template<typename _U1, typename _U2>
1249 tuple&
1250 operator=(pair<_U1, _U2>&& __in)
1251 {
1252 this->_M_head(*this) = std::forward<_U1>(__in.first);
1253 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1254 return *this;
1255 }
1256
1257 void
1258 swap(tuple& __in)
1259 noexcept(noexcept(__in._M_swap(__in)))
1260 { _Inherited::_M_swap(__in); }
1261 };
1262
1263
1264 /// class tuple_size
1265 template<typename... _Elements>
1266 struct tuple_size<tuple<_Elements...>>
1267 : public integral_constant<std::size_t, sizeof...(_Elements)> { };
1268
1269#if __cplusplus201103L > 201402L
1270 template <typename _Tp>
1271 inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1272#endif
1273
1274 /**
1275 * Recursive case for tuple_element: strip off the first element in
1276 * the tuple and retrieve the (i-1)th element of the remaining tuple.
1277 */
1278 template<std::size_t __i, typename _Head, typename... _Tail>
1279 struct tuple_element<__i, tuple<_Head, _Tail...> >
1280 : tuple_element<__i - 1, tuple<_Tail...> > { };
1281
1282 /**
1283 * Basis case for tuple_element: The first element is the one we're seeking.
1284 */
1285 template<typename _Head, typename... _Tail>
1286 struct tuple_element<0, tuple<_Head, _Tail...> >
1287 {
1288 typedef _Head type;
1289 };
1290
1291 /**
1292 * Error case for tuple_element: invalid index.
1293 */
1294 template<size_t __i>
1295 struct tuple_element<__i, tuple<>>
1296 {
1297 static_assert(__i < tuple_size<tuple<>>::value,
1298 "tuple index is in range");
1299 };
1300
1301 template<std::size_t __i, typename _Head, typename... _Tail>
1302 constexpr _Head&
1303 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1304 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1305
1306 template<std::size_t __i, typename _Head, typename... _Tail>
1307 constexpr const _Head&
1308 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1309 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
16
Calling '_Tuple_impl::_M_head'
19
Returning from '_Tuple_impl::_M_head'
1310
1311 /// Return a reference to the ith element of a tuple.
1312 template<std::size_t __i, typename... _Elements>
1313 constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1314 get(tuple<_Elements...>& __t) noexcept
1315 { return std::__get_helper<__i>(__t); }
1316
1317 /// Return a const reference to the ith element of a const tuple.
1318 template<std::size_t __i, typename... _Elements>
1319 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1320 get(const tuple<_Elements...>& __t) noexcept
1321 { return std::__get_helper<__i>(__t); }
15
Calling '__get_helper<0, clang::ASTContext *, std::default_delete<clang::ASTContext>>'
20
Returning from '__get_helper<0, clang::ASTContext *, std::default_delete<clang::ASTContext>>'
1322
1323 /// Return an rvalue reference to the ith element of a tuple rvalue.
1324 template<std::size_t __i, typename... _Elements>
1325 constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1326 get(tuple<_Elements...>&& __t) noexcept
1327 {
1328 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1329 return std::forward<__element_type&&>(std::get<__i>(__t));
1330 }
1331
1332 /// Return a const rvalue reference to the ith element of a const tuple rvalue.
1333 template<std::size_t __i, typename... _Elements>
1334 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
1335 get(const tuple<_Elements...>&& __t) noexcept
1336 {
1337 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1338 return std::forward<const __element_type&&>(std::get<__i>(__t));
1339 }
1340
1341#if __cplusplus201103L > 201103L
1342
1343#define __cpp_lib_tuples_by_type 201304
1344
1345 template<typename _Head, size_t __i, typename... _Tail>
1346 constexpr _Head&
1347 __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1348 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1349
1350 template<typename _Head, size_t __i, typename... _Tail>
1351 constexpr const _Head&
1352 __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1353 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1354
1355 /// Return a reference to the unique element of type _Tp of a tuple.
1356 template <typename _Tp, typename... _Types>
1357 constexpr _Tp&
1358 get(tuple<_Types...>& __t) noexcept
1359 { return std::__get_helper2<_Tp>(__t); }
1360
1361 /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1362 template <typename _Tp, typename... _Types>
1363 constexpr _Tp&&
1364 get(tuple<_Types...>&& __t) noexcept
1365 { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
1366
1367 /// Return a const reference to the unique element of type _Tp of a tuple.
1368 template <typename _Tp, typename... _Types>
1369 constexpr const _Tp&
1370 get(const tuple<_Types...>& __t) noexcept
1371 { return std::__get_helper2<_Tp>(__t); }
1372
1373 /// Return a const reference to the unique element of type _Tp of
1374 /// a const tuple rvalue.
1375 template <typename _Tp, typename... _Types>
1376 constexpr const _Tp&&
1377 get(const tuple<_Types...>&& __t) noexcept
1378 { return std::forward<const _Tp&&>(std::__get_helper2<_Tp>(__t)); }
1379#endif
1380
1381 // This class performs the comparison operations on tuples
1382 template<typename _Tp, typename _Up, size_t __i, size_t __size>
1383 struct __tuple_compare
1384 {
1385 static constexpr bool
1386 __eq(const _Tp& __t, const _Up& __u)
1387 {
1388 return bool(std::get<__i>(__t) == std::get<__i>(__u))
1389 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1390 }
1391
1392 static constexpr bool
1393 __less(const _Tp& __t, const _Up& __u)
1394 {
1395 return bool(std::get<__i>(__t) < std::get<__i>(__u))
1396 || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1397 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1398 }
1399 };
1400
1401 template<typename _Tp, typename _Up, size_t __size>
1402 struct __tuple_compare<_Tp, _Up, __size, __size>
1403 {
1404 static constexpr bool
1405 __eq(const _Tp&, const _Up&) { return true; }
1406
1407 static constexpr bool
1408 __less(const _Tp&, const _Up&) { return false; }
1409 };
1410
1411 template<typename... _TElements, typename... _UElements>
1412 constexpr bool
1413 operator==(const tuple<_TElements...>& __t,
1414 const tuple<_UElements...>& __u)
1415 {
1416 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1417 "tuple objects can only be compared if they have equal sizes.");
1418 using __compare = __tuple_compare<tuple<_TElements...>,
1419 tuple<_UElements...>,
1420 0, sizeof...(_TElements)>;
1421 return __compare::__eq(__t, __u);
1422 }
1423
1424 template<typename... _TElements, typename... _UElements>
1425 constexpr bool
1426 operator<(const tuple<_TElements...>& __t,
1427 const tuple<_UElements...>& __u)
1428 {
1429 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1430 "tuple objects can only be compared if they have equal sizes.");
1431 using __compare = __tuple_compare<tuple<_TElements...>,
1432 tuple<_UElements...>,
1433 0, sizeof...(_TElements)>;
1434 return __compare::__less(__t, __u);
1435 }
1436
1437 template<typename... _TElements, typename... _UElements>
1438 constexpr bool
1439 operator!=(const tuple<_TElements...>& __t,
1440 const tuple<_UElements...>& __u)
1441 { return !(__t == __u); }
1442
1443 template<typename... _TElements, typename... _UElements>
1444 constexpr bool
1445 operator>(const tuple<_TElements...>& __t,
1446 const tuple<_UElements...>& __u)
1447 { return __u < __t; }
1448
1449 template<typename... _TElements, typename... _UElements>
1450 constexpr bool
1451 operator<=(const tuple<_TElements...>& __t,
1452 const tuple<_UElements...>& __u)
1453 { return !(__u < __t); }
1454
1455 template<typename... _TElements, typename... _UElements>
1456 constexpr bool
1457 operator>=(const tuple<_TElements...>& __t,
1458 const tuple<_UElements...>& __u)
1459 { return !(__t < __u); }
1460
1461 // NB: DR 705.
1462 template<typename... _Elements>
1463 constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1464 make_tuple(_Elements&&... __args)
1465 {
1466 typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1467 __result_type;
1468 return __result_type(std::forward<_Elements>(__args)...);
1469 }
1470
1471 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1472 // 2275. Why is forward_as_tuple not constexpr?
1473 template<typename... _Elements>
1474 constexpr tuple<_Elements&&...>
1475 forward_as_tuple(_Elements&&... __args) noexcept
1476 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1477
1478 template<size_t, typename, typename, size_t>
1479 struct __make_tuple_impl;
1480
1481 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1482 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1483 : __make_tuple_impl<_Idx + 1,
1484 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1485 _Tuple, _Nm>
1486 { };
1487
1488 template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1489 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1490 {
1491 typedef tuple<_Tp...> __type;
1492 };
1493
1494 template<typename _Tuple>
1495 struct __do_make_tuple
1496 : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
1497 { };
1498
1499 // Returns the std::tuple equivalent of a tuple-like type.
1500 template<typename _Tuple>
1501 struct __make_tuple
1502 : public __do_make_tuple<typename std::remove_cv
1503 <typename std::remove_reference<_Tuple>::type>::type>
1504 { };
1505
1506 // Combines several std::tuple's into a single one.
1507 template<typename...>
1508 struct __combine_tuples;
1509
1510 template<>
1511 struct __combine_tuples<>
1512 {
1513 typedef tuple<> __type;
1514 };
1515
1516 template<typename... _Ts>
1517 struct __combine_tuples<tuple<_Ts...>>
1518 {
1519 typedef tuple<_Ts...> __type;
1520 };
1521
1522 template<typename... _T1s, typename... _T2s, typename... _Rem>
1523 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1524 {
1525 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1526 _Rem...>::__type __type;
1527 };
1528
1529 // Computes the result type of tuple_cat given a set of tuple-like types.
1530 template<typename... _Tpls>
1531 struct __tuple_cat_result
1532 {
1533 typedef typename __combine_tuples
1534 <typename __make_tuple<_Tpls>::__type...>::__type __type;
1535 };
1536
1537 // Helper to determine the index set for the first tuple-like
1538 // type of a given set.
1539 template<typename...>
1540 struct __make_1st_indices;
1541
1542 template<>
1543 struct __make_1st_indices<>
1544 {
1545 typedef std::_Index_tuple<> __type;
1546 };
1547
1548 template<typename _Tp, typename... _Tpls>
1549 struct __make_1st_indices<_Tp, _Tpls...>
1550 {
1551 typedef typename std::_Build_index_tuple<std::tuple_size<
1552 typename std::remove_reference<_Tp>::type>::value>::__type __type;
1553 };
1554
1555 // Performs the actual concatenation by step-wise expanding tuple-like
1556 // objects into the elements, which are finally forwarded into the
1557 // result tuple.
1558 template<typename _Ret, typename _Indices, typename... _Tpls>
1559 struct __tuple_concater;
1560
1561 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1562 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1563 {
1564 template<typename... _Us>
1565 static constexpr _Ret
1566 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1567 {
1568 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1569 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1570 return __next::_S_do(std::forward<_Tpls>(__tps)...,
1571 std::forward<_Us>(__us)...,
1572 std::get<_Is>(std::forward<_Tp>(__tp))...);
1573 }
1574 };
1575
1576 template<typename _Ret>
1577 struct __tuple_concater<_Ret, std::_Index_tuple<>>
1578 {
1579 template<typename... _Us>
1580 static constexpr _Ret
1581 _S_do(_Us&&... __us)
1582 {
1583 return _Ret(std::forward<_Us>(__us)...);
1584 }
1585 };
1586
1587 /// tuple_cat
1588 template<typename... _Tpls, typename = typename
1589 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1590 constexpr auto
1591 tuple_cat(_Tpls&&... __tpls)
1592 -> typename __tuple_cat_result<_Tpls...>::__type
1593 {
1594 typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1595 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1596 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1597 return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1598 }
1599
1600 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1601 // 2301. Why is tie not constexpr?
1602 /// tie
1603 template<typename... _Elements>
1604 constexpr tuple<_Elements&...>
1605 tie(_Elements&... __args) noexcept
1606 { return tuple<_Elements&...>(__args...); }
1607
1608 /// swap
1609 template<typename... _Elements>
1610 inline
1611#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
1612 // Constrained free swap overload, see p0185r1
1613 typename enable_if<__and_<__is_swappable<_Elements>...>::value
1614 >::type
1615#else
1616 void
1617#endif
1618 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1619 noexcept(noexcept(__x.swap(__y)))
1620 { __x.swap(__y); }
1621
1622#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
1623 template<typename... _Elements>
1624 typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
1625 swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
1626#endif
1627
1628 // A class (and instance) which can be used in 'tie' when an element
1629 // of a tuple is not required.
1630 // _GLIBCXX14_CONSTEXPR
1631 // 2933. PR for LWG 2773 could be clearer
1632 struct _Swallow_assign
1633 {
1634 template<class _Tp>
1635 _GLIBCXX14_CONSTEXPR const _Swallow_assign&
1636 operator=(const _Tp&) const
1637 { return *this; }
1638 };
1639
1640 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1641 // 2773. Making std::ignore constexpr
1642 _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
1643
1644 /// Partial specialization for tuples
1645 template<typename... _Types, typename _Alloc>
1646 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1647
1648 // See stl_pair.h...
1649 template<class _T1, class _T2>
1650 template<typename... _Args1, typename... _Args2>
1651 inline
1652 pair<_T1, _T2>::
1653 pair(piecewise_construct_t,
1654 tuple<_Args1...> __first, tuple<_Args2...> __second)
1655 : pair(__first, __second,
1656 typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1657 typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1658 { }
1659
1660 template<class _T1, class _T2>
1661 template<typename... _Args1, std::size_t... _Indexes1,
1662 typename... _Args2, std::size_t... _Indexes2>
1663 inline
1664 pair<_T1, _T2>::
1665 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1666 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1667 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1668 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1669 { }
1670
1671#if __cplusplus201103L > 201402L
1672# define __cpp_lib_apply 201603
1673
1674 template <typename _Fn, typename _Tuple, size_t... _Idx>
1675 constexpr decltype(auto)
1676 __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
1677 {
1678 return std::__invoke(std::forward<_Fn>(__f),
1679 std::get<_Idx>(std::forward<_Tuple>(__t))...);
1680 }
1681
1682 template <typename _Fn, typename _Tuple>
1683 constexpr decltype(auto)
1684 apply(_Fn&& __f, _Tuple&& __t)
1685 {
1686 using _Indices = make_index_sequence<tuple_size_v<decay_t<_Tuple>>>;
1687 return std::__apply_impl(std::forward<_Fn>(__f),
1688 std::forward<_Tuple>(__t),
1689 _Indices{});
1690 }
1691
1692#define __cpp_lib_make_from_tuple 201606
1693
1694 template <typename _Tp, typename _Tuple, size_t... _Idx>
1695 constexpr _Tp
1696 __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
1697 { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
1698
1699 template <typename _Tp, typename _Tuple>
1700 constexpr _Tp
1701 make_from_tuple(_Tuple&& __t)
1702 {
1703 return __make_from_tuple_impl<_Tp>(
1704 std::forward<_Tuple>(__t),
1705 make_index_sequence<tuple_size_v<decay_t<_Tuple>>>{});
1706 }
1707#endif // C++17
1708
1709 /// @}
1710
1711_GLIBCXX_END_NAMESPACE_VERSION
1712} // namespace std
1713
1714#endif // C++11
1715
1716#endif // _GLIBCXX_TUPLE