blob: 320f1eb4b721c86ac5f4ebb1d2c8929bf99c1755 [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"
Greg Claytonf0705c82011-10-22 03:33:13 +000039#include "clang/AST/DeclTemplate.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040#include "clang/AST/RecordLayout.h"
41#include "clang/AST/Type.h"
42#include "clang/Basic/Builtins.h"
43#include "clang/Basic/FileManager.h"
Sean Callanan79439e82010-11-18 02:56:27 +000044#include "clang/Basic/FileSystemOptions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045#include "clang/Basic/SourceManager.h"
46#include "clang/Basic/TargetInfo.h"
47#include "clang/Basic/TargetOptions.h"
48#include "clang/Frontend/FrontendOptions.h"
49#include "clang/Frontend/LangStandard.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000050
51#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000052#undef NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000053#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
54// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
55#include <assert.h>
56#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057
Greg Clayton514487e2011-02-15 21:59:32 +000058#include "lldb/Core/ArchSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059#include "lldb/Core/dwarf.h"
Greg Clayton73b472d2010-10-27 03:32:59 +000060#include "lldb/Core/Flags.h"
Sean Callananfb8b7092010-10-28 18:19:36 +000061#include "lldb/Core/Log.h"
Greg Claytonf0705c82011-10-22 03:33:13 +000062#include "lldb/Core/RegularExpression.h"
63#include "lldb/Expression/ASTDumper.h"
Jim Inghamd555bac2011-06-24 22:03:24 +000064#include "lldb/Target/ExecutionContext.h"
65#include "lldb/Target/Process.h"
66#include "lldb/Target/ObjCLanguageRuntime.h"
67
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068
Eli Friedman932197d2010-06-13 19:06:42 +000069#include <stdio.h>
70
Greg Claytonc86103d2010-08-05 01:57:25 +000071using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072using namespace lldb_private;
73using namespace llvm;
74using namespace clang;
75
Greg Clayton6beaaa62011-01-17 03:46:26 +000076
77static bool
78GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
79{
80 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
81 switch (type_class)
82 {
83 case clang::Type::Record:
84 case clang::Type::Enum:
85 {
Sean Callanan78e37602011-01-27 04:42:51 +000086 const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +000087 if (tag_type)
88 {
89 clang::TagDecl *tag_decl = tag_type->getDecl();
90 if (tag_decl)
91 {
92 if (tag_decl->getDefinition())
93 return true;
94
95 if (tag_decl->hasExternalLexicalStorage())
96 {
Greg Clayton007d5be2011-05-30 00:49:24 +000097 if (ast)
Greg Clayton6beaaa62011-01-17 03:46:26 +000098 {
Greg Clayton007d5be2011-05-30 00:49:24 +000099 ExternalASTSource *external_ast_source = ast->getExternalSource();
100 if (external_ast_source)
101 {
102 external_ast_source->CompleteType(tag_decl);
103 return !tag_type->isIncompleteType();
104 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000105 }
106 }
107 return false;
108 }
109 }
110
111 }
112 break;
113
114 case clang::Type::ObjCObject:
115 case clang::Type::ObjCInterface:
116 {
Sean Callanan78e37602011-01-27 04:42:51 +0000117 const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000118 if (objc_class_type)
119 {
120 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
121 // We currently can't complete objective C types through the newly added ASTContext
122 // because it only supports TagDecl objects right now...
Enrico Granata9dd75c82011-07-15 23:30:15 +0000123 if (class_interface_decl)
Greg Clayton6beaaa62011-01-17 03:46:26 +0000124 {
Enrico Granata0a3958e2011-07-02 00:25:22 +0000125 bool is_forward_decl = class_interface_decl->isForwardDecl();
126 if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
Greg Clayton6beaaa62011-01-17 03:46:26 +0000127 {
Enrico Granata0a3958e2011-07-02 00:25:22 +0000128 if (ast)
Greg Clayton007d5be2011-05-30 00:49:24 +0000129 {
Enrico Granata0a3958e2011-07-02 00:25:22 +0000130 ExternalASTSource *external_ast_source = ast->getExternalSource();
131 if (external_ast_source)
132 {
133 external_ast_source->CompleteType (class_interface_decl);
134 is_forward_decl = class_interface_decl->isForwardDecl();
135 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000136 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000137 return is_forward_decl == false;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000138 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000139 return true;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000140 }
Enrico Granata0a3958e2011-07-02 00:25:22 +0000141 else
142 return false;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000143 }
144 }
145 break;
146
147 case clang::Type::Typedef:
148 return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType());
Sean Callanan912855f2011-08-11 23:56:13 +0000149
150 case clang::Type::Elaborated:
151 return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType());
Greg Clayton6beaaa62011-01-17 03:46:26 +0000152
153 default:
154 break;
155 }
156
157 return true;
158}
159
160
Greg Clayton8cf05932010-07-22 18:30:50 +0000161static AccessSpecifier
Greg Claytonc86103d2010-08-05 01:57:25 +0000162ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000163{
164 switch (access)
165 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000166 default: break;
167 case eAccessNone: return AS_none;
168 case eAccessPublic: return AS_public;
169 case eAccessPrivate: return AS_private;
170 case eAccessProtected: return AS_protected;
Greg Clayton8cf05932010-07-22 18:30:50 +0000171 }
172 return AS_none;
173}
174
175static ObjCIvarDecl::AccessControl
Greg Claytonc86103d2010-08-05 01:57:25 +0000176ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000177{
178 switch (access)
179 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000180 default: break;
181 case eAccessNone: return ObjCIvarDecl::None;
182 case eAccessPublic: return ObjCIvarDecl::Public;
183 case eAccessPrivate: return ObjCIvarDecl::Private;
184 case eAccessProtected: return ObjCIvarDecl::Protected;
185 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton8cf05932010-07-22 18:30:50 +0000186 }
187 return ObjCIvarDecl::None;
188}
189
190
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191static void
192ParseLangArgs
193(
194 LangOptions &Opts,
Greg Clayton94e5d782010-06-13 17:34:29 +0000195 InputKind IK
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196)
197{
198 // FIXME: Cleanup per-file based stuff.
199
200 // Set some properties which depend soley on the input kind; it would be nice
201 // to move these to the language standard, and have the driver resolve the
202 // input kind + language standard.
Greg Clayton94e5d782010-06-13 17:34:29 +0000203 if (IK == IK_Asm) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204 Opts.AsmPreprocessor = 1;
Greg Clayton94e5d782010-06-13 17:34:29 +0000205 } else if (IK == IK_ObjC ||
206 IK == IK_ObjCXX ||
207 IK == IK_PreprocessedObjC ||
208 IK == IK_PreprocessedObjCXX) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209 Opts.ObjC1 = Opts.ObjC2 = 1;
210 }
211
212 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
213
214 if (LangStd == LangStandard::lang_unspecified) {
215 // Based on the base language, pick one.
216 switch (IK) {
Greg Clayton94e5d782010-06-13 17:34:29 +0000217 case IK_None:
218 case IK_AST:
Sean Callananfb0b7582011-03-15 00:17:19 +0000219 case IK_LLVM_IR:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000220 assert (!"Invalid input kind!");
Greg Clayton94e5d782010-06-13 17:34:29 +0000221 case IK_OpenCL:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000222 LangStd = LangStandard::lang_opencl;
223 break;
Sean Callananfb0b7582011-03-15 00:17:19 +0000224 case IK_CUDA:
225 LangStd = LangStandard::lang_cuda;
226 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000227 case IK_Asm:
228 case IK_C:
229 case IK_PreprocessedC:
230 case IK_ObjC:
231 case IK_PreprocessedObjC:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232 LangStd = LangStandard::lang_gnu99;
233 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000234 case IK_CXX:
235 case IK_PreprocessedCXX:
236 case IK_ObjCXX:
237 case IK_PreprocessedObjCXX:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000238 LangStd = LangStandard::lang_gnucxx98;
239 break;
240 }
241 }
242
243 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
244 Opts.BCPLComment = Std.hasBCPLComments();
245 Opts.C99 = Std.isC99();
246 Opts.CPlusPlus = Std.isCPlusPlus();
247 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
248 Opts.Digraphs = Std.hasDigraphs();
249 Opts.GNUMode = Std.isGNUMode();
250 Opts.GNUInline = !Std.isC99();
251 Opts.HexFloats = Std.hasHexFloats();
252 Opts.ImplicitInt = Std.hasImplicitInt();
253
254 // OpenCL has some additional defaults.
255 if (LangStd == LangStandard::lang_opencl) {
256 Opts.OpenCL = 1;
257 Opts.AltiVec = 1;
258 Opts.CXXOperatorNames = 1;
259 Opts.LaxVectorConversions = 1;
260 }
261
262 // OpenCL and C++ both have bool, true, false keywords.
263 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
264
265// if (Opts.CPlusPlus)
266// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
267//
268// if (Args.hasArg(OPT_fobjc_gc_only))
269// Opts.setGCMode(LangOptions::GCOnly);
270// else if (Args.hasArg(OPT_fobjc_gc))
271// Opts.setGCMode(LangOptions::HybridGC);
272//
273// if (Args.hasArg(OPT_print_ivar_layout))
274// Opts.ObjCGCBitmapPrint = 1;
275//
276// if (Args.hasArg(OPT_faltivec))
277// Opts.AltiVec = 1;
278//
279// if (Args.hasArg(OPT_pthread))
280// Opts.POSIXThreads = 1;
281//
282// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
283// "default");
284// if (Vis == "default")
Sean Callanan31e851c2010-10-29 18:38:40 +0000285 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000286// else if (Vis == "hidden")
287// Opts.setVisibilityMode(LangOptions::Hidden);
288// else if (Vis == "protected")
289// Opts.setVisibilityMode(LangOptions::Protected);
290// else
291// Diags.Report(diag::err_drv_invalid_value)
292// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
293
294// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
295
296 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
297 // is specified, or -std is set to a conforming mode.
298 Opts.Trigraphs = !Opts.GNUMode;
299// if (Args.hasArg(OPT_trigraphs))
300// Opts.Trigraphs = 1;
301//
302// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
303// OPT_fno_dollars_in_identifiers,
304// !Opts.AsmPreprocessor);
305// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
306// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
307// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
308// if (Args.hasArg(OPT_fno_lax_vector_conversions))
309// Opts.LaxVectorConversions = 0;
310// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
311// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
312// Opts.Blocks = Args.hasArg(OPT_fblocks);
313// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
314// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
315// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
316// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
317// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
318// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
319// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
320// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
321// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
322// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
323// Diags);
324// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
325// Opts.ObjCConstantStringClass = getLastArgValue(Args,
326// OPT_fconstant_string_class);
327// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
328// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
329// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
330// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
331// Opts.Static = Args.hasArg(OPT_static_define);
332 Opts.OptimizeSize = 0;
333
334 // FIXME: Eliminate this dependency.
335// unsigned Opt =
336// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
337// Opts.Optimize = Opt != 0;
338 unsigned Opt = 0;
339
340 // This is the __NO_INLINE__ define, which just depends on things like the
341 // optimization level and -fno-inline, not actually whether the backend has
342 // inlining enabled.
343 //
344 // FIXME: This is affected by other options (-fno-inline).
345 Opts.NoInline = !Opt;
346
347// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
348// switch (SSP) {
349// default:
350// Diags.Report(diag::err_drv_invalid_value)
351// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
352// break;
353// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
354// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
355// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
356// }
357}
358
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359
Greg Clayton6beaaa62011-01-17 03:46:26 +0000360ClangASTContext::ClangASTContext (const char *target_triple) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 m_target_triple(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000362 m_ast_ap(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363 m_language_options_ap(),
364 m_source_manager_ap(),
Sean Callanan880e6802011-10-07 23:18:13 +0000365 m_diagnostics_engine_ap(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366 m_target_options_ap(),
367 m_target_info_ap(),
368 m_identifier_table_ap(),
369 m_selector_table_ap(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000370 m_builtins_ap(),
371 m_callback_tag_decl (NULL),
372 m_callback_objc_decl (NULL),
373 m_callback_baton (NULL)
374
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375{
376 if (target_triple && target_triple[0])
Greg Clayton880cbb02011-07-30 01:26:02 +0000377 SetTargetTriple (target_triple);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378}
379
380//----------------------------------------------------------------------
381// Destructor
382//----------------------------------------------------------------------
383ClangASTContext::~ClangASTContext()
384{
385 m_builtins_ap.reset();
386 m_selector_table_ap.reset();
387 m_identifier_table_ap.reset();
388 m_target_info_ap.reset();
389 m_target_options_ap.reset();
Sean Callanan880e6802011-10-07 23:18:13 +0000390 m_diagnostics_engine_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391 m_source_manager_ap.reset();
392 m_language_options_ap.reset();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000393 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394}
395
396
397void
398ClangASTContext::Clear()
399{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000400 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000401 m_language_options_ap.reset();
402 m_source_manager_ap.reset();
Sean Callanan880e6802011-10-07 23:18:13 +0000403 m_diagnostics_engine_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404 m_target_options_ap.reset();
405 m_target_info_ap.reset();
406 m_identifier_table_ap.reset();
407 m_selector_table_ap.reset();
408 m_builtins_ap.reset();
409}
410
411const char *
412ClangASTContext::GetTargetTriple ()
413{
414 return m_target_triple.c_str();
415}
416
417void
418ClangASTContext::SetTargetTriple (const char *target_triple)
419{
420 Clear();
421 m_target_triple.assign(target_triple);
422}
423
Greg Clayton514487e2011-02-15 21:59:32 +0000424void
425ClangASTContext::SetArchitecture (const ArchSpec &arch)
426{
Greg Clayton880cbb02011-07-30 01:26:02 +0000427 SetTargetTriple(arch.GetTriple().str().c_str());
Greg Clayton514487e2011-02-15 21:59:32 +0000428}
429
Greg Clayton6beaaa62011-01-17 03:46:26 +0000430bool
431ClangASTContext::HasExternalSource ()
432{
433 ASTContext *ast = getASTContext();
434 if (ast)
435 return ast->getExternalSource () != NULL;
436 return false;
437}
438
439void
440ClangASTContext::SetExternalSource (llvm::OwningPtr<ExternalASTSource> &ast_source_ap)
441{
442 ASTContext *ast = getASTContext();
443 if (ast)
444 {
445 ast->setExternalSource (ast_source_ap);
446 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
447 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
448 }
449}
450
451void
452ClangASTContext::RemoveExternalSource ()
453{
454 ASTContext *ast = getASTContext();
455
456 if (ast)
457 {
458 llvm::OwningPtr<ExternalASTSource> empty_ast_source_ap;
459 ast->setExternalSource (empty_ast_source_ap);
460 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
461 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
462 }
463}
464
465
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466
467ASTContext *
468ClangASTContext::getASTContext()
469{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000470 if (m_ast_ap.get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000471 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000472 m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
473 *getSourceManager(),
Sean Callanan880e6802011-10-07 23:18:13 +0000474 getTargetInfo(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000475 *getIdentifierTable(),
476 *getSelectorTable(),
477 *getBuiltinContext(),
478 0));
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000479
Greg Clayton6beaaa62011-01-17 03:46:26 +0000480 if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton)
481 {
482 m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
483 //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
484 }
485
Sean Callanan880e6802011-10-07 23:18:13 +0000486 m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000488 return m_ast_ap.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489}
490
491Builtin::Context *
492ClangASTContext::getBuiltinContext()
493{
494 if (m_builtins_ap.get() == NULL)
Sean Callanan880e6802011-10-07 23:18:13 +0000495 m_builtins_ap.reset (new Builtin::Context());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 return m_builtins_ap.get();
497}
498
499IdentifierTable *
500ClangASTContext::getIdentifierTable()
501{
502 if (m_identifier_table_ap.get() == NULL)
503 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
504 return m_identifier_table_ap.get();
505}
506
507LangOptions *
508ClangASTContext::getLanguageOptions()
509{
510 if (m_language_options_ap.get() == NULL)
511 {
512 m_language_options_ap.reset(new LangOptions());
Greg Clayton94e5d782010-06-13 17:34:29 +0000513 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
514// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515 }
516 return m_language_options_ap.get();
517}
518
519SelectorTable *
520ClangASTContext::getSelectorTable()
521{
522 if (m_selector_table_ap.get() == NULL)
523 m_selector_table_ap.reset (new SelectorTable());
524 return m_selector_table_ap.get();
525}
526
Sean Callanan79439e82010-11-18 02:56:27 +0000527clang::FileManager *
528ClangASTContext::getFileManager()
529{
530 if (m_file_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000531 {
532 clang::FileSystemOptions file_system_options;
533 m_file_manager_ap.reset(new clang::FileManager(file_system_options));
534 }
Sean Callanan79439e82010-11-18 02:56:27 +0000535 return m_file_manager_ap.get();
536}
537
Greg Claytone1a916a2010-07-21 22:12:05 +0000538clang::SourceManager *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000539ClangASTContext::getSourceManager()
540{
541 if (m_source_manager_ap.get() == NULL)
Sean Callanan880e6802011-10-07 23:18:13 +0000542 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnosticsEngine(), *getFileManager()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000543 return m_source_manager_ap.get();
544}
545
Sean Callanan880e6802011-10-07 23:18:13 +0000546clang::DiagnosticsEngine *
547ClangASTContext::getDiagnosticsEngine()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000548{
Sean Callanan880e6802011-10-07 23:18:13 +0000549 if (m_diagnostics_engine_ap.get() == NULL)
Greg Claytona651b532010-11-19 21:46:54 +0000550 {
551 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
Sean Callanan880e6802011-10-07 23:18:13 +0000552 m_diagnostics_engine_ap.reset(new DiagnosticsEngine(diag_id_sp));
Greg Claytona651b532010-11-19 21:46:54 +0000553 }
Sean Callanan880e6802011-10-07 23:18:13 +0000554 return m_diagnostics_engine_ap.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000555}
556
Sean Callanan880e6802011-10-07 23:18:13 +0000557class NullDiagnosticConsumer : public DiagnosticConsumer
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000558{
559public:
Sean Callanan880e6802011-10-07 23:18:13 +0000560 NullDiagnosticConsumer ()
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000561 {
562 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
563 }
564
Sean Callanan880e6802011-10-07 23:18:13 +0000565 void HandleDiagnostic (DiagnosticsEngine::Level DiagLevel, const Diagnostic &info)
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000566 {
567 if (m_log)
568 {
569 llvm::SmallVectorImpl<char> diag_str(10);
570 info.FormatDiagnostic(diag_str);
571 diag_str.push_back('\0');
572 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
573 }
574 }
Sean Callanan880e6802011-10-07 23:18:13 +0000575
576 DiagnosticConsumer *clone (DiagnosticsEngine &Diags) const
577 {
578 return new NullDiagnosticConsumer ();
579 }
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000580private:
581 LogSP m_log;
582};
583
Sean Callanan880e6802011-10-07 23:18:13 +0000584DiagnosticConsumer *
585ClangASTContext::getDiagnosticConsumer()
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000586{
Sean Callanan880e6802011-10-07 23:18:13 +0000587 if (m_diagnostic_consumer_ap.get() == NULL)
588 m_diagnostic_consumer_ap.reset(new NullDiagnosticConsumer);
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000589
Sean Callanan880e6802011-10-07 23:18:13 +0000590 return m_diagnostic_consumer_ap.get();
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000591}
592
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000593TargetOptions *
594ClangASTContext::getTargetOptions()
595{
596 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
597 {
598 m_target_options_ap.reset (new TargetOptions());
599 if (m_target_options_ap.get())
600 m_target_options_ap->Triple = m_target_triple;
601 }
602 return m_target_options_ap.get();
603}
604
605
606TargetInfo *
607ClangASTContext::getTargetInfo()
608{
609 // target_triple should be something like "x86_64-apple-darwin10"
610 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
Sean Callanan880e6802011-10-07 23:18:13 +0000611 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(), *getTargetOptions()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000612 return m_target_info_ap.get();
613}
614
615#pragma mark Basic Types
616
617static inline bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000618QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000619{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000620 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000621 if (qual_type_bit_size == bit_size)
622 return true;
623 return false;
624}
625
Greg Clayton1be10fc2010-09-29 01:12:09 +0000626clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +0000627ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000628{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000629 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630
Greg Clayton6beaaa62011-01-17 03:46:26 +0000631 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000632
Greg Clayton6beaaa62011-01-17 03:46:26 +0000633 return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634}
635
Greg Clayton1be10fc2010-09-29 01:12:09 +0000636clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000637ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000638{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000639 if (!ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000640 return NULL;
641
642 switch (encoding)
643 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000644 case eEncodingInvalid:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000645 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
646 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000647 break;
648
Greg Claytonc86103d2010-08-05 01:57:25 +0000649 case eEncodingUint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000650 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
651 return ast->UnsignedCharTy.getAsOpaquePtr();
652 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
653 return ast->UnsignedShortTy.getAsOpaquePtr();
654 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
655 return ast->UnsignedIntTy.getAsOpaquePtr();
656 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
657 return ast->UnsignedLongTy.getAsOpaquePtr();
658 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
659 return ast->UnsignedLongLongTy.getAsOpaquePtr();
660 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
661 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000662 break;
663
Greg Claytonc86103d2010-08-05 01:57:25 +0000664 case eEncodingSint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000665 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
666 return ast->CharTy.getAsOpaquePtr();
667 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
668 return ast->ShortTy.getAsOpaquePtr();
669 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
670 return ast->IntTy.getAsOpaquePtr();
671 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
672 return ast->LongTy.getAsOpaquePtr();
673 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
674 return ast->LongLongTy.getAsOpaquePtr();
675 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
676 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000677 break;
678
Greg Claytonc86103d2010-08-05 01:57:25 +0000679 case eEncodingIEEE754:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000680 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
681 return ast->FloatTy.getAsOpaquePtr();
682 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
683 return ast->DoubleTy.getAsOpaquePtr();
684 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
685 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000686 break;
687
Greg Claytonc86103d2010-08-05 01:57:25 +0000688 case eEncodingVector:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000689 default:
690 break;
691 }
692
693 return NULL;
694}
695
Greg Clayton1be10fc2010-09-29 01:12:09 +0000696clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
698{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000699 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000700
701 #define streq(a,b) strcmp(a,b) == 0
Greg Clayton6beaaa62011-01-17 03:46:26 +0000702 assert (ast != NULL);
703 if (ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704 {
705 switch (dw_ate)
706 {
707 default:
708 break;
709
710 case DW_ATE_address:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000711 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
712 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000713 break;
714
715 case DW_ATE_boolean:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000716 if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
717 return ast->BoolTy.getAsOpaquePtr();
718 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
719 return ast->UnsignedCharTy.getAsOpaquePtr();
720 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
721 return ast->UnsignedShortTy.getAsOpaquePtr();
722 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
723 return ast->UnsignedIntTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000724 break;
725
Greg Clayton49462ea2011-01-15 02:52:14 +0000726 case DW_ATE_lo_user:
727 // This has been seen to mean DW_AT_complex_integer
Greg Clayton5732f242011-01-27 09:15:11 +0000728 if (::strstr(type_name, "complex"))
Greg Clayton49462ea2011-01-15 02:52:14 +0000729 {
730 clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000731 return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000732 }
733 break;
734
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000735 case DW_ATE_complex_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000736 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
737 return ast->FloatComplexTy.getAsOpaquePtr();
738 else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
739 return ast->DoubleComplexTy.getAsOpaquePtr();
740 else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
741 return ast->LongDoubleComplexTy.getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000742 else
743 {
744 clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000745 return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000746 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000747 break;
748
749 case DW_ATE_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000750 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
751 return ast->FloatTy.getAsOpaquePtr();
752 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
753 return ast->DoubleTy.getAsOpaquePtr();
754 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
755 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756 break;
757
758 case DW_ATE_signed:
759 if (type_name)
760 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000761 if (strstr(type_name, "long long"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000762 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000763 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
764 return ast->LongLongTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000765 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000766 else if (strstr(type_name, "long"))
767 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000768 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
769 return ast->LongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000770 }
771 else if (strstr(type_name, "short"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000772 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000773 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
774 return ast->ShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000775 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000776 else if (strstr(type_name, "char"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000777 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000778 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
779 return ast->CharTy.getAsOpaquePtr();
780 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
781 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000783 else if (strstr(type_name, "int"))
784 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000785 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
786 return ast->IntTy.getAsOpaquePtr();
787 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
788 return ast->Int128Ty.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000789 }
790 else if (streq(type_name, "wchar_t"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000791 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000792 if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
793 return ast->WCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000794 }
Greg Clayton7bd65b92011-02-09 23:39:34 +0000795 else if (streq(type_name, "void"))
796 {
797 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
798 return ast->VoidTy.getAsOpaquePtr();
799 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800 }
801 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000802 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
803 return ast->CharTy.getAsOpaquePtr();
804 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
805 return ast->ShortTy.getAsOpaquePtr();
806 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
807 return ast->IntTy.getAsOpaquePtr();
808 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
809 return ast->LongTy.getAsOpaquePtr();
810 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
811 return ast->LongLongTy.getAsOpaquePtr();
812 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
813 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000814 break;
815
816 case DW_ATE_signed_char:
817 if (type_name)
818 {
819 if (streq(type_name, "signed char"))
820 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000821 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
822 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000823 }
824 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000825 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
826 return ast->CharTy.getAsOpaquePtr();
827 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
828 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829 break;
830
831 case DW_ATE_unsigned:
832 if (type_name)
833 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000834 if (strstr(type_name, "long long"))
835 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000836 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
837 return ast->UnsignedLongLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000838 }
839 else if (strstr(type_name, "long"))
840 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000841 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
842 return ast->UnsignedLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000843 }
844 else if (strstr(type_name, "short"))
845 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000846 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
847 return ast->UnsignedShortTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000848 }
849 else if (strstr(type_name, "char"))
850 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000851 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
852 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000853 }
854 else if (strstr(type_name, "int"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000855 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000856 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
857 return ast->UnsignedIntTy.getAsOpaquePtr();
858 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
859 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000860 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000861 }
862 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000863 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
864 return ast->UnsignedCharTy.getAsOpaquePtr();
865 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
866 return ast->UnsignedShortTy.getAsOpaquePtr();
867 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
868 return ast->UnsignedIntTy.getAsOpaquePtr();
869 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
870 return ast->UnsignedLongTy.getAsOpaquePtr();
871 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
872 return ast->UnsignedLongLongTy.getAsOpaquePtr();
873 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
874 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000875 break;
876
877 case DW_ATE_unsigned_char:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000878 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
879 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton7bd65b92011-02-09 23:39:34 +0000880 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
881 return ast->UnsignedShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000882 break;
883
884 case DW_ATE_imaginary_float:
885 break;
886 }
887 }
888 // This assert should fire for anything that we don't catch above so we know
889 // to fix any issues we run into.
Greg Claytondc968d12011-05-17 18:15:05 +0000890 if (type_name)
891 {
892 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);
893 }
894 else
895 {
896 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);
897 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000898 return NULL;
899}
900
Greg Clayton1be10fc2010-09-29 01:12:09 +0000901clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000902ClangASTContext::GetBuiltInType_void(ASTContext *ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000903{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000904 return ast->VoidTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000905}
906
Greg Clayton1be10fc2010-09-29 01:12:09 +0000907clang_type_t
Sean Callananf7c3e272010-11-19 02:52:21 +0000908ClangASTContext::GetBuiltInType_bool()
909{
910 return getASTContext()->BoolTy.getAsOpaquePtr();
911}
912
913clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000914ClangASTContext::GetBuiltInType_objc_id()
915{
Sean Callananf6c73082010-12-06 23:53:20 +0000916 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000917}
918
Greg Clayton1be10fc2010-09-29 01:12:09 +0000919clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000920ClangASTContext::GetBuiltInType_objc_Class()
921{
Sean Callanana2424172010-10-25 00:29:48 +0000922 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000923}
924
Greg Clayton1be10fc2010-09-29 01:12:09 +0000925clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000926ClangASTContext::GetBuiltInType_objc_selector()
927{
Sean Callananf6c73082010-12-06 23:53:20 +0000928 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000929}
930
Greg Clayton1be10fc2010-09-29 01:12:09 +0000931clang_type_t
Sean Callanan77502262011-05-12 23:54:16 +0000932ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
933{
934 return ast->UnknownAnyTy.getAsOpaquePtr();
935}
936
937clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000938ClangASTContext::GetCStringType (bool is_const)
939{
940 QualType char_type(getASTContext()->CharTy);
941
942 if (is_const)
943 char_type.addConst();
944
945 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
946}
947
Greg Clayton1be10fc2010-09-29 01:12:09 +0000948clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000949ClangASTContext::GetVoidPtrType (bool is_const)
950{
951 return GetVoidPtrType(getASTContext(), is_const);
952}
953
Greg Clayton1be10fc2010-09-29 01:12:09 +0000954clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000955ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000956{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000957 QualType void_ptr_type(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000958
959 if (is_const)
960 void_ptr_type.addConst();
961
962 return void_ptr_type.getAsOpaquePtr();
963}
964
Greg Clayton1be10fc2010-09-29 01:12:09 +0000965clang_type_t
Greg Clayton38a61402010-12-02 23:20:03 +0000966ClangASTContext::CopyType (ASTContext *dst_ast,
967 ASTContext *src_ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000968 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000969{
Sean Callanan79439e82010-11-18 02:56:27 +0000970 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000971 FileManager file_manager (file_system_options);
972 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000973 *src_ast, file_manager,
974 false);
Sean Callanan0617fcb2010-11-09 22:37:10 +0000975
Greg Clayton38a61402010-12-02 23:20:03 +0000976 QualType src (QualType::getFromOpaquePtr(clang_type));
977 QualType dst (importer.Import(src));
Sean Callanan0617fcb2010-11-09 22:37:10 +0000978
979 return dst.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000980}
981
Greg Clayton526e5af2010-11-13 03:52:47 +0000982
983clang::Decl *
Greg Clayton38a61402010-12-02 23:20:03 +0000984ClangASTContext::CopyDecl (ASTContext *dst_ast,
985 ASTContext *src_ast,
Greg Clayton526e5af2010-11-13 03:52:47 +0000986 clang::Decl *source_decl)
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000987{
Sean Callanan79439e82010-11-18 02:56:27 +0000988 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000989 FileManager file_manager (file_system_options);
990 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000991 *src_ast, file_manager,
992 false);
Greg Clayton526e5af2010-11-13 03:52:47 +0000993
994 return importer.Import(source_decl);
995}
996
Sean Callanan23a30272010-07-16 00:00:27 +0000997bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000998ClangASTContext::AreTypesSame(ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000999 clang_type_t type1,
1000 clang_type_t type2)
Sean Callanan4dcca2622010-07-15 22:30:52 +00001001{
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001002 return ast->hasSameType (QualType::getFromOpaquePtr(type1),
1003 QualType::getFromOpaquePtr(type2));
Sean Callanan4dcca2622010-07-15 22:30:52 +00001004}
1005
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001006#pragma mark CVR modifiers
1007
Greg Clayton1be10fc2010-09-29 01:12:09 +00001008clang_type_t
1009ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001010{
1011 if (clang_type)
1012 {
1013 QualType result(QualType::getFromOpaquePtr(clang_type));
1014 result.addConst();
1015 return result.getAsOpaquePtr();
1016 }
1017 return NULL;
1018}
1019
Greg Clayton1be10fc2010-09-29 01:12:09 +00001020clang_type_t
1021ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001022{
1023 if (clang_type)
1024 {
1025 QualType result(QualType::getFromOpaquePtr(clang_type));
1026 result.getQualifiers().setRestrict (true);
1027 return result.getAsOpaquePtr();
1028 }
1029 return NULL;
1030}
1031
Greg Clayton1be10fc2010-09-29 01:12:09 +00001032clang_type_t
1033ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001034{
1035 if (clang_type)
1036 {
1037 QualType result(QualType::getFromOpaquePtr(clang_type));
1038 result.getQualifiers().setVolatile (true);
1039 return result.getAsOpaquePtr();
1040 }
1041 return NULL;
1042}
1043
Greg Clayton6beaaa62011-01-17 03:46:26 +00001044
1045clang_type_t
1046ClangASTContext::GetTypeForDecl (TagDecl *decl)
1047{
1048 // No need to call the getASTContext() accessor (which can create the AST
1049 // if it isn't created yet, because we can't have created a decl in this
1050 // AST if our AST didn't already exist...
1051 if (m_ast_ap.get())
1052 return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
1053 return NULL;
1054}
1055
1056clang_type_t
1057ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
1058{
1059 // No need to call the getASTContext() accessor (which can create the AST
1060 // if it isn't created yet, because we can't have created a decl in this
1061 // AST if our AST didn't already exist...
1062 if (m_ast_ap.get())
1063 return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
1064 return NULL;
1065}
1066
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067#pragma mark Structure, Unions, Classes
1068
Greg Clayton1be10fc2010-09-29 01:12:09 +00001069clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +00001070ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001071{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001072 ASTContext *ast = getASTContext();
1073 assert (ast != NULL);
Sean Callanana2424172010-10-25 00:29:48 +00001074
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001075 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001076 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001077
Greg Clayton9e409562010-07-28 02:04:09 +00001078
Greg Claytone1be9962011-08-24 23:50:00 +00001079 if (language == eLanguageTypeObjC || language == eLanguageTypeObjC_plus_plus)
Greg Clayton9e409562010-07-28 02:04:09 +00001080 {
Greg Claytonaaf99e02010-10-11 02:25:34 +00001081 bool isForwardDecl = true;
Greg Clayton9e409562010-07-28 02:04:09 +00001082 bool isInternal = false;
1083 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
1084 }
1085
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001086 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1087 // we will need to update this code. I was told to currently always use
1088 // the CXXRecordDecl class since we often don't know from debug information
1089 // if something is struct or a class, so we default to always use the more
1090 // complete definition just in case.
Greg Claytonf0705c82011-10-22 03:33:13 +00001091 CXXRecordDecl *decl = CXXRecordDecl::Create (*ast,
1092 (TagDecl::TagKind)kind,
1093 decl_ctx,
1094 SourceLocation(),
1095 SourceLocation(),
1096 name && name[0] ? &ast->Idents.get(name) : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097
Greg Clayton6beaaa62011-01-17 03:46:26 +00001098 return ast->getTagDeclType(decl).getAsOpaquePtr();
1099}
1100
Greg Claytonf0705c82011-10-22 03:33:13 +00001101ClassTemplateDecl *
1102ClangASTContext::CreateClassTemplateDecl (DeclContext *decl_ctx,
1103 const char *class_name,
1104 int kind,
1105 const TemplateParameterInfos &template_param_infos)
1106{
1107 ASTContext *ast = getASTContext();
1108
1109 ClassTemplateDecl *class_template_decl = NULL;
1110 if (decl_ctx == NULL)
1111 decl_ctx = ast->getTranslationUnitDecl();
1112
1113 IdentifierInfo &identifier_info = ast->Idents.get(class_name);
1114 DeclarationName decl_name (&identifier_info);
1115
1116 clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
1117 for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos)
1118 {
1119 class_template_decl = dyn_cast<clang::ClassTemplateDecl>(*pos);
1120 if (class_template_decl)
1121 return class_template_decl;
1122 }
1123
1124 llvm::SmallVector<NamedDecl *, 8> template_param_decls;
1125 const bool parameter_pack = false;
1126 const bool is_typename = false;
1127 const unsigned depth = 0;
1128 const size_t num_template_params = template_param_infos.GetSize();
1129 for (size_t i=0; i<num_template_params; ++i)
1130 {
1131 const char *name = template_param_infos.names[i];
1132 if (template_param_infos.args[i].getAsIntegral())
1133 {
1134 template_param_decls.push_back (NonTypeTemplateParmDecl::Create (*ast,
1135 ast->getTranslationUnitDecl(), // Is this the right decl context?, SourceLocation StartLoc,
1136 SourceLocation(),
1137 SourceLocation(),
1138 depth,
1139 i,
1140 &ast->Idents.get(name),
1141 template_param_infos.args[i].getAsType(),
1142 parameter_pack,
1143 NULL));
1144
1145 }
1146 else
1147 {
1148 template_param_decls.push_back (TemplateTypeParmDecl::Create (*ast,
1149 ast->getTranslationUnitDecl(), // Is this the right decl context?
1150 SourceLocation(),
1151 SourceLocation(),
1152 depth,
1153 i,
1154 &ast->Idents.get(name),
1155 is_typename,
1156 parameter_pack));
1157 }
1158 }
1159
1160 TemplateParameterList *template_param_list = TemplateParameterList::Create (*ast,
1161 SourceLocation(),
1162 SourceLocation(),
1163 &template_param_decls.front(),
1164 template_param_decls.size(),
1165 SourceLocation());
1166
1167
1168 CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create (*ast,
1169 (TagDecl::TagKind)kind,
1170 decl_ctx, // What decl context do we use here? TU? The actual decl context?
1171 SourceLocation(),
1172 SourceLocation(),
1173 &identifier_info);
1174
1175
1176 class_template_decl = ClassTemplateDecl::Create (*ast,
1177 decl_ctx, // What decl context do we use here? TU? The actual decl context?
1178 SourceLocation(),
1179 decl_name,
1180 template_param_list,
1181 template_cxx_decl,
1182 NULL);
1183
1184 if (class_template_decl)
1185 decl_ctx->addDecl (class_template_decl);
1186
1187 return class_template_decl;
1188}
1189
1190
1191ClassTemplateSpecializationDecl *
1192ClangASTContext::CreateClassTemplateSpecializationDecl (DeclContext *decl_ctx,
1193 ClassTemplateDecl *class_template_decl,
1194 int kind,
1195 const TemplateParameterInfos &template_param_infos)
1196{
1197 ASTContext *ast = getASTContext();
1198 ClassTemplateSpecializationDecl *class_template_specialization_decl = ClassTemplateSpecializationDecl::Create (*ast,
1199 (TagDecl::TagKind)kind,
1200 decl_ctx,
1201 SourceLocation(),
1202 SourceLocation(),
1203 class_template_decl,
1204 &template_param_infos.args.front(),
1205 template_param_infos.args.size(),
1206 NULL);
1207
1208 return class_template_specialization_decl;
1209}
1210
1211lldb::clang_type_t
1212ClangASTContext::CreateClassTemplateSpecializationType (ClassTemplateSpecializationDecl *class_template_specialization_decl)
1213{
1214 if (class_template_specialization_decl)
1215 {
1216 ASTContext *ast = getASTContext();
1217 if (ast)
1218 return ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr();
1219 }
1220 return NULL;
1221}
1222
Greg Clayton6beaaa62011-01-17 03:46:26 +00001223bool
1224ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
1225{
1226 if (clang_type == NULL)
1227 return false;
1228
1229 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1230
1231 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1232 switch (type_class)
1233 {
1234 case clang::Type::Record:
1235 {
1236 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
1237 if (cxx_record_decl)
1238 {
1239 cxx_record_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001240 cxx_record_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001241 return true;
1242 }
1243 }
1244 break;
1245
1246 case clang::Type::Enum:
1247 {
1248 EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
1249 if (enum_decl)
1250 {
1251 enum_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001252 enum_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001253 return true;
1254 }
1255 }
1256 break;
1257
1258 case clang::Type::ObjCObject:
1259 case clang::Type::ObjCInterface:
1260 {
Sean Callanan78e37602011-01-27 04:42:51 +00001261 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001262 assert (objc_class_type);
1263 if (objc_class_type)
1264 {
1265 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1266
1267 if (class_interface_decl)
1268 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001269 class_interface_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001270 class_interface_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001271 return true;
1272 }
1273 }
1274 }
1275 break;
1276
1277 case clang::Type::Typedef:
1278 return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
Sean Callanan912855f2011-08-11 23:56:13 +00001279
1280 case clang::Type::Elaborated:
1281 return ClangASTContext::SetHasExternalStorage (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001282
1283 default:
1284 break;
1285 }
1286 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001287}
1288
Greg Claytona3c444a2010-10-01 23:13:49 +00001289static bool
1290IsOperator (const char *name, OverloadedOperatorKind &op_kind)
1291{
1292 if (name == NULL || name[0] == '\0')
1293 return false;
1294
Sean Callanana43f20d2010-12-10 19:51:54 +00001295#define OPERATOR_PREFIX "operator"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001296#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
Sean Callananbfeff8c2010-12-10 02:15:55 +00001297
1298 const char *post_op_name = NULL;
1299
Sean Callanana43f20d2010-12-10 19:51:54 +00001300 bool no_space = true;
Sean Callananbfeff8c2010-12-10 02:15:55 +00001301
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001302 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
Greg Claytona3c444a2010-10-01 23:13:49 +00001303 return false;
1304
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001305 post_op_name = name + OPERATOR_PREFIX_LENGTH;
1306
Sean Callanana43f20d2010-12-10 19:51:54 +00001307 if (post_op_name[0] == ' ')
1308 {
1309 post_op_name++;
1310 no_space = false;
1311 }
1312
1313#undef OPERATOR_PREFIX
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001314#undef OPERATOR_PREFIX_LENGTH
Sean Callanana43f20d2010-12-10 19:51:54 +00001315
Greg Claytona3c444a2010-10-01 23:13:49 +00001316 // This is an operator, set the overloaded operator kind to invalid
1317 // in case this is a conversion operator...
1318 op_kind = NUM_OVERLOADED_OPERATORS;
1319
1320 switch (post_op_name[0])
1321 {
Sean Callananbfeff8c2010-12-10 02:15:55 +00001322 default:
1323 if (no_space)
1324 return false;
1325 break;
Greg Claytona3c444a2010-10-01 23:13:49 +00001326 case 'n':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001327 if (no_space)
1328 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001329 if (strcmp (post_op_name, "new") == 0)
1330 op_kind = OO_New;
1331 else if (strcmp (post_op_name, "new[]") == 0)
1332 op_kind = OO_Array_New;
1333 break;
1334
1335 case 'd':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001336 if (no_space)
1337 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001338 if (strcmp (post_op_name, "delete") == 0)
1339 op_kind = OO_Delete;
1340 else if (strcmp (post_op_name, "delete[]") == 0)
1341 op_kind = OO_Array_Delete;
1342 break;
1343
1344 case '+':
1345 if (post_op_name[1] == '\0')
1346 op_kind = OO_Plus;
1347 else if (post_op_name[2] == '\0')
1348 {
1349 if (post_op_name[1] == '=')
1350 op_kind = OO_PlusEqual;
1351 else if (post_op_name[1] == '+')
1352 op_kind = OO_PlusPlus;
1353 }
1354 break;
1355
1356 case '-':
1357 if (post_op_name[1] == '\0')
1358 op_kind = OO_Minus;
1359 else if (post_op_name[2] == '\0')
1360 {
1361 switch (post_op_name[1])
1362 {
1363 case '=': op_kind = OO_MinusEqual; break;
1364 case '-': op_kind = OO_MinusMinus; break;
1365 case '>': op_kind = OO_Arrow; break;
1366 }
1367 }
1368 else if (post_op_name[3] == '\0')
1369 {
1370 if (post_op_name[2] == '*')
1371 op_kind = OO_ArrowStar; break;
1372 }
1373 break;
1374
1375 case '*':
1376 if (post_op_name[1] == '\0')
1377 op_kind = OO_Star;
1378 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1379 op_kind = OO_StarEqual;
1380 break;
1381
1382 case '/':
1383 if (post_op_name[1] == '\0')
1384 op_kind = OO_Slash;
1385 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1386 op_kind = OO_SlashEqual;
1387 break;
1388
1389 case '%':
1390 if (post_op_name[1] == '\0')
1391 op_kind = OO_Percent;
1392 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1393 op_kind = OO_PercentEqual;
1394 break;
1395
1396
1397 case '^':
1398 if (post_op_name[1] == '\0')
1399 op_kind = OO_Caret;
1400 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1401 op_kind = OO_CaretEqual;
1402 break;
1403
1404 case '&':
1405 if (post_op_name[1] == '\0')
1406 op_kind = OO_Amp;
1407 else if (post_op_name[2] == '\0')
1408 {
1409 switch (post_op_name[1])
1410 {
1411 case '=': op_kind = OO_AmpEqual; break;
1412 case '&': op_kind = OO_AmpAmp; break;
1413 }
1414 }
1415 break;
1416
1417 case '|':
1418 if (post_op_name[1] == '\0')
1419 op_kind = OO_Pipe;
1420 else if (post_op_name[2] == '\0')
1421 {
1422 switch (post_op_name[1])
1423 {
1424 case '=': op_kind = OO_PipeEqual; break;
1425 case '|': op_kind = OO_PipePipe; break;
1426 }
1427 }
1428 break;
1429
1430 case '~':
1431 if (post_op_name[1] == '\0')
1432 op_kind = OO_Tilde;
1433 break;
1434
1435 case '!':
1436 if (post_op_name[1] == '\0')
1437 op_kind = OO_Exclaim;
1438 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1439 op_kind = OO_ExclaimEqual;
1440 break;
1441
1442 case '=':
1443 if (post_op_name[1] == '\0')
1444 op_kind = OO_Equal;
1445 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1446 op_kind = OO_EqualEqual;
1447 break;
1448
1449 case '<':
1450 if (post_op_name[1] == '\0')
1451 op_kind = OO_Less;
1452 else if (post_op_name[2] == '\0')
1453 {
1454 switch (post_op_name[1])
1455 {
1456 case '<': op_kind = OO_LessLess; break;
1457 case '=': op_kind = OO_LessEqual; break;
1458 }
1459 }
1460 else if (post_op_name[3] == '\0')
1461 {
1462 if (post_op_name[2] == '=')
1463 op_kind = OO_LessLessEqual;
1464 }
1465 break;
1466
1467 case '>':
1468 if (post_op_name[1] == '\0')
1469 op_kind = OO_Greater;
1470 else if (post_op_name[2] == '\0')
1471 {
1472 switch (post_op_name[1])
1473 {
1474 case '>': op_kind = OO_GreaterGreater; break;
1475 case '=': op_kind = OO_GreaterEqual; break;
1476 }
1477 }
1478 else if (post_op_name[1] == '>' &&
1479 post_op_name[2] == '=' &&
1480 post_op_name[3] == '\0')
1481 {
1482 op_kind = OO_GreaterGreaterEqual;
1483 }
1484 break;
1485
1486 case ',':
1487 if (post_op_name[1] == '\0')
1488 op_kind = OO_Comma;
1489 break;
1490
1491 case '(':
1492 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1493 op_kind = OO_Call;
1494 break;
1495
1496 case '[':
1497 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1498 op_kind = OO_Subscript;
1499 break;
1500 }
1501
1502 return true;
1503}
Greg Clayton6beaaa62011-01-17 03:46:26 +00001504
Greg Clayton090d0982011-06-19 03:43:27 +00001505static inline bool
Sean Callanan6d9f5db2011-10-15 01:15:07 +00001506check_op_param (uint32_t op_kind, bool unary, bool binary, uint32_t num_params)
Greg Clayton090d0982011-06-19 03:43:27 +00001507{
Sean Callanan6d9f5db2011-10-15 01:15:07 +00001508 // Special-case call since it can take any number of operands
1509 if(op_kind == OO_Call)
1510 return true;
1511
Greg Clayton090d0982011-06-19 03:43:27 +00001512 // The parameter count doens't include "this"
1513 if (num_params == 0)
1514 return unary;
1515 if (num_params == 1)
1516 return binary;
Sean Callanan6d9f5db2011-10-15 01:15:07 +00001517 else
Greg Clayton090d0982011-06-19 03:43:27 +00001518 return false;
1519}
Sean Callanan6d9f5db2011-10-15 01:15:07 +00001520;
Greg Clayton090d0982011-06-19 03:43:27 +00001521bool
1522ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, uint32_t num_params)
1523{
Sean Callanan6d9f5db2011-10-15 01:15:07 +00001524#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) case OO_##Name: return check_op_param (op_kind, Unary, Binary, num_params);
Greg Clayton090d0982011-06-19 03:43:27 +00001525 switch (op_kind)
1526 {
1527#include "clang/Basic/OperatorKinds.def"
1528 default: break;
1529 }
1530 return false;
1531}
1532
Greg Claytona51ed9b2010-09-23 01:09:21 +00001533CXXMethodDecl *
Sean Callanan61da09b2010-09-17 02:58:26 +00001534ClangASTContext::AddMethodToCXXRecordType
1535(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001536 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001537 clang_type_t record_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001538 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001539 clang_type_t method_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001540 lldb::AccessType access,
Greg Clayton0fffff52010-09-24 05:15:53 +00001541 bool is_virtual,
1542 bool is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00001543 bool is_inline,
1544 bool is_explicit
Greg Claytona51ed9b2010-09-23 01:09:21 +00001545)
Sean Callanan61da09b2010-09-17 02:58:26 +00001546{
Sean Callananfc55f5d2010-09-21 00:44:12 +00001547 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chend440bcc2010-09-28 16:10:54 +00001548 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001549
Greg Clayton6beaaa62011-01-17 03:46:26 +00001550 assert(ast);
Sean Callanan61da09b2010-09-17 02:58:26 +00001551
Greg Clayton6beaaa62011-01-17 03:46:26 +00001552 IdentifierTable *identifier_table = &ast->Idents;
Sean Callanan61da09b2010-09-17 02:58:26 +00001553
1554 assert(identifier_table);
1555
Sean Callananfc55f5d2010-09-21 00:44:12 +00001556 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001557
Greg Clayton6beaaa62011-01-17 03:46:26 +00001558 CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
Sean Callanan61da09b2010-09-17 02:58:26 +00001559
Greg Clayton0fffff52010-09-24 05:15:53 +00001560 if (cxx_record_decl == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001561 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001562
Greg Clayton0fffff52010-09-24 05:15:53 +00001563 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001564
Greg Claytonf51de672010-10-01 02:31:07 +00001565 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001566
Greg Claytonf51de672010-10-01 02:31:07 +00001567 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton878eaf12010-10-01 03:45:20 +00001568
Greg Clayton878eaf12010-10-01 03:45:20 +00001569 const bool is_implicitly_declared = false;
Greg Claytonf51de672010-10-01 02:31:07 +00001570
Sean Callanan78e37602011-01-27 04:42:51 +00001571 const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton878eaf12010-10-01 03:45:20 +00001572
Greg Clayton90a2acd2010-10-02 01:40:05 +00001573 if (function_Type == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001574 return NULL;
1575
Sean Callanan78e37602011-01-27 04:42:51 +00001576 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton878eaf12010-10-01 03:45:20 +00001577
1578 if (!method_function_prototype)
1579 return NULL;
1580
1581 unsigned int num_params = method_function_prototype->getNumArgs();
1582
1583 if (name[0] == '~')
Greg Claytonf51de672010-10-01 02:31:07 +00001584 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001585 cxx_method_decl = CXXDestructorDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001586 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001587 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001588 DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001589 method_qual_type,
Sean Callanan31e851c2010-10-29 18:38:40 +00001590 NULL,
Greg Clayton878eaf12010-10-01 03:45:20 +00001591 is_inline,
1592 is_implicitly_declared);
1593 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001594 else if (decl_name == cxx_record_decl->getDeclName())
Greg Clayton878eaf12010-10-01 03:45:20 +00001595 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001596 cxx_method_decl = CXXConstructorDecl::Create (*ast,
Greg Claytonf51de672010-10-01 02:31:07 +00001597 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001598 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001599 DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Claytonf51de672010-10-01 02:31:07 +00001600 method_qual_type,
1601 NULL, // TypeSourceInfo *
1602 is_explicit,
1603 is_inline,
Sean Callanan880e6802011-10-07 23:18:13 +00001604 is_implicitly_declared,
1605 false /*is_constexpr*/);
Greg Claytonf51de672010-10-01 02:31:07 +00001606 }
1607 else
Greg Clayton878eaf12010-10-01 03:45:20 +00001608 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001609
1610 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1611 if (IsOperator (name, op_kind))
Greg Clayton878eaf12010-10-01 03:45:20 +00001612 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001613 if (op_kind != NUM_OVERLOADED_OPERATORS)
1614 {
Greg Clayton090d0982011-06-19 03:43:27 +00001615 // Check the number of operator parameters. Sometimes we have
1616 // seen bad DWARF that doesn't correctly describe operators and
1617 // if we try to create a methed and add it to the class, clang
1618 // will assert and crash, so we need to make sure things are
1619 // acceptable.
1620 if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
1621 return NULL;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001622 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001623 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001624 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001625 DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001626 method_qual_type,
1627 NULL, // TypeSourceInfo *
Greg Claytona3c444a2010-10-01 23:13:49 +00001628 is_static,
1629 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001630 is_inline,
Sean Callanan880e6802011-10-07 23:18:13 +00001631 false /*is_constexpr*/,
Sean Callananfb0b7582011-03-15 00:17:19 +00001632 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001633 }
1634 else if (num_params == 0)
1635 {
1636 // Conversion operators don't take params...
Greg Clayton6beaaa62011-01-17 03:46:26 +00001637 cxx_method_decl = CXXConversionDecl::Create (*ast,
Greg Claytona3c444a2010-10-01 23:13:49 +00001638 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001639 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001640 DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytona3c444a2010-10-01 23:13:49 +00001641 method_qual_type,
1642 NULL, // TypeSourceInfo *
1643 is_inline,
Sean Callananfb0b7582011-03-15 00:17:19 +00001644 is_explicit,
Sean Callanan880e6802011-10-07 23:18:13 +00001645 false /*is_constexpr*/,
Sean Callananfb0b7582011-03-15 00:17:19 +00001646 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001647 }
Greg Clayton878eaf12010-10-01 03:45:20 +00001648 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001649
1650 if (cxx_method_decl == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001651 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001652 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001653 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001654 SourceLocation(),
Greg Claytona3c444a2010-10-01 23:13:49 +00001655 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001656 method_qual_type,
1657 NULL, // TypeSourceInfo *
1658 is_static,
1659 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001660 is_inline,
Sean Callanan880e6802011-10-07 23:18:13 +00001661 false /*is_constexpr*/,
Sean Callananfb0b7582011-03-15 00:17:19 +00001662 SourceLocation());
Greg Clayton878eaf12010-10-01 03:45:20 +00001663 }
Greg Claytonf51de672010-10-01 02:31:07 +00001664 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001665
Greg Clayton1be10fc2010-09-29 01:12:09 +00001666 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton0fffff52010-09-24 05:15:53 +00001667
1668 cxx_method_decl->setAccess (access_specifier);
1669 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001670
Sean Callananfc55f5d2010-09-21 00:44:12 +00001671 // Populate the method decl with parameter decls
Sean Callananfc55f5d2010-09-21 00:44:12 +00001672
Charles Davis8c444c42011-05-19 23:33:46 +00001673 llvm::SmallVector<ParmVarDecl *, 12> params;
Sean Callananfc55f5d2010-09-21 00:44:12 +00001674
1675 for (int param_index = 0;
1676 param_index < num_params;
1677 ++param_index)
1678 {
Charles Davis8c444c42011-05-19 23:33:46 +00001679 params.push_back (ParmVarDecl::Create (*ast,
1680 cxx_method_decl,
1681 SourceLocation(),
1682 SourceLocation(),
1683 NULL, // anonymous
1684 method_function_prototype->getArgType(param_index),
1685 NULL,
1686 SC_None,
1687 SC_None,
1688 NULL));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001689 }
1690
Sean Callanan880e6802011-10-07 23:18:13 +00001691 cxx_method_decl->setParams (ArrayRef<ParmVarDecl*>(params));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001692
Greg Clayton0fffff52010-09-24 05:15:53 +00001693 cxx_record_decl->addDecl (cxx_method_decl);
Greg Claytonc432c192011-01-20 04:18:48 +00001694
1695// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic());
1696// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate());
1697// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD());
1698// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty());
1699// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract());
1700// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor());
1701// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
1702// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
1703// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor());
Greg Claytona51ed9b2010-09-23 01:09:21 +00001704 return cxx_method_decl;
Sean Callanan61da09b2010-09-17 02:58:26 +00001705}
1706
1707bool
Greg Clayton8cf05932010-07-22 18:30:50 +00001708ClangASTContext::AddFieldToRecordType
1709(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001710 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001711 clang_type_t record_clang_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001712 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001713 clang_type_t field_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001714 AccessType access,
1715 uint32_t bitfield_bit_size
1716)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001717{
1718 if (record_clang_type == NULL || field_type == NULL)
1719 return false;
1720
Greg Clayton6beaaa62011-01-17 03:46:26 +00001721 IdentifierTable *identifier_table = &ast->Idents;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001722
Greg Clayton6beaaa62011-01-17 03:46:26 +00001723 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001724 assert (identifier_table != NULL);
1725
1726 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1727
Sean Callanan78e37602011-01-27 04:42:51 +00001728 const clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001729 if (clang_type)
1730 {
1731 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1732
1733 if (record_type)
1734 {
1735 RecordDecl *record_decl = record_type->getDecl();
1736
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001737 clang::Expr *bit_width = NULL;
1738 if (bitfield_bit_size != 0)
1739 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001740 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1741 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001742 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001743 FieldDecl *field = FieldDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001744 record_decl,
1745 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001746 SourceLocation(),
Greg Clayton8cf05932010-07-22 18:30:50 +00001747 name ? &identifier_table->get(name) : NULL, // Identifier
1748 QualType::getFromOpaquePtr(field_type), // Field type
Sean Callanancc427fa2011-07-30 02:42:06 +00001749 NULL, // TInfo *
Greg Clayton8cf05932010-07-22 18:30:50 +00001750 bit_width, // BitWidth
Sean Callanancc427fa2011-07-30 02:42:06 +00001751 false, // Mutable
1752 false); // HasInit
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001753
Greg Clayton8cf05932010-07-22 18:30:50 +00001754 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001755
1756 if (field)
1757 {
1758 record_decl->addDecl(field);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001759 }
1760 }
Greg Clayton9e409562010-07-28 02:04:09 +00001761 else
1762 {
Sean Callanan78e37602011-01-27 04:42:51 +00001763 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001764 if (objc_class_type)
1765 {
Greg Clayton0fffff52010-09-24 05:15:53 +00001766 bool is_synthesized = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001767 ClangASTContext::AddObjCClassIVar (ast,
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001768 record_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001769 name,
1770 field_type,
1771 access,
1772 bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001773 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001774 }
1775 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001776 }
1777 return false;
1778}
1779
1780bool
1781ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1782{
1783 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1784}
1785
1786bool
1787ClangASTContext::FieldIsBitfield
1788(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001789 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001790 FieldDecl* field,
1791 uint32_t& bitfield_bit_size
1792)
1793{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001794 if (ast == NULL || field == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001795 return false;
1796
1797 if (field->isBitField())
1798 {
1799 Expr* bit_width_expr = field->getBitWidth();
1800 if (bit_width_expr)
1801 {
1802 llvm::APSInt bit_width_apsint;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001803 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001804 {
1805 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1806 return true;
1807 }
1808 }
1809 }
1810 return false;
1811}
1812
1813bool
1814ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1815{
1816 if (record_decl == NULL)
1817 return false;
1818
1819 if (!record_decl->field_empty())
1820 return true;
1821
1822 // No fields, lets check this is a CXX record and check the base classes
1823 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1824 if (cxx_record_decl)
1825 {
1826 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1827 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1828 base_class != base_class_end;
1829 ++base_class)
1830 {
1831 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1832 if (RecordHasFields(base_class_decl))
1833 return true;
1834 }
1835 }
1836 return false;
1837}
1838
1839void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001840ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001841{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001842 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001843 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001844 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1845
Sean Callanan78e37602011-01-27 04:42:51 +00001846 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001847 if (record_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001848 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001849 RecordDecl *record_decl = record_type->getDecl();
1850 if (record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001851 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001852 uint32_t field_idx;
1853 RecordDecl::field_iterator field, field_end;
1854 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1855 field != field_end;
1856 ++field, ++field_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001857 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001858 // If no accessibility was assigned, assign the correct one
1859 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1860 field->setAccess ((AccessSpecifier)default_accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001861 }
1862 }
1863 }
1864 }
1865}
1866
1867#pragma mark C++ Base Classes
1868
1869CXXBaseSpecifier *
Greg Clayton1be10fc2010-09-29 01:12:09 +00001870ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001871{
1872 if (base_class_type)
Greg Claytone6371122010-07-30 20:30:44 +00001873 return new CXXBaseSpecifier (SourceRange(),
1874 is_virtual,
1875 base_of_class,
1876 ConvertAccessTypeToAccessSpecifier (access),
Sean Callanan2c777c42011-01-18 23:32:05 +00001877 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
1878 SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001879 return NULL;
1880}
1881
Greg Clayton0b42ac32010-07-02 01:29:13 +00001882void
1883ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1884{
1885 for (unsigned i=0; i<num_base_classes; ++i)
1886 {
1887 delete base_classes[i];
1888 base_classes[i] = NULL;
1889 }
1890}
1891
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001892bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001893ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001894{
1895 if (class_clang_type)
1896 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001897 CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
1898 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001899 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001900 cxx_record_decl->setBases(base_classes, num_base_classes);
1901 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001902 }
1903 }
1904 return false;
1905}
Greg Clayton8cf05932010-07-22 18:30:50 +00001906#pragma mark Objective C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001907
Greg Clayton1be10fc2010-09-29 01:12:09 +00001908clang_type_t
Greg Clayton8cf05932010-07-22 18:30:50 +00001909ClangASTContext::CreateObjCClass
1910(
1911 const char *name,
1912 DeclContext *decl_ctx,
1913 bool isForwardDecl,
1914 bool isInternal
1915)
1916{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001917 ASTContext *ast = getASTContext();
1918 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001919 assert (name && name[0]);
1920 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001921 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001922
1923 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1924 // we will need to update this code. I was told to currently always use
1925 // the CXXRecordDecl class since we often don't know from debug information
1926 // if something is struct or a class, so we default to always use the more
1927 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001928 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001929 decl_ctx,
1930 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001931 &ast->Idents.get(name),
Greg Clayton8cf05932010-07-22 18:30:50 +00001932 SourceLocation(),
1933 isForwardDecl,
1934 isInternal);
Greg Clayton9e409562010-07-28 02:04:09 +00001935
Greg Clayton6beaaa62011-01-17 03:46:26 +00001936 return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001937}
1938
1939bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001940ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton8cf05932010-07-22 18:30:50 +00001941{
1942 if (class_opaque_type && super_opaque_type)
1943 {
1944 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1945 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
Sean Callanan78e37602011-01-27 04:42:51 +00001946 const clang::Type *class_type = class_qual_type.getTypePtr();
1947 const clang::Type *super_type = super_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001948 if (class_type && super_type)
1949 {
Sean Callanan78e37602011-01-27 04:42:51 +00001950 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1951 const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001952 if (objc_class_type && objc_super_type)
1953 {
1954 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1955 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1956 if (class_interface_decl && super_interface_decl)
1957 {
1958 class_interface_decl->setSuperClass(super_interface_decl);
1959 return true;
1960 }
1961 }
1962 }
1963 }
1964 return false;
1965}
1966
1967
1968bool
1969ClangASTContext::AddObjCClassIVar
1970(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001971 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001972 clang_type_t class_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001973 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001974 clang_type_t ivar_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001975 AccessType access,
1976 uint32_t bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001977 bool is_synthesized
Greg Clayton8cf05932010-07-22 18:30:50 +00001978)
1979{
1980 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1981 return false;
1982
Greg Clayton6beaaa62011-01-17 03:46:26 +00001983 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton8cf05932010-07-22 18:30:50 +00001984
Greg Clayton6beaaa62011-01-17 03:46:26 +00001985 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001986 assert (identifier_table != NULL);
1987
1988 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1989
Sean Callanan78e37602011-01-27 04:42:51 +00001990 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001991 if (class_type)
1992 {
Sean Callanan78e37602011-01-27 04:42:51 +00001993 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001994
1995 if (objc_class_type)
1996 {
1997 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1998
1999 if (class_interface_decl)
2000 {
2001 clang::Expr *bit_width = NULL;
2002 if (bitfield_bit_size != 0)
2003 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002004 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
2005 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Greg Clayton8cf05932010-07-22 18:30:50 +00002006 }
2007
Greg Clayton6beaaa62011-01-17 03:46:26 +00002008 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast,
Greg Clayton9e409562010-07-28 02:04:09 +00002009 class_interface_decl,
2010 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00002011 SourceLocation(),
Greg Clayton9e409562010-07-28 02:04:09 +00002012 &identifier_table->get(name), // Identifier
2013 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
2014 NULL, // TypeSourceInfo *
2015 ConvertAccessTypeToObjCIvarAccessControl (access),
2016 bit_width,
Greg Clayton0fffff52010-09-24 05:15:53 +00002017 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00002018
2019 if (field)
2020 {
2021 class_interface_decl->addDecl(field);
2022 return true;
2023 }
Greg Clayton8cf05932010-07-22 18:30:50 +00002024 }
2025 }
2026 }
2027 return false;
2028}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002029
Greg Clayton9e409562010-07-28 02:04:09 +00002030
2031bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00002032ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9e409562010-07-28 02:04:09 +00002033{
2034 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
2035
Sean Callanan78e37602011-01-27 04:42:51 +00002036 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton9e409562010-07-28 02:04:09 +00002037 if (class_type)
2038 {
Sean Callanan78e37602011-01-27 04:42:51 +00002039 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00002040
2041 if (objc_class_type)
2042 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
2043 }
2044 return false;
2045}
2046
2047bool
2048ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
2049{
2050 while (class_interface_decl)
2051 {
2052 if (class_interface_decl->ivar_size() > 0)
2053 return true;
2054
2055 if (check_superclass)
2056 class_interface_decl = class_interface_decl->getSuperClass();
2057 else
2058 break;
2059 }
2060 return false;
2061}
Greg Clayton0fffff52010-09-24 05:15:53 +00002062
Greg Clayton1be10fc2010-09-29 01:12:09 +00002063ObjCMethodDecl *
Greg Clayton0fffff52010-09-24 05:15:53 +00002064ClangASTContext::AddMethodToObjCObjectType
2065(
Greg Clayton6beaaa62011-01-17 03:46:26 +00002066 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002067 clang_type_t class_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00002068 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton1be10fc2010-09-29 01:12:09 +00002069 clang_type_t method_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00002070 lldb::AccessType access
2071)
2072{
2073 if (class_opaque_type == NULL || method_opaque_type == NULL)
2074 return NULL;
2075
Greg Clayton6beaaa62011-01-17 03:46:26 +00002076 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton0fffff52010-09-24 05:15:53 +00002077
Greg Clayton6beaaa62011-01-17 03:46:26 +00002078 assert (ast != NULL);
Greg Clayton0fffff52010-09-24 05:15:53 +00002079 assert (identifier_table != NULL);
2080
2081 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
2082
Sean Callanan78e37602011-01-27 04:42:51 +00002083 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton0fffff52010-09-24 05:15:53 +00002084 if (class_type == NULL)
2085 return NULL;
2086
Sean Callanan78e37602011-01-27 04:42:51 +00002087 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton0fffff52010-09-24 05:15:53 +00002088
2089 if (objc_class_type == NULL)
2090 return NULL;
2091
2092 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2093
2094 if (class_interface_decl == NULL)
2095 return NULL;
Greg Clayton9e409562010-07-28 02:04:09 +00002096
Greg Clayton0fffff52010-09-24 05:15:53 +00002097 const char *selector_start = ::strchr (name, ' ');
2098 if (selector_start == NULL)
2099 return NULL;
2100
2101 selector_start++;
2102 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
2103 return NULL;
2104 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
2105
Greg Clayton450e3f32010-10-12 02:24:53 +00002106 size_t len = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +00002107 const char *start;
Greg Clayton450e3f32010-10-12 02:24:53 +00002108 //printf ("name = '%s'\n", name);
2109
2110 unsigned num_selectors_with_args = 0;
2111 for (start = selector_start;
Greg Clayton0fffff52010-09-24 05:15:53 +00002112 start && *start != '\0' && *start != ']';
Greg Clayton450e3f32010-10-12 02:24:53 +00002113 start += len)
Greg Clayton0fffff52010-09-24 05:15:53 +00002114 {
Greg Clayton450e3f32010-10-12 02:24:53 +00002115 len = ::strcspn(start, ":]");
Greg Clayton90f90cd2010-10-27 04:01:14 +00002116 bool has_arg = (start[len] == ':');
2117 if (has_arg)
Greg Clayton450e3f32010-10-12 02:24:53 +00002118 ++num_selectors_with_args;
Greg Clayton0fffff52010-09-24 05:15:53 +00002119 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton90f90cd2010-10-27 04:01:14 +00002120 if (has_arg)
2121 len += 1;
Greg Clayton0fffff52010-09-24 05:15:53 +00002122 }
2123
2124
2125 if (selector_idents.size() == 0)
2126 return 0;
2127
Greg Clayton6beaaa62011-01-17 03:46:26 +00002128 clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton0fffff52010-09-24 05:15:53 +00002129 selector_idents.data());
2130
2131 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
2132
2133 // Populate the method decl with parameter decls
Sean Callanan78e37602011-01-27 04:42:51 +00002134 const clang::Type *method_type(method_qual_type.getTypePtr());
Greg Clayton0fffff52010-09-24 05:15:53 +00002135
2136 if (method_type == NULL)
2137 return NULL;
2138
Sean Callanan78e37602011-01-27 04:42:51 +00002139 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00002140
2141 if (!method_function_prototype)
2142 return NULL;
2143
2144
2145 bool is_variadic = false;
2146 bool is_synthesized = false;
2147 bool is_defined = false;
2148 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
2149
2150 const unsigned num_args = method_function_prototype->getNumArgs();
2151
Greg Clayton6beaaa62011-01-17 03:46:26 +00002152 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00002153 SourceLocation(), // beginLoc,
2154 SourceLocation(), // endLoc,
2155 method_selector,
2156 method_function_prototype->getResultType(),
2157 NULL, // TypeSourceInfo *ResultTInfo,
2158 GetDeclContextForType (class_opaque_type),
2159 name[0] == '-',
2160 is_variadic,
2161 is_synthesized,
Sean Callanan880e6802011-10-07 23:18:13 +00002162 true, // is_implicitly_declared
Greg Clayton0fffff52010-09-24 05:15:53 +00002163 is_defined,
2164 imp_control,
Sean Callanan880e6802011-10-07 23:18:13 +00002165 false /*has_related_result_type*/);
Greg Clayton0fffff52010-09-24 05:15:53 +00002166
2167
2168 if (objc_method_decl == NULL)
2169 return NULL;
2170
2171 if (num_args > 0)
2172 {
2173 llvm::SmallVector<ParmVarDecl *, 12> params;
2174
2175 for (int param_index = 0; param_index < num_args; ++param_index)
2176 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002177 params.push_back (ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00002178 objc_method_decl,
2179 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00002180 SourceLocation(),
Greg Clayton0fffff52010-09-24 05:15:53 +00002181 NULL, // anonymous
2182 method_function_prototype->getArgType(param_index),
2183 NULL,
2184 SC_Auto,
2185 SC_Auto,
2186 NULL));
2187 }
2188
Sean Callanan880e6802011-10-07 23:18:13 +00002189 objc_method_decl->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
Greg Clayton0fffff52010-09-24 05:15:53 +00002190 }
2191
2192 class_interface_decl->addDecl (objc_method_decl);
2193
2194
2195 return objc_method_decl;
2196}
2197
2198
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002199uint32_t
Greg Clayton73b472d2010-10-27 03:32:59 +00002200ClangASTContext::GetTypeInfo
2201(
2202 clang_type_t clang_type,
Greg Clayton6beaaa62011-01-17 03:46:26 +00002203 clang::ASTContext *ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002204 clang_type_t *pointee_or_element_clang_type
2205)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002206{
2207 if (clang_type == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00002208 return 0;
2209
2210 if (pointee_or_element_clang_type)
2211 *pointee_or_element_clang_type = NULL;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002212
2213 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2214
2215 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2216 switch (type_class)
2217 {
Sean Callanana2424172010-10-25 00:29:48 +00002218 case clang::Type::Builtin:
2219 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2220 {
Sean Callanana2424172010-10-25 00:29:48 +00002221 case clang::BuiltinType::ObjCId:
2222 case clang::BuiltinType::ObjCClass:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002223 if (ast && pointee_or_element_clang_type)
2224 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanana2424172010-10-25 00:29:48 +00002225 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00002226 break;
2227 case clang::BuiltinType::Bool:
2228 case clang::BuiltinType::Char_U:
2229 case clang::BuiltinType::UChar:
2230 case clang::BuiltinType::WChar_U:
2231 case clang::BuiltinType::Char16:
2232 case clang::BuiltinType::Char32:
2233 case clang::BuiltinType::UShort:
2234 case clang::BuiltinType::UInt:
2235 case clang::BuiltinType::ULong:
2236 case clang::BuiltinType::ULongLong:
2237 case clang::BuiltinType::UInt128:
2238 case clang::BuiltinType::Char_S:
2239 case clang::BuiltinType::SChar:
2240 case clang::BuiltinType::WChar_S:
2241 case clang::BuiltinType::Short:
2242 case clang::BuiltinType::Int:
2243 case clang::BuiltinType::Long:
2244 case clang::BuiltinType::LongLong:
2245 case clang::BuiltinType::Int128:
2246 case clang::BuiltinType::Float:
2247 case clang::BuiltinType::Double:
2248 case clang::BuiltinType::LongDouble:
2249 return eTypeIsBuiltIn | eTypeHasValue | eTypeIsScalar;
Greg Clayton73b472d2010-10-27 03:32:59 +00002250 default:
2251 break;
Sean Callanana2424172010-10-25 00:29:48 +00002252 }
2253 return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002254
2255 case clang::Type::BlockPointer:
2256 if (pointee_or_element_clang_type)
2257 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2258 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
2259
Greg Clayton49462ea2011-01-15 02:52:14 +00002260 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002261
2262 case clang::Type::ConstantArray:
2263 case clang::Type::DependentSizedArray:
2264 case clang::Type::IncompleteArray:
2265 case clang::Type::VariableArray:
2266 if (pointee_or_element_clang_type)
2267 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
2268 return eTypeHasChildren | eTypeIsArray;
2269
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002270 case clang::Type::DependentName: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002271 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
2272 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
2273 case clang::Type::Decltype: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002274
2275 case clang::Type::Enum:
2276 if (pointee_or_element_clang_type)
2277 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
2278 return eTypeIsEnumeration | eTypeHasValue;
2279
Sean Callanan912855f2011-08-11 23:56:13 +00002280 case clang::Type::Elaborated:
2281 return ClangASTContext::GetTypeInfo (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2282 ast,
2283 pointee_or_element_clang_type);
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002284 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
2285 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
2286 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002287 case clang::Type::InjectedClassName: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002288
2289 case clang::Type::LValueReference:
2290 case clang::Type::RValueReference:
2291 if (pointee_or_element_clang_type)
2292 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
2293 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
2294
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002295 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002296
2297 case clang::Type::ObjCObjectPointer:
2298 if (pointee_or_element_clang_type)
2299 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2300 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
2301
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002302 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2303 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Clayton73b472d2010-10-27 03:32:59 +00002304
2305 case clang::Type::Pointer:
2306 if (pointee_or_element_clang_type)
2307 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2308 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
2309
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002310 case clang::Type::Record:
2311 if (qual_type->getAsCXXRecordDecl())
2312 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
2313 else
2314 return eTypeHasChildren | eTypeIsStructUnion;
2315 break;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002316 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
2317 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
2318 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Clayton73b472d2010-10-27 03:32:59 +00002319
2320 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002321 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00002322 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002323 pointee_or_element_clang_type);
2324
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002325 case clang::Type::TypeOfExpr: return 0;
2326 case clang::Type::TypeOf: return 0;
2327 case clang::Type::UnresolvedUsing: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002328 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
2329 default: return 0;
2330 }
2331 return 0;
2332}
2333
Greg Clayton9e409562010-07-28 02:04:09 +00002334
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002335#pragma mark Aggregate Types
2336
2337bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00002338ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002339{
2340 if (clang_type == NULL)
2341 return false;
2342
2343 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2344
Greg Clayton737b9322010-09-13 03:32:57 +00002345 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2346 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002347 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002348 case clang::Type::IncompleteArray:
2349 case clang::Type::VariableArray:
2350 case clang::Type::ConstantArray:
2351 case clang::Type::ExtVector:
2352 case clang::Type::Vector:
2353 case clang::Type::Record:
Greg Clayton9e409562010-07-28 02:04:09 +00002354 case clang::Type::ObjCObject:
2355 case clang::Type::ObjCInterface:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002356 return true;
Sean Callanan912855f2011-08-11 23:56:13 +00002357 case clang::Type::Elaborated:
2358 return ClangASTContext::IsAggregateType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Greg Claytone1a916a2010-07-21 22:12:05 +00002359 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002360 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002361
2362 default:
2363 break;
2364 }
2365 // The clang type does have a value
2366 return false;
2367}
2368
2369uint32_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00002370ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002371{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002372 if (clang_type == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002373 return 0;
2374
2375 uint32_t num_children = 0;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002376 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00002377 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2378 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002379 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002380 case clang::Type::Builtin:
2381 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2382 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002383 case clang::BuiltinType::ObjCId: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002384 case clang::BuiltinType::ObjCClass: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002385 num_children = 1;
Greg Clayton73b472d2010-10-27 03:32:59 +00002386 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002387
2388 default:
2389 break;
2390 }
2391 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002392
Greg Clayton49462ea2011-01-15 02:52:14 +00002393 case clang::Type::Complex: return 0;
Greg Clayton54979cd2010-12-15 05:08:08 +00002394
Greg Claytone1a916a2010-07-21 22:12:05 +00002395 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002396 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002397 {
2398 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2399 const RecordDecl *record_decl = record_type->getDecl();
2400 assert(record_decl);
2401 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2402 if (cxx_record_decl)
2403 {
2404 if (omit_empty_base_classes)
2405 {
2406 // Check each base classes to see if it or any of its
2407 // base classes contain any fields. This can help
2408 // limit the noise in variable views by not having to
2409 // show base classes that contain no members.
2410 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2411 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2412 base_class != base_class_end;
2413 ++base_class)
2414 {
2415 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2416
2417 // Skip empty base classes
2418 if (RecordHasFields(base_class_decl) == false)
2419 continue;
2420
2421 num_children++;
2422 }
2423 }
2424 else
2425 {
2426 // Include all base classes
2427 num_children += cxx_record_decl->getNumBases();
2428 }
2429
2430 }
2431 RecordDecl::field_iterator field, field_end;
2432 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2433 ++num_children;
2434 }
2435 break;
2436
Greg Clayton9e409562010-07-28 02:04:09 +00002437 case clang::Type::ObjCObject:
2438 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002439 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002440 {
Sean Callanan78e37602011-01-27 04:42:51 +00002441 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002442 assert (objc_class_type);
2443 if (objc_class_type)
2444 {
2445 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2446
2447 if (class_interface_decl)
2448 {
2449
2450 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2451 if (superclass_interface_decl)
2452 {
2453 if (omit_empty_base_classes)
2454 {
2455 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2456 ++num_children;
2457 }
2458 else
2459 ++num_children;
2460 }
2461
2462 num_children += class_interface_decl->ivar_size();
2463 }
2464 }
2465 }
2466 break;
2467
2468 case clang::Type::ObjCObjectPointer:
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002469 {
Sean Callanan78e37602011-01-27 04:42:51 +00002470 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002471 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002472 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2473 pointee_type.getAsOpaquePtr(),
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002474 omit_empty_base_classes);
2475 // If this type points to a simple type, then it has 1 child
2476 if (num_pointee_children == 0)
2477 num_children = 1;
2478 else
2479 num_children = num_pointee_children;
2480 }
2481 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002482
Greg Claytone1a916a2010-07-21 22:12:05 +00002483 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002484 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2485 break;
2486
Greg Claytone1a916a2010-07-21 22:12:05 +00002487 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002488 {
Sean Callanan78e37602011-01-27 04:42:51 +00002489 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002490 QualType pointee_type (pointer_type->getPointeeType());
Greg Clayton6beaaa62011-01-17 03:46:26 +00002491 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2492 pointee_type.getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00002493 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002494 if (num_pointee_children == 0)
Greg Clayton54979cd2010-12-15 05:08:08 +00002495 {
2496 // We have a pointer to a pointee type that claims it has no children.
2497 // We will want to look at
2498 num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
2499 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002500 else
2501 num_children = num_pointee_children;
2502 }
2503 break;
2504
Greg Clayton73b472d2010-10-27 03:32:59 +00002505 case clang::Type::LValueReference:
2506 case clang::Type::RValueReference:
2507 {
Sean Callanan78e37602011-01-27 04:42:51 +00002508 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002509 QualType pointee_type = reference_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002510 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2511 pointee_type.getAsOpaquePtr(),
Greg Clayton73b472d2010-10-27 03:32:59 +00002512 omit_empty_base_classes);
2513 // If this type points to a simple type, then it has 1 child
2514 if (num_pointee_children == 0)
2515 num_children = 1;
2516 else
2517 num_children = num_pointee_children;
2518 }
2519 break;
2520
2521
Greg Claytone1a916a2010-07-21 22:12:05 +00002522 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002523 num_children = ClangASTContext::GetNumChildren (ast,
2524 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2525 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002526 break;
Sean Callanan912855f2011-08-11 23:56:13 +00002527
2528 case clang::Type::Elaborated:
2529 num_children = ClangASTContext::GetNumChildren (ast,
2530 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2531 omit_empty_base_classes);
2532 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002533
2534 default:
2535 break;
2536 }
2537 return num_children;
2538}
2539
Greg Claytonbf2331c2011-09-09 23:04:00 +00002540uint32_t
2541ClangASTContext::GetNumDirectBaseClasses (clang::ASTContext *ast, clang_type_t clang_type)
2542{
2543 if (clang_type == NULL)
2544 return 0;
2545
2546 uint32_t count = 0;
2547 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2548 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2549 switch (type_class)
2550 {
2551 case clang::Type::Record:
2552 if (GetCompleteQualType (ast, qual_type))
2553 {
2554 const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2555 if (cxx_record_decl)
2556 count = cxx_record_decl->getNumBases();
2557 }
2558 break;
2559
2560 case clang::Type::ObjCObject:
2561 case clang::Type::ObjCInterface:
2562 if (GetCompleteQualType (ast, qual_type))
2563 {
2564 const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
2565 if (objc_class_type)
2566 {
2567 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2568
2569 if (class_interface_decl && class_interface_decl->getSuperClass())
2570 count = 1;
2571 }
2572 }
2573 break;
2574
2575
2576 case clang::Type::Typedef:
2577 count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2578 break;
2579
2580 case clang::Type::Elaborated:
2581 count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2582 break;
2583
2584 default:
2585 break;
2586 }
2587 return count;
2588}
2589
2590uint32_t
2591ClangASTContext::GetNumVirtualBaseClasses (clang::ASTContext *ast,
2592 clang_type_t clang_type)
2593{
2594 if (clang_type == NULL)
2595 return 0;
2596
2597 uint32_t count = 0;
2598 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2599 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2600 switch (type_class)
2601 {
2602 case clang::Type::Record:
2603 if (GetCompleteQualType (ast, qual_type))
2604 {
2605 const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2606 if (cxx_record_decl)
2607 count = cxx_record_decl->getNumVBases();
2608 }
2609 break;
2610
2611 case clang::Type::Typedef:
2612 count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2613 break;
2614
2615 case clang::Type::Elaborated:
2616 count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2617 break;
2618
2619 default:
2620 break;
2621 }
2622 return count;
2623}
2624
2625uint32_t
2626ClangASTContext::GetNumFields (clang::ASTContext *ast, clang_type_t clang_type)
2627{
2628 if (clang_type == NULL)
2629 return 0;
2630
2631 uint32_t count = 0;
2632 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2633 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2634 switch (type_class)
2635 {
2636 case clang::Type::Record:
2637 if (GetCompleteQualType (ast, qual_type))
2638 {
2639 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
2640 if (record_type)
2641 {
2642 RecordDecl *record_decl = record_type->getDecl();
2643 if (record_decl)
2644 {
2645 uint32_t field_idx = 0;
2646 RecordDecl::field_iterator field, field_end;
2647 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2648 ++field_idx;
2649 count = field_idx;
2650 }
2651 }
2652 }
2653 break;
2654
2655 case clang::Type::Typedef:
2656 count = ClangASTContext::GetNumFields (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2657 break;
2658
2659 case clang::Type::Elaborated:
2660 count = ClangASTContext::GetNumFields (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2661 break;
2662
2663 default:
2664 break;
2665 }
2666 return count;
2667}
2668
2669clang_type_t
2670ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast,
2671 clang_type_t clang_type,
2672 uint32_t idx,
2673 uint32_t *byte_offset_ptr)
2674{
2675 if (clang_type == NULL)
2676 return 0;
2677
2678 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2679 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2680 switch (type_class)
2681 {
2682 case clang::Type::Record:
2683 if (GetCompleteQualType (ast, qual_type))
2684 {
2685 const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2686 if (cxx_record_decl)
2687 {
2688 uint32_t curr_idx = 0;
2689 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2690 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2691 base_class != base_class_end;
2692 ++base_class, ++curr_idx)
2693 {
2694 if (curr_idx == idx)
2695 {
2696 if (byte_offset_ptr)
2697 {
2698 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
2699 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2700// if (base_class->isVirtual())
2701// *byte_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
2702// else
2703 *byte_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
2704 }
2705 return base_class->getType().getAsOpaquePtr();
2706 }
2707 }
2708 }
2709 }
2710 break;
2711
2712 case clang::Type::ObjCObject:
2713 case clang::Type::ObjCInterface:
2714 if (idx == 0 && GetCompleteQualType (ast, qual_type))
2715 {
2716 const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
2717 if (objc_class_type)
2718 {
2719 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2720
2721 if (class_interface_decl)
2722 {
2723 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2724 if (superclass_interface_decl)
2725 {
2726 if (byte_offset_ptr)
2727 *byte_offset_ptr = 0;
2728 return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr();
2729 }
2730 }
2731 }
2732 }
2733 break;
2734
2735
2736 case clang::Type::Typedef:
2737 return ClangASTContext::GetDirectBaseClassAtIndex (ast,
2738 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2739 idx,
2740 byte_offset_ptr);
2741
2742 case clang::Type::Elaborated:
2743 return ClangASTContext::GetDirectBaseClassAtIndex (ast,
2744 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2745 idx,
2746 byte_offset_ptr);
2747
2748 default:
2749 break;
2750 }
2751 return NULL;
2752}
2753
2754clang_type_t
2755ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast,
2756 clang_type_t clang_type,
2757 uint32_t idx,
2758 uint32_t *byte_offset_ptr)
2759{
2760 if (clang_type == NULL)
2761 return 0;
2762
2763 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2764 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2765 switch (type_class)
2766 {
2767 case clang::Type::Record:
2768 if (GetCompleteQualType (ast, qual_type))
2769 {
2770 const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2771 if (cxx_record_decl)
2772 {
2773 uint32_t curr_idx = 0;
2774 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2775 for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end();
2776 base_class != base_class_end;
2777 ++base_class, ++curr_idx)
2778 {
2779 if (curr_idx == idx)
2780 {
2781 if (byte_offset_ptr)
2782 {
2783 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
2784 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2785 *byte_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
2786
2787 }
2788 return base_class->getType().getAsOpaquePtr();
2789 }
2790 }
2791 }
2792 }
2793 break;
2794
2795 case clang::Type::Typedef:
2796 return ClangASTContext::GetVirtualBaseClassAtIndex (ast,
2797 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2798 idx,
2799 byte_offset_ptr);
2800
2801 case clang::Type::Elaborated:
2802 return ClangASTContext::GetVirtualBaseClassAtIndex (ast,
2803 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2804 idx,
2805 byte_offset_ptr);
2806
2807 default:
2808 break;
2809 }
2810 return NULL;
2811}
2812
2813clang_type_t
2814ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast,
2815 clang_type_t clang_type,
2816 uint32_t idx,
2817 std::string& name,
2818 uint32_t *byte_offset_ptr)
2819{
2820 if (clang_type == NULL)
2821 return 0;
2822
2823 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2824 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2825 switch (type_class)
2826 {
2827 case clang::Type::Record:
2828 if (GetCompleteQualType (ast, qual_type))
2829 {
2830 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2831 const RecordDecl *record_decl = record_type->getDecl();
2832 uint32_t field_idx = 0;
2833 RecordDecl::field_iterator field, field_end;
2834 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
2835 {
2836 if (idx == field_idx)
2837 {
2838 // Print the member type if requested
2839 // Print the member name and equal sign
2840 name.assign(field->getNameAsString());
2841
2842 // Figure out the type byte size (field_type_info.first) and
2843 // alignment (field_type_info.second) from the AST context.
2844 if (byte_offset_ptr)
2845 {
2846 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
2847 *byte_offset_ptr = (record_layout.getFieldOffset (field_idx) + 7) / 8;
2848 }
2849
2850 return field->getType().getAsOpaquePtr();
2851 }
2852 }
2853 }
2854 break;
2855
2856 case clang::Type::ObjCObject:
2857 case clang::Type::ObjCInterface:
2858 if (GetCompleteQualType (ast, qual_type))
2859 {
2860 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2861 assert (objc_class_type);
2862 if (objc_class_type)
2863 {
2864 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2865
2866 if (class_interface_decl)
2867 {
2868 if (idx < (class_interface_decl->ivar_size()))
2869 {
2870 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2871 uint32_t ivar_idx = 0;
2872
2873 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx)
2874 {
2875 if (ivar_idx == idx)
2876 {
2877 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2878
2879 QualType ivar_qual_type(ivar_decl->getType());
2880
2881 name.assign(ivar_decl->getNameAsString());
2882
2883 if (byte_offset_ptr)
2884 {
2885 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
2886 *byte_offset_ptr = (interface_layout.getFieldOffset (ivar_idx) + 7)/8;
2887 }
2888
2889 return ivar_qual_type.getAsOpaquePtr();
2890 }
2891 }
2892 }
2893 }
2894 }
2895 }
2896 break;
2897
2898
2899 case clang::Type::Typedef:
2900 return ClangASTContext::GetFieldAtIndex (ast,
2901 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2902 idx,
2903 name,
2904 byte_offset_ptr);
2905
2906 case clang::Type::Elaborated:
2907 return ClangASTContext::GetFieldAtIndex (ast,
2908 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2909 idx,
2910 name,
2911 byte_offset_ptr);
2912
2913 default:
2914 break;
2915 }
2916 return NULL;
2917}
2918
2919
Greg Clayton54979cd2010-12-15 05:08:08 +00002920// If a pointer to a pointee type (the clang_type arg) says that it has no
2921// children, then we either need to trust it, or override it and return a
2922// different result. For example, an "int *" has one child that is an integer,
2923// but a function pointer doesn't have any children. Likewise if a Record type
2924// claims it has no children, then there really is nothing to show.
2925uint32_t
2926ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
2927{
2928 if (clang_type == NULL)
2929 return 0;
2930
2931 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2932 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2933 switch (type_class)
2934 {
Greg Clayton97a43712011-01-08 22:26:47 +00002935 case clang::Type::Builtin:
2936 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2937 {
Greg Clayton7260f622011-04-18 08:33:37 +00002938 case clang::BuiltinType::UnknownAny:
Greg Clayton97a43712011-01-08 22:26:47 +00002939 case clang::BuiltinType::Void:
2940 case clang::BuiltinType::NullPtr:
2941 return 0;
2942 case clang::BuiltinType::Bool:
2943 case clang::BuiltinType::Char_U:
2944 case clang::BuiltinType::UChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002945 case clang::BuiltinType::WChar_U:
Greg Clayton97a43712011-01-08 22:26:47 +00002946 case clang::BuiltinType::Char16:
2947 case clang::BuiltinType::Char32:
2948 case clang::BuiltinType::UShort:
2949 case clang::BuiltinType::UInt:
2950 case clang::BuiltinType::ULong:
2951 case clang::BuiltinType::ULongLong:
2952 case clang::BuiltinType::UInt128:
2953 case clang::BuiltinType::Char_S:
2954 case clang::BuiltinType::SChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002955 case clang::BuiltinType::WChar_S:
Greg Clayton97a43712011-01-08 22:26:47 +00002956 case clang::BuiltinType::Short:
2957 case clang::BuiltinType::Int:
2958 case clang::BuiltinType::Long:
2959 case clang::BuiltinType::LongLong:
2960 case clang::BuiltinType::Int128:
2961 case clang::BuiltinType::Float:
2962 case clang::BuiltinType::Double:
2963 case clang::BuiltinType::LongDouble:
2964 case clang::BuiltinType::Dependent:
2965 case clang::BuiltinType::Overload:
Greg Clayton97a43712011-01-08 22:26:47 +00002966 case clang::BuiltinType::ObjCId:
2967 case clang::BuiltinType::ObjCClass:
2968 case clang::BuiltinType::ObjCSel:
Sean Callanand12cf8bb2011-05-15 22:34:38 +00002969 case clang::BuiltinType::BoundMember:
Greg Claytonf0705c82011-10-22 03:33:13 +00002970 case clang::BuiltinType::Half:
2971 case clang::BuiltinType::ARCUnbridgedCast:
Greg Clayton97a43712011-01-08 22:26:47 +00002972 return 1;
2973 }
2974 break;
2975
Greg Clayton49462ea2011-01-15 02:52:14 +00002976 case clang::Type::Complex: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00002977 case clang::Type::Pointer: return 1;
2978 case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
2979 case clang::Type::LValueReference: return 1;
2980 case clang::Type::RValueReference: return 1;
2981 case clang::Type::MemberPointer: return 0;
2982 case clang::Type::ConstantArray: return 0;
2983 case clang::Type::IncompleteArray: return 0;
2984 case clang::Type::VariableArray: return 0;
2985 case clang::Type::DependentSizedArray: return 0;
2986 case clang::Type::DependentSizedExtVector: return 0;
2987 case clang::Type::Vector: return 0;
2988 case clang::Type::ExtVector: return 0;
2989 case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
2990 case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
2991 case clang::Type::UnresolvedUsing: return 0;
2992 case clang::Type::Paren: return 0;
2993 case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00002994 case clang::Type::Elaborated: return ClangASTContext::GetNumPointeeChildren (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002995 case clang::Type::TypeOfExpr: return 0;
2996 case clang::Type::TypeOf: return 0;
2997 case clang::Type::Decltype: return 0;
2998 case clang::Type::Record: return 0;
2999 case clang::Type::Enum: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00003000 case clang::Type::TemplateTypeParm: return 1;
3001 case clang::Type::SubstTemplateTypeParm: return 1;
3002 case clang::Type::TemplateSpecialization: return 1;
3003 case clang::Type::InjectedClassName: return 0;
3004 case clang::Type::DependentName: return 1;
3005 case clang::Type::DependentTemplateSpecialization: return 1;
3006 case clang::Type::ObjCObject: return 0;
3007 case clang::Type::ObjCInterface: return 0;
3008 case clang::Type::ObjCObjectPointer: return 1;
3009 default:
3010 break;
3011 }
3012 return 0;
3013}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003014
Greg Clayton1be10fc2010-09-29 01:12:09 +00003015clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003016ClangASTContext::GetChildClangTypeAtIndex
3017(
Jim Inghamd555bac2011-06-24 22:03:24 +00003018 ExecutionContext *exe_ctx,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003019 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003020 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003021 uint32_t idx,
3022 bool transparent_pointers,
3023 bool omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003024 bool ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003025 std::string& child_name,
3026 uint32_t &child_byte_size,
3027 int32_t &child_byte_offset,
3028 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003029 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003030 bool &child_is_base_class,
3031 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003032)
3033{
3034 if (parent_clang_type)
3035
Jim Inghamd555bac2011-06-24 22:03:24 +00003036 return GetChildClangTypeAtIndex (exe_ctx,
3037 getASTContext(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003038 parent_name,
3039 parent_clang_type,
3040 idx,
3041 transparent_pointers,
3042 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003043 ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003044 child_name,
3045 child_byte_size,
3046 child_byte_offset,
3047 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003048 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003049 child_is_base_class,
3050 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003051 return NULL;
3052}
3053
Greg Clayton1be10fc2010-09-29 01:12:09 +00003054clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003055ClangASTContext::GetChildClangTypeAtIndex
3056(
Jim Inghamd555bac2011-06-24 22:03:24 +00003057 ExecutionContext *exe_ctx,
Greg Clayton6beaaa62011-01-17 03:46:26 +00003058 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003059 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003060 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003061 uint32_t idx,
3062 bool transparent_pointers,
3063 bool omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003064 bool ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003065 std::string& child_name,
3066 uint32_t &child_byte_size,
3067 int32_t &child_byte_offset,
3068 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003069 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003070 bool &child_is_base_class,
3071 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003072)
3073{
3074 if (parent_clang_type == NULL)
3075 return NULL;
3076
Greg Clayton6beaaa62011-01-17 03:46:26 +00003077 if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003078 {
3079 uint32_t bit_offset;
3080 child_bitfield_bit_size = 0;
3081 child_bitfield_bit_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003082 child_is_base_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003083 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003084 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
3085 switch (parent_type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003086 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003087 case clang::Type::Builtin:
3088 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
3089 {
3090 case clang::BuiltinType::ObjCId:
3091 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00003092 child_name = "isa";
Greg Clayton6beaaa62011-01-17 03:46:26 +00003093 child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
3094 return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003095
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003096 default:
3097 break;
3098 }
3099 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003100
Greg Claytone1a916a2010-07-21 22:12:05 +00003101 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003102 if (GetCompleteQualType (ast, parent_qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003103 {
3104 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
3105 const RecordDecl *record_decl = record_type->getDecl();
3106 assert(record_decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003107 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003108 uint32_t child_idx = 0;
3109
3110 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3111 if (cxx_record_decl)
3112 {
3113 // We might have base classes to print out first
3114 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3115 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3116 base_class != base_class_end;
3117 ++base_class)
3118 {
3119 const CXXRecordDecl *base_class_decl = NULL;
3120
3121 // Skip empty base classes
3122 if (omit_empty_base_classes)
3123 {
3124 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3125 if (RecordHasFields(base_class_decl) == false)
3126 continue;
3127 }
3128
3129 if (idx == child_idx)
3130 {
3131 if (base_class_decl == NULL)
3132 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3133
3134
3135 if (base_class->isVirtual())
Greg Clayton6ed95942011-01-22 07:12:45 +00003136 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003137 else
Greg Clayton6ed95942011-01-22 07:12:45 +00003138 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003139
3140 // Base classes should be a multiple of 8 bits in size
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003141 child_byte_offset = bit_offset/8;
Greg Claytone3055942011-06-30 02:28:26 +00003142
3143 child_name = ClangASTType::GetTypeNameForQualType(base_class->getType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003144
Greg Clayton6beaaa62011-01-17 03:46:26 +00003145 uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003146
Jim Inghamf46b3382011-04-15 23:42:06 +00003147 // Base classes bit sizes should be a multiple of 8 bits in size
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003148 assert (clang_type_info_bit_size % 8 == 0);
3149 child_byte_size = clang_type_info_bit_size / 8;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003150 child_is_base_class = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003151 return base_class->getType().getAsOpaquePtr();
3152 }
3153 // We don't increment the child index in the for loop since we might
3154 // be skipping empty base classes
3155 ++child_idx;
3156 }
3157 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003158 // Make sure index is in range...
3159 uint32_t field_idx = 0;
3160 RecordDecl::field_iterator field, field_end;
3161 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
3162 {
3163 if (idx == child_idx)
3164 {
3165 // Print the member type if requested
3166 // Print the member name and equal sign
3167 child_name.assign(field->getNameAsString().c_str());
3168
3169 // Figure out the type byte size (field_type_info.first) and
3170 // alignment (field_type_info.second) from the AST context.
Greg Clayton6beaaa62011-01-17 03:46:26 +00003171 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
Greg Claytonc982c762010-07-09 20:39:50 +00003172 assert(field_idx < record_layout.getFieldCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003173
3174 child_byte_size = field_type_info.first / 8;
3175
3176 // Figure out the field offset within the current struct/union/class type
3177 bit_offset = record_layout.getFieldOffset (field_idx);
3178 child_byte_offset = bit_offset / 8;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003179 if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003180 child_bitfield_bit_offset = bit_offset % 8;
3181
3182 return field->getType().getAsOpaquePtr();
3183 }
3184 }
3185 }
3186 break;
3187
Greg Clayton9e409562010-07-28 02:04:09 +00003188 case clang::Type::ObjCObject:
3189 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003190 if (GetCompleteQualType (ast, parent_qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003191 {
Sean Callanan78e37602011-01-27 04:42:51 +00003192 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003193 assert (objc_class_type);
3194 if (objc_class_type)
3195 {
3196 uint32_t child_idx = 0;
3197 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3198
3199 if (class_interface_decl)
3200 {
3201
Greg Clayton6beaaa62011-01-17 03:46:26 +00003202 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
Greg Clayton9e409562010-07-28 02:04:09 +00003203 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3204 if (superclass_interface_decl)
3205 {
3206 if (omit_empty_base_classes)
3207 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003208 if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9e409562010-07-28 02:04:09 +00003209 {
3210 if (idx == 0)
3211 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003212 QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
Greg Clayton9e409562010-07-28 02:04:09 +00003213
3214
3215 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
3216
Greg Clayton6beaaa62011-01-17 03:46:26 +00003217 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003218
3219 child_byte_size = ivar_type_info.first / 8;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003220 child_byte_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003221 child_is_base_class = true;
Greg Clayton9e409562010-07-28 02:04:09 +00003222
3223 return ivar_qual_type.getAsOpaquePtr();
3224 }
3225
3226 ++child_idx;
3227 }
3228 }
3229 else
3230 ++child_idx;
3231 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003232
3233 const uint32_t superclass_idx = child_idx;
Greg Clayton9e409562010-07-28 02:04:09 +00003234
3235 if (idx < (child_idx + class_interface_decl->ivar_size()))
3236 {
3237 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3238
3239 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3240 {
3241 if (child_idx == idx)
3242 {
3243 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3244
3245 QualType ivar_qual_type(ivar_decl->getType());
3246
3247 child_name.assign(ivar_decl->getNameAsString().c_str());
3248
Greg Clayton6beaaa62011-01-17 03:46:26 +00003249 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003250
3251 child_byte_size = ivar_type_info.first / 8;
3252
3253 // Figure out the field offset within the current struct/union/class type
Jim Inghamd555bac2011-06-24 22:03:24 +00003254 // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
3255 // that doesn't account for the space taken up by unbacked properties, or from
3256 // the changing size of base classes that are newer than this class.
3257 // So if we have a process around that we can ask about this object, do so.
3258 child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
Greg Claytonc14ee322011-09-22 04:58:26 +00003259 Process *process = NULL;
3260 if (exe_ctx)
3261 process = exe_ctx->GetProcessPtr();
3262 if (process)
Jim Inghamd555bac2011-06-24 22:03:24 +00003263 {
Greg Claytonc14ee322011-09-22 04:58:26 +00003264 ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
Jim Inghamd555bac2011-06-24 22:03:24 +00003265 if (objc_runtime != NULL)
3266 {
Enrico Granata6f3533f2011-07-29 19:53:35 +00003267 ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
Jim Inghamd555bac2011-06-24 22:03:24 +00003268 child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
3269 }
3270 }
3271
3272 if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
3273 {
3274 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
3275 child_byte_offset = bit_offset / 8;
3276 }
Greg Clayton9e409562010-07-28 02:04:09 +00003277
3278 return ivar_qual_type.getAsOpaquePtr();
3279 }
3280 ++child_idx;
3281 }
3282 }
3283 }
3284 }
3285 }
3286 break;
3287
3288 case clang::Type::ObjCObjectPointer:
3289 {
Sean Callanan78e37602011-01-27 04:42:51 +00003290 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003291 QualType pointee_type = pointer_type->getPointeeType();
3292
3293 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3294 {
Greg Claytone221f822011-01-21 01:59:00 +00003295 child_is_deref_of_parent = false;
3296 bool tmp_child_is_deref_of_parent = false;
Jim Inghamd555bac2011-06-24 22:03:24 +00003297 return GetChildClangTypeAtIndex (exe_ctx,
3298 ast,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003299 parent_name,
3300 pointer_type->getPointeeType().getAsOpaquePtr(),
3301 idx,
3302 transparent_pointers,
3303 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003304 ignore_array_bounds,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003305 child_name,
3306 child_byte_size,
3307 child_byte_offset,
3308 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003309 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003310 child_is_base_class,
3311 tmp_child_is_deref_of_parent);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003312 }
3313 else
3314 {
Greg Claytone221f822011-01-21 01:59:00 +00003315 child_is_deref_of_parent = true;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003316 if (parent_name)
3317 {
3318 child_name.assign(1, '*');
3319 child_name += parent_name;
3320 }
3321
3322 // We have a pointer to an simple type
3323 if (idx == 0)
3324 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003325 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003326 assert(clang_type_info.first % 8 == 0);
3327 child_byte_size = clang_type_info.first / 8;
3328 child_byte_offset = 0;
3329 return pointee_type.getAsOpaquePtr();
3330 }
3331 }
Greg Clayton9e409562010-07-28 02:04:09 +00003332 }
3333 break;
3334
Greg Claytone1a916a2010-07-21 22:12:05 +00003335 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003336 {
3337 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3338 const uint64_t element_count = array->getSize().getLimitedValue();
3339
Greg Claytondaf515f2011-07-09 20:12:33 +00003340 if (ignore_array_bounds || idx < element_count)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003341 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003342 if (GetCompleteQualType (ast, array->getElementType()))
3343 {
3344 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003345
Greg Clayton6beaaa62011-01-17 03:46:26 +00003346 char element_name[64];
3347 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003348
Greg Clayton6beaaa62011-01-17 03:46:26 +00003349 child_name.assign(element_name);
3350 assert(field_type_info.first % 8 == 0);
3351 child_byte_size = field_type_info.first / 8;
Greg Claytondaf515f2011-07-09 20:12:33 +00003352 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003353 return array->getElementType().getAsOpaquePtr();
3354 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003355 }
3356 }
3357 break;
3358
Greg Claytone1a916a2010-07-21 22:12:05 +00003359 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003360 {
Sean Callanan78e37602011-01-27 04:42:51 +00003361 const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003362 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton97a43712011-01-08 22:26:47 +00003363
3364 // Don't dereference "void *" pointers
3365 if (pointee_type->isVoidType())
3366 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003367
3368 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3369 {
Greg Claytone221f822011-01-21 01:59:00 +00003370 child_is_deref_of_parent = false;
3371 bool tmp_child_is_deref_of_parent = false;
Jim Inghamd555bac2011-06-24 22:03:24 +00003372 return GetChildClangTypeAtIndex (exe_ctx,
3373 ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003374 parent_name,
3375 pointer_type->getPointeeType().getAsOpaquePtr(),
3376 idx,
3377 transparent_pointers,
3378 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003379 ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003380 child_name,
3381 child_byte_size,
3382 child_byte_offset,
3383 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003384 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003385 child_is_base_class,
3386 tmp_child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003387 }
3388 else
3389 {
Greg Claytone221f822011-01-21 01:59:00 +00003390 child_is_deref_of_parent = true;
3391
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003392 if (parent_name)
3393 {
3394 child_name.assign(1, '*');
3395 child_name += parent_name;
3396 }
3397
3398 // We have a pointer to an simple type
3399 if (idx == 0)
3400 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003401 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003402 assert(clang_type_info.first % 8 == 0);
3403 child_byte_size = clang_type_info.first / 8;
3404 child_byte_offset = 0;
3405 return pointee_type.getAsOpaquePtr();
3406 }
3407 }
3408 }
3409 break;
3410
Greg Clayton73b472d2010-10-27 03:32:59 +00003411 case clang::Type::LValueReference:
3412 case clang::Type::RValueReference:
3413 {
Sean Callanan78e37602011-01-27 04:42:51 +00003414 const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00003415 QualType pointee_type(reference_type->getPointeeType());
3416 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
3417 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
3418 {
Greg Claytone221f822011-01-21 01:59:00 +00003419 child_is_deref_of_parent = false;
3420 bool tmp_child_is_deref_of_parent = false;
Jim Inghamd555bac2011-06-24 22:03:24 +00003421 return GetChildClangTypeAtIndex (exe_ctx,
3422 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00003423 parent_name,
3424 pointee_clang_type,
3425 idx,
3426 transparent_pointers,
3427 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003428 ignore_array_bounds,
Greg Clayton73b472d2010-10-27 03:32:59 +00003429 child_name,
3430 child_byte_size,
3431 child_byte_offset,
3432 child_bitfield_bit_size,
3433 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003434 child_is_base_class,
3435 tmp_child_is_deref_of_parent);
Greg Clayton73b472d2010-10-27 03:32:59 +00003436 }
3437 else
3438 {
3439 if (parent_name)
3440 {
3441 child_name.assign(1, '&');
3442 child_name += parent_name;
3443 }
3444
3445 // We have a pointer to an simple type
3446 if (idx == 0)
3447 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003448 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Clayton73b472d2010-10-27 03:32:59 +00003449 assert(clang_type_info.first % 8 == 0);
3450 child_byte_size = clang_type_info.first / 8;
3451 child_byte_offset = 0;
3452 return pointee_type.getAsOpaquePtr();
3453 }
3454 }
3455 }
3456 break;
3457
Greg Claytone1a916a2010-07-21 22:12:05 +00003458 case clang::Type::Typedef:
Jim Inghamd555bac2011-06-24 22:03:24 +00003459 return GetChildClangTypeAtIndex (exe_ctx,
3460 ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003461 parent_name,
Sean Callanan48114472010-12-13 01:26:27 +00003462 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003463 idx,
3464 transparent_pointers,
3465 omit_empty_base_classes,
Greg Claytondaf515f2011-07-09 20:12:33 +00003466 ignore_array_bounds,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003467 child_name,
3468 child_byte_size,
3469 child_byte_offset,
3470 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003471 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00003472 child_is_base_class,
3473 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003474 break;
Sean Callanan912855f2011-08-11 23:56:13 +00003475
3476 case clang::Type::Elaborated:
3477 return GetChildClangTypeAtIndex (exe_ctx,
3478 ast,
3479 parent_name,
3480 cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
3481 idx,
3482 transparent_pointers,
3483 omit_empty_base_classes,
3484 ignore_array_bounds,
3485 child_name,
3486 child_byte_size,
3487 child_byte_offset,
3488 child_bitfield_bit_size,
3489 child_bitfield_bit_offset,
3490 child_is_base_class,
3491 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003492
3493 default:
3494 break;
3495 }
3496 }
Greg Clayton19503a22010-07-23 15:37:46 +00003497 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003498}
3499
3500static inline bool
3501BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
3502{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003503 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003504}
3505
3506static uint32_t
3507GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
3508{
3509 uint32_t num_bases = 0;
3510 if (cxx_record_decl)
3511 {
3512 if (omit_empty_base_classes)
3513 {
3514 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3515 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3516 base_class != base_class_end;
3517 ++base_class)
3518 {
3519 // Skip empty base classes
3520 if (omit_empty_base_classes)
3521 {
3522 if (BaseSpecifierIsEmpty (base_class))
3523 continue;
3524 }
3525 ++num_bases;
3526 }
3527 }
3528 else
3529 num_bases = cxx_record_decl->getNumBases();
3530 }
3531 return num_bases;
3532}
3533
3534
3535static uint32_t
3536GetIndexForRecordBase
3537(
3538 const RecordDecl *record_decl,
3539 const CXXBaseSpecifier *base_spec,
3540 bool omit_empty_base_classes
3541)
3542{
3543 uint32_t child_idx = 0;
3544
3545 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3546
3547// const char *super_name = record_decl->getNameAsCString();
3548// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
3549// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
3550//
3551 if (cxx_record_decl)
3552 {
3553 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3554 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3555 base_class != base_class_end;
3556 ++base_class)
3557 {
3558 if (omit_empty_base_classes)
3559 {
3560 if (BaseSpecifierIsEmpty (base_class))
3561 continue;
3562 }
3563
3564// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
3565// child_idx,
3566// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
3567//
3568//
3569 if (base_class == base_spec)
3570 return child_idx;
3571 ++child_idx;
3572 }
3573 }
3574
3575 return UINT32_MAX;
3576}
3577
3578
3579static uint32_t
3580GetIndexForRecordChild
3581(
3582 const RecordDecl *record_decl,
3583 NamedDecl *canonical_decl,
3584 bool omit_empty_base_classes
3585)
3586{
3587 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
3588
3589// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3590//
3591//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
3592// if (cxx_record_decl)
3593// {
3594// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3595// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3596// base_class != base_class_end;
3597// ++base_class)
3598// {
3599// if (omit_empty_base_classes)
3600// {
3601// if (BaseSpecifierIsEmpty (base_class))
3602// continue;
3603// }
3604//
3605//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
3606//// record_decl->getNameAsCString(),
3607//// canonical_decl->getNameAsCString(),
3608//// child_idx,
3609//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
3610//
3611//
3612// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3613// if (curr_base_class_decl == canonical_decl)
3614// {
3615// return child_idx;
3616// }
3617// ++child_idx;
3618// }
3619// }
3620//
3621// const uint32_t num_bases = child_idx;
3622 RecordDecl::field_iterator field, field_end;
3623 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3624 field != field_end;
3625 ++field, ++child_idx)
3626 {
3627// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
3628// record_decl->getNameAsCString(),
3629// canonical_decl->getNameAsCString(),
3630// child_idx - num_bases,
3631// field->getNameAsCString());
3632
3633 if (field->getCanonicalDecl() == canonical_decl)
3634 return child_idx;
3635 }
3636
3637 return UINT32_MAX;
3638}
3639
3640// Look for a child member (doesn't include base classes, but it does include
3641// their members) in the type hierarchy. Returns an index path into "clang_type"
3642// on how to reach the appropriate member.
3643//
3644// class A
3645// {
3646// public:
3647// int m_a;
3648// int m_b;
3649// };
3650//
3651// class B
3652// {
3653// };
3654//
3655// class C :
3656// public B,
3657// public A
3658// {
3659// };
3660//
3661// If we have a clang type that describes "class C", and we wanted to looked
3662// "m_b" in it:
3663//
3664// With omit_empty_base_classes == false we would get an integer array back with:
3665// { 1, 1 }
3666// The first index 1 is the child index for "class A" within class C
3667// The second index 1 is the child index for "m_b" within class A
3668//
3669// With omit_empty_base_classes == true we would get an integer array back with:
3670// { 0, 1 }
3671// 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)
3672// The second index 1 is the child index for "m_b" within class A
3673
3674size_t
3675ClangASTContext::GetIndexOfChildMemberWithName
3676(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003677 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003678 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003679 const char *name,
3680 bool omit_empty_base_classes,
3681 std::vector<uint32_t>& child_indexes
3682)
3683{
3684 if (clang_type && name && name[0])
3685 {
3686 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003687 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3688 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003689 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003690 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003691 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003692 {
3693 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3694 const RecordDecl *record_decl = record_type->getDecl();
3695
3696 assert(record_decl);
3697 uint32_t child_idx = 0;
3698
3699 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3700
3701 // Try and find a field that matches NAME
3702 RecordDecl::field_iterator field, field_end;
3703 StringRef name_sref(name);
3704 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3705 field != field_end;
3706 ++field, ++child_idx)
3707 {
3708 if (field->getName().equals (name_sref))
3709 {
3710 // We have to add on the number of base classes to this index!
3711 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
3712 return child_indexes.size();
3713 }
3714 }
3715
3716 if (cxx_record_decl)
3717 {
3718 const RecordDecl *parent_record_decl = cxx_record_decl;
3719
3720 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
3721
3722 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
3723 // Didn't find things easily, lets let clang do its thang...
Sean Callanancc427fa2011-07-30 02:42:06 +00003724 IdentifierInfo & ident_ref = ast->Idents.get(name_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003725 DeclarationName decl_name(&ident_ref);
3726
3727 CXXBasePaths paths;
3728 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
3729 decl_name.getAsOpaquePtr(),
3730 paths))
3731 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003732 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
3733 for (path = paths.begin(); path != path_end; ++path)
3734 {
3735 const size_t num_path_elements = path->size();
3736 for (size_t e=0; e<num_path_elements; ++e)
3737 {
3738 CXXBasePathElement elem = (*path)[e];
3739
3740 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
3741 if (child_idx == UINT32_MAX)
3742 {
3743 child_indexes.clear();
3744 return 0;
3745 }
3746 else
3747 {
3748 child_indexes.push_back (child_idx);
3749 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
3750 }
3751 }
3752 DeclContext::lookup_iterator named_decl_pos;
3753 for (named_decl_pos = path->Decls.first;
3754 named_decl_pos != path->Decls.second && parent_record_decl;
3755 ++named_decl_pos)
3756 {
3757 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
3758
3759 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
3760 if (child_idx == UINT32_MAX)
3761 {
3762 child_indexes.clear();
3763 return 0;
3764 }
3765 else
3766 {
3767 child_indexes.push_back (child_idx);
3768 }
3769 }
3770 }
3771 return child_indexes.size();
3772 }
3773 }
3774
3775 }
3776 break;
3777
Greg Clayton9e409562010-07-28 02:04:09 +00003778 case clang::Type::ObjCObject:
3779 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003780 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003781 {
3782 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003783 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003784 assert (objc_class_type);
3785 if (objc_class_type)
3786 {
3787 uint32_t child_idx = 0;
3788 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3789
3790 if (class_interface_decl)
3791 {
3792 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3793 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3794
Greg Clayton6ba78152010-09-18 02:11:07 +00003795 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9e409562010-07-28 02:04:09 +00003796 {
3797 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3798
3799 if (ivar_decl->getName().equals (name_sref))
3800 {
3801 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3802 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3803 ++child_idx;
3804
3805 child_indexes.push_back (child_idx);
3806 return child_indexes.size();
3807 }
3808 }
3809
3810 if (superclass_interface_decl)
3811 {
3812 // The super class index is always zero for ObjC classes,
3813 // so we push it onto the child indexes in case we find
3814 // an ivar in our superclass...
3815 child_indexes.push_back (0);
3816
Greg Clayton6beaaa62011-01-17 03:46:26 +00003817 if (GetIndexOfChildMemberWithName (ast,
3818 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00003819 name,
3820 omit_empty_base_classes,
3821 child_indexes))
3822 {
3823 // We did find an ivar in a superclass so just
3824 // return the results!
3825 return child_indexes.size();
3826 }
3827
3828 // We didn't find an ivar matching "name" in our
3829 // superclass, pop the superclass zero index that
3830 // we pushed on above.
3831 child_indexes.pop_back();
3832 }
3833 }
3834 }
3835 }
3836 break;
3837
3838 case clang::Type::ObjCObjectPointer:
3839 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003840 return GetIndexOfChildMemberWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003841 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3842 name,
3843 omit_empty_base_classes,
3844 child_indexes);
3845 }
3846 break;
3847
3848
Greg Claytone1a916a2010-07-21 22:12:05 +00003849 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003850 {
3851// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3852// const uint64_t element_count = array->getSize().getLimitedValue();
3853//
3854// if (idx < element_count)
3855// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003856// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003857//
3858// char element_name[32];
3859// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3860//
3861// child_name.assign(element_name);
3862// assert(field_type_info.first % 8 == 0);
3863// child_byte_size = field_type_info.first / 8;
3864// child_byte_offset = idx * child_byte_size;
3865// return array->getElementType().getAsOpaquePtr();
3866// }
3867 }
3868 break;
3869
Greg Claytone1a916a2010-07-21 22:12:05 +00003870// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003871// {
3872// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3873// QualType pointee_type = mem_ptr_type->getPointeeType();
3874//
3875// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3876// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003877// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003878// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3879// name);
3880// }
3881// }
3882// break;
3883//
Greg Claytone1a916a2010-07-21 22:12:05 +00003884 case clang::Type::LValueReference:
3885 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003886 {
Sean Callanan78e37602011-01-27 04:42:51 +00003887 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003888 QualType pointee_type = reference_type->getPointeeType();
3889
3890 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3891 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003892 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003893 reference_type->getPointeeType().getAsOpaquePtr(),
3894 name,
3895 omit_empty_base_classes,
3896 child_indexes);
3897 }
3898 }
3899 break;
3900
Greg Claytone1a916a2010-07-21 22:12:05 +00003901 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003902 {
Sean Callanan78e37602011-01-27 04:42:51 +00003903 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003904 QualType pointee_type = pointer_type->getPointeeType();
3905
3906 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3907 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003908 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003909 pointer_type->getPointeeType().getAsOpaquePtr(),
3910 name,
3911 omit_empty_base_classes,
3912 child_indexes);
3913 }
3914 else
3915 {
3916// if (parent_name)
3917// {
3918// child_name.assign(1, '*');
3919// child_name += parent_name;
3920// }
3921//
3922// // We have a pointer to an simple type
3923// if (idx == 0)
3924// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003925// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003926// assert(clang_type_info.first % 8 == 0);
3927// child_byte_size = clang_type_info.first / 8;
3928// child_byte_offset = 0;
3929// return pointee_type.getAsOpaquePtr();
3930// }
3931 }
3932 }
3933 break;
3934
Greg Claytone1a916a2010-07-21 22:12:05 +00003935 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003936 return GetIndexOfChildMemberWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003937 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003938 name,
3939 omit_empty_base_classes,
3940 child_indexes);
3941
3942 default:
3943 break;
3944 }
3945 }
3946 return 0;
3947}
3948
3949
3950// Get the index of the child of "clang_type" whose name matches. This function
3951// doesn't descend into the children, but only looks one level deep and name
3952// matches can include base class names.
3953
3954uint32_t
3955ClangASTContext::GetIndexOfChildWithName
3956(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003957 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003958 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003959 const char *name,
3960 bool omit_empty_base_classes
3961)
3962{
3963 if (clang_type && name && name[0])
3964 {
3965 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00003966
Greg Clayton737b9322010-09-13 03:32:57 +00003967 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9e409562010-07-28 02:04:09 +00003968
Greg Clayton737b9322010-09-13 03:32:57 +00003969 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003970 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003971 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003972 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003973 {
3974 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3975 const RecordDecl *record_decl = record_type->getDecl();
3976
3977 assert(record_decl);
3978 uint32_t child_idx = 0;
3979
3980 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3981
3982 if (cxx_record_decl)
3983 {
3984 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3985 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3986 base_class != base_class_end;
3987 ++base_class)
3988 {
3989 // Skip empty base classes
3990 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3991 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3992 continue;
3993
Greg Claytone3055942011-06-30 02:28:26 +00003994 std::string base_class_type_name (ClangASTType::GetTypeNameForQualType(base_class->getType()));
3995 if (base_class_type_name.compare (name) == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003996 return child_idx;
3997 ++child_idx;
3998 }
3999 }
4000
4001 // Try and find a field that matches NAME
4002 RecordDecl::field_iterator field, field_end;
4003 StringRef name_sref(name);
4004 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
4005 field != field_end;
4006 ++field, ++child_idx)
4007 {
4008 if (field->getName().equals (name_sref))
4009 return child_idx;
4010 }
4011
4012 }
4013 break;
4014
Greg Clayton9e409562010-07-28 02:04:09 +00004015 case clang::Type::ObjCObject:
4016 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00004017 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00004018 {
4019 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00004020 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00004021 assert (objc_class_type);
4022 if (objc_class_type)
4023 {
4024 uint32_t child_idx = 0;
4025 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
4026
4027 if (class_interface_decl)
4028 {
4029 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
4030 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
4031
4032 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
4033 {
4034 const ObjCIvarDecl* ivar_decl = *ivar_pos;
4035
4036 if (ivar_decl->getName().equals (name_sref))
4037 {
4038 if ((!omit_empty_base_classes && superclass_interface_decl) ||
4039 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
4040 ++child_idx;
4041
4042 return child_idx;
4043 }
4044 }
4045
4046 if (superclass_interface_decl)
4047 {
4048 if (superclass_interface_decl->getName().equals (name_sref))
4049 return 0;
4050 }
4051 }
4052 }
4053 }
4054 break;
4055
4056 case clang::Type::ObjCObjectPointer:
4057 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004058 return GetIndexOfChildWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00004059 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
4060 name,
4061 omit_empty_base_classes);
4062 }
4063 break;
4064
Greg Claytone1a916a2010-07-21 22:12:05 +00004065 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004066 {
4067// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
4068// const uint64_t element_count = array->getSize().getLimitedValue();
4069//
4070// if (idx < element_count)
4071// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004072// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004073//
4074// char element_name[32];
4075// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
4076//
4077// child_name.assign(element_name);
4078// assert(field_type_info.first % 8 == 0);
4079// child_byte_size = field_type_info.first / 8;
4080// child_byte_offset = idx * child_byte_size;
4081// return array->getElementType().getAsOpaquePtr();
4082// }
4083 }
4084 break;
4085
Greg Claytone1a916a2010-07-21 22:12:05 +00004086// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004087// {
4088// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
4089// QualType pointee_type = mem_ptr_type->getPointeeType();
4090//
4091// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
4092// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004093// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004094// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
4095// name);
4096// }
4097// }
4098// break;
4099//
Greg Claytone1a916a2010-07-21 22:12:05 +00004100 case clang::Type::LValueReference:
4101 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004102 {
Sean Callanan78e37602011-01-27 04:42:51 +00004103 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004104 QualType pointee_type = reference_type->getPointeeType();
4105
4106 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
4107 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004108 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004109 reference_type->getPointeeType().getAsOpaquePtr(),
4110 name,
4111 omit_empty_base_classes);
4112 }
4113 }
4114 break;
4115
Greg Claytone1a916a2010-07-21 22:12:05 +00004116 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004117 {
Sean Callanan78e37602011-01-27 04:42:51 +00004118 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004119 QualType pointee_type = pointer_type->getPointeeType();
4120
4121 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
4122 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004123 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004124 pointer_type->getPointeeType().getAsOpaquePtr(),
4125 name,
4126 omit_empty_base_classes);
4127 }
4128 else
4129 {
4130// if (parent_name)
4131// {
4132// child_name.assign(1, '*');
4133// child_name += parent_name;
4134// }
4135//
4136// // We have a pointer to an simple type
4137// if (idx == 0)
4138// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004139// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004140// assert(clang_type_info.first % 8 == 0);
4141// child_byte_size = clang_type_info.first / 8;
4142// child_byte_offset = 0;
4143// return pointee_type.getAsOpaquePtr();
4144// }
4145 }
4146 }
4147 break;
4148
Greg Claytone1a916a2010-07-21 22:12:05 +00004149 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00004150 return GetIndexOfChildWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00004151 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004152 name,
4153 omit_empty_base_classes);
4154
4155 default:
4156 break;
4157 }
4158 }
4159 return UINT32_MAX;
4160}
4161
4162#pragma mark TagType
4163
4164bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004165ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004166{
4167 if (tag_clang_type)
4168 {
4169 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00004170 const clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004171 if (clang_type)
4172 {
Sean Callanan78e37602011-01-27 04:42:51 +00004173 const TagType *tag_type = dyn_cast<TagType>(clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004174 if (tag_type)
4175 {
4176 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
4177 if (tag_decl)
4178 {
4179 tag_decl->setTagKind ((TagDecl::TagKind)kind);
4180 return true;
4181 }
4182 }
4183 }
4184 }
4185 return false;
4186}
4187
4188
4189#pragma mark DeclContext Functions
4190
4191DeclContext *
Greg Clayton1be10fc2010-09-29 01:12:09 +00004192ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004193{
4194 if (clang_type == NULL)
4195 return NULL;
4196
4197 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004198 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4199 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004200 {
Sean Callanancc427fa2011-07-30 02:42:06 +00004201 case clang::Type::UnaryTransform: break;
Greg Clayton9e409562010-07-28 02:04:09 +00004202 case clang::Type::FunctionNoProto: break;
4203 case clang::Type::FunctionProto: break;
4204 case clang::Type::IncompleteArray: break;
4205 case clang::Type::VariableArray: break;
4206 case clang::Type::ConstantArray: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004207 case clang::Type::DependentSizedArray: break;
Greg Clayton9e409562010-07-28 02:04:09 +00004208 case clang::Type::ExtVector: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004209 case clang::Type::DependentSizedExtVector: break;
Greg Clayton9e409562010-07-28 02:04:09 +00004210 case clang::Type::Vector: break;
4211 case clang::Type::Builtin: break;
4212 case clang::Type::BlockPointer: break;
4213 case clang::Type::Pointer: break;
4214 case clang::Type::LValueReference: break;
4215 case clang::Type::RValueReference: break;
4216 case clang::Type::MemberPointer: break;
4217 case clang::Type::Complex: break;
4218 case clang::Type::ObjCObject: break;
4219 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
4220 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
4221 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
4222 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
Sean Callanan48114472010-12-13 01:26:27 +00004223 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00004224 case clang::Type::Elaborated: return ClangASTContext::GetDeclContextForType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00004225 case clang::Type::TypeOfExpr: break;
4226 case clang::Type::TypeOf: break;
4227 case clang::Type::Decltype: break;
4228 //case clang::Type::QualifiedName: break;
4229 case clang::Type::TemplateSpecialization: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004230 case clang::Type::DependentTemplateSpecialization: break;
4231 case clang::Type::TemplateTypeParm: break;
4232 case clang::Type::SubstTemplateTypeParm: break;
4233 case clang::Type::SubstTemplateTypeParmPack:break;
4234 case clang::Type::PackExpansion: break;
4235 case clang::Type::UnresolvedUsing: break;
4236 case clang::Type::Paren: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00004237 case clang::Type::Attributed: break;
4238 case clang::Type::Auto: break;
4239 case clang::Type::InjectedClassName: break;
4240 case clang::Type::DependentName: break;
Greg Claytonea3e7d52011-10-08 00:49:15 +00004241 case clang::Type::Atomic: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004242 }
4243 // No DeclContext in this type...
4244 return NULL;
4245}
4246
4247#pragma mark Namespace Declarations
4248
4249NamespaceDecl *
Greg Clayton030a2042011-10-14 21:34:45 +00004250ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004251{
Greg Clayton030a2042011-10-14 21:34:45 +00004252 NamespaceDecl *namespace_decl = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004253 if (name)
4254 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004255 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004256 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00004257 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton030a2042011-10-14 21:34:45 +00004258
4259 IdentifierInfo &identifier_info = ast->Idents.get(name);
4260 DeclarationName decl_name (&identifier_info);
4261 clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
4262 for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos)
4263 {
4264 namespace_decl = dyn_cast<clang::NamespaceDecl>(*pos);
4265 if (namespace_decl)
4266 return namespace_decl;
4267 }
4268
4269 namespace_decl = NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &identifier_info);
4270
4271 decl_ctx->addDecl (namespace_decl);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004272 }
Greg Clayton030a2042011-10-14 21:34:45 +00004273 return namespace_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004274}
4275
4276
4277#pragma mark Function Types
4278
4279FunctionDecl *
Greg Clayton147e1fa2011-10-14 22:47:18 +00004280ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004281{
Greg Clayton147e1fa2011-10-14 22:47:18 +00004282 FunctionDecl *func_decl = NULL;
4283 ASTContext *ast = getASTContext();
4284 if (decl_ctx == NULL)
4285 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004286
Greg Clayton147e1fa2011-10-14 22:47:18 +00004287 if (name && name[0])
4288 {
4289 func_decl = FunctionDecl::Create (*ast,
4290 decl_ctx,
4291 SourceLocation(),
4292 SourceLocation(),
4293 DeclarationName (&ast->Idents.get(name)),
4294 QualType::getFromOpaquePtr(function_clang_type),
4295 NULL,
4296 (FunctionDecl::StorageClass)storage,
4297 (FunctionDecl::StorageClass)storage,
4298 is_inline);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004299 }
Greg Clayton147e1fa2011-10-14 22:47:18 +00004300 else
4301 {
4302 func_decl = FunctionDecl::Create (*ast,
4303 decl_ctx,
4304 SourceLocation(),
4305 SourceLocation(),
4306 DeclarationName (),
4307 QualType::getFromOpaquePtr(function_clang_type),
4308 NULL,
4309 (FunctionDecl::StorageClass)storage,
4310 (FunctionDecl::StorageClass)storage,
4311 is_inline);
4312 }
4313 if (func_decl)
4314 decl_ctx->addDecl (func_decl);
4315 return func_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004316}
4317
Greg Clayton1be10fc2010-09-29 01:12:09 +00004318clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00004319ClangASTContext::CreateFunctionType (ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00004320 clang_type_t result_type,
4321 clang_type_t *args,
Sean Callananc81256a2010-09-16 20:40:25 +00004322 unsigned num_args,
4323 bool is_variadic,
4324 unsigned type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004325{
Greg Clayton6beaaa62011-01-17 03:46:26 +00004326 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004327 std::vector<QualType> qual_type_args;
4328 for (unsigned i=0; i<num_args; ++i)
4329 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
4330
4331 // TODO: Detect calling convention in DWARF?
Sean Callanan2c777c42011-01-18 23:32:05 +00004332 FunctionProtoType::ExtProtoInfo proto_info;
4333 proto_info.Variadic = is_variadic;
Sean Callananfb0b7582011-03-15 00:17:19 +00004334 proto_info.ExceptionSpecType = EST_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00004335 proto_info.TypeQuals = type_quals;
Sean Callananfb0b7582011-03-15 00:17:19 +00004336 proto_info.RefQualifier = RQ_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00004337 proto_info.NumExceptions = 0;
4338 proto_info.Exceptions = NULL;
4339
Greg Clayton147e1fa2011-10-14 22:47:18 +00004340 return ast->getFunctionType (QualType::getFromOpaquePtr(result_type),
4341 qual_type_args.empty() ? NULL : &qual_type_args.front(),
4342 qual_type_args.size(),
4343 proto_info).getAsOpaquePtr(); // NoReturn);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004344}
4345
4346ParmVarDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00004347ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004348{
Greg Clayton6beaaa62011-01-17 03:46:26 +00004349 ASTContext *ast = getASTContext();
4350 assert (ast != NULL);
4351 return ParmVarDecl::Create(*ast,
4352 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004353 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004354 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00004355 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callananc81256a2010-09-16 20:40:25 +00004356 QualType::getFromOpaquePtr(param_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004357 NULL,
4358 (VarDecl::StorageClass)storage,
4359 (VarDecl::StorageClass)storage,
4360 0);
4361}
4362
4363void
4364ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
4365{
4366 if (function_decl)
Sean Callanan880e6802011-10-07 23:18:13 +00004367 function_decl->setParams (ArrayRef<ParmVarDecl*>(params, num_params));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004368}
4369
4370
4371#pragma mark Array Types
4372
Greg Clayton1be10fc2010-09-29 01:12:09 +00004373clang_type_t
4374ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004375{
4376 if (element_type)
4377 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00004378 ASTContext *ast = getASTContext();
4379 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004380 llvm::APInt ap_element_count (64, element_count);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004381 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004382 ap_element_count,
4383 ArrayType::Normal,
4384 0).getAsOpaquePtr(); // ElemQuals
4385 }
4386 return NULL;
4387}
4388
4389
4390#pragma mark TagDecl
4391
4392bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004393ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004394{
4395 if (clang_type)
4396 {
4397 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00004398 const clang::Type *t = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004399 if (t)
4400 {
Sean Callanan78e37602011-01-27 04:42:51 +00004401 const TagType *tag_type = dyn_cast<TagType>(t);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004402 if (tag_type)
4403 {
4404 TagDecl *tag_decl = tag_type->getDecl();
4405 if (tag_decl)
4406 {
4407 tag_decl->startDefinition();
4408 return true;
4409 }
4410 }
4411 }
4412 }
4413 return false;
4414}
4415
4416bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004417ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004418{
4419 if (clang_type)
4420 {
4421 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton14372242010-09-29 03:44:17 +00004422
4423 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4424
4425 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004426 {
Greg Clayton14372242010-09-29 03:44:17 +00004427 cxx_record_decl->completeDefinition();
4428
4429 return true;
4430 }
4431
Sean Callanan78e37602011-01-27 04:42:51 +00004432 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
Sean Callanana2424172010-10-25 00:29:48 +00004433
4434 if (objc_class_type)
4435 {
4436 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
4437
4438 class_interface_decl->setForwardDecl(false);
4439 }
4440
Greg Clayton14372242010-09-29 03:44:17 +00004441 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
4442
4443 if (enum_type)
4444 {
4445 EnumDecl *enum_decl = enum_type->getDecl();
4446
4447 if (enum_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004448 {
Greg Clayton14372242010-09-29 03:44:17 +00004449 /// TODO This really needs to be fixed.
4450
4451 unsigned NumPositiveBits = 1;
4452 unsigned NumNegativeBits = 0;
4453
Greg Clayton6beaaa62011-01-17 03:46:26 +00004454 ASTContext *ast = getASTContext();
Greg Claytone02b8502010-10-12 04:29:14 +00004455
4456 QualType promotion_qual_type;
4457 // If the enum integer type is less than an integer in bit width,
4458 // then we must promote it to an integer size.
Greg Clayton6beaaa62011-01-17 03:46:26 +00004459 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
Greg Claytone02b8502010-10-12 04:29:14 +00004460 {
4461 if (enum_decl->getIntegerType()->isSignedIntegerType())
Greg Clayton6beaaa62011-01-17 03:46:26 +00004462 promotion_qual_type = ast->IntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00004463 else
Greg Clayton6beaaa62011-01-17 03:46:26 +00004464 promotion_qual_type = ast->UnsignedIntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00004465 }
4466 else
4467 promotion_qual_type = enum_decl->getIntegerType();
4468
4469 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton14372242010-09-29 03:44:17 +00004470 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004471 }
4472 }
4473 }
4474 return false;
4475}
4476
4477
4478#pragma mark Enumeration Types
4479
Greg Clayton1be10fc2010-09-29 01:12:09 +00004480clang_type_t
Greg Claytonca512b32011-01-14 04:54:56 +00004481ClangASTContext::CreateEnumerationType
4482(
4483 const char *name,
4484 DeclContext *decl_ctx,
4485 const Declaration &decl,
4486 clang_type_t integer_qual_type
4487)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004488{
4489 // TODO: Do something intelligent with the Declaration object passed in
4490 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00004491 ASTContext *ast = getASTContext();
4492 assert (ast != NULL);
Greg Claytone02b8502010-10-12 04:29:14 +00004493
4494 // TODO: ask about these...
4495// const bool IsScoped = false;
4496// const bool IsFixed = false;
4497
Greg Clayton6beaaa62011-01-17 03:46:26 +00004498 EnumDecl *enum_decl = EnumDecl::Create (*ast,
Greg Claytonca512b32011-01-14 04:54:56 +00004499 decl_ctx,
Greg Claytone02b8502010-10-12 04:29:14 +00004500 SourceLocation(),
Greg Claytone02b8502010-10-12 04:29:14 +00004501 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004502 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callanan48114472010-12-13 01:26:27 +00004503 NULL,
4504 false, // IsScoped
4505 false, // IsScopedUsingClassTag
4506 false); // IsFixed
Sean Callanan2652ad22011-01-18 01:03:44 +00004507
4508
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004509 if (enum_decl)
Greg Clayton83ff3892010-09-12 23:17:56 +00004510 {
4511 // TODO: check if we should be setting the promotion type too?
4512 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00004513
4514 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
4515
Greg Clayton6beaaa62011-01-17 03:46:26 +00004516 return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Clayton83ff3892010-09-12 23:17:56 +00004517 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004518 return NULL;
4519}
4520
Greg Clayton1be10fc2010-09-29 01:12:09 +00004521clang_type_t
4522ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
4523{
4524 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
4525
Sean Callanan78e37602011-01-27 04:42:51 +00004526 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Greg Clayton1be10fc2010-09-29 01:12:09 +00004527 if (clang_type)
4528 {
4529 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
4530 if (enum_type)
4531 {
4532 EnumDecl *enum_decl = enum_type->getDecl();
4533 if (enum_decl)
4534 return enum_decl->getIntegerType().getAsOpaquePtr();
4535 }
4536 }
4537 return NULL;
4538}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004539bool
4540ClangASTContext::AddEnumerationValueToEnumerationType
4541(
Greg Clayton1be10fc2010-09-29 01:12:09 +00004542 clang_type_t enum_clang_type,
4543 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004544 const Declaration &decl,
4545 const char *name,
4546 int64_t enum_value,
4547 uint32_t enum_value_bit_size
4548)
4549{
4550 if (enum_clang_type && enumerator_clang_type && name)
4551 {
4552 // TODO: Do something intelligent with the Declaration object passed in
4553 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00004554 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004555 IdentifierTable *identifier_table = getIdentifierTable();
4556
Greg Clayton6beaaa62011-01-17 03:46:26 +00004557 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004558 assert (identifier_table != NULL);
4559 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
4560
Sean Callanan78e37602011-01-27 04:42:51 +00004561 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004562 if (clang_type)
4563 {
4564 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
4565
4566 if (enum_type)
4567 {
4568 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
4569 enum_llvm_apsint = enum_value;
4570 EnumConstantDecl *enumerator_decl =
Greg Clayton6beaaa62011-01-17 03:46:26 +00004571 EnumConstantDecl::Create (*ast,
4572 enum_type->getDecl(),
4573 SourceLocation(),
4574 name ? &identifier_table->get(name) : NULL, // Identifier
4575 QualType::getFromOpaquePtr(enumerator_clang_type),
4576 NULL,
4577 enum_llvm_apsint);
4578
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004579 if (enumerator_decl)
4580 {
4581 enum_type->getDecl()->addDecl(enumerator_decl);
4582 return true;
4583 }
4584 }
4585 }
4586 }
4587 return false;
4588}
4589
4590#pragma mark Pointers & References
4591
Greg Clayton1be10fc2010-09-29 01:12:09 +00004592clang_type_t
4593ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004594{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00004595 return CreatePointerType (getASTContext(), clang_type);
4596}
4597
4598clang_type_t
4599ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
4600{
4601 if (ast && clang_type)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004602 {
4603 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4604
Greg Clayton737b9322010-09-13 03:32:57 +00004605 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4606 switch (type_class)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004607 {
4608 case clang::Type::ObjCObject:
4609 case clang::Type::ObjCInterface:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00004610 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004611
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004612 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00004613 return ast->getPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00004614 }
4615 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004616 return NULL;
4617}
4618
Greg Clayton1be10fc2010-09-29 01:12:09 +00004619clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00004620ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
4621 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004622{
4623 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00004624 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004625 return NULL;
4626}
4627
Greg Clayton1be10fc2010-09-29 01:12:09 +00004628clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00004629ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
4630 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004631{
4632 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00004633 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004634 return NULL;
4635}
4636
Greg Clayton1be10fc2010-09-29 01:12:09 +00004637clang_type_t
4638ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Clayton9b81a312010-06-12 01:20:30 +00004639{
4640 if (clang_pointee_type && clang_pointee_type)
4641 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
4642 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
4643 return NULL;
4644}
4645
Greg Clayton1a65ae12011-01-25 23:55:37 +00004646uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004647ClangASTContext::GetPointerBitSize ()
4648{
Greg Clayton6beaaa62011-01-17 03:46:26 +00004649 ASTContext *ast = getASTContext();
4650 return ast->getTypeSize(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004651}
4652
4653bool
Greg Claytondea8cb42011-06-29 22:09:02 +00004654ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
4655{
4656 QualType pointee_qual_type;
4657 if (clang_type)
4658 {
4659 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4660 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4661 bool success = false;
4662 switch (type_class)
4663 {
4664 case clang::Type::Builtin:
4665 if (cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
4666 {
4667 if (dynamic_pointee_type)
4668 *dynamic_pointee_type = clang_type;
4669 return true;
4670 }
4671 break;
4672
4673 case clang::Type::ObjCObjectPointer:
4674 if (dynamic_pointee_type)
4675 *dynamic_pointee_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4676 return true;
4677
4678 case clang::Type::Pointer:
4679 pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
4680 success = true;
4681 break;
4682
4683 case clang::Type::LValueReference:
4684 case clang::Type::RValueReference:
4685 pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
4686 success = true;
4687 break;
4688
4689 case clang::Type::Typedef:
Greg Claytonaffb03b2011-07-08 18:27:39 +00004690 return ClangASTContext::IsPossibleDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
Sean Callanan912855f2011-08-11 23:56:13 +00004691
4692 case clang::Type::Elaborated:
4693 return ClangASTContext::IsPossibleDynamicType (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), dynamic_pointee_type);
4694
Greg Claytondea8cb42011-06-29 22:09:02 +00004695 default:
4696 break;
4697 }
4698
4699 if (success)
4700 {
4701 // Check to make sure what we are pointing too is a possible dynamic C++ type
4702 // We currently accept any "void *" (in case we have a class that has been
4703 // watered down to an opaque pointer) and virtual C++ classes.
4704 const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
4705 switch (pointee_type_class)
4706 {
4707 case clang::Type::Builtin:
4708 switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
4709 {
4710 case clang::BuiltinType::UnknownAny:
4711 case clang::BuiltinType::Void:
4712 if (dynamic_pointee_type)
4713 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4714 return true;
4715
4716 case clang::BuiltinType::NullPtr:
4717 case clang::BuiltinType::Bool:
4718 case clang::BuiltinType::Char_U:
4719 case clang::BuiltinType::UChar:
4720 case clang::BuiltinType::WChar_U:
4721 case clang::BuiltinType::Char16:
4722 case clang::BuiltinType::Char32:
4723 case clang::BuiltinType::UShort:
4724 case clang::BuiltinType::UInt:
4725 case clang::BuiltinType::ULong:
4726 case clang::BuiltinType::ULongLong:
4727 case clang::BuiltinType::UInt128:
4728 case clang::BuiltinType::Char_S:
4729 case clang::BuiltinType::SChar:
4730 case clang::BuiltinType::WChar_S:
4731 case clang::BuiltinType::Short:
4732 case clang::BuiltinType::Int:
4733 case clang::BuiltinType::Long:
4734 case clang::BuiltinType::LongLong:
4735 case clang::BuiltinType::Int128:
4736 case clang::BuiltinType::Float:
4737 case clang::BuiltinType::Double:
4738 case clang::BuiltinType::LongDouble:
4739 case clang::BuiltinType::Dependent:
4740 case clang::BuiltinType::Overload:
4741 case clang::BuiltinType::ObjCId:
4742 case clang::BuiltinType::ObjCClass:
4743 case clang::BuiltinType::ObjCSel:
4744 case clang::BuiltinType::BoundMember:
Greg Claytonf0705c82011-10-22 03:33:13 +00004745 case clang::BuiltinType::Half:
4746 case clang::BuiltinType::ARCUnbridgedCast:
Greg Claytondea8cb42011-06-29 22:09:02 +00004747 break;
4748 }
4749 break;
4750
4751 case clang::Type::Record:
4752 {
4753 CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
4754 if (cxx_record_decl)
4755 {
4756 if (GetCompleteQualType (ast, pointee_qual_type))
4757 {
4758 success = cxx_record_decl->isDynamicClass();
4759 }
4760 else
4761 {
4762 // We failed to get the complete type, so we have to
4763 // treat this as a void * which we might possibly be
4764 // able to complete
4765 success = true;
4766 }
4767 if (success)
4768 {
4769 if (dynamic_pointee_type)
4770 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4771 return true;
4772 }
4773 }
4774 }
4775 break;
4776
4777 case clang::Type::ObjCObject:
4778 case clang::Type::ObjCInterface:
4779 {
4780 const clang::ObjCObjectType *objc_class_type = pointee_qual_type->getAsObjCQualifiedInterfaceType();
4781 if (objc_class_type)
4782 {
4783 GetCompleteQualType (ast, pointee_qual_type);
4784 if (dynamic_pointee_type)
4785 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4786 return true;
4787 }
4788 }
4789 break;
4790
4791 default:
4792 break;
4793 }
4794 }
4795 }
4796 if (dynamic_pointee_type)
4797 *dynamic_pointee_type = NULL;
4798 return false;
4799}
4800
4801
4802bool
Greg Clayton007d5be2011-05-30 00:49:24 +00004803ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
4804{
4805 QualType pointee_qual_type;
4806 if (clang_type)
4807 {
4808 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4809 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4810 bool success = false;
4811 switch (type_class)
4812 {
4813 case clang::Type::Pointer:
4814 pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
4815 success = true;
4816 break;
4817
4818 case clang::Type::LValueReference:
4819 case clang::Type::RValueReference:
4820 pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
4821 success = true;
4822 break;
4823
4824 case clang::Type::Typedef:
4825 return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
4826
Sean Callanan912855f2011-08-11 23:56:13 +00004827 case clang::Type::Elaborated:
4828 return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
4829
Greg Clayton007d5be2011-05-30 00:49:24 +00004830 default:
4831 break;
4832 }
4833
4834 if (success)
4835 {
4836 // Check to make sure what we are pointing too is a possible dynamic C++ type
4837 // We currently accept any "void *" (in case we have a class that has been
4838 // watered down to an opaque pointer) and virtual C++ classes.
4839 const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
4840 switch (pointee_type_class)
4841 {
4842 case clang::Type::Builtin:
4843 switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
4844 {
4845 case clang::BuiltinType::UnknownAny:
4846 case clang::BuiltinType::Void:
4847 if (dynamic_pointee_type)
4848 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4849 return true;
4850
4851 case clang::BuiltinType::NullPtr:
4852 case clang::BuiltinType::Bool:
4853 case clang::BuiltinType::Char_U:
4854 case clang::BuiltinType::UChar:
4855 case clang::BuiltinType::WChar_U:
4856 case clang::BuiltinType::Char16:
4857 case clang::BuiltinType::Char32:
4858 case clang::BuiltinType::UShort:
4859 case clang::BuiltinType::UInt:
4860 case clang::BuiltinType::ULong:
4861 case clang::BuiltinType::ULongLong:
4862 case clang::BuiltinType::UInt128:
4863 case clang::BuiltinType::Char_S:
4864 case clang::BuiltinType::SChar:
4865 case clang::BuiltinType::WChar_S:
4866 case clang::BuiltinType::Short:
4867 case clang::BuiltinType::Int:
4868 case clang::BuiltinType::Long:
4869 case clang::BuiltinType::LongLong:
4870 case clang::BuiltinType::Int128:
4871 case clang::BuiltinType::Float:
4872 case clang::BuiltinType::Double:
4873 case clang::BuiltinType::LongDouble:
4874 case clang::BuiltinType::Dependent:
4875 case clang::BuiltinType::Overload:
4876 case clang::BuiltinType::ObjCId:
4877 case clang::BuiltinType::ObjCClass:
4878 case clang::BuiltinType::ObjCSel:
4879 case clang::BuiltinType::BoundMember:
Greg Claytonf0705c82011-10-22 03:33:13 +00004880 case clang::BuiltinType::Half:
4881 case clang::BuiltinType::ARCUnbridgedCast:
Greg Clayton007d5be2011-05-30 00:49:24 +00004882 break;
4883 }
4884 break;
4885 case clang::Type::Record:
4886 {
4887 CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
4888 if (cxx_record_decl)
4889 {
4890 if (GetCompleteQualType (ast, pointee_qual_type))
4891 {
Greg Claytona13ad2ad2011-06-02 01:26:44 +00004892 success = cxx_record_decl->isDynamicClass();
Greg Clayton007d5be2011-05-30 00:49:24 +00004893 }
4894 else
4895 {
4896 // We failed to get the complete type, so we have to
4897 // treat this as a void * which we might possibly be
4898 // able to complete
4899 success = true;
4900 }
4901 if (success)
4902 {
4903 if (dynamic_pointee_type)
4904 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4905 return true;
4906 }
4907 }
4908 }
4909 break;
4910
4911 default:
4912 break;
4913 }
4914 }
4915 }
4916 if (dynamic_pointee_type)
4917 *dynamic_pointee_type = NULL;
4918 return false;
4919}
4920
4921
4922bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004923ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004924{
4925 if (clang_type == NULL)
4926 return false;
4927
4928 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004929 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4930 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004931 {
Sean Callanana2424172010-10-25 00:29:48 +00004932 case clang::Type::Builtin:
4933 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4934 {
4935 default:
4936 break;
4937 case clang::BuiltinType::ObjCId:
4938 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004939 return true;
4940 }
4941 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004942 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004943 if (target_type)
4944 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4945 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004946 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004947 if (target_type)
4948 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4949 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004950 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004951 if (target_type)
4952 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4953 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004954 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004955 if (target_type)
4956 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4957 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004958 case clang::Type::LValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004959 if (target_type)
4960 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4961 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004962 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004963 if (target_type)
4964 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4965 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004966 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004967 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00004968 case clang::Type::Elaborated:
4969 return ClangASTContext::IsPointerOrReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004970 default:
4971 break;
4972 }
4973 return false;
4974}
4975
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004976bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004977ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004978{
4979 if (!clang_type)
4980 return false;
4981
4982 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4983 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
4984
4985 if (builtin_type)
4986 {
4987 if (builtin_type->isInteger())
4988 is_signed = builtin_type->isSignedInteger();
4989
4990 return true;
4991 }
4992
4993 return false;
4994}
4995
4996bool
Greg Claytonaffb03b2011-07-08 18:27:39 +00004997ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t *target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004998{
Greg Claytonaffb03b2011-07-08 18:27:39 +00004999 if (target_type)
5000 *target_type = NULL;
5001
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005002 if (clang_type)
5003 {
5004 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00005005 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5006 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005007 {
Sean Callanana2424172010-10-25 00:29:48 +00005008 case clang::Type::Builtin:
5009 switch (cast<clang::BuiltinType>(qual_type)->getKind())
5010 {
5011 default:
5012 break;
5013 case clang::BuiltinType::ObjCId:
5014 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00005015 return true;
5016 }
5017 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00005018 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005019 if (target_type)
5020 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
5021 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00005022 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005023 if (target_type)
5024 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
5025 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00005026 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005027 if (target_type)
5028 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
5029 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00005030 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005031 if (target_type)
5032 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
5033 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00005034 case clang::Type::Typedef:
Greg Claytonaffb03b2011-07-08 18:27:39 +00005035 return ClangASTContext::IsPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Sean Callanan912855f2011-08-11 23:56:13 +00005036 case clang::Type::Elaborated:
5037 return ClangASTContext::IsPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), target_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005038 default:
5039 break;
5040 }
5041 }
5042 return false;
5043}
5044
5045bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005046ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005047{
5048 if (clang_type)
5049 {
5050 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5051
5052 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
5053 {
5054 clang::BuiltinType::Kind kind = BT->getKind();
5055 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
5056 {
5057 count = 1;
5058 is_complex = false;
5059 return true;
5060 }
5061 }
5062 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
5063 {
5064 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
5065 {
5066 count = 2;
5067 is_complex = true;
5068 return true;
5069 }
5070 }
5071 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
5072 {
5073 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
5074 {
5075 count = VT->getNumElements();
5076 is_complex = false;
5077 return true;
5078 }
5079 }
5080 }
5081 return false;
5082}
5083
Enrico Granata9fc19442011-07-06 02:13:41 +00005084bool
5085ClangASTContext::IsScalarType (lldb::clang_type_t clang_type)
5086{
5087 bool is_signed;
5088 if (ClangASTContext::IsIntegerType(clang_type, is_signed))
5089 return true;
5090
5091 uint32_t count;
5092 bool is_complex;
5093 return ClangASTContext::IsFloatingPointType(clang_type, count, is_complex) && !is_complex;
5094}
5095
5096bool
5097ClangASTContext::IsPointerToScalarType (lldb::clang_type_t clang_type)
5098{
5099 if (!IsPointerType(clang_type))
5100 return false;
5101
5102 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5103 lldb::clang_type_t pointee_type = qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
5104 return IsScalarType(pointee_type);
5105}
5106
5107bool
5108ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type)
5109{
5110 if (!IsArrayType(clang_type))
5111 return false;
5112
5113 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5114 lldb::clang_type_t item_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
5115 return IsScalarType(item_type);
5116}
5117
Greg Clayton8f92f0a2010-10-14 22:52:14 +00005118
5119bool
5120ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
5121{
5122 if (clang_type)
5123 {
5124 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5125
5126 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
5127 if (cxx_record_decl)
5128 {
5129 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
5130 return true;
5131 }
5132 }
5133 class_name.clear();
5134 return false;
5135}
5136
5137
Greg Clayton0fffff52010-09-24 05:15:53 +00005138bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005139ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00005140{
5141 if (clang_type)
5142 {
5143 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5144 if (qual_type->getAsCXXRecordDecl() != NULL)
5145 return true;
5146 }
5147 return false;
5148}
5149
Greg Clayton20568dd2011-10-13 23:13:20 +00005150bool
5151ClangASTContext::IsBeingDefined (lldb::clang_type_t clang_type)
5152{
5153 if (clang_type)
5154 {
5155 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5156 const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type);
5157 if (tag_type)
5158 return tag_type->isBeingDefined();
5159 }
5160 return false;
5161}
5162
Greg Clayton0fffff52010-09-24 05:15:53 +00005163bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005164ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00005165{
5166 if (clang_type)
5167 {
5168 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5169 if (qual_type->isObjCObjectOrInterfaceType())
5170 return true;
5171 }
5172 return false;
5173}
5174
5175
Greg Clayton73b472d2010-10-27 03:32:59 +00005176bool
5177ClangASTContext::IsCharType (clang_type_t clang_type)
5178{
5179 if (clang_type)
5180 return QualType::getFromOpaquePtr(clang_type)->isCharType();
5181 return false;
5182}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005183
5184bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005185ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005186{
Greg Clayton73b472d2010-10-27 03:32:59 +00005187 clang_type_t pointee_or_element_clang_type = NULL;
5188 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
5189
5190 if (pointee_or_element_clang_type == NULL)
5191 return false;
5192
5193 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005194 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005195 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
5196
5197 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005198 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005199 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5200 if (type_flags.Test (eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005201 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005202 // We know the size of the array and it could be a C string
5203 // since it is an array of characters
5204 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
5205 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005206 }
Greg Clayton73b472d2010-10-27 03:32:59 +00005207 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005208 {
Greg Clayton73b472d2010-10-27 03:32:59 +00005209 length = 0;
5210 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005211 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005212
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005213 }
5214 }
5215 return false;
5216}
5217
5218bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005219ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton737b9322010-09-13 03:32:57 +00005220{
5221 if (clang_type)
5222 {
5223 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5224
5225 if (qual_type->isFunctionPointerType())
5226 return true;
5227
5228 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5229 switch (type_class)
5230 {
Sean Callananfb0b7582011-03-15 00:17:19 +00005231 default:
5232 break;
Greg Clayton737b9322010-09-13 03:32:57 +00005233 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00005234 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00005235 case clang::Type::Elaborated:
5236 return ClangASTContext::IsFunctionPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00005237
5238 case clang::Type::LValueReference:
5239 case clang::Type::RValueReference:
5240 {
Sean Callanan78e37602011-01-27 04:42:51 +00005241 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00005242 if (reference_type)
5243 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
5244 }
5245 break;
5246 }
5247 }
5248 return false;
5249}
5250
Greg Clayton73b472d2010-10-27 03:32:59 +00005251size_t
5252ClangASTContext::GetArraySize (clang_type_t clang_type)
5253{
5254 if (clang_type)
5255 {
Greg Claytonef37d68a2011-07-09 17:12:27 +00005256 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
5257 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5258 switch (type_class)
5259 {
5260 case clang::Type::ConstantArray:
5261 {
5262 const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
5263 if (array)
5264 return array->getSize().getLimitedValue();
5265 }
5266 break;
5267
5268 case clang::Type::Typedef:
5269 return ClangASTContext::GetArraySize(cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Sean Callanan912855f2011-08-11 23:56:13 +00005270
5271 case clang::Type::Elaborated:
5272 return ClangASTContext::GetArraySize(cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
Enrico Granataf9fa6ee2011-07-12 00:18:11 +00005273
5274 default:
5275 break;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005276 }
Greg Clayton73b472d2010-10-27 03:32:59 +00005277 }
5278 return 0;
5279}
Greg Clayton737b9322010-09-13 03:32:57 +00005280
5281bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00005282ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005283{
5284 if (!clang_type)
5285 return false;
5286
5287 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5288
Greg Clayton737b9322010-09-13 03:32:57 +00005289 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5290 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005291 {
Sean Callananfb0b7582011-03-15 00:17:19 +00005292 default:
5293 break;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005294
Greg Claytone1a916a2010-07-21 22:12:05 +00005295 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005296 if (member_type)
5297 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5298 if (size)
Greg Claytonac4827f2011-04-01 18:14:08 +00005299 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005300 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005301
Greg Claytone1a916a2010-07-21 22:12:05 +00005302 case clang::Type::IncompleteArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005303 if (member_type)
5304 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5305 if (size)
5306 *size = 0;
5307 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005308
Greg Claytone1a916a2010-07-21 22:12:05 +00005309 case clang::Type::VariableArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005310 if (member_type)
5311 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5312 if (size)
5313 *size = 0;
Greg Clayton03dbf2e2011-02-02 00:52:14 +00005314 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005315
Greg Claytone1a916a2010-07-21 22:12:05 +00005316 case clang::Type::DependentSizedArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005317 if (member_type)
5318 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5319 if (size)
5320 *size = 0;
5321 return true;
Greg Claytonef37d68a2011-07-09 17:12:27 +00005322
5323 case clang::Type::Typedef:
5324 return ClangASTContext::IsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
5325 member_type,
5326 size);
Sean Callanan912855f2011-08-11 23:56:13 +00005327
5328 case clang::Type::Elaborated:
5329 return ClangASTContext::IsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
5330 member_type,
5331 size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005332 }
5333 return false;
5334}
5335
5336
5337#pragma mark Typedefs
5338
Greg Clayton1be10fc2010-09-29 01:12:09 +00005339clang_type_t
5340ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005341{
5342 if (clang_type)
5343 {
5344 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00005345 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005346 IdentifierTable *identifier_table = getIdentifierTable();
Greg Clayton6beaaa62011-01-17 03:46:26 +00005347 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005348 assert (identifier_table != NULL);
5349 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00005350 decl_ctx = ast->getTranslationUnitDecl();
5351 TypedefDecl *decl = TypedefDecl::Create (*ast,
5352 decl_ctx,
5353 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00005354 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00005355 name ? &identifier_table->get(name) : NULL, // Identifier
5356 ast->CreateTypeSourceInfo(qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00005357
Greg Clayton147e1fa2011-10-14 22:47:18 +00005358 //decl_ctx->addDecl (decl);
5359
Sean Callanan2652ad22011-01-18 01:03:44 +00005360 decl->setAccess(AS_public); // TODO respect proper access specifier
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005361
5362 // Get a uniqued QualType for the typedef decl type
Greg Clayton6beaaa62011-01-17 03:46:26 +00005363 return ast->getTypedefType (decl).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005364 }
5365 return NULL;
5366}
5367
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005368// Disable this for now since I can't seem to get a nicely formatted float
5369// out of the APFloat class without just getting the float, double or quad
5370// and then using a formatted print on it which defeats the purpose. We ideally
5371// would like to get perfect string values for any kind of float semantics
5372// so we can support remote targets. The code below also requires a patch to
5373// llvm::APInt.
5374//bool
Greg Clayton6beaaa62011-01-17 03:46:26 +00005375//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 +00005376//{
5377// uint32_t count = 0;
5378// bool is_complex = false;
5379// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
5380// {
5381// unsigned num_bytes_per_float = byte_size / count;
5382// unsigned num_bits_per_float = num_bytes_per_float * 8;
5383//
5384// float_str.clear();
5385// uint32_t i;
5386// for (i=0; i<count; i++)
5387// {
5388// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
5389// bool is_ieee = false;
5390// APFloat ap_float(ap_int, is_ieee);
5391// char s[1024];
5392// unsigned int hex_digits = 0;
5393// bool upper_case = false;
5394//
5395// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
5396// {
5397// if (i > 0)
5398// float_str.append(", ");
5399// float_str.append(s);
5400// if (i == 1 && is_complex)
5401// float_str.append(1, 'i');
5402// }
5403// }
5404// return !float_str.empty();
5405// }
5406// return false;
5407//}
5408
5409size_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00005410ClangASTContext::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 +00005411{
5412 if (clang_type)
5413 {
5414 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5415 uint32_t count = 0;
5416 bool is_complex = false;
5417 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
5418 {
5419 // TODO: handle complex and vector types
5420 if (count != 1)
5421 return false;
5422
5423 StringRef s_sref(s);
Greg Clayton6beaaa62011-01-17 03:46:26 +00005424 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005425
Greg Clayton6beaaa62011-01-17 03:46:26 +00005426 const uint64_t bit_size = ast->getTypeSize (qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005427 const uint64_t byte_size = bit_size / 8;
5428 if (dst_size >= byte_size)
5429 {
5430 if (bit_size == sizeof(float)*8)
5431 {
5432 float float32 = ap_float.convertToFloat();
5433 ::memcpy (dst, &float32, byte_size);
5434 return byte_size;
5435 }
5436 else if (bit_size >= 64)
5437 {
5438 llvm::APInt ap_int(ap_float.bitcastToAPInt());
5439 ::memcpy (dst, ap_int.getRawData(), byte_size);
5440 return byte_size;
5441 }
5442 }
5443 }
5444 }
5445 return 0;
5446}
Sean Callanan6fe64b52010-09-17 02:24:29 +00005447
5448unsigned
Greg Clayton1be10fc2010-09-29 01:12:09 +00005449ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanan6fe64b52010-09-17 02:24:29 +00005450{
5451 assert (clang_type);
5452
5453 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5454
5455 return qual_type.getQualifiers().getCVRQualifiers();
5456}
Greg Clayton6beaaa62011-01-17 03:46:26 +00005457
5458bool
5459ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
5460{
5461 if (clang_type == NULL)
5462 return false;
5463
Greg Claytonc432c192011-01-20 04:18:48 +00005464 return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00005465}
5466
5467
5468bool
5469ClangASTContext::GetCompleteType (clang_type_t clang_type)
5470{
5471 return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
5472}
5473
Greg Claytona2721472011-06-25 00:44:06 +00005474bool
5475ClangASTContext::GetCompleteDecl (clang::ASTContext *ast,
5476 clang::Decl *decl)
5477{
5478 if (!decl)
5479 return false;
5480
5481 ExternalASTSource *ast_source = ast->getExternalSource();
5482
5483 if (!ast_source)
5484 return false;
5485
5486 if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
5487 {
5488 if (tag_decl->getDefinition())
5489 return true;
5490
5491 if (!tag_decl->hasExternalLexicalStorage())
5492 return false;
5493
5494 ast_source->CompleteType(tag_decl);
5495
5496 return !tag_decl->getTypeForDecl()->isIncompleteType();
5497 }
5498 else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
5499 {
5500 if (!objc_interface_decl->isForwardDecl())
5501 return true;
5502
5503 if (!objc_interface_decl->hasExternalLexicalStorage())
5504 return false;
5505
5506 ast_source->CompleteType(objc_interface_decl);
5507
5508 return !objc_interface_decl->isForwardDecl();
5509 }
5510 else
5511 {
5512 return false;
5513 }
5514}
5515
Greg Clayton2c5f0e92011-08-04 21:02:57 +00005516clang::DeclContext *
5517ClangASTContext::GetAsDeclContext (clang::CXXMethodDecl *cxx_method_decl)
5518{
Sean Callanana87bee82011-08-19 06:19:25 +00005519 return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00005520}
5521
5522clang::DeclContext *
5523ClangASTContext::GetAsDeclContext (clang::ObjCMethodDecl *objc_method_decl)
5524{
Sean Callanana87bee82011-08-19 06:19:25 +00005525 return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00005526}
5527