blob: 3797769f6f26fd2864fabef6d6d0d1c480199d04 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedman932197d2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Greg Clayton6beaaa62011-01-17 03:46:26 +000017
18// Clang headers like to use NDEBUG inside of them to enable/disable debug
19// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing
20// or another. This is bad because it means that if clang was built in release
21// mode, it assumes that you are building in release mode which is not always
22// the case. You can end up with functions that are defined as empty in header
23// files when NDEBUG is not defined, and this can cause link errors with the
24// clang .a files that you have since you might be missing functions in the .a
25// file. So we have to define NDEBUG when including clang headers to avoid any
26// mismatches. This is covered by rdar://problem/8691220
27
28#ifndef NDEBUG
29#define LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000030#define NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000031// Need to include assert.h so it is as clang would expect it to be (disabled)
32#include <assert.h>
33#endif
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "clang/AST/ASTContext.h"
36#include "clang/AST/ASTImporter.h"
37#include "clang/AST/CXXInheritance.h"
Greg Clayton8cf05932010-07-22 18:30:50 +000038#include "clang/AST/DeclObjC.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "clang/AST/RecordLayout.h"
40#include "clang/AST/Type.h"
41#include "clang/Basic/Builtins.h"
42#include "clang/Basic/FileManager.h"
Sean Callanan79439e82010-11-18 02:56:27 +000043#include "clang/Basic/FileSystemOptions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044#include "clang/Basic/SourceManager.h"
45#include "clang/Basic/TargetInfo.h"
46#include "clang/Basic/TargetOptions.h"
47#include "clang/Frontend/FrontendOptions.h"
48#include "clang/Frontend/LangStandard.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000049
50#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000051#undef NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000052#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
53// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
54#include <assert.h>
55#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056
Greg Clayton514487e2011-02-15 21:59:32 +000057#include "lldb/Core/ArchSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058#include "lldb/Core/dwarf.h"
Greg Clayton73b472d2010-10-27 03:32:59 +000059#include "lldb/Core/Flags.h"
Sean Callananfb8b7092010-10-28 18:19:36 +000060#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061
Eli Friedman932197d2010-06-13 19:06:42 +000062#include <stdio.h>
63
Greg Claytonc86103d2010-08-05 01:57:25 +000064using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065using namespace lldb_private;
66using namespace llvm;
67using namespace clang;
68
Greg Clayton6beaaa62011-01-17 03:46:26 +000069
70static bool
71GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
72{
73 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
74 switch (type_class)
75 {
76 case clang::Type::Record:
77 case clang::Type::Enum:
78 {
Sean Callanan78e37602011-01-27 04:42:51 +000079 const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +000080 if (tag_type)
81 {
82 clang::TagDecl *tag_decl = tag_type->getDecl();
83 if (tag_decl)
84 {
85 if (tag_decl->getDefinition())
86 return true;
87
88 if (tag_decl->hasExternalLexicalStorage())
89 {
90 ExternalASTSource *external_ast_source = ast->getExternalSource();
91 if (external_ast_source)
92 {
93 external_ast_source->CompleteType(tag_decl);
94 return !tag_type->isIncompleteType();
95 }
96 }
97 return false;
98 }
99 }
100
101 }
102 break;
103
104 case clang::Type::ObjCObject:
105 case clang::Type::ObjCInterface:
106 {
Sean Callanan78e37602011-01-27 04:42:51 +0000107 const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000108 if (objc_class_type)
109 {
110 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
111 // We currently can't complete objective C types through the newly added ASTContext
112 // because it only supports TagDecl objects right now...
113 bool is_forward_decl = class_interface_decl->isForwardDecl();
114 if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
115 {
116 ExternalASTSource *external_ast_source = ast->getExternalSource();
117 if (external_ast_source)
118 {
119 external_ast_source->CompleteType (class_interface_decl);
120 is_forward_decl = class_interface_decl->isForwardDecl();
121 }
Greg Claytonc432c192011-01-20 04:18:48 +0000122 return is_forward_decl == false;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000123 }
Greg Claytonc432c192011-01-20 04:18:48 +0000124 return true;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000125 }
126 }
127 break;
128
129 case clang::Type::Typedef:
130 return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType());
131
132 default:
133 break;
134 }
135
136 return true;
137}
138
139
Greg Clayton8cf05932010-07-22 18:30:50 +0000140static AccessSpecifier
Greg Claytonc86103d2010-08-05 01:57:25 +0000141ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000142{
143 switch (access)
144 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000145 default: break;
146 case eAccessNone: return AS_none;
147 case eAccessPublic: return AS_public;
148 case eAccessPrivate: return AS_private;
149 case eAccessProtected: return AS_protected;
Greg Clayton8cf05932010-07-22 18:30:50 +0000150 }
151 return AS_none;
152}
153
154static ObjCIvarDecl::AccessControl
Greg Claytonc86103d2010-08-05 01:57:25 +0000155ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000156{
157 switch (access)
158 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000159 default: break;
160 case eAccessNone: return ObjCIvarDecl::None;
161 case eAccessPublic: return ObjCIvarDecl::Public;
162 case eAccessPrivate: return ObjCIvarDecl::Private;
163 case eAccessProtected: return ObjCIvarDecl::Protected;
164 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton8cf05932010-07-22 18:30:50 +0000165 }
166 return ObjCIvarDecl::None;
167}
168
169
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170static void
171ParseLangArgs
172(
173 LangOptions &Opts,
Greg Clayton94e5d782010-06-13 17:34:29 +0000174 InputKind IK
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175)
176{
177 // FIXME: Cleanup per-file based stuff.
178
179 // Set some properties which depend soley on the input kind; it would be nice
180 // to move these to the language standard, and have the driver resolve the
181 // input kind + language standard.
Greg Clayton94e5d782010-06-13 17:34:29 +0000182 if (IK == IK_Asm) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183 Opts.AsmPreprocessor = 1;
Greg Clayton94e5d782010-06-13 17:34:29 +0000184 } else if (IK == IK_ObjC ||
185 IK == IK_ObjCXX ||
186 IK == IK_PreprocessedObjC ||
187 IK == IK_PreprocessedObjCXX) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188 Opts.ObjC1 = Opts.ObjC2 = 1;
189 }
190
191 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
192
193 if (LangStd == LangStandard::lang_unspecified) {
194 // Based on the base language, pick one.
195 switch (IK) {
Greg Clayton94e5d782010-06-13 17:34:29 +0000196 case IK_None:
197 case IK_AST:
Sean Callananfb0b7582011-03-15 00:17:19 +0000198 case IK_LLVM_IR:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000199 assert (!"Invalid input kind!");
Greg Clayton94e5d782010-06-13 17:34:29 +0000200 case IK_OpenCL:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201 LangStd = LangStandard::lang_opencl;
202 break;
Sean Callananfb0b7582011-03-15 00:17:19 +0000203 case IK_CUDA:
204 LangStd = LangStandard::lang_cuda;
205 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000206 case IK_Asm:
207 case IK_C:
208 case IK_PreprocessedC:
209 case IK_ObjC:
210 case IK_PreprocessedObjC:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211 LangStd = LangStandard::lang_gnu99;
212 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000213 case IK_CXX:
214 case IK_PreprocessedCXX:
215 case IK_ObjCXX:
216 case IK_PreprocessedObjCXX:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217 LangStd = LangStandard::lang_gnucxx98;
218 break;
219 }
220 }
221
222 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
223 Opts.BCPLComment = Std.hasBCPLComments();
224 Opts.C99 = Std.isC99();
225 Opts.CPlusPlus = Std.isCPlusPlus();
226 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
227 Opts.Digraphs = Std.hasDigraphs();
228 Opts.GNUMode = Std.isGNUMode();
229 Opts.GNUInline = !Std.isC99();
230 Opts.HexFloats = Std.hasHexFloats();
231 Opts.ImplicitInt = Std.hasImplicitInt();
232
233 // OpenCL has some additional defaults.
234 if (LangStd == LangStandard::lang_opencl) {
235 Opts.OpenCL = 1;
236 Opts.AltiVec = 1;
237 Opts.CXXOperatorNames = 1;
238 Opts.LaxVectorConversions = 1;
239 }
240
241 // OpenCL and C++ both have bool, true, false keywords.
242 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
243
244// if (Opts.CPlusPlus)
245// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
246//
247// if (Args.hasArg(OPT_fobjc_gc_only))
248// Opts.setGCMode(LangOptions::GCOnly);
249// else if (Args.hasArg(OPT_fobjc_gc))
250// Opts.setGCMode(LangOptions::HybridGC);
251//
252// if (Args.hasArg(OPT_print_ivar_layout))
253// Opts.ObjCGCBitmapPrint = 1;
254//
255// if (Args.hasArg(OPT_faltivec))
256// Opts.AltiVec = 1;
257//
258// if (Args.hasArg(OPT_pthread))
259// Opts.POSIXThreads = 1;
260//
261// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
262// "default");
263// if (Vis == "default")
Sean Callanan31e851c2010-10-29 18:38:40 +0000264 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265// else if (Vis == "hidden")
266// Opts.setVisibilityMode(LangOptions::Hidden);
267// else if (Vis == "protected")
268// Opts.setVisibilityMode(LangOptions::Protected);
269// else
270// Diags.Report(diag::err_drv_invalid_value)
271// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
272
273// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
274
275 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
276 // is specified, or -std is set to a conforming mode.
277 Opts.Trigraphs = !Opts.GNUMode;
278// if (Args.hasArg(OPT_trigraphs))
279// Opts.Trigraphs = 1;
280//
281// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
282// OPT_fno_dollars_in_identifiers,
283// !Opts.AsmPreprocessor);
284// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
285// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
286// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
287// if (Args.hasArg(OPT_fno_lax_vector_conversions))
288// Opts.LaxVectorConversions = 0;
289// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
290// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
291// Opts.Blocks = Args.hasArg(OPT_fblocks);
292// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
293// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
294// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
295// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
296// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
297// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
298// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
299// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
300// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
301// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
302// Diags);
303// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
304// Opts.ObjCConstantStringClass = getLastArgValue(Args,
305// OPT_fconstant_string_class);
306// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
307// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
308// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
309// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
310// Opts.Static = Args.hasArg(OPT_static_define);
311 Opts.OptimizeSize = 0;
312
313 // FIXME: Eliminate this dependency.
314// unsigned Opt =
315// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
316// Opts.Optimize = Opt != 0;
317 unsigned Opt = 0;
318
319 // This is the __NO_INLINE__ define, which just depends on things like the
320 // optimization level and -fno-inline, not actually whether the backend has
321 // inlining enabled.
322 //
323 // FIXME: This is affected by other options (-fno-inline).
324 Opts.NoInline = !Opt;
325
326// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
327// switch (SSP) {
328// default:
329// Diags.Report(diag::err_drv_invalid_value)
330// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
331// break;
332// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
333// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
334// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
335// }
336}
337
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000338
Greg Clayton6beaaa62011-01-17 03:46:26 +0000339ClangASTContext::ClangASTContext (const char *target_triple) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 m_target_triple(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000341 m_ast_ap(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 m_language_options_ap(),
343 m_source_manager_ap(),
344 m_diagnostic_ap(),
345 m_target_options_ap(),
346 m_target_info_ap(),
347 m_identifier_table_ap(),
348 m_selector_table_ap(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000349 m_builtins_ap(),
350 m_callback_tag_decl (NULL),
351 m_callback_objc_decl (NULL),
352 m_callback_baton (NULL)
353
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000354{
355 if (target_triple && target_triple[0])
356 m_target_triple.assign (target_triple);
357}
358
359//----------------------------------------------------------------------
360// Destructor
361//----------------------------------------------------------------------
362ClangASTContext::~ClangASTContext()
363{
364 m_builtins_ap.reset();
365 m_selector_table_ap.reset();
366 m_identifier_table_ap.reset();
367 m_target_info_ap.reset();
368 m_target_options_ap.reset();
369 m_diagnostic_ap.reset();
370 m_source_manager_ap.reset();
371 m_language_options_ap.reset();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000372 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373}
374
375
376void
377ClangASTContext::Clear()
378{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000379 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380 m_language_options_ap.reset();
381 m_source_manager_ap.reset();
382 m_diagnostic_ap.reset();
383 m_target_options_ap.reset();
384 m_target_info_ap.reset();
385 m_identifier_table_ap.reset();
386 m_selector_table_ap.reset();
387 m_builtins_ap.reset();
388}
389
390const char *
391ClangASTContext::GetTargetTriple ()
392{
393 return m_target_triple.c_str();
394}
395
396void
397ClangASTContext::SetTargetTriple (const char *target_triple)
398{
399 Clear();
400 m_target_triple.assign(target_triple);
401}
402
Greg Clayton514487e2011-02-15 21:59:32 +0000403void
404ClangASTContext::SetArchitecture (const ArchSpec &arch)
405{
406 Clear();
407 m_target_triple.assign(arch.GetTriple().str());
408}
409
Greg Clayton6beaaa62011-01-17 03:46:26 +0000410bool
411ClangASTContext::HasExternalSource ()
412{
413 ASTContext *ast = getASTContext();
414 if (ast)
415 return ast->getExternalSource () != NULL;
416 return false;
417}
418
419void
420ClangASTContext::SetExternalSource (llvm::OwningPtr<ExternalASTSource> &ast_source_ap)
421{
422 ASTContext *ast = getASTContext();
423 if (ast)
424 {
425 ast->setExternalSource (ast_source_ap);
426 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
427 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
428 }
429}
430
431void
432ClangASTContext::RemoveExternalSource ()
433{
434 ASTContext *ast = getASTContext();
435
436 if (ast)
437 {
438 llvm::OwningPtr<ExternalASTSource> empty_ast_source_ap;
439 ast->setExternalSource (empty_ast_source_ap);
440 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
441 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
442 }
443}
444
445
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446
447ASTContext *
448ClangASTContext::getASTContext()
449{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000450 if (m_ast_ap.get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000452 m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
453 *getSourceManager(),
454 *getTargetInfo(),
455 *getIdentifierTable(),
456 *getSelectorTable(),
457 *getBuiltinContext(),
458 0));
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000459
Greg Clayton6beaaa62011-01-17 03:46:26 +0000460 if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton)
461 {
462 m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
463 //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
464 }
465
466 m_ast_ap->getDiagnostics().setClient(getDiagnosticClient(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000468 return m_ast_ap.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469}
470
471Builtin::Context *
472ClangASTContext::getBuiltinContext()
473{
474 if (m_builtins_ap.get() == NULL)
475 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
476 return m_builtins_ap.get();
477}
478
479IdentifierTable *
480ClangASTContext::getIdentifierTable()
481{
482 if (m_identifier_table_ap.get() == NULL)
483 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
484 return m_identifier_table_ap.get();
485}
486
487LangOptions *
488ClangASTContext::getLanguageOptions()
489{
490 if (m_language_options_ap.get() == NULL)
491 {
492 m_language_options_ap.reset(new LangOptions());
Greg Clayton94e5d782010-06-13 17:34:29 +0000493 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
494// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000495 }
496 return m_language_options_ap.get();
497}
498
499SelectorTable *
500ClangASTContext::getSelectorTable()
501{
502 if (m_selector_table_ap.get() == NULL)
503 m_selector_table_ap.reset (new SelectorTable());
504 return m_selector_table_ap.get();
505}
506
Sean Callanan79439e82010-11-18 02:56:27 +0000507clang::FileManager *
508ClangASTContext::getFileManager()
509{
510 if (m_file_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000511 {
512 clang::FileSystemOptions file_system_options;
513 m_file_manager_ap.reset(new clang::FileManager(file_system_options));
514 }
Sean Callanan79439e82010-11-18 02:56:27 +0000515 return m_file_manager_ap.get();
516}
517
Greg Claytone1a916a2010-07-21 22:12:05 +0000518clang::SourceManager *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519ClangASTContext::getSourceManager()
520{
521 if (m_source_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000522 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523 return m_source_manager_ap.get();
524}
525
526Diagnostic *
527ClangASTContext::getDiagnostic()
528{
529 if (m_diagnostic_ap.get() == NULL)
Greg Claytona651b532010-11-19 21:46:54 +0000530 {
531 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
532 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
533 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534 return m_diagnostic_ap.get();
535}
536
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000537class NullDiagnosticClient : public DiagnosticClient
538{
539public:
540 NullDiagnosticClient ()
541 {
542 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
543 }
544
545 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
546 {
547 if (m_log)
548 {
549 llvm::SmallVectorImpl<char> diag_str(10);
550 info.FormatDiagnostic(diag_str);
551 diag_str.push_back('\0');
552 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
553 }
554 }
555private:
556 LogSP m_log;
557};
558
559DiagnosticClient *
560ClangASTContext::getDiagnosticClient()
561{
562 if (m_diagnostic_client_ap.get() == NULL)
563 m_diagnostic_client_ap.reset(new NullDiagnosticClient);
564
565 return m_diagnostic_client_ap.get();
566}
567
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000568TargetOptions *
569ClangASTContext::getTargetOptions()
570{
571 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
572 {
573 m_target_options_ap.reset (new TargetOptions());
574 if (m_target_options_ap.get())
575 m_target_options_ap->Triple = m_target_triple;
576 }
577 return m_target_options_ap.get();
578}
579
580
581TargetInfo *
582ClangASTContext::getTargetInfo()
583{
584 // target_triple should be something like "x86_64-apple-darwin10"
585 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
586 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
587 return m_target_info_ap.get();
588}
589
590#pragma mark Basic Types
591
592static inline bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000593QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000595 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 if (qual_type_bit_size == bit_size)
597 return true;
598 return false;
599}
600
Greg Clayton1be10fc2010-09-29 01:12:09 +0000601clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +0000602ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000603{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000604 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605
Greg Clayton6beaaa62011-01-17 03:46:26 +0000606 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607
Greg Clayton6beaaa62011-01-17 03:46:26 +0000608 return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000609}
610
Greg Clayton1be10fc2010-09-29 01:12:09 +0000611clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000612ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000613{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000614 if (!ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000615 return NULL;
616
617 switch (encoding)
618 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000619 case eEncodingInvalid:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000620 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
621 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622 break;
623
Greg Claytonc86103d2010-08-05 01:57:25 +0000624 case eEncodingUint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000625 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
626 return ast->UnsignedCharTy.getAsOpaquePtr();
627 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
628 return ast->UnsignedShortTy.getAsOpaquePtr();
629 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
630 return ast->UnsignedIntTy.getAsOpaquePtr();
631 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
632 return ast->UnsignedLongTy.getAsOpaquePtr();
633 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
634 return ast->UnsignedLongLongTy.getAsOpaquePtr();
635 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
636 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000637 break;
638
Greg Claytonc86103d2010-08-05 01:57:25 +0000639 case eEncodingSint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000640 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
641 return ast->CharTy.getAsOpaquePtr();
642 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
643 return ast->ShortTy.getAsOpaquePtr();
644 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
645 return ast->IntTy.getAsOpaquePtr();
646 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
647 return ast->LongTy.getAsOpaquePtr();
648 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
649 return ast->LongLongTy.getAsOpaquePtr();
650 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
651 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652 break;
653
Greg Claytonc86103d2010-08-05 01:57:25 +0000654 case eEncodingIEEE754:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000655 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
656 return ast->FloatTy.getAsOpaquePtr();
657 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
658 return ast->DoubleTy.getAsOpaquePtr();
659 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
660 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000661 break;
662
Greg Claytonc86103d2010-08-05 01:57:25 +0000663 case eEncodingVector:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000664 default:
665 break;
666 }
667
668 return NULL;
669}
670
Greg Clayton1be10fc2010-09-29 01:12:09 +0000671clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
673{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000674 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000675
676 #define streq(a,b) strcmp(a,b) == 0
Greg Clayton6beaaa62011-01-17 03:46:26 +0000677 assert (ast != NULL);
678 if (ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000679 {
680 switch (dw_ate)
681 {
682 default:
683 break;
684
685 case DW_ATE_address:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000686 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
687 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000688 break;
689
690 case DW_ATE_boolean:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000691 if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
692 return ast->BoolTy.getAsOpaquePtr();
693 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
694 return ast->UnsignedCharTy.getAsOpaquePtr();
695 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
696 return ast->UnsignedShortTy.getAsOpaquePtr();
697 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
698 return ast->UnsignedIntTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000699 break;
700
Greg Clayton49462ea2011-01-15 02:52:14 +0000701 case DW_ATE_lo_user:
702 // This has been seen to mean DW_AT_complex_integer
Greg Clayton5732f242011-01-27 09:15:11 +0000703 if (::strstr(type_name, "complex"))
Greg Clayton49462ea2011-01-15 02:52:14 +0000704 {
705 clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000706 return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000707 }
708 break;
709
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000710 case DW_ATE_complex_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000711 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
712 return ast->FloatComplexTy.getAsOpaquePtr();
713 else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
714 return ast->DoubleComplexTy.getAsOpaquePtr();
715 else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
716 return ast->LongDoubleComplexTy.getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000717 else
718 {
719 clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000720 return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000721 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000722 break;
723
724 case DW_ATE_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000725 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
726 return ast->FloatTy.getAsOpaquePtr();
727 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
728 return ast->DoubleTy.getAsOpaquePtr();
729 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
730 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731 break;
732
733 case DW_ATE_signed:
734 if (type_name)
735 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000736 if (strstr(type_name, "long long"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000738 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
739 return ast->LongLongTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000740 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000741 else if (strstr(type_name, "long"))
742 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000743 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
744 return ast->LongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000745 }
746 else if (strstr(type_name, "short"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000747 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000748 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
749 return ast->ShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000750 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000751 else if (strstr(type_name, "char"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000752 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000753 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
754 return ast->CharTy.getAsOpaquePtr();
755 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
756 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000758 else if (strstr(type_name, "int"))
759 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000760 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
761 return ast->IntTy.getAsOpaquePtr();
762 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
763 return ast->Int128Ty.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000764 }
765 else if (streq(type_name, "wchar_t"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000766 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000767 if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
768 return ast->WCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000769 }
Greg Clayton7bd65b92011-02-09 23:39:34 +0000770 else if (streq(type_name, "void"))
771 {
772 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
773 return ast->VoidTy.getAsOpaquePtr();
774 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000775 }
776 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000777 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
778 return ast->CharTy.getAsOpaquePtr();
779 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
780 return ast->ShortTy.getAsOpaquePtr();
781 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
782 return ast->IntTy.getAsOpaquePtr();
783 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
784 return ast->LongTy.getAsOpaquePtr();
785 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
786 return ast->LongLongTy.getAsOpaquePtr();
787 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
788 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000789 break;
790
791 case DW_ATE_signed_char:
792 if (type_name)
793 {
794 if (streq(type_name, "signed char"))
795 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000796 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
797 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000798 }
799 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000800 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
801 return ast->CharTy.getAsOpaquePtr();
802 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
803 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000804 break;
805
806 case DW_ATE_unsigned:
807 if (type_name)
808 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000809 if (strstr(type_name, "long long"))
810 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000811 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
812 return ast->UnsignedLongLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000813 }
814 else if (strstr(type_name, "long"))
815 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000816 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
817 return ast->UnsignedLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000818 }
819 else if (strstr(type_name, "short"))
820 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000821 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
822 return ast->UnsignedShortTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000823 }
824 else if (strstr(type_name, "char"))
825 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000826 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
827 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000828 }
829 else if (strstr(type_name, "int"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000830 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000831 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
832 return ast->UnsignedIntTy.getAsOpaquePtr();
833 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
834 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000835 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000836 }
837 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000838 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
839 return ast->UnsignedCharTy.getAsOpaquePtr();
840 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
841 return ast->UnsignedShortTy.getAsOpaquePtr();
842 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
843 return ast->UnsignedIntTy.getAsOpaquePtr();
844 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
845 return ast->UnsignedLongTy.getAsOpaquePtr();
846 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
847 return ast->UnsignedLongLongTy.getAsOpaquePtr();
848 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
849 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000850 break;
851
852 case DW_ATE_unsigned_char:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000853 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
854 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton7bd65b92011-02-09 23:39:34 +0000855 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
856 return ast->UnsignedShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857 break;
858
859 case DW_ATE_imaginary_float:
860 break;
861 }
862 }
863 // This assert should fire for anything that we don't catch above so we know
864 // to fix any issues we run into.
865 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
866 return NULL;
867}
868
Greg Clayton1be10fc2010-09-29 01:12:09 +0000869clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000870ClangASTContext::GetBuiltInType_void(ASTContext *ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000871{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000872 return ast->VoidTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000873}
874
Greg Clayton1be10fc2010-09-29 01:12:09 +0000875clang_type_t
Sean Callananf7c3e272010-11-19 02:52:21 +0000876ClangASTContext::GetBuiltInType_bool()
877{
878 return getASTContext()->BoolTy.getAsOpaquePtr();
879}
880
881clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000882ClangASTContext::GetBuiltInType_objc_id()
883{
Sean Callananf6c73082010-12-06 23:53:20 +0000884 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000885}
886
Greg Clayton1be10fc2010-09-29 01:12:09 +0000887clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000888ClangASTContext::GetBuiltInType_objc_Class()
889{
Sean Callanana2424172010-10-25 00:29:48 +0000890 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000891}
892
Greg Clayton1be10fc2010-09-29 01:12:09 +0000893clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000894ClangASTContext::GetBuiltInType_objc_selector()
895{
Sean Callananf6c73082010-12-06 23:53:20 +0000896 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000897}
898
Greg Clayton1be10fc2010-09-29 01:12:09 +0000899clang_type_t
Sean Callanan77502262011-05-12 23:54:16 +0000900ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
901{
902 return ast->UnknownAnyTy.getAsOpaquePtr();
903}
904
905clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000906ClangASTContext::GetCStringType (bool is_const)
907{
908 QualType char_type(getASTContext()->CharTy);
909
910 if (is_const)
911 char_type.addConst();
912
913 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
914}
915
Greg Clayton1be10fc2010-09-29 01:12:09 +0000916clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000917ClangASTContext::GetVoidPtrType (bool is_const)
918{
919 return GetVoidPtrType(getASTContext(), is_const);
920}
921
Greg Clayton1be10fc2010-09-29 01:12:09 +0000922clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000923ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000925 QualType void_ptr_type(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000926
927 if (is_const)
928 void_ptr_type.addConst();
929
930 return void_ptr_type.getAsOpaquePtr();
931}
932
Greg Clayton1be10fc2010-09-29 01:12:09 +0000933clang_type_t
Greg Clayton38a61402010-12-02 23:20:03 +0000934ClangASTContext::CopyType (ASTContext *dst_ast,
935 ASTContext *src_ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000936 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000937{
Sean Callanan79439e82010-11-18 02:56:27 +0000938 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000939 FileManager file_manager (file_system_options);
940 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000941 *src_ast, file_manager,
942 false);
Sean Callanan0617fcb2010-11-09 22:37:10 +0000943
Greg Clayton38a61402010-12-02 23:20:03 +0000944 QualType src (QualType::getFromOpaquePtr(clang_type));
945 QualType dst (importer.Import(src));
Sean Callanan0617fcb2010-11-09 22:37:10 +0000946
947 return dst.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000948}
949
Greg Clayton526e5af2010-11-13 03:52:47 +0000950
951clang::Decl *
Greg Clayton38a61402010-12-02 23:20:03 +0000952ClangASTContext::CopyDecl (ASTContext *dst_ast,
953 ASTContext *src_ast,
Greg Clayton526e5af2010-11-13 03:52:47 +0000954 clang::Decl *source_decl)
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000955{
Sean Callanan79439e82010-11-18 02:56:27 +0000956 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000957 FileManager file_manager (file_system_options);
958 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000959 *src_ast, file_manager,
960 false);
Greg Clayton526e5af2010-11-13 03:52:47 +0000961
962 return importer.Import(source_decl);
963}
964
Sean Callanan23a30272010-07-16 00:00:27 +0000965bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000966ClangASTContext::AreTypesSame(ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000967 clang_type_t type1,
968 clang_type_t type2)
Sean Callanan4dcca2622010-07-15 22:30:52 +0000969{
Greg Claytonf4ecaa52011-02-16 23:00:21 +0000970 return ast->hasSameType (QualType::getFromOpaquePtr(type1),
971 QualType::getFromOpaquePtr(type2));
Sean Callanan4dcca2622010-07-15 22:30:52 +0000972}
973
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000974#pragma mark CVR modifiers
975
Greg Clayton1be10fc2010-09-29 01:12:09 +0000976clang_type_t
977ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000978{
979 if (clang_type)
980 {
981 QualType result(QualType::getFromOpaquePtr(clang_type));
982 result.addConst();
983 return result.getAsOpaquePtr();
984 }
985 return NULL;
986}
987
Greg Clayton1be10fc2010-09-29 01:12:09 +0000988clang_type_t
989ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000990{
991 if (clang_type)
992 {
993 QualType result(QualType::getFromOpaquePtr(clang_type));
994 result.getQualifiers().setRestrict (true);
995 return result.getAsOpaquePtr();
996 }
997 return NULL;
998}
999
Greg Clayton1be10fc2010-09-29 01:12:09 +00001000clang_type_t
1001ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001002{
1003 if (clang_type)
1004 {
1005 QualType result(QualType::getFromOpaquePtr(clang_type));
1006 result.getQualifiers().setVolatile (true);
1007 return result.getAsOpaquePtr();
1008 }
1009 return NULL;
1010}
1011
Greg Clayton6beaaa62011-01-17 03:46:26 +00001012
1013clang_type_t
1014ClangASTContext::GetTypeForDecl (TagDecl *decl)
1015{
1016 // No need to call the getASTContext() accessor (which can create the AST
1017 // if it isn't created yet, because we can't have created a decl in this
1018 // AST if our AST didn't already exist...
1019 if (m_ast_ap.get())
1020 return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
1021 return NULL;
1022}
1023
1024clang_type_t
1025ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
1026{
1027 // No need to call the getASTContext() accessor (which can create the AST
1028 // if it isn't created yet, because we can't have created a decl in this
1029 // AST if our AST didn't already exist...
1030 if (m_ast_ap.get())
1031 return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
1032 return NULL;
1033}
1034
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001035#pragma mark Structure, Unions, Classes
1036
Greg Clayton1be10fc2010-09-29 01:12:09 +00001037clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +00001038ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001039{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001040 ASTContext *ast = getASTContext();
1041 assert (ast != NULL);
Sean Callanana2424172010-10-25 00:29:48 +00001042
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001043 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001044 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001045
Greg Clayton9e409562010-07-28 02:04:09 +00001046
Greg Claytonc86103d2010-08-05 01:57:25 +00001047 if (language == eLanguageTypeObjC)
Greg Clayton9e409562010-07-28 02:04:09 +00001048 {
Greg Claytonaaf99e02010-10-11 02:25:34 +00001049 bool isForwardDecl = true;
Greg Clayton9e409562010-07-28 02:04:09 +00001050 bool isInternal = false;
1051 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
1052 }
1053
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1055 // we will need to update this code. I was told to currently always use
1056 // the CXXRecordDecl class since we often don't know from debug information
1057 // if something is struct or a class, so we default to always use the more
1058 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001059 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001060 (TagDecl::TagKind)kind,
1061 decl_ctx,
1062 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001063 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001064 name && name[0] ? &ast->Idents.get(name) : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001065
Greg Clayton6beaaa62011-01-17 03:46:26 +00001066 return ast->getTagDeclType(decl).getAsOpaquePtr();
1067}
1068
1069bool
1070ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
1071{
1072 if (clang_type == NULL)
1073 return false;
1074
1075 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1076
1077 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1078 switch (type_class)
1079 {
1080 case clang::Type::Record:
1081 {
1082 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
1083 if (cxx_record_decl)
1084 {
1085 cxx_record_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001086 cxx_record_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001087 return true;
1088 }
1089 }
1090 break;
1091
1092 case clang::Type::Enum:
1093 {
1094 EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
1095 if (enum_decl)
1096 {
1097 enum_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001098 enum_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001099 return true;
1100 }
1101 }
1102 break;
1103
1104 case clang::Type::ObjCObject:
1105 case clang::Type::ObjCInterface:
1106 {
Sean Callanan78e37602011-01-27 04:42:51 +00001107 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001108 assert (objc_class_type);
1109 if (objc_class_type)
1110 {
1111 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1112
1113 if (class_interface_decl)
1114 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001115 class_interface_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001116 class_interface_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001117 return true;
1118 }
1119 }
1120 }
1121 break;
1122
1123 case clang::Type::Typedef:
1124 return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
1125
1126 default:
1127 break;
1128 }
1129 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001130}
1131
Greg Claytona3c444a2010-10-01 23:13:49 +00001132static bool
1133IsOperator (const char *name, OverloadedOperatorKind &op_kind)
1134{
1135 if (name == NULL || name[0] == '\0')
1136 return false;
1137
Sean Callanana43f20d2010-12-10 19:51:54 +00001138#define OPERATOR_PREFIX "operator"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001139#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
Sean Callananbfeff8c2010-12-10 02:15:55 +00001140
1141 const char *post_op_name = NULL;
1142
Sean Callanana43f20d2010-12-10 19:51:54 +00001143 bool no_space = true;
Sean Callananbfeff8c2010-12-10 02:15:55 +00001144
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001145 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
Greg Claytona3c444a2010-10-01 23:13:49 +00001146 return false;
1147
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001148 post_op_name = name + OPERATOR_PREFIX_LENGTH;
1149
Sean Callanana43f20d2010-12-10 19:51:54 +00001150 if (post_op_name[0] == ' ')
1151 {
1152 post_op_name++;
1153 no_space = false;
1154 }
1155
1156#undef OPERATOR_PREFIX
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001157#undef OPERATOR_PREFIX_LENGTH
Sean Callanana43f20d2010-12-10 19:51:54 +00001158
Greg Claytona3c444a2010-10-01 23:13:49 +00001159 // This is an operator, set the overloaded operator kind to invalid
1160 // in case this is a conversion operator...
1161 op_kind = NUM_OVERLOADED_OPERATORS;
1162
1163 switch (post_op_name[0])
1164 {
Sean Callananbfeff8c2010-12-10 02:15:55 +00001165 default:
1166 if (no_space)
1167 return false;
1168 break;
Greg Claytona3c444a2010-10-01 23:13:49 +00001169 case 'n':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001170 if (no_space)
1171 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001172 if (strcmp (post_op_name, "new") == 0)
1173 op_kind = OO_New;
1174 else if (strcmp (post_op_name, "new[]") == 0)
1175 op_kind = OO_Array_New;
1176 break;
1177
1178 case 'd':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001179 if (no_space)
1180 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001181 if (strcmp (post_op_name, "delete") == 0)
1182 op_kind = OO_Delete;
1183 else if (strcmp (post_op_name, "delete[]") == 0)
1184 op_kind = OO_Array_Delete;
1185 break;
1186
1187 case '+':
1188 if (post_op_name[1] == '\0')
1189 op_kind = OO_Plus;
1190 else if (post_op_name[2] == '\0')
1191 {
1192 if (post_op_name[1] == '=')
1193 op_kind = OO_PlusEqual;
1194 else if (post_op_name[1] == '+')
1195 op_kind = OO_PlusPlus;
1196 }
1197 break;
1198
1199 case '-':
1200 if (post_op_name[1] == '\0')
1201 op_kind = OO_Minus;
1202 else if (post_op_name[2] == '\0')
1203 {
1204 switch (post_op_name[1])
1205 {
1206 case '=': op_kind = OO_MinusEqual; break;
1207 case '-': op_kind = OO_MinusMinus; break;
1208 case '>': op_kind = OO_Arrow; break;
1209 }
1210 }
1211 else if (post_op_name[3] == '\0')
1212 {
1213 if (post_op_name[2] == '*')
1214 op_kind = OO_ArrowStar; break;
1215 }
1216 break;
1217
1218 case '*':
1219 if (post_op_name[1] == '\0')
1220 op_kind = OO_Star;
1221 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1222 op_kind = OO_StarEqual;
1223 break;
1224
1225 case '/':
1226 if (post_op_name[1] == '\0')
1227 op_kind = OO_Slash;
1228 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1229 op_kind = OO_SlashEqual;
1230 break;
1231
1232 case '%':
1233 if (post_op_name[1] == '\0')
1234 op_kind = OO_Percent;
1235 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1236 op_kind = OO_PercentEqual;
1237 break;
1238
1239
1240 case '^':
1241 if (post_op_name[1] == '\0')
1242 op_kind = OO_Caret;
1243 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1244 op_kind = OO_CaretEqual;
1245 break;
1246
1247 case '&':
1248 if (post_op_name[1] == '\0')
1249 op_kind = OO_Amp;
1250 else if (post_op_name[2] == '\0')
1251 {
1252 switch (post_op_name[1])
1253 {
1254 case '=': op_kind = OO_AmpEqual; break;
1255 case '&': op_kind = OO_AmpAmp; break;
1256 }
1257 }
1258 break;
1259
1260 case '|':
1261 if (post_op_name[1] == '\0')
1262 op_kind = OO_Pipe;
1263 else if (post_op_name[2] == '\0')
1264 {
1265 switch (post_op_name[1])
1266 {
1267 case '=': op_kind = OO_PipeEqual; break;
1268 case '|': op_kind = OO_PipePipe; break;
1269 }
1270 }
1271 break;
1272
1273 case '~':
1274 if (post_op_name[1] == '\0')
1275 op_kind = OO_Tilde;
1276 break;
1277
1278 case '!':
1279 if (post_op_name[1] == '\0')
1280 op_kind = OO_Exclaim;
1281 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1282 op_kind = OO_ExclaimEqual;
1283 break;
1284
1285 case '=':
1286 if (post_op_name[1] == '\0')
1287 op_kind = OO_Equal;
1288 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1289 op_kind = OO_EqualEqual;
1290 break;
1291
1292 case '<':
1293 if (post_op_name[1] == '\0')
1294 op_kind = OO_Less;
1295 else if (post_op_name[2] == '\0')
1296 {
1297 switch (post_op_name[1])
1298 {
1299 case '<': op_kind = OO_LessLess; break;
1300 case '=': op_kind = OO_LessEqual; break;
1301 }
1302 }
1303 else if (post_op_name[3] == '\0')
1304 {
1305 if (post_op_name[2] == '=')
1306 op_kind = OO_LessLessEqual;
1307 }
1308 break;
1309
1310 case '>':
1311 if (post_op_name[1] == '\0')
1312 op_kind = OO_Greater;
1313 else if (post_op_name[2] == '\0')
1314 {
1315 switch (post_op_name[1])
1316 {
1317 case '>': op_kind = OO_GreaterGreater; break;
1318 case '=': op_kind = OO_GreaterEqual; break;
1319 }
1320 }
1321 else if (post_op_name[1] == '>' &&
1322 post_op_name[2] == '=' &&
1323 post_op_name[3] == '\0')
1324 {
1325 op_kind = OO_GreaterGreaterEqual;
1326 }
1327 break;
1328
1329 case ',':
1330 if (post_op_name[1] == '\0')
1331 op_kind = OO_Comma;
1332 break;
1333
1334 case '(':
1335 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1336 op_kind = OO_Call;
1337 break;
1338
1339 case '[':
1340 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1341 op_kind = OO_Subscript;
1342 break;
1343 }
1344
1345 return true;
1346}
Greg Clayton6beaaa62011-01-17 03:46:26 +00001347
Greg Claytona51ed9b2010-09-23 01:09:21 +00001348CXXMethodDecl *
Sean Callanan61da09b2010-09-17 02:58:26 +00001349ClangASTContext::AddMethodToCXXRecordType
1350(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001351 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001352 clang_type_t record_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001353 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001354 clang_type_t method_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001355 lldb::AccessType access,
Greg Clayton0fffff52010-09-24 05:15:53 +00001356 bool is_virtual,
1357 bool is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00001358 bool is_inline,
1359 bool is_explicit
Greg Claytona51ed9b2010-09-23 01:09:21 +00001360)
Sean Callanan61da09b2010-09-17 02:58:26 +00001361{
Sean Callananfc55f5d2010-09-21 00:44:12 +00001362 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chend440bcc2010-09-28 16:10:54 +00001363 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001364
Greg Clayton6beaaa62011-01-17 03:46:26 +00001365 assert(ast);
Sean Callanan61da09b2010-09-17 02:58:26 +00001366
Greg Clayton6beaaa62011-01-17 03:46:26 +00001367 IdentifierTable *identifier_table = &ast->Idents;
Sean Callanan61da09b2010-09-17 02:58:26 +00001368
1369 assert(identifier_table);
1370
Sean Callananfc55f5d2010-09-21 00:44:12 +00001371 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001372
Greg Clayton6beaaa62011-01-17 03:46:26 +00001373 CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
Sean Callanan61da09b2010-09-17 02:58:26 +00001374
Greg Clayton0fffff52010-09-24 05:15:53 +00001375 if (cxx_record_decl == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001376 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001377
Greg Clayton0fffff52010-09-24 05:15:53 +00001378 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001379
Greg Claytonf51de672010-10-01 02:31:07 +00001380 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001381
Greg Claytonf51de672010-10-01 02:31:07 +00001382 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton878eaf12010-10-01 03:45:20 +00001383
Greg Clayton878eaf12010-10-01 03:45:20 +00001384 const bool is_implicitly_declared = false;
Greg Claytonf51de672010-10-01 02:31:07 +00001385
Sean Callanan78e37602011-01-27 04:42:51 +00001386 const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton878eaf12010-10-01 03:45:20 +00001387
Greg Clayton90a2acd2010-10-02 01:40:05 +00001388 if (function_Type == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001389 return NULL;
1390
Sean Callanan78e37602011-01-27 04:42:51 +00001391 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton878eaf12010-10-01 03:45:20 +00001392
1393 if (!method_function_prototype)
1394 return NULL;
1395
1396 unsigned int num_params = method_function_prototype->getNumArgs();
1397
1398 if (name[0] == '~')
Greg Claytonf51de672010-10-01 02:31:07 +00001399 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001400 cxx_method_decl = CXXDestructorDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001401 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001402 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001403 DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001404 method_qual_type,
Sean Callanan31e851c2010-10-29 18:38:40 +00001405 NULL,
Greg Clayton878eaf12010-10-01 03:45:20 +00001406 is_inline,
1407 is_implicitly_declared);
1408 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001409 else if (decl_name == cxx_record_decl->getDeclName())
Greg Clayton878eaf12010-10-01 03:45:20 +00001410 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001411 cxx_method_decl = CXXConstructorDecl::Create (*ast,
Greg Claytonf51de672010-10-01 02:31:07 +00001412 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001413 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001414 DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Claytonf51de672010-10-01 02:31:07 +00001415 method_qual_type,
1416 NULL, // TypeSourceInfo *
1417 is_explicit,
1418 is_inline,
1419 is_implicitly_declared);
1420 }
1421 else
Greg Clayton878eaf12010-10-01 03:45:20 +00001422 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001423
1424 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1425 if (IsOperator (name, op_kind))
Greg Clayton878eaf12010-10-01 03:45:20 +00001426 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001427 if (op_kind != NUM_OVERLOADED_OPERATORS)
1428 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001429 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001430 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001431 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001432 DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001433 method_qual_type,
1434 NULL, // TypeSourceInfo *
Greg Claytona3c444a2010-10-01 23:13:49 +00001435 is_static,
1436 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001437 is_inline,
1438 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001439 }
1440 else if (num_params == 0)
1441 {
1442 // Conversion operators don't take params...
Greg Clayton6beaaa62011-01-17 03:46:26 +00001443 cxx_method_decl = CXXConversionDecl::Create (*ast,
Greg Claytona3c444a2010-10-01 23:13:49 +00001444 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001445 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001446 DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytona3c444a2010-10-01 23:13:49 +00001447 method_qual_type,
1448 NULL, // TypeSourceInfo *
1449 is_inline,
Sean Callananfb0b7582011-03-15 00:17:19 +00001450 is_explicit,
1451 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001452 }
Greg Clayton878eaf12010-10-01 03:45:20 +00001453 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001454
1455 if (cxx_method_decl == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001456 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001457 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001458 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001459 SourceLocation(),
Greg Claytona3c444a2010-10-01 23:13:49 +00001460 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001461 method_qual_type,
1462 NULL, // TypeSourceInfo *
1463 is_static,
1464 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001465 is_inline,
1466 SourceLocation());
Greg Clayton878eaf12010-10-01 03:45:20 +00001467 }
Greg Claytonf51de672010-10-01 02:31:07 +00001468 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001469
Greg Clayton1be10fc2010-09-29 01:12:09 +00001470 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton0fffff52010-09-24 05:15:53 +00001471
1472 cxx_method_decl->setAccess (access_specifier);
1473 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001474
Sean Callananfc55f5d2010-09-21 00:44:12 +00001475 // Populate the method decl with parameter decls
Sean Callananfc55f5d2010-09-21 00:44:12 +00001476
1477 ParmVarDecl *params[num_params];
1478
1479 for (int param_index = 0;
1480 param_index < num_params;
1481 ++param_index)
1482 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001483 params[param_index] = ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001484 cxx_method_decl,
1485 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001486 SourceLocation(),
Greg Clayton0fffff52010-09-24 05:15:53 +00001487 NULL, // anonymous
1488 method_function_prototype->getArgType(param_index),
1489 NULL,
1490 SC_None,
1491 SC_None,
1492 NULL);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001493 }
1494
Greg Clayton0fffff52010-09-24 05:15:53 +00001495 cxx_method_decl->setParams (params, num_params);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001496
Greg Clayton0fffff52010-09-24 05:15:53 +00001497 cxx_record_decl->addDecl (cxx_method_decl);
Greg Claytonc432c192011-01-20 04:18:48 +00001498
1499// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic());
1500// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate());
1501// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD());
1502// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty());
1503// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract());
1504// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor());
1505// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
1506// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
1507// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor());
Greg Claytona51ed9b2010-09-23 01:09:21 +00001508 return cxx_method_decl;
Sean Callanan61da09b2010-09-17 02:58:26 +00001509}
1510
1511bool
Greg Clayton8cf05932010-07-22 18:30:50 +00001512ClangASTContext::AddFieldToRecordType
1513(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001514 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001515 clang_type_t record_clang_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001516 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001517 clang_type_t field_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001518 AccessType access,
1519 uint32_t bitfield_bit_size
1520)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001521{
1522 if (record_clang_type == NULL || field_type == NULL)
1523 return false;
1524
Greg Clayton6beaaa62011-01-17 03:46:26 +00001525 IdentifierTable *identifier_table = &ast->Idents;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001526
Greg Clayton6beaaa62011-01-17 03:46:26 +00001527 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001528 assert (identifier_table != NULL);
1529
1530 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1531
Sean Callanan78e37602011-01-27 04:42:51 +00001532 const clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001533 if (clang_type)
1534 {
1535 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1536
1537 if (record_type)
1538 {
1539 RecordDecl *record_decl = record_type->getDecl();
1540
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001541 clang::Expr *bit_width = NULL;
1542 if (bitfield_bit_size != 0)
1543 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001544 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1545 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001546 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001547 FieldDecl *field = FieldDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001548 record_decl,
1549 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001550 SourceLocation(),
Greg Clayton8cf05932010-07-22 18:30:50 +00001551 name ? &identifier_table->get(name) : NULL, // Identifier
1552 QualType::getFromOpaquePtr(field_type), // Field type
1553 NULL, // DeclaratorInfo *
1554 bit_width, // BitWidth
1555 false); // Mutable
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001556
Greg Clayton8cf05932010-07-22 18:30:50 +00001557 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001558
1559 if (field)
1560 {
1561 record_decl->addDecl(field);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001562 }
1563 }
Greg Clayton9e409562010-07-28 02:04:09 +00001564 else
1565 {
Sean Callanan78e37602011-01-27 04:42:51 +00001566 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001567 if (objc_class_type)
1568 {
Greg Clayton0fffff52010-09-24 05:15:53 +00001569 bool is_synthesized = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001570 ClangASTContext::AddObjCClassIVar (ast,
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001571 record_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001572 name,
1573 field_type,
1574 access,
1575 bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001576 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001577 }
1578 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001579 }
1580 return false;
1581}
1582
1583bool
1584ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1585{
1586 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1587}
1588
1589bool
1590ClangASTContext::FieldIsBitfield
1591(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001592 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001593 FieldDecl* field,
1594 uint32_t& bitfield_bit_size
1595)
1596{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001597 if (ast == NULL || field == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001598 return false;
1599
1600 if (field->isBitField())
1601 {
1602 Expr* bit_width_expr = field->getBitWidth();
1603 if (bit_width_expr)
1604 {
1605 llvm::APSInt bit_width_apsint;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001606 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001607 {
1608 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1609 return true;
1610 }
1611 }
1612 }
1613 return false;
1614}
1615
1616bool
1617ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1618{
1619 if (record_decl == NULL)
1620 return false;
1621
1622 if (!record_decl->field_empty())
1623 return true;
1624
1625 // No fields, lets check this is a CXX record and check the base classes
1626 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1627 if (cxx_record_decl)
1628 {
1629 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1630 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1631 base_class != base_class_end;
1632 ++base_class)
1633 {
1634 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1635 if (RecordHasFields(base_class_decl))
1636 return true;
1637 }
1638 }
1639 return false;
1640}
1641
1642void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001643ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001644{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001645 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001646 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001647 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1648
Sean Callanan78e37602011-01-27 04:42:51 +00001649 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001650 if (record_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001652 RecordDecl *record_decl = record_type->getDecl();
1653 if (record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001654 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001655 uint32_t field_idx;
1656 RecordDecl::field_iterator field, field_end;
1657 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1658 field != field_end;
1659 ++field, ++field_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001660 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001661 // If no accessibility was assigned, assign the correct one
1662 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1663 field->setAccess ((AccessSpecifier)default_accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001664 }
1665 }
1666 }
1667 }
1668}
1669
1670#pragma mark C++ Base Classes
1671
1672CXXBaseSpecifier *
Greg Clayton1be10fc2010-09-29 01:12:09 +00001673ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001674{
1675 if (base_class_type)
Greg Claytone6371122010-07-30 20:30:44 +00001676 return new CXXBaseSpecifier (SourceRange(),
1677 is_virtual,
1678 base_of_class,
1679 ConvertAccessTypeToAccessSpecifier (access),
Sean Callanan2c777c42011-01-18 23:32:05 +00001680 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
1681 SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001682 return NULL;
1683}
1684
Greg Clayton0b42ac32010-07-02 01:29:13 +00001685void
1686ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1687{
1688 for (unsigned i=0; i<num_base_classes; ++i)
1689 {
1690 delete base_classes[i];
1691 base_classes[i] = NULL;
1692 }
1693}
1694
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001695bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001696ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001697{
1698 if (class_clang_type)
1699 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001700 CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
1701 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001702 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001703 cxx_record_decl->setBases(base_classes, num_base_classes);
1704 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001705 }
1706 }
1707 return false;
1708}
Greg Clayton8cf05932010-07-22 18:30:50 +00001709#pragma mark Objective C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001710
Greg Clayton1be10fc2010-09-29 01:12:09 +00001711clang_type_t
Greg Clayton8cf05932010-07-22 18:30:50 +00001712ClangASTContext::CreateObjCClass
1713(
1714 const char *name,
1715 DeclContext *decl_ctx,
1716 bool isForwardDecl,
1717 bool isInternal
1718)
1719{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001720 ASTContext *ast = getASTContext();
1721 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001722 assert (name && name[0]);
1723 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001724 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001725
1726 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1727 // we will need to update this code. I was told to currently always use
1728 // the CXXRecordDecl class since we often don't know from debug information
1729 // if something is struct or a class, so we default to always use the more
1730 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001731 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001732 decl_ctx,
1733 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001734 &ast->Idents.get(name),
Greg Clayton8cf05932010-07-22 18:30:50 +00001735 SourceLocation(),
1736 isForwardDecl,
1737 isInternal);
Greg Clayton9e409562010-07-28 02:04:09 +00001738
Greg Clayton6beaaa62011-01-17 03:46:26 +00001739 return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001740}
1741
1742bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001743ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton8cf05932010-07-22 18:30:50 +00001744{
1745 if (class_opaque_type && super_opaque_type)
1746 {
1747 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1748 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
Sean Callanan78e37602011-01-27 04:42:51 +00001749 const clang::Type *class_type = class_qual_type.getTypePtr();
1750 const clang::Type *super_type = super_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001751 if (class_type && super_type)
1752 {
Sean Callanan78e37602011-01-27 04:42:51 +00001753 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1754 const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001755 if (objc_class_type && objc_super_type)
1756 {
1757 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1758 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1759 if (class_interface_decl && super_interface_decl)
1760 {
1761 class_interface_decl->setSuperClass(super_interface_decl);
1762 return true;
1763 }
1764 }
1765 }
1766 }
1767 return false;
1768}
1769
1770
1771bool
1772ClangASTContext::AddObjCClassIVar
1773(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001774 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001775 clang_type_t class_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001776 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001777 clang_type_t ivar_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001778 AccessType access,
1779 uint32_t bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001780 bool is_synthesized
Greg Clayton8cf05932010-07-22 18:30:50 +00001781)
1782{
1783 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1784 return false;
1785
Greg Clayton6beaaa62011-01-17 03:46:26 +00001786 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton8cf05932010-07-22 18:30:50 +00001787
Greg Clayton6beaaa62011-01-17 03:46:26 +00001788 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001789 assert (identifier_table != NULL);
1790
1791 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1792
Sean Callanan78e37602011-01-27 04:42:51 +00001793 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001794 if (class_type)
1795 {
Sean Callanan78e37602011-01-27 04:42:51 +00001796 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001797
1798 if (objc_class_type)
1799 {
1800 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1801
1802 if (class_interface_decl)
1803 {
1804 clang::Expr *bit_width = NULL;
1805 if (bitfield_bit_size != 0)
1806 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001807 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1808 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Greg Clayton8cf05932010-07-22 18:30:50 +00001809 }
1810
Greg Clayton6beaaa62011-01-17 03:46:26 +00001811 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast,
Greg Clayton9e409562010-07-28 02:04:09 +00001812 class_interface_decl,
1813 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001814 SourceLocation(),
Greg Clayton9e409562010-07-28 02:04:09 +00001815 &identifier_table->get(name), // Identifier
1816 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1817 NULL, // TypeSourceInfo *
1818 ConvertAccessTypeToObjCIvarAccessControl (access),
1819 bit_width,
Greg Clayton0fffff52010-09-24 05:15:53 +00001820 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001821
1822 if (field)
1823 {
1824 class_interface_decl->addDecl(field);
1825 return true;
1826 }
Greg Clayton8cf05932010-07-22 18:30:50 +00001827 }
1828 }
1829 }
1830 return false;
1831}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001832
Greg Clayton9e409562010-07-28 02:04:09 +00001833
1834bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001835ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9e409562010-07-28 02:04:09 +00001836{
1837 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1838
Sean Callanan78e37602011-01-27 04:42:51 +00001839 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton9e409562010-07-28 02:04:09 +00001840 if (class_type)
1841 {
Sean Callanan78e37602011-01-27 04:42:51 +00001842 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001843
1844 if (objc_class_type)
1845 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1846 }
1847 return false;
1848}
1849
1850bool
1851ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1852{
1853 while (class_interface_decl)
1854 {
1855 if (class_interface_decl->ivar_size() > 0)
1856 return true;
1857
1858 if (check_superclass)
1859 class_interface_decl = class_interface_decl->getSuperClass();
1860 else
1861 break;
1862 }
1863 return false;
1864}
Greg Clayton0fffff52010-09-24 05:15:53 +00001865
Greg Clayton1be10fc2010-09-29 01:12:09 +00001866ObjCMethodDecl *
Greg Clayton0fffff52010-09-24 05:15:53 +00001867ClangASTContext::AddMethodToObjCObjectType
1868(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001869 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001870 clang_type_t class_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001871 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton1be10fc2010-09-29 01:12:09 +00001872 clang_type_t method_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001873 lldb::AccessType access
1874)
1875{
1876 if (class_opaque_type == NULL || method_opaque_type == NULL)
1877 return NULL;
1878
Greg Clayton6beaaa62011-01-17 03:46:26 +00001879 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton0fffff52010-09-24 05:15:53 +00001880
Greg Clayton6beaaa62011-01-17 03:46:26 +00001881 assert (ast != NULL);
Greg Clayton0fffff52010-09-24 05:15:53 +00001882 assert (identifier_table != NULL);
1883
1884 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1885
Sean Callanan78e37602011-01-27 04:42:51 +00001886 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton0fffff52010-09-24 05:15:53 +00001887 if (class_type == NULL)
1888 return NULL;
1889
Sean Callanan78e37602011-01-27 04:42:51 +00001890 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton0fffff52010-09-24 05:15:53 +00001891
1892 if (objc_class_type == NULL)
1893 return NULL;
1894
1895 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1896
1897 if (class_interface_decl == NULL)
1898 return NULL;
Greg Clayton9e409562010-07-28 02:04:09 +00001899
Greg Clayton0fffff52010-09-24 05:15:53 +00001900 const char *selector_start = ::strchr (name, ' ');
1901 if (selector_start == NULL)
1902 return NULL;
1903
1904 selector_start++;
1905 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1906 return NULL;
1907 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1908
Greg Clayton450e3f32010-10-12 02:24:53 +00001909 size_t len = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +00001910 const char *start;
Greg Clayton450e3f32010-10-12 02:24:53 +00001911 //printf ("name = '%s'\n", name);
1912
1913 unsigned num_selectors_with_args = 0;
1914 for (start = selector_start;
Greg Clayton0fffff52010-09-24 05:15:53 +00001915 start && *start != '\0' && *start != ']';
Greg Clayton450e3f32010-10-12 02:24:53 +00001916 start += len)
Greg Clayton0fffff52010-09-24 05:15:53 +00001917 {
Greg Clayton450e3f32010-10-12 02:24:53 +00001918 len = ::strcspn(start, ":]");
Greg Clayton90f90cd2010-10-27 04:01:14 +00001919 bool has_arg = (start[len] == ':');
1920 if (has_arg)
Greg Clayton450e3f32010-10-12 02:24:53 +00001921 ++num_selectors_with_args;
Greg Clayton0fffff52010-09-24 05:15:53 +00001922 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton90f90cd2010-10-27 04:01:14 +00001923 if (has_arg)
1924 len += 1;
Greg Clayton0fffff52010-09-24 05:15:53 +00001925 }
1926
1927
1928 if (selector_idents.size() == 0)
1929 return 0;
1930
Greg Clayton6beaaa62011-01-17 03:46:26 +00001931 clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton0fffff52010-09-24 05:15:53 +00001932 selector_idents.data());
1933
1934 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1935
1936 // Populate the method decl with parameter decls
Sean Callanan78e37602011-01-27 04:42:51 +00001937 const clang::Type *method_type(method_qual_type.getTypePtr());
Greg Clayton0fffff52010-09-24 05:15:53 +00001938
1939 if (method_type == NULL)
1940 return NULL;
1941
Sean Callanan78e37602011-01-27 04:42:51 +00001942 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001943
1944 if (!method_function_prototype)
1945 return NULL;
1946
1947
1948 bool is_variadic = false;
1949 bool is_synthesized = false;
1950 bool is_defined = false;
1951 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1952
1953 const unsigned num_args = method_function_prototype->getNumArgs();
1954
Greg Clayton6beaaa62011-01-17 03:46:26 +00001955 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001956 SourceLocation(), // beginLoc,
1957 SourceLocation(), // endLoc,
1958 method_selector,
1959 method_function_prototype->getResultType(),
1960 NULL, // TypeSourceInfo *ResultTInfo,
1961 GetDeclContextForType (class_opaque_type),
1962 name[0] == '-',
1963 is_variadic,
1964 is_synthesized,
1965 is_defined,
1966 imp_control,
1967 num_args);
1968
1969
1970 if (objc_method_decl == NULL)
1971 return NULL;
1972
1973 if (num_args > 0)
1974 {
1975 llvm::SmallVector<ParmVarDecl *, 12> params;
1976
1977 for (int param_index = 0; param_index < num_args; ++param_index)
1978 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001979 params.push_back (ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001980 objc_method_decl,
1981 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001982 SourceLocation(),
Greg Clayton0fffff52010-09-24 05:15:53 +00001983 NULL, // anonymous
1984 method_function_prototype->getArgType(param_index),
1985 NULL,
1986 SC_Auto,
1987 SC_Auto,
1988 NULL));
1989 }
1990
Greg Clayton6beaaa62011-01-17 03:46:26 +00001991 objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args);
Greg Clayton0fffff52010-09-24 05:15:53 +00001992 }
1993
1994 class_interface_decl->addDecl (objc_method_decl);
1995
1996
1997 return objc_method_decl;
1998}
1999
2000
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002001uint32_t
Greg Clayton73b472d2010-10-27 03:32:59 +00002002ClangASTContext::GetTypeInfo
2003(
2004 clang_type_t clang_type,
Greg Clayton6beaaa62011-01-17 03:46:26 +00002005 clang::ASTContext *ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002006 clang_type_t *pointee_or_element_clang_type
2007)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002008{
2009 if (clang_type == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00002010 return 0;
2011
2012 if (pointee_or_element_clang_type)
2013 *pointee_or_element_clang_type = NULL;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002014
2015 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2016
2017 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2018 switch (type_class)
2019 {
Sean Callanana2424172010-10-25 00:29:48 +00002020 case clang::Type::Builtin:
2021 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2022 {
Sean Callanana2424172010-10-25 00:29:48 +00002023 case clang::BuiltinType::ObjCId:
2024 case clang::BuiltinType::ObjCClass:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002025 if (ast && pointee_or_element_clang_type)
2026 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanana2424172010-10-25 00:29:48 +00002027 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002028
2029 default:
2030 break;
Sean Callanana2424172010-10-25 00:29:48 +00002031 }
2032 return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002033
2034 case clang::Type::BlockPointer:
2035 if (pointee_or_element_clang_type)
2036 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2037 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
2038
Greg Clayton49462ea2011-01-15 02:52:14 +00002039 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002040
2041 case clang::Type::ConstantArray:
2042 case clang::Type::DependentSizedArray:
2043 case clang::Type::IncompleteArray:
2044 case clang::Type::VariableArray:
2045 if (pointee_or_element_clang_type)
2046 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
2047 return eTypeHasChildren | eTypeIsArray;
2048
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002049 case clang::Type::DependentName: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002050 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
2051 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
2052 case clang::Type::Decltype: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002053
2054 case clang::Type::Enum:
2055 if (pointee_or_element_clang_type)
2056 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
2057 return eTypeIsEnumeration | eTypeHasValue;
2058
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002059 case clang::Type::Elaborated: return 0;
2060 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
2061 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
2062 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002063 case clang::Type::InjectedClassName: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002064
2065 case clang::Type::LValueReference:
2066 case clang::Type::RValueReference:
2067 if (pointee_or_element_clang_type)
2068 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
2069 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
2070
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002071 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002072
2073 case clang::Type::ObjCObjectPointer:
2074 if (pointee_or_element_clang_type)
2075 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2076 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
2077
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002078 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2079 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Clayton73b472d2010-10-27 03:32:59 +00002080
2081 case clang::Type::Pointer:
2082 if (pointee_or_element_clang_type)
2083 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2084 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
2085
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002086 case clang::Type::Record:
2087 if (qual_type->getAsCXXRecordDecl())
2088 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
2089 else
2090 return eTypeHasChildren | eTypeIsStructUnion;
2091 break;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002092 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
2093 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
2094 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Clayton73b472d2010-10-27 03:32:59 +00002095
2096 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002097 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00002098 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002099 pointee_or_element_clang_type);
2100
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002101 case clang::Type::TypeOfExpr: return 0;
2102 case clang::Type::TypeOf: return 0;
2103 case clang::Type::UnresolvedUsing: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002104 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
2105 default: return 0;
2106 }
2107 return 0;
2108}
2109
Greg Clayton9e409562010-07-28 02:04:09 +00002110
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002111#pragma mark Aggregate Types
2112
2113bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00002114ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002115{
2116 if (clang_type == NULL)
2117 return false;
2118
2119 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2120
Greg Clayton737b9322010-09-13 03:32:57 +00002121 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2122 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002123 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002124 case clang::Type::IncompleteArray:
2125 case clang::Type::VariableArray:
2126 case clang::Type::ConstantArray:
2127 case clang::Type::ExtVector:
2128 case clang::Type::Vector:
2129 case clang::Type::Record:
Greg Clayton9e409562010-07-28 02:04:09 +00002130 case clang::Type::ObjCObject:
2131 case clang::Type::ObjCInterface:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002132 return true;
2133
Greg Claytone1a916a2010-07-21 22:12:05 +00002134 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002135 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002136
2137 default:
2138 break;
2139 }
2140 // The clang type does have a value
2141 return false;
2142}
2143
2144uint32_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00002145ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002146{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002147 if (clang_type == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002148 return 0;
2149
2150 uint32_t num_children = 0;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002151 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00002152 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2153 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002154 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002155 case clang::Type::Builtin:
2156 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2157 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002158 case clang::BuiltinType::ObjCId: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002159 case clang::BuiltinType::ObjCClass: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002160 num_children = 1;
Greg Clayton73b472d2010-10-27 03:32:59 +00002161 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002162
2163 default:
2164 break;
2165 }
2166 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002167
Greg Clayton49462ea2011-01-15 02:52:14 +00002168 case clang::Type::Complex: return 0;
Greg Clayton54979cd2010-12-15 05:08:08 +00002169
Greg Claytone1a916a2010-07-21 22:12:05 +00002170 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002171 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002172 {
2173 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2174 const RecordDecl *record_decl = record_type->getDecl();
2175 assert(record_decl);
2176 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2177 if (cxx_record_decl)
2178 {
2179 if (omit_empty_base_classes)
2180 {
2181 // Check each base classes to see if it or any of its
2182 // base classes contain any fields. This can help
2183 // limit the noise in variable views by not having to
2184 // show base classes that contain no members.
2185 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2186 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2187 base_class != base_class_end;
2188 ++base_class)
2189 {
2190 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2191
2192 // Skip empty base classes
2193 if (RecordHasFields(base_class_decl) == false)
2194 continue;
2195
2196 num_children++;
2197 }
2198 }
2199 else
2200 {
2201 // Include all base classes
2202 num_children += cxx_record_decl->getNumBases();
2203 }
2204
2205 }
2206 RecordDecl::field_iterator field, field_end;
2207 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2208 ++num_children;
2209 }
2210 break;
2211
Greg Clayton9e409562010-07-28 02:04:09 +00002212 case clang::Type::ObjCObject:
2213 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002214 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002215 {
Sean Callanan78e37602011-01-27 04:42:51 +00002216 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002217 assert (objc_class_type);
2218 if (objc_class_type)
2219 {
2220 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2221
2222 if (class_interface_decl)
2223 {
2224
2225 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2226 if (superclass_interface_decl)
2227 {
2228 if (omit_empty_base_classes)
2229 {
2230 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2231 ++num_children;
2232 }
2233 else
2234 ++num_children;
2235 }
2236
2237 num_children += class_interface_decl->ivar_size();
2238 }
2239 }
2240 }
2241 break;
2242
2243 case clang::Type::ObjCObjectPointer:
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002244 {
Sean Callanan78e37602011-01-27 04:42:51 +00002245 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002246 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002247 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2248 pointee_type.getAsOpaquePtr(),
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002249 omit_empty_base_classes);
2250 // If this type points to a simple type, then it has 1 child
2251 if (num_pointee_children == 0)
2252 num_children = 1;
2253 else
2254 num_children = num_pointee_children;
2255 }
2256 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002257
Greg Claytone1a916a2010-07-21 22:12:05 +00002258 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002259 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2260 break;
2261
Greg Claytone1a916a2010-07-21 22:12:05 +00002262 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002263 {
Sean Callanan78e37602011-01-27 04:42:51 +00002264 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002265 QualType pointee_type (pointer_type->getPointeeType());
Greg Clayton6beaaa62011-01-17 03:46:26 +00002266 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2267 pointee_type.getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00002268 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002269 if (num_pointee_children == 0)
Greg Clayton54979cd2010-12-15 05:08:08 +00002270 {
2271 // We have a pointer to a pointee type that claims it has no children.
2272 // We will want to look at
2273 num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
2274 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002275 else
2276 num_children = num_pointee_children;
2277 }
2278 break;
2279
Greg Clayton73b472d2010-10-27 03:32:59 +00002280 case clang::Type::LValueReference:
2281 case clang::Type::RValueReference:
2282 {
Sean Callanan78e37602011-01-27 04:42:51 +00002283 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002284 QualType pointee_type = reference_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002285 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2286 pointee_type.getAsOpaquePtr(),
Greg Clayton73b472d2010-10-27 03:32:59 +00002287 omit_empty_base_classes);
2288 // If this type points to a simple type, then it has 1 child
2289 if (num_pointee_children == 0)
2290 num_children = 1;
2291 else
2292 num_children = num_pointee_children;
2293 }
2294 break;
2295
2296
Greg Claytone1a916a2010-07-21 22:12:05 +00002297 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002298 num_children = ClangASTContext::GetNumChildren (ast,
2299 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2300 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002301 break;
2302
2303 default:
2304 break;
2305 }
2306 return num_children;
2307}
2308
Greg Clayton54979cd2010-12-15 05:08:08 +00002309// If a pointer to a pointee type (the clang_type arg) says that it has no
2310// children, then we either need to trust it, or override it and return a
2311// different result. For example, an "int *" has one child that is an integer,
2312// but a function pointer doesn't have any children. Likewise if a Record type
2313// claims it has no children, then there really is nothing to show.
2314uint32_t
2315ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
2316{
2317 if (clang_type == NULL)
2318 return 0;
2319
2320 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2321 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2322 switch (type_class)
2323 {
Greg Clayton97a43712011-01-08 22:26:47 +00002324 case clang::Type::Builtin:
2325 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2326 {
Greg Clayton7260f622011-04-18 08:33:37 +00002327 case clang::BuiltinType::UnknownAny:
Greg Clayton97a43712011-01-08 22:26:47 +00002328 case clang::BuiltinType::Void:
2329 case clang::BuiltinType::NullPtr:
2330 return 0;
2331 case clang::BuiltinType::Bool:
2332 case clang::BuiltinType::Char_U:
2333 case clang::BuiltinType::UChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002334 case clang::BuiltinType::WChar_U:
Greg Clayton97a43712011-01-08 22:26:47 +00002335 case clang::BuiltinType::Char16:
2336 case clang::BuiltinType::Char32:
2337 case clang::BuiltinType::UShort:
2338 case clang::BuiltinType::UInt:
2339 case clang::BuiltinType::ULong:
2340 case clang::BuiltinType::ULongLong:
2341 case clang::BuiltinType::UInt128:
2342 case clang::BuiltinType::Char_S:
2343 case clang::BuiltinType::SChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002344 case clang::BuiltinType::WChar_S:
Greg Clayton97a43712011-01-08 22:26:47 +00002345 case clang::BuiltinType::Short:
2346 case clang::BuiltinType::Int:
2347 case clang::BuiltinType::Long:
2348 case clang::BuiltinType::LongLong:
2349 case clang::BuiltinType::Int128:
2350 case clang::BuiltinType::Float:
2351 case clang::BuiltinType::Double:
2352 case clang::BuiltinType::LongDouble:
2353 case clang::BuiltinType::Dependent:
2354 case clang::BuiltinType::Overload:
Greg Clayton97a43712011-01-08 22:26:47 +00002355 case clang::BuiltinType::ObjCId:
2356 case clang::BuiltinType::ObjCClass:
2357 case clang::BuiltinType::ObjCSel:
Sean Callanand12cf8bb2011-05-15 22:34:38 +00002358 case clang::BuiltinType::BoundMember:
Greg Clayton97a43712011-01-08 22:26:47 +00002359 return 1;
2360 }
2361 break;
2362
Greg Clayton49462ea2011-01-15 02:52:14 +00002363 case clang::Type::Complex: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00002364 case clang::Type::Pointer: return 1;
2365 case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
2366 case clang::Type::LValueReference: return 1;
2367 case clang::Type::RValueReference: return 1;
2368 case clang::Type::MemberPointer: return 0;
2369 case clang::Type::ConstantArray: return 0;
2370 case clang::Type::IncompleteArray: return 0;
2371 case clang::Type::VariableArray: return 0;
2372 case clang::Type::DependentSizedArray: return 0;
2373 case clang::Type::DependentSizedExtVector: return 0;
2374 case clang::Type::Vector: return 0;
2375 case clang::Type::ExtVector: return 0;
2376 case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
2377 case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
2378 case clang::Type::UnresolvedUsing: return 0;
2379 case clang::Type::Paren: return 0;
2380 case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2381 case clang::Type::TypeOfExpr: return 0;
2382 case clang::Type::TypeOf: return 0;
2383 case clang::Type::Decltype: return 0;
2384 case clang::Type::Record: return 0;
2385 case clang::Type::Enum: return 1;
2386 case clang::Type::Elaborated: return 1;
2387 case clang::Type::TemplateTypeParm: return 1;
2388 case clang::Type::SubstTemplateTypeParm: return 1;
2389 case clang::Type::TemplateSpecialization: return 1;
2390 case clang::Type::InjectedClassName: return 0;
2391 case clang::Type::DependentName: return 1;
2392 case clang::Type::DependentTemplateSpecialization: return 1;
2393 case clang::Type::ObjCObject: return 0;
2394 case clang::Type::ObjCInterface: return 0;
2395 case clang::Type::ObjCObjectPointer: return 1;
2396 default:
2397 break;
2398 }
2399 return 0;
2400}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002401
Greg Clayton1be10fc2010-09-29 01:12:09 +00002402clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002403ClangASTContext::GetChildClangTypeAtIndex
2404(
2405 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002406 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002407 uint32_t idx,
2408 bool transparent_pointers,
2409 bool omit_empty_base_classes,
2410 std::string& child_name,
2411 uint32_t &child_byte_size,
2412 int32_t &child_byte_offset,
2413 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002414 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002415 bool &child_is_base_class,
2416 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002417)
2418{
2419 if (parent_clang_type)
2420
2421 return GetChildClangTypeAtIndex (getASTContext(),
2422 parent_name,
2423 parent_clang_type,
2424 idx,
2425 transparent_pointers,
2426 omit_empty_base_classes,
2427 child_name,
2428 child_byte_size,
2429 child_byte_offset,
2430 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002431 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002432 child_is_base_class,
2433 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002434 return NULL;
2435}
2436
Greg Clayton1be10fc2010-09-29 01:12:09 +00002437clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002438ClangASTContext::GetChildClangTypeAtIndex
2439(
Greg Clayton6beaaa62011-01-17 03:46:26 +00002440 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002441 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002442 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002443 uint32_t idx,
2444 bool transparent_pointers,
2445 bool omit_empty_base_classes,
2446 std::string& child_name,
2447 uint32_t &child_byte_size,
2448 int32_t &child_byte_offset,
2449 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002450 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002451 bool &child_is_base_class,
2452 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002453)
2454{
2455 if (parent_clang_type == NULL)
2456 return NULL;
2457
Greg Clayton6beaaa62011-01-17 03:46:26 +00002458 if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002459 {
2460 uint32_t bit_offset;
2461 child_bitfield_bit_size = 0;
2462 child_bitfield_bit_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002463 child_is_base_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002464 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00002465 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2466 switch (parent_type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002467 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002468 case clang::Type::Builtin:
2469 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2470 {
2471 case clang::BuiltinType::ObjCId:
2472 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00002473 child_name = "isa";
Greg Clayton6beaaa62011-01-17 03:46:26 +00002474 child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
2475 return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002476
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002477 default:
2478 break;
2479 }
2480 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002481
Greg Claytone1a916a2010-07-21 22:12:05 +00002482 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002483 if (GetCompleteQualType (ast, parent_qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002484 {
2485 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2486 const RecordDecl *record_decl = record_type->getDecl();
2487 assert(record_decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00002488 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002489 uint32_t child_idx = 0;
2490
2491 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2492 if (cxx_record_decl)
2493 {
2494 // We might have base classes to print out first
2495 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2496 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2497 base_class != base_class_end;
2498 ++base_class)
2499 {
2500 const CXXRecordDecl *base_class_decl = NULL;
2501
2502 // Skip empty base classes
2503 if (omit_empty_base_classes)
2504 {
2505 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2506 if (RecordHasFields(base_class_decl) == false)
2507 continue;
2508 }
2509
2510 if (idx == child_idx)
2511 {
2512 if (base_class_decl == NULL)
2513 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2514
2515
2516 if (base_class->isVirtual())
Greg Clayton6ed95942011-01-22 07:12:45 +00002517 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002518 else
Greg Clayton6ed95942011-01-22 07:12:45 +00002519 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002520
2521 // Base classes should be a multiple of 8 bits in size
2522 assert (bit_offset % 8 == 0);
2523 child_byte_offset = bit_offset/8;
2524 std::string base_class_type_name(base_class->getType().getAsString());
2525
2526 child_name.assign(base_class_type_name.c_str());
2527
Greg Clayton6beaaa62011-01-17 03:46:26 +00002528 uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002529
Jim Inghamf46b3382011-04-15 23:42:06 +00002530 // Base classes bit sizes should be a multiple of 8 bits in size
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002531 assert (clang_type_info_bit_size % 8 == 0);
2532 child_byte_size = clang_type_info_bit_size / 8;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002533 child_is_base_class = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002534 return base_class->getType().getAsOpaquePtr();
2535 }
2536 // We don't increment the child index in the for loop since we might
2537 // be skipping empty base classes
2538 ++child_idx;
2539 }
2540 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002541 // Make sure index is in range...
2542 uint32_t field_idx = 0;
2543 RecordDecl::field_iterator field, field_end;
2544 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2545 {
2546 if (idx == child_idx)
2547 {
2548 // Print the member type if requested
2549 // Print the member name and equal sign
2550 child_name.assign(field->getNameAsString().c_str());
2551
2552 // Figure out the type byte size (field_type_info.first) and
2553 // alignment (field_type_info.second) from the AST context.
Greg Clayton6beaaa62011-01-17 03:46:26 +00002554 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
Greg Claytonc982c762010-07-09 20:39:50 +00002555 assert(field_idx < record_layout.getFieldCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002556
2557 child_byte_size = field_type_info.first / 8;
2558
2559 // Figure out the field offset within the current struct/union/class type
2560 bit_offset = record_layout.getFieldOffset (field_idx);
2561 child_byte_offset = bit_offset / 8;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002562 if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002563 child_bitfield_bit_offset = bit_offset % 8;
2564
2565 return field->getType().getAsOpaquePtr();
2566 }
2567 }
2568 }
2569 break;
2570
Greg Clayton9e409562010-07-28 02:04:09 +00002571 case clang::Type::ObjCObject:
2572 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002573 if (GetCompleteQualType (ast, parent_qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002574 {
Sean Callanan78e37602011-01-27 04:42:51 +00002575 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002576 assert (objc_class_type);
2577 if (objc_class_type)
2578 {
2579 uint32_t child_idx = 0;
2580 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2581
2582 if (class_interface_decl)
2583 {
2584
Greg Clayton6beaaa62011-01-17 03:46:26 +00002585 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
Greg Clayton9e409562010-07-28 02:04:09 +00002586 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2587 if (superclass_interface_decl)
2588 {
2589 if (omit_empty_base_classes)
2590 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002591 if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9e409562010-07-28 02:04:09 +00002592 {
2593 if (idx == 0)
2594 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002595 QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
Greg Clayton9e409562010-07-28 02:04:09 +00002596
2597
2598 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2599
Greg Clayton6beaaa62011-01-17 03:46:26 +00002600 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002601
2602 child_byte_size = ivar_type_info.first / 8;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002603 child_byte_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002604 child_is_base_class = true;
Greg Clayton9e409562010-07-28 02:04:09 +00002605
2606 return ivar_qual_type.getAsOpaquePtr();
2607 }
2608
2609 ++child_idx;
2610 }
2611 }
2612 else
2613 ++child_idx;
2614 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002615
2616 const uint32_t superclass_idx = child_idx;
Greg Clayton9e409562010-07-28 02:04:09 +00002617
2618 if (idx < (child_idx + class_interface_decl->ivar_size()))
2619 {
2620 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2621
2622 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2623 {
2624 if (child_idx == idx)
2625 {
2626 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2627
2628 QualType ivar_qual_type(ivar_decl->getType());
2629
2630 child_name.assign(ivar_decl->getNameAsString().c_str());
2631
Greg Clayton6beaaa62011-01-17 03:46:26 +00002632 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002633
2634 child_byte_size = ivar_type_info.first / 8;
2635
2636 // Figure out the field offset within the current struct/union/class type
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002637 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9e409562010-07-28 02:04:09 +00002638 child_byte_offset = bit_offset / 8;
2639
2640 return ivar_qual_type.getAsOpaquePtr();
2641 }
2642 ++child_idx;
2643 }
2644 }
2645 }
2646 }
2647 }
2648 break;
2649
2650 case clang::Type::ObjCObjectPointer:
2651 {
Sean Callanan78e37602011-01-27 04:42:51 +00002652 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002653 QualType pointee_type = pointer_type->getPointeeType();
2654
2655 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2656 {
Greg Claytone221f822011-01-21 01:59:00 +00002657 child_is_deref_of_parent = false;
2658 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002659 return GetChildClangTypeAtIndex (ast,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002660 parent_name,
2661 pointer_type->getPointeeType().getAsOpaquePtr(),
2662 idx,
2663 transparent_pointers,
2664 omit_empty_base_classes,
2665 child_name,
2666 child_byte_size,
2667 child_byte_offset,
2668 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002669 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002670 child_is_base_class,
2671 tmp_child_is_deref_of_parent);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002672 }
2673 else
2674 {
Greg Claytone221f822011-01-21 01:59:00 +00002675 child_is_deref_of_parent = true;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002676 if (parent_name)
2677 {
2678 child_name.assign(1, '*');
2679 child_name += parent_name;
2680 }
2681
2682 // We have a pointer to an simple type
2683 if (idx == 0)
2684 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002685 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002686 assert(clang_type_info.first % 8 == 0);
2687 child_byte_size = clang_type_info.first / 8;
2688 child_byte_offset = 0;
2689 return pointee_type.getAsOpaquePtr();
2690 }
2691 }
Greg Clayton9e409562010-07-28 02:04:09 +00002692 }
2693 break;
2694
Greg Claytone1a916a2010-07-21 22:12:05 +00002695 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002696 {
2697 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2698 const uint64_t element_count = array->getSize().getLimitedValue();
2699
2700 if (idx < element_count)
2701 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002702 if (GetCompleteQualType (ast, array->getElementType()))
2703 {
2704 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002705
Greg Clayton6beaaa62011-01-17 03:46:26 +00002706 char element_name[64];
2707 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002708
Greg Clayton6beaaa62011-01-17 03:46:26 +00002709 child_name.assign(element_name);
2710 assert(field_type_info.first % 8 == 0);
2711 child_byte_size = field_type_info.first / 8;
2712 child_byte_offset = idx * child_byte_size;
2713 return array->getElementType().getAsOpaquePtr();
2714 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002715 }
2716 }
2717 break;
2718
Greg Claytone1a916a2010-07-21 22:12:05 +00002719 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002720 {
Sean Callanan78e37602011-01-27 04:42:51 +00002721 const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002722 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton97a43712011-01-08 22:26:47 +00002723
2724 // Don't dereference "void *" pointers
2725 if (pointee_type->isVoidType())
2726 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002727
2728 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2729 {
Greg Claytone221f822011-01-21 01:59:00 +00002730 child_is_deref_of_parent = false;
2731 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002732 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002733 parent_name,
2734 pointer_type->getPointeeType().getAsOpaquePtr(),
2735 idx,
2736 transparent_pointers,
2737 omit_empty_base_classes,
2738 child_name,
2739 child_byte_size,
2740 child_byte_offset,
2741 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002742 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002743 child_is_base_class,
2744 tmp_child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002745 }
2746 else
2747 {
Greg Claytone221f822011-01-21 01:59:00 +00002748 child_is_deref_of_parent = true;
2749
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002750 if (parent_name)
2751 {
2752 child_name.assign(1, '*');
2753 child_name += parent_name;
2754 }
2755
2756 // We have a pointer to an simple type
2757 if (idx == 0)
2758 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002759 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002760 assert(clang_type_info.first % 8 == 0);
2761 child_byte_size = clang_type_info.first / 8;
2762 child_byte_offset = 0;
2763 return pointee_type.getAsOpaquePtr();
2764 }
2765 }
2766 }
2767 break;
2768
Greg Clayton73b472d2010-10-27 03:32:59 +00002769 case clang::Type::LValueReference:
2770 case clang::Type::RValueReference:
2771 {
Sean Callanan78e37602011-01-27 04:42:51 +00002772 const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002773 QualType pointee_type(reference_type->getPointeeType());
2774 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2775 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2776 {
Greg Claytone221f822011-01-21 01:59:00 +00002777 child_is_deref_of_parent = false;
2778 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002779 return GetChildClangTypeAtIndex (ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002780 parent_name,
2781 pointee_clang_type,
2782 idx,
2783 transparent_pointers,
2784 omit_empty_base_classes,
2785 child_name,
2786 child_byte_size,
2787 child_byte_offset,
2788 child_bitfield_bit_size,
2789 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002790 child_is_base_class,
2791 tmp_child_is_deref_of_parent);
Greg Clayton73b472d2010-10-27 03:32:59 +00002792 }
2793 else
2794 {
2795 if (parent_name)
2796 {
2797 child_name.assign(1, '&');
2798 child_name += parent_name;
2799 }
2800
2801 // We have a pointer to an simple type
2802 if (idx == 0)
2803 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002804 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Clayton73b472d2010-10-27 03:32:59 +00002805 assert(clang_type_info.first % 8 == 0);
2806 child_byte_size = clang_type_info.first / 8;
2807 child_byte_offset = 0;
2808 return pointee_type.getAsOpaquePtr();
2809 }
2810 }
2811 }
2812 break;
2813
Greg Claytone1a916a2010-07-21 22:12:05 +00002814 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002815 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002816 parent_name,
Sean Callanan48114472010-12-13 01:26:27 +00002817 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002818 idx,
2819 transparent_pointers,
2820 omit_empty_base_classes,
2821 child_name,
2822 child_byte_size,
2823 child_byte_offset,
2824 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002825 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002826 child_is_base_class,
2827 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002828 break;
2829
2830 default:
2831 break;
2832 }
2833 }
Greg Clayton19503a22010-07-23 15:37:46 +00002834 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002835}
2836
2837static inline bool
2838BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2839{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002840 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002841}
2842
2843static uint32_t
2844GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2845{
2846 uint32_t num_bases = 0;
2847 if (cxx_record_decl)
2848 {
2849 if (omit_empty_base_classes)
2850 {
2851 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2852 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2853 base_class != base_class_end;
2854 ++base_class)
2855 {
2856 // Skip empty base classes
2857 if (omit_empty_base_classes)
2858 {
2859 if (BaseSpecifierIsEmpty (base_class))
2860 continue;
2861 }
2862 ++num_bases;
2863 }
2864 }
2865 else
2866 num_bases = cxx_record_decl->getNumBases();
2867 }
2868 return num_bases;
2869}
2870
2871
2872static uint32_t
2873GetIndexForRecordBase
2874(
2875 const RecordDecl *record_decl,
2876 const CXXBaseSpecifier *base_spec,
2877 bool omit_empty_base_classes
2878)
2879{
2880 uint32_t child_idx = 0;
2881
2882 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2883
2884// const char *super_name = record_decl->getNameAsCString();
2885// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2886// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2887//
2888 if (cxx_record_decl)
2889 {
2890 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2891 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2892 base_class != base_class_end;
2893 ++base_class)
2894 {
2895 if (omit_empty_base_classes)
2896 {
2897 if (BaseSpecifierIsEmpty (base_class))
2898 continue;
2899 }
2900
2901// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2902// child_idx,
2903// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2904//
2905//
2906 if (base_class == base_spec)
2907 return child_idx;
2908 ++child_idx;
2909 }
2910 }
2911
2912 return UINT32_MAX;
2913}
2914
2915
2916static uint32_t
2917GetIndexForRecordChild
2918(
2919 const RecordDecl *record_decl,
2920 NamedDecl *canonical_decl,
2921 bool omit_empty_base_classes
2922)
2923{
2924 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2925
2926// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2927//
2928//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2929// if (cxx_record_decl)
2930// {
2931// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2932// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2933// base_class != base_class_end;
2934// ++base_class)
2935// {
2936// if (omit_empty_base_classes)
2937// {
2938// if (BaseSpecifierIsEmpty (base_class))
2939// continue;
2940// }
2941//
2942//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2943//// record_decl->getNameAsCString(),
2944//// canonical_decl->getNameAsCString(),
2945//// child_idx,
2946//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2947//
2948//
2949// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2950// if (curr_base_class_decl == canonical_decl)
2951// {
2952// return child_idx;
2953// }
2954// ++child_idx;
2955// }
2956// }
2957//
2958// const uint32_t num_bases = child_idx;
2959 RecordDecl::field_iterator field, field_end;
2960 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2961 field != field_end;
2962 ++field, ++child_idx)
2963 {
2964// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2965// record_decl->getNameAsCString(),
2966// canonical_decl->getNameAsCString(),
2967// child_idx - num_bases,
2968// field->getNameAsCString());
2969
2970 if (field->getCanonicalDecl() == canonical_decl)
2971 return child_idx;
2972 }
2973
2974 return UINT32_MAX;
2975}
2976
2977// Look for a child member (doesn't include base classes, but it does include
2978// their members) in the type hierarchy. Returns an index path into "clang_type"
2979// on how to reach the appropriate member.
2980//
2981// class A
2982// {
2983// public:
2984// int m_a;
2985// int m_b;
2986// };
2987//
2988// class B
2989// {
2990// };
2991//
2992// class C :
2993// public B,
2994// public A
2995// {
2996// };
2997//
2998// If we have a clang type that describes "class C", and we wanted to looked
2999// "m_b" in it:
3000//
3001// With omit_empty_base_classes == false we would get an integer array back with:
3002// { 1, 1 }
3003// The first index 1 is the child index for "class A" within class C
3004// The second index 1 is the child index for "m_b" within class A
3005//
3006// With omit_empty_base_classes == true we would get an integer array back with:
3007// { 0, 1 }
3008// 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)
3009// The second index 1 is the child index for "m_b" within class A
3010
3011size_t
3012ClangASTContext::GetIndexOfChildMemberWithName
3013(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003014 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003015 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003016 const char *name,
3017 bool omit_empty_base_classes,
3018 std::vector<uint32_t>& child_indexes
3019)
3020{
3021 if (clang_type && name && name[0])
3022 {
3023 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003024 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3025 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003026 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003027 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003028 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003029 {
3030 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3031 const RecordDecl *record_decl = record_type->getDecl();
3032
3033 assert(record_decl);
3034 uint32_t child_idx = 0;
3035
3036 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3037
3038 // Try and find a field that matches NAME
3039 RecordDecl::field_iterator field, field_end;
3040 StringRef name_sref(name);
3041 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3042 field != field_end;
3043 ++field, ++child_idx)
3044 {
3045 if (field->getName().equals (name_sref))
3046 {
3047 // We have to add on the number of base classes to this index!
3048 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
3049 return child_indexes.size();
3050 }
3051 }
3052
3053 if (cxx_record_decl)
3054 {
3055 const RecordDecl *parent_record_decl = cxx_record_decl;
3056
3057 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
3058
3059 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
3060 // Didn't find things easily, lets let clang do its thang...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003061 IdentifierInfo & ident_ref = ast->Idents.get(name, name + strlen (name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003062 DeclarationName decl_name(&ident_ref);
3063
3064 CXXBasePaths paths;
3065 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
3066 decl_name.getAsOpaquePtr(),
3067 paths))
3068 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003069 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
3070 for (path = paths.begin(); path != path_end; ++path)
3071 {
3072 const size_t num_path_elements = path->size();
3073 for (size_t e=0; e<num_path_elements; ++e)
3074 {
3075 CXXBasePathElement elem = (*path)[e];
3076
3077 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
3078 if (child_idx == UINT32_MAX)
3079 {
3080 child_indexes.clear();
3081 return 0;
3082 }
3083 else
3084 {
3085 child_indexes.push_back (child_idx);
3086 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
3087 }
3088 }
3089 DeclContext::lookup_iterator named_decl_pos;
3090 for (named_decl_pos = path->Decls.first;
3091 named_decl_pos != path->Decls.second && parent_record_decl;
3092 ++named_decl_pos)
3093 {
3094 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
3095
3096 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
3097 if (child_idx == UINT32_MAX)
3098 {
3099 child_indexes.clear();
3100 return 0;
3101 }
3102 else
3103 {
3104 child_indexes.push_back (child_idx);
3105 }
3106 }
3107 }
3108 return child_indexes.size();
3109 }
3110 }
3111
3112 }
3113 break;
3114
Greg Clayton9e409562010-07-28 02:04:09 +00003115 case clang::Type::ObjCObject:
3116 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003117 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003118 {
3119 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003120 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003121 assert (objc_class_type);
3122 if (objc_class_type)
3123 {
3124 uint32_t child_idx = 0;
3125 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3126
3127 if (class_interface_decl)
3128 {
3129 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3130 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3131
Greg Clayton6ba78152010-09-18 02:11:07 +00003132 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9e409562010-07-28 02:04:09 +00003133 {
3134 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3135
3136 if (ivar_decl->getName().equals (name_sref))
3137 {
3138 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3139 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3140 ++child_idx;
3141
3142 child_indexes.push_back (child_idx);
3143 return child_indexes.size();
3144 }
3145 }
3146
3147 if (superclass_interface_decl)
3148 {
3149 // The super class index is always zero for ObjC classes,
3150 // so we push it onto the child indexes in case we find
3151 // an ivar in our superclass...
3152 child_indexes.push_back (0);
3153
Greg Clayton6beaaa62011-01-17 03:46:26 +00003154 if (GetIndexOfChildMemberWithName (ast,
3155 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00003156 name,
3157 omit_empty_base_classes,
3158 child_indexes))
3159 {
3160 // We did find an ivar in a superclass so just
3161 // return the results!
3162 return child_indexes.size();
3163 }
3164
3165 // We didn't find an ivar matching "name" in our
3166 // superclass, pop the superclass zero index that
3167 // we pushed on above.
3168 child_indexes.pop_back();
3169 }
3170 }
3171 }
3172 }
3173 break;
3174
3175 case clang::Type::ObjCObjectPointer:
3176 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003177 return GetIndexOfChildMemberWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003178 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3179 name,
3180 omit_empty_base_classes,
3181 child_indexes);
3182 }
3183 break;
3184
3185
Greg Claytone1a916a2010-07-21 22:12:05 +00003186 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003187 {
3188// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3189// const uint64_t element_count = array->getSize().getLimitedValue();
3190//
3191// if (idx < element_count)
3192// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003193// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003194//
3195// char element_name[32];
3196// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3197//
3198// child_name.assign(element_name);
3199// assert(field_type_info.first % 8 == 0);
3200// child_byte_size = field_type_info.first / 8;
3201// child_byte_offset = idx * child_byte_size;
3202// return array->getElementType().getAsOpaquePtr();
3203// }
3204 }
3205 break;
3206
Greg Claytone1a916a2010-07-21 22:12:05 +00003207// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003208// {
3209// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3210// QualType pointee_type = mem_ptr_type->getPointeeType();
3211//
3212// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3213// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003214// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003215// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3216// name);
3217// }
3218// }
3219// break;
3220//
Greg Claytone1a916a2010-07-21 22:12:05 +00003221 case clang::Type::LValueReference:
3222 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003223 {
Sean Callanan78e37602011-01-27 04:42:51 +00003224 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003225 QualType pointee_type = reference_type->getPointeeType();
3226
3227 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3228 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003229 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003230 reference_type->getPointeeType().getAsOpaquePtr(),
3231 name,
3232 omit_empty_base_classes,
3233 child_indexes);
3234 }
3235 }
3236 break;
3237
Greg Claytone1a916a2010-07-21 22:12:05 +00003238 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003239 {
Sean Callanan78e37602011-01-27 04:42:51 +00003240 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003241 QualType pointee_type = pointer_type->getPointeeType();
3242
3243 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3244 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003245 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003246 pointer_type->getPointeeType().getAsOpaquePtr(),
3247 name,
3248 omit_empty_base_classes,
3249 child_indexes);
3250 }
3251 else
3252 {
3253// if (parent_name)
3254// {
3255// child_name.assign(1, '*');
3256// child_name += parent_name;
3257// }
3258//
3259// // We have a pointer to an simple type
3260// if (idx == 0)
3261// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003262// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003263// assert(clang_type_info.first % 8 == 0);
3264// child_byte_size = clang_type_info.first / 8;
3265// child_byte_offset = 0;
3266// return pointee_type.getAsOpaquePtr();
3267// }
3268 }
3269 }
3270 break;
3271
Greg Claytone1a916a2010-07-21 22:12:05 +00003272 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003273 return GetIndexOfChildMemberWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003274 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003275 name,
3276 omit_empty_base_classes,
3277 child_indexes);
3278
3279 default:
3280 break;
3281 }
3282 }
3283 return 0;
3284}
3285
3286
3287// Get the index of the child of "clang_type" whose name matches. This function
3288// doesn't descend into the children, but only looks one level deep and name
3289// matches can include base class names.
3290
3291uint32_t
3292ClangASTContext::GetIndexOfChildWithName
3293(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003294 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003295 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003296 const char *name,
3297 bool omit_empty_base_classes
3298)
3299{
3300 if (clang_type && name && name[0])
3301 {
3302 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00003303
Greg Clayton737b9322010-09-13 03:32:57 +00003304 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9e409562010-07-28 02:04:09 +00003305
Greg Clayton737b9322010-09-13 03:32:57 +00003306 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003307 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003308 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003309 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003310 {
3311 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3312 const RecordDecl *record_decl = record_type->getDecl();
3313
3314 assert(record_decl);
3315 uint32_t child_idx = 0;
3316
3317 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3318
3319 if (cxx_record_decl)
3320 {
3321 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3322 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3323 base_class != base_class_end;
3324 ++base_class)
3325 {
3326 // Skip empty base classes
3327 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3328 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3329 continue;
3330
3331 if (base_class->getType().getAsString().compare (name) == 0)
3332 return child_idx;
3333 ++child_idx;
3334 }
3335 }
3336
3337 // Try and find a field that matches NAME
3338 RecordDecl::field_iterator field, field_end;
3339 StringRef name_sref(name);
3340 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3341 field != field_end;
3342 ++field, ++child_idx)
3343 {
3344 if (field->getName().equals (name_sref))
3345 return child_idx;
3346 }
3347
3348 }
3349 break;
3350
Greg Clayton9e409562010-07-28 02:04:09 +00003351 case clang::Type::ObjCObject:
3352 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003353 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003354 {
3355 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003356 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003357 assert (objc_class_type);
3358 if (objc_class_type)
3359 {
3360 uint32_t child_idx = 0;
3361 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3362
3363 if (class_interface_decl)
3364 {
3365 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3366 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3367
3368 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3369 {
3370 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3371
3372 if (ivar_decl->getName().equals (name_sref))
3373 {
3374 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3375 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3376 ++child_idx;
3377
3378 return child_idx;
3379 }
3380 }
3381
3382 if (superclass_interface_decl)
3383 {
3384 if (superclass_interface_decl->getName().equals (name_sref))
3385 return 0;
3386 }
3387 }
3388 }
3389 }
3390 break;
3391
3392 case clang::Type::ObjCObjectPointer:
3393 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003394 return GetIndexOfChildWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003395 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3396 name,
3397 omit_empty_base_classes);
3398 }
3399 break;
3400
Greg Claytone1a916a2010-07-21 22:12:05 +00003401 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003402 {
3403// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3404// const uint64_t element_count = array->getSize().getLimitedValue();
3405//
3406// if (idx < element_count)
3407// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003408// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003409//
3410// char element_name[32];
3411// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3412//
3413// child_name.assign(element_name);
3414// assert(field_type_info.first % 8 == 0);
3415// child_byte_size = field_type_info.first / 8;
3416// child_byte_offset = idx * child_byte_size;
3417// return array->getElementType().getAsOpaquePtr();
3418// }
3419 }
3420 break;
3421
Greg Claytone1a916a2010-07-21 22:12:05 +00003422// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003423// {
3424// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3425// QualType pointee_type = mem_ptr_type->getPointeeType();
3426//
3427// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3428// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003429// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003430// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3431// name);
3432// }
3433// }
3434// break;
3435//
Greg Claytone1a916a2010-07-21 22:12:05 +00003436 case clang::Type::LValueReference:
3437 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003438 {
Sean Callanan78e37602011-01-27 04:42:51 +00003439 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003440 QualType pointee_type = reference_type->getPointeeType();
3441
3442 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3443 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003444 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003445 reference_type->getPointeeType().getAsOpaquePtr(),
3446 name,
3447 omit_empty_base_classes);
3448 }
3449 }
3450 break;
3451
Greg Claytone1a916a2010-07-21 22:12:05 +00003452 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003453 {
Sean Callanan78e37602011-01-27 04:42:51 +00003454 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003455 QualType pointee_type = pointer_type->getPointeeType();
3456
3457 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3458 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003459 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003460 pointer_type->getPointeeType().getAsOpaquePtr(),
3461 name,
3462 omit_empty_base_classes);
3463 }
3464 else
3465 {
3466// if (parent_name)
3467// {
3468// child_name.assign(1, '*');
3469// child_name += parent_name;
3470// }
3471//
3472// // We have a pointer to an simple type
3473// if (idx == 0)
3474// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003475// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003476// assert(clang_type_info.first % 8 == 0);
3477// child_byte_size = clang_type_info.first / 8;
3478// child_byte_offset = 0;
3479// return pointee_type.getAsOpaquePtr();
3480// }
3481 }
3482 }
3483 break;
3484
Greg Claytone1a916a2010-07-21 22:12:05 +00003485 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003486 return GetIndexOfChildWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003487 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003488 name,
3489 omit_empty_base_classes);
3490
3491 default:
3492 break;
3493 }
3494 }
3495 return UINT32_MAX;
3496}
3497
3498#pragma mark TagType
3499
3500bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003501ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003502{
3503 if (tag_clang_type)
3504 {
3505 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00003506 const clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003507 if (clang_type)
3508 {
Sean Callanan78e37602011-01-27 04:42:51 +00003509 const TagType *tag_type = dyn_cast<TagType>(clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003510 if (tag_type)
3511 {
3512 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3513 if (tag_decl)
3514 {
3515 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3516 return true;
3517 }
3518 }
3519 }
3520 }
3521 return false;
3522}
3523
3524
3525#pragma mark DeclContext Functions
3526
3527DeclContext *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003528ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003529{
3530 if (clang_type == NULL)
3531 return NULL;
3532
3533 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003534 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3535 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003536 {
Greg Clayton9e409562010-07-28 02:04:09 +00003537 case clang::Type::FunctionNoProto: break;
3538 case clang::Type::FunctionProto: break;
3539 case clang::Type::IncompleteArray: break;
3540 case clang::Type::VariableArray: break;
3541 case clang::Type::ConstantArray: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003542 case clang::Type::DependentSizedArray: break;
Greg Clayton9e409562010-07-28 02:04:09 +00003543 case clang::Type::ExtVector: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003544 case clang::Type::DependentSizedExtVector: break;
Greg Clayton9e409562010-07-28 02:04:09 +00003545 case clang::Type::Vector: break;
3546 case clang::Type::Builtin: break;
3547 case clang::Type::BlockPointer: break;
3548 case clang::Type::Pointer: break;
3549 case clang::Type::LValueReference: break;
3550 case clang::Type::RValueReference: break;
3551 case clang::Type::MemberPointer: break;
3552 case clang::Type::Complex: break;
3553 case clang::Type::ObjCObject: break;
3554 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3555 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3556 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3557 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
Sean Callanan48114472010-12-13 01:26:27 +00003558 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003559
Greg Clayton9e409562010-07-28 02:04:09 +00003560 case clang::Type::TypeOfExpr: break;
3561 case clang::Type::TypeOf: break;
3562 case clang::Type::Decltype: break;
3563 //case clang::Type::QualifiedName: break;
3564 case clang::Type::TemplateSpecialization: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003565 case clang::Type::DependentTemplateSpecialization: break;
3566 case clang::Type::TemplateTypeParm: break;
3567 case clang::Type::SubstTemplateTypeParm: break;
3568 case clang::Type::SubstTemplateTypeParmPack:break;
3569 case clang::Type::PackExpansion: break;
3570 case clang::Type::UnresolvedUsing: break;
3571 case clang::Type::Paren: break;
3572 case clang::Type::Elaborated: break;
3573 case clang::Type::Attributed: break;
3574 case clang::Type::Auto: break;
3575 case clang::Type::InjectedClassName: break;
3576 case clang::Type::DependentName: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003577 }
3578 // No DeclContext in this type...
3579 return NULL;
3580}
3581
3582#pragma mark Namespace Declarations
3583
3584NamespaceDecl *
3585ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3586{
3587 // TODO: Do something intelligent with the Declaration object passed in
3588 // like maybe filling in the SourceLocation with it...
3589 if (name)
3590 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003591 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003592 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00003593 decl_ctx = ast->getTranslationUnitDecl();
Sean Callananfb0b7582011-03-15 00:17:19 +00003594 return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &ast->Idents.get(name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003595 }
3596 return NULL;
3597}
3598
3599
3600#pragma mark Function Types
3601
3602FunctionDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003603ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003604{
3605 if (name)
3606 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003607 ASTContext *ast = getASTContext();
3608 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003609
3610 if (name && name[0])
3611 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003612 return FunctionDecl::Create(*ast,
3613 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003614 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003615 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003616 DeclarationName (&ast->Idents.get(name)),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003617 QualType::getFromOpaquePtr(function_clang_type),
3618 NULL,
3619 (FunctionDecl::StorageClass)storage,
3620 (FunctionDecl::StorageClass)storage,
3621 is_inline);
3622 }
3623 else
3624 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003625 return FunctionDecl::Create(*ast,
3626 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003627 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003628 SourceLocation(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003629 DeclarationName (),
3630 QualType::getFromOpaquePtr(function_clang_type),
3631 NULL,
3632 (FunctionDecl::StorageClass)storage,
3633 (FunctionDecl::StorageClass)storage,
3634 is_inline);
3635 }
3636 }
3637 return NULL;
3638}
3639
Greg Clayton1be10fc2010-09-29 01:12:09 +00003640clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00003641ClangASTContext::CreateFunctionType (ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003642 clang_type_t result_type,
3643 clang_type_t *args,
Sean Callananc81256a2010-09-16 20:40:25 +00003644 unsigned num_args,
3645 bool is_variadic,
3646 unsigned type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003647{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003648 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003649 std::vector<QualType> qual_type_args;
3650 for (unsigned i=0; i<num_args; ++i)
3651 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3652
3653 // TODO: Detect calling convention in DWARF?
Sean Callanan2c777c42011-01-18 23:32:05 +00003654 FunctionProtoType::ExtProtoInfo proto_info;
3655 proto_info.Variadic = is_variadic;
Sean Callananfb0b7582011-03-15 00:17:19 +00003656 proto_info.ExceptionSpecType = EST_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00003657 proto_info.TypeQuals = type_quals;
Sean Callananfb0b7582011-03-15 00:17:19 +00003658 proto_info.RefQualifier = RQ_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00003659 proto_info.NumExceptions = 0;
3660 proto_info.Exceptions = NULL;
3661
Greg Clayton6beaaa62011-01-17 03:46:26 +00003662 return ast->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton471b31c2010-07-20 22:52:08 +00003663 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003664 qual_type_args.size(),
Sean Callanan2c777c42011-01-18 23:32:05 +00003665 proto_info).getAsOpaquePtr(); // NoReturn);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003666}
3667
3668ParmVarDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003669ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003670{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003671 ASTContext *ast = getASTContext();
3672 assert (ast != NULL);
3673 return ParmVarDecl::Create(*ast,
3674 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003675 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003676 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003677 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callananc81256a2010-09-16 20:40:25 +00003678 QualType::getFromOpaquePtr(param_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003679 NULL,
3680 (VarDecl::StorageClass)storage,
3681 (VarDecl::StorageClass)storage,
3682 0);
3683}
3684
3685void
3686ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3687{
3688 if (function_decl)
3689 function_decl->setParams (params, num_params);
3690}
3691
3692
3693#pragma mark Array Types
3694
Greg Clayton1be10fc2010-09-29 01:12:09 +00003695clang_type_t
3696ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003697{
3698 if (element_type)
3699 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003700 ASTContext *ast = getASTContext();
3701 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003702 llvm::APInt ap_element_count (64, element_count);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003703 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003704 ap_element_count,
3705 ArrayType::Normal,
3706 0).getAsOpaquePtr(); // ElemQuals
3707 }
3708 return NULL;
3709}
3710
3711
3712#pragma mark TagDecl
3713
3714bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003715ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003716{
3717 if (clang_type)
3718 {
3719 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00003720 const clang::Type *t = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003721 if (t)
3722 {
Sean Callanan78e37602011-01-27 04:42:51 +00003723 const TagType *tag_type = dyn_cast<TagType>(t);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003724 if (tag_type)
3725 {
3726 TagDecl *tag_decl = tag_type->getDecl();
3727 if (tag_decl)
3728 {
3729 tag_decl->startDefinition();
3730 return true;
3731 }
3732 }
3733 }
3734 }
3735 return false;
3736}
3737
3738bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003739ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003740{
3741 if (clang_type)
3742 {
3743 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton14372242010-09-29 03:44:17 +00003744
3745 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3746
3747 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003748 {
Greg Clayton14372242010-09-29 03:44:17 +00003749 cxx_record_decl->completeDefinition();
3750
3751 return true;
3752 }
3753
Sean Callanan78e37602011-01-27 04:42:51 +00003754 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
Sean Callanana2424172010-10-25 00:29:48 +00003755
3756 if (objc_class_type)
3757 {
3758 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3759
3760 class_interface_decl->setForwardDecl(false);
3761 }
3762
Greg Clayton14372242010-09-29 03:44:17 +00003763 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3764
3765 if (enum_type)
3766 {
3767 EnumDecl *enum_decl = enum_type->getDecl();
3768
3769 if (enum_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003770 {
Greg Clayton14372242010-09-29 03:44:17 +00003771 /// TODO This really needs to be fixed.
3772
3773 unsigned NumPositiveBits = 1;
3774 unsigned NumNegativeBits = 0;
3775
Greg Clayton6beaaa62011-01-17 03:46:26 +00003776 ASTContext *ast = getASTContext();
Greg Claytone02b8502010-10-12 04:29:14 +00003777
3778 QualType promotion_qual_type;
3779 // If the enum integer type is less than an integer in bit width,
3780 // then we must promote it to an integer size.
Greg Clayton6beaaa62011-01-17 03:46:26 +00003781 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
Greg Claytone02b8502010-10-12 04:29:14 +00003782 {
3783 if (enum_decl->getIntegerType()->isSignedIntegerType())
Greg Clayton6beaaa62011-01-17 03:46:26 +00003784 promotion_qual_type = ast->IntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003785 else
Greg Clayton6beaaa62011-01-17 03:46:26 +00003786 promotion_qual_type = ast->UnsignedIntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003787 }
3788 else
3789 promotion_qual_type = enum_decl->getIntegerType();
3790
3791 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton14372242010-09-29 03:44:17 +00003792 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003793 }
3794 }
3795 }
3796 return false;
3797}
3798
3799
3800#pragma mark Enumeration Types
3801
Greg Clayton1be10fc2010-09-29 01:12:09 +00003802clang_type_t
Greg Claytonca512b32011-01-14 04:54:56 +00003803ClangASTContext::CreateEnumerationType
3804(
3805 const char *name,
3806 DeclContext *decl_ctx,
3807 const Declaration &decl,
3808 clang_type_t integer_qual_type
3809)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003810{
3811 // TODO: Do something intelligent with the Declaration object passed in
3812 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003813 ASTContext *ast = getASTContext();
3814 assert (ast != NULL);
Greg Claytone02b8502010-10-12 04:29:14 +00003815
3816 // TODO: ask about these...
3817// const bool IsScoped = false;
3818// const bool IsFixed = false;
3819
Greg Clayton6beaaa62011-01-17 03:46:26 +00003820 EnumDecl *enum_decl = EnumDecl::Create (*ast,
Greg Claytonca512b32011-01-14 04:54:56 +00003821 decl_ctx,
Greg Claytone02b8502010-10-12 04:29:14 +00003822 SourceLocation(),
Greg Claytone02b8502010-10-12 04:29:14 +00003823 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003824 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callanan48114472010-12-13 01:26:27 +00003825 NULL,
3826 false, // IsScoped
3827 false, // IsScopedUsingClassTag
3828 false); // IsFixed
Sean Callanan2652ad22011-01-18 01:03:44 +00003829
3830
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003831 if (enum_decl)
Greg Clayton83ff3892010-09-12 23:17:56 +00003832 {
3833 // TODO: check if we should be setting the promotion type too?
3834 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00003835
3836 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
3837
Greg Clayton6beaaa62011-01-17 03:46:26 +00003838 return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Clayton83ff3892010-09-12 23:17:56 +00003839 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003840 return NULL;
3841}
3842
Greg Clayton1be10fc2010-09-29 01:12:09 +00003843clang_type_t
3844ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3845{
3846 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3847
Sean Callanan78e37602011-01-27 04:42:51 +00003848 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003849 if (clang_type)
3850 {
3851 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3852 if (enum_type)
3853 {
3854 EnumDecl *enum_decl = enum_type->getDecl();
3855 if (enum_decl)
3856 return enum_decl->getIntegerType().getAsOpaquePtr();
3857 }
3858 }
3859 return NULL;
3860}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003861bool
3862ClangASTContext::AddEnumerationValueToEnumerationType
3863(
Greg Clayton1be10fc2010-09-29 01:12:09 +00003864 clang_type_t enum_clang_type,
3865 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003866 const Declaration &decl,
3867 const char *name,
3868 int64_t enum_value,
3869 uint32_t enum_value_bit_size
3870)
3871{
3872 if (enum_clang_type && enumerator_clang_type && name)
3873 {
3874 // TODO: Do something intelligent with the Declaration object passed in
3875 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003876 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003877 IdentifierTable *identifier_table = getIdentifierTable();
3878
Greg Clayton6beaaa62011-01-17 03:46:26 +00003879 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003880 assert (identifier_table != NULL);
3881 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3882
Sean Callanan78e37602011-01-27 04:42:51 +00003883 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003884 if (clang_type)
3885 {
3886 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3887
3888 if (enum_type)
3889 {
3890 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3891 enum_llvm_apsint = enum_value;
3892 EnumConstantDecl *enumerator_decl =
Greg Clayton6beaaa62011-01-17 03:46:26 +00003893 EnumConstantDecl::Create (*ast,
3894 enum_type->getDecl(),
3895 SourceLocation(),
3896 name ? &identifier_table->get(name) : NULL, // Identifier
3897 QualType::getFromOpaquePtr(enumerator_clang_type),
3898 NULL,
3899 enum_llvm_apsint);
3900
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003901 if (enumerator_decl)
3902 {
3903 enum_type->getDecl()->addDecl(enumerator_decl);
3904 return true;
3905 }
3906 }
3907 }
3908 }
3909 return false;
3910}
3911
3912#pragma mark Pointers & References
3913
Greg Clayton1be10fc2010-09-29 01:12:09 +00003914clang_type_t
3915ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003916{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003917 return CreatePointerType (getASTContext(), clang_type);
3918}
3919
3920clang_type_t
3921ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
3922{
3923 if (ast && clang_type)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003924 {
3925 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3926
Greg Clayton737b9322010-09-13 03:32:57 +00003927 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3928 switch (type_class)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003929 {
3930 case clang::Type::ObjCObject:
3931 case clang::Type::ObjCInterface:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003932 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003933
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003934 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003935 return ast->getPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003936 }
3937 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003938 return NULL;
3939}
3940
Greg Clayton1be10fc2010-09-29 01:12:09 +00003941clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003942ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
3943 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003944{
3945 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003946 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003947 return NULL;
3948}
3949
Greg Clayton1be10fc2010-09-29 01:12:09 +00003950clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003951ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
3952 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003953{
3954 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003955 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003956 return NULL;
3957}
3958
Greg Clayton1be10fc2010-09-29 01:12:09 +00003959clang_type_t
3960ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Clayton9b81a312010-06-12 01:20:30 +00003961{
3962 if (clang_pointee_type && clang_pointee_type)
3963 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3964 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3965 return NULL;
3966}
3967
Greg Clayton1a65ae12011-01-25 23:55:37 +00003968uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003969ClangASTContext::GetPointerBitSize ()
3970{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003971 ASTContext *ast = getASTContext();
3972 return ast->getTypeSize(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003973}
3974
3975bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003976ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003977{
3978 if (clang_type == NULL)
3979 return false;
3980
3981 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003982 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3983 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003984 {
Sean Callanana2424172010-10-25 00:29:48 +00003985 case clang::Type::Builtin:
3986 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3987 {
3988 default:
3989 break;
3990 case clang::BuiltinType::ObjCId:
3991 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00003992 return true;
3993 }
3994 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00003995 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003996 if (target_type)
3997 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3998 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003999 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004000 if (target_type)
4001 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4002 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004003 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004004 if (target_type)
4005 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4006 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004007 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004008 if (target_type)
4009 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4010 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004011 case clang::Type::LValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004012 if (target_type)
4013 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4014 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004015 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004016 if (target_type)
4017 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4018 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004019 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004020 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004021 default:
4022 break;
4023 }
4024 return false;
4025}
4026
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004027bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004028ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004029{
4030 if (!clang_type)
4031 return false;
4032
4033 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4034 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
4035
4036 if (builtin_type)
4037 {
4038 if (builtin_type->isInteger())
4039 is_signed = builtin_type->isSignedInteger();
4040
4041 return true;
4042 }
4043
4044 return false;
4045}
4046
4047bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004048ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004049{
4050 if (clang_type)
4051 {
4052 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004053 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4054 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004055 {
Sean Callanana2424172010-10-25 00:29:48 +00004056 case clang::Type::Builtin:
4057 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4058 {
4059 default:
4060 break;
4061 case clang::BuiltinType::ObjCId:
4062 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004063 return true;
4064 }
4065 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004066 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004067 if (target_type)
4068 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4069 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004070 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004071 if (target_type)
4072 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4073 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004074 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004075 if (target_type)
4076 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4077 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004078 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004079 if (target_type)
4080 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4081 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004082 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004083 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004084 default:
4085 break;
4086 }
4087 }
4088 return false;
4089}
4090
4091bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004092ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004093{
4094 if (clang_type)
4095 {
4096 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4097
4098 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
4099 {
4100 clang::BuiltinType::Kind kind = BT->getKind();
4101 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
4102 {
4103 count = 1;
4104 is_complex = false;
4105 return true;
4106 }
4107 }
4108 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
4109 {
4110 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
4111 {
4112 count = 2;
4113 is_complex = true;
4114 return true;
4115 }
4116 }
4117 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
4118 {
4119 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
4120 {
4121 count = VT->getNumElements();
4122 is_complex = false;
4123 return true;
4124 }
4125 }
4126 }
4127 return false;
4128}
4129
Greg Clayton8f92f0a2010-10-14 22:52:14 +00004130
4131bool
4132ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
4133{
4134 if (clang_type)
4135 {
4136 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4137
4138 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4139 if (cxx_record_decl)
4140 {
4141 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
4142 return true;
4143 }
4144 }
4145 class_name.clear();
4146 return false;
4147}
4148
4149
Greg Clayton0fffff52010-09-24 05:15:53 +00004150bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004151ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004152{
4153 if (clang_type)
4154 {
4155 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4156 if (qual_type->getAsCXXRecordDecl() != NULL)
4157 return true;
4158 }
4159 return false;
4160}
4161
4162bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004163ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004164{
4165 if (clang_type)
4166 {
4167 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4168 if (qual_type->isObjCObjectOrInterfaceType())
4169 return true;
4170 }
4171 return false;
4172}
4173
4174
Greg Clayton73b472d2010-10-27 03:32:59 +00004175bool
4176ClangASTContext::IsCharType (clang_type_t clang_type)
4177{
4178 if (clang_type)
4179 return QualType::getFromOpaquePtr(clang_type)->isCharType();
4180 return false;
4181}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004182
4183bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004184ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004185{
Greg Clayton73b472d2010-10-27 03:32:59 +00004186 clang_type_t pointee_or_element_clang_type = NULL;
4187 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
4188
4189 if (pointee_or_element_clang_type == NULL)
4190 return false;
4191
4192 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004193 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004194 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
4195
4196 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004197 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004198 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4199 if (type_flags.Test (eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004200 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004201 // We know the size of the array and it could be a C string
4202 // since it is an array of characters
4203 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
4204 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004205 }
Greg Clayton73b472d2010-10-27 03:32:59 +00004206 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004207 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004208 length = 0;
4209 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004210 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004211
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004212 }
4213 }
4214 return false;
4215}
4216
4217bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004218ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton737b9322010-09-13 03:32:57 +00004219{
4220 if (clang_type)
4221 {
4222 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4223
4224 if (qual_type->isFunctionPointerType())
4225 return true;
4226
4227 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4228 switch (type_class)
4229 {
Sean Callananfb0b7582011-03-15 00:17:19 +00004230 default:
4231 break;
Greg Clayton737b9322010-09-13 03:32:57 +00004232 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004233 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004234
4235 case clang::Type::LValueReference:
4236 case clang::Type::RValueReference:
4237 {
Sean Callanan78e37602011-01-27 04:42:51 +00004238 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004239 if (reference_type)
4240 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
4241 }
4242 break;
4243 }
4244 }
4245 return false;
4246}
4247
Greg Clayton73b472d2010-10-27 03:32:59 +00004248size_t
4249ClangASTContext::GetArraySize (clang_type_t clang_type)
4250{
4251 if (clang_type)
4252 {
Sean Callanan78e37602011-01-27 04:42:51 +00004253 const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00004254 if (array)
4255 return array->getSize().getLimitedValue();
4256 }
4257 return 0;
4258}
Greg Clayton737b9322010-09-13 03:32:57 +00004259
4260bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004261ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004262{
4263 if (!clang_type)
4264 return false;
4265
4266 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4267
Greg Clayton737b9322010-09-13 03:32:57 +00004268 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4269 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004270 {
Sean Callananfb0b7582011-03-15 00:17:19 +00004271 default:
4272 break;
Greg Claytone1a916a2010-07-21 22:12:05 +00004273 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004274 if (member_type)
4275 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4276 if (size)
Greg Claytonac4827f2011-04-01 18:14:08 +00004277 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004278 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004279 case clang::Type::IncompleteArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004280 if (member_type)
4281 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4282 if (size)
4283 *size = 0;
4284 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004285 case clang::Type::VariableArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004286 if (member_type)
4287 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4288 if (size)
4289 *size = 0;
Greg Clayton03dbf2e2011-02-02 00:52:14 +00004290 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004291 case clang::Type::DependentSizedArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004292 if (member_type)
4293 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4294 if (size)
4295 *size = 0;
4296 return true;
4297 }
4298 return false;
4299}
4300
4301
4302#pragma mark Typedefs
4303
Greg Clayton1be10fc2010-09-29 01:12:09 +00004304clang_type_t
4305ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004306{
4307 if (clang_type)
4308 {
4309 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004310 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004311 IdentifierTable *identifier_table = getIdentifierTable();
Greg Clayton6beaaa62011-01-17 03:46:26 +00004312 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004313 assert (identifier_table != NULL);
4314 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00004315 decl_ctx = ast->getTranslationUnitDecl();
4316 TypedefDecl *decl = TypedefDecl::Create (*ast,
4317 decl_ctx,
4318 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004319 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00004320 name ? &identifier_table->get(name) : NULL, // Identifier
4321 ast->CreateTypeSourceInfo(qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00004322
4323 decl->setAccess(AS_public); // TODO respect proper access specifier
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004324
4325 // Get a uniqued QualType for the typedef decl type
Greg Clayton6beaaa62011-01-17 03:46:26 +00004326 return ast->getTypedefType (decl).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004327 }
4328 return NULL;
4329}
4330
4331
4332std::string
Greg Clayton1be10fc2010-09-29 01:12:09 +00004333ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004334{
4335 std::string return_name;
4336
Greg Clayton1be10fc2010-09-29 01:12:09 +00004337 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004338
Greg Clayton1be10fc2010-09-29 01:12:09 +00004339 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004340 if (typedef_type)
4341 {
Sean Callanand12cf8bb2011-05-15 22:34:38 +00004342 const TypedefNameDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004343 return_name = typedef_decl->getQualifiedNameAsString();
4344 }
4345 else
4346 {
4347 return_name = qual_type.getAsString();
4348 }
4349
4350 return return_name;
4351}
4352
4353// Disable this for now since I can't seem to get a nicely formatted float
4354// out of the APFloat class without just getting the float, double or quad
4355// and then using a formatted print on it which defeats the purpose. We ideally
4356// would like to get perfect string values for any kind of float semantics
4357// so we can support remote targets. The code below also requires a patch to
4358// llvm::APInt.
4359//bool
Greg Clayton6beaaa62011-01-17 03:46:26 +00004360//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 +00004361//{
4362// uint32_t count = 0;
4363// bool is_complex = false;
4364// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4365// {
4366// unsigned num_bytes_per_float = byte_size / count;
4367// unsigned num_bits_per_float = num_bytes_per_float * 8;
4368//
4369// float_str.clear();
4370// uint32_t i;
4371// for (i=0; i<count; i++)
4372// {
4373// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
4374// bool is_ieee = false;
4375// APFloat ap_float(ap_int, is_ieee);
4376// char s[1024];
4377// unsigned int hex_digits = 0;
4378// bool upper_case = false;
4379//
4380// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
4381// {
4382// if (i > 0)
4383// float_str.append(", ");
4384// float_str.append(s);
4385// if (i == 1 && is_complex)
4386// float_str.append(1, 'i');
4387// }
4388// }
4389// return !float_str.empty();
4390// }
4391// return false;
4392//}
4393
4394size_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00004395ClangASTContext::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 +00004396{
4397 if (clang_type)
4398 {
4399 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4400 uint32_t count = 0;
4401 bool is_complex = false;
4402 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4403 {
4404 // TODO: handle complex and vector types
4405 if (count != 1)
4406 return false;
4407
4408 StringRef s_sref(s);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004409 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004410
Greg Clayton6beaaa62011-01-17 03:46:26 +00004411 const uint64_t bit_size = ast->getTypeSize (qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004412 const uint64_t byte_size = bit_size / 8;
4413 if (dst_size >= byte_size)
4414 {
4415 if (bit_size == sizeof(float)*8)
4416 {
4417 float float32 = ap_float.convertToFloat();
4418 ::memcpy (dst, &float32, byte_size);
4419 return byte_size;
4420 }
4421 else if (bit_size >= 64)
4422 {
4423 llvm::APInt ap_int(ap_float.bitcastToAPInt());
4424 ::memcpy (dst, ap_int.getRawData(), byte_size);
4425 return byte_size;
4426 }
4427 }
4428 }
4429 }
4430 return 0;
4431}
Sean Callanan6fe64b52010-09-17 02:24:29 +00004432
4433unsigned
Greg Clayton1be10fc2010-09-29 01:12:09 +00004434ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanan6fe64b52010-09-17 02:24:29 +00004435{
4436 assert (clang_type);
4437
4438 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4439
4440 return qual_type.getQualifiers().getCVRQualifiers();
4441}
Greg Clayton6beaaa62011-01-17 03:46:26 +00004442
4443bool
4444ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
4445{
4446 if (clang_type == NULL)
4447 return false;
4448
Greg Claytonc432c192011-01-20 04:18:48 +00004449 return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004450}
4451
4452
4453bool
4454ClangASTContext::GetCompleteType (clang_type_t clang_type)
4455{
4456 return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
4457}
4458