blob: 1c0ec1baf092015e38d6f5d8066d1379e1334bea [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Eli Friedman932197d2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Greg Clayton6beaaa62011-01-17 03:46:26 +000017
18// Clang headers like to use NDEBUG inside of them to enable/disable debug
19// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing
20// or another. This is bad because it means that if clang was built in release
21// mode, it assumes that you are building in release mode which is not always
22// the case. You can end up with functions that are defined as empty in header
23// files when NDEBUG is not defined, and this can cause link errors with the
24// clang .a files that you have since you might be missing functions in the .a
25// file. So we have to define NDEBUG when including clang headers to avoid any
26// mismatches. This is covered by rdar://problem/8691220
27
28#ifndef NDEBUG
29#define LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000030#define NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000031// Need to include assert.h so it is as clang would expect it to be (disabled)
32#include <assert.h>
33#endif
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "clang/AST/ASTContext.h"
36#include "clang/AST/ASTImporter.h"
37#include "clang/AST/CXXInheritance.h"
Greg Clayton8cf05932010-07-22 18:30:50 +000038#include "clang/AST/DeclObjC.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "clang/AST/RecordLayout.h"
40#include "clang/AST/Type.h"
41#include "clang/Basic/Builtins.h"
42#include "clang/Basic/FileManager.h"
Sean Callanan79439e82010-11-18 02:56:27 +000043#include "clang/Basic/FileSystemOptions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044#include "clang/Basic/SourceManager.h"
45#include "clang/Basic/TargetInfo.h"
46#include "clang/Basic/TargetOptions.h"
47#include "clang/Frontend/FrontendOptions.h"
48#include "clang/Frontend/LangStandard.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000049
50#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000051#undef NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000052#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
53// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
54#include <assert.h>
55#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056
Greg Clayton514487e2011-02-15 21:59:32 +000057#include "lldb/Core/ArchSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058#include "lldb/Core/dwarf.h"
Greg Clayton73b472d2010-10-27 03:32:59 +000059#include "lldb/Core/Flags.h"
Sean Callananfb8b7092010-10-28 18:19:36 +000060#include "lldb/Core/Log.h"
Jim Inghamd555bac2011-06-24 22:03:24 +000061#include "lldb/Target/ExecutionContext.h"
62#include "lldb/Target/Process.h"
63#include "lldb/Target/ObjCLanguageRuntime.h"
64
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065
Eli Friedman932197d2010-06-13 19:06:42 +000066#include <stdio.h>
67
Greg Claytonc86103d2010-08-05 01:57:25 +000068using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069using namespace lldb_private;
70using namespace llvm;
71using namespace clang;
72
Greg Clayton6beaaa62011-01-17 03:46:26 +000073
74static bool
75GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
76{
77 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
78 switch (type_class)
79 {
80 case clang::Type::Record:
81 case clang::Type::Enum:
82 {
Sean Callanan78e37602011-01-27 04:42:51 +000083 const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +000084 if (tag_type)
85 {
86 clang::TagDecl *tag_decl = tag_type->getDecl();
87 if (tag_decl)
88 {
89 if (tag_decl->getDefinition())
90 return true;
91
92 if (tag_decl->hasExternalLexicalStorage())
93 {
Greg Clayton007d5be2011-05-30 00:49:24 +000094 if (ast)
Greg Clayton6beaaa62011-01-17 03:46:26 +000095 {
Greg Clayton007d5be2011-05-30 00:49:24 +000096 ExternalASTSource *external_ast_source = ast->getExternalSource();
97 if (external_ast_source)
98 {
99 external_ast_source->CompleteType(tag_decl);
100 return !tag_type->isIncompleteType();
101 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000102 }
103 }
104 return false;
105 }
106 }
107
108 }
109 break;
110
111 case clang::Type::ObjCObject:
112 case clang::Type::ObjCInterface:
113 {
Sean Callanan78e37602011-01-27 04:42:51 +0000114 const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000115 if (objc_class_type)
116 {
117 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
118 // We currently can't complete objective C types through the newly added ASTContext
119 // because it only supports TagDecl objects right now...
Enrico Granata9dd75c82011-07-15 23:30:15 +0000120 if (class_interface_decl)
Greg Clayton6beaaa62011-01-17 03:46:26 +0000121 {
Enrico Granata0a3958e2011-07-02 00:25:22 +0000122 bool is_forward_decl = class_interface_decl->isForwardDecl();
123 if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
Greg Clayton6beaaa62011-01-17 03:46:26 +0000124 {
Enrico Granata0a3958e2011-07-02 00:25:22 +0000125 if (ast)
Greg Clayton007d5be2011-05-30 00:49:24 +0000126 {
Enrico Granata0a3958e2011-07-02 00:25:22 +0000127 ExternalASTSource *external_ast_source = ast->getExternalSource();
128 if (external_ast_source)
129 {
130 external_ast_source->CompleteType (class_interface_decl);
131 is_forward_decl = class_interface_decl->isForwardDecl();
132 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000133 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000134 return is_forward_decl == false;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000135 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000136 return true;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000137 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000138 else
139 return false;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000140 }
141 }
142 break;
143
144 case clang::Type::Typedef:
145 return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType());
Sean Callanan912855f2011-08-11 23:56:13 +0000146
147 case clang::Type::Elaborated:
148 return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType());
Greg Clayton6beaaa62011-01-17 03:46:26 +0000149
150 default:
151 break;
152 }
153
154 return true;
155}
156
157
Greg Clayton8cf05932010-07-22 18:30:50 +0000158static AccessSpecifier
Greg Claytonc86103d2010-08-05 01:57:25 +0000159ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000160{
161 switch (access)
162 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000163 default: break;
164 case eAccessNone: return AS_none;
165 case eAccessPublic: return AS_public;
166 case eAccessPrivate: return AS_private;
167 case eAccessProtected: return AS_protected;
Greg Clayton8cf05932010-07-22 18:30:50 +0000168 }
169 return AS_none;
170}
171
172static ObjCIvarDecl::AccessControl
Greg Claytonc86103d2010-08-05 01:57:25 +0000173ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000174{
175 switch (access)
176 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000177 default: break;
178 case eAccessNone: return ObjCIvarDecl::None;
179 case eAccessPublic: return ObjCIvarDecl::Public;
180 case eAccessPrivate: return ObjCIvarDecl::Private;
181 case eAccessProtected: return ObjCIvarDecl::Protected;
182 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton8cf05932010-07-22 18:30:50 +0000183 }
184 return ObjCIvarDecl::None;
185}
186
187
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188static void
189ParseLangArgs
190(
191 LangOptions &Opts,
Greg Clayton94e5d782010-06-13 17:34:29 +0000192 InputKind IK
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193)
194{
195 // FIXME: Cleanup per-file based stuff.
196
197 // Set some properties which depend soley on the input kind; it would be nice
198 // to move these to the language standard, and have the driver resolve the
199 // input kind + language standard.
Greg Clayton94e5d782010-06-13 17:34:29 +0000200 if (IK == IK_Asm) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201 Opts.AsmPreprocessor = 1;
Greg Clayton94e5d782010-06-13 17:34:29 +0000202 } else if (IK == IK_ObjC ||
203 IK == IK_ObjCXX ||
204 IK == IK_PreprocessedObjC ||
205 IK == IK_PreprocessedObjCXX) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206 Opts.ObjC1 = Opts.ObjC2 = 1;
207 }
208
209 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
210
211 if (LangStd == LangStandard::lang_unspecified) {
212 // Based on the base language, pick one.
213 switch (IK) {
Greg Clayton94e5d782010-06-13 17:34:29 +0000214 case IK_None:
215 case IK_AST:
Sean Callananfb0b7582011-03-15 00:17:19 +0000216 case IK_LLVM_IR:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000217 assert (!"Invalid input kind!");
Greg Clayton94e5d782010-06-13 17:34:29 +0000218 case IK_OpenCL:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219 LangStd = LangStandard::lang_opencl;
220 break;
Sean Callananfb0b7582011-03-15 00:17:19 +0000221 case IK_CUDA:
222 LangStd = LangStandard::lang_cuda;
223 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000224 case IK_Asm:
225 case IK_C:
226 case IK_PreprocessedC:
227 case IK_ObjC:
228 case IK_PreprocessedObjC:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229 LangStd = LangStandard::lang_gnu99;
230 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000231 case IK_CXX:
232 case IK_PreprocessedCXX:
233 case IK_ObjCXX:
234 case IK_PreprocessedObjCXX:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235 LangStd = LangStandard::lang_gnucxx98;
236 break;
237 }
238 }
239
240 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
241 Opts.BCPLComment = Std.hasBCPLComments();
242 Opts.C99 = Std.isC99();
243 Opts.CPlusPlus = Std.isCPlusPlus();
244 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
245 Opts.Digraphs = Std.hasDigraphs();
246 Opts.GNUMode = Std.isGNUMode();
247 Opts.GNUInline = !Std.isC99();
248 Opts.HexFloats = Std.hasHexFloats();
249 Opts.ImplicitInt = Std.hasImplicitInt();
250
251 // OpenCL has some additional defaults.
252 if (LangStd == LangStandard::lang_opencl) {
253 Opts.OpenCL = 1;
254 Opts.AltiVec = 1;
255 Opts.CXXOperatorNames = 1;
256 Opts.LaxVectorConversions = 1;
257 }
258
259 // OpenCL and C++ both have bool, true, false keywords.
260 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
261
262// if (Opts.CPlusPlus)
263// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
264//
265// if (Args.hasArg(OPT_fobjc_gc_only))
266// Opts.setGCMode(LangOptions::GCOnly);
267// else if (Args.hasArg(OPT_fobjc_gc))
268// Opts.setGCMode(LangOptions::HybridGC);
269//
270// if (Args.hasArg(OPT_print_ivar_layout))
271// Opts.ObjCGCBitmapPrint = 1;
272//
273// if (Args.hasArg(OPT_faltivec))
274// Opts.AltiVec = 1;
275//
276// if (Args.hasArg(OPT_pthread))
277// Opts.POSIXThreads = 1;
278//
279// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
280// "default");
281// if (Vis == "default")
Sean Callanan31e851c2010-10-29 18:38:40 +0000282 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283// else if (Vis == "hidden")
284// Opts.setVisibilityMode(LangOptions::Hidden);
285// else if (Vis == "protected")
286// Opts.setVisibilityMode(LangOptions::Protected);
287// else
288// Diags.Report(diag::err_drv_invalid_value)
289// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
290
291// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
292
293 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
294 // is specified, or -std is set to a conforming mode.
295 Opts.Trigraphs = !Opts.GNUMode;
296// if (Args.hasArg(OPT_trigraphs))
297// Opts.Trigraphs = 1;
298//
299// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
300// OPT_fno_dollars_in_identifiers,
301// !Opts.AsmPreprocessor);
302// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
303// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
304// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
305// if (Args.hasArg(OPT_fno_lax_vector_conversions))
306// Opts.LaxVectorConversions = 0;
307// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
308// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
309// Opts.Blocks = Args.hasArg(OPT_fblocks);
310// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
311// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
312// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
313// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
314// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
315// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
316// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
317// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
318// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
319// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
320// Diags);
321// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
322// Opts.ObjCConstantStringClass = getLastArgValue(Args,
323// OPT_fconstant_string_class);
324// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
325// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
326// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
327// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
328// Opts.Static = Args.hasArg(OPT_static_define);
329 Opts.OptimizeSize = 0;
330
331 // FIXME: Eliminate this dependency.
332// unsigned Opt =
333// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
334// Opts.Optimize = Opt != 0;
335 unsigned Opt = 0;
336
337 // This is the __NO_INLINE__ define, which just depends on things like the
338 // optimization level and -fno-inline, not actually whether the backend has
339 // inlining enabled.
340 //
341 // FIXME: This is affected by other options (-fno-inline).
342 Opts.NoInline = !Opt;
343
344// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
345// switch (SSP) {
346// default:
347// Diags.Report(diag::err_drv_invalid_value)
348// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
349// break;
350// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
351// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
352// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
353// }
354}
355
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356
Greg Clayton6beaaa62011-01-17 03:46:26 +0000357ClangASTContext::ClangASTContext (const char *target_triple) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358 m_target_triple(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000359 m_ast_ap(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360 m_language_options_ap(),
361 m_source_manager_ap(),
362 m_diagnostic_ap(),
363 m_target_options_ap(),
364 m_target_info_ap(),
365 m_identifier_table_ap(),
366 m_selector_table_ap(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000367 m_builtins_ap(),
368 m_callback_tag_decl (NULL),
369 m_callback_objc_decl (NULL),
370 m_callback_baton (NULL)
371
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372{
373 if (target_triple && target_triple[0])
Greg Clayton880cbb02011-07-30 01:26:02 +0000374 SetTargetTriple (target_triple);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375}
376
377//----------------------------------------------------------------------
378// Destructor
379//----------------------------------------------------------------------
380ClangASTContext::~ClangASTContext()
381{
382 m_builtins_ap.reset();
383 m_selector_table_ap.reset();
384 m_identifier_table_ap.reset();
385 m_target_info_ap.reset();
386 m_target_options_ap.reset();
387 m_diagnostic_ap.reset();
388 m_source_manager_ap.reset();
389 m_language_options_ap.reset();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000390 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391}
392
393
394void
395ClangASTContext::Clear()
396{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000397 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398 m_language_options_ap.reset();
399 m_source_manager_ap.reset();
400 m_diagnostic_ap.reset();
401 m_target_options_ap.reset();
402 m_target_info_ap.reset();
403 m_identifier_table_ap.reset();
404 m_selector_table_ap.reset();
405 m_builtins_ap.reset();
406}
407
408const char *
409ClangASTContext::GetTargetTriple ()
410{
411 return m_target_triple.c_str();
412}
413
414void
415ClangASTContext::SetTargetTriple (const char *target_triple)
416{
417 Clear();
418 m_target_triple.assign(target_triple);
419}
420
Greg Clayton514487e2011-02-15 21:59:32 +0000421void
422ClangASTContext::SetArchitecture (const ArchSpec &arch)
423{
Greg Clayton880cbb02011-07-30 01:26:02 +0000424 SetTargetTriple(arch.GetTriple().str().c_str());
Greg Clayton514487e2011-02-15 21:59:32 +0000425}
426
Greg Clayton6beaaa62011-01-17 03:46:26 +0000427bool
428ClangASTContext::HasExternalSource ()
429{
430 ASTContext *ast = getASTContext();
431 if (ast)
432 return ast->getExternalSource () != NULL;
433 return false;
434}
435
436void
437ClangASTContext::SetExternalSource (llvm::OwningPtr<ExternalASTSource> &ast_source_ap)
438{
439 ASTContext *ast = getASTContext();
440 if (ast)
441 {
442 ast->setExternalSource (ast_source_ap);
443 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
444 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
445 }
446}
447
448void
449ClangASTContext::RemoveExternalSource ()
450{
451 ASTContext *ast = getASTContext();
452
453 if (ast)
454 {
455 llvm::OwningPtr<ExternalASTSource> empty_ast_source_ap;
456 ast->setExternalSource (empty_ast_source_ap);
457 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
458 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
459 }
460}
461
462
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463
464ASTContext *
465ClangASTContext::getASTContext()
466{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000467 if (m_ast_ap.get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000468 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000469 m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
470 *getSourceManager(),
471 *getTargetInfo(),
472 *getIdentifierTable(),
473 *getSelectorTable(),
474 *getBuiltinContext(),
475 0));
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000476
Greg Clayton6beaaa62011-01-17 03:46:26 +0000477 if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton)
478 {
479 m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
480 //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
481 }
482
483 m_ast_ap->getDiagnostics().setClient(getDiagnosticClient(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000485 return m_ast_ap.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486}
487
488Builtin::Context *
489ClangASTContext::getBuiltinContext()
490{
491 if (m_builtins_ap.get() == NULL)
492 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
493 return m_builtins_ap.get();
494}
495
496IdentifierTable *
497ClangASTContext::getIdentifierTable()
498{
499 if (m_identifier_table_ap.get() == NULL)
500 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
501 return m_identifier_table_ap.get();
502}
503
504LangOptions *
505ClangASTContext::getLanguageOptions()
506{
507 if (m_language_options_ap.get() == NULL)
508 {
509 m_language_options_ap.reset(new LangOptions());
Greg Clayton94e5d782010-06-13 17:34:29 +0000510 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
511// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512 }
513 return m_language_options_ap.get();
514}
515
516SelectorTable *
517ClangASTContext::getSelectorTable()
518{
519 if (m_selector_table_ap.get() == NULL)
520 m_selector_table_ap.reset (new SelectorTable());
521 return m_selector_table_ap.get();
522}
523
Sean Callanan79439e82010-11-18 02:56:27 +0000524clang::FileManager *
525ClangASTContext::getFileManager()
526{
527 if (m_file_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000528 {
529 clang::FileSystemOptions file_system_options;
530 m_file_manager_ap.reset(new clang::FileManager(file_system_options));
531 }
Sean Callanan79439e82010-11-18 02:56:27 +0000532 return m_file_manager_ap.get();
533}
534
Greg Claytone1a916a2010-07-21 22:12:05 +0000535clang::SourceManager *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536ClangASTContext::getSourceManager()
537{
538 if (m_source_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000539 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540 return m_source_manager_ap.get();
541}
542
543Diagnostic *
544ClangASTContext::getDiagnostic()
545{
546 if (m_diagnostic_ap.get() == NULL)
Greg Claytona651b532010-11-19 21:46:54 +0000547 {
548 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
549 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
550 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000551 return m_diagnostic_ap.get();
552}
553
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000554class NullDiagnosticClient : public DiagnosticClient
555{
556public:
557 NullDiagnosticClient ()
558 {
559 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
560 }
561
562 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
563 {
564 if (m_log)
565 {
566 llvm::SmallVectorImpl<char> diag_str(10);
567 info.FormatDiagnostic(diag_str);
568 diag_str.push_back('\0');
569 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
570 }
571 }
572private:
573 LogSP m_log;
574};
575
576DiagnosticClient *
577ClangASTContext::getDiagnosticClient()
578{
579 if (m_diagnostic_client_ap.get() == NULL)
580 m_diagnostic_client_ap.reset(new NullDiagnosticClient);
581
582 return m_diagnostic_client_ap.get();
583}
584
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000585TargetOptions *
586ClangASTContext::getTargetOptions()
587{
588 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
589 {
590 m_target_options_ap.reset (new TargetOptions());
591 if (m_target_options_ap.get())
592 m_target_options_ap->Triple = m_target_triple;
593 }
594 return m_target_options_ap.get();
595}
596
597
598TargetInfo *
599ClangASTContext::getTargetInfo()
600{
601 // target_triple should be something like "x86_64-apple-darwin10"
602 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
603 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
604 return m_target_info_ap.get();
605}
606
607#pragma mark Basic Types
608
609static inline bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000610QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000611{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000612 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000613 if (qual_type_bit_size == bit_size)
614 return true;
615 return false;
616}
617
Greg Clayton1be10fc2010-09-29 01:12:09 +0000618clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +0000619ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000620{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000621 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622
Greg Clayton6beaaa62011-01-17 03:46:26 +0000623 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000624
Greg Clayton6beaaa62011-01-17 03:46:26 +0000625 return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000626}
627
Greg Clayton1be10fc2010-09-29 01:12:09 +0000628clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000629ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000631 if (!ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000632 return NULL;
633
634 switch (encoding)
635 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000636 case eEncodingInvalid:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000637 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
638 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639 break;
640
Greg Claytonc86103d2010-08-05 01:57:25 +0000641 case eEncodingUint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000642 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
643 return ast->UnsignedCharTy.getAsOpaquePtr();
644 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
645 return ast->UnsignedShortTy.getAsOpaquePtr();
646 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
647 return ast->UnsignedIntTy.getAsOpaquePtr();
648 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
649 return ast->UnsignedLongTy.getAsOpaquePtr();
650 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
651 return ast->UnsignedLongLongTy.getAsOpaquePtr();
652 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
653 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000654 break;
655
Greg Claytonc86103d2010-08-05 01:57:25 +0000656 case eEncodingSint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000657 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
658 return ast->CharTy.getAsOpaquePtr();
659 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
660 return ast->ShortTy.getAsOpaquePtr();
661 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
662 return ast->IntTy.getAsOpaquePtr();
663 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
664 return ast->LongTy.getAsOpaquePtr();
665 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
666 return ast->LongLongTy.getAsOpaquePtr();
667 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
668 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000669 break;
670
Greg Claytonc86103d2010-08-05 01:57:25 +0000671 case eEncodingIEEE754:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000672 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
673 return ast->FloatTy.getAsOpaquePtr();
674 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
675 return ast->DoubleTy.getAsOpaquePtr();
676 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
677 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000678 break;
679
Greg Claytonc86103d2010-08-05 01:57:25 +0000680 case eEncodingVector:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681 default:
682 break;
683 }
684
685 return NULL;
686}
687
Greg Clayton1be10fc2010-09-29 01:12:09 +0000688clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000689ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
690{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000691 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000692
693 #define streq(a,b) strcmp(a,b) == 0
Greg Clayton6beaaa62011-01-17 03:46:26 +0000694 assert (ast != NULL);
695 if (ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696 {
697 switch (dw_ate)
698 {
699 default:
700 break;
701
702 case DW_ATE_address:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000703 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
704 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000705 break;
706
707 case DW_ATE_boolean:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000708 if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
709 return ast->BoolTy.getAsOpaquePtr();
710 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
711 return ast->UnsignedCharTy.getAsOpaquePtr();
712 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
713 return ast->UnsignedShortTy.getAsOpaquePtr();
714 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
715 return ast->UnsignedIntTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716 break;
717
Greg Clayton49462ea2011-01-15 02:52:14 +0000718 case DW_ATE_lo_user:
719 // This has been seen to mean DW_AT_complex_integer
Greg Clayton5732f242011-01-27 09:15:11 +0000720 if (::strstr(type_name, "complex"))
Greg Clayton49462ea2011-01-15 02:52:14 +0000721 {
722 clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000723 return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000724 }
725 break;
726
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727 case DW_ATE_complex_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000728 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
729 return ast->FloatComplexTy.getAsOpaquePtr();
730 else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
731 return ast->DoubleComplexTy.getAsOpaquePtr();
732 else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
733 return ast->LongDoubleComplexTy.getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000734 else
735 {
736 clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000737 return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000738 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000739 break;
740
741 case DW_ATE_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000742 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
743 return ast->FloatTy.getAsOpaquePtr();
744 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
745 return ast->DoubleTy.getAsOpaquePtr();
746 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
747 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000748 break;
749
750 case DW_ATE_signed:
751 if (type_name)
752 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000753 if (strstr(type_name, "long long"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000755 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
756 return ast->LongLongTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000758 else if (strstr(type_name, "long"))
759 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000760 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
761 return ast->LongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000762 }
763 else if (strstr(type_name, "short"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000764 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000765 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
766 return ast->ShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000767 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000768 else if (strstr(type_name, "char"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000769 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000770 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
771 return ast->CharTy.getAsOpaquePtr();
772 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
773 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000775 else if (strstr(type_name, "int"))
776 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000777 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
778 return ast->IntTy.getAsOpaquePtr();
779 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
780 return ast->Int128Ty.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000781 }
782 else if (streq(type_name, "wchar_t"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000783 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000784 if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
785 return ast->WCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000786 }
Greg Clayton7bd65b92011-02-09 23:39:34 +0000787 else if (streq(type_name, "void"))
788 {
789 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
790 return ast->VoidTy.getAsOpaquePtr();
791 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000792 }
793 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000794 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
795 return ast->CharTy.getAsOpaquePtr();
796 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
797 return ast->ShortTy.getAsOpaquePtr();
798 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
799 return ast->IntTy.getAsOpaquePtr();
800 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
801 return ast->LongTy.getAsOpaquePtr();
802 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
803 return ast->LongLongTy.getAsOpaquePtr();
804 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
805 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000806 break;
807
808 case DW_ATE_signed_char:
809 if (type_name)
810 {
811 if (streq(type_name, "signed char"))
812 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000813 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
814 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000815 }
816 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000817 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
818 return ast->CharTy.getAsOpaquePtr();
819 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
820 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000821 break;
822
823 case DW_ATE_unsigned:
824 if (type_name)
825 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000826 if (strstr(type_name, "long long"))
827 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000828 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
829 return ast->UnsignedLongLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000830 }
831 else if (strstr(type_name, "long"))
832 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000833 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
834 return ast->UnsignedLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000835 }
836 else if (strstr(type_name, "short"))
837 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000838 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
839 return ast->UnsignedShortTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000840 }
841 else if (strstr(type_name, "char"))
842 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000843 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
844 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000845 }
846 else if (strstr(type_name, "int"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000847 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000848 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
849 return ast->UnsignedIntTy.getAsOpaquePtr();
850 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
851 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000852 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853 }
854 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000855 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
856 return ast->UnsignedCharTy.getAsOpaquePtr();
857 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
858 return ast->UnsignedShortTy.getAsOpaquePtr();
859 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
860 return ast->UnsignedIntTy.getAsOpaquePtr();
861 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
862 return ast->UnsignedLongTy.getAsOpaquePtr();
863 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
864 return ast->UnsignedLongLongTy.getAsOpaquePtr();
865 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
866 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000867 break;
868
869 case DW_ATE_unsigned_char:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000870 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
871 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton7bd65b92011-02-09 23:39:34 +0000872 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
873 return ast->UnsignedShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874 break;
875
876 case DW_ATE_imaginary_float:
877 break;
878 }
879 }
880 // This assert should fire for anything that we don't catch above so we know
881 // to fix any issues we run into.
Greg Claytondc968d12011-05-17 18:15:05 +0000882 if (type_name)
883 {
884 fprintf (stderr, "error: need to add support for DW_TAG_base_type '%s' encoded with DW_ATE = 0x%x, bit_size = %u\n", type_name, dw_ate, bit_size);
885 }
886 else
887 {
888 fprintf (stderr, "error: need to add support for DW_TAG_base_type encoded with DW_ATE = 0x%x, bit_size = %u\n", dw_ate, bit_size);
889 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000890 return NULL;
891}
892
Greg Clayton1be10fc2010-09-29 01:12:09 +0000893clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000894ClangASTContext::GetBuiltInType_void(ASTContext *ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000895{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000896 return ast->VoidTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000897}
898
Greg Clayton1be10fc2010-09-29 01:12:09 +0000899clang_type_t
Sean Callananf7c3e272010-11-19 02:52:21 +0000900ClangASTContext::GetBuiltInType_bool()
901{
902 return getASTContext()->BoolTy.getAsOpaquePtr();
903}
904
905clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000906ClangASTContext::GetBuiltInType_objc_id()
907{
Sean Callananf6c73082010-12-06 23:53:20 +0000908 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000909}
910
Greg Clayton1be10fc2010-09-29 01:12:09 +0000911clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000912ClangASTContext::GetBuiltInType_objc_Class()
913{
Sean Callanana2424172010-10-25 00:29:48 +0000914 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000915}
916
Greg Clayton1be10fc2010-09-29 01:12:09 +0000917clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000918ClangASTContext::GetBuiltInType_objc_selector()
919{
Sean Callananf6c73082010-12-06 23:53:20 +0000920 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000921}
922
Greg Clayton1be10fc2010-09-29 01:12:09 +0000923clang_type_t
Sean Callanan77502262011-05-12 23:54:16 +0000924ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
925{
926 return ast->UnknownAnyTy.getAsOpaquePtr();
927}
928
929clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000930ClangASTContext::GetCStringType (bool is_const)
931{
932 QualType char_type(getASTContext()->CharTy);
933
934 if (is_const)
935 char_type.addConst();
936
937 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
938}
939
Greg Clayton1be10fc2010-09-29 01:12:09 +0000940clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000941ClangASTContext::GetVoidPtrType (bool is_const)
942{
943 return GetVoidPtrType(getASTContext(), is_const);
944}
945
Greg Clayton1be10fc2010-09-29 01:12:09 +0000946clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000947ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000948{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000949 QualType void_ptr_type(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950
951 if (is_const)
952 void_ptr_type.addConst();
953
954 return void_ptr_type.getAsOpaquePtr();
955}
956
Greg Clayton1be10fc2010-09-29 01:12:09 +0000957clang_type_t
Greg Clayton38a61402010-12-02 23:20:03 +0000958ClangASTContext::CopyType (ASTContext *dst_ast,
959 ASTContext *src_ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000960 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000961{
Sean Callanan79439e82010-11-18 02:56:27 +0000962 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000963 FileManager file_manager (file_system_options);
964 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000965 *src_ast, file_manager,
966 false);
Sean Callanan0617fcb2010-11-09 22:37:10 +0000967
Greg Clayton38a61402010-12-02 23:20:03 +0000968 QualType src (QualType::getFromOpaquePtr(clang_type));
969 QualType dst (importer.Import(src));
Sean Callanan0617fcb2010-11-09 22:37:10 +0000970
971 return dst.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000972}
973
Greg Clayton526e5af2010-11-13 03:52:47 +0000974
975clang::Decl *
Greg Clayton38a61402010-12-02 23:20:03 +0000976ClangASTContext::CopyDecl (ASTContext *dst_ast,
977 ASTContext *src_ast,
Greg Clayton526e5af2010-11-13 03:52:47 +0000978 clang::Decl *source_decl)
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000979{
Sean Callanan79439e82010-11-18 02:56:27 +0000980 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000981 FileManager file_manager (file_system_options);
982 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000983 *src_ast, file_manager,
984 false);
Greg Clayton526e5af2010-11-13 03:52:47 +0000985
986 return importer.Import(source_decl);
987}
988
Sean Callanan23a30272010-07-16 00:00:27 +0000989bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000990ClangASTContext::AreTypesSame(ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000991 clang_type_t type1,
992 clang_type_t type2)
Sean Callanan4dcca2622010-07-15 22:30:52 +0000993{
Greg Claytonf4ecaa52011-02-16 23:00:21 +0000994 return ast->hasSameType (QualType::getFromOpaquePtr(type1),
995 QualType::getFromOpaquePtr(type2));
Sean Callanan4dcca2622010-07-15 22:30:52 +0000996}
997
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000998#pragma mark CVR modifiers
999
Greg Clayton1be10fc2010-09-29 01:12:09 +00001000clang_type_t
1001ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001002{
1003 if (clang_type)
1004 {
1005 QualType result(QualType::getFromOpaquePtr(clang_type));
1006 result.addConst();
1007 return result.getAsOpaquePtr();
1008 }
1009 return NULL;
1010}
1011
Greg Clayton1be10fc2010-09-29 01:12:09 +00001012clang_type_t
1013ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014{
1015 if (clang_type)
1016 {
1017 QualType result(QualType::getFromOpaquePtr(clang_type));
1018 result.getQualifiers().setRestrict (true);
1019 return result.getAsOpaquePtr();
1020 }
1021 return NULL;
1022}
1023
Greg Clayton1be10fc2010-09-29 01:12:09 +00001024clang_type_t
1025ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026{
1027 if (clang_type)
1028 {
1029 QualType result(QualType::getFromOpaquePtr(clang_type));
1030 result.getQualifiers().setVolatile (true);
1031 return result.getAsOpaquePtr();
1032 }
1033 return NULL;
1034}
1035
Greg Clayton6beaaa62011-01-17 03:46:26 +00001036
1037clang_type_t
1038ClangASTContext::GetTypeForDecl (TagDecl *decl)
1039{
1040 // No need to call the getASTContext() accessor (which can create the AST
1041 // if it isn't created yet, because we can't have created a decl in this
1042 // AST if our AST didn't already exist...
1043 if (m_ast_ap.get())
1044 return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
1045 return NULL;
1046}
1047
1048clang_type_t
1049ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
1050{
1051 // No need to call the getASTContext() accessor (which can create the AST
1052 // if it isn't created yet, because we can't have created a decl in this
1053 // AST if our AST didn't already exist...
1054 if (m_ast_ap.get())
1055 return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
1056 return NULL;
1057}
1058
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001059#pragma mark Structure, Unions, Classes
1060
Greg Clayton1be10fc2010-09-29 01:12:09 +00001061clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +00001062ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001064 ASTContext *ast = getASTContext();
1065 assert (ast != NULL);
Sean Callanana2424172010-10-25 00:29:48 +00001066
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001068 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001069
Greg Clayton9e409562010-07-28 02:04:09 +00001070
Greg Claytone1be9962011-08-24 23:50:00 +00001071 if (language == eLanguageTypeObjC || language == eLanguageTypeObjC_plus_plus)
Greg Clayton9e409562010-07-28 02:04:09 +00001072 {
Greg Claytonaaf99e02010-10-11 02:25:34 +00001073 bool isForwardDecl = true;
Greg Clayton9e409562010-07-28 02:04:09 +00001074 bool isInternal = false;
1075 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
1076 }
1077
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001078 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1079 // we will need to update this code. I was told to currently always use
1080 // the CXXRecordDecl class since we often don't know from debug information
1081 // if something is struct or a class, so we default to always use the more
1082 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001083 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001084 (TagDecl::TagKind)kind,
1085 decl_ctx,
1086 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001087 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001088 name && name[0] ? &ast->Idents.get(name) : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089
Greg Clayton6beaaa62011-01-17 03:46:26 +00001090 return ast->getTagDeclType(decl).getAsOpaquePtr();
1091}
1092
1093bool
1094ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
1095{
1096 if (clang_type == NULL)
1097 return false;
1098
1099 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1100
1101 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1102 switch (type_class)
1103 {
1104 case clang::Type::Record:
1105 {
1106 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
1107 if (cxx_record_decl)
1108 {
1109 cxx_record_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001110 cxx_record_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001111 return true;
1112 }
1113 }
1114 break;
1115
1116 case clang::Type::Enum:
1117 {
1118 EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
1119 if (enum_decl)
1120 {
1121 enum_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001122 enum_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001123 return true;
1124 }
1125 }
1126 break;
1127
1128 case clang::Type::ObjCObject:
1129 case clang::Type::ObjCInterface:
1130 {
Sean Callanan78e37602011-01-27 04:42:51 +00001131 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001132 assert (objc_class_type);
1133 if (objc_class_type)
1134 {
1135 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1136
1137 if (class_interface_decl)
1138 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001139 class_interface_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001140 class_interface_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001141 return true;
1142 }
1143 }
1144 }
1145 break;
1146
1147 case clang::Type::Typedef:
1148 return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
Sean Callanan912855f2011-08-11 23:56:13 +00001149
1150 case clang::Type::Elaborated:
1151 return ClangASTContext::SetHasExternalStorage (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001152
1153 default:
1154 break;
1155 }
1156 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157}
1158
Greg Claytona3c444a2010-10-01 23:13:49 +00001159static bool
1160IsOperator (const char *name, OverloadedOperatorKind &op_kind)
1161{
1162 if (name == NULL || name[0] == '\0')
1163 return false;
1164
Sean Callanana43f20d2010-12-10 19:51:54 +00001165#define OPERATOR_PREFIX "operator"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001166#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
Sean Callananbfeff8c2010-12-10 02:15:55 +00001167
1168 const char *post_op_name = NULL;
1169
Sean Callanana43f20d2010-12-10 19:51:54 +00001170 bool no_space = true;
Sean Callananbfeff8c2010-12-10 02:15:55 +00001171
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001172 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
Greg Claytona3c444a2010-10-01 23:13:49 +00001173 return false;
1174
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001175 post_op_name = name + OPERATOR_PREFIX_LENGTH;
1176
Sean Callanana43f20d2010-12-10 19:51:54 +00001177 if (post_op_name[0] == ' ')
1178 {
1179 post_op_name++;
1180 no_space = false;
1181 }
1182
1183#undef OPERATOR_PREFIX
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001184#undef OPERATOR_PREFIX_LENGTH
Sean Callanana43f20d2010-12-10 19:51:54 +00001185
Greg Claytona3c444a2010-10-01 23:13:49 +00001186 // This is an operator, set the overloaded operator kind to invalid
1187 // in case this is a conversion operator...
1188 op_kind = NUM_OVERLOADED_OPERATORS;
1189
1190 switch (post_op_name[0])
1191 {
Sean Callananbfeff8c2010-12-10 02:15:55 +00001192 default:
1193 if (no_space)
1194 return false;
1195 break;
Greg Claytona3c444a2010-10-01 23:13:49 +00001196 case 'n':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001197 if (no_space)
1198 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001199 if (strcmp (post_op_name, "new") == 0)
1200 op_kind = OO_New;
1201 else if (strcmp (post_op_name, "new[]") == 0)
1202 op_kind = OO_Array_New;
1203 break;
1204
1205 case 'd':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001206 if (no_space)
1207 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001208 if (strcmp (post_op_name, "delete") == 0)
1209 op_kind = OO_Delete;
1210 else if (strcmp (post_op_name, "delete[]") == 0)
1211 op_kind = OO_Array_Delete;
1212 break;
1213
1214 case '+':
1215 if (post_op_name[1] == '\0')
1216 op_kind = OO_Plus;
1217 else if (post_op_name[2] == '\0')
1218 {
1219 if (post_op_name[1] == '=')
1220 op_kind = OO_PlusEqual;
1221 else if (post_op_name[1] == '+')
1222 op_kind = OO_PlusPlus;
1223 }
1224 break;
1225
1226 case '-':
1227 if (post_op_name[1] == '\0')
1228 op_kind = OO_Minus;
1229 else if (post_op_name[2] == '\0')
1230 {
1231 switch (post_op_name[1])
1232 {
1233 case '=': op_kind = OO_MinusEqual; break;
1234 case '-': op_kind = OO_MinusMinus; break;
1235 case '>': op_kind = OO_Arrow; break;
1236 }
1237 }
1238 else if (post_op_name[3] == '\0')
1239 {
1240 if (post_op_name[2] == '*')
1241 op_kind = OO_ArrowStar; break;
1242 }
1243 break;
1244
1245 case '*':
1246 if (post_op_name[1] == '\0')
1247 op_kind = OO_Star;
1248 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1249 op_kind = OO_StarEqual;
1250 break;
1251
1252 case '/':
1253 if (post_op_name[1] == '\0')
1254 op_kind = OO_Slash;
1255 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1256 op_kind = OO_SlashEqual;
1257 break;
1258
1259 case '%':
1260 if (post_op_name[1] == '\0')
1261 op_kind = OO_Percent;
1262 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1263 op_kind = OO_PercentEqual;
1264 break;
1265
1266
1267 case '^':
1268 if (post_op_name[1] == '\0')
1269 op_kind = OO_Caret;
1270 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1271 op_kind = OO_CaretEqual;
1272 break;
1273
1274 case '&':
1275 if (post_op_name[1] == '\0')
1276 op_kind = OO_Amp;
1277 else if (post_op_name[2] == '\0')
1278 {
1279 switch (post_op_name[1])
1280 {
1281 case '=': op_kind = OO_AmpEqual; break;
1282 case '&': op_kind = OO_AmpAmp; break;
1283 }
1284 }
1285 break;
1286
1287 case '|':
1288 if (post_op_name[1] == '\0')
1289 op_kind = OO_Pipe;
1290 else if (post_op_name[2] == '\0')
1291 {
1292 switch (post_op_name[1])
1293 {
1294 case '=': op_kind = OO_PipeEqual; break;
1295 case '|': op_kind = OO_PipePipe; break;
1296 }
1297 }
1298 break;
1299
1300 case '~':
1301 if (post_op_name[1] == '\0')
1302 op_kind = OO_Tilde;
1303 break;
1304
1305 case '!':
1306 if (post_op_name[1] == '\0')
1307 op_kind = OO_Exclaim;
1308 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1309 op_kind = OO_ExclaimEqual;
1310 break;
1311
1312 case '=':
1313 if (post_op_name[1] == '\0')
1314 op_kind = OO_Equal;
1315 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1316 op_kind = OO_EqualEqual;
1317 break;
1318
1319 case '<':
1320 if (post_op_name[1] == '\0')
1321 op_kind = OO_Less;
1322 else if (post_op_name[2] == '\0')
1323 {
1324 switch (post_op_name[1])
1325 {
1326 case '<': op_kind = OO_LessLess; break;
1327 case '=': op_kind = OO_LessEqual; break;
1328 }
1329 }
1330 else if (post_op_name[3] == '\0')
1331 {
1332 if (post_op_name[2] == '=')
1333 op_kind = OO_LessLessEqual;
1334 }
1335 break;
1336
1337 case '>':
1338 if (post_op_name[1] == '\0')
1339 op_kind = OO_Greater;
1340 else if (post_op_name[2] == '\0')
1341 {
1342 switch (post_op_name[1])
1343 {
1344 case '>': op_kind = OO_GreaterGreater; break;
1345 case '=': op_kind = OO_GreaterEqual; break;
1346 }
1347 }
1348 else if (post_op_name[1] == '>' &&
1349 post_op_name[2] == '=' &&
1350 post_op_name[3] == '\0')
1351 {
1352 op_kind = OO_GreaterGreaterEqual;
1353 }
1354 break;
1355
1356 case ',':
1357 if (post_op_name[1] == '\0')
1358 op_kind = OO_Comma;
1359 break;
1360
1361 case '(':
1362 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1363 op_kind = OO_Call;
1364 break;
1365
1366 case '[':
1367 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1368 op_kind = OO_Subscript;
1369 break;
1370 }
1371
1372 return true;
1373}
Greg Clayton6beaaa62011-01-17 03:46:26 +00001374
Greg Clayton090d0982011-06-19 03:43:27 +00001375static inline bool
1376check_op_param (bool unary, bool binary, uint32_t num_params)
1377{
1378 // The parameter count doens't include "this"
1379 if (num_params == 0)
1380 return unary;
1381 if (num_params == 1)
1382 return binary;
1383 return false;
1384}
1385
1386bool
1387ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, uint32_t num_params)
1388{
1389#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) case OO_##Name: return check_op_param (Unary, Binary, num_params);
1390 switch (op_kind)
1391 {
1392#include "clang/Basic/OperatorKinds.def"
1393 default: break;
1394 }
1395 return false;
1396}
1397
Greg Claytona51ed9b2010-09-23 01:09:21 +00001398CXXMethodDecl *
Sean Callanan61da09b2010-09-17 02:58:26 +00001399ClangASTContext::AddMethodToCXXRecordType
1400(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001401 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001402 clang_type_t record_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001403 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001404 clang_type_t method_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001405 lldb::AccessType access,
Greg Clayton0fffff52010-09-24 05:15:53 +00001406 bool is_virtual,
1407 bool is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00001408 bool is_inline,
1409 bool is_explicit
Greg Claytona51ed9b2010-09-23 01:09:21 +00001410)
Sean Callanan61da09b2010-09-17 02:58:26 +00001411{
Sean Callananfc55f5d2010-09-21 00:44:12 +00001412 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chend440bcc2010-09-28 16:10:54 +00001413 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001414
Greg Clayton6beaaa62011-01-17 03:46:26 +00001415 assert(ast);
Sean Callanan61da09b2010-09-17 02:58:26 +00001416
Greg Clayton6beaaa62011-01-17 03:46:26 +00001417 IdentifierTable *identifier_table = &ast->Idents;
Sean Callanan61da09b2010-09-17 02:58:26 +00001418
1419 assert(identifier_table);
1420
Sean Callananfc55f5d2010-09-21 00:44:12 +00001421 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001422
Greg Clayton6beaaa62011-01-17 03:46:26 +00001423 CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
Sean Callanan61da09b2010-09-17 02:58:26 +00001424
Greg Clayton0fffff52010-09-24 05:15:53 +00001425 if (cxx_record_decl == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001426 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001427
Greg Clayton0fffff52010-09-24 05:15:53 +00001428 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001429
Greg Claytonf51de672010-10-01 02:31:07 +00001430 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001431
Greg Claytonf51de672010-10-01 02:31:07 +00001432 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton878eaf12010-10-01 03:45:20 +00001433
Greg Clayton878eaf12010-10-01 03:45:20 +00001434 const bool is_implicitly_declared = false;
Greg Claytonf51de672010-10-01 02:31:07 +00001435
Sean Callanan78e37602011-01-27 04:42:51 +00001436 const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton878eaf12010-10-01 03:45:20 +00001437
Greg Clayton90a2acd2010-10-02 01:40:05 +00001438 if (function_Type == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001439 return NULL;
1440
Sean Callanan78e37602011-01-27 04:42:51 +00001441 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton878eaf12010-10-01 03:45:20 +00001442
1443 if (!method_function_prototype)
1444 return NULL;
1445
1446 unsigned int num_params = method_function_prototype->getNumArgs();
1447
1448 if (name[0] == '~')
Greg Claytonf51de672010-10-01 02:31:07 +00001449 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001450 cxx_method_decl = CXXDestructorDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001451 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001452 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001453 DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001454 method_qual_type,
Sean Callanan31e851c2010-10-29 18:38:40 +00001455 NULL,
Greg Clayton878eaf12010-10-01 03:45:20 +00001456 is_inline,
1457 is_implicitly_declared);
1458 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001459 else if (decl_name == cxx_record_decl->getDeclName())
Greg Clayton878eaf12010-10-01 03:45:20 +00001460 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001461 cxx_method_decl = CXXConstructorDecl::Create (*ast,
Greg Claytonf51de672010-10-01 02:31:07 +00001462 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001463 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001464 DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Claytonf51de672010-10-01 02:31:07 +00001465 method_qual_type,
1466 NULL, // TypeSourceInfo *
1467 is_explicit,
1468 is_inline,
1469 is_implicitly_declared);
1470 }
1471 else
Greg Clayton878eaf12010-10-01 03:45:20 +00001472 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001473
1474 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1475 if (IsOperator (name, op_kind))
Greg Clayton878eaf12010-10-01 03:45:20 +00001476 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001477 if (op_kind != NUM_OVERLOADED_OPERATORS)
1478 {
Greg Clayton090d0982011-06-19 03:43:27 +00001479 // Check the number of operator parameters. Sometimes we have
1480 // seen bad DWARF that doesn't correctly describe operators and
1481 // if we try to create a methed and add it to the class, clang
1482 // will assert and crash, so we need to make sure things are
1483 // acceptable.
1484 if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
1485 return NULL;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001486 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001487 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001488 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001489 DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001490 method_qual_type,
1491 NULL, // TypeSourceInfo *
Greg Claytona3c444a2010-10-01 23:13:49 +00001492 is_static,
1493 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001494 is_inline,
1495 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001496 }
1497 else if (num_params == 0)
1498 {
1499 // Conversion operators don't take params...
Greg Clayton6beaaa62011-01-17 03:46:26 +00001500 cxx_method_decl = CXXConversionDecl::Create (*ast,
Greg Claytona3c444a2010-10-01 23:13:49 +00001501 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001502 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001503 DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytona3c444a2010-10-01 23:13:49 +00001504 method_qual_type,
1505 NULL, // TypeSourceInfo *
1506 is_inline,
Sean Callananfb0b7582011-03-15 00:17:19 +00001507 is_explicit,
1508 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001509 }
Greg Clayton878eaf12010-10-01 03:45:20 +00001510 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001511
1512 if (cxx_method_decl == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001513 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001514 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001515 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001516 SourceLocation(),
Greg Claytona3c444a2010-10-01 23:13:49 +00001517 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001518 method_qual_type,
1519 NULL, // TypeSourceInfo *
1520 is_static,
1521 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001522 is_inline,
1523 SourceLocation());
Greg Clayton878eaf12010-10-01 03:45:20 +00001524 }
Greg Claytonf51de672010-10-01 02:31:07 +00001525 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001526
Greg Clayton1be10fc2010-09-29 01:12:09 +00001527 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton0fffff52010-09-24 05:15:53 +00001528
1529 cxx_method_decl->setAccess (access_specifier);
1530 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001531
Sean Callananfc55f5d2010-09-21 00:44:12 +00001532 // Populate the method decl with parameter decls
Sean Callananfc55f5d2010-09-21 00:44:12 +00001533
Charles Davis8c444c42011-05-19 23:33:46 +00001534 llvm::SmallVector<ParmVarDecl *, 12> params;
Sean Callananfc55f5d2010-09-21 00:44:12 +00001535
1536 for (int param_index = 0;
1537 param_index < num_params;
1538 ++param_index)
1539 {
Charles Davis8c444c42011-05-19 23:33:46 +00001540 params.push_back (ParmVarDecl::Create (*ast,
1541 cxx_method_decl,
1542 SourceLocation(),
1543 SourceLocation(),
1544 NULL, // anonymous
1545 method_function_prototype->getArgType(param_index),
1546 NULL,
1547 SC_None,
1548 SC_None,
1549 NULL));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001550 }
1551
Charles Davis8c444c42011-05-19 23:33:46 +00001552 cxx_method_decl->setParams (params.data(), num_params);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001553
Greg Clayton0fffff52010-09-24 05:15:53 +00001554 cxx_record_decl->addDecl (cxx_method_decl);
Greg Claytonc432c192011-01-20 04:18:48 +00001555
1556// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic());
1557// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate());
1558// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD());
1559// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty());
1560// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract());
1561// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor());
1562// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
1563// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
1564// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor());
Greg Claytona51ed9b2010-09-23 01:09:21 +00001565 return cxx_method_decl;
Sean Callanan61da09b2010-09-17 02:58:26 +00001566}
1567
1568bool
Greg Clayton8cf05932010-07-22 18:30:50 +00001569ClangASTContext::AddFieldToRecordType
1570(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001571 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001572 clang_type_t record_clang_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001573 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001574 clang_type_t field_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001575 AccessType access,
1576 uint32_t bitfield_bit_size
1577)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001578{
1579 if (record_clang_type == NULL || field_type == NULL)
1580 return false;
1581
Greg Clayton6beaaa62011-01-17 03:46:26 +00001582 IdentifierTable *identifier_table = &ast->Idents;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001583
Greg Clayton6beaaa62011-01-17 03:46:26 +00001584 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001585 assert (identifier_table != NULL);
1586
1587 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1588
Sean Callanan78e37602011-01-27 04:42:51 +00001589 const clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001590 if (clang_type)
1591 {
1592 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1593
1594 if (record_type)
1595 {
1596 RecordDecl *record_decl = record_type->getDecl();
1597
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001598 clang::Expr *bit_width = NULL;
1599 if (bitfield_bit_size != 0)
1600 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001601 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1602 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001603 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001604 FieldDecl *field = FieldDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001605 record_decl,
1606 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001607 SourceLocation(),
Greg Clayton8cf05932010-07-22 18:30:50 +00001608 name ? &identifier_table->get(name) : NULL, // Identifier
1609 QualType::getFromOpaquePtr(field_type), // Field type
Sean Callanancc427fa2011-07-30 02:42:06 +00001610 NULL, // TInfo *
Greg Clayton8cf05932010-07-22 18:30:50 +00001611 bit_width, // BitWidth
Sean Callanancc427fa2011-07-30 02:42:06 +00001612 false, // Mutable
1613 false); // HasInit
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001614
Greg Clayton8cf05932010-07-22 18:30:50 +00001615 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001616
1617 if (field)
1618 {
1619 record_decl->addDecl(field);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001620 }
1621 }
Greg Clayton9e409562010-07-28 02:04:09 +00001622 else
1623 {
Sean Callanan78e37602011-01-27 04:42:51 +00001624 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001625 if (objc_class_type)
1626 {
Greg Clayton0fffff52010-09-24 05:15:53 +00001627 bool is_synthesized = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001628 ClangASTContext::AddObjCClassIVar (ast,
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001629 record_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001630 name,
1631 field_type,
1632 access,
1633 bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001634 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001635 }
1636 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001637 }
1638 return false;
1639}
1640
1641bool
1642ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1643{
1644 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1645}
1646
1647bool
1648ClangASTContext::FieldIsBitfield
1649(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001650 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651 FieldDecl* field,
1652 uint32_t& bitfield_bit_size
1653)
1654{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001655 if (ast == NULL || field == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001656 return false;
1657
1658 if (field->isBitField())
1659 {
1660 Expr* bit_width_expr = field->getBitWidth();
1661 if (bit_width_expr)
1662 {
1663 llvm::APSInt bit_width_apsint;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001664 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001665 {
1666 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1667 return true;
1668 }
1669 }
1670 }
1671 return false;
1672}
1673
1674bool
1675ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1676{
1677 if (record_decl == NULL)
1678 return false;
1679
1680 if (!record_decl->field_empty())
1681 return true;
1682
1683 // No fields, lets check this is a CXX record and check the base classes
1684 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1685 if (cxx_record_decl)
1686 {
1687 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1688 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1689 base_class != base_class_end;
1690 ++base_class)
1691 {
1692 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1693 if (RecordHasFields(base_class_decl))
1694 return true;
1695 }
1696 }
1697 return false;
1698}
1699
1700void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001701ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001702{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001703 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001704 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001705 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1706
Sean Callanan78e37602011-01-27 04:42:51 +00001707 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001708 if (record_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001709 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001710 RecordDecl *record_decl = record_type->getDecl();
1711 if (record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001712 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001713 uint32_t field_idx;
1714 RecordDecl::field_iterator field, field_end;
1715 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1716 field != field_end;
1717 ++field, ++field_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001718 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001719 // If no accessibility was assigned, assign the correct one
1720 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1721 field->setAccess ((AccessSpecifier)default_accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001722 }
1723 }
1724 }
1725 }
1726}
1727
1728#pragma mark C++ Base Classes
1729
1730CXXBaseSpecifier *
Greg Clayton1be10fc2010-09-29 01:12:09 +00001731ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001732{
1733 if (base_class_type)
Greg Claytone6371122010-07-30 20:30:44 +00001734 return new CXXBaseSpecifier (SourceRange(),
1735 is_virtual,
1736 base_of_class,
1737 ConvertAccessTypeToAccessSpecifier (access),
Sean Callanan2c777c42011-01-18 23:32:05 +00001738 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
1739 SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001740 return NULL;
1741}
1742
Greg Clayton0b42ac32010-07-02 01:29:13 +00001743void
1744ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1745{
1746 for (unsigned i=0; i<num_base_classes; ++i)
1747 {
1748 delete base_classes[i];
1749 base_classes[i] = NULL;
1750 }
1751}
1752
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001753bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001754ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001755{
1756 if (class_clang_type)
1757 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001758 CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
1759 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001760 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001761 cxx_record_decl->setBases(base_classes, num_base_classes);
1762 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001763 }
1764 }
1765 return false;
1766}
Greg Clayton8cf05932010-07-22 18:30:50 +00001767#pragma mark Objective C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001768
Greg Clayton1be10fc2010-09-29 01:12:09 +00001769clang_type_t
Greg Clayton8cf05932010-07-22 18:30:50 +00001770ClangASTContext::CreateObjCClass
1771(
1772 const char *name,
1773 DeclContext *decl_ctx,
1774 bool isForwardDecl,
1775 bool isInternal
1776)
1777{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001778 ASTContext *ast = getASTContext();
1779 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001780 assert (name && name[0]);
1781 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001782 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001783
1784 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1785 // we will need to update this code. I was told to currently always use
1786 // the CXXRecordDecl class since we often don't know from debug information
1787 // if something is struct or a class, so we default to always use the more
1788 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001789 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001790 decl_ctx,
1791 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001792 &ast->Idents.get(name),
Greg Clayton8cf05932010-07-22 18:30:50 +00001793 SourceLocation(),
1794 isForwardDecl,
1795 isInternal);
Greg Clayton9e409562010-07-28 02:04:09 +00001796
Greg Clayton6beaaa62011-01-17 03:46:26 +00001797 return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001798}
1799
1800bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001801ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton8cf05932010-07-22 18:30:50 +00001802{
1803 if (class_opaque_type && super_opaque_type)
1804 {
1805 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1806 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
Sean Callanan78e37602011-01-27 04:42:51 +00001807 const clang::Type *class_type = class_qual_type.getTypePtr();
1808 const clang::Type *super_type = super_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001809 if (class_type && super_type)
1810 {
Sean Callanan78e37602011-01-27 04:42:51 +00001811 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1812 const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001813 if (objc_class_type && objc_super_type)
1814 {
1815 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1816 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1817 if (class_interface_decl && super_interface_decl)
1818 {
1819 class_interface_decl->setSuperClass(super_interface_decl);
1820 return true;
1821 }
1822 }
1823 }
1824 }
1825 return false;
1826}
1827
1828
1829bool
1830ClangASTContext::AddObjCClassIVar
1831(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001832 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001833 clang_type_t class_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001834 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001835 clang_type_t ivar_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001836 AccessType access,
1837 uint32_t bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001838 bool is_synthesized
Greg Clayton8cf05932010-07-22 18:30:50 +00001839)
1840{
1841 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1842 return false;
1843
Greg Clayton6beaaa62011-01-17 03:46:26 +00001844 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton8cf05932010-07-22 18:30:50 +00001845
Greg Clayton6beaaa62011-01-17 03:46:26 +00001846 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001847 assert (identifier_table != NULL);
1848
1849 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1850
Sean Callanan78e37602011-01-27 04:42:51 +00001851 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001852 if (class_type)
1853 {
Sean Callanan78e37602011-01-27 04:42:51 +00001854 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001855
1856 if (objc_class_type)
1857 {
1858 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1859
1860 if (class_interface_decl)
1861 {
1862 clang::Expr *bit_width = NULL;
1863 if (bitfield_bit_size != 0)
1864 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001865 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1866 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Greg Clayton8cf05932010-07-22 18:30:50 +00001867 }
1868
Greg Clayton6beaaa62011-01-17 03:46:26 +00001869 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast,
Greg Clayton9e409562010-07-28 02:04:09 +00001870 class_interface_decl,
1871 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001872 SourceLocation(),
Greg Clayton9e409562010-07-28 02:04:09 +00001873 &identifier_table->get(name), // Identifier
1874 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1875 NULL, // TypeSourceInfo *
1876 ConvertAccessTypeToObjCIvarAccessControl (access),
1877 bit_width,
Greg Clayton0fffff52010-09-24 05:15:53 +00001878 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001879
1880 if (field)
1881 {
1882 class_interface_decl->addDecl(field);
1883 return true;
1884 }
Greg Clayton8cf05932010-07-22 18:30:50 +00001885 }
1886 }
1887 }
1888 return false;
1889}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001890
Greg Clayton9e409562010-07-28 02:04:09 +00001891
1892bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001893ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9e409562010-07-28 02:04:09 +00001894{
1895 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1896
Sean Callanan78e37602011-01-27 04:42:51 +00001897 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton9e409562010-07-28 02:04:09 +00001898 if (class_type)
1899 {
Sean Callanan78e37602011-01-27 04:42:51 +00001900 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001901
1902 if (objc_class_type)
1903 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1904 }
1905 return false;
1906}
1907
1908bool
1909ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1910{
1911 while (class_interface_decl)
1912 {
1913 if (class_interface_decl->ivar_size() > 0)
1914 return true;
1915
1916 if (check_superclass)
1917 class_interface_decl = class_interface_decl->getSuperClass();
1918 else
1919 break;
1920 }
1921 return false;
1922}
Greg Clayton0fffff52010-09-24 05:15:53 +00001923
Greg Clayton1be10fc2010-09-29 01:12:09 +00001924ObjCMethodDecl *
Greg Clayton0fffff52010-09-24 05:15:53 +00001925ClangASTContext::AddMethodToObjCObjectType
1926(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001927 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001928 clang_type_t class_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001929 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton1be10fc2010-09-29 01:12:09 +00001930 clang_type_t method_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001931 lldb::AccessType access
1932)
1933{
1934 if (class_opaque_type == NULL || method_opaque_type == NULL)
1935 return NULL;
1936
Greg Clayton6beaaa62011-01-17 03:46:26 +00001937 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton0fffff52010-09-24 05:15:53 +00001938
Greg Clayton6beaaa62011-01-17 03:46:26 +00001939 assert (ast != NULL);
Greg Clayton0fffff52010-09-24 05:15:53 +00001940 assert (identifier_table != NULL);
1941
1942 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1943
Sean Callanan78e37602011-01-27 04:42:51 +00001944 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton0fffff52010-09-24 05:15:53 +00001945 if (class_type == NULL)
1946 return NULL;
1947
Sean Callanan78e37602011-01-27 04:42:51 +00001948 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton0fffff52010-09-24 05:15:53 +00001949
1950 if (objc_class_type == NULL)
1951 return NULL;
1952
1953 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1954
1955 if (class_interface_decl == NULL)
1956 return NULL;
Greg Clayton9e409562010-07-28 02:04:09 +00001957
Greg Clayton0fffff52010-09-24 05:15:53 +00001958 const char *selector_start = ::strchr (name, ' ');
1959 if (selector_start == NULL)
1960 return NULL;
1961
1962 selector_start++;
1963 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1964 return NULL;
1965 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1966
Greg Clayton450e3f32010-10-12 02:24:53 +00001967 size_t len = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +00001968 const char *start;
Greg Clayton450e3f32010-10-12 02:24:53 +00001969 //printf ("name = '%s'\n", name);
1970
1971 unsigned num_selectors_with_args = 0;
1972 for (start = selector_start;
Greg Clayton0fffff52010-09-24 05:15:53 +00001973 start && *start != '\0' && *start != ']';
Greg Clayton450e3f32010-10-12 02:24:53 +00001974 start += len)
Greg Clayton0fffff52010-09-24 05:15:53 +00001975 {
Greg Clayton450e3f32010-10-12 02:24:53 +00001976 len = ::strcspn(start, ":]");
Greg Clayton90f90cd2010-10-27 04:01:14 +00001977 bool has_arg = (start[len] == ':');
1978 if (has_arg)
Greg Clayton450e3f32010-10-12 02:24:53 +00001979 ++num_selectors_with_args;
Greg Clayton0fffff52010-09-24 05:15:53 +00001980 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton90f90cd2010-10-27 04:01:14 +00001981 if (has_arg)
1982 len += 1;
Greg Clayton0fffff52010-09-24 05:15:53 +00001983 }
1984
1985
1986 if (selector_idents.size() == 0)
1987 return 0;
1988
Greg Clayton6beaaa62011-01-17 03:46:26 +00001989 clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton0fffff52010-09-24 05:15:53 +00001990 selector_idents.data());
1991
1992 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1993
1994 // Populate the method decl with parameter decls
Sean Callanan78e37602011-01-27 04:42:51 +00001995 const clang::Type *method_type(method_qual_type.getTypePtr());
Greg Clayton0fffff52010-09-24 05:15:53 +00001996
1997 if (method_type == NULL)
1998 return NULL;
1999
Sean Callanan78e37602011-01-27 04:42:51 +00002000 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00002001
2002 if (!method_function_prototype)
2003 return NULL;
2004
2005
2006 bool is_variadic = false;
2007 bool is_synthesized = false;
2008 bool is_defined = false;
2009 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
2010
2011 const unsigned num_args = method_function_prototype->getNumArgs();
2012
Greg Clayton6beaaa62011-01-17 03:46:26 +00002013 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00002014 SourceLocation(), // beginLoc,
2015 SourceLocation(), // endLoc,
2016 method_selector,
2017 method_function_prototype->getResultType(),
2018 NULL, // TypeSourceInfo *ResultTInfo,
2019 GetDeclContextForType (class_opaque_type),
2020 name[0] == '-',
2021 is_variadic,
2022 is_synthesized,
2023 is_defined,
2024 imp_control,
2025 num_args);
2026
2027
2028 if (objc_method_decl == NULL)
2029 return NULL;
2030
2031 if (num_args > 0)
2032 {
2033 llvm::SmallVector<ParmVarDecl *, 12> params;
2034
2035 for (int param_index = 0; param_index < num_args; ++param_index)
2036 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002037 params.push_back (ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00002038 objc_method_decl,
2039 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00002040 SourceLocation(),
Greg Clayton0fffff52010-09-24 05:15:53 +00002041 NULL, // anonymous
2042 method_function_prototype->getArgType(param_index),
2043 NULL,
2044 SC_Auto,
2045 SC_Auto,
2046 NULL));
2047 }
2048
Greg Clayton6beaaa62011-01-17 03:46:26 +00002049 objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args);
Greg Clayton0fffff52010-09-24 05:15:53 +00002050 }
2051
2052 class_interface_decl->addDecl (objc_method_decl);
2053
2054
2055 return objc_method_decl;
2056}
2057
2058
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002059uint32_t
Greg Clayton73b472d2010-10-27 03:32:59 +00002060ClangASTContext::GetTypeInfo
2061(
2062 clang_type_t clang_type,
Greg Clayton6beaaa62011-01-17 03:46:26 +00002063 clang::ASTContext *ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002064 clang_type_t *pointee_or_element_clang_type
2065)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002066{
2067 if (clang_type == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00002068 return 0;
2069
2070 if (pointee_or_element_clang_type)
2071 *pointee_or_element_clang_type = NULL;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002072
2073 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2074
2075 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2076 switch (type_class)
2077 {
Sean Callanana2424172010-10-25 00:29:48 +00002078 case clang::Type::Builtin:
2079 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2080 {
Sean Callanana2424172010-10-25 00:29:48 +00002081 case clang::BuiltinType::ObjCId:
2082 case clang::BuiltinType::ObjCClass:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002083 if (ast && pointee_or_element_clang_type)
2084 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanana2424172010-10-25 00:29:48 +00002085 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002086 break;
2087 case clang::BuiltinType::Bool:
2088 case clang::BuiltinType::Char_U:
2089 case clang::BuiltinType::UChar:
2090 case clang::BuiltinType::WChar_U:
2091 case clang::BuiltinType::Char16:
2092 case clang::BuiltinType::Char32:
2093 case clang::BuiltinType::UShort:
2094 case clang::BuiltinType::UInt:
2095 case clang::BuiltinType::ULong:
2096 case clang::BuiltinType::ULongLong:
2097 case clang::BuiltinType::UInt128:
2098 case clang::BuiltinType::Char_S:
2099 case clang::BuiltinType::SChar:
2100 case clang::BuiltinType::WChar_S:
2101 case clang::BuiltinType::Short:
2102 case clang::BuiltinType::Int:
2103 case clang::BuiltinType::Long:
2104 case clang::BuiltinType::LongLong:
2105 case clang::BuiltinType::Int128:
2106 case clang::BuiltinType::Float:
2107 case clang::BuiltinType::Double:
2108 case clang::BuiltinType::LongDouble:
2109 return eTypeIsBuiltIn | eTypeHasValue | eTypeIsScalar;
Greg Clayton73b472d2010-10-27 03:32:59 +00002110 default:
2111 break;
Sean Callanana2424172010-10-25 00:29:48 +00002112 }
2113 return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002114
2115 case clang::Type::BlockPointer:
2116 if (pointee_or_element_clang_type)
2117 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2118 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
2119
Greg Clayton49462ea2011-01-15 02:52:14 +00002120 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002121
2122 case clang::Type::ConstantArray:
2123 case clang::Type::DependentSizedArray:
2124 case clang::Type::IncompleteArray:
2125 case clang::Type::VariableArray:
2126 if (pointee_or_element_clang_type)
2127 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
2128 return eTypeHasChildren | eTypeIsArray;
2129
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002130 case clang::Type::DependentName: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002131 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
2132 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
2133 case clang::Type::Decltype: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002134
2135 case clang::Type::Enum:
2136 if (pointee_or_element_clang_type)
2137 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
2138 return eTypeIsEnumeration | eTypeHasValue;
2139
Sean Callanan912855f2011-08-11 23:56:13 +00002140 case clang::Type::Elaborated:
2141 return ClangASTContext::GetTypeInfo (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2142 ast,
2143 pointee_or_element_clang_type);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002144 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
2145 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
2146 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002147 case clang::Type::InjectedClassName: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002148
2149 case clang::Type::LValueReference:
2150 case clang::Type::RValueReference:
2151 if (pointee_or_element_clang_type)
2152 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
2153 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
2154
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002155 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002156
2157 case clang::Type::ObjCObjectPointer:
2158 if (pointee_or_element_clang_type)
2159 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2160 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
2161
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002162 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2163 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Clayton73b472d2010-10-27 03:32:59 +00002164
2165 case clang::Type::Pointer:
2166 if (pointee_or_element_clang_type)
2167 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2168 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
2169
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002170 case clang::Type::Record:
2171 if (qual_type->getAsCXXRecordDecl())
2172 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
2173 else
2174 return eTypeHasChildren | eTypeIsStructUnion;
2175 break;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002176 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
2177 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
2178 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Clayton73b472d2010-10-27 03:32:59 +00002179
2180 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002181 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00002182 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002183 pointee_or_element_clang_type);
2184
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002185 case clang::Type::TypeOfExpr: return 0;
2186 case clang::Type::TypeOf: return 0;
2187 case clang::Type::UnresolvedUsing: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002188 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
2189 default: return 0;
2190 }
2191 return 0;
2192}
2193
Greg Clayton9e409562010-07-28 02:04:09 +00002194
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002195#pragma mark Aggregate Types
2196
2197bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00002198ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002199{
2200 if (clang_type == NULL)
2201 return false;
2202
2203 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2204
Greg Clayton737b9322010-09-13 03:32:57 +00002205 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2206 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002207 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002208 case clang::Type::IncompleteArray:
2209 case clang::Type::VariableArray:
2210 case clang::Type::ConstantArray:
2211 case clang::Type::ExtVector:
2212 case clang::Type::Vector:
2213 case clang::Type::Record:
Greg Clayton9e409562010-07-28 02:04:09 +00002214 case clang::Type::ObjCObject:
2215 case clang::Type::ObjCInterface:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002216 return true;
Sean Callanan912855f2011-08-11 23:56:13 +00002217 case clang::Type::Elaborated:
2218 return ClangASTContext::IsAggregateType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Greg Claytone1a916a2010-07-21 22:12:05 +00002219 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002220 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002221
2222 default:
2223 break;
2224 }
2225 // The clang type does have a value
2226 return false;
2227}
2228
2229uint32_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00002230ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002231{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002232 if (clang_type == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002233 return 0;
2234
2235 uint32_t num_children = 0;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002236 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00002237 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2238 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002239 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002240 case clang::Type::Builtin:
2241 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2242 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002243 case clang::BuiltinType::ObjCId: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002244 case clang::BuiltinType::ObjCClass: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002245 num_children = 1;
Greg Clayton73b472d2010-10-27 03:32:59 +00002246 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002247
2248 default:
2249 break;
2250 }
2251 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002252
Greg Clayton49462ea2011-01-15 02:52:14 +00002253 case clang::Type::Complex: return 0;
Greg Clayton54979cd2010-12-15 05:08:08 +00002254
Greg Claytone1a916a2010-07-21 22:12:05 +00002255 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002256 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002257 {
2258 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2259 const RecordDecl *record_decl = record_type->getDecl();
2260 assert(record_decl);
2261 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2262 if (cxx_record_decl)
2263 {
2264 if (omit_empty_base_classes)
2265 {
2266 // Check each base classes to see if it or any of its
2267 // base classes contain any fields. This can help
2268 // limit the noise in variable views by not having to
2269 // show base classes that contain no members.
2270 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2271 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2272 base_class != base_class_end;
2273 ++base_class)
2274 {
2275 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2276
2277 // Skip empty base classes
2278 if (RecordHasFields(base_class_decl) == false)
2279 continue;
2280
2281 num_children++;
2282 }
2283 }
2284 else
2285 {
2286 // Include all base classes
2287 num_children += cxx_record_decl->getNumBases();
2288 }
2289
2290 }
2291 RecordDecl::field_iterator field, field_end;
2292 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2293 ++num_children;
2294 }
2295 break;
2296
Greg Clayton9e409562010-07-28 02:04:09 +00002297 case clang::Type::ObjCObject:
2298 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002299 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002300 {
Sean Callanan78e37602011-01-27 04:42:51 +00002301 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002302 assert (objc_class_type);
2303 if (objc_class_type)
2304 {
2305 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2306
2307 if (class_interface_decl)
2308 {
2309
2310 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2311 if (superclass_interface_decl)
2312 {
2313 if (omit_empty_base_classes)
2314 {
2315 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2316 ++num_children;
2317 }
2318 else
2319 ++num_children;
2320 }
2321
2322 num_children += class_interface_decl->ivar_size();
2323 }
2324 }
2325 }
2326 break;
2327
2328 case clang::Type::ObjCObjectPointer:
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002329 {
Sean Callanan78e37602011-01-27 04:42:51 +00002330 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002331 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002332 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2333 pointee_type.getAsOpaquePtr(),
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002334 omit_empty_base_classes);
2335 // If this type points to a simple type, then it has 1 child
2336 if (num_pointee_children == 0)
2337 num_children = 1;
2338 else
2339 num_children = num_pointee_children;
2340 }
2341 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002342
Greg Claytone1a916a2010-07-21 22:12:05 +00002343 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002344 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2345 break;
2346
Greg Claytone1a916a2010-07-21 22:12:05 +00002347 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002348 {
Sean Callanan78e37602011-01-27 04:42:51 +00002349 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002350 QualType pointee_type (pointer_type->getPointeeType());
Greg Clayton6beaaa62011-01-17 03:46:26 +00002351 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2352 pointee_type.getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00002353 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002354 if (num_pointee_children == 0)
Greg Clayton54979cd2010-12-15 05:08:08 +00002355 {
2356 // We have a pointer to a pointee type that claims it has no children.
2357 // We will want to look at
2358 num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
2359 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002360 else
2361 num_children = num_pointee_children;
2362 }
2363 break;
2364
Greg Clayton73b472d2010-10-27 03:32:59 +00002365 case clang::Type::LValueReference:
2366 case clang::Type::RValueReference:
2367 {
Sean Callanan78e37602011-01-27 04:42:51 +00002368 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002369 QualType pointee_type = reference_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002370 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2371 pointee_type.getAsOpaquePtr(),
Greg Clayton73b472d2010-10-27 03:32:59 +00002372 omit_empty_base_classes);
2373 // If this type points to a simple type, then it has 1 child
2374 if (num_pointee_children == 0)
2375 num_children = 1;
2376 else
2377 num_children = num_pointee_children;
2378 }
2379 break;
2380
2381
Greg Claytone1a916a2010-07-21 22:12:05 +00002382 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002383 num_children = ClangASTContext::GetNumChildren (ast,
2384 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2385 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002386 break;
Sean Callanan912855f2011-08-11 23:56:13 +00002387
2388 case clang::Type::Elaborated:
2389 num_children = ClangASTContext::GetNumChildren (ast,
2390 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2391 omit_empty_base_classes);
2392 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002393
2394 default:
2395 break;
2396 }
2397 return num_children;
2398}
2399
Greg Claytonbf2331c2011-09-09 23:04:00 +00002400uint32_t
2401ClangASTContext::GetNumDirectBaseClasses (clang::ASTContext *ast, clang_type_t clang_type)
2402{
2403 if (clang_type == NULL)
2404 return 0;
2405
2406 uint32_t count = 0;
2407 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2408 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2409 switch (type_class)
2410 {
2411 case clang::Type::Record:
2412 if (GetCompleteQualType (ast, qual_type))
2413 {
2414 const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2415 if (cxx_record_decl)
2416 count = cxx_record_decl->getNumBases();
2417 }
2418 break;
2419
2420 case clang::Type::ObjCObject:
2421 case clang::Type::ObjCInterface:
2422 if (GetCompleteQualType (ast, qual_type))
2423 {
2424 const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
2425 if (objc_class_type)
2426 {
2427 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2428
2429 if (class_interface_decl && class_interface_decl->getSuperClass())
2430 count = 1;
2431 }
2432 }
2433 break;
2434
2435
2436 case clang::Type::Typedef:
2437 count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2438 break;
2439
2440 case clang::Type::Elaborated:
2441 count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2442 break;
2443
2444 default:
2445 break;
2446 }
2447 return count;
2448}
2449
2450uint32_t
2451ClangASTContext::GetNumVirtualBaseClasses (clang::ASTContext *ast,
2452 clang_type_t clang_type)
2453{
2454 if (clang_type == NULL)
2455 return 0;
2456
2457 uint32_t count = 0;
2458 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2459 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2460 switch (type_class)
2461 {
2462 case clang::Type::Record:
2463 if (GetCompleteQualType (ast, qual_type))
2464 {
2465 const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2466 if (cxx_record_decl)
2467 count = cxx_record_decl->getNumVBases();
2468 }
2469 break;
2470
2471 case clang::Type::Typedef:
2472 count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2473 break;
2474
2475 case clang::Type::Elaborated:
2476 count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2477 break;
2478
2479 default:
2480 break;
2481 }
2482 return count;
2483}
2484
2485uint32_t
2486ClangASTContext::GetNumFields (clang::ASTContext *ast, clang_type_t clang_type)
2487{
2488 if (clang_type == NULL)
2489 return 0;
2490
2491 uint32_t count = 0;
2492 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2493 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2494 switch (type_class)
2495 {
2496 case clang::Type::Record:
2497 if (GetCompleteQualType (ast, qual_type))
2498 {
2499 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
2500 if (record_type)
2501 {
2502 RecordDecl *record_decl = record_type->getDecl();
2503 if (record_decl)
2504 {
2505 uint32_t field_idx = 0;
2506 RecordDecl::field_iterator field, field_end;
2507 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2508 ++field_idx;
2509 count = field_idx;
2510 }
2511 }
2512 }
2513 break;
2514
2515 case clang::Type::Typedef:
2516 count = ClangASTContext::GetNumFields (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2517 break;
2518
2519 case clang::Type::Elaborated:
2520 count = ClangASTContext::GetNumFields (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2521 break;
2522
2523 default:
2524 break;
2525 }
2526 return count;
2527}
2528
2529clang_type_t
2530ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast,
2531 clang_type_t clang_type,
2532 uint32_t idx,
2533 uint32_t *byte_offset_ptr)
2534{
2535 if (clang_type == NULL)
2536 return 0;
2537
2538 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2539 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2540 switch (type_class)
2541 {
2542 case clang::Type::Record:
2543 if (GetCompleteQualType (ast, qual_type))
2544 {
2545 const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2546 if (cxx_record_decl)
2547 {
2548 uint32_t curr_idx = 0;
2549 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2550 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2551 base_class != base_class_end;
2552 ++base_class, ++curr_idx)
2553 {
2554 if (curr_idx == idx)
2555 {
2556 if (byte_offset_ptr)
2557 {
2558 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
2559 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2560// if (base_class->isVirtual())
2561// *byte_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
2562// else
2563 *byte_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
2564 }
2565 return base_class->getType().getAsOpaquePtr();
2566 }
2567 }
2568 }
2569 }
2570 break;
2571
2572 case clang::Type::ObjCObject:
2573 case clang::Type::ObjCInterface:
2574 if (idx == 0 && GetCompleteQualType (ast, qual_type))
2575 {
2576 const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
2577 if (objc_class_type)
2578 {
2579 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2580
2581 if (class_interface_decl)
2582 {
2583 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2584 if (superclass_interface_decl)
2585 {
2586 if (byte_offset_ptr)
2587 *byte_offset_ptr = 0;
2588 return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr();
2589 }
2590 }
2591 }
2592 }
2593 break;
2594
2595
2596 case clang::Type::Typedef:
2597 return ClangASTContext::GetDirectBaseClassAtIndex (ast,
2598 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2599 idx,
2600 byte_offset_ptr);
2601
2602 case clang::Type::Elaborated:
2603 return ClangASTContext::GetDirectBaseClassAtIndex (ast,
2604 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2605 idx,
2606 byte_offset_ptr);
2607
2608 default:
2609 break;
2610 }
2611 return NULL;
2612}
2613
2614clang_type_t
2615ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast,
2616 clang_type_t clang_type,
2617 uint32_t idx,
2618 uint32_t *byte_offset_ptr)
2619{
2620 if (clang_type == NULL)
2621 return 0;
2622
2623 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2624 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2625 switch (type_class)
2626 {
2627 case clang::Type::Record:
2628 if (GetCompleteQualType (ast, qual_type))
2629 {
2630 const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2631 if (cxx_record_decl)
2632 {
2633 uint32_t curr_idx = 0;
2634 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2635 for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end();
2636 base_class != base_class_end;
2637 ++base_class, ++curr_idx)
2638 {
2639 if (curr_idx == idx)
2640 {
2641 if (byte_offset_ptr)
2642 {
2643 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
2644 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2645 *byte_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
2646
2647 }
2648 return base_class->getType().getAsOpaquePtr();
2649 }
2650 }
2651 }
2652 }
2653 break;
2654
2655 case clang::Type::Typedef:
2656 return ClangASTContext::GetVirtualBaseClassAtIndex (ast,
2657 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2658 idx,
2659 byte_offset_ptr);
2660
2661 case clang::Type::Elaborated:
2662 return ClangASTContext::GetVirtualBaseClassAtIndex (ast,
2663 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2664 idx,
2665 byte_offset_ptr);
2666
2667 default:
2668 break;
2669 }
2670 return NULL;
2671}
2672
2673clang_type_t
2674ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast,
2675 clang_type_t clang_type,
2676 uint32_t idx,
2677 std::string& name,
2678 uint32_t *byte_offset_ptr)
2679{
2680 if (clang_type == NULL)
2681 return 0;
2682
2683 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2684 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2685 switch (type_class)
2686 {
2687 case clang::Type::Record:
2688 if (GetCompleteQualType (ast, qual_type))
2689 {
2690 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2691 const RecordDecl *record_decl = record_type->getDecl();
2692 uint32_t field_idx = 0;
2693 RecordDecl::field_iterator field, field_end;
2694 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
2695 {
2696 if (idx == field_idx)
2697 {
2698 // Print the member type if requested
2699 // Print the member name and equal sign
2700 name.assign(field->getNameAsString());
2701
2702 // Figure out the type byte size (field_type_info.first) and
2703 // alignment (field_type_info.second) from the AST context.
2704 if (byte_offset_ptr)
2705 {
2706 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
2707 *byte_offset_ptr = (record_layout.getFieldOffset (field_idx) + 7) / 8;
2708 }
2709
2710 return field->getType().getAsOpaquePtr();
2711 }
2712 }
2713 }
2714 break;
2715
2716 case clang::Type::ObjCObject:
2717 case clang::Type::ObjCInterface:
2718 if (GetCompleteQualType (ast, qual_type))
2719 {
2720 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2721 assert (objc_class_type);
2722 if (objc_class_type)
2723 {
2724 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2725
2726 if (class_interface_decl)
2727 {
2728 if (idx < (class_interface_decl->ivar_size()))
2729 {
2730 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2731 uint32_t ivar_idx = 0;
2732
2733 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx)
2734 {
2735 if (ivar_idx == idx)
2736 {
2737 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2738
2739 QualType ivar_qual_type(ivar_decl->getType());
2740
2741 name.assign(ivar_decl->getNameAsString());
2742
2743 if (byte_offset_ptr)
2744 {
2745 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
2746 *byte_offset_ptr = (interface_layout.getFieldOffset (ivar_idx) + 7)/8;
2747 }
2748
2749 return ivar_qual_type.getAsOpaquePtr();
2750 }
2751 }
2752 }
2753 }
2754 }
2755 }
2756 break;
2757
2758
2759 case clang::Type::Typedef:
2760 return ClangASTContext::GetFieldAtIndex (ast,
2761 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2762 idx,
2763 name,
2764 byte_offset_ptr);
2765
2766 case clang::Type::Elaborated:
2767 return ClangASTContext::GetFieldAtIndex (ast,
2768 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2769 idx,
2770 name,
2771 byte_offset_ptr);
2772
2773 default:
2774 break;
2775 }
2776 return NULL;
2777}
2778
2779
Greg Clayton54979cd2010-12-15 05:08:08 +00002780// If a pointer to a pointee type (the clang_type arg) says that it has no
2781// children, then we either need to trust it, or override it and return a
2782// different result. For example, an "int *" has one child that is an integer,
2783// but a function pointer doesn't have any children. Likewise if a Record type
2784// claims it has no children, then there really is nothing to show.
2785uint32_t
2786ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
2787{
2788 if (clang_type == NULL)
2789 return 0;
2790
2791 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2792 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2793 switch (type_class)
2794 {
Greg Clayton97a43712011-01-08 22:26:47 +00002795 case clang::Type::Builtin:
2796 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2797 {
Greg Clayton7260f622011-04-18 08:33:37 +00002798 case clang::BuiltinType::UnknownAny:
Greg Clayton97a43712011-01-08 22:26:47 +00002799 case clang::BuiltinType::Void:
2800 case clang::BuiltinType::NullPtr:
2801 return 0;
2802 case clang::BuiltinType::Bool:
2803 case clang::BuiltinType::Char_U:
2804 case clang::BuiltinType::UChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002805 case clang::BuiltinType::WChar_U:
Greg Clayton97a43712011-01-08 22:26:47 +00002806 case clang::BuiltinType::Char16:
2807 case clang::BuiltinType::Char32:
2808 case clang::BuiltinType::UShort:
2809 case clang::BuiltinType::UInt:
2810 case clang::BuiltinType::ULong:
2811 case clang::BuiltinType::ULongLong:
2812 case clang::BuiltinType::UInt128:
2813 case clang::BuiltinType::Char_S:
2814 case clang::BuiltinType::SChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002815 case clang::BuiltinType::WChar_S:
Greg Clayton97a43712011-01-08 22:26:47 +00002816 case clang::BuiltinType::Short:
2817 case clang::BuiltinType::Int:
2818 case clang::BuiltinType::Long:
2819 case clang::BuiltinType::LongLong:
2820 case clang::BuiltinType::Int128:
2821 case clang::BuiltinType::Float:
2822 case clang::BuiltinType::Double:
2823 case clang::BuiltinType::LongDouble:
2824 case clang::BuiltinType::Dependent:
2825 case clang::BuiltinType::Overload:
Greg Clayton97a43712011-01-08 22:26:47 +00002826 case clang::BuiltinType::ObjCId:
2827 case clang::BuiltinType::ObjCClass:
2828 case clang::BuiltinType::ObjCSel:
Sean Callanand12cf8bb2011-05-15 22:34:38 +00002829 case clang::BuiltinType::BoundMember:
Greg Clayton97a43712011-01-08 22:26:47 +00002830 return 1;
2831 }
2832 break;
2833
Greg Clayton49462ea2011-01-15 02:52:14 +00002834 case clang::Type::Complex: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00002835 case clang::Type::Pointer: return 1;
2836 case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
2837 case clang::Type::LValueReference: return 1;
2838 case clang::Type::RValueReference: return 1;
2839 case clang::Type::MemberPointer: return 0;
2840 case clang::Type::ConstantArray: return 0;
2841 case clang::Type::IncompleteArray: return 0;
2842 case clang::Type::VariableArray: return 0;
2843 case clang::Type::DependentSizedArray: return 0;
2844 case clang::Type::DependentSizedExtVector: return 0;
2845 case clang::Type::Vector: return 0;
2846 case clang::Type::ExtVector: return 0;
2847 case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
2848 case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
2849 case clang::Type::UnresolvedUsing: return 0;
2850 case clang::Type::Paren: return 0;
2851 case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00002852 case clang::Type::Elaborated: return ClangASTContext::GetNumPointeeChildren (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002853 case clang::Type::TypeOfExpr: return 0;
2854 case clang::Type::TypeOf: return 0;
2855 case clang::Type::Decltype: return 0;
2856 case clang::Type::Record: return 0;
2857 case clang::Type::Enum: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00002858 case clang::Type::TemplateTypeParm: return 1;
2859 case clang::Type::SubstTemplateTypeParm: return 1;
2860 case clang::Type::TemplateSpecialization: return 1;
2861 case clang::Type::InjectedClassName: return 0;
2862 case clang::Type::DependentName: return 1;
2863 case clang::Type::DependentTemplateSpecialization: return 1;
2864 case clang::Type::ObjCObject: return 0;
2865 case clang::Type::ObjCInterface: return 0;
2866 case clang::Type::ObjCObjectPointer: return 1;
2867 default:
2868 break;
2869 }
2870 return 0;
2871}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002872
Greg Clayton1be10fc2010-09-29 01:12:09 +00002873clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002874ClangASTContext::GetChildClangTypeAtIndex
2875(
Jim Inghamd555bac2011-06-24 22:03:24 +00002876 ExecutionContext *exe_ctx,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002877 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002878 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002879 uint32_t idx,
2880 bool transparent_pointers,
2881 bool omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00002882 bool ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002883 std::string& child_name,
2884 uint32_t &child_byte_size,
2885 int32_t &child_byte_offset,
2886 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002887 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002888 bool &child_is_base_class,
2889 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002890)
2891{
2892 if (parent_clang_type)
2893
Jim Inghamd555bac2011-06-24 22:03:24 +00002894 return GetChildClangTypeAtIndex (exe_ctx,
2895 getASTContext(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002896 parent_name,
2897 parent_clang_type,
2898 idx,
2899 transparent_pointers,
2900 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00002901 ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002902 child_name,
2903 child_byte_size,
2904 child_byte_offset,
2905 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002906 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002907 child_is_base_class,
2908 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002909 return NULL;
2910}
2911
Greg Clayton1be10fc2010-09-29 01:12:09 +00002912clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002913ClangASTContext::GetChildClangTypeAtIndex
2914(
Jim Inghamd555bac2011-06-24 22:03:24 +00002915 ExecutionContext *exe_ctx,
Greg Clayton6beaaa62011-01-17 03:46:26 +00002916 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002917 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002918 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002919 uint32_t idx,
2920 bool transparent_pointers,
2921 bool omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00002922 bool ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002923 std::string& child_name,
2924 uint32_t &child_byte_size,
2925 int32_t &child_byte_offset,
2926 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002927 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002928 bool &child_is_base_class,
2929 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002930)
2931{
2932 if (parent_clang_type == NULL)
2933 return NULL;
2934
Greg Clayton6beaaa62011-01-17 03:46:26 +00002935 if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002936 {
2937 uint32_t bit_offset;
2938 child_bitfield_bit_size = 0;
2939 child_bitfield_bit_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002940 child_is_base_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002941 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00002942 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2943 switch (parent_type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002944 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002945 case clang::Type::Builtin:
2946 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2947 {
2948 case clang::BuiltinType::ObjCId:
2949 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00002950 child_name = "isa";
Greg Clayton6beaaa62011-01-17 03:46:26 +00002951 child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
2952 return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002953
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002954 default:
2955 break;
2956 }
2957 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002958
Greg Claytone1a916a2010-07-21 22:12:05 +00002959 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002960 if (GetCompleteQualType (ast, parent_qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002961 {
2962 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2963 const RecordDecl *record_decl = record_type->getDecl();
2964 assert(record_decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00002965 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002966 uint32_t child_idx = 0;
2967
2968 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2969 if (cxx_record_decl)
2970 {
2971 // We might have base classes to print out first
2972 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2973 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2974 base_class != base_class_end;
2975 ++base_class)
2976 {
2977 const CXXRecordDecl *base_class_decl = NULL;
2978
2979 // Skip empty base classes
2980 if (omit_empty_base_classes)
2981 {
2982 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2983 if (RecordHasFields(base_class_decl) == false)
2984 continue;
2985 }
2986
2987 if (idx == child_idx)
2988 {
2989 if (base_class_decl == NULL)
2990 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2991
2992
2993 if (base_class->isVirtual())
Greg Clayton6ed95942011-01-22 07:12:45 +00002994 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002995 else
Greg Clayton6ed95942011-01-22 07:12:45 +00002996 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002997
2998 // Base classes should be a multiple of 8 bits in size
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002999 child_byte_offset = bit_offset/8;
Greg Claytone3055942011-06-30 02:28:26 +00003000
3001 child_name = ClangASTType::GetTypeNameForQualType(base_class->getType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003002
Greg Clayton6beaaa62011-01-17 03:46:26 +00003003 uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003004
Jim Inghamf46b3382011-04-15 23:42:06 +00003005 // Base classes bit sizes should be a multiple of 8 bits in size
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003006 assert (clang_type_info_bit_size % 8 == 0);
3007 child_byte_size = clang_type_info_bit_size / 8;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003008 child_is_base_class = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003009 return base_class->getType().getAsOpaquePtr();
3010 }
3011 // We don't increment the child index in the for loop since we might
3012 // be skipping empty base classes
3013 ++child_idx;
3014 }
3015 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003016 // Make sure index is in range...
3017 uint32_t field_idx = 0;
3018 RecordDecl::field_iterator field, field_end;
3019 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
3020 {
3021 if (idx == child_idx)
3022 {
3023 // Print the member type if requested
3024 // Print the member name and equal sign
3025 child_name.assign(field->getNameAsString().c_str());
3026
3027 // Figure out the type byte size (field_type_info.first) and
3028 // alignment (field_type_info.second) from the AST context.
Greg Clayton6beaaa62011-01-17 03:46:26 +00003029 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
Greg Claytonc982c762010-07-09 20:39:50 +00003030 assert(field_idx < record_layout.getFieldCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003031
3032 child_byte_size = field_type_info.first / 8;
3033
3034 // Figure out the field offset within the current struct/union/class type
3035 bit_offset = record_layout.getFieldOffset (field_idx);
3036 child_byte_offset = bit_offset / 8;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003037 if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003038 child_bitfield_bit_offset = bit_offset % 8;
3039
3040 return field->getType().getAsOpaquePtr();
3041 }
3042 }
3043 }
3044 break;
3045
Greg Clayton9e409562010-07-28 02:04:09 +00003046 case clang::Type::ObjCObject:
3047 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003048 if (GetCompleteQualType (ast, parent_qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003049 {
Sean Callanan78e37602011-01-27 04:42:51 +00003050 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003051 assert (objc_class_type);
3052 if (objc_class_type)
3053 {
3054 uint32_t child_idx = 0;
3055 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3056
3057 if (class_interface_decl)
3058 {
3059
Greg Clayton6beaaa62011-01-17 03:46:26 +00003060 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
Greg Clayton9e409562010-07-28 02:04:09 +00003061 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3062 if (superclass_interface_decl)
3063 {
3064 if (omit_empty_base_classes)
3065 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003066 if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9e409562010-07-28 02:04:09 +00003067 {
3068 if (idx == 0)
3069 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003070 QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
Greg Clayton9e409562010-07-28 02:04:09 +00003071
3072
3073 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
3074
Greg Clayton6beaaa62011-01-17 03:46:26 +00003075 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003076
3077 child_byte_size = ivar_type_info.first / 8;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003078 child_byte_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003079 child_is_base_class = true;
Greg Clayton9e409562010-07-28 02:04:09 +00003080
3081 return ivar_qual_type.getAsOpaquePtr();
3082 }
3083
3084 ++child_idx;
3085 }
3086 }
3087 else
3088 ++child_idx;
3089 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003090
3091 const uint32_t superclass_idx = child_idx;
Greg Clayton9e409562010-07-28 02:04:09 +00003092
3093 if (idx < (child_idx + class_interface_decl->ivar_size()))
3094 {
3095 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3096
3097 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3098 {
3099 if (child_idx == idx)
3100 {
3101 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3102
3103 QualType ivar_qual_type(ivar_decl->getType());
3104
3105 child_name.assign(ivar_decl->getNameAsString().c_str());
3106
Greg Clayton6beaaa62011-01-17 03:46:26 +00003107 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003108
3109 child_byte_size = ivar_type_info.first / 8;
3110
3111 // Figure out the field offset within the current struct/union/class type
Jim Inghamd555bac2011-06-24 22:03:24 +00003112 // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
3113 // that doesn't account for the space taken up by unbacked properties, or from
3114 // the changing size of base classes that are newer than this class.
3115 // So if we have a process around that we can ask about this object, do so.
3116 child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
3117
3118 if (exe_ctx && exe_ctx->process)
3119 {
3120 ObjCLanguageRuntime *objc_runtime = exe_ctx->process->GetObjCLanguageRuntime();
3121 if (objc_runtime != NULL)
3122 {
Enrico Granata6f3533f2011-07-29 19:53:35 +00003123 ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
Jim Inghamd555bac2011-06-24 22:03:24 +00003124 child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
3125 }
3126 }
3127
3128 if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
3129 {
3130 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
3131 child_byte_offset = bit_offset / 8;
3132 }
Greg Clayton9e409562010-07-28 02:04:09 +00003133
3134 return ivar_qual_type.getAsOpaquePtr();
3135 }
3136 ++child_idx;
3137 }
3138 }
3139 }
3140 }
3141 }
3142 break;
3143
3144 case clang::Type::ObjCObjectPointer:
3145 {
Sean Callanan78e37602011-01-27 04:42:51 +00003146 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003147 QualType pointee_type = pointer_type->getPointeeType();
3148
3149 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3150 {
Greg Claytone221f822011-01-21 01:59:00 +00003151 child_is_deref_of_parent = false;
3152 bool tmp_child_is_deref_of_parent = false;
Jim Inghamd555bac2011-06-24 22:03:24 +00003153 return GetChildClangTypeAtIndex (exe_ctx,
3154 ast,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003155 parent_name,
3156 pointer_type->getPointeeType().getAsOpaquePtr(),
3157 idx,
3158 transparent_pointers,
3159 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003160 ignore_array_bounds,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003161 child_name,
3162 child_byte_size,
3163 child_byte_offset,
3164 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003165 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003166 child_is_base_class,
3167 tmp_child_is_deref_of_parent);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003168 }
3169 else
3170 {
Greg Claytone221f822011-01-21 01:59:00 +00003171 child_is_deref_of_parent = true;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003172 if (parent_name)
3173 {
3174 child_name.assign(1, '*');
3175 child_name += parent_name;
3176 }
3177
3178 // We have a pointer to an simple type
3179 if (idx == 0)
3180 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003181 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003182 assert(clang_type_info.first % 8 == 0);
3183 child_byte_size = clang_type_info.first / 8;
3184 child_byte_offset = 0;
3185 return pointee_type.getAsOpaquePtr();
3186 }
3187 }
Greg Clayton9e409562010-07-28 02:04:09 +00003188 }
3189 break;
3190
Greg Claytone1a916a2010-07-21 22:12:05 +00003191 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003192 {
3193 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3194 const uint64_t element_count = array->getSize().getLimitedValue();
3195
Greg Claytondaf515f2011-07-09 20:12:33 +00003196 if (ignore_array_bounds || idx < element_count)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003197 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003198 if (GetCompleteQualType (ast, array->getElementType()))
3199 {
3200 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003201
Greg Clayton6beaaa62011-01-17 03:46:26 +00003202 char element_name[64];
3203 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003204
Greg Clayton6beaaa62011-01-17 03:46:26 +00003205 child_name.assign(element_name);
3206 assert(field_type_info.first % 8 == 0);
3207 child_byte_size = field_type_info.first / 8;
Greg Claytondaf515f2011-07-09 20:12:33 +00003208 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003209 return array->getElementType().getAsOpaquePtr();
3210 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003211 }
3212 }
3213 break;
3214
Greg Claytone1a916a2010-07-21 22:12:05 +00003215 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003216 {
Sean Callanan78e37602011-01-27 04:42:51 +00003217 const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003218 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton97a43712011-01-08 22:26:47 +00003219
3220 // Don't dereference "void *" pointers
3221 if (pointee_type->isVoidType())
3222 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003223
3224 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3225 {
Greg Claytone221f822011-01-21 01:59:00 +00003226 child_is_deref_of_parent = false;
3227 bool tmp_child_is_deref_of_parent = false;
Jim Inghamd555bac2011-06-24 22:03:24 +00003228 return GetChildClangTypeAtIndex (exe_ctx,
3229 ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003230 parent_name,
3231 pointer_type->getPointeeType().getAsOpaquePtr(),
3232 idx,
3233 transparent_pointers,
3234 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003235 ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003236 child_name,
3237 child_byte_size,
3238 child_byte_offset,
3239 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003240 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003241 child_is_base_class,
3242 tmp_child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003243 }
3244 else
3245 {
Greg Claytone221f822011-01-21 01:59:00 +00003246 child_is_deref_of_parent = true;
3247
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003248 if (parent_name)
3249 {
3250 child_name.assign(1, '*');
3251 child_name += parent_name;
3252 }
3253
3254 // We have a pointer to an simple type
3255 if (idx == 0)
3256 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003257 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003258 assert(clang_type_info.first % 8 == 0);
3259 child_byte_size = clang_type_info.first / 8;
3260 child_byte_offset = 0;
3261 return pointee_type.getAsOpaquePtr();
3262 }
3263 }
3264 }
3265 break;
3266
Greg Clayton73b472d2010-10-27 03:32:59 +00003267 case clang::Type::LValueReference:
3268 case clang::Type::RValueReference:
3269 {
Sean Callanan78e37602011-01-27 04:42:51 +00003270 const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00003271 QualType pointee_type(reference_type->getPointeeType());
3272 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
3273 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
3274 {
Greg Claytone221f822011-01-21 01:59:00 +00003275 child_is_deref_of_parent = false;
3276 bool tmp_child_is_deref_of_parent = false;
Jim Inghamd555bac2011-06-24 22:03:24 +00003277 return GetChildClangTypeAtIndex (exe_ctx,
3278 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00003279 parent_name,
3280 pointee_clang_type,
3281 idx,
3282 transparent_pointers,
3283 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003284 ignore_array_bounds,
Greg Clayton73b472d2010-10-27 03:32:59 +00003285 child_name,
3286 child_byte_size,
3287 child_byte_offset,
3288 child_bitfield_bit_size,
3289 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003290 child_is_base_class,
3291 tmp_child_is_deref_of_parent);
Greg Clayton73b472d2010-10-27 03:32:59 +00003292 }
3293 else
3294 {
3295 if (parent_name)
3296 {
3297 child_name.assign(1, '&');
3298 child_name += parent_name;
3299 }
3300
3301 // We have a pointer to an simple type
3302 if (idx == 0)
3303 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003304 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Clayton73b472d2010-10-27 03:32:59 +00003305 assert(clang_type_info.first % 8 == 0);
3306 child_byte_size = clang_type_info.first / 8;
3307 child_byte_offset = 0;
3308 return pointee_type.getAsOpaquePtr();
3309 }
3310 }
3311 }
3312 break;
3313
Greg Claytone1a916a2010-07-21 22:12:05 +00003314 case clang::Type::Typedef:
Jim Inghamd555bac2011-06-24 22:03:24 +00003315 return GetChildClangTypeAtIndex (exe_ctx,
3316 ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003317 parent_name,
Sean Callanan48114472010-12-13 01:26:27 +00003318 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003319 idx,
3320 transparent_pointers,
3321 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003322 ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003323 child_name,
3324 child_byte_size,
3325 child_byte_offset,
3326 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003327 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003328 child_is_base_class,
3329 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003330 break;
Sean Callanan912855f2011-08-11 23:56:13 +00003331
3332 case clang::Type::Elaborated:
3333 return GetChildClangTypeAtIndex (exe_ctx,
3334 ast,
3335 parent_name,
3336 cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
3337 idx,
3338 transparent_pointers,
3339 omit_empty_base_classes,
3340 ignore_array_bounds,
3341 child_name,
3342 child_byte_size,
3343 child_byte_offset,
3344 child_bitfield_bit_size,
3345 child_bitfield_bit_offset,
3346 child_is_base_class,
3347 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003348
3349 default:
3350 break;
3351 }
3352 }
Greg Clayton19503a22010-07-23 15:37:46 +00003353 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003354}
3355
3356static inline bool
3357BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
3358{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003359 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003360}
3361
3362static uint32_t
3363GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
3364{
3365 uint32_t num_bases = 0;
3366 if (cxx_record_decl)
3367 {
3368 if (omit_empty_base_classes)
3369 {
3370 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3371 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3372 base_class != base_class_end;
3373 ++base_class)
3374 {
3375 // Skip empty base classes
3376 if (omit_empty_base_classes)
3377 {
3378 if (BaseSpecifierIsEmpty (base_class))
3379 continue;
3380 }
3381 ++num_bases;
3382 }
3383 }
3384 else
3385 num_bases = cxx_record_decl->getNumBases();
3386 }
3387 return num_bases;
3388}
3389
3390
3391static uint32_t
3392GetIndexForRecordBase
3393(
3394 const RecordDecl *record_decl,
3395 const CXXBaseSpecifier *base_spec,
3396 bool omit_empty_base_classes
3397)
3398{
3399 uint32_t child_idx = 0;
3400
3401 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3402
3403// const char *super_name = record_decl->getNameAsCString();
3404// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
3405// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
3406//
3407 if (cxx_record_decl)
3408 {
3409 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3410 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3411 base_class != base_class_end;
3412 ++base_class)
3413 {
3414 if (omit_empty_base_classes)
3415 {
3416 if (BaseSpecifierIsEmpty (base_class))
3417 continue;
3418 }
3419
3420// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
3421// child_idx,
3422// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
3423//
3424//
3425 if (base_class == base_spec)
3426 return child_idx;
3427 ++child_idx;
3428 }
3429 }
3430
3431 return UINT32_MAX;
3432}
3433
3434
3435static uint32_t
3436GetIndexForRecordChild
3437(
3438 const RecordDecl *record_decl,
3439 NamedDecl *canonical_decl,
3440 bool omit_empty_base_classes
3441)
3442{
3443 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
3444
3445// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3446//
3447//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
3448// if (cxx_record_decl)
3449// {
3450// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3451// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3452// base_class != base_class_end;
3453// ++base_class)
3454// {
3455// if (omit_empty_base_classes)
3456// {
3457// if (BaseSpecifierIsEmpty (base_class))
3458// continue;
3459// }
3460//
3461//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
3462//// record_decl->getNameAsCString(),
3463//// canonical_decl->getNameAsCString(),
3464//// child_idx,
3465//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
3466//
3467//
3468// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3469// if (curr_base_class_decl == canonical_decl)
3470// {
3471// return child_idx;
3472// }
3473// ++child_idx;
3474// }
3475// }
3476//
3477// const uint32_t num_bases = child_idx;
3478 RecordDecl::field_iterator field, field_end;
3479 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3480 field != field_end;
3481 ++field, ++child_idx)
3482 {
3483// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
3484// record_decl->getNameAsCString(),
3485// canonical_decl->getNameAsCString(),
3486// child_idx - num_bases,
3487// field->getNameAsCString());
3488
3489 if (field->getCanonicalDecl() == canonical_decl)
3490 return child_idx;
3491 }
3492
3493 return UINT32_MAX;
3494}
3495
3496// Look for a child member (doesn't include base classes, but it does include
3497// their members) in the type hierarchy. Returns an index path into "clang_type"
3498// on how to reach the appropriate member.
3499//
3500// class A
3501// {
3502// public:
3503// int m_a;
3504// int m_b;
3505// };
3506//
3507// class B
3508// {
3509// };
3510//
3511// class C :
3512// public B,
3513// public A
3514// {
3515// };
3516//
3517// If we have a clang type that describes "class C", and we wanted to looked
3518// "m_b" in it:
3519//
3520// With omit_empty_base_classes == false we would get an integer array back with:
3521// { 1, 1 }
3522// The first index 1 is the child index for "class A" within class C
3523// The second index 1 is the child index for "m_b" within class A
3524//
3525// With omit_empty_base_classes == true we would get an integer array back with:
3526// { 0, 1 }
3527// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count)
3528// The second index 1 is the child index for "m_b" within class A
3529
3530size_t
3531ClangASTContext::GetIndexOfChildMemberWithName
3532(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003533 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003534 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003535 const char *name,
3536 bool omit_empty_base_classes,
3537 std::vector<uint32_t>& child_indexes
3538)
3539{
3540 if (clang_type && name && name[0])
3541 {
3542 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003543 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3544 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003545 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003546 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003547 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003548 {
3549 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3550 const RecordDecl *record_decl = record_type->getDecl();
3551
3552 assert(record_decl);
3553 uint32_t child_idx = 0;
3554
3555 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3556
3557 // Try and find a field that matches NAME
3558 RecordDecl::field_iterator field, field_end;
3559 StringRef name_sref(name);
3560 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3561 field != field_end;
3562 ++field, ++child_idx)
3563 {
3564 if (field->getName().equals (name_sref))
3565 {
3566 // We have to add on the number of base classes to this index!
3567 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
3568 return child_indexes.size();
3569 }
3570 }
3571
3572 if (cxx_record_decl)
3573 {
3574 const RecordDecl *parent_record_decl = cxx_record_decl;
3575
3576 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
3577
3578 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
3579 // Didn't find things easily, lets let clang do its thang...
Sean Callanancc427fa2011-07-30 02:42:06 +00003580 IdentifierInfo & ident_ref = ast->Idents.get(name_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003581 DeclarationName decl_name(&ident_ref);
3582
3583 CXXBasePaths paths;
3584 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
3585 decl_name.getAsOpaquePtr(),
3586 paths))
3587 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003588 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
3589 for (path = paths.begin(); path != path_end; ++path)
3590 {
3591 const size_t num_path_elements = path->size();
3592 for (size_t e=0; e<num_path_elements; ++e)
3593 {
3594 CXXBasePathElement elem = (*path)[e];
3595
3596 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
3597 if (child_idx == UINT32_MAX)
3598 {
3599 child_indexes.clear();
3600 return 0;
3601 }
3602 else
3603 {
3604 child_indexes.push_back (child_idx);
3605 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
3606 }
3607 }
3608 DeclContext::lookup_iterator named_decl_pos;
3609 for (named_decl_pos = path->Decls.first;
3610 named_decl_pos != path->Decls.second && parent_record_decl;
3611 ++named_decl_pos)
3612 {
3613 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
3614
3615 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
3616 if (child_idx == UINT32_MAX)
3617 {
3618 child_indexes.clear();
3619 return 0;
3620 }
3621 else
3622 {
3623 child_indexes.push_back (child_idx);
3624 }
3625 }
3626 }
3627 return child_indexes.size();
3628 }
3629 }
3630
3631 }
3632 break;
3633
Greg Clayton9e409562010-07-28 02:04:09 +00003634 case clang::Type::ObjCObject:
3635 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003636 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003637 {
3638 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003639 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003640 assert (objc_class_type);
3641 if (objc_class_type)
3642 {
3643 uint32_t child_idx = 0;
3644 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3645
3646 if (class_interface_decl)
3647 {
3648 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3649 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3650
Greg Clayton6ba78152010-09-18 02:11:07 +00003651 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9e409562010-07-28 02:04:09 +00003652 {
3653 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3654
3655 if (ivar_decl->getName().equals (name_sref))
3656 {
3657 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3658 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3659 ++child_idx;
3660
3661 child_indexes.push_back (child_idx);
3662 return child_indexes.size();
3663 }
3664 }
3665
3666 if (superclass_interface_decl)
3667 {
3668 // The super class index is always zero for ObjC classes,
3669 // so we push it onto the child indexes in case we find
3670 // an ivar in our superclass...
3671 child_indexes.push_back (0);
3672
Greg Clayton6beaaa62011-01-17 03:46:26 +00003673 if (GetIndexOfChildMemberWithName (ast,
3674 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00003675 name,
3676 omit_empty_base_classes,
3677 child_indexes))
3678 {
3679 // We did find an ivar in a superclass so just
3680 // return the results!
3681 return child_indexes.size();
3682 }
3683
3684 // We didn't find an ivar matching "name" in our
3685 // superclass, pop the superclass zero index that
3686 // we pushed on above.
3687 child_indexes.pop_back();
3688 }
3689 }
3690 }
3691 }
3692 break;
3693
3694 case clang::Type::ObjCObjectPointer:
3695 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003696 return GetIndexOfChildMemberWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003697 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3698 name,
3699 omit_empty_base_classes,
3700 child_indexes);
3701 }
3702 break;
3703
3704
Greg Claytone1a916a2010-07-21 22:12:05 +00003705 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003706 {
3707// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3708// const uint64_t element_count = array->getSize().getLimitedValue();
3709//
3710// if (idx < element_count)
3711// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003712// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003713//
3714// char element_name[32];
3715// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3716//
3717// child_name.assign(element_name);
3718// assert(field_type_info.first % 8 == 0);
3719// child_byte_size = field_type_info.first / 8;
3720// child_byte_offset = idx * child_byte_size;
3721// return array->getElementType().getAsOpaquePtr();
3722// }
3723 }
3724 break;
3725
Greg Claytone1a916a2010-07-21 22:12:05 +00003726// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003727// {
3728// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3729// QualType pointee_type = mem_ptr_type->getPointeeType();
3730//
3731// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3732// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003733// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003734// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3735// name);
3736// }
3737// }
3738// break;
3739//
Greg Claytone1a916a2010-07-21 22:12:05 +00003740 case clang::Type::LValueReference:
3741 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003742 {
Sean Callanan78e37602011-01-27 04:42:51 +00003743 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003744 QualType pointee_type = reference_type->getPointeeType();
3745
3746 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3747 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003748 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003749 reference_type->getPointeeType().getAsOpaquePtr(),
3750 name,
3751 omit_empty_base_classes,
3752 child_indexes);
3753 }
3754 }
3755 break;
3756
Greg Claytone1a916a2010-07-21 22:12:05 +00003757 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003758 {
Sean Callanan78e37602011-01-27 04:42:51 +00003759 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003760 QualType pointee_type = pointer_type->getPointeeType();
3761
3762 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3763 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003764 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003765 pointer_type->getPointeeType().getAsOpaquePtr(),
3766 name,
3767 omit_empty_base_classes,
3768 child_indexes);
3769 }
3770 else
3771 {
3772// if (parent_name)
3773// {
3774// child_name.assign(1, '*');
3775// child_name += parent_name;
3776// }
3777//
3778// // We have a pointer to an simple type
3779// if (idx == 0)
3780// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003781// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003782// assert(clang_type_info.first % 8 == 0);
3783// child_byte_size = clang_type_info.first / 8;
3784// child_byte_offset = 0;
3785// return pointee_type.getAsOpaquePtr();
3786// }
3787 }
3788 }
3789 break;
3790
Greg Claytone1a916a2010-07-21 22:12:05 +00003791 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003792 return GetIndexOfChildMemberWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003793 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003794 name,
3795 omit_empty_base_classes,
3796 child_indexes);
3797
3798 default:
3799 break;
3800 }
3801 }
3802 return 0;
3803}
3804
3805
3806// Get the index of the child of "clang_type" whose name matches. This function
3807// doesn't descend into the children, but only looks one level deep and name
3808// matches can include base class names.
3809
3810uint32_t
3811ClangASTContext::GetIndexOfChildWithName
3812(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003813 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003814 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003815 const char *name,
3816 bool omit_empty_base_classes
3817)
3818{
3819 if (clang_type && name && name[0])
3820 {
3821 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00003822
Greg Clayton737b9322010-09-13 03:32:57 +00003823 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9e409562010-07-28 02:04:09 +00003824
Greg Clayton737b9322010-09-13 03:32:57 +00003825 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003826 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003827 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003828 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003829 {
3830 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3831 const RecordDecl *record_decl = record_type->getDecl();
3832
3833 assert(record_decl);
3834 uint32_t child_idx = 0;
3835
3836 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3837
3838 if (cxx_record_decl)
3839 {
3840 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3841 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3842 base_class != base_class_end;
3843 ++base_class)
3844 {
3845 // Skip empty base classes
3846 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3847 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3848 continue;
3849
Greg Claytone3055942011-06-30 02:28:26 +00003850 std::string base_class_type_name (ClangASTType::GetTypeNameForQualType(base_class->getType()));
3851 if (base_class_type_name.compare (name) == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003852 return child_idx;
3853 ++child_idx;
3854 }
3855 }
3856
3857 // Try and find a field that matches NAME
3858 RecordDecl::field_iterator field, field_end;
3859 StringRef name_sref(name);
3860 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3861 field != field_end;
3862 ++field, ++child_idx)
3863 {
3864 if (field->getName().equals (name_sref))
3865 return child_idx;
3866 }
3867
3868 }
3869 break;
3870
Greg Clayton9e409562010-07-28 02:04:09 +00003871 case clang::Type::ObjCObject:
3872 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003873 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003874 {
3875 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003876 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003877 assert (objc_class_type);
3878 if (objc_class_type)
3879 {
3880 uint32_t child_idx = 0;
3881 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3882
3883 if (class_interface_decl)
3884 {
3885 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3886 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3887
3888 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3889 {
3890 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3891
3892 if (ivar_decl->getName().equals (name_sref))
3893 {
3894 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3895 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3896 ++child_idx;
3897
3898 return child_idx;
3899 }
3900 }
3901
3902 if (superclass_interface_decl)
3903 {
3904 if (superclass_interface_decl->getName().equals (name_sref))
3905 return 0;
3906 }
3907 }
3908 }
3909 }
3910 break;
3911
3912 case clang::Type::ObjCObjectPointer:
3913 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003914 return GetIndexOfChildWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003915 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3916 name,
3917 omit_empty_base_classes);
3918 }
3919 break;
3920
Greg Claytone1a916a2010-07-21 22:12:05 +00003921 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003922 {
3923// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3924// const uint64_t element_count = array->getSize().getLimitedValue();
3925//
3926// if (idx < element_count)
3927// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003928// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003929//
3930// char element_name[32];
3931// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3932//
3933// child_name.assign(element_name);
3934// assert(field_type_info.first % 8 == 0);
3935// child_byte_size = field_type_info.first / 8;
3936// child_byte_offset = idx * child_byte_size;
3937// return array->getElementType().getAsOpaquePtr();
3938// }
3939 }
3940 break;
3941
Greg Claytone1a916a2010-07-21 22:12:05 +00003942// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003943// {
3944// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3945// QualType pointee_type = mem_ptr_type->getPointeeType();
3946//
3947// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3948// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003949// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003950// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3951// name);
3952// }
3953// }
3954// break;
3955//
Greg Claytone1a916a2010-07-21 22:12:05 +00003956 case clang::Type::LValueReference:
3957 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003958 {
Sean Callanan78e37602011-01-27 04:42:51 +00003959 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003960 QualType pointee_type = reference_type->getPointeeType();
3961
3962 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3963 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003964 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003965 reference_type->getPointeeType().getAsOpaquePtr(),
3966 name,
3967 omit_empty_base_classes);
3968 }
3969 }
3970 break;
3971
Greg Claytone1a916a2010-07-21 22:12:05 +00003972 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003973 {
Sean Callanan78e37602011-01-27 04:42:51 +00003974 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003975 QualType pointee_type = pointer_type->getPointeeType();
3976
3977 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3978 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003979 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003980 pointer_type->getPointeeType().getAsOpaquePtr(),
3981 name,
3982 omit_empty_base_classes);
3983 }
3984 else
3985 {
3986// if (parent_name)
3987// {
3988// child_name.assign(1, '*');
3989// child_name += parent_name;
3990// }
3991//
3992// // We have a pointer to an simple type
3993// if (idx == 0)
3994// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003995// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003996// assert(clang_type_info.first % 8 == 0);
3997// child_byte_size = clang_type_info.first / 8;
3998// child_byte_offset = 0;
3999// return pointee_type.getAsOpaquePtr();
4000// }
4001 }
4002 }
4003 break;
4004
Greg Claytone1a916a2010-07-21 22:12:05 +00004005 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00004006 return GetIndexOfChildWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00004007 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004008 name,
4009 omit_empty_base_classes);
4010
4011 default:
4012 break;
4013 }
4014 }
4015 return UINT32_MAX;
4016}
4017
4018#pragma mark TagType
4019
4020bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004021ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004022{
4023 if (tag_clang_type)
4024 {
4025 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00004026 const clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004027 if (clang_type)
4028 {
Sean Callanan78e37602011-01-27 04:42:51 +00004029 const TagType *tag_type = dyn_cast<TagType>(clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004030 if (tag_type)
4031 {
4032 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
4033 if (tag_decl)
4034 {
4035 tag_decl->setTagKind ((TagDecl::TagKind)kind);
4036 return true;
4037 }
4038 }
4039 }
4040 }
4041 return false;
4042}
4043
4044
4045#pragma mark DeclContext Functions
4046
4047DeclContext *
Greg Clayton1be10fc2010-09-29 01:12:09 +00004048ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004049{
4050 if (clang_type == NULL)
4051 return NULL;
4052
4053 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004054 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4055 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004056 {
Sean Callanancc427fa2011-07-30 02:42:06 +00004057 case clang::Type::UnaryTransform: break;
Greg Clayton9e409562010-07-28 02:04:09 +00004058 case clang::Type::FunctionNoProto: break;
4059 case clang::Type::FunctionProto: break;
4060 case clang::Type::IncompleteArray: break;
4061 case clang::Type::VariableArray: break;
4062 case clang::Type::ConstantArray: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004063 case clang::Type::DependentSizedArray: break;
Greg Clayton9e409562010-07-28 02:04:09 +00004064 case clang::Type::ExtVector: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004065 case clang::Type::DependentSizedExtVector: break;
Greg Clayton9e409562010-07-28 02:04:09 +00004066 case clang::Type::Vector: break;
4067 case clang::Type::Builtin: break;
4068 case clang::Type::BlockPointer: break;
4069 case clang::Type::Pointer: break;
4070 case clang::Type::LValueReference: break;
4071 case clang::Type::RValueReference: break;
4072 case clang::Type::MemberPointer: break;
4073 case clang::Type::Complex: break;
4074 case clang::Type::ObjCObject: break;
4075 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
4076 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
4077 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
4078 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
Sean Callanan48114472010-12-13 01:26:27 +00004079 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00004080 case clang::Type::Elaborated: return ClangASTContext::GetDeclContextForType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00004081 case clang::Type::TypeOfExpr: break;
4082 case clang::Type::TypeOf: break;
4083 case clang::Type::Decltype: break;
4084 //case clang::Type::QualifiedName: break;
4085 case clang::Type::TemplateSpecialization: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004086 case clang::Type::DependentTemplateSpecialization: break;
4087 case clang::Type::TemplateTypeParm: break;
4088 case clang::Type::SubstTemplateTypeParm: break;
4089 case clang::Type::SubstTemplateTypeParmPack:break;
4090 case clang::Type::PackExpansion: break;
4091 case clang::Type::UnresolvedUsing: break;
4092 case clang::Type::Paren: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004093 case clang::Type::Attributed: break;
4094 case clang::Type::Auto: break;
4095 case clang::Type::InjectedClassName: break;
4096 case clang::Type::DependentName: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004097 }
4098 // No DeclContext in this type...
4099 return NULL;
4100}
4101
4102#pragma mark Namespace Declarations
4103
4104NamespaceDecl *
4105ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
4106{
4107 // TODO: Do something intelligent with the Declaration object passed in
4108 // like maybe filling in the SourceLocation with it...
4109 if (name)
4110 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004111 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004112 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00004113 decl_ctx = ast->getTranslationUnitDecl();
Sean Callananfb0b7582011-03-15 00:17:19 +00004114 return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &ast->Idents.get(name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004115 }
4116 return NULL;
4117}
4118
4119
4120#pragma mark Function Types
4121
4122FunctionDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00004123ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004124{
4125 if (name)
4126 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004127 ASTContext *ast = getASTContext();
4128 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004129
4130 if (name && name[0])
4131 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004132 return FunctionDecl::Create(*ast,
4133 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004134 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004135 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00004136 DeclarationName (&ast->Idents.get(name)),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004137 QualType::getFromOpaquePtr(function_clang_type),
4138 NULL,
4139 (FunctionDecl::StorageClass)storage,
4140 (FunctionDecl::StorageClass)storage,
4141 is_inline);
4142 }
4143 else
4144 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004145 return FunctionDecl::Create(*ast,
4146 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004147 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004148 SourceLocation(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004149 DeclarationName (),
4150 QualType::getFromOpaquePtr(function_clang_type),
4151 NULL,
4152 (FunctionDecl::StorageClass)storage,
4153 (FunctionDecl::StorageClass)storage,
4154 is_inline);
4155 }
4156 }
4157 return NULL;
4158}
4159
Greg Clayton1be10fc2010-09-29 01:12:09 +00004160clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00004161ClangASTContext::CreateFunctionType (ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00004162 clang_type_t result_type,
4163 clang_type_t *args,
Sean Callananc81256a2010-09-16 20:40:25 +00004164 unsigned num_args,
4165 bool is_variadic,
4166 unsigned type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004167{
Greg Clayton6beaaa62011-01-17 03:46:26 +00004168 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004169 std::vector<QualType> qual_type_args;
4170 for (unsigned i=0; i<num_args; ++i)
4171 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
4172
4173 // TODO: Detect calling convention in DWARF?
Sean Callanan2c777c42011-01-18 23:32:05 +00004174 FunctionProtoType::ExtProtoInfo proto_info;
4175 proto_info.Variadic = is_variadic;
Sean Callananfb0b7582011-03-15 00:17:19 +00004176 proto_info.ExceptionSpecType = EST_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00004177 proto_info.TypeQuals = type_quals;
Sean Callananfb0b7582011-03-15 00:17:19 +00004178 proto_info.RefQualifier = RQ_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00004179 proto_info.NumExceptions = 0;
4180 proto_info.Exceptions = NULL;
4181
Greg Clayton6beaaa62011-01-17 03:46:26 +00004182 return ast->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton471b31c2010-07-20 22:52:08 +00004183 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004184 qual_type_args.size(),
Sean Callanan2c777c42011-01-18 23:32:05 +00004185 proto_info).getAsOpaquePtr(); // NoReturn);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004186}
4187
4188ParmVarDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00004189ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004190{
Greg Clayton6beaaa62011-01-17 03:46:26 +00004191 ASTContext *ast = getASTContext();
4192 assert (ast != NULL);
4193 return ParmVarDecl::Create(*ast,
4194 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004195 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004196 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00004197 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callananc81256a2010-09-16 20:40:25 +00004198 QualType::getFromOpaquePtr(param_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004199 NULL,
4200 (VarDecl::StorageClass)storage,
4201 (VarDecl::StorageClass)storage,
4202 0);
4203}
4204
4205void
4206ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
4207{
4208 if (function_decl)
4209 function_decl->setParams (params, num_params);
4210}
4211
4212
4213#pragma mark Array Types
4214
Greg Clayton1be10fc2010-09-29 01:12:09 +00004215clang_type_t
4216ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004217{
4218 if (element_type)
4219 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004220 ASTContext *ast = getASTContext();
4221 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004222 llvm::APInt ap_element_count (64, element_count);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004223 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004224 ap_element_count,
4225 ArrayType::Normal,
4226 0).getAsOpaquePtr(); // ElemQuals
4227 }
4228 return NULL;
4229}
4230
4231
4232#pragma mark TagDecl
4233
4234bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004235ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004236{
4237 if (clang_type)
4238 {
4239 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00004240 const clang::Type *t = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004241 if (t)
4242 {
Sean Callanan78e37602011-01-27 04:42:51 +00004243 const TagType *tag_type = dyn_cast<TagType>(t);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004244 if (tag_type)
4245 {
4246 TagDecl *tag_decl = tag_type->getDecl();
4247 if (tag_decl)
4248 {
4249 tag_decl->startDefinition();
4250 return true;
4251 }
4252 }
4253 }
4254 }
4255 return false;
4256}
4257
4258bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004259ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004260{
4261 if (clang_type)
4262 {
4263 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton14372242010-09-29 03:44:17 +00004264
4265 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4266
4267 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004268 {
Greg Clayton14372242010-09-29 03:44:17 +00004269 cxx_record_decl->completeDefinition();
4270
4271 return true;
4272 }
4273
Sean Callanan78e37602011-01-27 04:42:51 +00004274 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
Sean Callanana2424172010-10-25 00:29:48 +00004275
4276 if (objc_class_type)
4277 {
4278 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
4279
4280 class_interface_decl->setForwardDecl(false);
4281 }
4282
Greg Clayton14372242010-09-29 03:44:17 +00004283 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
4284
4285 if (enum_type)
4286 {
4287 EnumDecl *enum_decl = enum_type->getDecl();
4288
4289 if (enum_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004290 {
Greg Clayton14372242010-09-29 03:44:17 +00004291 /// TODO This really needs to be fixed.
4292
4293 unsigned NumPositiveBits = 1;
4294 unsigned NumNegativeBits = 0;
4295
Greg Clayton6beaaa62011-01-17 03:46:26 +00004296 ASTContext *ast = getASTContext();
Greg Claytone02b8502010-10-12 04:29:14 +00004297
4298 QualType promotion_qual_type;
4299 // If the enum integer type is less than an integer in bit width,
4300 // then we must promote it to an integer size.
Greg Clayton6beaaa62011-01-17 03:46:26 +00004301 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
Greg Claytone02b8502010-10-12 04:29:14 +00004302 {
4303 if (enum_decl->getIntegerType()->isSignedIntegerType())
Greg Clayton6beaaa62011-01-17 03:46:26 +00004304 promotion_qual_type = ast->IntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00004305 else
Greg Clayton6beaaa62011-01-17 03:46:26 +00004306 promotion_qual_type = ast->UnsignedIntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00004307 }
4308 else
4309 promotion_qual_type = enum_decl->getIntegerType();
4310
4311 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton14372242010-09-29 03:44:17 +00004312 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004313 }
4314 }
4315 }
4316 return false;
4317}
4318
4319
4320#pragma mark Enumeration Types
4321
Greg Clayton1be10fc2010-09-29 01:12:09 +00004322clang_type_t
Greg Claytonca512b32011-01-14 04:54:56 +00004323ClangASTContext::CreateEnumerationType
4324(
4325 const char *name,
4326 DeclContext *decl_ctx,
4327 const Declaration &decl,
4328 clang_type_t integer_qual_type
4329)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004330{
4331 // TODO: Do something intelligent with the Declaration object passed in
4332 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00004333 ASTContext *ast = getASTContext();
4334 assert (ast != NULL);
Greg Claytone02b8502010-10-12 04:29:14 +00004335
4336 // TODO: ask about these...
4337// const bool IsScoped = false;
4338// const bool IsFixed = false;
4339
Greg Clayton6beaaa62011-01-17 03:46:26 +00004340 EnumDecl *enum_decl = EnumDecl::Create (*ast,
Greg Claytonca512b32011-01-14 04:54:56 +00004341 decl_ctx,
Greg Claytone02b8502010-10-12 04:29:14 +00004342 SourceLocation(),
Greg Claytone02b8502010-10-12 04:29:14 +00004343 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004344 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callanan48114472010-12-13 01:26:27 +00004345 NULL,
4346 false, // IsScoped
4347 false, // IsScopedUsingClassTag
4348 false); // IsFixed
Sean Callanan2652ad22011-01-18 01:03:44 +00004349
4350
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004351 if (enum_decl)
Greg Clayton83ff3892010-09-12 23:17:56 +00004352 {
4353 // TODO: check if we should be setting the promotion type too?
4354 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00004355
4356 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
4357
Greg Clayton6beaaa62011-01-17 03:46:26 +00004358 return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Clayton83ff3892010-09-12 23:17:56 +00004359 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004360 return NULL;
4361}
4362
Greg Clayton1be10fc2010-09-29 01:12:09 +00004363clang_type_t
4364ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
4365{
4366 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
4367
Sean Callanan78e37602011-01-27 04:42:51 +00004368 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Greg Clayton1be10fc2010-09-29 01:12:09 +00004369 if (clang_type)
4370 {
4371 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
4372 if (enum_type)
4373 {
4374 EnumDecl *enum_decl = enum_type->getDecl();
4375 if (enum_decl)
4376 return enum_decl->getIntegerType().getAsOpaquePtr();
4377 }
4378 }
4379 return NULL;
4380}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004381bool
4382ClangASTContext::AddEnumerationValueToEnumerationType
4383(
Greg Clayton1be10fc2010-09-29 01:12:09 +00004384 clang_type_t enum_clang_type,
4385 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004386 const Declaration &decl,
4387 const char *name,
4388 int64_t enum_value,
4389 uint32_t enum_value_bit_size
4390)
4391{
4392 if (enum_clang_type && enumerator_clang_type && name)
4393 {
4394 // TODO: Do something intelligent with the Declaration object passed in
4395 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00004396 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004397 IdentifierTable *identifier_table = getIdentifierTable();
4398
Greg Clayton6beaaa62011-01-17 03:46:26 +00004399 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004400 assert (identifier_table != NULL);
4401 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
4402
Sean Callanan78e37602011-01-27 04:42:51 +00004403 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004404 if (clang_type)
4405 {
4406 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
4407
4408 if (enum_type)
4409 {
4410 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
4411 enum_llvm_apsint = enum_value;
4412 EnumConstantDecl *enumerator_decl =
Greg Clayton6beaaa62011-01-17 03:46:26 +00004413 EnumConstantDecl::Create (*ast,
4414 enum_type->getDecl(),
4415 SourceLocation(),
4416 name ? &identifier_table->get(name) : NULL, // Identifier
4417 QualType::getFromOpaquePtr(enumerator_clang_type),
4418 NULL,
4419 enum_llvm_apsint);
4420
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004421 if (enumerator_decl)
4422 {
4423 enum_type->getDecl()->addDecl(enumerator_decl);
4424 return true;
4425 }
4426 }
4427 }
4428 }
4429 return false;
4430}
4431
4432#pragma mark Pointers & References
4433
Greg Clayton1be10fc2010-09-29 01:12:09 +00004434clang_type_t
4435ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004436{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00004437 return CreatePointerType (getASTContext(), clang_type);
4438}
4439
4440clang_type_t
4441ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
4442{
4443 if (ast && clang_type)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004444 {
4445 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4446
Greg Clayton737b9322010-09-13 03:32:57 +00004447 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4448 switch (type_class)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004449 {
4450 case clang::Type::ObjCObject:
4451 case clang::Type::ObjCInterface:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00004452 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004453
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004454 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00004455 return ast->getPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004456 }
4457 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004458 return NULL;
4459}
4460
Greg Clayton1be10fc2010-09-29 01:12:09 +00004461clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00004462ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
4463 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004464{
4465 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00004466 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004467 return NULL;
4468}
4469
Greg Clayton1be10fc2010-09-29 01:12:09 +00004470clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00004471ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
4472 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004473{
4474 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00004475 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004476 return NULL;
4477}
4478
Greg Clayton1be10fc2010-09-29 01:12:09 +00004479clang_type_t
4480ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Clayton9b81a312010-06-12 01:20:30 +00004481{
4482 if (clang_pointee_type && clang_pointee_type)
4483 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
4484 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
4485 return NULL;
4486}
4487
Greg Clayton1a65ae12011-01-25 23:55:37 +00004488uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004489ClangASTContext::GetPointerBitSize ()
4490{
Greg Clayton6beaaa62011-01-17 03:46:26 +00004491 ASTContext *ast = getASTContext();
4492 return ast->getTypeSize(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004493}
4494
4495bool
Greg Claytondea8cb42011-06-29 22:09:02 +00004496ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
4497{
4498 QualType pointee_qual_type;
4499 if (clang_type)
4500 {
4501 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4502 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4503 bool success = false;
4504 switch (type_class)
4505 {
4506 case clang::Type::Builtin:
4507 if (cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
4508 {
4509 if (dynamic_pointee_type)
4510 *dynamic_pointee_type = clang_type;
4511 return true;
4512 }
4513 break;
4514
4515 case clang::Type::ObjCObjectPointer:
4516 if (dynamic_pointee_type)
4517 *dynamic_pointee_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4518 return true;
4519
4520 case clang::Type::Pointer:
4521 pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
4522 success = true;
4523 break;
4524
4525 case clang::Type::LValueReference:
4526 case clang::Type::RValueReference:
4527 pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
4528 success = true;
4529 break;
4530
4531 case clang::Type::Typedef:
Greg Claytonaffb03b2011-07-08 18:27:39 +00004532 return ClangASTContext::IsPossibleDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
Sean Callanan912855f2011-08-11 23:56:13 +00004533
4534 case clang::Type::Elaborated:
4535 return ClangASTContext::IsPossibleDynamicType (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), dynamic_pointee_type);
4536
Greg Claytondea8cb42011-06-29 22:09:02 +00004537 default:
4538 break;
4539 }
4540
4541 if (success)
4542 {
4543 // Check to make sure what we are pointing too is a possible dynamic C++ type
4544 // We currently accept any "void *" (in case we have a class that has been
4545 // watered down to an opaque pointer) and virtual C++ classes.
4546 const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
4547 switch (pointee_type_class)
4548 {
4549 case clang::Type::Builtin:
4550 switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
4551 {
4552 case clang::BuiltinType::UnknownAny:
4553 case clang::BuiltinType::Void:
4554 if (dynamic_pointee_type)
4555 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4556 return true;
4557
4558 case clang::BuiltinType::NullPtr:
4559 case clang::BuiltinType::Bool:
4560 case clang::BuiltinType::Char_U:
4561 case clang::BuiltinType::UChar:
4562 case clang::BuiltinType::WChar_U:
4563 case clang::BuiltinType::Char16:
4564 case clang::BuiltinType::Char32:
4565 case clang::BuiltinType::UShort:
4566 case clang::BuiltinType::UInt:
4567 case clang::BuiltinType::ULong:
4568 case clang::BuiltinType::ULongLong:
4569 case clang::BuiltinType::UInt128:
4570 case clang::BuiltinType::Char_S:
4571 case clang::BuiltinType::SChar:
4572 case clang::BuiltinType::WChar_S:
4573 case clang::BuiltinType::Short:
4574 case clang::BuiltinType::Int:
4575 case clang::BuiltinType::Long:
4576 case clang::BuiltinType::LongLong:
4577 case clang::BuiltinType::Int128:
4578 case clang::BuiltinType::Float:
4579 case clang::BuiltinType::Double:
4580 case clang::BuiltinType::LongDouble:
4581 case clang::BuiltinType::Dependent:
4582 case clang::BuiltinType::Overload:
4583 case clang::BuiltinType::ObjCId:
4584 case clang::BuiltinType::ObjCClass:
4585 case clang::BuiltinType::ObjCSel:
4586 case clang::BuiltinType::BoundMember:
4587 break;
4588 }
4589 break;
4590
4591 case clang::Type::Record:
4592 {
4593 CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
4594 if (cxx_record_decl)
4595 {
4596 if (GetCompleteQualType (ast, pointee_qual_type))
4597 {
4598 success = cxx_record_decl->isDynamicClass();
4599 }
4600 else
4601 {
4602 // We failed to get the complete type, so we have to
4603 // treat this as a void * which we might possibly be
4604 // able to complete
4605 success = true;
4606 }
4607 if (success)
4608 {
4609 if (dynamic_pointee_type)
4610 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4611 return true;
4612 }
4613 }
4614 }
4615 break;
4616
4617 case clang::Type::ObjCObject:
4618 case clang::Type::ObjCInterface:
4619 {
4620 const clang::ObjCObjectType *objc_class_type = pointee_qual_type->getAsObjCQualifiedInterfaceType();
4621 if (objc_class_type)
4622 {
4623 GetCompleteQualType (ast, pointee_qual_type);
4624 if (dynamic_pointee_type)
4625 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4626 return true;
4627 }
4628 }
4629 break;
4630
4631 default:
4632 break;
4633 }
4634 }
4635 }
4636 if (dynamic_pointee_type)
4637 *dynamic_pointee_type = NULL;
4638 return false;
4639}
4640
4641
4642bool
Greg Clayton007d5be2011-05-30 00:49:24 +00004643ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
4644{
4645 QualType pointee_qual_type;
4646 if (clang_type)
4647 {
4648 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4649 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4650 bool success = false;
4651 switch (type_class)
4652 {
4653 case clang::Type::Pointer:
4654 pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
4655 success = true;
4656 break;
4657
4658 case clang::Type::LValueReference:
4659 case clang::Type::RValueReference:
4660 pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
4661 success = true;
4662 break;
4663
4664 case clang::Type::Typedef:
4665 return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
4666
Sean Callanan912855f2011-08-11 23:56:13 +00004667 case clang::Type::Elaborated:
4668 return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
4669
Greg Clayton007d5be2011-05-30 00:49:24 +00004670 default:
4671 break;
4672 }
4673
4674 if (success)
4675 {
4676 // Check to make sure what we are pointing too is a possible dynamic C++ type
4677 // We currently accept any "void *" (in case we have a class that has been
4678 // watered down to an opaque pointer) and virtual C++ classes.
4679 const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
4680 switch (pointee_type_class)
4681 {
4682 case clang::Type::Builtin:
4683 switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
4684 {
4685 case clang::BuiltinType::UnknownAny:
4686 case clang::BuiltinType::Void:
4687 if (dynamic_pointee_type)
4688 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4689 return true;
4690
4691 case clang::BuiltinType::NullPtr:
4692 case clang::BuiltinType::Bool:
4693 case clang::BuiltinType::Char_U:
4694 case clang::BuiltinType::UChar:
4695 case clang::BuiltinType::WChar_U:
4696 case clang::BuiltinType::Char16:
4697 case clang::BuiltinType::Char32:
4698 case clang::BuiltinType::UShort:
4699 case clang::BuiltinType::UInt:
4700 case clang::BuiltinType::ULong:
4701 case clang::BuiltinType::ULongLong:
4702 case clang::BuiltinType::UInt128:
4703 case clang::BuiltinType::Char_S:
4704 case clang::BuiltinType::SChar:
4705 case clang::BuiltinType::WChar_S:
4706 case clang::BuiltinType::Short:
4707 case clang::BuiltinType::Int:
4708 case clang::BuiltinType::Long:
4709 case clang::BuiltinType::LongLong:
4710 case clang::BuiltinType::Int128:
4711 case clang::BuiltinType::Float:
4712 case clang::BuiltinType::Double:
4713 case clang::BuiltinType::LongDouble:
4714 case clang::BuiltinType::Dependent:
4715 case clang::BuiltinType::Overload:
4716 case clang::BuiltinType::ObjCId:
4717 case clang::BuiltinType::ObjCClass:
4718 case clang::BuiltinType::ObjCSel:
4719 case clang::BuiltinType::BoundMember:
4720 break;
4721 }
4722 break;
4723 case clang::Type::Record:
4724 {
4725 CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
4726 if (cxx_record_decl)
4727 {
4728 if (GetCompleteQualType (ast, pointee_qual_type))
4729 {
Greg Claytona13ad2ad2011-06-02 01:26:44 +00004730 success = cxx_record_decl->isDynamicClass();
Greg Clayton007d5be2011-05-30 00:49:24 +00004731 }
4732 else
4733 {
4734 // We failed to get the complete type, so we have to
4735 // treat this as a void * which we might possibly be
4736 // able to complete
4737 success = true;
4738 }
4739 if (success)
4740 {
4741 if (dynamic_pointee_type)
4742 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4743 return true;
4744 }
4745 }
4746 }
4747 break;
4748
4749 default:
4750 break;
4751 }
4752 }
4753 }
4754 if (dynamic_pointee_type)
4755 *dynamic_pointee_type = NULL;
4756 return false;
4757}
4758
4759
4760bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004761ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004762{
4763 if (clang_type == NULL)
4764 return false;
4765
4766 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004767 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4768 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004769 {
Sean Callanana2424172010-10-25 00:29:48 +00004770 case clang::Type::Builtin:
4771 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4772 {
4773 default:
4774 break;
4775 case clang::BuiltinType::ObjCId:
4776 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004777 return true;
4778 }
4779 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004780 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004781 if (target_type)
4782 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4783 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004784 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004785 if (target_type)
4786 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4787 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004788 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004789 if (target_type)
4790 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4791 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004792 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004793 if (target_type)
4794 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4795 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004796 case clang::Type::LValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004797 if (target_type)
4798 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4799 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004800 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004801 if (target_type)
4802 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4803 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004804 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004805 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00004806 case clang::Type::Elaborated:
4807 return ClangASTContext::IsPointerOrReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004808 default:
4809 break;
4810 }
4811 return false;
4812}
4813
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004814bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004815ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004816{
4817 if (!clang_type)
4818 return false;
4819
4820 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4821 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
4822
4823 if (builtin_type)
4824 {
4825 if (builtin_type->isInteger())
4826 is_signed = builtin_type->isSignedInteger();
4827
4828 return true;
4829 }
4830
4831 return false;
4832}
4833
4834bool
Greg Claytonaffb03b2011-07-08 18:27:39 +00004835ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t *target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004836{
Greg Claytonaffb03b2011-07-08 18:27:39 +00004837 if (target_type)
4838 *target_type = NULL;
4839
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004840 if (clang_type)
4841 {
4842 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004843 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4844 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004845 {
Sean Callanana2424172010-10-25 00:29:48 +00004846 case clang::Type::Builtin:
4847 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4848 {
4849 default:
4850 break;
4851 case clang::BuiltinType::ObjCId:
4852 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004853 return true;
4854 }
4855 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004856 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004857 if (target_type)
4858 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4859 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004860 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004861 if (target_type)
4862 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4863 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004864 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004865 if (target_type)
4866 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4867 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004868 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004869 if (target_type)
4870 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4871 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004872 case clang::Type::Typedef:
Greg Claytonaffb03b2011-07-08 18:27:39 +00004873 return ClangASTContext::IsPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Sean Callanan912855f2011-08-11 23:56:13 +00004874 case clang::Type::Elaborated:
4875 return ClangASTContext::IsPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), target_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004876 default:
4877 break;
4878 }
4879 }
4880 return false;
4881}
4882
4883bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004884ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004885{
4886 if (clang_type)
4887 {
4888 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4889
4890 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
4891 {
4892 clang::BuiltinType::Kind kind = BT->getKind();
4893 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
4894 {
4895 count = 1;
4896 is_complex = false;
4897 return true;
4898 }
4899 }
4900 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
4901 {
4902 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
4903 {
4904 count = 2;
4905 is_complex = true;
4906 return true;
4907 }
4908 }
4909 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
4910 {
4911 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
4912 {
4913 count = VT->getNumElements();
4914 is_complex = false;
4915 return true;
4916 }
4917 }
4918 }
4919 return false;
4920}
4921
Enrico Granata9fc19442011-07-06 02:13:41 +00004922bool
4923ClangASTContext::IsScalarType (lldb::clang_type_t clang_type)
4924{
4925 bool is_signed;
4926 if (ClangASTContext::IsIntegerType(clang_type, is_signed))
4927 return true;
4928
4929 uint32_t count;
4930 bool is_complex;
4931 return ClangASTContext::IsFloatingPointType(clang_type, count, is_complex) && !is_complex;
4932}
4933
4934bool
4935ClangASTContext::IsPointerToScalarType (lldb::clang_type_t clang_type)
4936{
4937 if (!IsPointerType(clang_type))
4938 return false;
4939
4940 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4941 lldb::clang_type_t pointee_type = qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
4942 return IsScalarType(pointee_type);
4943}
4944
4945bool
4946ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type)
4947{
4948 if (!IsArrayType(clang_type))
4949 return false;
4950
4951 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4952 lldb::clang_type_t item_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
4953 return IsScalarType(item_type);
4954}
4955
Greg Clayton8f92f0a2010-10-14 22:52:14 +00004956
4957bool
4958ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
4959{
4960 if (clang_type)
4961 {
4962 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4963
4964 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4965 if (cxx_record_decl)
4966 {
4967 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
4968 return true;
4969 }
4970 }
4971 class_name.clear();
4972 return false;
4973}
4974
4975
Greg Clayton0fffff52010-09-24 05:15:53 +00004976bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004977ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004978{
4979 if (clang_type)
4980 {
4981 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4982 if (qual_type->getAsCXXRecordDecl() != NULL)
4983 return true;
4984 }
4985 return false;
4986}
4987
4988bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004989ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004990{
4991 if (clang_type)
4992 {
4993 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4994 if (qual_type->isObjCObjectOrInterfaceType())
4995 return true;
4996 }
4997 return false;
4998}
4999
5000
Greg Clayton73b472d2010-10-27 03:32:59 +00005001bool
5002ClangASTContext::IsCharType (clang_type_t clang_type)
5003{
5004 if (clang_type)
5005 return QualType::getFromOpaquePtr(clang_type)->isCharType();
5006 return false;
5007}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005008
5009bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005010ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005011{
Greg Clayton73b472d2010-10-27 03:32:59 +00005012 clang_type_t pointee_or_element_clang_type = NULL;
5013 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
5014
5015 if (pointee_or_element_clang_type == NULL)
5016 return false;
5017
5018 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005019 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005020 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
5021
5022 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005023 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005024 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5025 if (type_flags.Test (eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005026 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005027 // We know the size of the array and it could be a C string
5028 // since it is an array of characters
5029 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
5030 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005031 }
Greg Clayton73b472d2010-10-27 03:32:59 +00005032 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005033 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005034 length = 0;
5035 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005036 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005037
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005038 }
5039 }
5040 return false;
5041}
5042
5043bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005044ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton737b9322010-09-13 03:32:57 +00005045{
5046 if (clang_type)
5047 {
5048 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5049
5050 if (qual_type->isFunctionPointerType())
5051 return true;
5052
5053 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5054 switch (type_class)
5055 {
Sean Callananfb0b7582011-03-15 00:17:19 +00005056 default:
5057 break;
Greg Clayton737b9322010-09-13 03:32:57 +00005058 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00005059 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00005060 case clang::Type::Elaborated:
5061 return ClangASTContext::IsFunctionPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00005062
5063 case clang::Type::LValueReference:
5064 case clang::Type::RValueReference:
5065 {
Sean Callanan78e37602011-01-27 04:42:51 +00005066 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00005067 if (reference_type)
5068 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
5069 }
5070 break;
5071 }
5072 }
5073 return false;
5074}
5075
Greg Clayton73b472d2010-10-27 03:32:59 +00005076size_t
5077ClangASTContext::GetArraySize (clang_type_t clang_type)
5078{
5079 if (clang_type)
5080 {
Greg Claytonef37d68a2011-07-09 17:12:27 +00005081 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
5082 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5083 switch (type_class)
5084 {
5085 case clang::Type::ConstantArray:
5086 {
5087 const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
5088 if (array)
5089 return array->getSize().getLimitedValue();
5090 }
5091 break;
5092
5093 case clang::Type::Typedef:
5094 return ClangASTContext::GetArraySize(cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00005095
5096 case clang::Type::Elaborated:
5097 return ClangASTContext::GetArraySize(cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00005098
5099 default:
5100 break;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005101 }
Greg Clayton73b472d2010-10-27 03:32:59 +00005102 }
5103 return 0;
5104}
Greg Clayton737b9322010-09-13 03:32:57 +00005105
5106bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005107ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005108{
5109 if (!clang_type)
5110 return false;
5111
5112 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5113
Greg Clayton737b9322010-09-13 03:32:57 +00005114 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5115 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005116 {
Sean Callananfb0b7582011-03-15 00:17:19 +00005117 default:
5118 break;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005119
Greg Claytone1a916a2010-07-21 22:12:05 +00005120 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005121 if (member_type)
5122 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5123 if (size)
Greg Claytonac4827f2011-04-01 18:14:08 +00005124 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005125 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005126
Greg Claytone1a916a2010-07-21 22:12:05 +00005127 case clang::Type::IncompleteArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005128 if (member_type)
5129 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5130 if (size)
5131 *size = 0;
5132 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005133
Greg Claytone1a916a2010-07-21 22:12:05 +00005134 case clang::Type::VariableArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005135 if (member_type)
5136 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5137 if (size)
5138 *size = 0;
Greg Clayton03dbf2e2011-02-02 00:52:14 +00005139 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005140
Greg Claytone1a916a2010-07-21 22:12:05 +00005141 case clang::Type::DependentSizedArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005142 if (member_type)
5143 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5144 if (size)
5145 *size = 0;
5146 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005147
5148 case clang::Type::Typedef:
5149 return ClangASTContext::IsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
5150 member_type,
5151 size);
Sean Callanan912855f2011-08-11 23:56:13 +00005152
5153 case clang::Type::Elaborated:
5154 return ClangASTContext::IsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
5155 member_type,
5156 size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005157 }
5158 return false;
5159}
5160
5161
5162#pragma mark Typedefs
5163
Greg Clayton1be10fc2010-09-29 01:12:09 +00005164clang_type_t
5165ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005166{
5167 if (clang_type)
5168 {
5169 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00005170 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005171 IdentifierTable *identifier_table = getIdentifierTable();
Greg Clayton6beaaa62011-01-17 03:46:26 +00005172 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005173 assert (identifier_table != NULL);
5174 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00005175 decl_ctx = ast->getTranslationUnitDecl();
5176 TypedefDecl *decl = TypedefDecl::Create (*ast,
5177 decl_ctx,
5178 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00005179 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00005180 name ? &identifier_table->get(name) : NULL, // Identifier
5181 ast->CreateTypeSourceInfo(qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00005182
5183 decl->setAccess(AS_public); // TODO respect proper access specifier
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005184
5185 // Get a uniqued QualType for the typedef decl type
Greg Clayton6beaaa62011-01-17 03:46:26 +00005186 return ast->getTypedefType (decl).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005187 }
5188 return NULL;
5189}
5190
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005191// Disable this for now since I can't seem to get a nicely formatted float
5192// out of the APFloat class without just getting the float, double or quad
5193// and then using a formatted print on it which defeats the purpose. We ideally
5194// would like to get perfect string values for any kind of float semantics
5195// so we can support remote targets. The code below also requires a patch to
5196// llvm::APInt.
5197//bool
Greg Clayton6beaaa62011-01-17 03:46:26 +00005198//ClangASTContext::ConvertFloatValueToString (ASTContext *ast, clang_type_t clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005199//{
5200// uint32_t count = 0;
5201// bool is_complex = false;
5202// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
5203// {
5204// unsigned num_bytes_per_float = byte_size / count;
5205// unsigned num_bits_per_float = num_bytes_per_float * 8;
5206//
5207// float_str.clear();
5208// uint32_t i;
5209// for (i=0; i<count; i++)
5210// {
5211// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
5212// bool is_ieee = false;
5213// APFloat ap_float(ap_int, is_ieee);
5214// char s[1024];
5215// unsigned int hex_digits = 0;
5216// bool upper_case = false;
5217//
5218// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
5219// {
5220// if (i > 0)
5221// float_str.append(", ");
5222// float_str.append(s);
5223// if (i == 1 && is_complex)
5224// float_str.append(1, 'i');
5225// }
5226// }
5227// return !float_str.empty();
5228// }
5229// return false;
5230//}
5231
5232size_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00005233ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005234{
5235 if (clang_type)
5236 {
5237 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5238 uint32_t count = 0;
5239 bool is_complex = false;
5240 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
5241 {
5242 // TODO: handle complex and vector types
5243 if (count != 1)
5244 return false;
5245
5246 StringRef s_sref(s);
Greg Clayton6beaaa62011-01-17 03:46:26 +00005247 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005248
Greg Clayton6beaaa62011-01-17 03:46:26 +00005249 const uint64_t bit_size = ast->getTypeSize (qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005250 const uint64_t byte_size = bit_size / 8;
5251 if (dst_size >= byte_size)
5252 {
5253 if (bit_size == sizeof(float)*8)
5254 {
5255 float float32 = ap_float.convertToFloat();
5256 ::memcpy (dst, &float32, byte_size);
5257 return byte_size;
5258 }
5259 else if (bit_size >= 64)
5260 {
5261 llvm::APInt ap_int(ap_float.bitcastToAPInt());
5262 ::memcpy (dst, ap_int.getRawData(), byte_size);
5263 return byte_size;
5264 }
5265 }
5266 }
5267 }
5268 return 0;
5269}
Sean Callanan6fe64b52010-09-17 02:24:29 +00005270
5271unsigned
Greg Clayton1be10fc2010-09-29 01:12:09 +00005272ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanan6fe64b52010-09-17 02:24:29 +00005273{
5274 assert (clang_type);
5275
5276 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5277
5278 return qual_type.getQualifiers().getCVRQualifiers();
5279}
Greg Clayton6beaaa62011-01-17 03:46:26 +00005280
5281bool
5282ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
5283{
5284 if (clang_type == NULL)
5285 return false;
5286
Greg Claytonc432c192011-01-20 04:18:48 +00005287 return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00005288}
5289
5290
5291bool
5292ClangASTContext::GetCompleteType (clang_type_t clang_type)
5293{
5294 return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
5295}
5296
Greg Claytona2721472011-06-25 00:44:06 +00005297bool
5298ClangASTContext::GetCompleteDecl (clang::ASTContext *ast,
5299 clang::Decl *decl)
5300{
5301 if (!decl)
5302 return false;
5303
5304 ExternalASTSource *ast_source = ast->getExternalSource();
5305
5306 if (!ast_source)
5307 return false;
5308
5309 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
5310 {
5311 if (tag_decl->getDefinition())
5312 return true;
5313
5314 if (!tag_decl->hasExternalLexicalStorage())
5315 return false;
5316
5317 ast_source->CompleteType(tag_decl);
5318
5319 return !tag_decl->getTypeForDecl()->isIncompleteType();
5320 }
5321 else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
5322 {
5323 if (!objc_interface_decl->isForwardDecl())
5324 return true;
5325
5326 if (!objc_interface_decl->hasExternalLexicalStorage())
5327 return false;
5328
5329 ast_source->CompleteType(objc_interface_decl);
5330
5331 return !objc_interface_decl->isForwardDecl();
5332 }
5333 else
5334 {
5335 return false;
5336 }
5337}
5338
Greg Clayton2c5f0e92011-08-04 21:02:57 +00005339clang::DeclContext *
5340ClangASTContext::GetAsDeclContext (clang::CXXMethodDecl *cxx_method_decl)
5341{
Sean Callanana87bee82011-08-19 06:19:25 +00005342 return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00005343}
5344
5345clang::DeclContext *
5346ClangASTContext::GetAsDeclContext (clang::ObjCMethodDecl *objc_method_decl)
5347{
Sean Callanana87bee82011-08-19 06:19:25 +00005348 return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00005349}
5350