blob: 7759164e51ca88839c4a2b4af5b2c657aef7c3d4 [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.
Greg Claytondc968d12011-05-17 18:15:05 +0000865 if (type_name)
866 {
867 fprintf (stderr, "error: need to add support for DW_TAG_base_type '%s' encoded with DW_ATE = 0x%x, bit_size = %u\n", type_name, dw_ate, bit_size);
868 }
869 else
870 {
871 fprintf (stderr, "error: need to add support for DW_TAG_base_type encoded with DW_ATE = 0x%x, bit_size = %u\n", dw_ate, bit_size);
872 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000873 return NULL;
874}
875
Greg Clayton1be10fc2010-09-29 01:12:09 +0000876clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000877ClangASTContext::GetBuiltInType_void(ASTContext *ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000878{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000879 return ast->VoidTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000880}
881
Greg Clayton1be10fc2010-09-29 01:12:09 +0000882clang_type_t
Sean Callananf7c3e272010-11-19 02:52:21 +0000883ClangASTContext::GetBuiltInType_bool()
884{
885 return getASTContext()->BoolTy.getAsOpaquePtr();
886}
887
888clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000889ClangASTContext::GetBuiltInType_objc_id()
890{
Sean Callananf6c73082010-12-06 23:53:20 +0000891 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000892}
893
Greg Clayton1be10fc2010-09-29 01:12:09 +0000894clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000895ClangASTContext::GetBuiltInType_objc_Class()
896{
Sean Callanana2424172010-10-25 00:29:48 +0000897 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000898}
899
Greg Clayton1be10fc2010-09-29 01:12:09 +0000900clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000901ClangASTContext::GetBuiltInType_objc_selector()
902{
Sean Callananf6c73082010-12-06 23:53:20 +0000903 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000904}
905
Greg Clayton1be10fc2010-09-29 01:12:09 +0000906clang_type_t
Sean Callanan77502262011-05-12 23:54:16 +0000907ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
908{
909 return ast->UnknownAnyTy.getAsOpaquePtr();
910}
911
912clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000913ClangASTContext::GetCStringType (bool is_const)
914{
915 QualType char_type(getASTContext()->CharTy);
916
917 if (is_const)
918 char_type.addConst();
919
920 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
921}
922
Greg Clayton1be10fc2010-09-29 01:12:09 +0000923clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924ClangASTContext::GetVoidPtrType (bool is_const)
925{
926 return GetVoidPtrType(getASTContext(), is_const);
927}
928
Greg Clayton1be10fc2010-09-29 01:12:09 +0000929clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000930ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000932 QualType void_ptr_type(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000933
934 if (is_const)
935 void_ptr_type.addConst();
936
937 return void_ptr_type.getAsOpaquePtr();
938}
939
Greg Clayton1be10fc2010-09-29 01:12:09 +0000940clang_type_t
Greg Clayton38a61402010-12-02 23:20:03 +0000941ClangASTContext::CopyType (ASTContext *dst_ast,
942 ASTContext *src_ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000943 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000944{
Sean Callanan79439e82010-11-18 02:56:27 +0000945 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000946 FileManager file_manager (file_system_options);
947 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000948 *src_ast, file_manager,
949 false);
Sean Callanan0617fcb2010-11-09 22:37:10 +0000950
Greg Clayton38a61402010-12-02 23:20:03 +0000951 QualType src (QualType::getFromOpaquePtr(clang_type));
952 QualType dst (importer.Import(src));
Sean Callanan0617fcb2010-11-09 22:37:10 +0000953
954 return dst.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000955}
956
Greg Clayton526e5af2010-11-13 03:52:47 +0000957
958clang::Decl *
Greg Clayton38a61402010-12-02 23:20:03 +0000959ClangASTContext::CopyDecl (ASTContext *dst_ast,
960 ASTContext *src_ast,
Greg Clayton526e5af2010-11-13 03:52:47 +0000961 clang::Decl *source_decl)
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000962{
Sean Callanan79439e82010-11-18 02:56:27 +0000963 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000964 FileManager file_manager (file_system_options);
965 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000966 *src_ast, file_manager,
967 false);
Greg Clayton526e5af2010-11-13 03:52:47 +0000968
969 return importer.Import(source_decl);
970}
971
Sean Callanan23a30272010-07-16 00:00:27 +0000972bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000973ClangASTContext::AreTypesSame(ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000974 clang_type_t type1,
975 clang_type_t type2)
Sean Callanan4dcca2622010-07-15 22:30:52 +0000976{
Greg Claytonf4ecaa52011-02-16 23:00:21 +0000977 return ast->hasSameType (QualType::getFromOpaquePtr(type1),
978 QualType::getFromOpaquePtr(type2));
Sean Callanan4dcca2622010-07-15 22:30:52 +0000979}
980
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981#pragma mark CVR modifiers
982
Greg Clayton1be10fc2010-09-29 01:12:09 +0000983clang_type_t
984ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000985{
986 if (clang_type)
987 {
988 QualType result(QualType::getFromOpaquePtr(clang_type));
989 result.addConst();
990 return result.getAsOpaquePtr();
991 }
992 return NULL;
993}
994
Greg Clayton1be10fc2010-09-29 01:12:09 +0000995clang_type_t
996ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000997{
998 if (clang_type)
999 {
1000 QualType result(QualType::getFromOpaquePtr(clang_type));
1001 result.getQualifiers().setRestrict (true);
1002 return result.getAsOpaquePtr();
1003 }
1004 return NULL;
1005}
1006
Greg Clayton1be10fc2010-09-29 01:12:09 +00001007clang_type_t
1008ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009{
1010 if (clang_type)
1011 {
1012 QualType result(QualType::getFromOpaquePtr(clang_type));
1013 result.getQualifiers().setVolatile (true);
1014 return result.getAsOpaquePtr();
1015 }
1016 return NULL;
1017}
1018
Greg Clayton6beaaa62011-01-17 03:46:26 +00001019
1020clang_type_t
1021ClangASTContext::GetTypeForDecl (TagDecl *decl)
1022{
1023 // No need to call the getASTContext() accessor (which can create the AST
1024 // if it isn't created yet, because we can't have created a decl in this
1025 // AST if our AST didn't already exist...
1026 if (m_ast_ap.get())
1027 return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
1028 return NULL;
1029}
1030
1031clang_type_t
1032ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
1033{
1034 // No need to call the getASTContext() accessor (which can create the AST
1035 // if it isn't created yet, because we can't have created a decl in this
1036 // AST if our AST didn't already exist...
1037 if (m_ast_ap.get())
1038 return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
1039 return NULL;
1040}
1041
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042#pragma mark Structure, Unions, Classes
1043
Greg Clayton1be10fc2010-09-29 01:12:09 +00001044clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +00001045ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001047 ASTContext *ast = getASTContext();
1048 assert (ast != NULL);
Sean Callanana2424172010-10-25 00:29:48 +00001049
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001050 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001051 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052
Greg Clayton9e409562010-07-28 02:04:09 +00001053
Greg Claytonc86103d2010-08-05 01:57:25 +00001054 if (language == eLanguageTypeObjC)
Greg Clayton9e409562010-07-28 02:04:09 +00001055 {
Greg Claytonaaf99e02010-10-11 02:25:34 +00001056 bool isForwardDecl = true;
Greg Clayton9e409562010-07-28 02:04:09 +00001057 bool isInternal = false;
1058 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
1059 }
1060
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1062 // we will need to update this code. I was told to currently always use
1063 // the CXXRecordDecl class since we often don't know from debug information
1064 // if something is struct or a class, so we default to always use the more
1065 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001066 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 (TagDecl::TagKind)kind,
1068 decl_ctx,
1069 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001070 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001071 name && name[0] ? &ast->Idents.get(name) : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001072
Greg Clayton6beaaa62011-01-17 03:46:26 +00001073 return ast->getTagDeclType(decl).getAsOpaquePtr();
1074}
1075
1076bool
1077ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
1078{
1079 if (clang_type == NULL)
1080 return false;
1081
1082 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1083
1084 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1085 switch (type_class)
1086 {
1087 case clang::Type::Record:
1088 {
1089 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
1090 if (cxx_record_decl)
1091 {
1092 cxx_record_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001093 cxx_record_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001094 return true;
1095 }
1096 }
1097 break;
1098
1099 case clang::Type::Enum:
1100 {
1101 EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
1102 if (enum_decl)
1103 {
1104 enum_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001105 enum_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001106 return true;
1107 }
1108 }
1109 break;
1110
1111 case clang::Type::ObjCObject:
1112 case clang::Type::ObjCInterface:
1113 {
Sean Callanan78e37602011-01-27 04:42:51 +00001114 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001115 assert (objc_class_type);
1116 if (objc_class_type)
1117 {
1118 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1119
1120 if (class_interface_decl)
1121 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001122 class_interface_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001123 class_interface_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001124 return true;
1125 }
1126 }
1127 }
1128 break;
1129
1130 case clang::Type::Typedef:
1131 return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
1132
1133 default:
1134 break;
1135 }
1136 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001137}
1138
Greg Claytona3c444a2010-10-01 23:13:49 +00001139static bool
1140IsOperator (const char *name, OverloadedOperatorKind &op_kind)
1141{
1142 if (name == NULL || name[0] == '\0')
1143 return false;
1144
Sean Callanana43f20d2010-12-10 19:51:54 +00001145#define OPERATOR_PREFIX "operator"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001146#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
Sean Callananbfeff8c2010-12-10 02:15:55 +00001147
1148 const char *post_op_name = NULL;
1149
Sean Callanana43f20d2010-12-10 19:51:54 +00001150 bool no_space = true;
Sean Callananbfeff8c2010-12-10 02:15:55 +00001151
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001152 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
Greg Claytona3c444a2010-10-01 23:13:49 +00001153 return false;
1154
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001155 post_op_name = name + OPERATOR_PREFIX_LENGTH;
1156
Sean Callanana43f20d2010-12-10 19:51:54 +00001157 if (post_op_name[0] == ' ')
1158 {
1159 post_op_name++;
1160 no_space = false;
1161 }
1162
1163#undef OPERATOR_PREFIX
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001164#undef OPERATOR_PREFIX_LENGTH
Sean Callanana43f20d2010-12-10 19:51:54 +00001165
Greg Claytona3c444a2010-10-01 23:13:49 +00001166 // This is an operator, set the overloaded operator kind to invalid
1167 // in case this is a conversion operator...
1168 op_kind = NUM_OVERLOADED_OPERATORS;
1169
1170 switch (post_op_name[0])
1171 {
Sean Callananbfeff8c2010-12-10 02:15:55 +00001172 default:
1173 if (no_space)
1174 return false;
1175 break;
Greg Claytona3c444a2010-10-01 23:13:49 +00001176 case 'n':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001177 if (no_space)
1178 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001179 if (strcmp (post_op_name, "new") == 0)
1180 op_kind = OO_New;
1181 else if (strcmp (post_op_name, "new[]") == 0)
1182 op_kind = OO_Array_New;
1183 break;
1184
1185 case 'd':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001186 if (no_space)
1187 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001188 if (strcmp (post_op_name, "delete") == 0)
1189 op_kind = OO_Delete;
1190 else if (strcmp (post_op_name, "delete[]") == 0)
1191 op_kind = OO_Array_Delete;
1192 break;
1193
1194 case '+':
1195 if (post_op_name[1] == '\0')
1196 op_kind = OO_Plus;
1197 else if (post_op_name[2] == '\0')
1198 {
1199 if (post_op_name[1] == '=')
1200 op_kind = OO_PlusEqual;
1201 else if (post_op_name[1] == '+')
1202 op_kind = OO_PlusPlus;
1203 }
1204 break;
1205
1206 case '-':
1207 if (post_op_name[1] == '\0')
1208 op_kind = OO_Minus;
1209 else if (post_op_name[2] == '\0')
1210 {
1211 switch (post_op_name[1])
1212 {
1213 case '=': op_kind = OO_MinusEqual; break;
1214 case '-': op_kind = OO_MinusMinus; break;
1215 case '>': op_kind = OO_Arrow; break;
1216 }
1217 }
1218 else if (post_op_name[3] == '\0')
1219 {
1220 if (post_op_name[2] == '*')
1221 op_kind = OO_ArrowStar; break;
1222 }
1223 break;
1224
1225 case '*':
1226 if (post_op_name[1] == '\0')
1227 op_kind = OO_Star;
1228 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1229 op_kind = OO_StarEqual;
1230 break;
1231
1232 case '/':
1233 if (post_op_name[1] == '\0')
1234 op_kind = OO_Slash;
1235 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1236 op_kind = OO_SlashEqual;
1237 break;
1238
1239 case '%':
1240 if (post_op_name[1] == '\0')
1241 op_kind = OO_Percent;
1242 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1243 op_kind = OO_PercentEqual;
1244 break;
1245
1246
1247 case '^':
1248 if (post_op_name[1] == '\0')
1249 op_kind = OO_Caret;
1250 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1251 op_kind = OO_CaretEqual;
1252 break;
1253
1254 case '&':
1255 if (post_op_name[1] == '\0')
1256 op_kind = OO_Amp;
1257 else if (post_op_name[2] == '\0')
1258 {
1259 switch (post_op_name[1])
1260 {
1261 case '=': op_kind = OO_AmpEqual; break;
1262 case '&': op_kind = OO_AmpAmp; break;
1263 }
1264 }
1265 break;
1266
1267 case '|':
1268 if (post_op_name[1] == '\0')
1269 op_kind = OO_Pipe;
1270 else if (post_op_name[2] == '\0')
1271 {
1272 switch (post_op_name[1])
1273 {
1274 case '=': op_kind = OO_PipeEqual; break;
1275 case '|': op_kind = OO_PipePipe; break;
1276 }
1277 }
1278 break;
1279
1280 case '~':
1281 if (post_op_name[1] == '\0')
1282 op_kind = OO_Tilde;
1283 break;
1284
1285 case '!':
1286 if (post_op_name[1] == '\0')
1287 op_kind = OO_Exclaim;
1288 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1289 op_kind = OO_ExclaimEqual;
1290 break;
1291
1292 case '=':
1293 if (post_op_name[1] == '\0')
1294 op_kind = OO_Equal;
1295 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1296 op_kind = OO_EqualEqual;
1297 break;
1298
1299 case '<':
1300 if (post_op_name[1] == '\0')
1301 op_kind = OO_Less;
1302 else if (post_op_name[2] == '\0')
1303 {
1304 switch (post_op_name[1])
1305 {
1306 case '<': op_kind = OO_LessLess; break;
1307 case '=': op_kind = OO_LessEqual; break;
1308 }
1309 }
1310 else if (post_op_name[3] == '\0')
1311 {
1312 if (post_op_name[2] == '=')
1313 op_kind = OO_LessLessEqual;
1314 }
1315 break;
1316
1317 case '>':
1318 if (post_op_name[1] == '\0')
1319 op_kind = OO_Greater;
1320 else if (post_op_name[2] == '\0')
1321 {
1322 switch (post_op_name[1])
1323 {
1324 case '>': op_kind = OO_GreaterGreater; break;
1325 case '=': op_kind = OO_GreaterEqual; break;
1326 }
1327 }
1328 else if (post_op_name[1] == '>' &&
1329 post_op_name[2] == '=' &&
1330 post_op_name[3] == '\0')
1331 {
1332 op_kind = OO_GreaterGreaterEqual;
1333 }
1334 break;
1335
1336 case ',':
1337 if (post_op_name[1] == '\0')
1338 op_kind = OO_Comma;
1339 break;
1340
1341 case '(':
1342 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1343 op_kind = OO_Call;
1344 break;
1345
1346 case '[':
1347 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1348 op_kind = OO_Subscript;
1349 break;
1350 }
1351
1352 return true;
1353}
Greg Clayton6beaaa62011-01-17 03:46:26 +00001354
Greg Claytona51ed9b2010-09-23 01:09:21 +00001355CXXMethodDecl *
Sean Callanan61da09b2010-09-17 02:58:26 +00001356ClangASTContext::AddMethodToCXXRecordType
1357(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001358 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001359 clang_type_t record_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001360 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001361 clang_type_t method_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001362 lldb::AccessType access,
Greg Clayton0fffff52010-09-24 05:15:53 +00001363 bool is_virtual,
1364 bool is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00001365 bool is_inline,
1366 bool is_explicit
Greg Claytona51ed9b2010-09-23 01:09:21 +00001367)
Sean Callanan61da09b2010-09-17 02:58:26 +00001368{
Sean Callananfc55f5d2010-09-21 00:44:12 +00001369 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chend440bcc2010-09-28 16:10:54 +00001370 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001371
Greg Clayton6beaaa62011-01-17 03:46:26 +00001372 assert(ast);
Sean Callanan61da09b2010-09-17 02:58:26 +00001373
Greg Clayton6beaaa62011-01-17 03:46:26 +00001374 IdentifierTable *identifier_table = &ast->Idents;
Sean Callanan61da09b2010-09-17 02:58:26 +00001375
1376 assert(identifier_table);
1377
Sean Callananfc55f5d2010-09-21 00:44:12 +00001378 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001379
Greg Clayton6beaaa62011-01-17 03:46:26 +00001380 CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
Sean Callanan61da09b2010-09-17 02:58:26 +00001381
Greg Clayton0fffff52010-09-24 05:15:53 +00001382 if (cxx_record_decl == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001383 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001384
Greg Clayton0fffff52010-09-24 05:15:53 +00001385 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001386
Greg Claytonf51de672010-10-01 02:31:07 +00001387 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001388
Greg Claytonf51de672010-10-01 02:31:07 +00001389 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton878eaf12010-10-01 03:45:20 +00001390
Greg Clayton878eaf12010-10-01 03:45:20 +00001391 const bool is_implicitly_declared = false;
Greg Claytonf51de672010-10-01 02:31:07 +00001392
Sean Callanan78e37602011-01-27 04:42:51 +00001393 const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton878eaf12010-10-01 03:45:20 +00001394
Greg Clayton90a2acd2010-10-02 01:40:05 +00001395 if (function_Type == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001396 return NULL;
1397
Sean Callanan78e37602011-01-27 04:42:51 +00001398 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton878eaf12010-10-01 03:45:20 +00001399
1400 if (!method_function_prototype)
1401 return NULL;
1402
1403 unsigned int num_params = method_function_prototype->getNumArgs();
1404
1405 if (name[0] == '~')
Greg Claytonf51de672010-10-01 02:31:07 +00001406 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001407 cxx_method_decl = CXXDestructorDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001408 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001409 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001410 DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001411 method_qual_type,
Sean Callanan31e851c2010-10-29 18:38:40 +00001412 NULL,
Greg Clayton878eaf12010-10-01 03:45:20 +00001413 is_inline,
1414 is_implicitly_declared);
1415 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001416 else if (decl_name == cxx_record_decl->getDeclName())
Greg Clayton878eaf12010-10-01 03:45:20 +00001417 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001418 cxx_method_decl = CXXConstructorDecl::Create (*ast,
Greg Claytonf51de672010-10-01 02:31:07 +00001419 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001420 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001421 DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Claytonf51de672010-10-01 02:31:07 +00001422 method_qual_type,
1423 NULL, // TypeSourceInfo *
1424 is_explicit,
1425 is_inline,
1426 is_implicitly_declared);
1427 }
1428 else
Greg Clayton878eaf12010-10-01 03:45:20 +00001429 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001430
1431 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1432 if (IsOperator (name, op_kind))
Greg Clayton878eaf12010-10-01 03:45:20 +00001433 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001434 if (op_kind != NUM_OVERLOADED_OPERATORS)
1435 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001436 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001437 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001438 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001439 DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001440 method_qual_type,
1441 NULL, // TypeSourceInfo *
Greg Claytona3c444a2010-10-01 23:13:49 +00001442 is_static,
1443 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001444 is_inline,
1445 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001446 }
1447 else if (num_params == 0)
1448 {
1449 // Conversion operators don't take params...
Greg Clayton6beaaa62011-01-17 03:46:26 +00001450 cxx_method_decl = CXXConversionDecl::Create (*ast,
Greg Claytona3c444a2010-10-01 23:13:49 +00001451 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001452 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001453 DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytona3c444a2010-10-01 23:13:49 +00001454 method_qual_type,
1455 NULL, // TypeSourceInfo *
1456 is_inline,
Sean Callananfb0b7582011-03-15 00:17:19 +00001457 is_explicit,
1458 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001459 }
Greg Clayton878eaf12010-10-01 03:45:20 +00001460 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001461
1462 if (cxx_method_decl == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001463 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001464 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001465 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001466 SourceLocation(),
Greg Claytona3c444a2010-10-01 23:13:49 +00001467 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001468 method_qual_type,
1469 NULL, // TypeSourceInfo *
1470 is_static,
1471 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001472 is_inline,
1473 SourceLocation());
Greg Clayton878eaf12010-10-01 03:45:20 +00001474 }
Greg Claytonf51de672010-10-01 02:31:07 +00001475 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001476
Greg Clayton1be10fc2010-09-29 01:12:09 +00001477 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton0fffff52010-09-24 05:15:53 +00001478
1479 cxx_method_decl->setAccess (access_specifier);
1480 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001481
Sean Callananfc55f5d2010-09-21 00:44:12 +00001482 // Populate the method decl with parameter decls
Sean Callananfc55f5d2010-09-21 00:44:12 +00001483
Charles Davis8c444c42011-05-19 23:33:46 +00001484 llvm::SmallVector<ParmVarDecl *, 12> params;
Sean Callananfc55f5d2010-09-21 00:44:12 +00001485
1486 for (int param_index = 0;
1487 param_index < num_params;
1488 ++param_index)
1489 {
Charles Davis8c444c42011-05-19 23:33:46 +00001490 params.push_back (ParmVarDecl::Create (*ast,
1491 cxx_method_decl,
1492 SourceLocation(),
1493 SourceLocation(),
1494 NULL, // anonymous
1495 method_function_prototype->getArgType(param_index),
1496 NULL,
1497 SC_None,
1498 SC_None,
1499 NULL));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001500 }
1501
Charles Davis8c444c42011-05-19 23:33:46 +00001502 cxx_method_decl->setParams (params.data(), num_params);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001503
Greg Clayton0fffff52010-09-24 05:15:53 +00001504 cxx_record_decl->addDecl (cxx_method_decl);
Greg Claytonc432c192011-01-20 04:18:48 +00001505
1506// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic());
1507// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate());
1508// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD());
1509// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty());
1510// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract());
1511// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor());
1512// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
1513// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
1514// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor());
Greg Claytona51ed9b2010-09-23 01:09:21 +00001515 return cxx_method_decl;
Sean Callanan61da09b2010-09-17 02:58:26 +00001516}
1517
1518bool
Greg Clayton8cf05932010-07-22 18:30:50 +00001519ClangASTContext::AddFieldToRecordType
1520(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001521 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001522 clang_type_t record_clang_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001523 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001524 clang_type_t field_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001525 AccessType access,
1526 uint32_t bitfield_bit_size
1527)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001528{
1529 if (record_clang_type == NULL || field_type == NULL)
1530 return false;
1531
Greg Clayton6beaaa62011-01-17 03:46:26 +00001532 IdentifierTable *identifier_table = &ast->Idents;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001533
Greg Clayton6beaaa62011-01-17 03:46:26 +00001534 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001535 assert (identifier_table != NULL);
1536
1537 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1538
Sean Callanan78e37602011-01-27 04:42:51 +00001539 const clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001540 if (clang_type)
1541 {
1542 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1543
1544 if (record_type)
1545 {
1546 RecordDecl *record_decl = record_type->getDecl();
1547
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001548 clang::Expr *bit_width = NULL;
1549 if (bitfield_bit_size != 0)
1550 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001551 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1552 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001553 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001554 FieldDecl *field = FieldDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001555 record_decl,
1556 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001557 SourceLocation(),
Greg Clayton8cf05932010-07-22 18:30:50 +00001558 name ? &identifier_table->get(name) : NULL, // Identifier
1559 QualType::getFromOpaquePtr(field_type), // Field type
1560 NULL, // DeclaratorInfo *
1561 bit_width, // BitWidth
1562 false); // Mutable
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001563
Greg Clayton8cf05932010-07-22 18:30:50 +00001564 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001565
1566 if (field)
1567 {
1568 record_decl->addDecl(field);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001569 }
1570 }
Greg Clayton9e409562010-07-28 02:04:09 +00001571 else
1572 {
Sean Callanan78e37602011-01-27 04:42:51 +00001573 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001574 if (objc_class_type)
1575 {
Greg Clayton0fffff52010-09-24 05:15:53 +00001576 bool is_synthesized = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001577 ClangASTContext::AddObjCClassIVar (ast,
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001578 record_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001579 name,
1580 field_type,
1581 access,
1582 bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001583 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001584 }
1585 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001586 }
1587 return false;
1588}
1589
1590bool
1591ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1592{
1593 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1594}
1595
1596bool
1597ClangASTContext::FieldIsBitfield
1598(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001599 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001600 FieldDecl* field,
1601 uint32_t& bitfield_bit_size
1602)
1603{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001604 if (ast == NULL || field == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001605 return false;
1606
1607 if (field->isBitField())
1608 {
1609 Expr* bit_width_expr = field->getBitWidth();
1610 if (bit_width_expr)
1611 {
1612 llvm::APSInt bit_width_apsint;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001613 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001614 {
1615 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1616 return true;
1617 }
1618 }
1619 }
1620 return false;
1621}
1622
1623bool
1624ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1625{
1626 if (record_decl == NULL)
1627 return false;
1628
1629 if (!record_decl->field_empty())
1630 return true;
1631
1632 // No fields, lets check this is a CXX record and check the base classes
1633 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1634 if (cxx_record_decl)
1635 {
1636 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1637 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1638 base_class != base_class_end;
1639 ++base_class)
1640 {
1641 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1642 if (RecordHasFields(base_class_decl))
1643 return true;
1644 }
1645 }
1646 return false;
1647}
1648
1649void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001650ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001652 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001653 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001654 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1655
Sean Callanan78e37602011-01-27 04:42:51 +00001656 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001657 if (record_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001658 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001659 RecordDecl *record_decl = record_type->getDecl();
1660 if (record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001661 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001662 uint32_t field_idx;
1663 RecordDecl::field_iterator field, field_end;
1664 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1665 field != field_end;
1666 ++field, ++field_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001667 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001668 // If no accessibility was assigned, assign the correct one
1669 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1670 field->setAccess ((AccessSpecifier)default_accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001671 }
1672 }
1673 }
1674 }
1675}
1676
1677#pragma mark C++ Base Classes
1678
1679CXXBaseSpecifier *
Greg Clayton1be10fc2010-09-29 01:12:09 +00001680ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001681{
1682 if (base_class_type)
Greg Claytone6371122010-07-30 20:30:44 +00001683 return new CXXBaseSpecifier (SourceRange(),
1684 is_virtual,
1685 base_of_class,
1686 ConvertAccessTypeToAccessSpecifier (access),
Sean Callanan2c777c42011-01-18 23:32:05 +00001687 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
1688 SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001689 return NULL;
1690}
1691
Greg Clayton0b42ac32010-07-02 01:29:13 +00001692void
1693ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1694{
1695 for (unsigned i=0; i<num_base_classes; ++i)
1696 {
1697 delete base_classes[i];
1698 base_classes[i] = NULL;
1699 }
1700}
1701
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001702bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001703ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001704{
1705 if (class_clang_type)
1706 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001707 CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
1708 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001709 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001710 cxx_record_decl->setBases(base_classes, num_base_classes);
1711 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001712 }
1713 }
1714 return false;
1715}
Greg Clayton8cf05932010-07-22 18:30:50 +00001716#pragma mark Objective C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001717
Greg Clayton1be10fc2010-09-29 01:12:09 +00001718clang_type_t
Greg Clayton8cf05932010-07-22 18:30:50 +00001719ClangASTContext::CreateObjCClass
1720(
1721 const char *name,
1722 DeclContext *decl_ctx,
1723 bool isForwardDecl,
1724 bool isInternal
1725)
1726{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001727 ASTContext *ast = getASTContext();
1728 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001729 assert (name && name[0]);
1730 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001731 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001732
1733 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1734 // we will need to update this code. I was told to currently always use
1735 // the CXXRecordDecl class since we often don't know from debug information
1736 // if something is struct or a class, so we default to always use the more
1737 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001738 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001739 decl_ctx,
1740 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001741 &ast->Idents.get(name),
Greg Clayton8cf05932010-07-22 18:30:50 +00001742 SourceLocation(),
1743 isForwardDecl,
1744 isInternal);
Greg Clayton9e409562010-07-28 02:04:09 +00001745
Greg Clayton6beaaa62011-01-17 03:46:26 +00001746 return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001747}
1748
1749bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001750ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton8cf05932010-07-22 18:30:50 +00001751{
1752 if (class_opaque_type && super_opaque_type)
1753 {
1754 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1755 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
Sean Callanan78e37602011-01-27 04:42:51 +00001756 const clang::Type *class_type = class_qual_type.getTypePtr();
1757 const clang::Type *super_type = super_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001758 if (class_type && super_type)
1759 {
Sean Callanan78e37602011-01-27 04:42:51 +00001760 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1761 const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001762 if (objc_class_type && objc_super_type)
1763 {
1764 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1765 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1766 if (class_interface_decl && super_interface_decl)
1767 {
1768 class_interface_decl->setSuperClass(super_interface_decl);
1769 return true;
1770 }
1771 }
1772 }
1773 }
1774 return false;
1775}
1776
1777
1778bool
1779ClangASTContext::AddObjCClassIVar
1780(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001781 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001782 clang_type_t class_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001783 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001784 clang_type_t ivar_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001785 AccessType access,
1786 uint32_t bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001787 bool is_synthesized
Greg Clayton8cf05932010-07-22 18:30:50 +00001788)
1789{
1790 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1791 return false;
1792
Greg Clayton6beaaa62011-01-17 03:46:26 +00001793 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton8cf05932010-07-22 18:30:50 +00001794
Greg Clayton6beaaa62011-01-17 03:46:26 +00001795 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001796 assert (identifier_table != NULL);
1797
1798 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1799
Sean Callanan78e37602011-01-27 04:42:51 +00001800 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001801 if (class_type)
1802 {
Sean Callanan78e37602011-01-27 04:42:51 +00001803 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001804
1805 if (objc_class_type)
1806 {
1807 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1808
1809 if (class_interface_decl)
1810 {
1811 clang::Expr *bit_width = NULL;
1812 if (bitfield_bit_size != 0)
1813 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001814 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1815 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Greg Clayton8cf05932010-07-22 18:30:50 +00001816 }
1817
Greg Clayton6beaaa62011-01-17 03:46:26 +00001818 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast,
Greg Clayton9e409562010-07-28 02:04:09 +00001819 class_interface_decl,
1820 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001821 SourceLocation(),
Greg Clayton9e409562010-07-28 02:04:09 +00001822 &identifier_table->get(name), // Identifier
1823 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1824 NULL, // TypeSourceInfo *
1825 ConvertAccessTypeToObjCIvarAccessControl (access),
1826 bit_width,
Greg Clayton0fffff52010-09-24 05:15:53 +00001827 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001828
1829 if (field)
1830 {
1831 class_interface_decl->addDecl(field);
1832 return true;
1833 }
Greg Clayton8cf05932010-07-22 18:30:50 +00001834 }
1835 }
1836 }
1837 return false;
1838}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001839
Greg Clayton9e409562010-07-28 02:04:09 +00001840
1841bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001842ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9e409562010-07-28 02:04:09 +00001843{
1844 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1845
Sean Callanan78e37602011-01-27 04:42:51 +00001846 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton9e409562010-07-28 02:04:09 +00001847 if (class_type)
1848 {
Sean Callanan78e37602011-01-27 04:42:51 +00001849 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001850
1851 if (objc_class_type)
1852 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1853 }
1854 return false;
1855}
1856
1857bool
1858ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1859{
1860 while (class_interface_decl)
1861 {
1862 if (class_interface_decl->ivar_size() > 0)
1863 return true;
1864
1865 if (check_superclass)
1866 class_interface_decl = class_interface_decl->getSuperClass();
1867 else
1868 break;
1869 }
1870 return false;
1871}
Greg Clayton0fffff52010-09-24 05:15:53 +00001872
Greg Clayton1be10fc2010-09-29 01:12:09 +00001873ObjCMethodDecl *
Greg Clayton0fffff52010-09-24 05:15:53 +00001874ClangASTContext::AddMethodToObjCObjectType
1875(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001876 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001877 clang_type_t class_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001878 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton1be10fc2010-09-29 01:12:09 +00001879 clang_type_t method_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001880 lldb::AccessType access
1881)
1882{
1883 if (class_opaque_type == NULL || method_opaque_type == NULL)
1884 return NULL;
1885
Greg Clayton6beaaa62011-01-17 03:46:26 +00001886 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton0fffff52010-09-24 05:15:53 +00001887
Greg Clayton6beaaa62011-01-17 03:46:26 +00001888 assert (ast != NULL);
Greg Clayton0fffff52010-09-24 05:15:53 +00001889 assert (identifier_table != NULL);
1890
1891 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1892
Sean Callanan78e37602011-01-27 04:42:51 +00001893 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton0fffff52010-09-24 05:15:53 +00001894 if (class_type == NULL)
1895 return NULL;
1896
Sean Callanan78e37602011-01-27 04:42:51 +00001897 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton0fffff52010-09-24 05:15:53 +00001898
1899 if (objc_class_type == NULL)
1900 return NULL;
1901
1902 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1903
1904 if (class_interface_decl == NULL)
1905 return NULL;
Greg Clayton9e409562010-07-28 02:04:09 +00001906
Greg Clayton0fffff52010-09-24 05:15:53 +00001907 const char *selector_start = ::strchr (name, ' ');
1908 if (selector_start == NULL)
1909 return NULL;
1910
1911 selector_start++;
1912 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1913 return NULL;
1914 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1915
Greg Clayton450e3f32010-10-12 02:24:53 +00001916 size_t len = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +00001917 const char *start;
Greg Clayton450e3f32010-10-12 02:24:53 +00001918 //printf ("name = '%s'\n", name);
1919
1920 unsigned num_selectors_with_args = 0;
1921 for (start = selector_start;
Greg Clayton0fffff52010-09-24 05:15:53 +00001922 start && *start != '\0' && *start != ']';
Greg Clayton450e3f32010-10-12 02:24:53 +00001923 start += len)
Greg Clayton0fffff52010-09-24 05:15:53 +00001924 {
Greg Clayton450e3f32010-10-12 02:24:53 +00001925 len = ::strcspn(start, ":]");
Greg Clayton90f90cd2010-10-27 04:01:14 +00001926 bool has_arg = (start[len] == ':');
1927 if (has_arg)
Greg Clayton450e3f32010-10-12 02:24:53 +00001928 ++num_selectors_with_args;
Greg Clayton0fffff52010-09-24 05:15:53 +00001929 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton90f90cd2010-10-27 04:01:14 +00001930 if (has_arg)
1931 len += 1;
Greg Clayton0fffff52010-09-24 05:15:53 +00001932 }
1933
1934
1935 if (selector_idents.size() == 0)
1936 return 0;
1937
Greg Clayton6beaaa62011-01-17 03:46:26 +00001938 clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton0fffff52010-09-24 05:15:53 +00001939 selector_idents.data());
1940
1941 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1942
1943 // Populate the method decl with parameter decls
Sean Callanan78e37602011-01-27 04:42:51 +00001944 const clang::Type *method_type(method_qual_type.getTypePtr());
Greg Clayton0fffff52010-09-24 05:15:53 +00001945
1946 if (method_type == NULL)
1947 return NULL;
1948
Sean Callanan78e37602011-01-27 04:42:51 +00001949 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001950
1951 if (!method_function_prototype)
1952 return NULL;
1953
1954
1955 bool is_variadic = false;
1956 bool is_synthesized = false;
1957 bool is_defined = false;
1958 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1959
1960 const unsigned num_args = method_function_prototype->getNumArgs();
1961
Greg Clayton6beaaa62011-01-17 03:46:26 +00001962 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001963 SourceLocation(), // beginLoc,
1964 SourceLocation(), // endLoc,
1965 method_selector,
1966 method_function_prototype->getResultType(),
1967 NULL, // TypeSourceInfo *ResultTInfo,
1968 GetDeclContextForType (class_opaque_type),
1969 name[0] == '-',
1970 is_variadic,
1971 is_synthesized,
1972 is_defined,
1973 imp_control,
1974 num_args);
1975
1976
1977 if (objc_method_decl == NULL)
1978 return NULL;
1979
1980 if (num_args > 0)
1981 {
1982 llvm::SmallVector<ParmVarDecl *, 12> params;
1983
1984 for (int param_index = 0; param_index < num_args; ++param_index)
1985 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001986 params.push_back (ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001987 objc_method_decl,
1988 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001989 SourceLocation(),
Greg Clayton0fffff52010-09-24 05:15:53 +00001990 NULL, // anonymous
1991 method_function_prototype->getArgType(param_index),
1992 NULL,
1993 SC_Auto,
1994 SC_Auto,
1995 NULL));
1996 }
1997
Greg Clayton6beaaa62011-01-17 03:46:26 +00001998 objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args);
Greg Clayton0fffff52010-09-24 05:15:53 +00001999 }
2000
2001 class_interface_decl->addDecl (objc_method_decl);
2002
2003
2004 return objc_method_decl;
2005}
2006
2007
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002008uint32_t
Greg Clayton73b472d2010-10-27 03:32:59 +00002009ClangASTContext::GetTypeInfo
2010(
2011 clang_type_t clang_type,
Greg Clayton6beaaa62011-01-17 03:46:26 +00002012 clang::ASTContext *ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002013 clang_type_t *pointee_or_element_clang_type
2014)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002015{
2016 if (clang_type == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00002017 return 0;
2018
2019 if (pointee_or_element_clang_type)
2020 *pointee_or_element_clang_type = NULL;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002021
2022 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2023
2024 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2025 switch (type_class)
2026 {
Sean Callanana2424172010-10-25 00:29:48 +00002027 case clang::Type::Builtin:
2028 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2029 {
Sean Callanana2424172010-10-25 00:29:48 +00002030 case clang::BuiltinType::ObjCId:
2031 case clang::BuiltinType::ObjCClass:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002032 if (ast && pointee_or_element_clang_type)
2033 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanana2424172010-10-25 00:29:48 +00002034 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002035
2036 default:
2037 break;
Sean Callanana2424172010-10-25 00:29:48 +00002038 }
2039 return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002040
2041 case clang::Type::BlockPointer:
2042 if (pointee_or_element_clang_type)
2043 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2044 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
2045
Greg Clayton49462ea2011-01-15 02:52:14 +00002046 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002047
2048 case clang::Type::ConstantArray:
2049 case clang::Type::DependentSizedArray:
2050 case clang::Type::IncompleteArray:
2051 case clang::Type::VariableArray:
2052 if (pointee_or_element_clang_type)
2053 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
2054 return eTypeHasChildren | eTypeIsArray;
2055
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002056 case clang::Type::DependentName: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002057 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
2058 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
2059 case clang::Type::Decltype: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002060
2061 case clang::Type::Enum:
2062 if (pointee_or_element_clang_type)
2063 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
2064 return eTypeIsEnumeration | eTypeHasValue;
2065
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002066 case clang::Type::Elaborated: return 0;
2067 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
2068 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
2069 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002070 case clang::Type::InjectedClassName: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002071
2072 case clang::Type::LValueReference:
2073 case clang::Type::RValueReference:
2074 if (pointee_or_element_clang_type)
2075 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
2076 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
2077
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002078 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002079
2080 case clang::Type::ObjCObjectPointer:
2081 if (pointee_or_element_clang_type)
2082 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2083 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
2084
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002085 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2086 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Clayton73b472d2010-10-27 03:32:59 +00002087
2088 case clang::Type::Pointer:
2089 if (pointee_or_element_clang_type)
2090 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2091 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
2092
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002093 case clang::Type::Record:
2094 if (qual_type->getAsCXXRecordDecl())
2095 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
2096 else
2097 return eTypeHasChildren | eTypeIsStructUnion;
2098 break;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002099 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
2100 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
2101 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Clayton73b472d2010-10-27 03:32:59 +00002102
2103 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002104 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00002105 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002106 pointee_or_element_clang_type);
2107
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002108 case clang::Type::TypeOfExpr: return 0;
2109 case clang::Type::TypeOf: return 0;
2110 case clang::Type::UnresolvedUsing: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002111 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
2112 default: return 0;
2113 }
2114 return 0;
2115}
2116
Greg Clayton9e409562010-07-28 02:04:09 +00002117
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002118#pragma mark Aggregate Types
2119
2120bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00002121ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002122{
2123 if (clang_type == NULL)
2124 return false;
2125
2126 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2127
Greg Clayton737b9322010-09-13 03:32:57 +00002128 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2129 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002130 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002131 case clang::Type::IncompleteArray:
2132 case clang::Type::VariableArray:
2133 case clang::Type::ConstantArray:
2134 case clang::Type::ExtVector:
2135 case clang::Type::Vector:
2136 case clang::Type::Record:
Greg Clayton9e409562010-07-28 02:04:09 +00002137 case clang::Type::ObjCObject:
2138 case clang::Type::ObjCInterface:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002139 return true;
2140
Greg Claytone1a916a2010-07-21 22:12:05 +00002141 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002142 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002143
2144 default:
2145 break;
2146 }
2147 // The clang type does have a value
2148 return false;
2149}
2150
2151uint32_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00002152ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002153{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002154 if (clang_type == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002155 return 0;
2156
2157 uint32_t num_children = 0;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002158 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00002159 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2160 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002161 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002162 case clang::Type::Builtin:
2163 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2164 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002165 case clang::BuiltinType::ObjCId: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002166 case clang::BuiltinType::ObjCClass: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002167 num_children = 1;
Greg Clayton73b472d2010-10-27 03:32:59 +00002168 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002169
2170 default:
2171 break;
2172 }
2173 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002174
Greg Clayton49462ea2011-01-15 02:52:14 +00002175 case clang::Type::Complex: return 0;
Greg Clayton54979cd2010-12-15 05:08:08 +00002176
Greg Claytone1a916a2010-07-21 22:12:05 +00002177 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002178 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002179 {
2180 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2181 const RecordDecl *record_decl = record_type->getDecl();
2182 assert(record_decl);
2183 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2184 if (cxx_record_decl)
2185 {
2186 if (omit_empty_base_classes)
2187 {
2188 // Check each base classes to see if it or any of its
2189 // base classes contain any fields. This can help
2190 // limit the noise in variable views by not having to
2191 // show base classes that contain no members.
2192 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2193 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2194 base_class != base_class_end;
2195 ++base_class)
2196 {
2197 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2198
2199 // Skip empty base classes
2200 if (RecordHasFields(base_class_decl) == false)
2201 continue;
2202
2203 num_children++;
2204 }
2205 }
2206 else
2207 {
2208 // Include all base classes
2209 num_children += cxx_record_decl->getNumBases();
2210 }
2211
2212 }
2213 RecordDecl::field_iterator field, field_end;
2214 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2215 ++num_children;
2216 }
2217 break;
2218
Greg Clayton9e409562010-07-28 02:04:09 +00002219 case clang::Type::ObjCObject:
2220 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002221 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002222 {
Sean Callanan78e37602011-01-27 04:42:51 +00002223 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002224 assert (objc_class_type);
2225 if (objc_class_type)
2226 {
2227 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2228
2229 if (class_interface_decl)
2230 {
2231
2232 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2233 if (superclass_interface_decl)
2234 {
2235 if (omit_empty_base_classes)
2236 {
2237 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2238 ++num_children;
2239 }
2240 else
2241 ++num_children;
2242 }
2243
2244 num_children += class_interface_decl->ivar_size();
2245 }
2246 }
2247 }
2248 break;
2249
2250 case clang::Type::ObjCObjectPointer:
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002251 {
Sean Callanan78e37602011-01-27 04:42:51 +00002252 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002253 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002254 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2255 pointee_type.getAsOpaquePtr(),
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002256 omit_empty_base_classes);
2257 // If this type points to a simple type, then it has 1 child
2258 if (num_pointee_children == 0)
2259 num_children = 1;
2260 else
2261 num_children = num_pointee_children;
2262 }
2263 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002264
Greg Claytone1a916a2010-07-21 22:12:05 +00002265 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002266 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2267 break;
2268
Greg Claytone1a916a2010-07-21 22:12:05 +00002269 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002270 {
Sean Callanan78e37602011-01-27 04:42:51 +00002271 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002272 QualType pointee_type (pointer_type->getPointeeType());
Greg Clayton6beaaa62011-01-17 03:46:26 +00002273 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2274 pointee_type.getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00002275 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002276 if (num_pointee_children == 0)
Greg Clayton54979cd2010-12-15 05:08:08 +00002277 {
2278 // We have a pointer to a pointee type that claims it has no children.
2279 // We will want to look at
2280 num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
2281 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002282 else
2283 num_children = num_pointee_children;
2284 }
2285 break;
2286
Greg Clayton73b472d2010-10-27 03:32:59 +00002287 case clang::Type::LValueReference:
2288 case clang::Type::RValueReference:
2289 {
Sean Callanan78e37602011-01-27 04:42:51 +00002290 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002291 QualType pointee_type = reference_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002292 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2293 pointee_type.getAsOpaquePtr(),
Greg Clayton73b472d2010-10-27 03:32:59 +00002294 omit_empty_base_classes);
2295 // If this type points to a simple type, then it has 1 child
2296 if (num_pointee_children == 0)
2297 num_children = 1;
2298 else
2299 num_children = num_pointee_children;
2300 }
2301 break;
2302
2303
Greg Claytone1a916a2010-07-21 22:12:05 +00002304 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002305 num_children = ClangASTContext::GetNumChildren (ast,
2306 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2307 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002308 break;
2309
2310 default:
2311 break;
2312 }
2313 return num_children;
2314}
2315
Greg Clayton54979cd2010-12-15 05:08:08 +00002316// If a pointer to a pointee type (the clang_type arg) says that it has no
2317// children, then we either need to trust it, or override it and return a
2318// different result. For example, an "int *" has one child that is an integer,
2319// but a function pointer doesn't have any children. Likewise if a Record type
2320// claims it has no children, then there really is nothing to show.
2321uint32_t
2322ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
2323{
2324 if (clang_type == NULL)
2325 return 0;
2326
2327 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2328 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2329 switch (type_class)
2330 {
Greg Clayton97a43712011-01-08 22:26:47 +00002331 case clang::Type::Builtin:
2332 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2333 {
Greg Clayton7260f622011-04-18 08:33:37 +00002334 case clang::BuiltinType::UnknownAny:
Greg Clayton97a43712011-01-08 22:26:47 +00002335 case clang::BuiltinType::Void:
2336 case clang::BuiltinType::NullPtr:
2337 return 0;
2338 case clang::BuiltinType::Bool:
2339 case clang::BuiltinType::Char_U:
2340 case clang::BuiltinType::UChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002341 case clang::BuiltinType::WChar_U:
Greg Clayton97a43712011-01-08 22:26:47 +00002342 case clang::BuiltinType::Char16:
2343 case clang::BuiltinType::Char32:
2344 case clang::BuiltinType::UShort:
2345 case clang::BuiltinType::UInt:
2346 case clang::BuiltinType::ULong:
2347 case clang::BuiltinType::ULongLong:
2348 case clang::BuiltinType::UInt128:
2349 case clang::BuiltinType::Char_S:
2350 case clang::BuiltinType::SChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002351 case clang::BuiltinType::WChar_S:
Greg Clayton97a43712011-01-08 22:26:47 +00002352 case clang::BuiltinType::Short:
2353 case clang::BuiltinType::Int:
2354 case clang::BuiltinType::Long:
2355 case clang::BuiltinType::LongLong:
2356 case clang::BuiltinType::Int128:
2357 case clang::BuiltinType::Float:
2358 case clang::BuiltinType::Double:
2359 case clang::BuiltinType::LongDouble:
2360 case clang::BuiltinType::Dependent:
2361 case clang::BuiltinType::Overload:
Greg Clayton97a43712011-01-08 22:26:47 +00002362 case clang::BuiltinType::ObjCId:
2363 case clang::BuiltinType::ObjCClass:
2364 case clang::BuiltinType::ObjCSel:
Sean Callanand12cf8bb2011-05-15 22:34:38 +00002365 case clang::BuiltinType::BoundMember:
Greg Clayton97a43712011-01-08 22:26:47 +00002366 return 1;
2367 }
2368 break;
2369
Greg Clayton49462ea2011-01-15 02:52:14 +00002370 case clang::Type::Complex: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00002371 case clang::Type::Pointer: return 1;
2372 case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
2373 case clang::Type::LValueReference: return 1;
2374 case clang::Type::RValueReference: return 1;
2375 case clang::Type::MemberPointer: return 0;
2376 case clang::Type::ConstantArray: return 0;
2377 case clang::Type::IncompleteArray: return 0;
2378 case clang::Type::VariableArray: return 0;
2379 case clang::Type::DependentSizedArray: return 0;
2380 case clang::Type::DependentSizedExtVector: return 0;
2381 case clang::Type::Vector: return 0;
2382 case clang::Type::ExtVector: return 0;
2383 case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
2384 case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
2385 case clang::Type::UnresolvedUsing: return 0;
2386 case clang::Type::Paren: return 0;
2387 case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2388 case clang::Type::TypeOfExpr: return 0;
2389 case clang::Type::TypeOf: return 0;
2390 case clang::Type::Decltype: return 0;
2391 case clang::Type::Record: return 0;
2392 case clang::Type::Enum: return 1;
2393 case clang::Type::Elaborated: return 1;
2394 case clang::Type::TemplateTypeParm: return 1;
2395 case clang::Type::SubstTemplateTypeParm: return 1;
2396 case clang::Type::TemplateSpecialization: return 1;
2397 case clang::Type::InjectedClassName: return 0;
2398 case clang::Type::DependentName: return 1;
2399 case clang::Type::DependentTemplateSpecialization: return 1;
2400 case clang::Type::ObjCObject: return 0;
2401 case clang::Type::ObjCInterface: return 0;
2402 case clang::Type::ObjCObjectPointer: return 1;
2403 default:
2404 break;
2405 }
2406 return 0;
2407}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002408
Greg Clayton1be10fc2010-09-29 01:12:09 +00002409clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002410ClangASTContext::GetChildClangTypeAtIndex
2411(
2412 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002413 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002414 uint32_t idx,
2415 bool transparent_pointers,
2416 bool omit_empty_base_classes,
2417 std::string& child_name,
2418 uint32_t &child_byte_size,
2419 int32_t &child_byte_offset,
2420 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002421 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002422 bool &child_is_base_class,
2423 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002424)
2425{
2426 if (parent_clang_type)
2427
2428 return GetChildClangTypeAtIndex (getASTContext(),
2429 parent_name,
2430 parent_clang_type,
2431 idx,
2432 transparent_pointers,
2433 omit_empty_base_classes,
2434 child_name,
2435 child_byte_size,
2436 child_byte_offset,
2437 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002438 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002439 child_is_base_class,
2440 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002441 return NULL;
2442}
2443
Greg Clayton1be10fc2010-09-29 01:12:09 +00002444clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002445ClangASTContext::GetChildClangTypeAtIndex
2446(
Greg Clayton6beaaa62011-01-17 03:46:26 +00002447 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002448 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002449 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002450 uint32_t idx,
2451 bool transparent_pointers,
2452 bool omit_empty_base_classes,
2453 std::string& child_name,
2454 uint32_t &child_byte_size,
2455 int32_t &child_byte_offset,
2456 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002457 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002458 bool &child_is_base_class,
2459 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002460)
2461{
2462 if (parent_clang_type == NULL)
2463 return NULL;
2464
Greg Clayton6beaaa62011-01-17 03:46:26 +00002465 if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002466 {
2467 uint32_t bit_offset;
2468 child_bitfield_bit_size = 0;
2469 child_bitfield_bit_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002470 child_is_base_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002471 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00002472 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2473 switch (parent_type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002474 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002475 case clang::Type::Builtin:
2476 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2477 {
2478 case clang::BuiltinType::ObjCId:
2479 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00002480 child_name = "isa";
Greg Clayton6beaaa62011-01-17 03:46:26 +00002481 child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
2482 return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002483
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002484 default:
2485 break;
2486 }
2487 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002488
Greg Claytone1a916a2010-07-21 22:12:05 +00002489 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002490 if (GetCompleteQualType (ast, parent_qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002491 {
2492 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2493 const RecordDecl *record_decl = record_type->getDecl();
2494 assert(record_decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00002495 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002496 uint32_t child_idx = 0;
2497
2498 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2499 if (cxx_record_decl)
2500 {
2501 // We might have base classes to print out first
2502 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2503 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2504 base_class != base_class_end;
2505 ++base_class)
2506 {
2507 const CXXRecordDecl *base_class_decl = NULL;
2508
2509 // Skip empty base classes
2510 if (omit_empty_base_classes)
2511 {
2512 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2513 if (RecordHasFields(base_class_decl) == false)
2514 continue;
2515 }
2516
2517 if (idx == child_idx)
2518 {
2519 if (base_class_decl == NULL)
2520 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2521
2522
2523 if (base_class->isVirtual())
Greg Clayton6ed95942011-01-22 07:12:45 +00002524 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002525 else
Greg Clayton6ed95942011-01-22 07:12:45 +00002526 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002527
2528 // Base classes should be a multiple of 8 bits in size
2529 assert (bit_offset % 8 == 0);
2530 child_byte_offset = bit_offset/8;
2531 std::string base_class_type_name(base_class->getType().getAsString());
2532
2533 child_name.assign(base_class_type_name.c_str());
2534
Greg Clayton6beaaa62011-01-17 03:46:26 +00002535 uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002536
Jim Inghamf46b3382011-04-15 23:42:06 +00002537 // Base classes bit sizes should be a multiple of 8 bits in size
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002538 assert (clang_type_info_bit_size % 8 == 0);
2539 child_byte_size = clang_type_info_bit_size / 8;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002540 child_is_base_class = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002541 return base_class->getType().getAsOpaquePtr();
2542 }
2543 // We don't increment the child index in the for loop since we might
2544 // be skipping empty base classes
2545 ++child_idx;
2546 }
2547 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002548 // Make sure index is in range...
2549 uint32_t field_idx = 0;
2550 RecordDecl::field_iterator field, field_end;
2551 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2552 {
2553 if (idx == child_idx)
2554 {
2555 // Print the member type if requested
2556 // Print the member name and equal sign
2557 child_name.assign(field->getNameAsString().c_str());
2558
2559 // Figure out the type byte size (field_type_info.first) and
2560 // alignment (field_type_info.second) from the AST context.
Greg Clayton6beaaa62011-01-17 03:46:26 +00002561 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
Greg Claytonc982c762010-07-09 20:39:50 +00002562 assert(field_idx < record_layout.getFieldCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002563
2564 child_byte_size = field_type_info.first / 8;
2565
2566 // Figure out the field offset within the current struct/union/class type
2567 bit_offset = record_layout.getFieldOffset (field_idx);
2568 child_byte_offset = bit_offset / 8;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002569 if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002570 child_bitfield_bit_offset = bit_offset % 8;
2571
2572 return field->getType().getAsOpaquePtr();
2573 }
2574 }
2575 }
2576 break;
2577
Greg Clayton9e409562010-07-28 02:04:09 +00002578 case clang::Type::ObjCObject:
2579 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002580 if (GetCompleteQualType (ast, parent_qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002581 {
Sean Callanan78e37602011-01-27 04:42:51 +00002582 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002583 assert (objc_class_type);
2584 if (objc_class_type)
2585 {
2586 uint32_t child_idx = 0;
2587 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2588
2589 if (class_interface_decl)
2590 {
2591
Greg Clayton6beaaa62011-01-17 03:46:26 +00002592 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
Greg Clayton9e409562010-07-28 02:04:09 +00002593 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2594 if (superclass_interface_decl)
2595 {
2596 if (omit_empty_base_classes)
2597 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002598 if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9e409562010-07-28 02:04:09 +00002599 {
2600 if (idx == 0)
2601 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002602 QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
Greg Clayton9e409562010-07-28 02:04:09 +00002603
2604
2605 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2606
Greg Clayton6beaaa62011-01-17 03:46:26 +00002607 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002608
2609 child_byte_size = ivar_type_info.first / 8;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002610 child_byte_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002611 child_is_base_class = true;
Greg Clayton9e409562010-07-28 02:04:09 +00002612
2613 return ivar_qual_type.getAsOpaquePtr();
2614 }
2615
2616 ++child_idx;
2617 }
2618 }
2619 else
2620 ++child_idx;
2621 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002622
2623 const uint32_t superclass_idx = child_idx;
Greg Clayton9e409562010-07-28 02:04:09 +00002624
2625 if (idx < (child_idx + class_interface_decl->ivar_size()))
2626 {
2627 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2628
2629 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2630 {
2631 if (child_idx == idx)
2632 {
2633 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2634
2635 QualType ivar_qual_type(ivar_decl->getType());
2636
2637 child_name.assign(ivar_decl->getNameAsString().c_str());
2638
Greg Clayton6beaaa62011-01-17 03:46:26 +00002639 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002640
2641 child_byte_size = ivar_type_info.first / 8;
2642
2643 // Figure out the field offset within the current struct/union/class type
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002644 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9e409562010-07-28 02:04:09 +00002645 child_byte_offset = bit_offset / 8;
2646
2647 return ivar_qual_type.getAsOpaquePtr();
2648 }
2649 ++child_idx;
2650 }
2651 }
2652 }
2653 }
2654 }
2655 break;
2656
2657 case clang::Type::ObjCObjectPointer:
2658 {
Sean Callanan78e37602011-01-27 04:42:51 +00002659 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002660 QualType pointee_type = pointer_type->getPointeeType();
2661
2662 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2663 {
Greg Claytone221f822011-01-21 01:59:00 +00002664 child_is_deref_of_parent = false;
2665 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002666 return GetChildClangTypeAtIndex (ast,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002667 parent_name,
2668 pointer_type->getPointeeType().getAsOpaquePtr(),
2669 idx,
2670 transparent_pointers,
2671 omit_empty_base_classes,
2672 child_name,
2673 child_byte_size,
2674 child_byte_offset,
2675 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002676 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002677 child_is_base_class,
2678 tmp_child_is_deref_of_parent);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002679 }
2680 else
2681 {
Greg Claytone221f822011-01-21 01:59:00 +00002682 child_is_deref_of_parent = true;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002683 if (parent_name)
2684 {
2685 child_name.assign(1, '*');
2686 child_name += parent_name;
2687 }
2688
2689 // We have a pointer to an simple type
2690 if (idx == 0)
2691 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002692 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002693 assert(clang_type_info.first % 8 == 0);
2694 child_byte_size = clang_type_info.first / 8;
2695 child_byte_offset = 0;
2696 return pointee_type.getAsOpaquePtr();
2697 }
2698 }
Greg Clayton9e409562010-07-28 02:04:09 +00002699 }
2700 break;
2701
Greg Claytone1a916a2010-07-21 22:12:05 +00002702 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002703 {
2704 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2705 const uint64_t element_count = array->getSize().getLimitedValue();
2706
2707 if (idx < element_count)
2708 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002709 if (GetCompleteQualType (ast, array->getElementType()))
2710 {
2711 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002712
Greg Clayton6beaaa62011-01-17 03:46:26 +00002713 char element_name[64];
2714 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002715
Greg Clayton6beaaa62011-01-17 03:46:26 +00002716 child_name.assign(element_name);
2717 assert(field_type_info.first % 8 == 0);
2718 child_byte_size = field_type_info.first / 8;
2719 child_byte_offset = idx * child_byte_size;
2720 return array->getElementType().getAsOpaquePtr();
2721 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002722 }
2723 }
2724 break;
2725
Greg Claytone1a916a2010-07-21 22:12:05 +00002726 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002727 {
Sean Callanan78e37602011-01-27 04:42:51 +00002728 const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002729 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton97a43712011-01-08 22:26:47 +00002730
2731 // Don't dereference "void *" pointers
2732 if (pointee_type->isVoidType())
2733 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002734
2735 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2736 {
Greg Claytone221f822011-01-21 01:59:00 +00002737 child_is_deref_of_parent = false;
2738 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002739 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002740 parent_name,
2741 pointer_type->getPointeeType().getAsOpaquePtr(),
2742 idx,
2743 transparent_pointers,
2744 omit_empty_base_classes,
2745 child_name,
2746 child_byte_size,
2747 child_byte_offset,
2748 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002749 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002750 child_is_base_class,
2751 tmp_child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002752 }
2753 else
2754 {
Greg Claytone221f822011-01-21 01:59:00 +00002755 child_is_deref_of_parent = true;
2756
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002757 if (parent_name)
2758 {
2759 child_name.assign(1, '*');
2760 child_name += parent_name;
2761 }
2762
2763 // We have a pointer to an simple type
2764 if (idx == 0)
2765 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002766 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002767 assert(clang_type_info.first % 8 == 0);
2768 child_byte_size = clang_type_info.first / 8;
2769 child_byte_offset = 0;
2770 return pointee_type.getAsOpaquePtr();
2771 }
2772 }
2773 }
2774 break;
2775
Greg Clayton73b472d2010-10-27 03:32:59 +00002776 case clang::Type::LValueReference:
2777 case clang::Type::RValueReference:
2778 {
Sean Callanan78e37602011-01-27 04:42:51 +00002779 const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002780 QualType pointee_type(reference_type->getPointeeType());
2781 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2782 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2783 {
Greg Claytone221f822011-01-21 01:59:00 +00002784 child_is_deref_of_parent = false;
2785 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002786 return GetChildClangTypeAtIndex (ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002787 parent_name,
2788 pointee_clang_type,
2789 idx,
2790 transparent_pointers,
2791 omit_empty_base_classes,
2792 child_name,
2793 child_byte_size,
2794 child_byte_offset,
2795 child_bitfield_bit_size,
2796 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002797 child_is_base_class,
2798 tmp_child_is_deref_of_parent);
Greg Clayton73b472d2010-10-27 03:32:59 +00002799 }
2800 else
2801 {
2802 if (parent_name)
2803 {
2804 child_name.assign(1, '&');
2805 child_name += parent_name;
2806 }
2807
2808 // We have a pointer to an simple type
2809 if (idx == 0)
2810 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002811 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Clayton73b472d2010-10-27 03:32:59 +00002812 assert(clang_type_info.first % 8 == 0);
2813 child_byte_size = clang_type_info.first / 8;
2814 child_byte_offset = 0;
2815 return pointee_type.getAsOpaquePtr();
2816 }
2817 }
2818 }
2819 break;
2820
Greg Claytone1a916a2010-07-21 22:12:05 +00002821 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002822 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002823 parent_name,
Sean Callanan48114472010-12-13 01:26:27 +00002824 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002825 idx,
2826 transparent_pointers,
2827 omit_empty_base_classes,
2828 child_name,
2829 child_byte_size,
2830 child_byte_offset,
2831 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002832 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002833 child_is_base_class,
2834 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002835 break;
2836
2837 default:
2838 break;
2839 }
2840 }
Greg Clayton19503a22010-07-23 15:37:46 +00002841 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002842}
2843
2844static inline bool
2845BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2846{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002847 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002848}
2849
2850static uint32_t
2851GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2852{
2853 uint32_t num_bases = 0;
2854 if (cxx_record_decl)
2855 {
2856 if (omit_empty_base_classes)
2857 {
2858 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2859 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2860 base_class != base_class_end;
2861 ++base_class)
2862 {
2863 // Skip empty base classes
2864 if (omit_empty_base_classes)
2865 {
2866 if (BaseSpecifierIsEmpty (base_class))
2867 continue;
2868 }
2869 ++num_bases;
2870 }
2871 }
2872 else
2873 num_bases = cxx_record_decl->getNumBases();
2874 }
2875 return num_bases;
2876}
2877
2878
2879static uint32_t
2880GetIndexForRecordBase
2881(
2882 const RecordDecl *record_decl,
2883 const CXXBaseSpecifier *base_spec,
2884 bool omit_empty_base_classes
2885)
2886{
2887 uint32_t child_idx = 0;
2888
2889 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2890
2891// const char *super_name = record_decl->getNameAsCString();
2892// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2893// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2894//
2895 if (cxx_record_decl)
2896 {
2897 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2898 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2899 base_class != base_class_end;
2900 ++base_class)
2901 {
2902 if (omit_empty_base_classes)
2903 {
2904 if (BaseSpecifierIsEmpty (base_class))
2905 continue;
2906 }
2907
2908// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2909// child_idx,
2910// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2911//
2912//
2913 if (base_class == base_spec)
2914 return child_idx;
2915 ++child_idx;
2916 }
2917 }
2918
2919 return UINT32_MAX;
2920}
2921
2922
2923static uint32_t
2924GetIndexForRecordChild
2925(
2926 const RecordDecl *record_decl,
2927 NamedDecl *canonical_decl,
2928 bool omit_empty_base_classes
2929)
2930{
2931 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2932
2933// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2934//
2935//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2936// if (cxx_record_decl)
2937// {
2938// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2939// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2940// base_class != base_class_end;
2941// ++base_class)
2942// {
2943// if (omit_empty_base_classes)
2944// {
2945// if (BaseSpecifierIsEmpty (base_class))
2946// continue;
2947// }
2948//
2949//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2950//// record_decl->getNameAsCString(),
2951//// canonical_decl->getNameAsCString(),
2952//// child_idx,
2953//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2954//
2955//
2956// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2957// if (curr_base_class_decl == canonical_decl)
2958// {
2959// return child_idx;
2960// }
2961// ++child_idx;
2962// }
2963// }
2964//
2965// const uint32_t num_bases = child_idx;
2966 RecordDecl::field_iterator field, field_end;
2967 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2968 field != field_end;
2969 ++field, ++child_idx)
2970 {
2971// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2972// record_decl->getNameAsCString(),
2973// canonical_decl->getNameAsCString(),
2974// child_idx - num_bases,
2975// field->getNameAsCString());
2976
2977 if (field->getCanonicalDecl() == canonical_decl)
2978 return child_idx;
2979 }
2980
2981 return UINT32_MAX;
2982}
2983
2984// Look for a child member (doesn't include base classes, but it does include
2985// their members) in the type hierarchy. Returns an index path into "clang_type"
2986// on how to reach the appropriate member.
2987//
2988// class A
2989// {
2990// public:
2991// int m_a;
2992// int m_b;
2993// };
2994//
2995// class B
2996// {
2997// };
2998//
2999// class C :
3000// public B,
3001// public A
3002// {
3003// };
3004//
3005// If we have a clang type that describes "class C", and we wanted to looked
3006// "m_b" in it:
3007//
3008// With omit_empty_base_classes == false we would get an integer array back with:
3009// { 1, 1 }
3010// The first index 1 is the child index for "class A" within class C
3011// The second index 1 is the child index for "m_b" within class A
3012//
3013// With omit_empty_base_classes == true we would get an integer array back with:
3014// { 0, 1 }
3015// 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)
3016// The second index 1 is the child index for "m_b" within class A
3017
3018size_t
3019ClangASTContext::GetIndexOfChildMemberWithName
3020(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003021 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003022 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003023 const char *name,
3024 bool omit_empty_base_classes,
3025 std::vector<uint32_t>& child_indexes
3026)
3027{
3028 if (clang_type && name && name[0])
3029 {
3030 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003031 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3032 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003033 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003034 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003035 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003036 {
3037 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3038 const RecordDecl *record_decl = record_type->getDecl();
3039
3040 assert(record_decl);
3041 uint32_t child_idx = 0;
3042
3043 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3044
3045 // Try and find a field that matches NAME
3046 RecordDecl::field_iterator field, field_end;
3047 StringRef name_sref(name);
3048 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3049 field != field_end;
3050 ++field, ++child_idx)
3051 {
3052 if (field->getName().equals (name_sref))
3053 {
3054 // We have to add on the number of base classes to this index!
3055 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
3056 return child_indexes.size();
3057 }
3058 }
3059
3060 if (cxx_record_decl)
3061 {
3062 const RecordDecl *parent_record_decl = cxx_record_decl;
3063
3064 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
3065
3066 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
3067 // Didn't find things easily, lets let clang do its thang...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003068 IdentifierInfo & ident_ref = ast->Idents.get(name, name + strlen (name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003069 DeclarationName decl_name(&ident_ref);
3070
3071 CXXBasePaths paths;
3072 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
3073 decl_name.getAsOpaquePtr(),
3074 paths))
3075 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003076 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
3077 for (path = paths.begin(); path != path_end; ++path)
3078 {
3079 const size_t num_path_elements = path->size();
3080 for (size_t e=0; e<num_path_elements; ++e)
3081 {
3082 CXXBasePathElement elem = (*path)[e];
3083
3084 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
3085 if (child_idx == UINT32_MAX)
3086 {
3087 child_indexes.clear();
3088 return 0;
3089 }
3090 else
3091 {
3092 child_indexes.push_back (child_idx);
3093 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
3094 }
3095 }
3096 DeclContext::lookup_iterator named_decl_pos;
3097 for (named_decl_pos = path->Decls.first;
3098 named_decl_pos != path->Decls.second && parent_record_decl;
3099 ++named_decl_pos)
3100 {
3101 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
3102
3103 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
3104 if (child_idx == UINT32_MAX)
3105 {
3106 child_indexes.clear();
3107 return 0;
3108 }
3109 else
3110 {
3111 child_indexes.push_back (child_idx);
3112 }
3113 }
3114 }
3115 return child_indexes.size();
3116 }
3117 }
3118
3119 }
3120 break;
3121
Greg Clayton9e409562010-07-28 02:04:09 +00003122 case clang::Type::ObjCObject:
3123 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003124 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003125 {
3126 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003127 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003128 assert (objc_class_type);
3129 if (objc_class_type)
3130 {
3131 uint32_t child_idx = 0;
3132 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3133
3134 if (class_interface_decl)
3135 {
3136 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3137 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3138
Greg Clayton6ba78152010-09-18 02:11:07 +00003139 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9e409562010-07-28 02:04:09 +00003140 {
3141 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3142
3143 if (ivar_decl->getName().equals (name_sref))
3144 {
3145 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3146 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3147 ++child_idx;
3148
3149 child_indexes.push_back (child_idx);
3150 return child_indexes.size();
3151 }
3152 }
3153
3154 if (superclass_interface_decl)
3155 {
3156 // The super class index is always zero for ObjC classes,
3157 // so we push it onto the child indexes in case we find
3158 // an ivar in our superclass...
3159 child_indexes.push_back (0);
3160
Greg Clayton6beaaa62011-01-17 03:46:26 +00003161 if (GetIndexOfChildMemberWithName (ast,
3162 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00003163 name,
3164 omit_empty_base_classes,
3165 child_indexes))
3166 {
3167 // We did find an ivar in a superclass so just
3168 // return the results!
3169 return child_indexes.size();
3170 }
3171
3172 // We didn't find an ivar matching "name" in our
3173 // superclass, pop the superclass zero index that
3174 // we pushed on above.
3175 child_indexes.pop_back();
3176 }
3177 }
3178 }
3179 }
3180 break;
3181
3182 case clang::Type::ObjCObjectPointer:
3183 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003184 return GetIndexOfChildMemberWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003185 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3186 name,
3187 omit_empty_base_classes,
3188 child_indexes);
3189 }
3190 break;
3191
3192
Greg Claytone1a916a2010-07-21 22:12:05 +00003193 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003194 {
3195// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3196// const uint64_t element_count = array->getSize().getLimitedValue();
3197//
3198// if (idx < element_count)
3199// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003200// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003201//
3202// char element_name[32];
3203// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3204//
3205// child_name.assign(element_name);
3206// assert(field_type_info.first % 8 == 0);
3207// child_byte_size = field_type_info.first / 8;
3208// child_byte_offset = idx * child_byte_size;
3209// return array->getElementType().getAsOpaquePtr();
3210// }
3211 }
3212 break;
3213
Greg Claytone1a916a2010-07-21 22:12:05 +00003214// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003215// {
3216// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3217// QualType pointee_type = mem_ptr_type->getPointeeType();
3218//
3219// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3220// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003221// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003222// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3223// name);
3224// }
3225// }
3226// break;
3227//
Greg Claytone1a916a2010-07-21 22:12:05 +00003228 case clang::Type::LValueReference:
3229 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003230 {
Sean Callanan78e37602011-01-27 04:42:51 +00003231 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003232 QualType pointee_type = reference_type->getPointeeType();
3233
3234 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3235 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003236 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003237 reference_type->getPointeeType().getAsOpaquePtr(),
3238 name,
3239 omit_empty_base_classes,
3240 child_indexes);
3241 }
3242 }
3243 break;
3244
Greg Claytone1a916a2010-07-21 22:12:05 +00003245 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003246 {
Sean Callanan78e37602011-01-27 04:42:51 +00003247 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003248 QualType pointee_type = pointer_type->getPointeeType();
3249
3250 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3251 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003252 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003253 pointer_type->getPointeeType().getAsOpaquePtr(),
3254 name,
3255 omit_empty_base_classes,
3256 child_indexes);
3257 }
3258 else
3259 {
3260// if (parent_name)
3261// {
3262// child_name.assign(1, '*');
3263// child_name += parent_name;
3264// }
3265//
3266// // We have a pointer to an simple type
3267// if (idx == 0)
3268// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003269// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003270// assert(clang_type_info.first % 8 == 0);
3271// child_byte_size = clang_type_info.first / 8;
3272// child_byte_offset = 0;
3273// return pointee_type.getAsOpaquePtr();
3274// }
3275 }
3276 }
3277 break;
3278
Greg Claytone1a916a2010-07-21 22:12:05 +00003279 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003280 return GetIndexOfChildMemberWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003281 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003282 name,
3283 omit_empty_base_classes,
3284 child_indexes);
3285
3286 default:
3287 break;
3288 }
3289 }
3290 return 0;
3291}
3292
3293
3294// Get the index of the child of "clang_type" whose name matches. This function
3295// doesn't descend into the children, but only looks one level deep and name
3296// matches can include base class names.
3297
3298uint32_t
3299ClangASTContext::GetIndexOfChildWithName
3300(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003301 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003302 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003303 const char *name,
3304 bool omit_empty_base_classes
3305)
3306{
3307 if (clang_type && name && name[0])
3308 {
3309 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00003310
Greg Clayton737b9322010-09-13 03:32:57 +00003311 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9e409562010-07-28 02:04:09 +00003312
Greg Clayton737b9322010-09-13 03:32:57 +00003313 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003314 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003315 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003316 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003317 {
3318 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3319 const RecordDecl *record_decl = record_type->getDecl();
3320
3321 assert(record_decl);
3322 uint32_t child_idx = 0;
3323
3324 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3325
3326 if (cxx_record_decl)
3327 {
3328 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3329 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3330 base_class != base_class_end;
3331 ++base_class)
3332 {
3333 // Skip empty base classes
3334 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3335 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3336 continue;
3337
3338 if (base_class->getType().getAsString().compare (name) == 0)
3339 return child_idx;
3340 ++child_idx;
3341 }
3342 }
3343
3344 // Try and find a field that matches NAME
3345 RecordDecl::field_iterator field, field_end;
3346 StringRef name_sref(name);
3347 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3348 field != field_end;
3349 ++field, ++child_idx)
3350 {
3351 if (field->getName().equals (name_sref))
3352 return child_idx;
3353 }
3354
3355 }
3356 break;
3357
Greg Clayton9e409562010-07-28 02:04:09 +00003358 case clang::Type::ObjCObject:
3359 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003360 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003361 {
3362 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003363 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003364 assert (objc_class_type);
3365 if (objc_class_type)
3366 {
3367 uint32_t child_idx = 0;
3368 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3369
3370 if (class_interface_decl)
3371 {
3372 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3373 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3374
3375 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3376 {
3377 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3378
3379 if (ivar_decl->getName().equals (name_sref))
3380 {
3381 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3382 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3383 ++child_idx;
3384
3385 return child_idx;
3386 }
3387 }
3388
3389 if (superclass_interface_decl)
3390 {
3391 if (superclass_interface_decl->getName().equals (name_sref))
3392 return 0;
3393 }
3394 }
3395 }
3396 }
3397 break;
3398
3399 case clang::Type::ObjCObjectPointer:
3400 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003401 return GetIndexOfChildWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003402 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3403 name,
3404 omit_empty_base_classes);
3405 }
3406 break;
3407
Greg Claytone1a916a2010-07-21 22:12:05 +00003408 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003409 {
3410// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3411// const uint64_t element_count = array->getSize().getLimitedValue();
3412//
3413// if (idx < element_count)
3414// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003415// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003416//
3417// char element_name[32];
3418// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3419//
3420// child_name.assign(element_name);
3421// assert(field_type_info.first % 8 == 0);
3422// child_byte_size = field_type_info.first / 8;
3423// child_byte_offset = idx * child_byte_size;
3424// return array->getElementType().getAsOpaquePtr();
3425// }
3426 }
3427 break;
3428
Greg Claytone1a916a2010-07-21 22:12:05 +00003429// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003430// {
3431// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3432// QualType pointee_type = mem_ptr_type->getPointeeType();
3433//
3434// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3435// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003436// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003437// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3438// name);
3439// }
3440// }
3441// break;
3442//
Greg Claytone1a916a2010-07-21 22:12:05 +00003443 case clang::Type::LValueReference:
3444 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003445 {
Sean Callanan78e37602011-01-27 04:42:51 +00003446 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003447 QualType pointee_type = reference_type->getPointeeType();
3448
3449 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3450 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003451 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003452 reference_type->getPointeeType().getAsOpaquePtr(),
3453 name,
3454 omit_empty_base_classes);
3455 }
3456 }
3457 break;
3458
Greg Claytone1a916a2010-07-21 22:12:05 +00003459 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003460 {
Sean Callanan78e37602011-01-27 04:42:51 +00003461 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003462 QualType pointee_type = pointer_type->getPointeeType();
3463
3464 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3465 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003466 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003467 pointer_type->getPointeeType().getAsOpaquePtr(),
3468 name,
3469 omit_empty_base_classes);
3470 }
3471 else
3472 {
3473// if (parent_name)
3474// {
3475// child_name.assign(1, '*');
3476// child_name += parent_name;
3477// }
3478//
3479// // We have a pointer to an simple type
3480// if (idx == 0)
3481// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003482// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003483// assert(clang_type_info.first % 8 == 0);
3484// child_byte_size = clang_type_info.first / 8;
3485// child_byte_offset = 0;
3486// return pointee_type.getAsOpaquePtr();
3487// }
3488 }
3489 }
3490 break;
3491
Greg Claytone1a916a2010-07-21 22:12:05 +00003492 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003493 return GetIndexOfChildWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003494 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003495 name,
3496 omit_empty_base_classes);
3497
3498 default:
3499 break;
3500 }
3501 }
3502 return UINT32_MAX;
3503}
3504
3505#pragma mark TagType
3506
3507bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003508ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003509{
3510 if (tag_clang_type)
3511 {
3512 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00003513 const clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003514 if (clang_type)
3515 {
Sean Callanan78e37602011-01-27 04:42:51 +00003516 const TagType *tag_type = dyn_cast<TagType>(clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003517 if (tag_type)
3518 {
3519 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3520 if (tag_decl)
3521 {
3522 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3523 return true;
3524 }
3525 }
3526 }
3527 }
3528 return false;
3529}
3530
3531
3532#pragma mark DeclContext Functions
3533
3534DeclContext *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003535ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003536{
3537 if (clang_type == NULL)
3538 return NULL;
3539
3540 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003541 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3542 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003543 {
Greg Clayton9e409562010-07-28 02:04:09 +00003544 case clang::Type::FunctionNoProto: break;
3545 case clang::Type::FunctionProto: break;
3546 case clang::Type::IncompleteArray: break;
3547 case clang::Type::VariableArray: break;
3548 case clang::Type::ConstantArray: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003549 case clang::Type::DependentSizedArray: break;
Greg Clayton9e409562010-07-28 02:04:09 +00003550 case clang::Type::ExtVector: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003551 case clang::Type::DependentSizedExtVector: break;
Greg Clayton9e409562010-07-28 02:04:09 +00003552 case clang::Type::Vector: break;
3553 case clang::Type::Builtin: break;
3554 case clang::Type::BlockPointer: break;
3555 case clang::Type::Pointer: break;
3556 case clang::Type::LValueReference: break;
3557 case clang::Type::RValueReference: break;
3558 case clang::Type::MemberPointer: break;
3559 case clang::Type::Complex: break;
3560 case clang::Type::ObjCObject: break;
3561 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3562 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3563 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3564 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
Sean Callanan48114472010-12-13 01:26:27 +00003565 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003566
Greg Clayton9e409562010-07-28 02:04:09 +00003567 case clang::Type::TypeOfExpr: break;
3568 case clang::Type::TypeOf: break;
3569 case clang::Type::Decltype: break;
3570 //case clang::Type::QualifiedName: break;
3571 case clang::Type::TemplateSpecialization: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003572 case clang::Type::DependentTemplateSpecialization: break;
3573 case clang::Type::TemplateTypeParm: break;
3574 case clang::Type::SubstTemplateTypeParm: break;
3575 case clang::Type::SubstTemplateTypeParmPack:break;
3576 case clang::Type::PackExpansion: break;
3577 case clang::Type::UnresolvedUsing: break;
3578 case clang::Type::Paren: break;
3579 case clang::Type::Elaborated: break;
3580 case clang::Type::Attributed: break;
3581 case clang::Type::Auto: break;
3582 case clang::Type::InjectedClassName: break;
3583 case clang::Type::DependentName: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003584 }
3585 // No DeclContext in this type...
3586 return NULL;
3587}
3588
3589#pragma mark Namespace Declarations
3590
3591NamespaceDecl *
3592ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3593{
3594 // TODO: Do something intelligent with the Declaration object passed in
3595 // like maybe filling in the SourceLocation with it...
3596 if (name)
3597 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003598 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003599 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00003600 decl_ctx = ast->getTranslationUnitDecl();
Sean Callananfb0b7582011-03-15 00:17:19 +00003601 return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &ast->Idents.get(name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003602 }
3603 return NULL;
3604}
3605
3606
3607#pragma mark Function Types
3608
3609FunctionDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003610ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003611{
3612 if (name)
3613 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003614 ASTContext *ast = getASTContext();
3615 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003616
3617 if (name && name[0])
3618 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003619 return FunctionDecl::Create(*ast,
3620 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003621 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003622 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003623 DeclarationName (&ast->Idents.get(name)),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003624 QualType::getFromOpaquePtr(function_clang_type),
3625 NULL,
3626 (FunctionDecl::StorageClass)storage,
3627 (FunctionDecl::StorageClass)storage,
3628 is_inline);
3629 }
3630 else
3631 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003632 return FunctionDecl::Create(*ast,
3633 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003634 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003635 SourceLocation(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003636 DeclarationName (),
3637 QualType::getFromOpaquePtr(function_clang_type),
3638 NULL,
3639 (FunctionDecl::StorageClass)storage,
3640 (FunctionDecl::StorageClass)storage,
3641 is_inline);
3642 }
3643 }
3644 return NULL;
3645}
3646
Greg Clayton1be10fc2010-09-29 01:12:09 +00003647clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00003648ClangASTContext::CreateFunctionType (ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003649 clang_type_t result_type,
3650 clang_type_t *args,
Sean Callananc81256a2010-09-16 20:40:25 +00003651 unsigned num_args,
3652 bool is_variadic,
3653 unsigned type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003654{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003655 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003656 std::vector<QualType> qual_type_args;
3657 for (unsigned i=0; i<num_args; ++i)
3658 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3659
3660 // TODO: Detect calling convention in DWARF?
Sean Callanan2c777c42011-01-18 23:32:05 +00003661 FunctionProtoType::ExtProtoInfo proto_info;
3662 proto_info.Variadic = is_variadic;
Sean Callananfb0b7582011-03-15 00:17:19 +00003663 proto_info.ExceptionSpecType = EST_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00003664 proto_info.TypeQuals = type_quals;
Sean Callananfb0b7582011-03-15 00:17:19 +00003665 proto_info.RefQualifier = RQ_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00003666 proto_info.NumExceptions = 0;
3667 proto_info.Exceptions = NULL;
3668
Greg Clayton6beaaa62011-01-17 03:46:26 +00003669 return ast->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton471b31c2010-07-20 22:52:08 +00003670 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003671 qual_type_args.size(),
Sean Callanan2c777c42011-01-18 23:32:05 +00003672 proto_info).getAsOpaquePtr(); // NoReturn);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003673}
3674
3675ParmVarDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003676ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003677{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003678 ASTContext *ast = getASTContext();
3679 assert (ast != NULL);
3680 return ParmVarDecl::Create(*ast,
3681 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003682 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003683 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003684 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callananc81256a2010-09-16 20:40:25 +00003685 QualType::getFromOpaquePtr(param_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003686 NULL,
3687 (VarDecl::StorageClass)storage,
3688 (VarDecl::StorageClass)storage,
3689 0);
3690}
3691
3692void
3693ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3694{
3695 if (function_decl)
3696 function_decl->setParams (params, num_params);
3697}
3698
3699
3700#pragma mark Array Types
3701
Greg Clayton1be10fc2010-09-29 01:12:09 +00003702clang_type_t
3703ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003704{
3705 if (element_type)
3706 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003707 ASTContext *ast = getASTContext();
3708 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003709 llvm::APInt ap_element_count (64, element_count);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003710 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003711 ap_element_count,
3712 ArrayType::Normal,
3713 0).getAsOpaquePtr(); // ElemQuals
3714 }
3715 return NULL;
3716}
3717
3718
3719#pragma mark TagDecl
3720
3721bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003722ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003723{
3724 if (clang_type)
3725 {
3726 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00003727 const clang::Type *t = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003728 if (t)
3729 {
Sean Callanan78e37602011-01-27 04:42:51 +00003730 const TagType *tag_type = dyn_cast<TagType>(t);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003731 if (tag_type)
3732 {
3733 TagDecl *tag_decl = tag_type->getDecl();
3734 if (tag_decl)
3735 {
3736 tag_decl->startDefinition();
3737 return true;
3738 }
3739 }
3740 }
3741 }
3742 return false;
3743}
3744
3745bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003746ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003747{
3748 if (clang_type)
3749 {
3750 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton14372242010-09-29 03:44:17 +00003751
3752 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3753
3754 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003755 {
Greg Clayton14372242010-09-29 03:44:17 +00003756 cxx_record_decl->completeDefinition();
3757
3758 return true;
3759 }
3760
Sean Callanan78e37602011-01-27 04:42:51 +00003761 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
Sean Callanana2424172010-10-25 00:29:48 +00003762
3763 if (objc_class_type)
3764 {
3765 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3766
3767 class_interface_decl->setForwardDecl(false);
3768 }
3769
Greg Clayton14372242010-09-29 03:44:17 +00003770 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3771
3772 if (enum_type)
3773 {
3774 EnumDecl *enum_decl = enum_type->getDecl();
3775
3776 if (enum_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003777 {
Greg Clayton14372242010-09-29 03:44:17 +00003778 /// TODO This really needs to be fixed.
3779
3780 unsigned NumPositiveBits = 1;
3781 unsigned NumNegativeBits = 0;
3782
Greg Clayton6beaaa62011-01-17 03:46:26 +00003783 ASTContext *ast = getASTContext();
Greg Claytone02b8502010-10-12 04:29:14 +00003784
3785 QualType promotion_qual_type;
3786 // If the enum integer type is less than an integer in bit width,
3787 // then we must promote it to an integer size.
Greg Clayton6beaaa62011-01-17 03:46:26 +00003788 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
Greg Claytone02b8502010-10-12 04:29:14 +00003789 {
3790 if (enum_decl->getIntegerType()->isSignedIntegerType())
Greg Clayton6beaaa62011-01-17 03:46:26 +00003791 promotion_qual_type = ast->IntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003792 else
Greg Clayton6beaaa62011-01-17 03:46:26 +00003793 promotion_qual_type = ast->UnsignedIntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003794 }
3795 else
3796 promotion_qual_type = enum_decl->getIntegerType();
3797
3798 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton14372242010-09-29 03:44:17 +00003799 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003800 }
3801 }
3802 }
3803 return false;
3804}
3805
3806
3807#pragma mark Enumeration Types
3808
Greg Clayton1be10fc2010-09-29 01:12:09 +00003809clang_type_t
Greg Claytonca512b32011-01-14 04:54:56 +00003810ClangASTContext::CreateEnumerationType
3811(
3812 const char *name,
3813 DeclContext *decl_ctx,
3814 const Declaration &decl,
3815 clang_type_t integer_qual_type
3816)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003817{
3818 // TODO: Do something intelligent with the Declaration object passed in
3819 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003820 ASTContext *ast = getASTContext();
3821 assert (ast != NULL);
Greg Claytone02b8502010-10-12 04:29:14 +00003822
3823 // TODO: ask about these...
3824// const bool IsScoped = false;
3825// const bool IsFixed = false;
3826
Greg Clayton6beaaa62011-01-17 03:46:26 +00003827 EnumDecl *enum_decl = EnumDecl::Create (*ast,
Greg Claytonca512b32011-01-14 04:54:56 +00003828 decl_ctx,
Greg Claytone02b8502010-10-12 04:29:14 +00003829 SourceLocation(),
Greg Claytone02b8502010-10-12 04:29:14 +00003830 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003831 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callanan48114472010-12-13 01:26:27 +00003832 NULL,
3833 false, // IsScoped
3834 false, // IsScopedUsingClassTag
3835 false); // IsFixed
Sean Callanan2652ad22011-01-18 01:03:44 +00003836
3837
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003838 if (enum_decl)
Greg Clayton83ff3892010-09-12 23:17:56 +00003839 {
3840 // TODO: check if we should be setting the promotion type too?
3841 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00003842
3843 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
3844
Greg Clayton6beaaa62011-01-17 03:46:26 +00003845 return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Clayton83ff3892010-09-12 23:17:56 +00003846 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003847 return NULL;
3848}
3849
Greg Clayton1be10fc2010-09-29 01:12:09 +00003850clang_type_t
3851ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3852{
3853 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3854
Sean Callanan78e37602011-01-27 04:42:51 +00003855 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003856 if (clang_type)
3857 {
3858 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3859 if (enum_type)
3860 {
3861 EnumDecl *enum_decl = enum_type->getDecl();
3862 if (enum_decl)
3863 return enum_decl->getIntegerType().getAsOpaquePtr();
3864 }
3865 }
3866 return NULL;
3867}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003868bool
3869ClangASTContext::AddEnumerationValueToEnumerationType
3870(
Greg Clayton1be10fc2010-09-29 01:12:09 +00003871 clang_type_t enum_clang_type,
3872 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003873 const Declaration &decl,
3874 const char *name,
3875 int64_t enum_value,
3876 uint32_t enum_value_bit_size
3877)
3878{
3879 if (enum_clang_type && enumerator_clang_type && name)
3880 {
3881 // TODO: Do something intelligent with the Declaration object passed in
3882 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003883 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003884 IdentifierTable *identifier_table = getIdentifierTable();
3885
Greg Clayton6beaaa62011-01-17 03:46:26 +00003886 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003887 assert (identifier_table != NULL);
3888 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3889
Sean Callanan78e37602011-01-27 04:42:51 +00003890 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003891 if (clang_type)
3892 {
3893 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3894
3895 if (enum_type)
3896 {
3897 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3898 enum_llvm_apsint = enum_value;
3899 EnumConstantDecl *enumerator_decl =
Greg Clayton6beaaa62011-01-17 03:46:26 +00003900 EnumConstantDecl::Create (*ast,
3901 enum_type->getDecl(),
3902 SourceLocation(),
3903 name ? &identifier_table->get(name) : NULL, // Identifier
3904 QualType::getFromOpaquePtr(enumerator_clang_type),
3905 NULL,
3906 enum_llvm_apsint);
3907
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003908 if (enumerator_decl)
3909 {
3910 enum_type->getDecl()->addDecl(enumerator_decl);
3911 return true;
3912 }
3913 }
3914 }
3915 }
3916 return false;
3917}
3918
3919#pragma mark Pointers & References
3920
Greg Clayton1be10fc2010-09-29 01:12:09 +00003921clang_type_t
3922ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003923{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003924 return CreatePointerType (getASTContext(), clang_type);
3925}
3926
3927clang_type_t
3928ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
3929{
3930 if (ast && clang_type)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003931 {
3932 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3933
Greg Clayton737b9322010-09-13 03:32:57 +00003934 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3935 switch (type_class)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003936 {
3937 case clang::Type::ObjCObject:
3938 case clang::Type::ObjCInterface:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003939 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003940
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003941 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003942 return ast->getPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003943 }
3944 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003945 return NULL;
3946}
3947
Greg Clayton1be10fc2010-09-29 01:12:09 +00003948clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003949ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
3950 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003951{
3952 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003953 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003954 return NULL;
3955}
3956
Greg Clayton1be10fc2010-09-29 01:12:09 +00003957clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003958ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
3959 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003960{
3961 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003962 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003963 return NULL;
3964}
3965
Greg Clayton1be10fc2010-09-29 01:12:09 +00003966clang_type_t
3967ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Clayton9b81a312010-06-12 01:20:30 +00003968{
3969 if (clang_pointee_type && clang_pointee_type)
3970 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3971 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3972 return NULL;
3973}
3974
Greg Clayton1a65ae12011-01-25 23:55:37 +00003975uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003976ClangASTContext::GetPointerBitSize ()
3977{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003978 ASTContext *ast = getASTContext();
3979 return ast->getTypeSize(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003980}
3981
3982bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003983ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003984{
3985 if (clang_type == NULL)
3986 return false;
3987
3988 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003989 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3990 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003991 {
Sean Callanana2424172010-10-25 00:29:48 +00003992 case clang::Type::Builtin:
3993 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3994 {
3995 default:
3996 break;
3997 case clang::BuiltinType::ObjCId:
3998 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00003999 return true;
4000 }
4001 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004002 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004003 if (target_type)
4004 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4005 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004006 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004007 if (target_type)
4008 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4009 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004010 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004011 if (target_type)
4012 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4013 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004014 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004015 if (target_type)
4016 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4017 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004018 case clang::Type::LValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004019 if (target_type)
4020 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4021 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004022 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004023 if (target_type)
4024 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4025 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004026 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004027 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004028 default:
4029 break;
4030 }
4031 return false;
4032}
4033
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004034bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004035ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004036{
4037 if (!clang_type)
4038 return false;
4039
4040 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4041 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
4042
4043 if (builtin_type)
4044 {
4045 if (builtin_type->isInteger())
4046 is_signed = builtin_type->isSignedInteger();
4047
4048 return true;
4049 }
4050
4051 return false;
4052}
4053
4054bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004055ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004056{
4057 if (clang_type)
4058 {
4059 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004060 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4061 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004062 {
Sean Callanana2424172010-10-25 00:29:48 +00004063 case clang::Type::Builtin:
4064 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4065 {
4066 default:
4067 break;
4068 case clang::BuiltinType::ObjCId:
4069 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004070 return true;
4071 }
4072 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004073 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004074 if (target_type)
4075 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4076 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004077 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004078 if (target_type)
4079 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4080 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004081 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004082 if (target_type)
4083 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4084 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004085 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004086 if (target_type)
4087 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4088 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004089 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004090 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004091 default:
4092 break;
4093 }
4094 }
4095 return false;
4096}
4097
4098bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004099ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004100{
4101 if (clang_type)
4102 {
4103 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4104
4105 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
4106 {
4107 clang::BuiltinType::Kind kind = BT->getKind();
4108 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
4109 {
4110 count = 1;
4111 is_complex = false;
4112 return true;
4113 }
4114 }
4115 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
4116 {
4117 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
4118 {
4119 count = 2;
4120 is_complex = true;
4121 return true;
4122 }
4123 }
4124 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
4125 {
4126 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
4127 {
4128 count = VT->getNumElements();
4129 is_complex = false;
4130 return true;
4131 }
4132 }
4133 }
4134 return false;
4135}
4136
Greg Clayton8f92f0a2010-10-14 22:52:14 +00004137
4138bool
4139ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
4140{
4141 if (clang_type)
4142 {
4143 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4144
4145 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4146 if (cxx_record_decl)
4147 {
4148 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
4149 return true;
4150 }
4151 }
4152 class_name.clear();
4153 return false;
4154}
4155
4156
Greg Clayton0fffff52010-09-24 05:15:53 +00004157bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004158ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004159{
4160 if (clang_type)
4161 {
4162 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4163 if (qual_type->getAsCXXRecordDecl() != NULL)
4164 return true;
4165 }
4166 return false;
4167}
4168
4169bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004170ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004171{
4172 if (clang_type)
4173 {
4174 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4175 if (qual_type->isObjCObjectOrInterfaceType())
4176 return true;
4177 }
4178 return false;
4179}
4180
4181
Greg Clayton73b472d2010-10-27 03:32:59 +00004182bool
4183ClangASTContext::IsCharType (clang_type_t clang_type)
4184{
4185 if (clang_type)
4186 return QualType::getFromOpaquePtr(clang_type)->isCharType();
4187 return false;
4188}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004189
4190bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004191ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004192{
Greg Clayton73b472d2010-10-27 03:32:59 +00004193 clang_type_t pointee_or_element_clang_type = NULL;
4194 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
4195
4196 if (pointee_or_element_clang_type == NULL)
4197 return false;
4198
4199 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004200 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004201 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
4202
4203 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004204 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004205 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4206 if (type_flags.Test (eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004207 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004208 // We know the size of the array and it could be a C string
4209 // since it is an array of characters
4210 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
4211 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004212 }
Greg Clayton73b472d2010-10-27 03:32:59 +00004213 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004214 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004215 length = 0;
4216 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004217 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004218
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004219 }
4220 }
4221 return false;
4222}
4223
4224bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004225ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton737b9322010-09-13 03:32:57 +00004226{
4227 if (clang_type)
4228 {
4229 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4230
4231 if (qual_type->isFunctionPointerType())
4232 return true;
4233
4234 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4235 switch (type_class)
4236 {
Sean Callananfb0b7582011-03-15 00:17:19 +00004237 default:
4238 break;
Greg Clayton737b9322010-09-13 03:32:57 +00004239 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004240 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004241
4242 case clang::Type::LValueReference:
4243 case clang::Type::RValueReference:
4244 {
Sean Callanan78e37602011-01-27 04:42:51 +00004245 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004246 if (reference_type)
4247 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
4248 }
4249 break;
4250 }
4251 }
4252 return false;
4253}
4254
Greg Clayton73b472d2010-10-27 03:32:59 +00004255size_t
4256ClangASTContext::GetArraySize (clang_type_t clang_type)
4257{
4258 if (clang_type)
4259 {
Sean Callanan78e37602011-01-27 04:42:51 +00004260 const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00004261 if (array)
4262 return array->getSize().getLimitedValue();
4263 }
4264 return 0;
4265}
Greg Clayton737b9322010-09-13 03:32:57 +00004266
4267bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004268ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004269{
4270 if (!clang_type)
4271 return false;
4272
4273 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4274
Greg Clayton737b9322010-09-13 03:32:57 +00004275 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4276 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004277 {
Sean Callananfb0b7582011-03-15 00:17:19 +00004278 default:
4279 break;
Greg Claytone1a916a2010-07-21 22:12:05 +00004280 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004281 if (member_type)
4282 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4283 if (size)
Greg Claytonac4827f2011-04-01 18:14:08 +00004284 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004285 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004286 case clang::Type::IncompleteArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004287 if (member_type)
4288 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4289 if (size)
4290 *size = 0;
4291 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004292 case clang::Type::VariableArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004293 if (member_type)
4294 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4295 if (size)
4296 *size = 0;
Greg Clayton03dbf2e2011-02-02 00:52:14 +00004297 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004298 case clang::Type::DependentSizedArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004299 if (member_type)
4300 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4301 if (size)
4302 *size = 0;
4303 return true;
4304 }
4305 return false;
4306}
4307
4308
4309#pragma mark Typedefs
4310
Greg Clayton1be10fc2010-09-29 01:12:09 +00004311clang_type_t
4312ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004313{
4314 if (clang_type)
4315 {
4316 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004317 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004318 IdentifierTable *identifier_table = getIdentifierTable();
Greg Clayton6beaaa62011-01-17 03:46:26 +00004319 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004320 assert (identifier_table != NULL);
4321 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00004322 decl_ctx = ast->getTranslationUnitDecl();
4323 TypedefDecl *decl = TypedefDecl::Create (*ast,
4324 decl_ctx,
4325 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004326 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00004327 name ? &identifier_table->get(name) : NULL, // Identifier
4328 ast->CreateTypeSourceInfo(qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00004329
4330 decl->setAccess(AS_public); // TODO respect proper access specifier
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004331
4332 // Get a uniqued QualType for the typedef decl type
Greg Clayton6beaaa62011-01-17 03:46:26 +00004333 return ast->getTypedefType (decl).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004334 }
4335 return NULL;
4336}
4337
4338
4339std::string
Greg Clayton1be10fc2010-09-29 01:12:09 +00004340ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004341{
4342 std::string return_name;
4343
Greg Clayton1be10fc2010-09-29 01:12:09 +00004344 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004345
Greg Clayton1be10fc2010-09-29 01:12:09 +00004346 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004347 if (typedef_type)
4348 {
Sean Callanand12cf8bb2011-05-15 22:34:38 +00004349 const TypedefNameDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004350 return_name = typedef_decl->getQualifiedNameAsString();
4351 }
4352 else
4353 {
4354 return_name = qual_type.getAsString();
4355 }
4356
4357 return return_name;
4358}
4359
4360// Disable this for now since I can't seem to get a nicely formatted float
4361// out of the APFloat class without just getting the float, double or quad
4362// and then using a formatted print on it which defeats the purpose. We ideally
4363// would like to get perfect string values for any kind of float semantics
4364// so we can support remote targets. The code below also requires a patch to
4365// llvm::APInt.
4366//bool
Greg Clayton6beaaa62011-01-17 03:46:26 +00004367//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 +00004368//{
4369// uint32_t count = 0;
4370// bool is_complex = false;
4371// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4372// {
4373// unsigned num_bytes_per_float = byte_size / count;
4374// unsigned num_bits_per_float = num_bytes_per_float * 8;
4375//
4376// float_str.clear();
4377// uint32_t i;
4378// for (i=0; i<count; i++)
4379// {
4380// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
4381// bool is_ieee = false;
4382// APFloat ap_float(ap_int, is_ieee);
4383// char s[1024];
4384// unsigned int hex_digits = 0;
4385// bool upper_case = false;
4386//
4387// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
4388// {
4389// if (i > 0)
4390// float_str.append(", ");
4391// float_str.append(s);
4392// if (i == 1 && is_complex)
4393// float_str.append(1, 'i');
4394// }
4395// }
4396// return !float_str.empty();
4397// }
4398// return false;
4399//}
4400
4401size_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00004402ClangASTContext::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 +00004403{
4404 if (clang_type)
4405 {
4406 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4407 uint32_t count = 0;
4408 bool is_complex = false;
4409 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4410 {
4411 // TODO: handle complex and vector types
4412 if (count != 1)
4413 return false;
4414
4415 StringRef s_sref(s);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004416 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004417
Greg Clayton6beaaa62011-01-17 03:46:26 +00004418 const uint64_t bit_size = ast->getTypeSize (qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004419 const uint64_t byte_size = bit_size / 8;
4420 if (dst_size >= byte_size)
4421 {
4422 if (bit_size == sizeof(float)*8)
4423 {
4424 float float32 = ap_float.convertToFloat();
4425 ::memcpy (dst, &float32, byte_size);
4426 return byte_size;
4427 }
4428 else if (bit_size >= 64)
4429 {
4430 llvm::APInt ap_int(ap_float.bitcastToAPInt());
4431 ::memcpy (dst, ap_int.getRawData(), byte_size);
4432 return byte_size;
4433 }
4434 }
4435 }
4436 }
4437 return 0;
4438}
Sean Callanan6fe64b52010-09-17 02:24:29 +00004439
4440unsigned
Greg Clayton1be10fc2010-09-29 01:12:09 +00004441ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanan6fe64b52010-09-17 02:24:29 +00004442{
4443 assert (clang_type);
4444
4445 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4446
4447 return qual_type.getQualifiers().getCVRQualifiers();
4448}
Greg Clayton6beaaa62011-01-17 03:46:26 +00004449
4450bool
4451ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
4452{
4453 if (clang_type == NULL)
4454 return false;
4455
Greg Claytonc432c192011-01-20 04:18:48 +00004456 return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004457}
4458
4459
4460bool
4461ClangASTContext::GetCompleteType (clang_type_t clang_type)
4462{
4463 return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
4464}
4465