blob: 43996398e1d5ce392118cc0cac32cf24ba111d85 [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;
Greg Claytonc14ee322011-09-22 04:58:26 +00003117 Process *process = NULL;
3118 if (exe_ctx)
3119 process = exe_ctx->GetProcessPtr();
3120 if (process)
Jim Inghamd555bac2011-06-24 22:03:24 +00003121 {
Greg Claytonc14ee322011-09-22 04:58:26 +00003122 ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
Jim Inghamd555bac2011-06-24 22:03:24 +00003123 if (objc_runtime != NULL)
3124 {
Enrico Granata6f3533f2011-07-29 19:53:35 +00003125 ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
Jim Inghamd555bac2011-06-24 22:03:24 +00003126 child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
3127 }
3128 }
3129
3130 if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
3131 {
3132 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
3133 child_byte_offset = bit_offset / 8;
3134 }
Greg Clayton9e409562010-07-28 02:04:09 +00003135
3136 return ivar_qual_type.getAsOpaquePtr();
3137 }
3138 ++child_idx;
3139 }
3140 }
3141 }
3142 }
3143 }
3144 break;
3145
3146 case clang::Type::ObjCObjectPointer:
3147 {
Sean Callanan78e37602011-01-27 04:42:51 +00003148 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003149 QualType pointee_type = pointer_type->getPointeeType();
3150
3151 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3152 {
Greg Claytone221f822011-01-21 01:59:00 +00003153 child_is_deref_of_parent = false;
3154 bool tmp_child_is_deref_of_parent = false;
Jim Inghamd555bac2011-06-24 22:03:24 +00003155 return GetChildClangTypeAtIndex (exe_ctx,
3156 ast,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003157 parent_name,
3158 pointer_type->getPointeeType().getAsOpaquePtr(),
3159 idx,
3160 transparent_pointers,
3161 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003162 ignore_array_bounds,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003163 child_name,
3164 child_byte_size,
3165 child_byte_offset,
3166 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003167 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003168 child_is_base_class,
3169 tmp_child_is_deref_of_parent);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003170 }
3171 else
3172 {
Greg Claytone221f822011-01-21 01:59:00 +00003173 child_is_deref_of_parent = true;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003174 if (parent_name)
3175 {
3176 child_name.assign(1, '*');
3177 child_name += parent_name;
3178 }
3179
3180 // We have a pointer to an simple type
3181 if (idx == 0)
3182 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003183 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003184 assert(clang_type_info.first % 8 == 0);
3185 child_byte_size = clang_type_info.first / 8;
3186 child_byte_offset = 0;
3187 return pointee_type.getAsOpaquePtr();
3188 }
3189 }
Greg Clayton9e409562010-07-28 02:04:09 +00003190 }
3191 break;
3192
Greg Claytone1a916a2010-07-21 22:12:05 +00003193 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003194 {
3195 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3196 const uint64_t element_count = array->getSize().getLimitedValue();
3197
Greg Claytondaf515f2011-07-09 20:12:33 +00003198 if (ignore_array_bounds || idx < element_count)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003199 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003200 if (GetCompleteQualType (ast, array->getElementType()))
3201 {
3202 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003203
Greg Clayton6beaaa62011-01-17 03:46:26 +00003204 char element_name[64];
3205 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003206
Greg Clayton6beaaa62011-01-17 03:46:26 +00003207 child_name.assign(element_name);
3208 assert(field_type_info.first % 8 == 0);
3209 child_byte_size = field_type_info.first / 8;
Greg Claytondaf515f2011-07-09 20:12:33 +00003210 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003211 return array->getElementType().getAsOpaquePtr();
3212 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003213 }
3214 }
3215 break;
3216
Greg Claytone1a916a2010-07-21 22:12:05 +00003217 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003218 {
Sean Callanan78e37602011-01-27 04:42:51 +00003219 const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003220 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton97a43712011-01-08 22:26:47 +00003221
3222 // Don't dereference "void *" pointers
3223 if (pointee_type->isVoidType())
3224 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003225
3226 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3227 {
Greg Claytone221f822011-01-21 01:59:00 +00003228 child_is_deref_of_parent = false;
3229 bool tmp_child_is_deref_of_parent = false;
Jim Inghamd555bac2011-06-24 22:03:24 +00003230 return GetChildClangTypeAtIndex (exe_ctx,
3231 ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003232 parent_name,
3233 pointer_type->getPointeeType().getAsOpaquePtr(),
3234 idx,
3235 transparent_pointers,
3236 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003237 ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003238 child_name,
3239 child_byte_size,
3240 child_byte_offset,
3241 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003242 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003243 child_is_base_class,
3244 tmp_child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003245 }
3246 else
3247 {
Greg Claytone221f822011-01-21 01:59:00 +00003248 child_is_deref_of_parent = true;
3249
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003250 if (parent_name)
3251 {
3252 child_name.assign(1, '*');
3253 child_name += parent_name;
3254 }
3255
3256 // We have a pointer to an simple type
3257 if (idx == 0)
3258 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003259 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003260 assert(clang_type_info.first % 8 == 0);
3261 child_byte_size = clang_type_info.first / 8;
3262 child_byte_offset = 0;
3263 return pointee_type.getAsOpaquePtr();
3264 }
3265 }
3266 }
3267 break;
3268
Greg Clayton73b472d2010-10-27 03:32:59 +00003269 case clang::Type::LValueReference:
3270 case clang::Type::RValueReference:
3271 {
Sean Callanan78e37602011-01-27 04:42:51 +00003272 const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00003273 QualType pointee_type(reference_type->getPointeeType());
3274 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
3275 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
3276 {
Greg Claytone221f822011-01-21 01:59:00 +00003277 child_is_deref_of_parent = false;
3278 bool tmp_child_is_deref_of_parent = false;
Jim Inghamd555bac2011-06-24 22:03:24 +00003279 return GetChildClangTypeAtIndex (exe_ctx,
3280 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00003281 parent_name,
3282 pointee_clang_type,
3283 idx,
3284 transparent_pointers,
3285 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003286 ignore_array_bounds,
Greg Clayton73b472d2010-10-27 03:32:59 +00003287 child_name,
3288 child_byte_size,
3289 child_byte_offset,
3290 child_bitfield_bit_size,
3291 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003292 child_is_base_class,
3293 tmp_child_is_deref_of_parent);
Greg Clayton73b472d2010-10-27 03:32:59 +00003294 }
3295 else
3296 {
3297 if (parent_name)
3298 {
3299 child_name.assign(1, '&');
3300 child_name += parent_name;
3301 }
3302
3303 // We have a pointer to an simple type
3304 if (idx == 0)
3305 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003306 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Clayton73b472d2010-10-27 03:32:59 +00003307 assert(clang_type_info.first % 8 == 0);
3308 child_byte_size = clang_type_info.first / 8;
3309 child_byte_offset = 0;
3310 return pointee_type.getAsOpaquePtr();
3311 }
3312 }
3313 }
3314 break;
3315
Greg Claytone1a916a2010-07-21 22:12:05 +00003316 case clang::Type::Typedef:
Jim Inghamd555bac2011-06-24 22:03:24 +00003317 return GetChildClangTypeAtIndex (exe_ctx,
3318 ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003319 parent_name,
Sean Callanan48114472010-12-13 01:26:27 +00003320 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003321 idx,
3322 transparent_pointers,
3323 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003324 ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003325 child_name,
3326 child_byte_size,
3327 child_byte_offset,
3328 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003329 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003330 child_is_base_class,
3331 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003332 break;
Sean Callanan912855f2011-08-11 23:56:13 +00003333
3334 case clang::Type::Elaborated:
3335 return GetChildClangTypeAtIndex (exe_ctx,
3336 ast,
3337 parent_name,
3338 cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
3339 idx,
3340 transparent_pointers,
3341 omit_empty_base_classes,
3342 ignore_array_bounds,
3343 child_name,
3344 child_byte_size,
3345 child_byte_offset,
3346 child_bitfield_bit_size,
3347 child_bitfield_bit_offset,
3348 child_is_base_class,
3349 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003350
3351 default:
3352 break;
3353 }
3354 }
Greg Clayton19503a22010-07-23 15:37:46 +00003355 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003356}
3357
3358static inline bool
3359BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
3360{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003361 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003362}
3363
3364static uint32_t
3365GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
3366{
3367 uint32_t num_bases = 0;
3368 if (cxx_record_decl)
3369 {
3370 if (omit_empty_base_classes)
3371 {
3372 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3373 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3374 base_class != base_class_end;
3375 ++base_class)
3376 {
3377 // Skip empty base classes
3378 if (omit_empty_base_classes)
3379 {
3380 if (BaseSpecifierIsEmpty (base_class))
3381 continue;
3382 }
3383 ++num_bases;
3384 }
3385 }
3386 else
3387 num_bases = cxx_record_decl->getNumBases();
3388 }
3389 return num_bases;
3390}
3391
3392
3393static uint32_t
3394GetIndexForRecordBase
3395(
3396 const RecordDecl *record_decl,
3397 const CXXBaseSpecifier *base_spec,
3398 bool omit_empty_base_classes
3399)
3400{
3401 uint32_t child_idx = 0;
3402
3403 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3404
3405// const char *super_name = record_decl->getNameAsCString();
3406// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
3407// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
3408//
3409 if (cxx_record_decl)
3410 {
3411 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3412 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3413 base_class != base_class_end;
3414 ++base_class)
3415 {
3416 if (omit_empty_base_classes)
3417 {
3418 if (BaseSpecifierIsEmpty (base_class))
3419 continue;
3420 }
3421
3422// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
3423// child_idx,
3424// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
3425//
3426//
3427 if (base_class == base_spec)
3428 return child_idx;
3429 ++child_idx;
3430 }
3431 }
3432
3433 return UINT32_MAX;
3434}
3435
3436
3437static uint32_t
3438GetIndexForRecordChild
3439(
3440 const RecordDecl *record_decl,
3441 NamedDecl *canonical_decl,
3442 bool omit_empty_base_classes
3443)
3444{
3445 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
3446
3447// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3448//
3449//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
3450// if (cxx_record_decl)
3451// {
3452// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3453// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3454// base_class != base_class_end;
3455// ++base_class)
3456// {
3457// if (omit_empty_base_classes)
3458// {
3459// if (BaseSpecifierIsEmpty (base_class))
3460// continue;
3461// }
3462//
3463//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
3464//// record_decl->getNameAsCString(),
3465//// canonical_decl->getNameAsCString(),
3466//// child_idx,
3467//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
3468//
3469//
3470// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3471// if (curr_base_class_decl == canonical_decl)
3472// {
3473// return child_idx;
3474// }
3475// ++child_idx;
3476// }
3477// }
3478//
3479// const uint32_t num_bases = child_idx;
3480 RecordDecl::field_iterator field, field_end;
3481 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3482 field != field_end;
3483 ++field, ++child_idx)
3484 {
3485// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
3486// record_decl->getNameAsCString(),
3487// canonical_decl->getNameAsCString(),
3488// child_idx - num_bases,
3489// field->getNameAsCString());
3490
3491 if (field->getCanonicalDecl() == canonical_decl)
3492 return child_idx;
3493 }
3494
3495 return UINT32_MAX;
3496}
3497
3498// Look for a child member (doesn't include base classes, but it does include
3499// their members) in the type hierarchy. Returns an index path into "clang_type"
3500// on how to reach the appropriate member.
3501//
3502// class A
3503// {
3504// public:
3505// int m_a;
3506// int m_b;
3507// };
3508//
3509// class B
3510// {
3511// };
3512//
3513// class C :
3514// public B,
3515// public A
3516// {
3517// };
3518//
3519// If we have a clang type that describes "class C", and we wanted to looked
3520// "m_b" in it:
3521//
3522// With omit_empty_base_classes == false we would get an integer array back with:
3523// { 1, 1 }
3524// The first index 1 is the child index for "class A" within class C
3525// The second index 1 is the child index for "m_b" within class A
3526//
3527// With omit_empty_base_classes == true we would get an integer array back with:
3528// { 0, 1 }
3529// 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)
3530// The second index 1 is the child index for "m_b" within class A
3531
3532size_t
3533ClangASTContext::GetIndexOfChildMemberWithName
3534(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003535 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003536 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003537 const char *name,
3538 bool omit_empty_base_classes,
3539 std::vector<uint32_t>& child_indexes
3540)
3541{
3542 if (clang_type && name && name[0])
3543 {
3544 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003545 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3546 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003547 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003548 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003549 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003550 {
3551 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3552 const RecordDecl *record_decl = record_type->getDecl();
3553
3554 assert(record_decl);
3555 uint32_t child_idx = 0;
3556
3557 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3558
3559 // Try and find a field that matches NAME
3560 RecordDecl::field_iterator field, field_end;
3561 StringRef name_sref(name);
3562 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3563 field != field_end;
3564 ++field, ++child_idx)
3565 {
3566 if (field->getName().equals (name_sref))
3567 {
3568 // We have to add on the number of base classes to this index!
3569 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
3570 return child_indexes.size();
3571 }
3572 }
3573
3574 if (cxx_record_decl)
3575 {
3576 const RecordDecl *parent_record_decl = cxx_record_decl;
3577
3578 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
3579
3580 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
3581 // Didn't find things easily, lets let clang do its thang...
Sean Callanancc427fa2011-07-30 02:42:06 +00003582 IdentifierInfo & ident_ref = ast->Idents.get(name_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003583 DeclarationName decl_name(&ident_ref);
3584
3585 CXXBasePaths paths;
3586 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
3587 decl_name.getAsOpaquePtr(),
3588 paths))
3589 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003590 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
3591 for (path = paths.begin(); path != path_end; ++path)
3592 {
3593 const size_t num_path_elements = path->size();
3594 for (size_t e=0; e<num_path_elements; ++e)
3595 {
3596 CXXBasePathElement elem = (*path)[e];
3597
3598 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
3599 if (child_idx == UINT32_MAX)
3600 {
3601 child_indexes.clear();
3602 return 0;
3603 }
3604 else
3605 {
3606 child_indexes.push_back (child_idx);
3607 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
3608 }
3609 }
3610 DeclContext::lookup_iterator named_decl_pos;
3611 for (named_decl_pos = path->Decls.first;
3612 named_decl_pos != path->Decls.second && parent_record_decl;
3613 ++named_decl_pos)
3614 {
3615 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
3616
3617 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
3618 if (child_idx == UINT32_MAX)
3619 {
3620 child_indexes.clear();
3621 return 0;
3622 }
3623 else
3624 {
3625 child_indexes.push_back (child_idx);
3626 }
3627 }
3628 }
3629 return child_indexes.size();
3630 }
3631 }
3632
3633 }
3634 break;
3635
Greg Clayton9e409562010-07-28 02:04:09 +00003636 case clang::Type::ObjCObject:
3637 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003638 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003639 {
3640 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003641 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003642 assert (objc_class_type);
3643 if (objc_class_type)
3644 {
3645 uint32_t child_idx = 0;
3646 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3647
3648 if (class_interface_decl)
3649 {
3650 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3651 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3652
Greg Clayton6ba78152010-09-18 02:11:07 +00003653 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9e409562010-07-28 02:04:09 +00003654 {
3655 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3656
3657 if (ivar_decl->getName().equals (name_sref))
3658 {
3659 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3660 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3661 ++child_idx;
3662
3663 child_indexes.push_back (child_idx);
3664 return child_indexes.size();
3665 }
3666 }
3667
3668 if (superclass_interface_decl)
3669 {
3670 // The super class index is always zero for ObjC classes,
3671 // so we push it onto the child indexes in case we find
3672 // an ivar in our superclass...
3673 child_indexes.push_back (0);
3674
Greg Clayton6beaaa62011-01-17 03:46:26 +00003675 if (GetIndexOfChildMemberWithName (ast,
3676 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00003677 name,
3678 omit_empty_base_classes,
3679 child_indexes))
3680 {
3681 // We did find an ivar in a superclass so just
3682 // return the results!
3683 return child_indexes.size();
3684 }
3685
3686 // We didn't find an ivar matching "name" in our
3687 // superclass, pop the superclass zero index that
3688 // we pushed on above.
3689 child_indexes.pop_back();
3690 }
3691 }
3692 }
3693 }
3694 break;
3695
3696 case clang::Type::ObjCObjectPointer:
3697 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003698 return GetIndexOfChildMemberWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003699 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3700 name,
3701 omit_empty_base_classes,
3702 child_indexes);
3703 }
3704 break;
3705
3706
Greg Claytone1a916a2010-07-21 22:12:05 +00003707 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003708 {
3709// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3710// const uint64_t element_count = array->getSize().getLimitedValue();
3711//
3712// if (idx < element_count)
3713// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003714// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003715//
3716// char element_name[32];
3717// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3718//
3719// child_name.assign(element_name);
3720// assert(field_type_info.first % 8 == 0);
3721// child_byte_size = field_type_info.first / 8;
3722// child_byte_offset = idx * child_byte_size;
3723// return array->getElementType().getAsOpaquePtr();
3724// }
3725 }
3726 break;
3727
Greg Claytone1a916a2010-07-21 22:12:05 +00003728// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003729// {
3730// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3731// QualType pointee_type = mem_ptr_type->getPointeeType();
3732//
3733// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3734// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003735// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003736// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3737// name);
3738// }
3739// }
3740// break;
3741//
Greg Claytone1a916a2010-07-21 22:12:05 +00003742 case clang::Type::LValueReference:
3743 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003744 {
Sean Callanan78e37602011-01-27 04:42:51 +00003745 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003746 QualType pointee_type = reference_type->getPointeeType();
3747
3748 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3749 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003750 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003751 reference_type->getPointeeType().getAsOpaquePtr(),
3752 name,
3753 omit_empty_base_classes,
3754 child_indexes);
3755 }
3756 }
3757 break;
3758
Greg Claytone1a916a2010-07-21 22:12:05 +00003759 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003760 {
Sean Callanan78e37602011-01-27 04:42:51 +00003761 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003762 QualType pointee_type = pointer_type->getPointeeType();
3763
3764 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3765 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003766 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003767 pointer_type->getPointeeType().getAsOpaquePtr(),
3768 name,
3769 omit_empty_base_classes,
3770 child_indexes);
3771 }
3772 else
3773 {
3774// if (parent_name)
3775// {
3776// child_name.assign(1, '*');
3777// child_name += parent_name;
3778// }
3779//
3780// // We have a pointer to an simple type
3781// if (idx == 0)
3782// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003783// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003784// assert(clang_type_info.first % 8 == 0);
3785// child_byte_size = clang_type_info.first / 8;
3786// child_byte_offset = 0;
3787// return pointee_type.getAsOpaquePtr();
3788// }
3789 }
3790 }
3791 break;
3792
Greg Claytone1a916a2010-07-21 22:12:05 +00003793 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003794 return GetIndexOfChildMemberWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003795 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003796 name,
3797 omit_empty_base_classes,
3798 child_indexes);
3799
3800 default:
3801 break;
3802 }
3803 }
3804 return 0;
3805}
3806
3807
3808// Get the index of the child of "clang_type" whose name matches. This function
3809// doesn't descend into the children, but only looks one level deep and name
3810// matches can include base class names.
3811
3812uint32_t
3813ClangASTContext::GetIndexOfChildWithName
3814(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003815 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003816 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003817 const char *name,
3818 bool omit_empty_base_classes
3819)
3820{
3821 if (clang_type && name && name[0])
3822 {
3823 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00003824
Greg Clayton737b9322010-09-13 03:32:57 +00003825 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9e409562010-07-28 02:04:09 +00003826
Greg Clayton737b9322010-09-13 03:32:57 +00003827 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003828 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003829 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003830 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003831 {
3832 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3833 const RecordDecl *record_decl = record_type->getDecl();
3834
3835 assert(record_decl);
3836 uint32_t child_idx = 0;
3837
3838 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3839
3840 if (cxx_record_decl)
3841 {
3842 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3843 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3844 base_class != base_class_end;
3845 ++base_class)
3846 {
3847 // Skip empty base classes
3848 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3849 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3850 continue;
3851
Greg Claytone3055942011-06-30 02:28:26 +00003852 std::string base_class_type_name (ClangASTType::GetTypeNameForQualType(base_class->getType()));
3853 if (base_class_type_name.compare (name) == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003854 return child_idx;
3855 ++child_idx;
3856 }
3857 }
3858
3859 // Try and find a field that matches NAME
3860 RecordDecl::field_iterator field, field_end;
3861 StringRef name_sref(name);
3862 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3863 field != field_end;
3864 ++field, ++child_idx)
3865 {
3866 if (field->getName().equals (name_sref))
3867 return child_idx;
3868 }
3869
3870 }
3871 break;
3872
Greg Clayton9e409562010-07-28 02:04:09 +00003873 case clang::Type::ObjCObject:
3874 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003875 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003876 {
3877 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003878 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003879 assert (objc_class_type);
3880 if (objc_class_type)
3881 {
3882 uint32_t child_idx = 0;
3883 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3884
3885 if (class_interface_decl)
3886 {
3887 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3888 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3889
3890 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3891 {
3892 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3893
3894 if (ivar_decl->getName().equals (name_sref))
3895 {
3896 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3897 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3898 ++child_idx;
3899
3900 return child_idx;
3901 }
3902 }
3903
3904 if (superclass_interface_decl)
3905 {
3906 if (superclass_interface_decl->getName().equals (name_sref))
3907 return 0;
3908 }
3909 }
3910 }
3911 }
3912 break;
3913
3914 case clang::Type::ObjCObjectPointer:
3915 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003916 return GetIndexOfChildWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003917 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3918 name,
3919 omit_empty_base_classes);
3920 }
3921 break;
3922
Greg Claytone1a916a2010-07-21 22:12:05 +00003923 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003924 {
3925// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3926// const uint64_t element_count = array->getSize().getLimitedValue();
3927//
3928// if (idx < element_count)
3929// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003930// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003931//
3932// char element_name[32];
3933// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3934//
3935// child_name.assign(element_name);
3936// assert(field_type_info.first % 8 == 0);
3937// child_byte_size = field_type_info.first / 8;
3938// child_byte_offset = idx * child_byte_size;
3939// return array->getElementType().getAsOpaquePtr();
3940// }
3941 }
3942 break;
3943
Greg Claytone1a916a2010-07-21 22:12:05 +00003944// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003945// {
3946// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3947// QualType pointee_type = mem_ptr_type->getPointeeType();
3948//
3949// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3950// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003951// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003952// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3953// name);
3954// }
3955// }
3956// break;
3957//
Greg Claytone1a916a2010-07-21 22:12:05 +00003958 case clang::Type::LValueReference:
3959 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003960 {
Sean Callanan78e37602011-01-27 04:42:51 +00003961 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003962 QualType pointee_type = reference_type->getPointeeType();
3963
3964 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3965 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003966 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003967 reference_type->getPointeeType().getAsOpaquePtr(),
3968 name,
3969 omit_empty_base_classes);
3970 }
3971 }
3972 break;
3973
Greg Claytone1a916a2010-07-21 22:12:05 +00003974 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003975 {
Sean Callanan78e37602011-01-27 04:42:51 +00003976 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003977 QualType pointee_type = pointer_type->getPointeeType();
3978
3979 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3980 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003981 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003982 pointer_type->getPointeeType().getAsOpaquePtr(),
3983 name,
3984 omit_empty_base_classes);
3985 }
3986 else
3987 {
3988// if (parent_name)
3989// {
3990// child_name.assign(1, '*');
3991// child_name += parent_name;
3992// }
3993//
3994// // We have a pointer to an simple type
3995// if (idx == 0)
3996// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003997// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003998// assert(clang_type_info.first % 8 == 0);
3999// child_byte_size = clang_type_info.first / 8;
4000// child_byte_offset = 0;
4001// return pointee_type.getAsOpaquePtr();
4002// }
4003 }
4004 }
4005 break;
4006
Greg Claytone1a916a2010-07-21 22:12:05 +00004007 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00004008 return GetIndexOfChildWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00004009 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004010 name,
4011 omit_empty_base_classes);
4012
4013 default:
4014 break;
4015 }
4016 }
4017 return UINT32_MAX;
4018}
4019
4020#pragma mark TagType
4021
4022bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004023ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004024{
4025 if (tag_clang_type)
4026 {
4027 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00004028 const clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004029 if (clang_type)
4030 {
Sean Callanan78e37602011-01-27 04:42:51 +00004031 const TagType *tag_type = dyn_cast<TagType>(clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004032 if (tag_type)
4033 {
4034 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
4035 if (tag_decl)
4036 {
4037 tag_decl->setTagKind ((TagDecl::TagKind)kind);
4038 return true;
4039 }
4040 }
4041 }
4042 }
4043 return false;
4044}
4045
4046
4047#pragma mark DeclContext Functions
4048
4049DeclContext *
Greg Clayton1be10fc2010-09-29 01:12:09 +00004050ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004051{
4052 if (clang_type == NULL)
4053 return NULL;
4054
4055 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004056 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4057 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004058 {
Sean Callanancc427fa2011-07-30 02:42:06 +00004059 case clang::Type::UnaryTransform: break;
Greg Clayton9e409562010-07-28 02:04:09 +00004060 case clang::Type::FunctionNoProto: break;
4061 case clang::Type::FunctionProto: break;
4062 case clang::Type::IncompleteArray: break;
4063 case clang::Type::VariableArray: break;
4064 case clang::Type::ConstantArray: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004065 case clang::Type::DependentSizedArray: break;
Greg Clayton9e409562010-07-28 02:04:09 +00004066 case clang::Type::ExtVector: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004067 case clang::Type::DependentSizedExtVector: break;
Greg Clayton9e409562010-07-28 02:04:09 +00004068 case clang::Type::Vector: break;
4069 case clang::Type::Builtin: break;
4070 case clang::Type::BlockPointer: break;
4071 case clang::Type::Pointer: break;
4072 case clang::Type::LValueReference: break;
4073 case clang::Type::RValueReference: break;
4074 case clang::Type::MemberPointer: break;
4075 case clang::Type::Complex: break;
4076 case clang::Type::ObjCObject: break;
4077 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
4078 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
4079 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
4080 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
Sean Callanan48114472010-12-13 01:26:27 +00004081 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00004082 case clang::Type::Elaborated: return ClangASTContext::GetDeclContextForType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00004083 case clang::Type::TypeOfExpr: break;
4084 case clang::Type::TypeOf: break;
4085 case clang::Type::Decltype: break;
4086 //case clang::Type::QualifiedName: break;
4087 case clang::Type::TemplateSpecialization: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004088 case clang::Type::DependentTemplateSpecialization: break;
4089 case clang::Type::TemplateTypeParm: break;
4090 case clang::Type::SubstTemplateTypeParm: break;
4091 case clang::Type::SubstTemplateTypeParmPack:break;
4092 case clang::Type::PackExpansion: break;
4093 case clang::Type::UnresolvedUsing: break;
4094 case clang::Type::Paren: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004095 case clang::Type::Attributed: break;
4096 case clang::Type::Auto: break;
4097 case clang::Type::InjectedClassName: break;
4098 case clang::Type::DependentName: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004099 }
4100 // No DeclContext in this type...
4101 return NULL;
4102}
4103
4104#pragma mark Namespace Declarations
4105
4106NamespaceDecl *
4107ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
4108{
4109 // TODO: Do something intelligent with the Declaration object passed in
4110 // like maybe filling in the SourceLocation with it...
4111 if (name)
4112 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004113 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004114 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00004115 decl_ctx = ast->getTranslationUnitDecl();
Sean Callananfb0b7582011-03-15 00:17:19 +00004116 return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &ast->Idents.get(name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004117 }
4118 return NULL;
4119}
4120
4121
4122#pragma mark Function Types
4123
4124FunctionDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00004125ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004126{
4127 if (name)
4128 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004129 ASTContext *ast = getASTContext();
4130 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004131
4132 if (name && name[0])
4133 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004134 return FunctionDecl::Create(*ast,
4135 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004136 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004137 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00004138 DeclarationName (&ast->Idents.get(name)),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004139 QualType::getFromOpaquePtr(function_clang_type),
4140 NULL,
4141 (FunctionDecl::StorageClass)storage,
4142 (FunctionDecl::StorageClass)storage,
4143 is_inline);
4144 }
4145 else
4146 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004147 return FunctionDecl::Create(*ast,
4148 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004149 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004150 SourceLocation(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004151 DeclarationName (),
4152 QualType::getFromOpaquePtr(function_clang_type),
4153 NULL,
4154 (FunctionDecl::StorageClass)storage,
4155 (FunctionDecl::StorageClass)storage,
4156 is_inline);
4157 }
4158 }
4159 return NULL;
4160}
4161
Greg Clayton1be10fc2010-09-29 01:12:09 +00004162clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00004163ClangASTContext::CreateFunctionType (ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00004164 clang_type_t result_type,
4165 clang_type_t *args,
Sean Callananc81256a2010-09-16 20:40:25 +00004166 unsigned num_args,
4167 bool is_variadic,
4168 unsigned type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004169{
Greg Clayton6beaaa62011-01-17 03:46:26 +00004170 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004171 std::vector<QualType> qual_type_args;
4172 for (unsigned i=0; i<num_args; ++i)
4173 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
4174
4175 // TODO: Detect calling convention in DWARF?
Sean Callanan2c777c42011-01-18 23:32:05 +00004176 FunctionProtoType::ExtProtoInfo proto_info;
4177 proto_info.Variadic = is_variadic;
Sean Callananfb0b7582011-03-15 00:17:19 +00004178 proto_info.ExceptionSpecType = EST_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00004179 proto_info.TypeQuals = type_quals;
Sean Callananfb0b7582011-03-15 00:17:19 +00004180 proto_info.RefQualifier = RQ_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00004181 proto_info.NumExceptions = 0;
4182 proto_info.Exceptions = NULL;
4183
Greg Clayton6beaaa62011-01-17 03:46:26 +00004184 return ast->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton471b31c2010-07-20 22:52:08 +00004185 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004186 qual_type_args.size(),
Sean Callanan2c777c42011-01-18 23:32:05 +00004187 proto_info).getAsOpaquePtr(); // NoReturn);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004188}
4189
4190ParmVarDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00004191ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004192{
Greg Clayton6beaaa62011-01-17 03:46:26 +00004193 ASTContext *ast = getASTContext();
4194 assert (ast != NULL);
4195 return ParmVarDecl::Create(*ast,
4196 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004197 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004198 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00004199 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callananc81256a2010-09-16 20:40:25 +00004200 QualType::getFromOpaquePtr(param_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004201 NULL,
4202 (VarDecl::StorageClass)storage,
4203 (VarDecl::StorageClass)storage,
4204 0);
4205}
4206
4207void
4208ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
4209{
4210 if (function_decl)
4211 function_decl->setParams (params, num_params);
4212}
4213
4214
4215#pragma mark Array Types
4216
Greg Clayton1be10fc2010-09-29 01:12:09 +00004217clang_type_t
4218ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004219{
4220 if (element_type)
4221 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004222 ASTContext *ast = getASTContext();
4223 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004224 llvm::APInt ap_element_count (64, element_count);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004225 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004226 ap_element_count,
4227 ArrayType::Normal,
4228 0).getAsOpaquePtr(); // ElemQuals
4229 }
4230 return NULL;
4231}
4232
4233
4234#pragma mark TagDecl
4235
4236bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004237ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004238{
4239 if (clang_type)
4240 {
4241 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00004242 const clang::Type *t = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004243 if (t)
4244 {
Sean Callanan78e37602011-01-27 04:42:51 +00004245 const TagType *tag_type = dyn_cast<TagType>(t);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004246 if (tag_type)
4247 {
4248 TagDecl *tag_decl = tag_type->getDecl();
4249 if (tag_decl)
4250 {
4251 tag_decl->startDefinition();
4252 return true;
4253 }
4254 }
4255 }
4256 }
4257 return false;
4258}
4259
4260bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004261ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004262{
4263 if (clang_type)
4264 {
4265 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton14372242010-09-29 03:44:17 +00004266
4267 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4268
4269 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004270 {
Greg Clayton14372242010-09-29 03:44:17 +00004271 cxx_record_decl->completeDefinition();
4272
4273 return true;
4274 }
4275
Sean Callanan78e37602011-01-27 04:42:51 +00004276 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
Sean Callanana2424172010-10-25 00:29:48 +00004277
4278 if (objc_class_type)
4279 {
4280 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
4281
4282 class_interface_decl->setForwardDecl(false);
4283 }
4284
Greg Clayton14372242010-09-29 03:44:17 +00004285 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
4286
4287 if (enum_type)
4288 {
4289 EnumDecl *enum_decl = enum_type->getDecl();
4290
4291 if (enum_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004292 {
Greg Clayton14372242010-09-29 03:44:17 +00004293 /// TODO This really needs to be fixed.
4294
4295 unsigned NumPositiveBits = 1;
4296 unsigned NumNegativeBits = 0;
4297
Greg Clayton6beaaa62011-01-17 03:46:26 +00004298 ASTContext *ast = getASTContext();
Greg Claytone02b8502010-10-12 04:29:14 +00004299
4300 QualType promotion_qual_type;
4301 // If the enum integer type is less than an integer in bit width,
4302 // then we must promote it to an integer size.
Greg Clayton6beaaa62011-01-17 03:46:26 +00004303 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
Greg Claytone02b8502010-10-12 04:29:14 +00004304 {
4305 if (enum_decl->getIntegerType()->isSignedIntegerType())
Greg Clayton6beaaa62011-01-17 03:46:26 +00004306 promotion_qual_type = ast->IntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00004307 else
Greg Clayton6beaaa62011-01-17 03:46:26 +00004308 promotion_qual_type = ast->UnsignedIntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00004309 }
4310 else
4311 promotion_qual_type = enum_decl->getIntegerType();
4312
4313 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton14372242010-09-29 03:44:17 +00004314 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004315 }
4316 }
4317 }
4318 return false;
4319}
4320
4321
4322#pragma mark Enumeration Types
4323
Greg Clayton1be10fc2010-09-29 01:12:09 +00004324clang_type_t
Greg Claytonca512b32011-01-14 04:54:56 +00004325ClangASTContext::CreateEnumerationType
4326(
4327 const char *name,
4328 DeclContext *decl_ctx,
4329 const Declaration &decl,
4330 clang_type_t integer_qual_type
4331)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004332{
4333 // TODO: Do something intelligent with the Declaration object passed in
4334 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00004335 ASTContext *ast = getASTContext();
4336 assert (ast != NULL);
Greg Claytone02b8502010-10-12 04:29:14 +00004337
4338 // TODO: ask about these...
4339// const bool IsScoped = false;
4340// const bool IsFixed = false;
4341
Greg Clayton6beaaa62011-01-17 03:46:26 +00004342 EnumDecl *enum_decl = EnumDecl::Create (*ast,
Greg Claytonca512b32011-01-14 04:54:56 +00004343 decl_ctx,
Greg Claytone02b8502010-10-12 04:29:14 +00004344 SourceLocation(),
Greg Claytone02b8502010-10-12 04:29:14 +00004345 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004346 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callanan48114472010-12-13 01:26:27 +00004347 NULL,
4348 false, // IsScoped
4349 false, // IsScopedUsingClassTag
4350 false); // IsFixed
Sean Callanan2652ad22011-01-18 01:03:44 +00004351
4352
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004353 if (enum_decl)
Greg Clayton83ff3892010-09-12 23:17:56 +00004354 {
4355 // TODO: check if we should be setting the promotion type too?
4356 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00004357
4358 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
4359
Greg Clayton6beaaa62011-01-17 03:46:26 +00004360 return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Clayton83ff3892010-09-12 23:17:56 +00004361 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004362 return NULL;
4363}
4364
Greg Clayton1be10fc2010-09-29 01:12:09 +00004365clang_type_t
4366ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
4367{
4368 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
4369
Sean Callanan78e37602011-01-27 04:42:51 +00004370 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Greg Clayton1be10fc2010-09-29 01:12:09 +00004371 if (clang_type)
4372 {
4373 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
4374 if (enum_type)
4375 {
4376 EnumDecl *enum_decl = enum_type->getDecl();
4377 if (enum_decl)
4378 return enum_decl->getIntegerType().getAsOpaquePtr();
4379 }
4380 }
4381 return NULL;
4382}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004383bool
4384ClangASTContext::AddEnumerationValueToEnumerationType
4385(
Greg Clayton1be10fc2010-09-29 01:12:09 +00004386 clang_type_t enum_clang_type,
4387 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004388 const Declaration &decl,
4389 const char *name,
4390 int64_t enum_value,
4391 uint32_t enum_value_bit_size
4392)
4393{
4394 if (enum_clang_type && enumerator_clang_type && name)
4395 {
4396 // TODO: Do something intelligent with the Declaration object passed in
4397 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00004398 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004399 IdentifierTable *identifier_table = getIdentifierTable();
4400
Greg Clayton6beaaa62011-01-17 03:46:26 +00004401 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004402 assert (identifier_table != NULL);
4403 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
4404
Sean Callanan78e37602011-01-27 04:42:51 +00004405 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004406 if (clang_type)
4407 {
4408 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
4409
4410 if (enum_type)
4411 {
4412 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
4413 enum_llvm_apsint = enum_value;
4414 EnumConstantDecl *enumerator_decl =
Greg Clayton6beaaa62011-01-17 03:46:26 +00004415 EnumConstantDecl::Create (*ast,
4416 enum_type->getDecl(),
4417 SourceLocation(),
4418 name ? &identifier_table->get(name) : NULL, // Identifier
4419 QualType::getFromOpaquePtr(enumerator_clang_type),
4420 NULL,
4421 enum_llvm_apsint);
4422
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004423 if (enumerator_decl)
4424 {
4425 enum_type->getDecl()->addDecl(enumerator_decl);
4426 return true;
4427 }
4428 }
4429 }
4430 }
4431 return false;
4432}
4433
4434#pragma mark Pointers & References
4435
Greg Clayton1be10fc2010-09-29 01:12:09 +00004436clang_type_t
4437ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004438{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00004439 return CreatePointerType (getASTContext(), clang_type);
4440}
4441
4442clang_type_t
4443ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
4444{
4445 if (ast && clang_type)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004446 {
4447 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4448
Greg Clayton737b9322010-09-13 03:32:57 +00004449 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4450 switch (type_class)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004451 {
4452 case clang::Type::ObjCObject:
4453 case clang::Type::ObjCInterface:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00004454 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004455
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004456 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00004457 return ast->getPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004458 }
4459 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004460 return NULL;
4461}
4462
Greg Clayton1be10fc2010-09-29 01:12:09 +00004463clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00004464ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
4465 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004466{
4467 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00004468 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004469 return NULL;
4470}
4471
Greg Clayton1be10fc2010-09-29 01:12:09 +00004472clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00004473ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
4474 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004475{
4476 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00004477 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004478 return NULL;
4479}
4480
Greg Clayton1be10fc2010-09-29 01:12:09 +00004481clang_type_t
4482ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Clayton9b81a312010-06-12 01:20:30 +00004483{
4484 if (clang_pointee_type && clang_pointee_type)
4485 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
4486 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
4487 return NULL;
4488}
4489
Greg Clayton1a65ae12011-01-25 23:55:37 +00004490uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004491ClangASTContext::GetPointerBitSize ()
4492{
Greg Clayton6beaaa62011-01-17 03:46:26 +00004493 ASTContext *ast = getASTContext();
4494 return ast->getTypeSize(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004495}
4496
4497bool
Greg Claytondea8cb42011-06-29 22:09:02 +00004498ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
4499{
4500 QualType pointee_qual_type;
4501 if (clang_type)
4502 {
4503 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4504 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4505 bool success = false;
4506 switch (type_class)
4507 {
4508 case clang::Type::Builtin:
4509 if (cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
4510 {
4511 if (dynamic_pointee_type)
4512 *dynamic_pointee_type = clang_type;
4513 return true;
4514 }
4515 break;
4516
4517 case clang::Type::ObjCObjectPointer:
4518 if (dynamic_pointee_type)
4519 *dynamic_pointee_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4520 return true;
4521
4522 case clang::Type::Pointer:
4523 pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
4524 success = true;
4525 break;
4526
4527 case clang::Type::LValueReference:
4528 case clang::Type::RValueReference:
4529 pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
4530 success = true;
4531 break;
4532
4533 case clang::Type::Typedef:
Greg Claytonaffb03b2011-07-08 18:27:39 +00004534 return ClangASTContext::IsPossibleDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
Sean Callanan912855f2011-08-11 23:56:13 +00004535
4536 case clang::Type::Elaborated:
4537 return ClangASTContext::IsPossibleDynamicType (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), dynamic_pointee_type);
4538
Greg Claytondea8cb42011-06-29 22:09:02 +00004539 default:
4540 break;
4541 }
4542
4543 if (success)
4544 {
4545 // Check to make sure what we are pointing too is a possible dynamic C++ type
4546 // We currently accept any "void *" (in case we have a class that has been
4547 // watered down to an opaque pointer) and virtual C++ classes.
4548 const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
4549 switch (pointee_type_class)
4550 {
4551 case clang::Type::Builtin:
4552 switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
4553 {
4554 case clang::BuiltinType::UnknownAny:
4555 case clang::BuiltinType::Void:
4556 if (dynamic_pointee_type)
4557 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4558 return true;
4559
4560 case clang::BuiltinType::NullPtr:
4561 case clang::BuiltinType::Bool:
4562 case clang::BuiltinType::Char_U:
4563 case clang::BuiltinType::UChar:
4564 case clang::BuiltinType::WChar_U:
4565 case clang::BuiltinType::Char16:
4566 case clang::BuiltinType::Char32:
4567 case clang::BuiltinType::UShort:
4568 case clang::BuiltinType::UInt:
4569 case clang::BuiltinType::ULong:
4570 case clang::BuiltinType::ULongLong:
4571 case clang::BuiltinType::UInt128:
4572 case clang::BuiltinType::Char_S:
4573 case clang::BuiltinType::SChar:
4574 case clang::BuiltinType::WChar_S:
4575 case clang::BuiltinType::Short:
4576 case clang::BuiltinType::Int:
4577 case clang::BuiltinType::Long:
4578 case clang::BuiltinType::LongLong:
4579 case clang::BuiltinType::Int128:
4580 case clang::BuiltinType::Float:
4581 case clang::BuiltinType::Double:
4582 case clang::BuiltinType::LongDouble:
4583 case clang::BuiltinType::Dependent:
4584 case clang::BuiltinType::Overload:
4585 case clang::BuiltinType::ObjCId:
4586 case clang::BuiltinType::ObjCClass:
4587 case clang::BuiltinType::ObjCSel:
4588 case clang::BuiltinType::BoundMember:
4589 break;
4590 }
4591 break;
4592
4593 case clang::Type::Record:
4594 {
4595 CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
4596 if (cxx_record_decl)
4597 {
4598 if (GetCompleteQualType (ast, pointee_qual_type))
4599 {
4600 success = cxx_record_decl->isDynamicClass();
4601 }
4602 else
4603 {
4604 // We failed to get the complete type, so we have to
4605 // treat this as a void * which we might possibly be
4606 // able to complete
4607 success = true;
4608 }
4609 if (success)
4610 {
4611 if (dynamic_pointee_type)
4612 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4613 return true;
4614 }
4615 }
4616 }
4617 break;
4618
4619 case clang::Type::ObjCObject:
4620 case clang::Type::ObjCInterface:
4621 {
4622 const clang::ObjCObjectType *objc_class_type = pointee_qual_type->getAsObjCQualifiedInterfaceType();
4623 if (objc_class_type)
4624 {
4625 GetCompleteQualType (ast, pointee_qual_type);
4626 if (dynamic_pointee_type)
4627 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4628 return true;
4629 }
4630 }
4631 break;
4632
4633 default:
4634 break;
4635 }
4636 }
4637 }
4638 if (dynamic_pointee_type)
4639 *dynamic_pointee_type = NULL;
4640 return false;
4641}
4642
4643
4644bool
Greg Clayton007d5be2011-05-30 00:49:24 +00004645ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
4646{
4647 QualType pointee_qual_type;
4648 if (clang_type)
4649 {
4650 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4651 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4652 bool success = false;
4653 switch (type_class)
4654 {
4655 case clang::Type::Pointer:
4656 pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
4657 success = true;
4658 break;
4659
4660 case clang::Type::LValueReference:
4661 case clang::Type::RValueReference:
4662 pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
4663 success = true;
4664 break;
4665
4666 case clang::Type::Typedef:
4667 return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
4668
Sean Callanan912855f2011-08-11 23:56:13 +00004669 case clang::Type::Elaborated:
4670 return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
4671
Greg Clayton007d5be2011-05-30 00:49:24 +00004672 default:
4673 break;
4674 }
4675
4676 if (success)
4677 {
4678 // Check to make sure what we are pointing too is a possible dynamic C++ type
4679 // We currently accept any "void *" (in case we have a class that has been
4680 // watered down to an opaque pointer) and virtual C++ classes.
4681 const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
4682 switch (pointee_type_class)
4683 {
4684 case clang::Type::Builtin:
4685 switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
4686 {
4687 case clang::BuiltinType::UnknownAny:
4688 case clang::BuiltinType::Void:
4689 if (dynamic_pointee_type)
4690 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4691 return true;
4692
4693 case clang::BuiltinType::NullPtr:
4694 case clang::BuiltinType::Bool:
4695 case clang::BuiltinType::Char_U:
4696 case clang::BuiltinType::UChar:
4697 case clang::BuiltinType::WChar_U:
4698 case clang::BuiltinType::Char16:
4699 case clang::BuiltinType::Char32:
4700 case clang::BuiltinType::UShort:
4701 case clang::BuiltinType::UInt:
4702 case clang::BuiltinType::ULong:
4703 case clang::BuiltinType::ULongLong:
4704 case clang::BuiltinType::UInt128:
4705 case clang::BuiltinType::Char_S:
4706 case clang::BuiltinType::SChar:
4707 case clang::BuiltinType::WChar_S:
4708 case clang::BuiltinType::Short:
4709 case clang::BuiltinType::Int:
4710 case clang::BuiltinType::Long:
4711 case clang::BuiltinType::LongLong:
4712 case clang::BuiltinType::Int128:
4713 case clang::BuiltinType::Float:
4714 case clang::BuiltinType::Double:
4715 case clang::BuiltinType::LongDouble:
4716 case clang::BuiltinType::Dependent:
4717 case clang::BuiltinType::Overload:
4718 case clang::BuiltinType::ObjCId:
4719 case clang::BuiltinType::ObjCClass:
4720 case clang::BuiltinType::ObjCSel:
4721 case clang::BuiltinType::BoundMember:
4722 break;
4723 }
4724 break;
4725 case clang::Type::Record:
4726 {
4727 CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
4728 if (cxx_record_decl)
4729 {
4730 if (GetCompleteQualType (ast, pointee_qual_type))
4731 {
Greg Claytona13ad2ad2011-06-02 01:26:44 +00004732 success = cxx_record_decl->isDynamicClass();
Greg Clayton007d5be2011-05-30 00:49:24 +00004733 }
4734 else
4735 {
4736 // We failed to get the complete type, so we have to
4737 // treat this as a void * which we might possibly be
4738 // able to complete
4739 success = true;
4740 }
4741 if (success)
4742 {
4743 if (dynamic_pointee_type)
4744 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4745 return true;
4746 }
4747 }
4748 }
4749 break;
4750
4751 default:
4752 break;
4753 }
4754 }
4755 }
4756 if (dynamic_pointee_type)
4757 *dynamic_pointee_type = NULL;
4758 return false;
4759}
4760
4761
4762bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004763ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004764{
4765 if (clang_type == NULL)
4766 return false;
4767
4768 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004769 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4770 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004771 {
Sean Callanana2424172010-10-25 00:29:48 +00004772 case clang::Type::Builtin:
4773 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4774 {
4775 default:
4776 break;
4777 case clang::BuiltinType::ObjCId:
4778 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004779 return true;
4780 }
4781 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004782 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004783 if (target_type)
4784 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4785 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004786 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004787 if (target_type)
4788 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4789 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004790 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004791 if (target_type)
4792 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4793 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004794 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004795 if (target_type)
4796 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4797 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004798 case clang::Type::LValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004799 if (target_type)
4800 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4801 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004802 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004803 if (target_type)
4804 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4805 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004806 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004807 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00004808 case clang::Type::Elaborated:
4809 return ClangASTContext::IsPointerOrReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004810 default:
4811 break;
4812 }
4813 return false;
4814}
4815
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004816bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004817ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004818{
4819 if (!clang_type)
4820 return false;
4821
4822 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4823 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
4824
4825 if (builtin_type)
4826 {
4827 if (builtin_type->isInteger())
4828 is_signed = builtin_type->isSignedInteger();
4829
4830 return true;
4831 }
4832
4833 return false;
4834}
4835
4836bool
Greg Claytonaffb03b2011-07-08 18:27:39 +00004837ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t *target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004838{
Greg Claytonaffb03b2011-07-08 18:27:39 +00004839 if (target_type)
4840 *target_type = NULL;
4841
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004842 if (clang_type)
4843 {
4844 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004845 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4846 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004847 {
Sean Callanana2424172010-10-25 00:29:48 +00004848 case clang::Type::Builtin:
4849 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4850 {
4851 default:
4852 break;
4853 case clang::BuiltinType::ObjCId:
4854 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004855 return true;
4856 }
4857 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004858 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004859 if (target_type)
4860 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4861 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004862 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004863 if (target_type)
4864 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4865 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004866 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004867 if (target_type)
4868 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4869 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004870 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004871 if (target_type)
4872 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4873 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004874 case clang::Type::Typedef:
Greg Claytonaffb03b2011-07-08 18:27:39 +00004875 return ClangASTContext::IsPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Sean Callanan912855f2011-08-11 23:56:13 +00004876 case clang::Type::Elaborated:
4877 return ClangASTContext::IsPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), target_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004878 default:
4879 break;
4880 }
4881 }
4882 return false;
4883}
4884
4885bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004886ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004887{
4888 if (clang_type)
4889 {
4890 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4891
4892 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
4893 {
4894 clang::BuiltinType::Kind kind = BT->getKind();
4895 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
4896 {
4897 count = 1;
4898 is_complex = false;
4899 return true;
4900 }
4901 }
4902 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
4903 {
4904 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
4905 {
4906 count = 2;
4907 is_complex = true;
4908 return true;
4909 }
4910 }
4911 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
4912 {
4913 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
4914 {
4915 count = VT->getNumElements();
4916 is_complex = false;
4917 return true;
4918 }
4919 }
4920 }
4921 return false;
4922}
4923
Enrico Granata9fc19442011-07-06 02:13:41 +00004924bool
4925ClangASTContext::IsScalarType (lldb::clang_type_t clang_type)
4926{
4927 bool is_signed;
4928 if (ClangASTContext::IsIntegerType(clang_type, is_signed))
4929 return true;
4930
4931 uint32_t count;
4932 bool is_complex;
4933 return ClangASTContext::IsFloatingPointType(clang_type, count, is_complex) && !is_complex;
4934}
4935
4936bool
4937ClangASTContext::IsPointerToScalarType (lldb::clang_type_t clang_type)
4938{
4939 if (!IsPointerType(clang_type))
4940 return false;
4941
4942 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4943 lldb::clang_type_t pointee_type = qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
4944 return IsScalarType(pointee_type);
4945}
4946
4947bool
4948ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type)
4949{
4950 if (!IsArrayType(clang_type))
4951 return false;
4952
4953 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4954 lldb::clang_type_t item_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
4955 return IsScalarType(item_type);
4956}
4957
Greg Clayton8f92f0a2010-10-14 22:52:14 +00004958
4959bool
4960ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
4961{
4962 if (clang_type)
4963 {
4964 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4965
4966 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4967 if (cxx_record_decl)
4968 {
4969 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
4970 return true;
4971 }
4972 }
4973 class_name.clear();
4974 return false;
4975}
4976
4977
Greg Clayton0fffff52010-09-24 05:15:53 +00004978bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004979ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004980{
4981 if (clang_type)
4982 {
4983 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4984 if (qual_type->getAsCXXRecordDecl() != NULL)
4985 return true;
4986 }
4987 return false;
4988}
4989
4990bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004991ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004992{
4993 if (clang_type)
4994 {
4995 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4996 if (qual_type->isObjCObjectOrInterfaceType())
4997 return true;
4998 }
4999 return false;
5000}
5001
5002
Greg Clayton73b472d2010-10-27 03:32:59 +00005003bool
5004ClangASTContext::IsCharType (clang_type_t clang_type)
5005{
5006 if (clang_type)
5007 return QualType::getFromOpaquePtr(clang_type)->isCharType();
5008 return false;
5009}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005010
5011bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005012ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005013{
Greg Clayton73b472d2010-10-27 03:32:59 +00005014 clang_type_t pointee_or_element_clang_type = NULL;
5015 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
5016
5017 if (pointee_or_element_clang_type == NULL)
5018 return false;
5019
5020 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005021 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005022 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
5023
5024 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005025 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005026 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5027 if (type_flags.Test (eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005028 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005029 // We know the size of the array and it could be a C string
5030 // since it is an array of characters
5031 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
5032 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005033 }
Greg Clayton73b472d2010-10-27 03:32:59 +00005034 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005035 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005036 length = 0;
5037 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005038 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005039
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005040 }
5041 }
5042 return false;
5043}
5044
5045bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005046ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton737b9322010-09-13 03:32:57 +00005047{
5048 if (clang_type)
5049 {
5050 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5051
5052 if (qual_type->isFunctionPointerType())
5053 return true;
5054
5055 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5056 switch (type_class)
5057 {
Sean Callananfb0b7582011-03-15 00:17:19 +00005058 default:
5059 break;
Greg Clayton737b9322010-09-13 03:32:57 +00005060 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00005061 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00005062 case clang::Type::Elaborated:
5063 return ClangASTContext::IsFunctionPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00005064
5065 case clang::Type::LValueReference:
5066 case clang::Type::RValueReference:
5067 {
Sean Callanan78e37602011-01-27 04:42:51 +00005068 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00005069 if (reference_type)
5070 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
5071 }
5072 break;
5073 }
5074 }
5075 return false;
5076}
5077
Greg Clayton73b472d2010-10-27 03:32:59 +00005078size_t
5079ClangASTContext::GetArraySize (clang_type_t clang_type)
5080{
5081 if (clang_type)
5082 {
Greg Claytonef37d68a2011-07-09 17:12:27 +00005083 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
5084 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5085 switch (type_class)
5086 {
5087 case clang::Type::ConstantArray:
5088 {
5089 const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
5090 if (array)
5091 return array->getSize().getLimitedValue();
5092 }
5093 break;
5094
5095 case clang::Type::Typedef:
5096 return ClangASTContext::GetArraySize(cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00005097
5098 case clang::Type::Elaborated:
5099 return ClangASTContext::GetArraySize(cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00005100
5101 default:
5102 break;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005103 }
Greg Clayton73b472d2010-10-27 03:32:59 +00005104 }
5105 return 0;
5106}
Greg Clayton737b9322010-09-13 03:32:57 +00005107
5108bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005109ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005110{
5111 if (!clang_type)
5112 return false;
5113
5114 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5115
Greg Clayton737b9322010-09-13 03:32:57 +00005116 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5117 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005118 {
Sean Callananfb0b7582011-03-15 00:17:19 +00005119 default:
5120 break;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005121
Greg Claytone1a916a2010-07-21 22:12:05 +00005122 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005123 if (member_type)
5124 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5125 if (size)
Greg Claytonac4827f2011-04-01 18:14:08 +00005126 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005127 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005128
Greg Claytone1a916a2010-07-21 22:12:05 +00005129 case clang::Type::IncompleteArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005130 if (member_type)
5131 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5132 if (size)
5133 *size = 0;
5134 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005135
Greg Claytone1a916a2010-07-21 22:12:05 +00005136 case clang::Type::VariableArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005137 if (member_type)
5138 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5139 if (size)
5140 *size = 0;
Greg Clayton03dbf2e2011-02-02 00:52:14 +00005141 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005142
Greg Claytone1a916a2010-07-21 22:12:05 +00005143 case clang::Type::DependentSizedArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005144 if (member_type)
5145 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5146 if (size)
5147 *size = 0;
5148 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005149
5150 case clang::Type::Typedef:
5151 return ClangASTContext::IsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
5152 member_type,
5153 size);
Sean Callanan912855f2011-08-11 23:56:13 +00005154
5155 case clang::Type::Elaborated:
5156 return ClangASTContext::IsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
5157 member_type,
5158 size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005159 }
5160 return false;
5161}
5162
5163
5164#pragma mark Typedefs
5165
Greg Clayton1be10fc2010-09-29 01:12:09 +00005166clang_type_t
5167ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005168{
5169 if (clang_type)
5170 {
5171 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00005172 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005173 IdentifierTable *identifier_table = getIdentifierTable();
Greg Clayton6beaaa62011-01-17 03:46:26 +00005174 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005175 assert (identifier_table != NULL);
5176 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00005177 decl_ctx = ast->getTranslationUnitDecl();
5178 TypedefDecl *decl = TypedefDecl::Create (*ast,
5179 decl_ctx,
5180 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00005181 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00005182 name ? &identifier_table->get(name) : NULL, // Identifier
5183 ast->CreateTypeSourceInfo(qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00005184
5185 decl->setAccess(AS_public); // TODO respect proper access specifier
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005186
5187 // Get a uniqued QualType for the typedef decl type
Greg Clayton6beaaa62011-01-17 03:46:26 +00005188 return ast->getTypedefType (decl).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005189 }
5190 return NULL;
5191}
5192
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005193// Disable this for now since I can't seem to get a nicely formatted float
5194// out of the APFloat class without just getting the float, double or quad
5195// and then using a formatted print on it which defeats the purpose. We ideally
5196// would like to get perfect string values for any kind of float semantics
5197// so we can support remote targets. The code below also requires a patch to
5198// llvm::APInt.
5199//bool
Greg Clayton6beaaa62011-01-17 03:46:26 +00005200//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 +00005201//{
5202// uint32_t count = 0;
5203// bool is_complex = false;
5204// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
5205// {
5206// unsigned num_bytes_per_float = byte_size / count;
5207// unsigned num_bits_per_float = num_bytes_per_float * 8;
5208//
5209// float_str.clear();
5210// uint32_t i;
5211// for (i=0; i<count; i++)
5212// {
5213// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
5214// bool is_ieee = false;
5215// APFloat ap_float(ap_int, is_ieee);
5216// char s[1024];
5217// unsigned int hex_digits = 0;
5218// bool upper_case = false;
5219//
5220// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
5221// {
5222// if (i > 0)
5223// float_str.append(", ");
5224// float_str.append(s);
5225// if (i == 1 && is_complex)
5226// float_str.append(1, 'i');
5227// }
5228// }
5229// return !float_str.empty();
5230// }
5231// return false;
5232//}
5233
5234size_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00005235ClangASTContext::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 +00005236{
5237 if (clang_type)
5238 {
5239 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5240 uint32_t count = 0;
5241 bool is_complex = false;
5242 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
5243 {
5244 // TODO: handle complex and vector types
5245 if (count != 1)
5246 return false;
5247
5248 StringRef s_sref(s);
Greg Clayton6beaaa62011-01-17 03:46:26 +00005249 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005250
Greg Clayton6beaaa62011-01-17 03:46:26 +00005251 const uint64_t bit_size = ast->getTypeSize (qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005252 const uint64_t byte_size = bit_size / 8;
5253 if (dst_size >= byte_size)
5254 {
5255 if (bit_size == sizeof(float)*8)
5256 {
5257 float float32 = ap_float.convertToFloat();
5258 ::memcpy (dst, &float32, byte_size);
5259 return byte_size;
5260 }
5261 else if (bit_size >= 64)
5262 {
5263 llvm::APInt ap_int(ap_float.bitcastToAPInt());
5264 ::memcpy (dst, ap_int.getRawData(), byte_size);
5265 return byte_size;
5266 }
5267 }
5268 }
5269 }
5270 return 0;
5271}
Sean Callanan6fe64b52010-09-17 02:24:29 +00005272
5273unsigned
Greg Clayton1be10fc2010-09-29 01:12:09 +00005274ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanan6fe64b52010-09-17 02:24:29 +00005275{
5276 assert (clang_type);
5277
5278 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5279
5280 return qual_type.getQualifiers().getCVRQualifiers();
5281}
Greg Clayton6beaaa62011-01-17 03:46:26 +00005282
5283bool
5284ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
5285{
5286 if (clang_type == NULL)
5287 return false;
5288
Greg Claytonc432c192011-01-20 04:18:48 +00005289 return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00005290}
5291
5292
5293bool
5294ClangASTContext::GetCompleteType (clang_type_t clang_type)
5295{
5296 return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
5297}
5298
Greg Claytona2721472011-06-25 00:44:06 +00005299bool
5300ClangASTContext::GetCompleteDecl (clang::ASTContext *ast,
5301 clang::Decl *decl)
5302{
5303 if (!decl)
5304 return false;
5305
5306 ExternalASTSource *ast_source = ast->getExternalSource();
5307
5308 if (!ast_source)
5309 return false;
5310
5311 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
5312 {
5313 if (tag_decl->getDefinition())
5314 return true;
5315
5316 if (!tag_decl->hasExternalLexicalStorage())
5317 return false;
5318
5319 ast_source->CompleteType(tag_decl);
5320
5321 return !tag_decl->getTypeForDecl()->isIncompleteType();
5322 }
5323 else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
5324 {
5325 if (!objc_interface_decl->isForwardDecl())
5326 return true;
5327
5328 if (!objc_interface_decl->hasExternalLexicalStorage())
5329 return false;
5330
5331 ast_source->CompleteType(objc_interface_decl);
5332
5333 return !objc_interface_decl->isForwardDecl();
5334 }
5335 else
5336 {
5337 return false;
5338 }
5339}
5340
Greg Clayton2c5f0e92011-08-04 21:02:57 +00005341clang::DeclContext *
5342ClangASTContext::GetAsDeclContext (clang::CXXMethodDecl *cxx_method_decl)
5343{
Sean Callanana87bee82011-08-19 06:19:25 +00005344 return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00005345}
5346
5347clang::DeclContext *
5348ClangASTContext::GetAsDeclContext (clang::ObjCMethodDecl *objc_method_decl)
5349{
Sean Callanana87bee82011-08-19 06:19:25 +00005350 return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00005351}
5352