blob: 6e426f119b692504239ca3bf185e6b8869b6f1b3 [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 {
Greg Clayton007d5be2011-05-30 00:49:24 +000090 if (ast)
Greg Clayton6beaaa62011-01-17 03:46:26 +000091 {
Greg Clayton007d5be2011-05-30 00:49:24 +000092 ExternalASTSource *external_ast_source = ast->getExternalSource();
93 if (external_ast_source)
94 {
95 external_ast_source->CompleteType(tag_decl);
96 return !tag_type->isIncompleteType();
97 }
Greg Clayton6beaaa62011-01-17 03:46:26 +000098 }
99 }
100 return false;
101 }
102 }
103
104 }
105 break;
106
107 case clang::Type::ObjCObject:
108 case clang::Type::ObjCInterface:
109 {
Sean Callanan78e37602011-01-27 04:42:51 +0000110 const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000111 if (objc_class_type)
112 {
113 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
114 // We currently can't complete objective C types through the newly added ASTContext
115 // because it only supports TagDecl objects right now...
116 bool is_forward_decl = class_interface_decl->isForwardDecl();
117 if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
118 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000119 if (ast)
Greg Clayton6beaaa62011-01-17 03:46:26 +0000120 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000121 ExternalASTSource *external_ast_source = ast->getExternalSource();
122 if (external_ast_source)
123 {
124 external_ast_source->CompleteType (class_interface_decl);
125 is_forward_decl = class_interface_decl->isForwardDecl();
126 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000127 }
Greg Claytonc432c192011-01-20 04:18:48 +0000128 return is_forward_decl == false;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000129 }
Greg Claytonc432c192011-01-20 04:18:48 +0000130 return true;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000131 }
132 }
133 break;
134
135 case clang::Type::Typedef:
136 return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType());
137
138 default:
139 break;
140 }
141
142 return true;
143}
144
145
Greg Clayton8cf05932010-07-22 18:30:50 +0000146static AccessSpecifier
Greg Claytonc86103d2010-08-05 01:57:25 +0000147ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000148{
149 switch (access)
150 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000151 default: break;
152 case eAccessNone: return AS_none;
153 case eAccessPublic: return AS_public;
154 case eAccessPrivate: return AS_private;
155 case eAccessProtected: return AS_protected;
Greg Clayton8cf05932010-07-22 18:30:50 +0000156 }
157 return AS_none;
158}
159
160static ObjCIvarDecl::AccessControl
Greg Claytonc86103d2010-08-05 01:57:25 +0000161ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000162{
163 switch (access)
164 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000165 default: break;
166 case eAccessNone: return ObjCIvarDecl::None;
167 case eAccessPublic: return ObjCIvarDecl::Public;
168 case eAccessPrivate: return ObjCIvarDecl::Private;
169 case eAccessProtected: return ObjCIvarDecl::Protected;
170 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton8cf05932010-07-22 18:30:50 +0000171 }
172 return ObjCIvarDecl::None;
173}
174
175
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176static void
177ParseLangArgs
178(
179 LangOptions &Opts,
Greg Clayton94e5d782010-06-13 17:34:29 +0000180 InputKind IK
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181)
182{
183 // FIXME: Cleanup per-file based stuff.
184
185 // Set some properties which depend soley on the input kind; it would be nice
186 // to move these to the language standard, and have the driver resolve the
187 // input kind + language standard.
Greg Clayton94e5d782010-06-13 17:34:29 +0000188 if (IK == IK_Asm) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189 Opts.AsmPreprocessor = 1;
Greg Clayton94e5d782010-06-13 17:34:29 +0000190 } else if (IK == IK_ObjC ||
191 IK == IK_ObjCXX ||
192 IK == IK_PreprocessedObjC ||
193 IK == IK_PreprocessedObjCXX) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000194 Opts.ObjC1 = Opts.ObjC2 = 1;
195 }
196
197 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
198
199 if (LangStd == LangStandard::lang_unspecified) {
200 // Based on the base language, pick one.
201 switch (IK) {
Greg Clayton94e5d782010-06-13 17:34:29 +0000202 case IK_None:
203 case IK_AST:
Sean Callananfb0b7582011-03-15 00:17:19 +0000204 case IK_LLVM_IR:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000205 assert (!"Invalid input kind!");
Greg Clayton94e5d782010-06-13 17:34:29 +0000206 case IK_OpenCL:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207 LangStd = LangStandard::lang_opencl;
208 break;
Sean Callananfb0b7582011-03-15 00:17:19 +0000209 case IK_CUDA:
210 LangStd = LangStandard::lang_cuda;
211 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000212 case IK_Asm:
213 case IK_C:
214 case IK_PreprocessedC:
215 case IK_ObjC:
216 case IK_PreprocessedObjC:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217 LangStd = LangStandard::lang_gnu99;
218 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000219 case IK_CXX:
220 case IK_PreprocessedCXX:
221 case IK_ObjCXX:
222 case IK_PreprocessedObjCXX:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000223 LangStd = LangStandard::lang_gnucxx98;
224 break;
225 }
226 }
227
228 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
229 Opts.BCPLComment = Std.hasBCPLComments();
230 Opts.C99 = Std.isC99();
231 Opts.CPlusPlus = Std.isCPlusPlus();
232 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
233 Opts.Digraphs = Std.hasDigraphs();
234 Opts.GNUMode = Std.isGNUMode();
235 Opts.GNUInline = !Std.isC99();
236 Opts.HexFloats = Std.hasHexFloats();
237 Opts.ImplicitInt = Std.hasImplicitInt();
238
239 // OpenCL has some additional defaults.
240 if (LangStd == LangStandard::lang_opencl) {
241 Opts.OpenCL = 1;
242 Opts.AltiVec = 1;
243 Opts.CXXOperatorNames = 1;
244 Opts.LaxVectorConversions = 1;
245 }
246
247 // OpenCL and C++ both have bool, true, false keywords.
248 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
249
250// if (Opts.CPlusPlus)
251// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
252//
253// if (Args.hasArg(OPT_fobjc_gc_only))
254// Opts.setGCMode(LangOptions::GCOnly);
255// else if (Args.hasArg(OPT_fobjc_gc))
256// Opts.setGCMode(LangOptions::HybridGC);
257//
258// if (Args.hasArg(OPT_print_ivar_layout))
259// Opts.ObjCGCBitmapPrint = 1;
260//
261// if (Args.hasArg(OPT_faltivec))
262// Opts.AltiVec = 1;
263//
264// if (Args.hasArg(OPT_pthread))
265// Opts.POSIXThreads = 1;
266//
267// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
268// "default");
269// if (Vis == "default")
Sean Callanan31e851c2010-10-29 18:38:40 +0000270 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271// else if (Vis == "hidden")
272// Opts.setVisibilityMode(LangOptions::Hidden);
273// else if (Vis == "protected")
274// Opts.setVisibilityMode(LangOptions::Protected);
275// else
276// Diags.Report(diag::err_drv_invalid_value)
277// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
278
279// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
280
281 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
282 // is specified, or -std is set to a conforming mode.
283 Opts.Trigraphs = !Opts.GNUMode;
284// if (Args.hasArg(OPT_trigraphs))
285// Opts.Trigraphs = 1;
286//
287// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
288// OPT_fno_dollars_in_identifiers,
289// !Opts.AsmPreprocessor);
290// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
291// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
292// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
293// if (Args.hasArg(OPT_fno_lax_vector_conversions))
294// Opts.LaxVectorConversions = 0;
295// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
296// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
297// Opts.Blocks = Args.hasArg(OPT_fblocks);
298// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
299// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
300// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
301// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
302// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
303// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
304// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
305// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
306// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
307// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
308// Diags);
309// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
310// Opts.ObjCConstantStringClass = getLastArgValue(Args,
311// OPT_fconstant_string_class);
312// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
313// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
314// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
315// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
316// Opts.Static = Args.hasArg(OPT_static_define);
317 Opts.OptimizeSize = 0;
318
319 // FIXME: Eliminate this dependency.
320// unsigned Opt =
321// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
322// Opts.Optimize = Opt != 0;
323 unsigned Opt = 0;
324
325 // This is the __NO_INLINE__ define, which just depends on things like the
326 // optimization level and -fno-inline, not actually whether the backend has
327 // inlining enabled.
328 //
329 // FIXME: This is affected by other options (-fno-inline).
330 Opts.NoInline = !Opt;
331
332// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
333// switch (SSP) {
334// default:
335// Diags.Report(diag::err_drv_invalid_value)
336// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
337// break;
338// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
339// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
340// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
341// }
342}
343
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344
Greg Clayton6beaaa62011-01-17 03:46:26 +0000345ClangASTContext::ClangASTContext (const char *target_triple) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346 m_target_triple(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000347 m_ast_ap(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348 m_language_options_ap(),
349 m_source_manager_ap(),
350 m_diagnostic_ap(),
351 m_target_options_ap(),
352 m_target_info_ap(),
353 m_identifier_table_ap(),
354 m_selector_table_ap(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000355 m_builtins_ap(),
356 m_callback_tag_decl (NULL),
357 m_callback_objc_decl (NULL),
358 m_callback_baton (NULL)
359
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360{
361 if (target_triple && target_triple[0])
362 m_target_triple.assign (target_triple);
363}
364
365//----------------------------------------------------------------------
366// Destructor
367//----------------------------------------------------------------------
368ClangASTContext::~ClangASTContext()
369{
370 m_builtins_ap.reset();
371 m_selector_table_ap.reset();
372 m_identifier_table_ap.reset();
373 m_target_info_ap.reset();
374 m_target_options_ap.reset();
375 m_diagnostic_ap.reset();
376 m_source_manager_ap.reset();
377 m_language_options_ap.reset();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000378 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000379}
380
381
382void
383ClangASTContext::Clear()
384{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000385 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386 m_language_options_ap.reset();
387 m_source_manager_ap.reset();
388 m_diagnostic_ap.reset();
389 m_target_options_ap.reset();
390 m_target_info_ap.reset();
391 m_identifier_table_ap.reset();
392 m_selector_table_ap.reset();
393 m_builtins_ap.reset();
394}
395
396const char *
397ClangASTContext::GetTargetTriple ()
398{
399 return m_target_triple.c_str();
400}
401
402void
403ClangASTContext::SetTargetTriple (const char *target_triple)
404{
405 Clear();
406 m_target_triple.assign(target_triple);
407}
408
Greg Clayton514487e2011-02-15 21:59:32 +0000409void
410ClangASTContext::SetArchitecture (const ArchSpec &arch)
411{
412 Clear();
413 m_target_triple.assign(arch.GetTriple().str());
414}
415
Greg Clayton6beaaa62011-01-17 03:46:26 +0000416bool
417ClangASTContext::HasExternalSource ()
418{
419 ASTContext *ast = getASTContext();
420 if (ast)
421 return ast->getExternalSource () != NULL;
422 return false;
423}
424
425void
426ClangASTContext::SetExternalSource (llvm::OwningPtr<ExternalASTSource> &ast_source_ap)
427{
428 ASTContext *ast = getASTContext();
429 if (ast)
430 {
431 ast->setExternalSource (ast_source_ap);
432 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
433 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
434 }
435}
436
437void
438ClangASTContext::RemoveExternalSource ()
439{
440 ASTContext *ast = getASTContext();
441
442 if (ast)
443 {
444 llvm::OwningPtr<ExternalASTSource> empty_ast_source_ap;
445 ast->setExternalSource (empty_ast_source_ap);
446 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
447 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
448 }
449}
450
451
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000452
453ASTContext *
454ClangASTContext::getASTContext()
455{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000456 if (m_ast_ap.get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000458 m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
459 *getSourceManager(),
460 *getTargetInfo(),
461 *getIdentifierTable(),
462 *getSelectorTable(),
463 *getBuiltinContext(),
464 0));
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000465
Greg Clayton6beaaa62011-01-17 03:46:26 +0000466 if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton)
467 {
468 m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
469 //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
470 }
471
472 m_ast_ap->getDiagnostics().setClient(getDiagnosticClient(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000473 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000474 return m_ast_ap.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475}
476
477Builtin::Context *
478ClangASTContext::getBuiltinContext()
479{
480 if (m_builtins_ap.get() == NULL)
481 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
482 return m_builtins_ap.get();
483}
484
485IdentifierTable *
486ClangASTContext::getIdentifierTable()
487{
488 if (m_identifier_table_ap.get() == NULL)
489 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
490 return m_identifier_table_ap.get();
491}
492
493LangOptions *
494ClangASTContext::getLanguageOptions()
495{
496 if (m_language_options_ap.get() == NULL)
497 {
498 m_language_options_ap.reset(new LangOptions());
Greg Clayton94e5d782010-06-13 17:34:29 +0000499 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
500// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000501 }
502 return m_language_options_ap.get();
503}
504
505SelectorTable *
506ClangASTContext::getSelectorTable()
507{
508 if (m_selector_table_ap.get() == NULL)
509 m_selector_table_ap.reset (new SelectorTable());
510 return m_selector_table_ap.get();
511}
512
Sean Callanan79439e82010-11-18 02:56:27 +0000513clang::FileManager *
514ClangASTContext::getFileManager()
515{
516 if (m_file_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000517 {
518 clang::FileSystemOptions file_system_options;
519 m_file_manager_ap.reset(new clang::FileManager(file_system_options));
520 }
Sean Callanan79439e82010-11-18 02:56:27 +0000521 return m_file_manager_ap.get();
522}
523
Greg Claytone1a916a2010-07-21 22:12:05 +0000524clang::SourceManager *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525ClangASTContext::getSourceManager()
526{
527 if (m_source_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000528 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 return m_source_manager_ap.get();
530}
531
532Diagnostic *
533ClangASTContext::getDiagnostic()
534{
535 if (m_diagnostic_ap.get() == NULL)
Greg Claytona651b532010-11-19 21:46:54 +0000536 {
537 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
538 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
539 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540 return m_diagnostic_ap.get();
541}
542
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000543class NullDiagnosticClient : public DiagnosticClient
544{
545public:
546 NullDiagnosticClient ()
547 {
548 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
549 }
550
551 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
552 {
553 if (m_log)
554 {
555 llvm::SmallVectorImpl<char> diag_str(10);
556 info.FormatDiagnostic(diag_str);
557 diag_str.push_back('\0');
558 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
559 }
560 }
561private:
562 LogSP m_log;
563};
564
565DiagnosticClient *
566ClangASTContext::getDiagnosticClient()
567{
568 if (m_diagnostic_client_ap.get() == NULL)
569 m_diagnostic_client_ap.reset(new NullDiagnosticClient);
570
571 return m_diagnostic_client_ap.get();
572}
573
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574TargetOptions *
575ClangASTContext::getTargetOptions()
576{
577 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
578 {
579 m_target_options_ap.reset (new TargetOptions());
580 if (m_target_options_ap.get())
581 m_target_options_ap->Triple = m_target_triple;
582 }
583 return m_target_options_ap.get();
584}
585
586
587TargetInfo *
588ClangASTContext::getTargetInfo()
589{
590 // target_triple should be something like "x86_64-apple-darwin10"
591 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
592 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
593 return m_target_info_ap.get();
594}
595
596#pragma mark Basic Types
597
598static inline bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000599QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000601 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602 if (qual_type_bit_size == bit_size)
603 return true;
604 return false;
605}
606
Greg Clayton1be10fc2010-09-29 01:12:09 +0000607clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +0000608ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000609{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000610 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000611
Greg Clayton6beaaa62011-01-17 03:46:26 +0000612 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000613
Greg Clayton6beaaa62011-01-17 03:46:26 +0000614 return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000615}
616
Greg Clayton1be10fc2010-09-29 01:12:09 +0000617clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000618ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000619{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000620 if (!ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000621 return NULL;
622
623 switch (encoding)
624 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000625 case eEncodingInvalid:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000626 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
627 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000628 break;
629
Greg Claytonc86103d2010-08-05 01:57:25 +0000630 case eEncodingUint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000631 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
632 return ast->UnsignedCharTy.getAsOpaquePtr();
633 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
634 return ast->UnsignedShortTy.getAsOpaquePtr();
635 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
636 return ast->UnsignedIntTy.getAsOpaquePtr();
637 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
638 return ast->UnsignedLongTy.getAsOpaquePtr();
639 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
640 return ast->UnsignedLongLongTy.getAsOpaquePtr();
641 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
642 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000643 break;
644
Greg Claytonc86103d2010-08-05 01:57:25 +0000645 case eEncodingSint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000646 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
647 return ast->CharTy.getAsOpaquePtr();
648 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
649 return ast->ShortTy.getAsOpaquePtr();
650 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
651 return ast->IntTy.getAsOpaquePtr();
652 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
653 return ast->LongTy.getAsOpaquePtr();
654 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
655 return ast->LongLongTy.getAsOpaquePtr();
656 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
657 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000658 break;
659
Greg Claytonc86103d2010-08-05 01:57:25 +0000660 case eEncodingIEEE754:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000661 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
662 return ast->FloatTy.getAsOpaquePtr();
663 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
664 return ast->DoubleTy.getAsOpaquePtr();
665 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
666 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000667 break;
668
Greg Claytonc86103d2010-08-05 01:57:25 +0000669 case eEncodingVector:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000670 default:
671 break;
672 }
673
674 return NULL;
675}
676
Greg Clayton1be10fc2010-09-29 01:12:09 +0000677clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000678ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
679{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000680 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681
682 #define streq(a,b) strcmp(a,b) == 0
Greg Clayton6beaaa62011-01-17 03:46:26 +0000683 assert (ast != NULL);
684 if (ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000685 {
686 switch (dw_ate)
687 {
688 default:
689 break;
690
691 case DW_ATE_address:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000692 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
693 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000694 break;
695
696 case DW_ATE_boolean:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000697 if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
698 return ast->BoolTy.getAsOpaquePtr();
699 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
700 return ast->UnsignedCharTy.getAsOpaquePtr();
701 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
702 return ast->UnsignedShortTy.getAsOpaquePtr();
703 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
704 return ast->UnsignedIntTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000705 break;
706
Greg Clayton49462ea2011-01-15 02:52:14 +0000707 case DW_ATE_lo_user:
708 // This has been seen to mean DW_AT_complex_integer
Greg Clayton5732f242011-01-27 09:15:11 +0000709 if (::strstr(type_name, "complex"))
Greg Clayton49462ea2011-01-15 02:52:14 +0000710 {
711 clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000712 return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000713 }
714 break;
715
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716 case DW_ATE_complex_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000717 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
718 return ast->FloatComplexTy.getAsOpaquePtr();
719 else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
720 return ast->DoubleComplexTy.getAsOpaquePtr();
721 else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
722 return ast->LongDoubleComplexTy.getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000723 else
724 {
725 clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000726 return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000727 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000728 break;
729
730 case DW_ATE_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000731 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
732 return ast->FloatTy.getAsOpaquePtr();
733 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
734 return ast->DoubleTy.getAsOpaquePtr();
735 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
736 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737 break;
738
739 case DW_ATE_signed:
740 if (type_name)
741 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000742 if (strstr(type_name, "long long"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000743 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000744 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
745 return ast->LongLongTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000746 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000747 else if (strstr(type_name, "long"))
748 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000749 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
750 return ast->LongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000751 }
752 else if (strstr(type_name, "short"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000753 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000754 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
755 return ast->ShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000757 else if (strstr(type_name, "char"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000758 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000759 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
760 return ast->CharTy.getAsOpaquePtr();
761 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
762 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000763 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000764 else if (strstr(type_name, "int"))
765 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000766 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
767 return ast->IntTy.getAsOpaquePtr();
768 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
769 return ast->Int128Ty.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000770 }
771 else if (streq(type_name, "wchar_t"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000772 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000773 if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
774 return ast->WCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000775 }
Greg Clayton7bd65b92011-02-09 23:39:34 +0000776 else if (streq(type_name, "void"))
777 {
778 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
779 return ast->VoidTy.getAsOpaquePtr();
780 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000781 }
782 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000783 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
784 return ast->CharTy.getAsOpaquePtr();
785 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
786 return ast->ShortTy.getAsOpaquePtr();
787 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
788 return ast->IntTy.getAsOpaquePtr();
789 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
790 return ast->LongTy.getAsOpaquePtr();
791 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
792 return ast->LongLongTy.getAsOpaquePtr();
793 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
794 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000795 break;
796
797 case DW_ATE_signed_char:
798 if (type_name)
799 {
800 if (streq(type_name, "signed char"))
801 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000802 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
803 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000804 }
805 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000806 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
807 return ast->CharTy.getAsOpaquePtr();
808 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
809 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000810 break;
811
812 case DW_ATE_unsigned:
813 if (type_name)
814 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000815 if (strstr(type_name, "long long"))
816 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000817 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
818 return ast->UnsignedLongLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000819 }
820 else if (strstr(type_name, "long"))
821 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000822 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
823 return ast->UnsignedLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000824 }
825 else if (strstr(type_name, "short"))
826 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000827 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
828 return ast->UnsignedShortTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000829 }
830 else if (strstr(type_name, "char"))
831 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000832 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
833 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000834 }
835 else if (strstr(type_name, "int"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000836 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000837 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
838 return ast->UnsignedIntTy.getAsOpaquePtr();
839 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
840 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000841 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842 }
843 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000844 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
845 return ast->UnsignedCharTy.getAsOpaquePtr();
846 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
847 return ast->UnsignedShortTy.getAsOpaquePtr();
848 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
849 return ast->UnsignedIntTy.getAsOpaquePtr();
850 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
851 return ast->UnsignedLongTy.getAsOpaquePtr();
852 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
853 return ast->UnsignedLongLongTy.getAsOpaquePtr();
854 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
855 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000856 break;
857
858 case DW_ATE_unsigned_char:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000859 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
860 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton7bd65b92011-02-09 23:39:34 +0000861 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
862 return ast->UnsignedShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000863 break;
864
865 case DW_ATE_imaginary_float:
866 break;
867 }
868 }
869 // This assert should fire for anything that we don't catch above so we know
870 // to fix any issues we run into.
Greg Claytondc968d12011-05-17 18:15:05 +0000871 if (type_name)
872 {
873 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);
874 }
875 else
876 {
877 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);
878 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000879 return NULL;
880}
881
Greg Clayton1be10fc2010-09-29 01:12:09 +0000882clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000883ClangASTContext::GetBuiltInType_void(ASTContext *ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000884{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000885 return ast->VoidTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000886}
887
Greg Clayton1be10fc2010-09-29 01:12:09 +0000888clang_type_t
Sean Callananf7c3e272010-11-19 02:52:21 +0000889ClangASTContext::GetBuiltInType_bool()
890{
891 return getASTContext()->BoolTy.getAsOpaquePtr();
892}
893
894clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000895ClangASTContext::GetBuiltInType_objc_id()
896{
Sean Callananf6c73082010-12-06 23:53:20 +0000897 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).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_Class()
902{
Sean Callanana2424172010-10-25 00:29:48 +0000903 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000904}
905
Greg Clayton1be10fc2010-09-29 01:12:09 +0000906clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000907ClangASTContext::GetBuiltInType_objc_selector()
908{
Sean Callananf6c73082010-12-06 23:53:20 +0000909 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000910}
911
Greg Clayton1be10fc2010-09-29 01:12:09 +0000912clang_type_t
Sean Callanan77502262011-05-12 23:54:16 +0000913ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
914{
915 return ast->UnknownAnyTy.getAsOpaquePtr();
916}
917
918clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000919ClangASTContext::GetCStringType (bool is_const)
920{
921 QualType char_type(getASTContext()->CharTy);
922
923 if (is_const)
924 char_type.addConst();
925
926 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
927}
928
Greg Clayton1be10fc2010-09-29 01:12:09 +0000929clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000930ClangASTContext::GetVoidPtrType (bool is_const)
931{
932 return GetVoidPtrType(getASTContext(), is_const);
933}
934
Greg Clayton1be10fc2010-09-29 01:12:09 +0000935clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000936ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000937{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000938 QualType void_ptr_type(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000939
940 if (is_const)
941 void_ptr_type.addConst();
942
943 return void_ptr_type.getAsOpaquePtr();
944}
945
Greg Clayton1be10fc2010-09-29 01:12:09 +0000946clang_type_t
Greg Clayton38a61402010-12-02 23:20:03 +0000947ClangASTContext::CopyType (ASTContext *dst_ast,
948 ASTContext *src_ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000949 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950{
Sean Callanan79439e82010-11-18 02:56:27 +0000951 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000952 FileManager file_manager (file_system_options);
953 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000954 *src_ast, file_manager,
955 false);
Sean Callanan0617fcb2010-11-09 22:37:10 +0000956
Greg Clayton38a61402010-12-02 23:20:03 +0000957 QualType src (QualType::getFromOpaquePtr(clang_type));
958 QualType dst (importer.Import(src));
Sean Callanan0617fcb2010-11-09 22:37:10 +0000959
960 return dst.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000961}
962
Greg Clayton526e5af2010-11-13 03:52:47 +0000963
964clang::Decl *
Greg Clayton38a61402010-12-02 23:20:03 +0000965ClangASTContext::CopyDecl (ASTContext *dst_ast,
966 ASTContext *src_ast,
Greg Clayton526e5af2010-11-13 03:52:47 +0000967 clang::Decl *source_decl)
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000968{
Sean Callanan79439e82010-11-18 02:56:27 +0000969 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000970 FileManager file_manager (file_system_options);
971 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000972 *src_ast, file_manager,
973 false);
Greg Clayton526e5af2010-11-13 03:52:47 +0000974
975 return importer.Import(source_decl);
976}
977
Sean Callanan23a30272010-07-16 00:00:27 +0000978bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000979ClangASTContext::AreTypesSame(ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000980 clang_type_t type1,
981 clang_type_t type2)
Sean Callanan4dcca2622010-07-15 22:30:52 +0000982{
Greg Claytonf4ecaa52011-02-16 23:00:21 +0000983 return ast->hasSameType (QualType::getFromOpaquePtr(type1),
984 QualType::getFromOpaquePtr(type2));
Sean Callanan4dcca2622010-07-15 22:30:52 +0000985}
986
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000987#pragma mark CVR modifiers
988
Greg Clayton1be10fc2010-09-29 01:12:09 +0000989clang_type_t
990ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000991{
992 if (clang_type)
993 {
994 QualType result(QualType::getFromOpaquePtr(clang_type));
995 result.addConst();
996 return result.getAsOpaquePtr();
997 }
998 return NULL;
999}
1000
Greg Clayton1be10fc2010-09-29 01:12:09 +00001001clang_type_t
1002ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001003{
1004 if (clang_type)
1005 {
1006 QualType result(QualType::getFromOpaquePtr(clang_type));
1007 result.getQualifiers().setRestrict (true);
1008 return result.getAsOpaquePtr();
1009 }
1010 return NULL;
1011}
1012
Greg Clayton1be10fc2010-09-29 01:12:09 +00001013clang_type_t
1014ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015{
1016 if (clang_type)
1017 {
1018 QualType result(QualType::getFromOpaquePtr(clang_type));
1019 result.getQualifiers().setVolatile (true);
1020 return result.getAsOpaquePtr();
1021 }
1022 return NULL;
1023}
1024
Greg Clayton6beaaa62011-01-17 03:46:26 +00001025
1026clang_type_t
1027ClangASTContext::GetTypeForDecl (TagDecl *decl)
1028{
1029 // No need to call the getASTContext() accessor (which can create the AST
1030 // if it isn't created yet, because we can't have created a decl in this
1031 // AST if our AST didn't already exist...
1032 if (m_ast_ap.get())
1033 return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
1034 return NULL;
1035}
1036
1037clang_type_t
1038ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
1039{
1040 // No need to call the getASTContext() accessor (which can create the AST
1041 // if it isn't created yet, because we can't have created a decl in this
1042 // AST if our AST didn't already exist...
1043 if (m_ast_ap.get())
1044 return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
1045 return NULL;
1046}
1047
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001048#pragma mark Structure, Unions, Classes
1049
Greg Clayton1be10fc2010-09-29 01:12:09 +00001050clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +00001051ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001053 ASTContext *ast = getASTContext();
1054 assert (ast != NULL);
Sean Callanana2424172010-10-25 00:29:48 +00001055
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001056 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001057 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001058
Greg Clayton9e409562010-07-28 02:04:09 +00001059
Greg Claytonc86103d2010-08-05 01:57:25 +00001060 if (language == eLanguageTypeObjC)
Greg Clayton9e409562010-07-28 02:04:09 +00001061 {
Greg Claytonaaf99e02010-10-11 02:25:34 +00001062 bool isForwardDecl = true;
Greg Clayton9e409562010-07-28 02:04:09 +00001063 bool isInternal = false;
1064 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
1065 }
1066
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1068 // we will need to update this code. I was told to currently always use
1069 // the CXXRecordDecl class since we often don't know from debug information
1070 // if something is struct or a class, so we default to always use the more
1071 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001072 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001073 (TagDecl::TagKind)kind,
1074 decl_ctx,
1075 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001076 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001077 name && name[0] ? &ast->Idents.get(name) : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001078
Greg Clayton6beaaa62011-01-17 03:46:26 +00001079 return ast->getTagDeclType(decl).getAsOpaquePtr();
1080}
1081
1082bool
1083ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
1084{
1085 if (clang_type == NULL)
1086 return false;
1087
1088 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1089
1090 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1091 switch (type_class)
1092 {
1093 case clang::Type::Record:
1094 {
1095 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
1096 if (cxx_record_decl)
1097 {
1098 cxx_record_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001099 cxx_record_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001100 return true;
1101 }
1102 }
1103 break;
1104
1105 case clang::Type::Enum:
1106 {
1107 EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
1108 if (enum_decl)
1109 {
1110 enum_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001111 enum_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001112 return true;
1113 }
1114 }
1115 break;
1116
1117 case clang::Type::ObjCObject:
1118 case clang::Type::ObjCInterface:
1119 {
Sean Callanan78e37602011-01-27 04:42:51 +00001120 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001121 assert (objc_class_type);
1122 if (objc_class_type)
1123 {
1124 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1125
1126 if (class_interface_decl)
1127 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001128 class_interface_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001129 class_interface_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001130 return true;
1131 }
1132 }
1133 }
1134 break;
1135
1136 case clang::Type::Typedef:
1137 return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
1138
1139 default:
1140 break;
1141 }
1142 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001143}
1144
Greg Claytona3c444a2010-10-01 23:13:49 +00001145static bool
1146IsOperator (const char *name, OverloadedOperatorKind &op_kind)
1147{
1148 if (name == NULL || name[0] == '\0')
1149 return false;
1150
Sean Callanana43f20d2010-12-10 19:51:54 +00001151#define OPERATOR_PREFIX "operator"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001152#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
Sean Callananbfeff8c2010-12-10 02:15:55 +00001153
1154 const char *post_op_name = NULL;
1155
Sean Callanana43f20d2010-12-10 19:51:54 +00001156 bool no_space = true;
Sean Callananbfeff8c2010-12-10 02:15:55 +00001157
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001158 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
Greg Claytona3c444a2010-10-01 23:13:49 +00001159 return false;
1160
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001161 post_op_name = name + OPERATOR_PREFIX_LENGTH;
1162
Sean Callanana43f20d2010-12-10 19:51:54 +00001163 if (post_op_name[0] == ' ')
1164 {
1165 post_op_name++;
1166 no_space = false;
1167 }
1168
1169#undef OPERATOR_PREFIX
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001170#undef OPERATOR_PREFIX_LENGTH
Sean Callanana43f20d2010-12-10 19:51:54 +00001171
Greg Claytona3c444a2010-10-01 23:13:49 +00001172 // This is an operator, set the overloaded operator kind to invalid
1173 // in case this is a conversion operator...
1174 op_kind = NUM_OVERLOADED_OPERATORS;
1175
1176 switch (post_op_name[0])
1177 {
Sean Callananbfeff8c2010-12-10 02:15:55 +00001178 default:
1179 if (no_space)
1180 return false;
1181 break;
Greg Claytona3c444a2010-10-01 23:13:49 +00001182 case 'n':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001183 if (no_space)
1184 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001185 if (strcmp (post_op_name, "new") == 0)
1186 op_kind = OO_New;
1187 else if (strcmp (post_op_name, "new[]") == 0)
1188 op_kind = OO_Array_New;
1189 break;
1190
1191 case 'd':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001192 if (no_space)
1193 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001194 if (strcmp (post_op_name, "delete") == 0)
1195 op_kind = OO_Delete;
1196 else if (strcmp (post_op_name, "delete[]") == 0)
1197 op_kind = OO_Array_Delete;
1198 break;
1199
1200 case '+':
1201 if (post_op_name[1] == '\0')
1202 op_kind = OO_Plus;
1203 else if (post_op_name[2] == '\0')
1204 {
1205 if (post_op_name[1] == '=')
1206 op_kind = OO_PlusEqual;
1207 else if (post_op_name[1] == '+')
1208 op_kind = OO_PlusPlus;
1209 }
1210 break;
1211
1212 case '-':
1213 if (post_op_name[1] == '\0')
1214 op_kind = OO_Minus;
1215 else if (post_op_name[2] == '\0')
1216 {
1217 switch (post_op_name[1])
1218 {
1219 case '=': op_kind = OO_MinusEqual; break;
1220 case '-': op_kind = OO_MinusMinus; break;
1221 case '>': op_kind = OO_Arrow; break;
1222 }
1223 }
1224 else if (post_op_name[3] == '\0')
1225 {
1226 if (post_op_name[2] == '*')
1227 op_kind = OO_ArrowStar; break;
1228 }
1229 break;
1230
1231 case '*':
1232 if (post_op_name[1] == '\0')
1233 op_kind = OO_Star;
1234 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1235 op_kind = OO_StarEqual;
1236 break;
1237
1238 case '/':
1239 if (post_op_name[1] == '\0')
1240 op_kind = OO_Slash;
1241 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1242 op_kind = OO_SlashEqual;
1243 break;
1244
1245 case '%':
1246 if (post_op_name[1] == '\0')
1247 op_kind = OO_Percent;
1248 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1249 op_kind = OO_PercentEqual;
1250 break;
1251
1252
1253 case '^':
1254 if (post_op_name[1] == '\0')
1255 op_kind = OO_Caret;
1256 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1257 op_kind = OO_CaretEqual;
1258 break;
1259
1260 case '&':
1261 if (post_op_name[1] == '\0')
1262 op_kind = OO_Amp;
1263 else if (post_op_name[2] == '\0')
1264 {
1265 switch (post_op_name[1])
1266 {
1267 case '=': op_kind = OO_AmpEqual; break;
1268 case '&': op_kind = OO_AmpAmp; break;
1269 }
1270 }
1271 break;
1272
1273 case '|':
1274 if (post_op_name[1] == '\0')
1275 op_kind = OO_Pipe;
1276 else if (post_op_name[2] == '\0')
1277 {
1278 switch (post_op_name[1])
1279 {
1280 case '=': op_kind = OO_PipeEqual; break;
1281 case '|': op_kind = OO_PipePipe; break;
1282 }
1283 }
1284 break;
1285
1286 case '~':
1287 if (post_op_name[1] == '\0')
1288 op_kind = OO_Tilde;
1289 break;
1290
1291 case '!':
1292 if (post_op_name[1] == '\0')
1293 op_kind = OO_Exclaim;
1294 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1295 op_kind = OO_ExclaimEqual;
1296 break;
1297
1298 case '=':
1299 if (post_op_name[1] == '\0')
1300 op_kind = OO_Equal;
1301 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1302 op_kind = OO_EqualEqual;
1303 break;
1304
1305 case '<':
1306 if (post_op_name[1] == '\0')
1307 op_kind = OO_Less;
1308 else if (post_op_name[2] == '\0')
1309 {
1310 switch (post_op_name[1])
1311 {
1312 case '<': op_kind = OO_LessLess; break;
1313 case '=': op_kind = OO_LessEqual; break;
1314 }
1315 }
1316 else if (post_op_name[3] == '\0')
1317 {
1318 if (post_op_name[2] == '=')
1319 op_kind = OO_LessLessEqual;
1320 }
1321 break;
1322
1323 case '>':
1324 if (post_op_name[1] == '\0')
1325 op_kind = OO_Greater;
1326 else if (post_op_name[2] == '\0')
1327 {
1328 switch (post_op_name[1])
1329 {
1330 case '>': op_kind = OO_GreaterGreater; break;
1331 case '=': op_kind = OO_GreaterEqual; break;
1332 }
1333 }
1334 else if (post_op_name[1] == '>' &&
1335 post_op_name[2] == '=' &&
1336 post_op_name[3] == '\0')
1337 {
1338 op_kind = OO_GreaterGreaterEqual;
1339 }
1340 break;
1341
1342 case ',':
1343 if (post_op_name[1] == '\0')
1344 op_kind = OO_Comma;
1345 break;
1346
1347 case '(':
1348 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1349 op_kind = OO_Call;
1350 break;
1351
1352 case '[':
1353 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1354 op_kind = OO_Subscript;
1355 break;
1356 }
1357
1358 return true;
1359}
Greg Clayton6beaaa62011-01-17 03:46:26 +00001360
Greg Clayton090d0982011-06-19 03:43:27 +00001361static inline bool
1362check_op_param (bool unary, bool binary, uint32_t num_params)
1363{
1364 // The parameter count doens't include "this"
1365 if (num_params == 0)
1366 return unary;
1367 if (num_params == 1)
1368 return binary;
1369 return false;
1370}
1371
1372bool
1373ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, uint32_t num_params)
1374{
1375#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) case OO_##Name: return check_op_param (Unary, Binary, num_params);
1376 switch (op_kind)
1377 {
1378#include "clang/Basic/OperatorKinds.def"
1379 default: break;
1380 }
1381 return false;
1382}
1383
Greg Claytona51ed9b2010-09-23 01:09:21 +00001384CXXMethodDecl *
Sean Callanan61da09b2010-09-17 02:58:26 +00001385ClangASTContext::AddMethodToCXXRecordType
1386(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001387 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001388 clang_type_t record_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001389 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001390 clang_type_t method_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001391 lldb::AccessType access,
Greg Clayton0fffff52010-09-24 05:15:53 +00001392 bool is_virtual,
1393 bool is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00001394 bool is_inline,
1395 bool is_explicit
Greg Claytona51ed9b2010-09-23 01:09:21 +00001396)
Sean Callanan61da09b2010-09-17 02:58:26 +00001397{
Sean Callananfc55f5d2010-09-21 00:44:12 +00001398 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chend440bcc2010-09-28 16:10:54 +00001399 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001400
Greg Clayton6beaaa62011-01-17 03:46:26 +00001401 assert(ast);
Sean Callanan61da09b2010-09-17 02:58:26 +00001402
Greg Clayton6beaaa62011-01-17 03:46:26 +00001403 IdentifierTable *identifier_table = &ast->Idents;
Sean Callanan61da09b2010-09-17 02:58:26 +00001404
1405 assert(identifier_table);
1406
Sean Callananfc55f5d2010-09-21 00:44:12 +00001407 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001408
Greg Clayton6beaaa62011-01-17 03:46:26 +00001409 CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
Sean Callanan61da09b2010-09-17 02:58:26 +00001410
Greg Clayton0fffff52010-09-24 05:15:53 +00001411 if (cxx_record_decl == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001412 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001413
Greg Clayton0fffff52010-09-24 05:15:53 +00001414 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001415
Greg Claytonf51de672010-10-01 02:31:07 +00001416 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001417
Greg Claytonf51de672010-10-01 02:31:07 +00001418 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton878eaf12010-10-01 03:45:20 +00001419
Greg Clayton878eaf12010-10-01 03:45:20 +00001420 const bool is_implicitly_declared = false;
Greg Claytonf51de672010-10-01 02:31:07 +00001421
Sean Callanan78e37602011-01-27 04:42:51 +00001422 const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton878eaf12010-10-01 03:45:20 +00001423
Greg Clayton90a2acd2010-10-02 01:40:05 +00001424 if (function_Type == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001425 return NULL;
1426
Sean Callanan78e37602011-01-27 04:42:51 +00001427 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton878eaf12010-10-01 03:45:20 +00001428
1429 if (!method_function_prototype)
1430 return NULL;
1431
1432 unsigned int num_params = method_function_prototype->getNumArgs();
1433
1434 if (name[0] == '~')
Greg Claytonf51de672010-10-01 02:31:07 +00001435 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001436 cxx_method_decl = CXXDestructorDecl::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.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001440 method_qual_type,
Sean Callanan31e851c2010-10-29 18:38:40 +00001441 NULL,
Greg Clayton878eaf12010-10-01 03:45:20 +00001442 is_inline,
1443 is_implicitly_declared);
1444 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001445 else if (decl_name == cxx_record_decl->getDeclName())
Greg Clayton878eaf12010-10-01 03:45:20 +00001446 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001447 cxx_method_decl = CXXConstructorDecl::Create (*ast,
Greg Claytonf51de672010-10-01 02:31:07 +00001448 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001449 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001450 DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Claytonf51de672010-10-01 02:31:07 +00001451 method_qual_type,
1452 NULL, // TypeSourceInfo *
1453 is_explicit,
1454 is_inline,
1455 is_implicitly_declared);
1456 }
1457 else
Greg Clayton878eaf12010-10-01 03:45:20 +00001458 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001459
1460 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1461 if (IsOperator (name, op_kind))
Greg Clayton878eaf12010-10-01 03:45:20 +00001462 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001463 if (op_kind != NUM_OVERLOADED_OPERATORS)
1464 {
Greg Clayton090d0982011-06-19 03:43:27 +00001465 // Check the number of operator parameters. Sometimes we have
1466 // seen bad DWARF that doesn't correctly describe operators and
1467 // if we try to create a methed and add it to the class, clang
1468 // will assert and crash, so we need to make sure things are
1469 // acceptable.
1470 if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
1471 return NULL;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001472 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001473 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001474 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001475 DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001476 method_qual_type,
1477 NULL, // TypeSourceInfo *
Greg Claytona3c444a2010-10-01 23:13:49 +00001478 is_static,
1479 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001480 is_inline,
1481 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001482 }
1483 else if (num_params == 0)
1484 {
1485 // Conversion operators don't take params...
Greg Clayton6beaaa62011-01-17 03:46:26 +00001486 cxx_method_decl = CXXConversionDecl::Create (*ast,
Greg Claytona3c444a2010-10-01 23:13:49 +00001487 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001488 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001489 DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytona3c444a2010-10-01 23:13:49 +00001490 method_qual_type,
1491 NULL, // TypeSourceInfo *
1492 is_inline,
Sean Callananfb0b7582011-03-15 00:17:19 +00001493 is_explicit,
1494 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001495 }
Greg Clayton878eaf12010-10-01 03:45:20 +00001496 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001497
1498 if (cxx_method_decl == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001499 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001500 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001501 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001502 SourceLocation(),
Greg Claytona3c444a2010-10-01 23:13:49 +00001503 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001504 method_qual_type,
1505 NULL, // TypeSourceInfo *
1506 is_static,
1507 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001508 is_inline,
1509 SourceLocation());
Greg Clayton878eaf12010-10-01 03:45:20 +00001510 }
Greg Claytonf51de672010-10-01 02:31:07 +00001511 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001512
Greg Clayton1be10fc2010-09-29 01:12:09 +00001513 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton0fffff52010-09-24 05:15:53 +00001514
1515 cxx_method_decl->setAccess (access_specifier);
1516 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001517
Sean Callananfc55f5d2010-09-21 00:44:12 +00001518 // Populate the method decl with parameter decls
Sean Callananfc55f5d2010-09-21 00:44:12 +00001519
Charles Davis8c444c42011-05-19 23:33:46 +00001520 llvm::SmallVector<ParmVarDecl *, 12> params;
Sean Callananfc55f5d2010-09-21 00:44:12 +00001521
1522 for (int param_index = 0;
1523 param_index < num_params;
1524 ++param_index)
1525 {
Charles Davis8c444c42011-05-19 23:33:46 +00001526 params.push_back (ParmVarDecl::Create (*ast,
1527 cxx_method_decl,
1528 SourceLocation(),
1529 SourceLocation(),
1530 NULL, // anonymous
1531 method_function_prototype->getArgType(param_index),
1532 NULL,
1533 SC_None,
1534 SC_None,
1535 NULL));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001536 }
1537
Charles Davis8c444c42011-05-19 23:33:46 +00001538 cxx_method_decl->setParams (params.data(), num_params);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001539
Greg Clayton0fffff52010-09-24 05:15:53 +00001540 cxx_record_decl->addDecl (cxx_method_decl);
Greg Claytonc432c192011-01-20 04:18:48 +00001541
1542// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic());
1543// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate());
1544// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD());
1545// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty());
1546// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract());
1547// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor());
1548// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
1549// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
1550// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor());
Greg Claytona51ed9b2010-09-23 01:09:21 +00001551 return cxx_method_decl;
Sean Callanan61da09b2010-09-17 02:58:26 +00001552}
1553
1554bool
Greg Clayton8cf05932010-07-22 18:30:50 +00001555ClangASTContext::AddFieldToRecordType
1556(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001557 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001558 clang_type_t record_clang_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001559 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001560 clang_type_t field_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001561 AccessType access,
1562 uint32_t bitfield_bit_size
1563)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001564{
1565 if (record_clang_type == NULL || field_type == NULL)
1566 return false;
1567
Greg Clayton6beaaa62011-01-17 03:46:26 +00001568 IdentifierTable *identifier_table = &ast->Idents;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001569
Greg Clayton6beaaa62011-01-17 03:46:26 +00001570 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001571 assert (identifier_table != NULL);
1572
1573 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1574
Sean Callanan78e37602011-01-27 04:42:51 +00001575 const clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001576 if (clang_type)
1577 {
1578 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1579
1580 if (record_type)
1581 {
1582 RecordDecl *record_decl = record_type->getDecl();
1583
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001584 clang::Expr *bit_width = NULL;
1585 if (bitfield_bit_size != 0)
1586 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001587 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1588 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001589 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001590 FieldDecl *field = FieldDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001591 record_decl,
1592 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001593 SourceLocation(),
Greg Clayton8cf05932010-07-22 18:30:50 +00001594 name ? &identifier_table->get(name) : NULL, // Identifier
1595 QualType::getFromOpaquePtr(field_type), // Field type
1596 NULL, // DeclaratorInfo *
1597 bit_width, // BitWidth
1598 false); // Mutable
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001599
Greg Clayton8cf05932010-07-22 18:30:50 +00001600 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001601
1602 if (field)
1603 {
1604 record_decl->addDecl(field);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001605 }
1606 }
Greg Clayton9e409562010-07-28 02:04:09 +00001607 else
1608 {
Sean Callanan78e37602011-01-27 04:42:51 +00001609 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001610 if (objc_class_type)
1611 {
Greg Clayton0fffff52010-09-24 05:15:53 +00001612 bool is_synthesized = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001613 ClangASTContext::AddObjCClassIVar (ast,
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001614 record_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001615 name,
1616 field_type,
1617 access,
1618 bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001619 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001620 }
1621 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001622 }
1623 return false;
1624}
1625
1626bool
1627ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1628{
1629 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1630}
1631
1632bool
1633ClangASTContext::FieldIsBitfield
1634(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001635 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001636 FieldDecl* field,
1637 uint32_t& bitfield_bit_size
1638)
1639{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001640 if (ast == NULL || field == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001641 return false;
1642
1643 if (field->isBitField())
1644 {
1645 Expr* bit_width_expr = field->getBitWidth();
1646 if (bit_width_expr)
1647 {
1648 llvm::APSInt bit_width_apsint;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001649 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001650 {
1651 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1652 return true;
1653 }
1654 }
1655 }
1656 return false;
1657}
1658
1659bool
1660ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1661{
1662 if (record_decl == NULL)
1663 return false;
1664
1665 if (!record_decl->field_empty())
1666 return true;
1667
1668 // No fields, lets check this is a CXX record and check the base classes
1669 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1670 if (cxx_record_decl)
1671 {
1672 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1673 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1674 base_class != base_class_end;
1675 ++base_class)
1676 {
1677 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1678 if (RecordHasFields(base_class_decl))
1679 return true;
1680 }
1681 }
1682 return false;
1683}
1684
1685void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001686ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001687{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001688 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001689 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001690 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1691
Sean Callanan78e37602011-01-27 04:42:51 +00001692 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001693 if (record_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001694 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001695 RecordDecl *record_decl = record_type->getDecl();
1696 if (record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001697 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001698 uint32_t field_idx;
1699 RecordDecl::field_iterator field, field_end;
1700 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1701 field != field_end;
1702 ++field, ++field_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001703 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001704 // If no accessibility was assigned, assign the correct one
1705 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1706 field->setAccess ((AccessSpecifier)default_accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001707 }
1708 }
1709 }
1710 }
1711}
1712
1713#pragma mark C++ Base Classes
1714
1715CXXBaseSpecifier *
Greg Clayton1be10fc2010-09-29 01:12:09 +00001716ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001717{
1718 if (base_class_type)
Greg Claytone6371122010-07-30 20:30:44 +00001719 return new CXXBaseSpecifier (SourceRange(),
1720 is_virtual,
1721 base_of_class,
1722 ConvertAccessTypeToAccessSpecifier (access),
Sean Callanan2c777c42011-01-18 23:32:05 +00001723 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
1724 SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001725 return NULL;
1726}
1727
Greg Clayton0b42ac32010-07-02 01:29:13 +00001728void
1729ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1730{
1731 for (unsigned i=0; i<num_base_classes; ++i)
1732 {
1733 delete base_classes[i];
1734 base_classes[i] = NULL;
1735 }
1736}
1737
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001738bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001739ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001740{
1741 if (class_clang_type)
1742 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001743 CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
1744 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001745 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001746 cxx_record_decl->setBases(base_classes, num_base_classes);
1747 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001748 }
1749 }
1750 return false;
1751}
Greg Clayton8cf05932010-07-22 18:30:50 +00001752#pragma mark Objective C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001753
Greg Clayton1be10fc2010-09-29 01:12:09 +00001754clang_type_t
Greg Clayton8cf05932010-07-22 18:30:50 +00001755ClangASTContext::CreateObjCClass
1756(
1757 const char *name,
1758 DeclContext *decl_ctx,
1759 bool isForwardDecl,
1760 bool isInternal
1761)
1762{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001763 ASTContext *ast = getASTContext();
1764 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001765 assert (name && name[0]);
1766 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001767 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001768
1769 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1770 // we will need to update this code. I was told to currently always use
1771 // the CXXRecordDecl class since we often don't know from debug information
1772 // if something is struct or a class, so we default to always use the more
1773 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001774 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001775 decl_ctx,
1776 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001777 &ast->Idents.get(name),
Greg Clayton8cf05932010-07-22 18:30:50 +00001778 SourceLocation(),
1779 isForwardDecl,
1780 isInternal);
Greg Clayton9e409562010-07-28 02:04:09 +00001781
Greg Clayton6beaaa62011-01-17 03:46:26 +00001782 return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001783}
1784
1785bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001786ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton8cf05932010-07-22 18:30:50 +00001787{
1788 if (class_opaque_type && super_opaque_type)
1789 {
1790 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1791 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
Sean Callanan78e37602011-01-27 04:42:51 +00001792 const clang::Type *class_type = class_qual_type.getTypePtr();
1793 const clang::Type *super_type = super_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001794 if (class_type && super_type)
1795 {
Sean Callanan78e37602011-01-27 04:42:51 +00001796 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1797 const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001798 if (objc_class_type && objc_super_type)
1799 {
1800 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1801 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1802 if (class_interface_decl && super_interface_decl)
1803 {
1804 class_interface_decl->setSuperClass(super_interface_decl);
1805 return true;
1806 }
1807 }
1808 }
1809 }
1810 return false;
1811}
1812
1813
1814bool
1815ClangASTContext::AddObjCClassIVar
1816(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001817 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001818 clang_type_t class_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001819 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001820 clang_type_t ivar_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001821 AccessType access,
1822 uint32_t bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001823 bool is_synthesized
Greg Clayton8cf05932010-07-22 18:30:50 +00001824)
1825{
1826 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1827 return false;
1828
Greg Clayton6beaaa62011-01-17 03:46:26 +00001829 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton8cf05932010-07-22 18:30:50 +00001830
Greg Clayton6beaaa62011-01-17 03:46:26 +00001831 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001832 assert (identifier_table != NULL);
1833
1834 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1835
Sean Callanan78e37602011-01-27 04:42:51 +00001836 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001837 if (class_type)
1838 {
Sean Callanan78e37602011-01-27 04:42:51 +00001839 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001840
1841 if (objc_class_type)
1842 {
1843 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1844
1845 if (class_interface_decl)
1846 {
1847 clang::Expr *bit_width = NULL;
1848 if (bitfield_bit_size != 0)
1849 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001850 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1851 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Greg Clayton8cf05932010-07-22 18:30:50 +00001852 }
1853
Greg Clayton6beaaa62011-01-17 03:46:26 +00001854 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast,
Greg Clayton9e409562010-07-28 02:04:09 +00001855 class_interface_decl,
1856 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001857 SourceLocation(),
Greg Clayton9e409562010-07-28 02:04:09 +00001858 &identifier_table->get(name), // Identifier
1859 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1860 NULL, // TypeSourceInfo *
1861 ConvertAccessTypeToObjCIvarAccessControl (access),
1862 bit_width,
Greg Clayton0fffff52010-09-24 05:15:53 +00001863 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001864
1865 if (field)
1866 {
1867 class_interface_decl->addDecl(field);
1868 return true;
1869 }
Greg Clayton8cf05932010-07-22 18:30:50 +00001870 }
1871 }
1872 }
1873 return false;
1874}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001875
Greg Clayton9e409562010-07-28 02:04:09 +00001876
1877bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001878ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9e409562010-07-28 02:04:09 +00001879{
1880 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1881
Sean Callanan78e37602011-01-27 04:42:51 +00001882 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton9e409562010-07-28 02:04:09 +00001883 if (class_type)
1884 {
Sean Callanan78e37602011-01-27 04:42:51 +00001885 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001886
1887 if (objc_class_type)
1888 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1889 }
1890 return false;
1891}
1892
1893bool
1894ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1895{
1896 while (class_interface_decl)
1897 {
1898 if (class_interface_decl->ivar_size() > 0)
1899 return true;
1900
1901 if (check_superclass)
1902 class_interface_decl = class_interface_decl->getSuperClass();
1903 else
1904 break;
1905 }
1906 return false;
1907}
Greg Clayton0fffff52010-09-24 05:15:53 +00001908
Greg Clayton1be10fc2010-09-29 01:12:09 +00001909ObjCMethodDecl *
Greg Clayton0fffff52010-09-24 05:15:53 +00001910ClangASTContext::AddMethodToObjCObjectType
1911(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001912 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001913 clang_type_t class_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001914 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton1be10fc2010-09-29 01:12:09 +00001915 clang_type_t method_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001916 lldb::AccessType access
1917)
1918{
1919 if (class_opaque_type == NULL || method_opaque_type == NULL)
1920 return NULL;
1921
Greg Clayton6beaaa62011-01-17 03:46:26 +00001922 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton0fffff52010-09-24 05:15:53 +00001923
Greg Clayton6beaaa62011-01-17 03:46:26 +00001924 assert (ast != NULL);
Greg Clayton0fffff52010-09-24 05:15:53 +00001925 assert (identifier_table != NULL);
1926
1927 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1928
Sean Callanan78e37602011-01-27 04:42:51 +00001929 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton0fffff52010-09-24 05:15:53 +00001930 if (class_type == NULL)
1931 return NULL;
1932
Sean Callanan78e37602011-01-27 04:42:51 +00001933 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton0fffff52010-09-24 05:15:53 +00001934
1935 if (objc_class_type == NULL)
1936 return NULL;
1937
1938 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1939
1940 if (class_interface_decl == NULL)
1941 return NULL;
Greg Clayton9e409562010-07-28 02:04:09 +00001942
Greg Clayton0fffff52010-09-24 05:15:53 +00001943 const char *selector_start = ::strchr (name, ' ');
1944 if (selector_start == NULL)
1945 return NULL;
1946
1947 selector_start++;
1948 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1949 return NULL;
1950 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1951
Greg Clayton450e3f32010-10-12 02:24:53 +00001952 size_t len = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +00001953 const char *start;
Greg Clayton450e3f32010-10-12 02:24:53 +00001954 //printf ("name = '%s'\n", name);
1955
1956 unsigned num_selectors_with_args = 0;
1957 for (start = selector_start;
Greg Clayton0fffff52010-09-24 05:15:53 +00001958 start && *start != '\0' && *start != ']';
Greg Clayton450e3f32010-10-12 02:24:53 +00001959 start += len)
Greg Clayton0fffff52010-09-24 05:15:53 +00001960 {
Greg Clayton450e3f32010-10-12 02:24:53 +00001961 len = ::strcspn(start, ":]");
Greg Clayton90f90cd2010-10-27 04:01:14 +00001962 bool has_arg = (start[len] == ':');
1963 if (has_arg)
Greg Clayton450e3f32010-10-12 02:24:53 +00001964 ++num_selectors_with_args;
Greg Clayton0fffff52010-09-24 05:15:53 +00001965 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton90f90cd2010-10-27 04:01:14 +00001966 if (has_arg)
1967 len += 1;
Greg Clayton0fffff52010-09-24 05:15:53 +00001968 }
1969
1970
1971 if (selector_idents.size() == 0)
1972 return 0;
1973
Greg Clayton6beaaa62011-01-17 03:46:26 +00001974 clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton0fffff52010-09-24 05:15:53 +00001975 selector_idents.data());
1976
1977 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1978
1979 // Populate the method decl with parameter decls
Sean Callanan78e37602011-01-27 04:42:51 +00001980 const clang::Type *method_type(method_qual_type.getTypePtr());
Greg Clayton0fffff52010-09-24 05:15:53 +00001981
1982 if (method_type == NULL)
1983 return NULL;
1984
Sean Callanan78e37602011-01-27 04:42:51 +00001985 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001986
1987 if (!method_function_prototype)
1988 return NULL;
1989
1990
1991 bool is_variadic = false;
1992 bool is_synthesized = false;
1993 bool is_defined = false;
1994 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1995
1996 const unsigned num_args = method_function_prototype->getNumArgs();
1997
Greg Clayton6beaaa62011-01-17 03:46:26 +00001998 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001999 SourceLocation(), // beginLoc,
2000 SourceLocation(), // endLoc,
2001 method_selector,
2002 method_function_prototype->getResultType(),
2003 NULL, // TypeSourceInfo *ResultTInfo,
2004 GetDeclContextForType (class_opaque_type),
2005 name[0] == '-',
2006 is_variadic,
2007 is_synthesized,
2008 is_defined,
2009 imp_control,
2010 num_args);
2011
2012
2013 if (objc_method_decl == NULL)
2014 return NULL;
2015
2016 if (num_args > 0)
2017 {
2018 llvm::SmallVector<ParmVarDecl *, 12> params;
2019
2020 for (int param_index = 0; param_index < num_args; ++param_index)
2021 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002022 params.push_back (ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00002023 objc_method_decl,
2024 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00002025 SourceLocation(),
Greg Clayton0fffff52010-09-24 05:15:53 +00002026 NULL, // anonymous
2027 method_function_prototype->getArgType(param_index),
2028 NULL,
2029 SC_Auto,
2030 SC_Auto,
2031 NULL));
2032 }
2033
Greg Clayton6beaaa62011-01-17 03:46:26 +00002034 objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args);
Greg Clayton0fffff52010-09-24 05:15:53 +00002035 }
2036
2037 class_interface_decl->addDecl (objc_method_decl);
2038
2039
2040 return objc_method_decl;
2041}
2042
2043
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002044uint32_t
Greg Clayton73b472d2010-10-27 03:32:59 +00002045ClangASTContext::GetTypeInfo
2046(
2047 clang_type_t clang_type,
Greg Clayton6beaaa62011-01-17 03:46:26 +00002048 clang::ASTContext *ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002049 clang_type_t *pointee_or_element_clang_type
2050)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002051{
2052 if (clang_type == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00002053 return 0;
2054
2055 if (pointee_or_element_clang_type)
2056 *pointee_or_element_clang_type = NULL;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002057
2058 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2059
2060 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2061 switch (type_class)
2062 {
Sean Callanana2424172010-10-25 00:29:48 +00002063 case clang::Type::Builtin:
2064 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2065 {
Sean Callanana2424172010-10-25 00:29:48 +00002066 case clang::BuiltinType::ObjCId:
2067 case clang::BuiltinType::ObjCClass:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002068 if (ast && pointee_or_element_clang_type)
2069 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanana2424172010-10-25 00:29:48 +00002070 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002071
2072 default:
2073 break;
Sean Callanana2424172010-10-25 00:29:48 +00002074 }
2075 return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002076
2077 case clang::Type::BlockPointer:
2078 if (pointee_or_element_clang_type)
2079 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2080 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
2081
Greg Clayton49462ea2011-01-15 02:52:14 +00002082 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002083
2084 case clang::Type::ConstantArray:
2085 case clang::Type::DependentSizedArray:
2086 case clang::Type::IncompleteArray:
2087 case clang::Type::VariableArray:
2088 if (pointee_or_element_clang_type)
2089 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
2090 return eTypeHasChildren | eTypeIsArray;
2091
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002092 case clang::Type::DependentName: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002093 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
2094 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
2095 case clang::Type::Decltype: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002096
2097 case clang::Type::Enum:
2098 if (pointee_or_element_clang_type)
2099 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
2100 return eTypeIsEnumeration | eTypeHasValue;
2101
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002102 case clang::Type::Elaborated: return 0;
2103 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
2104 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
2105 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002106 case clang::Type::InjectedClassName: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002107
2108 case clang::Type::LValueReference:
2109 case clang::Type::RValueReference:
2110 if (pointee_or_element_clang_type)
2111 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
2112 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
2113
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002114 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002115
2116 case clang::Type::ObjCObjectPointer:
2117 if (pointee_or_element_clang_type)
2118 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2119 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
2120
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002121 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2122 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Clayton73b472d2010-10-27 03:32:59 +00002123
2124 case clang::Type::Pointer:
2125 if (pointee_or_element_clang_type)
2126 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2127 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
2128
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002129 case clang::Type::Record:
2130 if (qual_type->getAsCXXRecordDecl())
2131 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
2132 else
2133 return eTypeHasChildren | eTypeIsStructUnion;
2134 break;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002135 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
2136 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
2137 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Clayton73b472d2010-10-27 03:32:59 +00002138
2139 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002140 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00002141 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002142 pointee_or_element_clang_type);
2143
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002144 case clang::Type::TypeOfExpr: return 0;
2145 case clang::Type::TypeOf: return 0;
2146 case clang::Type::UnresolvedUsing: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002147 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
2148 default: return 0;
2149 }
2150 return 0;
2151}
2152
Greg Clayton9e409562010-07-28 02:04:09 +00002153
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002154#pragma mark Aggregate Types
2155
2156bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00002157ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002158{
2159 if (clang_type == NULL)
2160 return false;
2161
2162 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2163
Greg Clayton737b9322010-09-13 03:32:57 +00002164 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2165 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002166 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002167 case clang::Type::IncompleteArray:
2168 case clang::Type::VariableArray:
2169 case clang::Type::ConstantArray:
2170 case clang::Type::ExtVector:
2171 case clang::Type::Vector:
2172 case clang::Type::Record:
Greg Clayton9e409562010-07-28 02:04:09 +00002173 case clang::Type::ObjCObject:
2174 case clang::Type::ObjCInterface:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002175 return true;
2176
Greg Claytone1a916a2010-07-21 22:12:05 +00002177 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002178 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002179
2180 default:
2181 break;
2182 }
2183 // The clang type does have a value
2184 return false;
2185}
2186
2187uint32_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00002188ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002189{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002190 if (clang_type == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002191 return 0;
2192
2193 uint32_t num_children = 0;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002194 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00002195 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2196 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002197 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002198 case clang::Type::Builtin:
2199 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2200 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002201 case clang::BuiltinType::ObjCId: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002202 case clang::BuiltinType::ObjCClass: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002203 num_children = 1;
Greg Clayton73b472d2010-10-27 03:32:59 +00002204 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002205
2206 default:
2207 break;
2208 }
2209 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002210
Greg Clayton49462ea2011-01-15 02:52:14 +00002211 case clang::Type::Complex: return 0;
Greg Clayton54979cd2010-12-15 05:08:08 +00002212
Greg Claytone1a916a2010-07-21 22:12:05 +00002213 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002214 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002215 {
2216 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2217 const RecordDecl *record_decl = record_type->getDecl();
2218 assert(record_decl);
2219 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2220 if (cxx_record_decl)
2221 {
2222 if (omit_empty_base_classes)
2223 {
2224 // Check each base classes to see if it or any of its
2225 // base classes contain any fields. This can help
2226 // limit the noise in variable views by not having to
2227 // show base classes that contain no members.
2228 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2229 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2230 base_class != base_class_end;
2231 ++base_class)
2232 {
2233 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2234
2235 // Skip empty base classes
2236 if (RecordHasFields(base_class_decl) == false)
2237 continue;
2238
2239 num_children++;
2240 }
2241 }
2242 else
2243 {
2244 // Include all base classes
2245 num_children += cxx_record_decl->getNumBases();
2246 }
2247
2248 }
2249 RecordDecl::field_iterator field, field_end;
2250 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2251 ++num_children;
2252 }
2253 break;
2254
Greg Clayton9e409562010-07-28 02:04:09 +00002255 case clang::Type::ObjCObject:
2256 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002257 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002258 {
Sean Callanan78e37602011-01-27 04:42:51 +00002259 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002260 assert (objc_class_type);
2261 if (objc_class_type)
2262 {
2263 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2264
2265 if (class_interface_decl)
2266 {
2267
2268 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2269 if (superclass_interface_decl)
2270 {
2271 if (omit_empty_base_classes)
2272 {
2273 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2274 ++num_children;
2275 }
2276 else
2277 ++num_children;
2278 }
2279
2280 num_children += class_interface_decl->ivar_size();
2281 }
2282 }
2283 }
2284 break;
2285
2286 case clang::Type::ObjCObjectPointer:
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002287 {
Sean Callanan78e37602011-01-27 04:42:51 +00002288 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002289 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002290 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2291 pointee_type.getAsOpaquePtr(),
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002292 omit_empty_base_classes);
2293 // If this type points to a simple type, then it has 1 child
2294 if (num_pointee_children == 0)
2295 num_children = 1;
2296 else
2297 num_children = num_pointee_children;
2298 }
2299 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002300
Greg Claytone1a916a2010-07-21 22:12:05 +00002301 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002302 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2303 break;
2304
Greg Claytone1a916a2010-07-21 22:12:05 +00002305 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002306 {
Sean Callanan78e37602011-01-27 04:42:51 +00002307 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002308 QualType pointee_type (pointer_type->getPointeeType());
Greg Clayton6beaaa62011-01-17 03:46:26 +00002309 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2310 pointee_type.getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00002311 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002312 if (num_pointee_children == 0)
Greg Clayton54979cd2010-12-15 05:08:08 +00002313 {
2314 // We have a pointer to a pointee type that claims it has no children.
2315 // We will want to look at
2316 num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
2317 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002318 else
2319 num_children = num_pointee_children;
2320 }
2321 break;
2322
Greg Clayton73b472d2010-10-27 03:32:59 +00002323 case clang::Type::LValueReference:
2324 case clang::Type::RValueReference:
2325 {
Sean Callanan78e37602011-01-27 04:42:51 +00002326 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002327 QualType pointee_type = reference_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002328 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2329 pointee_type.getAsOpaquePtr(),
Greg Clayton73b472d2010-10-27 03:32:59 +00002330 omit_empty_base_classes);
2331 // If this type points to a simple type, then it has 1 child
2332 if (num_pointee_children == 0)
2333 num_children = 1;
2334 else
2335 num_children = num_pointee_children;
2336 }
2337 break;
2338
2339
Greg Claytone1a916a2010-07-21 22:12:05 +00002340 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002341 num_children = ClangASTContext::GetNumChildren (ast,
2342 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2343 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002344 break;
2345
2346 default:
2347 break;
2348 }
2349 return num_children;
2350}
2351
Greg Clayton54979cd2010-12-15 05:08:08 +00002352// If a pointer to a pointee type (the clang_type arg) says that it has no
2353// children, then we either need to trust it, or override it and return a
2354// different result. For example, an "int *" has one child that is an integer,
2355// but a function pointer doesn't have any children. Likewise if a Record type
2356// claims it has no children, then there really is nothing to show.
2357uint32_t
2358ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
2359{
2360 if (clang_type == NULL)
2361 return 0;
2362
2363 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2364 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2365 switch (type_class)
2366 {
Greg Clayton97a43712011-01-08 22:26:47 +00002367 case clang::Type::Builtin:
2368 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2369 {
Greg Clayton7260f622011-04-18 08:33:37 +00002370 case clang::BuiltinType::UnknownAny:
Greg Clayton97a43712011-01-08 22:26:47 +00002371 case clang::BuiltinType::Void:
2372 case clang::BuiltinType::NullPtr:
2373 return 0;
2374 case clang::BuiltinType::Bool:
2375 case clang::BuiltinType::Char_U:
2376 case clang::BuiltinType::UChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002377 case clang::BuiltinType::WChar_U:
Greg Clayton97a43712011-01-08 22:26:47 +00002378 case clang::BuiltinType::Char16:
2379 case clang::BuiltinType::Char32:
2380 case clang::BuiltinType::UShort:
2381 case clang::BuiltinType::UInt:
2382 case clang::BuiltinType::ULong:
2383 case clang::BuiltinType::ULongLong:
2384 case clang::BuiltinType::UInt128:
2385 case clang::BuiltinType::Char_S:
2386 case clang::BuiltinType::SChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002387 case clang::BuiltinType::WChar_S:
Greg Clayton97a43712011-01-08 22:26:47 +00002388 case clang::BuiltinType::Short:
2389 case clang::BuiltinType::Int:
2390 case clang::BuiltinType::Long:
2391 case clang::BuiltinType::LongLong:
2392 case clang::BuiltinType::Int128:
2393 case clang::BuiltinType::Float:
2394 case clang::BuiltinType::Double:
2395 case clang::BuiltinType::LongDouble:
2396 case clang::BuiltinType::Dependent:
2397 case clang::BuiltinType::Overload:
Greg Clayton97a43712011-01-08 22:26:47 +00002398 case clang::BuiltinType::ObjCId:
2399 case clang::BuiltinType::ObjCClass:
2400 case clang::BuiltinType::ObjCSel:
Sean Callanand12cf8bb2011-05-15 22:34:38 +00002401 case clang::BuiltinType::BoundMember:
Greg Clayton97a43712011-01-08 22:26:47 +00002402 return 1;
2403 }
2404 break;
2405
Greg Clayton49462ea2011-01-15 02:52:14 +00002406 case clang::Type::Complex: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00002407 case clang::Type::Pointer: return 1;
2408 case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
2409 case clang::Type::LValueReference: return 1;
2410 case clang::Type::RValueReference: return 1;
2411 case clang::Type::MemberPointer: return 0;
2412 case clang::Type::ConstantArray: return 0;
2413 case clang::Type::IncompleteArray: return 0;
2414 case clang::Type::VariableArray: return 0;
2415 case clang::Type::DependentSizedArray: return 0;
2416 case clang::Type::DependentSizedExtVector: return 0;
2417 case clang::Type::Vector: return 0;
2418 case clang::Type::ExtVector: return 0;
2419 case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
2420 case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
2421 case clang::Type::UnresolvedUsing: return 0;
2422 case clang::Type::Paren: return 0;
2423 case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2424 case clang::Type::TypeOfExpr: return 0;
2425 case clang::Type::TypeOf: return 0;
2426 case clang::Type::Decltype: return 0;
2427 case clang::Type::Record: return 0;
2428 case clang::Type::Enum: return 1;
2429 case clang::Type::Elaborated: return 1;
2430 case clang::Type::TemplateTypeParm: return 1;
2431 case clang::Type::SubstTemplateTypeParm: return 1;
2432 case clang::Type::TemplateSpecialization: return 1;
2433 case clang::Type::InjectedClassName: return 0;
2434 case clang::Type::DependentName: return 1;
2435 case clang::Type::DependentTemplateSpecialization: return 1;
2436 case clang::Type::ObjCObject: return 0;
2437 case clang::Type::ObjCInterface: return 0;
2438 case clang::Type::ObjCObjectPointer: return 1;
2439 default:
2440 break;
2441 }
2442 return 0;
2443}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002444
Greg Clayton1be10fc2010-09-29 01:12:09 +00002445clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002446ClangASTContext::GetChildClangTypeAtIndex
2447(
2448 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)
2463
2464 return GetChildClangTypeAtIndex (getASTContext(),
2465 parent_name,
2466 parent_clang_type,
2467 idx,
2468 transparent_pointers,
2469 omit_empty_base_classes,
2470 child_name,
2471 child_byte_size,
2472 child_byte_offset,
2473 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002474 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002475 child_is_base_class,
2476 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002477 return NULL;
2478}
2479
Greg Clayton1be10fc2010-09-29 01:12:09 +00002480clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002481ClangASTContext::GetChildClangTypeAtIndex
2482(
Greg Clayton6beaaa62011-01-17 03:46:26 +00002483 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002484 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002485 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002486 uint32_t idx,
2487 bool transparent_pointers,
2488 bool omit_empty_base_classes,
2489 std::string& child_name,
2490 uint32_t &child_byte_size,
2491 int32_t &child_byte_offset,
2492 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002493 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002494 bool &child_is_base_class,
2495 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002496)
2497{
2498 if (parent_clang_type == NULL)
2499 return NULL;
2500
Greg Clayton6beaaa62011-01-17 03:46:26 +00002501 if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002502 {
2503 uint32_t bit_offset;
2504 child_bitfield_bit_size = 0;
2505 child_bitfield_bit_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002506 child_is_base_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002507 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00002508 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2509 switch (parent_type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002510 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002511 case clang::Type::Builtin:
2512 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2513 {
2514 case clang::BuiltinType::ObjCId:
2515 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00002516 child_name = "isa";
Greg Clayton6beaaa62011-01-17 03:46:26 +00002517 child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
2518 return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002519
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002520 default:
2521 break;
2522 }
2523 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002524
Greg Claytone1a916a2010-07-21 22:12:05 +00002525 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002526 if (GetCompleteQualType (ast, parent_qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002527 {
2528 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2529 const RecordDecl *record_decl = record_type->getDecl();
2530 assert(record_decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00002531 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002532 uint32_t child_idx = 0;
2533
2534 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2535 if (cxx_record_decl)
2536 {
2537 // We might have base classes to print out first
2538 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2539 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2540 base_class != base_class_end;
2541 ++base_class)
2542 {
2543 const CXXRecordDecl *base_class_decl = NULL;
2544
2545 // Skip empty base classes
2546 if (omit_empty_base_classes)
2547 {
2548 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2549 if (RecordHasFields(base_class_decl) == false)
2550 continue;
2551 }
2552
2553 if (idx == child_idx)
2554 {
2555 if (base_class_decl == NULL)
2556 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2557
2558
2559 if (base_class->isVirtual())
Greg Clayton6ed95942011-01-22 07:12:45 +00002560 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002561 else
Greg Clayton6ed95942011-01-22 07:12:45 +00002562 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002563
2564 // Base classes should be a multiple of 8 bits in size
2565 assert (bit_offset % 8 == 0);
2566 child_byte_offset = bit_offset/8;
2567 std::string base_class_type_name(base_class->getType().getAsString());
2568
2569 child_name.assign(base_class_type_name.c_str());
2570
Greg Clayton6beaaa62011-01-17 03:46:26 +00002571 uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002572
Jim Inghamf46b3382011-04-15 23:42:06 +00002573 // Base classes bit sizes should be a multiple of 8 bits in size
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002574 assert (clang_type_info_bit_size % 8 == 0);
2575 child_byte_size = clang_type_info_bit_size / 8;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002576 child_is_base_class = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002577 return base_class->getType().getAsOpaquePtr();
2578 }
2579 // We don't increment the child index in the for loop since we might
2580 // be skipping empty base classes
2581 ++child_idx;
2582 }
2583 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002584 // Make sure index is in range...
2585 uint32_t field_idx = 0;
2586 RecordDecl::field_iterator field, field_end;
2587 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2588 {
2589 if (idx == child_idx)
2590 {
2591 // Print the member type if requested
2592 // Print the member name and equal sign
2593 child_name.assign(field->getNameAsString().c_str());
2594
2595 // Figure out the type byte size (field_type_info.first) and
2596 // alignment (field_type_info.second) from the AST context.
Greg Clayton6beaaa62011-01-17 03:46:26 +00002597 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
Greg Claytonc982c762010-07-09 20:39:50 +00002598 assert(field_idx < record_layout.getFieldCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002599
2600 child_byte_size = field_type_info.first / 8;
2601
2602 // Figure out the field offset within the current struct/union/class type
2603 bit_offset = record_layout.getFieldOffset (field_idx);
2604 child_byte_offset = bit_offset / 8;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002605 if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002606 child_bitfield_bit_offset = bit_offset % 8;
2607
2608 return field->getType().getAsOpaquePtr();
2609 }
2610 }
2611 }
2612 break;
2613
Greg Clayton9e409562010-07-28 02:04:09 +00002614 case clang::Type::ObjCObject:
2615 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002616 if (GetCompleteQualType (ast, parent_qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002617 {
Sean Callanan78e37602011-01-27 04:42:51 +00002618 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002619 assert (objc_class_type);
2620 if (objc_class_type)
2621 {
2622 uint32_t child_idx = 0;
2623 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2624
2625 if (class_interface_decl)
2626 {
2627
Greg Clayton6beaaa62011-01-17 03:46:26 +00002628 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
Greg Clayton9e409562010-07-28 02:04:09 +00002629 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2630 if (superclass_interface_decl)
2631 {
2632 if (omit_empty_base_classes)
2633 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002634 if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9e409562010-07-28 02:04:09 +00002635 {
2636 if (idx == 0)
2637 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002638 QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
Greg Clayton9e409562010-07-28 02:04:09 +00002639
2640
2641 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2642
Greg Clayton6beaaa62011-01-17 03:46:26 +00002643 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002644
2645 child_byte_size = ivar_type_info.first / 8;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002646 child_byte_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002647 child_is_base_class = true;
Greg Clayton9e409562010-07-28 02:04:09 +00002648
2649 return ivar_qual_type.getAsOpaquePtr();
2650 }
2651
2652 ++child_idx;
2653 }
2654 }
2655 else
2656 ++child_idx;
2657 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002658
2659 const uint32_t superclass_idx = child_idx;
Greg Clayton9e409562010-07-28 02:04:09 +00002660
2661 if (idx < (child_idx + class_interface_decl->ivar_size()))
2662 {
2663 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2664
2665 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2666 {
2667 if (child_idx == idx)
2668 {
2669 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2670
2671 QualType ivar_qual_type(ivar_decl->getType());
2672
2673 child_name.assign(ivar_decl->getNameAsString().c_str());
2674
Greg Clayton6beaaa62011-01-17 03:46:26 +00002675 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002676
2677 child_byte_size = ivar_type_info.first / 8;
2678
2679 // Figure out the field offset within the current struct/union/class type
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002680 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9e409562010-07-28 02:04:09 +00002681 child_byte_offset = bit_offset / 8;
2682
2683 return ivar_qual_type.getAsOpaquePtr();
2684 }
2685 ++child_idx;
2686 }
2687 }
2688 }
2689 }
2690 }
2691 break;
2692
2693 case clang::Type::ObjCObjectPointer:
2694 {
Sean Callanan78e37602011-01-27 04:42:51 +00002695 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002696 QualType pointee_type = pointer_type->getPointeeType();
2697
2698 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2699 {
Greg Claytone221f822011-01-21 01:59:00 +00002700 child_is_deref_of_parent = false;
2701 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002702 return GetChildClangTypeAtIndex (ast,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002703 parent_name,
2704 pointer_type->getPointeeType().getAsOpaquePtr(),
2705 idx,
2706 transparent_pointers,
2707 omit_empty_base_classes,
2708 child_name,
2709 child_byte_size,
2710 child_byte_offset,
2711 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002712 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002713 child_is_base_class,
2714 tmp_child_is_deref_of_parent);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002715 }
2716 else
2717 {
Greg Claytone221f822011-01-21 01:59:00 +00002718 child_is_deref_of_parent = true;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002719 if (parent_name)
2720 {
2721 child_name.assign(1, '*');
2722 child_name += parent_name;
2723 }
2724
2725 // We have a pointer to an simple type
2726 if (idx == 0)
2727 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002728 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002729 assert(clang_type_info.first % 8 == 0);
2730 child_byte_size = clang_type_info.first / 8;
2731 child_byte_offset = 0;
2732 return pointee_type.getAsOpaquePtr();
2733 }
2734 }
Greg Clayton9e409562010-07-28 02:04:09 +00002735 }
2736 break;
2737
Greg Claytone1a916a2010-07-21 22:12:05 +00002738 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002739 {
2740 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2741 const uint64_t element_count = array->getSize().getLimitedValue();
2742
2743 if (idx < element_count)
2744 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002745 if (GetCompleteQualType (ast, array->getElementType()))
2746 {
2747 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002748
Greg Clayton6beaaa62011-01-17 03:46:26 +00002749 char element_name[64];
2750 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002751
Greg Clayton6beaaa62011-01-17 03:46:26 +00002752 child_name.assign(element_name);
2753 assert(field_type_info.first % 8 == 0);
2754 child_byte_size = field_type_info.first / 8;
2755 child_byte_offset = idx * child_byte_size;
2756 return array->getElementType().getAsOpaquePtr();
2757 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002758 }
2759 }
2760 break;
2761
Greg Claytone1a916a2010-07-21 22:12:05 +00002762 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002763 {
Sean Callanan78e37602011-01-27 04:42:51 +00002764 const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002765 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton97a43712011-01-08 22:26:47 +00002766
2767 // Don't dereference "void *" pointers
2768 if (pointee_type->isVoidType())
2769 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002770
2771 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2772 {
Greg Claytone221f822011-01-21 01:59:00 +00002773 child_is_deref_of_parent = false;
2774 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002775 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002776 parent_name,
2777 pointer_type->getPointeeType().getAsOpaquePtr(),
2778 idx,
2779 transparent_pointers,
2780 omit_empty_base_classes,
2781 child_name,
2782 child_byte_size,
2783 child_byte_offset,
2784 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002785 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002786 child_is_base_class,
2787 tmp_child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002788 }
2789 else
2790 {
Greg Claytone221f822011-01-21 01:59:00 +00002791 child_is_deref_of_parent = true;
2792
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002793 if (parent_name)
2794 {
2795 child_name.assign(1, '*');
2796 child_name += parent_name;
2797 }
2798
2799 // We have a pointer to an simple type
2800 if (idx == 0)
2801 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002802 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002803 assert(clang_type_info.first % 8 == 0);
2804 child_byte_size = clang_type_info.first / 8;
2805 child_byte_offset = 0;
2806 return pointee_type.getAsOpaquePtr();
2807 }
2808 }
2809 }
2810 break;
2811
Greg Clayton73b472d2010-10-27 03:32:59 +00002812 case clang::Type::LValueReference:
2813 case clang::Type::RValueReference:
2814 {
Sean Callanan78e37602011-01-27 04:42:51 +00002815 const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002816 QualType pointee_type(reference_type->getPointeeType());
2817 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2818 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2819 {
Greg Claytone221f822011-01-21 01:59:00 +00002820 child_is_deref_of_parent = false;
2821 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002822 return GetChildClangTypeAtIndex (ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002823 parent_name,
2824 pointee_clang_type,
2825 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,
2832 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002833 child_is_base_class,
2834 tmp_child_is_deref_of_parent);
Greg Clayton73b472d2010-10-27 03:32:59 +00002835 }
2836 else
2837 {
2838 if (parent_name)
2839 {
2840 child_name.assign(1, '&');
2841 child_name += parent_name;
2842 }
2843
2844 // We have a pointer to an simple type
2845 if (idx == 0)
2846 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002847 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Clayton73b472d2010-10-27 03:32:59 +00002848 assert(clang_type_info.first % 8 == 0);
2849 child_byte_size = clang_type_info.first / 8;
2850 child_byte_offset = 0;
2851 return pointee_type.getAsOpaquePtr();
2852 }
2853 }
2854 }
2855 break;
2856
Greg Claytone1a916a2010-07-21 22:12:05 +00002857 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002858 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002859 parent_name,
Sean Callanan48114472010-12-13 01:26:27 +00002860 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002861 idx,
2862 transparent_pointers,
2863 omit_empty_base_classes,
2864 child_name,
2865 child_byte_size,
2866 child_byte_offset,
2867 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002868 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002869 child_is_base_class,
2870 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002871 break;
2872
2873 default:
2874 break;
2875 }
2876 }
Greg Clayton19503a22010-07-23 15:37:46 +00002877 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002878}
2879
2880static inline bool
2881BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2882{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002883 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002884}
2885
2886static uint32_t
2887GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2888{
2889 uint32_t num_bases = 0;
2890 if (cxx_record_decl)
2891 {
2892 if (omit_empty_base_classes)
2893 {
2894 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2895 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2896 base_class != base_class_end;
2897 ++base_class)
2898 {
2899 // Skip empty base classes
2900 if (omit_empty_base_classes)
2901 {
2902 if (BaseSpecifierIsEmpty (base_class))
2903 continue;
2904 }
2905 ++num_bases;
2906 }
2907 }
2908 else
2909 num_bases = cxx_record_decl->getNumBases();
2910 }
2911 return num_bases;
2912}
2913
2914
2915static uint32_t
2916GetIndexForRecordBase
2917(
2918 const RecordDecl *record_decl,
2919 const CXXBaseSpecifier *base_spec,
2920 bool omit_empty_base_classes
2921)
2922{
2923 uint32_t child_idx = 0;
2924
2925 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2926
2927// const char *super_name = record_decl->getNameAsCString();
2928// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2929// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2930//
2931 if (cxx_record_decl)
2932 {
2933 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2934 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2935 base_class != base_class_end;
2936 ++base_class)
2937 {
2938 if (omit_empty_base_classes)
2939 {
2940 if (BaseSpecifierIsEmpty (base_class))
2941 continue;
2942 }
2943
2944// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2945// child_idx,
2946// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2947//
2948//
2949 if (base_class == base_spec)
2950 return child_idx;
2951 ++child_idx;
2952 }
2953 }
2954
2955 return UINT32_MAX;
2956}
2957
2958
2959static uint32_t
2960GetIndexForRecordChild
2961(
2962 const RecordDecl *record_decl,
2963 NamedDecl *canonical_decl,
2964 bool omit_empty_base_classes
2965)
2966{
2967 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2968
2969// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2970//
2971//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2972// if (cxx_record_decl)
2973// {
2974// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2975// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2976// base_class != base_class_end;
2977// ++base_class)
2978// {
2979// if (omit_empty_base_classes)
2980// {
2981// if (BaseSpecifierIsEmpty (base_class))
2982// continue;
2983// }
2984//
2985//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2986//// record_decl->getNameAsCString(),
2987//// canonical_decl->getNameAsCString(),
2988//// child_idx,
2989//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2990//
2991//
2992// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2993// if (curr_base_class_decl == canonical_decl)
2994// {
2995// return child_idx;
2996// }
2997// ++child_idx;
2998// }
2999// }
3000//
3001// const uint32_t num_bases = child_idx;
3002 RecordDecl::field_iterator field, field_end;
3003 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3004 field != field_end;
3005 ++field, ++child_idx)
3006 {
3007// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
3008// record_decl->getNameAsCString(),
3009// canonical_decl->getNameAsCString(),
3010// child_idx - num_bases,
3011// field->getNameAsCString());
3012
3013 if (field->getCanonicalDecl() == canonical_decl)
3014 return child_idx;
3015 }
3016
3017 return UINT32_MAX;
3018}
3019
3020// Look for a child member (doesn't include base classes, but it does include
3021// their members) in the type hierarchy. Returns an index path into "clang_type"
3022// on how to reach the appropriate member.
3023//
3024// class A
3025// {
3026// public:
3027// int m_a;
3028// int m_b;
3029// };
3030//
3031// class B
3032// {
3033// };
3034//
3035// class C :
3036// public B,
3037// public A
3038// {
3039// };
3040//
3041// If we have a clang type that describes "class C", and we wanted to looked
3042// "m_b" in it:
3043//
3044// With omit_empty_base_classes == false we would get an integer array back with:
3045// { 1, 1 }
3046// The first index 1 is the child index for "class A" within class C
3047// The second index 1 is the child index for "m_b" within class A
3048//
3049// With omit_empty_base_classes == true we would get an integer array back with:
3050// { 0, 1 }
3051// 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)
3052// The second index 1 is the child index for "m_b" within class A
3053
3054size_t
3055ClangASTContext::GetIndexOfChildMemberWithName
3056(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003057 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003058 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003059 const char *name,
3060 bool omit_empty_base_classes,
3061 std::vector<uint32_t>& child_indexes
3062)
3063{
3064 if (clang_type && name && name[0])
3065 {
3066 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003067 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3068 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003069 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003070 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003071 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003072 {
3073 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3074 const RecordDecl *record_decl = record_type->getDecl();
3075
3076 assert(record_decl);
3077 uint32_t child_idx = 0;
3078
3079 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3080
3081 // Try and find a field that matches NAME
3082 RecordDecl::field_iterator field, field_end;
3083 StringRef name_sref(name);
3084 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3085 field != field_end;
3086 ++field, ++child_idx)
3087 {
3088 if (field->getName().equals (name_sref))
3089 {
3090 // We have to add on the number of base classes to this index!
3091 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
3092 return child_indexes.size();
3093 }
3094 }
3095
3096 if (cxx_record_decl)
3097 {
3098 const RecordDecl *parent_record_decl = cxx_record_decl;
3099
3100 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
3101
3102 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
3103 // Didn't find things easily, lets let clang do its thang...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003104 IdentifierInfo & ident_ref = ast->Idents.get(name, name + strlen (name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003105 DeclarationName decl_name(&ident_ref);
3106
3107 CXXBasePaths paths;
3108 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
3109 decl_name.getAsOpaquePtr(),
3110 paths))
3111 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003112 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
3113 for (path = paths.begin(); path != path_end; ++path)
3114 {
3115 const size_t num_path_elements = path->size();
3116 for (size_t e=0; e<num_path_elements; ++e)
3117 {
3118 CXXBasePathElement elem = (*path)[e];
3119
3120 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
3121 if (child_idx == UINT32_MAX)
3122 {
3123 child_indexes.clear();
3124 return 0;
3125 }
3126 else
3127 {
3128 child_indexes.push_back (child_idx);
3129 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
3130 }
3131 }
3132 DeclContext::lookup_iterator named_decl_pos;
3133 for (named_decl_pos = path->Decls.first;
3134 named_decl_pos != path->Decls.second && parent_record_decl;
3135 ++named_decl_pos)
3136 {
3137 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
3138
3139 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
3140 if (child_idx == UINT32_MAX)
3141 {
3142 child_indexes.clear();
3143 return 0;
3144 }
3145 else
3146 {
3147 child_indexes.push_back (child_idx);
3148 }
3149 }
3150 }
3151 return child_indexes.size();
3152 }
3153 }
3154
3155 }
3156 break;
3157
Greg Clayton9e409562010-07-28 02:04:09 +00003158 case clang::Type::ObjCObject:
3159 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003160 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003161 {
3162 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003163 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003164 assert (objc_class_type);
3165 if (objc_class_type)
3166 {
3167 uint32_t child_idx = 0;
3168 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3169
3170 if (class_interface_decl)
3171 {
3172 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3173 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3174
Greg Clayton6ba78152010-09-18 02:11:07 +00003175 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9e409562010-07-28 02:04:09 +00003176 {
3177 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3178
3179 if (ivar_decl->getName().equals (name_sref))
3180 {
3181 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3182 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3183 ++child_idx;
3184
3185 child_indexes.push_back (child_idx);
3186 return child_indexes.size();
3187 }
3188 }
3189
3190 if (superclass_interface_decl)
3191 {
3192 // The super class index is always zero for ObjC classes,
3193 // so we push it onto the child indexes in case we find
3194 // an ivar in our superclass...
3195 child_indexes.push_back (0);
3196
Greg Clayton6beaaa62011-01-17 03:46:26 +00003197 if (GetIndexOfChildMemberWithName (ast,
3198 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00003199 name,
3200 omit_empty_base_classes,
3201 child_indexes))
3202 {
3203 // We did find an ivar in a superclass so just
3204 // return the results!
3205 return child_indexes.size();
3206 }
3207
3208 // We didn't find an ivar matching "name" in our
3209 // superclass, pop the superclass zero index that
3210 // we pushed on above.
3211 child_indexes.pop_back();
3212 }
3213 }
3214 }
3215 }
3216 break;
3217
3218 case clang::Type::ObjCObjectPointer:
3219 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003220 return GetIndexOfChildMemberWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003221 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3222 name,
3223 omit_empty_base_classes,
3224 child_indexes);
3225 }
3226 break;
3227
3228
Greg Claytone1a916a2010-07-21 22:12:05 +00003229 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003230 {
3231// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3232// const uint64_t element_count = array->getSize().getLimitedValue();
3233//
3234// if (idx < element_count)
3235// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003236// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003237//
3238// char element_name[32];
3239// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3240//
3241// child_name.assign(element_name);
3242// assert(field_type_info.first % 8 == 0);
3243// child_byte_size = field_type_info.first / 8;
3244// child_byte_offset = idx * child_byte_size;
3245// return array->getElementType().getAsOpaquePtr();
3246// }
3247 }
3248 break;
3249
Greg Claytone1a916a2010-07-21 22:12:05 +00003250// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003251// {
3252// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3253// QualType pointee_type = mem_ptr_type->getPointeeType();
3254//
3255// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3256// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003257// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003258// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3259// name);
3260// }
3261// }
3262// break;
3263//
Greg Claytone1a916a2010-07-21 22:12:05 +00003264 case clang::Type::LValueReference:
3265 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003266 {
Sean Callanan78e37602011-01-27 04:42:51 +00003267 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003268 QualType pointee_type = reference_type->getPointeeType();
3269
3270 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3271 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003272 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003273 reference_type->getPointeeType().getAsOpaquePtr(),
3274 name,
3275 omit_empty_base_classes,
3276 child_indexes);
3277 }
3278 }
3279 break;
3280
Greg Claytone1a916a2010-07-21 22:12:05 +00003281 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003282 {
Sean Callanan78e37602011-01-27 04:42:51 +00003283 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003284 QualType pointee_type = pointer_type->getPointeeType();
3285
3286 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3287 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003288 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003289 pointer_type->getPointeeType().getAsOpaquePtr(),
3290 name,
3291 omit_empty_base_classes,
3292 child_indexes);
3293 }
3294 else
3295 {
3296// if (parent_name)
3297// {
3298// child_name.assign(1, '*');
3299// child_name += parent_name;
3300// }
3301//
3302// // We have a pointer to an simple type
3303// if (idx == 0)
3304// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003305// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003306// assert(clang_type_info.first % 8 == 0);
3307// child_byte_size = clang_type_info.first / 8;
3308// child_byte_offset = 0;
3309// return pointee_type.getAsOpaquePtr();
3310// }
3311 }
3312 }
3313 break;
3314
Greg Claytone1a916a2010-07-21 22:12:05 +00003315 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003316 return GetIndexOfChildMemberWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003317 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003318 name,
3319 omit_empty_base_classes,
3320 child_indexes);
3321
3322 default:
3323 break;
3324 }
3325 }
3326 return 0;
3327}
3328
3329
3330// Get the index of the child of "clang_type" whose name matches. This function
3331// doesn't descend into the children, but only looks one level deep and name
3332// matches can include base class names.
3333
3334uint32_t
3335ClangASTContext::GetIndexOfChildWithName
3336(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003337 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003338 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003339 const char *name,
3340 bool omit_empty_base_classes
3341)
3342{
3343 if (clang_type && name && name[0])
3344 {
3345 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00003346
Greg Clayton737b9322010-09-13 03:32:57 +00003347 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9e409562010-07-28 02:04:09 +00003348
Greg Clayton737b9322010-09-13 03:32:57 +00003349 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003350 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003351 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003352 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003353 {
3354 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3355 const RecordDecl *record_decl = record_type->getDecl();
3356
3357 assert(record_decl);
3358 uint32_t child_idx = 0;
3359
3360 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3361
3362 if (cxx_record_decl)
3363 {
3364 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3365 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3366 base_class != base_class_end;
3367 ++base_class)
3368 {
3369 // Skip empty base classes
3370 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3371 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3372 continue;
3373
3374 if (base_class->getType().getAsString().compare (name) == 0)
3375 return child_idx;
3376 ++child_idx;
3377 }
3378 }
3379
3380 // Try and find a field that matches NAME
3381 RecordDecl::field_iterator field, field_end;
3382 StringRef name_sref(name);
3383 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3384 field != field_end;
3385 ++field, ++child_idx)
3386 {
3387 if (field->getName().equals (name_sref))
3388 return child_idx;
3389 }
3390
3391 }
3392 break;
3393
Greg Clayton9e409562010-07-28 02:04:09 +00003394 case clang::Type::ObjCObject:
3395 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003396 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003397 {
3398 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003399 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003400 assert (objc_class_type);
3401 if (objc_class_type)
3402 {
3403 uint32_t child_idx = 0;
3404 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3405
3406 if (class_interface_decl)
3407 {
3408 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3409 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3410
3411 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3412 {
3413 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3414
3415 if (ivar_decl->getName().equals (name_sref))
3416 {
3417 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3418 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3419 ++child_idx;
3420
3421 return child_idx;
3422 }
3423 }
3424
3425 if (superclass_interface_decl)
3426 {
3427 if (superclass_interface_decl->getName().equals (name_sref))
3428 return 0;
3429 }
3430 }
3431 }
3432 }
3433 break;
3434
3435 case clang::Type::ObjCObjectPointer:
3436 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003437 return GetIndexOfChildWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003438 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3439 name,
3440 omit_empty_base_classes);
3441 }
3442 break;
3443
Greg Claytone1a916a2010-07-21 22:12:05 +00003444 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003445 {
3446// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3447// const uint64_t element_count = array->getSize().getLimitedValue();
3448//
3449// if (idx < element_count)
3450// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003451// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003452//
3453// char element_name[32];
3454// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3455//
3456// child_name.assign(element_name);
3457// assert(field_type_info.first % 8 == 0);
3458// child_byte_size = field_type_info.first / 8;
3459// child_byte_offset = idx * child_byte_size;
3460// return array->getElementType().getAsOpaquePtr();
3461// }
3462 }
3463 break;
3464
Greg Claytone1a916a2010-07-21 22:12:05 +00003465// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003466// {
3467// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3468// QualType pointee_type = mem_ptr_type->getPointeeType();
3469//
3470// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3471// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003472// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003473// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3474// name);
3475// }
3476// }
3477// break;
3478//
Greg Claytone1a916a2010-07-21 22:12:05 +00003479 case clang::Type::LValueReference:
3480 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003481 {
Sean Callanan78e37602011-01-27 04:42:51 +00003482 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003483 QualType pointee_type = reference_type->getPointeeType();
3484
3485 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3486 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003487 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003488 reference_type->getPointeeType().getAsOpaquePtr(),
3489 name,
3490 omit_empty_base_classes);
3491 }
3492 }
3493 break;
3494
Greg Claytone1a916a2010-07-21 22:12:05 +00003495 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003496 {
Sean Callanan78e37602011-01-27 04:42:51 +00003497 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003498 QualType pointee_type = pointer_type->getPointeeType();
3499
3500 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3501 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003502 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003503 pointer_type->getPointeeType().getAsOpaquePtr(),
3504 name,
3505 omit_empty_base_classes);
3506 }
3507 else
3508 {
3509// if (parent_name)
3510// {
3511// child_name.assign(1, '*');
3512// child_name += parent_name;
3513// }
3514//
3515// // We have a pointer to an simple type
3516// if (idx == 0)
3517// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003518// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003519// assert(clang_type_info.first % 8 == 0);
3520// child_byte_size = clang_type_info.first / 8;
3521// child_byte_offset = 0;
3522// return pointee_type.getAsOpaquePtr();
3523// }
3524 }
3525 }
3526 break;
3527
Greg Claytone1a916a2010-07-21 22:12:05 +00003528 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003529 return GetIndexOfChildWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003530 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003531 name,
3532 omit_empty_base_classes);
3533
3534 default:
3535 break;
3536 }
3537 }
3538 return UINT32_MAX;
3539}
3540
3541#pragma mark TagType
3542
3543bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003544ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003545{
3546 if (tag_clang_type)
3547 {
3548 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00003549 const clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003550 if (clang_type)
3551 {
Sean Callanan78e37602011-01-27 04:42:51 +00003552 const TagType *tag_type = dyn_cast<TagType>(clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003553 if (tag_type)
3554 {
3555 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3556 if (tag_decl)
3557 {
3558 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3559 return true;
3560 }
3561 }
3562 }
3563 }
3564 return false;
3565}
3566
3567
3568#pragma mark DeclContext Functions
3569
3570DeclContext *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003571ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003572{
3573 if (clang_type == NULL)
3574 return NULL;
3575
3576 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003577 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3578 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003579 {
Greg Clayton9e409562010-07-28 02:04:09 +00003580 case clang::Type::FunctionNoProto: break;
3581 case clang::Type::FunctionProto: break;
3582 case clang::Type::IncompleteArray: break;
3583 case clang::Type::VariableArray: break;
3584 case clang::Type::ConstantArray: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003585 case clang::Type::DependentSizedArray: break;
Greg Clayton9e409562010-07-28 02:04:09 +00003586 case clang::Type::ExtVector: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003587 case clang::Type::DependentSizedExtVector: break;
Greg Clayton9e409562010-07-28 02:04:09 +00003588 case clang::Type::Vector: break;
3589 case clang::Type::Builtin: break;
3590 case clang::Type::BlockPointer: break;
3591 case clang::Type::Pointer: break;
3592 case clang::Type::LValueReference: break;
3593 case clang::Type::RValueReference: break;
3594 case clang::Type::MemberPointer: break;
3595 case clang::Type::Complex: break;
3596 case clang::Type::ObjCObject: break;
3597 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3598 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3599 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3600 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
Sean Callanan48114472010-12-13 01:26:27 +00003601 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003602
Greg Clayton9e409562010-07-28 02:04:09 +00003603 case clang::Type::TypeOfExpr: break;
3604 case clang::Type::TypeOf: break;
3605 case clang::Type::Decltype: break;
3606 //case clang::Type::QualifiedName: break;
3607 case clang::Type::TemplateSpecialization: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003608 case clang::Type::DependentTemplateSpecialization: break;
3609 case clang::Type::TemplateTypeParm: break;
3610 case clang::Type::SubstTemplateTypeParm: break;
3611 case clang::Type::SubstTemplateTypeParmPack:break;
3612 case clang::Type::PackExpansion: break;
3613 case clang::Type::UnresolvedUsing: break;
3614 case clang::Type::Paren: break;
3615 case clang::Type::Elaborated: break;
3616 case clang::Type::Attributed: break;
3617 case clang::Type::Auto: break;
3618 case clang::Type::InjectedClassName: break;
3619 case clang::Type::DependentName: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003620 }
3621 // No DeclContext in this type...
3622 return NULL;
3623}
3624
3625#pragma mark Namespace Declarations
3626
3627NamespaceDecl *
3628ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3629{
3630 // TODO: Do something intelligent with the Declaration object passed in
3631 // like maybe filling in the SourceLocation with it...
3632 if (name)
3633 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003634 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003635 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00003636 decl_ctx = ast->getTranslationUnitDecl();
Sean Callananfb0b7582011-03-15 00:17:19 +00003637 return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &ast->Idents.get(name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003638 }
3639 return NULL;
3640}
3641
3642
3643#pragma mark Function Types
3644
3645FunctionDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003646ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003647{
3648 if (name)
3649 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003650 ASTContext *ast = getASTContext();
3651 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003652
3653 if (name && name[0])
3654 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003655 return FunctionDecl::Create(*ast,
3656 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003657 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003658 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003659 DeclarationName (&ast->Idents.get(name)),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003660 QualType::getFromOpaquePtr(function_clang_type),
3661 NULL,
3662 (FunctionDecl::StorageClass)storage,
3663 (FunctionDecl::StorageClass)storage,
3664 is_inline);
3665 }
3666 else
3667 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003668 return FunctionDecl::Create(*ast,
3669 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003670 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003671 SourceLocation(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003672 DeclarationName (),
3673 QualType::getFromOpaquePtr(function_clang_type),
3674 NULL,
3675 (FunctionDecl::StorageClass)storage,
3676 (FunctionDecl::StorageClass)storage,
3677 is_inline);
3678 }
3679 }
3680 return NULL;
3681}
3682
Greg Clayton1be10fc2010-09-29 01:12:09 +00003683clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00003684ClangASTContext::CreateFunctionType (ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003685 clang_type_t result_type,
3686 clang_type_t *args,
Sean Callananc81256a2010-09-16 20:40:25 +00003687 unsigned num_args,
3688 bool is_variadic,
3689 unsigned type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003690{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003691 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003692 std::vector<QualType> qual_type_args;
3693 for (unsigned i=0; i<num_args; ++i)
3694 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3695
3696 // TODO: Detect calling convention in DWARF?
Sean Callanan2c777c42011-01-18 23:32:05 +00003697 FunctionProtoType::ExtProtoInfo proto_info;
3698 proto_info.Variadic = is_variadic;
Sean Callananfb0b7582011-03-15 00:17:19 +00003699 proto_info.ExceptionSpecType = EST_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00003700 proto_info.TypeQuals = type_quals;
Sean Callananfb0b7582011-03-15 00:17:19 +00003701 proto_info.RefQualifier = RQ_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00003702 proto_info.NumExceptions = 0;
3703 proto_info.Exceptions = NULL;
3704
Greg Clayton6beaaa62011-01-17 03:46:26 +00003705 return ast->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton471b31c2010-07-20 22:52:08 +00003706 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003707 qual_type_args.size(),
Sean Callanan2c777c42011-01-18 23:32:05 +00003708 proto_info).getAsOpaquePtr(); // NoReturn);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003709}
3710
3711ParmVarDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003712ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003713{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003714 ASTContext *ast = getASTContext();
3715 assert (ast != NULL);
3716 return ParmVarDecl::Create(*ast,
3717 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003718 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003719 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003720 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callananc81256a2010-09-16 20:40:25 +00003721 QualType::getFromOpaquePtr(param_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003722 NULL,
3723 (VarDecl::StorageClass)storage,
3724 (VarDecl::StorageClass)storage,
3725 0);
3726}
3727
3728void
3729ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3730{
3731 if (function_decl)
3732 function_decl->setParams (params, num_params);
3733}
3734
3735
3736#pragma mark Array Types
3737
Greg Clayton1be10fc2010-09-29 01:12:09 +00003738clang_type_t
3739ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003740{
3741 if (element_type)
3742 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003743 ASTContext *ast = getASTContext();
3744 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003745 llvm::APInt ap_element_count (64, element_count);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003746 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003747 ap_element_count,
3748 ArrayType::Normal,
3749 0).getAsOpaquePtr(); // ElemQuals
3750 }
3751 return NULL;
3752}
3753
3754
3755#pragma mark TagDecl
3756
3757bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003758ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003759{
3760 if (clang_type)
3761 {
3762 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00003763 const clang::Type *t = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003764 if (t)
3765 {
Sean Callanan78e37602011-01-27 04:42:51 +00003766 const TagType *tag_type = dyn_cast<TagType>(t);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003767 if (tag_type)
3768 {
3769 TagDecl *tag_decl = tag_type->getDecl();
3770 if (tag_decl)
3771 {
3772 tag_decl->startDefinition();
3773 return true;
3774 }
3775 }
3776 }
3777 }
3778 return false;
3779}
3780
3781bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003782ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003783{
3784 if (clang_type)
3785 {
3786 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton14372242010-09-29 03:44:17 +00003787
3788 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3789
3790 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003791 {
Greg Clayton14372242010-09-29 03:44:17 +00003792 cxx_record_decl->completeDefinition();
3793
3794 return true;
3795 }
3796
Sean Callanan78e37602011-01-27 04:42:51 +00003797 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
Sean Callanana2424172010-10-25 00:29:48 +00003798
3799 if (objc_class_type)
3800 {
3801 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3802
3803 class_interface_decl->setForwardDecl(false);
3804 }
3805
Greg Clayton14372242010-09-29 03:44:17 +00003806 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3807
3808 if (enum_type)
3809 {
3810 EnumDecl *enum_decl = enum_type->getDecl();
3811
3812 if (enum_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003813 {
Greg Clayton14372242010-09-29 03:44:17 +00003814 /// TODO This really needs to be fixed.
3815
3816 unsigned NumPositiveBits = 1;
3817 unsigned NumNegativeBits = 0;
3818
Greg Clayton6beaaa62011-01-17 03:46:26 +00003819 ASTContext *ast = getASTContext();
Greg Claytone02b8502010-10-12 04:29:14 +00003820
3821 QualType promotion_qual_type;
3822 // If the enum integer type is less than an integer in bit width,
3823 // then we must promote it to an integer size.
Greg Clayton6beaaa62011-01-17 03:46:26 +00003824 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
Greg Claytone02b8502010-10-12 04:29:14 +00003825 {
3826 if (enum_decl->getIntegerType()->isSignedIntegerType())
Greg Clayton6beaaa62011-01-17 03:46:26 +00003827 promotion_qual_type = ast->IntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003828 else
Greg Clayton6beaaa62011-01-17 03:46:26 +00003829 promotion_qual_type = ast->UnsignedIntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003830 }
3831 else
3832 promotion_qual_type = enum_decl->getIntegerType();
3833
3834 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton14372242010-09-29 03:44:17 +00003835 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003836 }
3837 }
3838 }
3839 return false;
3840}
3841
3842
3843#pragma mark Enumeration Types
3844
Greg Clayton1be10fc2010-09-29 01:12:09 +00003845clang_type_t
Greg Claytonca512b32011-01-14 04:54:56 +00003846ClangASTContext::CreateEnumerationType
3847(
3848 const char *name,
3849 DeclContext *decl_ctx,
3850 const Declaration &decl,
3851 clang_type_t integer_qual_type
3852)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003853{
3854 // TODO: Do something intelligent with the Declaration object passed in
3855 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003856 ASTContext *ast = getASTContext();
3857 assert (ast != NULL);
Greg Claytone02b8502010-10-12 04:29:14 +00003858
3859 // TODO: ask about these...
3860// const bool IsScoped = false;
3861// const bool IsFixed = false;
3862
Greg Clayton6beaaa62011-01-17 03:46:26 +00003863 EnumDecl *enum_decl = EnumDecl::Create (*ast,
Greg Claytonca512b32011-01-14 04:54:56 +00003864 decl_ctx,
Greg Claytone02b8502010-10-12 04:29:14 +00003865 SourceLocation(),
Greg Claytone02b8502010-10-12 04:29:14 +00003866 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003867 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callanan48114472010-12-13 01:26:27 +00003868 NULL,
3869 false, // IsScoped
3870 false, // IsScopedUsingClassTag
3871 false); // IsFixed
Sean Callanan2652ad22011-01-18 01:03:44 +00003872
3873
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003874 if (enum_decl)
Greg Clayton83ff3892010-09-12 23:17:56 +00003875 {
3876 // TODO: check if we should be setting the promotion type too?
3877 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00003878
3879 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
3880
Greg Clayton6beaaa62011-01-17 03:46:26 +00003881 return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Clayton83ff3892010-09-12 23:17:56 +00003882 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003883 return NULL;
3884}
3885
Greg Clayton1be10fc2010-09-29 01:12:09 +00003886clang_type_t
3887ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3888{
3889 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3890
Sean Callanan78e37602011-01-27 04:42:51 +00003891 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003892 if (clang_type)
3893 {
3894 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3895 if (enum_type)
3896 {
3897 EnumDecl *enum_decl = enum_type->getDecl();
3898 if (enum_decl)
3899 return enum_decl->getIntegerType().getAsOpaquePtr();
3900 }
3901 }
3902 return NULL;
3903}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003904bool
3905ClangASTContext::AddEnumerationValueToEnumerationType
3906(
Greg Clayton1be10fc2010-09-29 01:12:09 +00003907 clang_type_t enum_clang_type,
3908 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003909 const Declaration &decl,
3910 const char *name,
3911 int64_t enum_value,
3912 uint32_t enum_value_bit_size
3913)
3914{
3915 if (enum_clang_type && enumerator_clang_type && name)
3916 {
3917 // TODO: Do something intelligent with the Declaration object passed in
3918 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003919 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003920 IdentifierTable *identifier_table = getIdentifierTable();
3921
Greg Clayton6beaaa62011-01-17 03:46:26 +00003922 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003923 assert (identifier_table != NULL);
3924 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3925
Sean Callanan78e37602011-01-27 04:42:51 +00003926 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003927 if (clang_type)
3928 {
3929 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3930
3931 if (enum_type)
3932 {
3933 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3934 enum_llvm_apsint = enum_value;
3935 EnumConstantDecl *enumerator_decl =
Greg Clayton6beaaa62011-01-17 03:46:26 +00003936 EnumConstantDecl::Create (*ast,
3937 enum_type->getDecl(),
3938 SourceLocation(),
3939 name ? &identifier_table->get(name) : NULL, // Identifier
3940 QualType::getFromOpaquePtr(enumerator_clang_type),
3941 NULL,
3942 enum_llvm_apsint);
3943
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003944 if (enumerator_decl)
3945 {
3946 enum_type->getDecl()->addDecl(enumerator_decl);
3947 return true;
3948 }
3949 }
3950 }
3951 }
3952 return false;
3953}
3954
3955#pragma mark Pointers & References
3956
Greg Clayton1be10fc2010-09-29 01:12:09 +00003957clang_type_t
3958ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003959{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003960 return CreatePointerType (getASTContext(), clang_type);
3961}
3962
3963clang_type_t
3964ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
3965{
3966 if (ast && clang_type)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003967 {
3968 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3969
Greg Clayton737b9322010-09-13 03:32:57 +00003970 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3971 switch (type_class)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003972 {
3973 case clang::Type::ObjCObject:
3974 case clang::Type::ObjCInterface:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003975 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003976
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003977 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003978 return ast->getPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003979 }
3980 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003981 return NULL;
3982}
3983
Greg Clayton1be10fc2010-09-29 01:12:09 +00003984clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003985ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
3986 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003987{
3988 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003989 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003990 return NULL;
3991}
3992
Greg Clayton1be10fc2010-09-29 01:12:09 +00003993clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003994ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
3995 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003996{
3997 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003998 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003999 return NULL;
4000}
4001
Greg Clayton1be10fc2010-09-29 01:12:09 +00004002clang_type_t
4003ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Clayton9b81a312010-06-12 01:20:30 +00004004{
4005 if (clang_pointee_type && clang_pointee_type)
4006 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
4007 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
4008 return NULL;
4009}
4010
Greg Clayton1a65ae12011-01-25 23:55:37 +00004011uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004012ClangASTContext::GetPointerBitSize ()
4013{
Greg Clayton6beaaa62011-01-17 03:46:26 +00004014 ASTContext *ast = getASTContext();
4015 return ast->getTypeSize(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004016}
4017
4018bool
Greg Clayton007d5be2011-05-30 00:49:24 +00004019ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
4020{
4021 QualType pointee_qual_type;
4022 if (clang_type)
4023 {
4024 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4025 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4026 bool success = false;
4027 switch (type_class)
4028 {
4029 case clang::Type::Pointer:
4030 pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
4031 success = true;
4032 break;
4033
4034 case clang::Type::LValueReference:
4035 case clang::Type::RValueReference:
4036 pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
4037 success = true;
4038 break;
4039
4040 case clang::Type::Typedef:
4041 return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
4042
4043 default:
4044 break;
4045 }
4046
4047 if (success)
4048 {
4049 // Check to make sure what we are pointing too is a possible dynamic C++ type
4050 // We currently accept any "void *" (in case we have a class that has been
4051 // watered down to an opaque pointer) and virtual C++ classes.
4052 const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
4053 switch (pointee_type_class)
4054 {
4055 case clang::Type::Builtin:
4056 switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
4057 {
4058 case clang::BuiltinType::UnknownAny:
4059 case clang::BuiltinType::Void:
4060 if (dynamic_pointee_type)
4061 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4062 return true;
4063
4064 case clang::BuiltinType::NullPtr:
4065 case clang::BuiltinType::Bool:
4066 case clang::BuiltinType::Char_U:
4067 case clang::BuiltinType::UChar:
4068 case clang::BuiltinType::WChar_U:
4069 case clang::BuiltinType::Char16:
4070 case clang::BuiltinType::Char32:
4071 case clang::BuiltinType::UShort:
4072 case clang::BuiltinType::UInt:
4073 case clang::BuiltinType::ULong:
4074 case clang::BuiltinType::ULongLong:
4075 case clang::BuiltinType::UInt128:
4076 case clang::BuiltinType::Char_S:
4077 case clang::BuiltinType::SChar:
4078 case clang::BuiltinType::WChar_S:
4079 case clang::BuiltinType::Short:
4080 case clang::BuiltinType::Int:
4081 case clang::BuiltinType::Long:
4082 case clang::BuiltinType::LongLong:
4083 case clang::BuiltinType::Int128:
4084 case clang::BuiltinType::Float:
4085 case clang::BuiltinType::Double:
4086 case clang::BuiltinType::LongDouble:
4087 case clang::BuiltinType::Dependent:
4088 case clang::BuiltinType::Overload:
4089 case clang::BuiltinType::ObjCId:
4090 case clang::BuiltinType::ObjCClass:
4091 case clang::BuiltinType::ObjCSel:
4092 case clang::BuiltinType::BoundMember:
4093 break;
4094 }
4095 break;
4096 case clang::Type::Record:
4097 {
4098 CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
4099 if (cxx_record_decl)
4100 {
4101 if (GetCompleteQualType (ast, pointee_qual_type))
4102 {
Greg Claytona13ad2ad2011-06-02 01:26:44 +00004103 success = cxx_record_decl->isDynamicClass();
Greg Clayton007d5be2011-05-30 00:49:24 +00004104 }
4105 else
4106 {
4107 // We failed to get the complete type, so we have to
4108 // treat this as a void * which we might possibly be
4109 // able to complete
4110 success = true;
4111 }
4112 if (success)
4113 {
4114 if (dynamic_pointee_type)
4115 *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4116 return true;
4117 }
4118 }
4119 }
4120 break;
4121
4122 default:
4123 break;
4124 }
4125 }
4126 }
4127 if (dynamic_pointee_type)
4128 *dynamic_pointee_type = NULL;
4129 return false;
4130}
4131
4132
4133bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004134ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004135{
4136 if (clang_type == NULL)
4137 return false;
4138
4139 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004140 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4141 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004142 {
Sean Callanana2424172010-10-25 00:29:48 +00004143 case clang::Type::Builtin:
4144 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4145 {
4146 default:
4147 break;
4148 case clang::BuiltinType::ObjCId:
4149 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004150 return true;
4151 }
4152 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004153 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004154 if (target_type)
4155 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4156 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004157 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004158 if (target_type)
4159 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4160 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004161 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004162 if (target_type)
4163 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4164 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004165 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004166 if (target_type)
4167 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4168 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004169 case clang::Type::LValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004170 if (target_type)
4171 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4172 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004173 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004174 if (target_type)
4175 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4176 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004177 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004178 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004179 default:
4180 break;
4181 }
4182 return false;
4183}
4184
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004185bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004186ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004187{
4188 if (!clang_type)
4189 return false;
4190
4191 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4192 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
4193
4194 if (builtin_type)
4195 {
4196 if (builtin_type->isInteger())
4197 is_signed = builtin_type->isSignedInteger();
4198
4199 return true;
4200 }
4201
4202 return false;
4203}
4204
4205bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004206ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004207{
4208 if (clang_type)
4209 {
4210 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004211 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4212 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004213 {
Sean Callanana2424172010-10-25 00:29:48 +00004214 case clang::Type::Builtin:
4215 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4216 {
4217 default:
4218 break;
4219 case clang::BuiltinType::ObjCId:
4220 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004221 return true;
4222 }
4223 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004224 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004225 if (target_type)
4226 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4227 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004228 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004229 if (target_type)
4230 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4231 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004232 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004233 if (target_type)
4234 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4235 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004236 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004237 if (target_type)
4238 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4239 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004240 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004241 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004242 default:
4243 break;
4244 }
4245 }
4246 return false;
4247}
4248
4249bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004250ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004251{
4252 if (clang_type)
4253 {
4254 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4255
4256 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
4257 {
4258 clang::BuiltinType::Kind kind = BT->getKind();
4259 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
4260 {
4261 count = 1;
4262 is_complex = false;
4263 return true;
4264 }
4265 }
4266 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
4267 {
4268 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
4269 {
4270 count = 2;
4271 is_complex = true;
4272 return true;
4273 }
4274 }
4275 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
4276 {
4277 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
4278 {
4279 count = VT->getNumElements();
4280 is_complex = false;
4281 return true;
4282 }
4283 }
4284 }
4285 return false;
4286}
4287
Greg Clayton8f92f0a2010-10-14 22:52:14 +00004288
4289bool
4290ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
4291{
4292 if (clang_type)
4293 {
4294 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4295
4296 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4297 if (cxx_record_decl)
4298 {
4299 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
4300 return true;
4301 }
4302 }
4303 class_name.clear();
4304 return false;
4305}
4306
4307
Greg Clayton0fffff52010-09-24 05:15:53 +00004308bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004309ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004310{
4311 if (clang_type)
4312 {
4313 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4314 if (qual_type->getAsCXXRecordDecl() != NULL)
4315 return true;
4316 }
4317 return false;
4318}
4319
4320bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004321ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004322{
4323 if (clang_type)
4324 {
4325 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4326 if (qual_type->isObjCObjectOrInterfaceType())
4327 return true;
4328 }
4329 return false;
4330}
4331
4332
Greg Clayton73b472d2010-10-27 03:32:59 +00004333bool
4334ClangASTContext::IsCharType (clang_type_t clang_type)
4335{
4336 if (clang_type)
4337 return QualType::getFromOpaquePtr(clang_type)->isCharType();
4338 return false;
4339}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004340
4341bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004342ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004343{
Greg Clayton73b472d2010-10-27 03:32:59 +00004344 clang_type_t pointee_or_element_clang_type = NULL;
4345 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
4346
4347 if (pointee_or_element_clang_type == NULL)
4348 return false;
4349
4350 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004351 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004352 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
4353
4354 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004355 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004356 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4357 if (type_flags.Test (eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004358 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004359 // We know the size of the array and it could be a C string
4360 // since it is an array of characters
4361 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
4362 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004363 }
Greg Clayton73b472d2010-10-27 03:32:59 +00004364 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004365 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004366 length = 0;
4367 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004368 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004369
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004370 }
4371 }
4372 return false;
4373}
4374
4375bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004376ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton737b9322010-09-13 03:32:57 +00004377{
4378 if (clang_type)
4379 {
4380 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4381
4382 if (qual_type->isFunctionPointerType())
4383 return true;
4384
4385 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4386 switch (type_class)
4387 {
Sean Callananfb0b7582011-03-15 00:17:19 +00004388 default:
4389 break;
Greg Clayton737b9322010-09-13 03:32:57 +00004390 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004391 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004392
4393 case clang::Type::LValueReference:
4394 case clang::Type::RValueReference:
4395 {
Sean Callanan78e37602011-01-27 04:42:51 +00004396 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004397 if (reference_type)
4398 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
4399 }
4400 break;
4401 }
4402 }
4403 return false;
4404}
4405
Greg Clayton73b472d2010-10-27 03:32:59 +00004406size_t
4407ClangASTContext::GetArraySize (clang_type_t clang_type)
4408{
4409 if (clang_type)
4410 {
Sean Callanan78e37602011-01-27 04:42:51 +00004411 const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00004412 if (array)
4413 return array->getSize().getLimitedValue();
4414 }
4415 return 0;
4416}
Greg Clayton737b9322010-09-13 03:32:57 +00004417
4418bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004419ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004420{
4421 if (!clang_type)
4422 return false;
4423
4424 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4425
Greg Clayton737b9322010-09-13 03:32:57 +00004426 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4427 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004428 {
Sean Callananfb0b7582011-03-15 00:17:19 +00004429 default:
4430 break;
Greg Claytone1a916a2010-07-21 22:12:05 +00004431 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004432 if (member_type)
4433 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4434 if (size)
Greg Claytonac4827f2011-04-01 18:14:08 +00004435 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004436 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004437 case clang::Type::IncompleteArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004438 if (member_type)
4439 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4440 if (size)
4441 *size = 0;
4442 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004443 case clang::Type::VariableArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004444 if (member_type)
4445 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4446 if (size)
4447 *size = 0;
Greg Clayton03dbf2e2011-02-02 00:52:14 +00004448 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004449 case clang::Type::DependentSizedArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004450 if (member_type)
4451 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4452 if (size)
4453 *size = 0;
4454 return true;
4455 }
4456 return false;
4457}
4458
4459
4460#pragma mark Typedefs
4461
Greg Clayton1be10fc2010-09-29 01:12:09 +00004462clang_type_t
4463ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004464{
4465 if (clang_type)
4466 {
4467 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004468 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004469 IdentifierTable *identifier_table = getIdentifierTable();
Greg Clayton6beaaa62011-01-17 03:46:26 +00004470 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004471 assert (identifier_table != NULL);
4472 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00004473 decl_ctx = ast->getTranslationUnitDecl();
4474 TypedefDecl *decl = TypedefDecl::Create (*ast,
4475 decl_ctx,
4476 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004477 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00004478 name ? &identifier_table->get(name) : NULL, // Identifier
4479 ast->CreateTypeSourceInfo(qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00004480
4481 decl->setAccess(AS_public); // TODO respect proper access specifier
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004482
4483 // Get a uniqued QualType for the typedef decl type
Greg Clayton6beaaa62011-01-17 03:46:26 +00004484 return ast->getTypedefType (decl).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004485 }
4486 return NULL;
4487}
4488
4489
4490std::string
Greg Clayton1be10fc2010-09-29 01:12:09 +00004491ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004492{
4493 std::string return_name;
4494
Greg Clayton1be10fc2010-09-29 01:12:09 +00004495 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004496
Greg Clayton1be10fc2010-09-29 01:12:09 +00004497 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004498 if (typedef_type)
4499 {
Sean Callanand12cf8bb2011-05-15 22:34:38 +00004500 const TypedefNameDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004501 return_name = typedef_decl->getQualifiedNameAsString();
4502 }
4503 else
4504 {
4505 return_name = qual_type.getAsString();
4506 }
4507
4508 return return_name;
4509}
4510
4511// Disable this for now since I can't seem to get a nicely formatted float
4512// out of the APFloat class without just getting the float, double or quad
4513// and then using a formatted print on it which defeats the purpose. We ideally
4514// would like to get perfect string values for any kind of float semantics
4515// so we can support remote targets. The code below also requires a patch to
4516// llvm::APInt.
4517//bool
Greg Clayton6beaaa62011-01-17 03:46:26 +00004518//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 +00004519//{
4520// uint32_t count = 0;
4521// bool is_complex = false;
4522// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4523// {
4524// unsigned num_bytes_per_float = byte_size / count;
4525// unsigned num_bits_per_float = num_bytes_per_float * 8;
4526//
4527// float_str.clear();
4528// uint32_t i;
4529// for (i=0; i<count; i++)
4530// {
4531// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
4532// bool is_ieee = false;
4533// APFloat ap_float(ap_int, is_ieee);
4534// char s[1024];
4535// unsigned int hex_digits = 0;
4536// bool upper_case = false;
4537//
4538// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
4539// {
4540// if (i > 0)
4541// float_str.append(", ");
4542// float_str.append(s);
4543// if (i == 1 && is_complex)
4544// float_str.append(1, 'i');
4545// }
4546// }
4547// return !float_str.empty();
4548// }
4549// return false;
4550//}
4551
4552size_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00004553ClangASTContext::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 +00004554{
4555 if (clang_type)
4556 {
4557 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4558 uint32_t count = 0;
4559 bool is_complex = false;
4560 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4561 {
4562 // TODO: handle complex and vector types
4563 if (count != 1)
4564 return false;
4565
4566 StringRef s_sref(s);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004567 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004568
Greg Clayton6beaaa62011-01-17 03:46:26 +00004569 const uint64_t bit_size = ast->getTypeSize (qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004570 const uint64_t byte_size = bit_size / 8;
4571 if (dst_size >= byte_size)
4572 {
4573 if (bit_size == sizeof(float)*8)
4574 {
4575 float float32 = ap_float.convertToFloat();
4576 ::memcpy (dst, &float32, byte_size);
4577 return byte_size;
4578 }
4579 else if (bit_size >= 64)
4580 {
4581 llvm::APInt ap_int(ap_float.bitcastToAPInt());
4582 ::memcpy (dst, ap_int.getRawData(), byte_size);
4583 return byte_size;
4584 }
4585 }
4586 }
4587 }
4588 return 0;
4589}
Sean Callanan6fe64b52010-09-17 02:24:29 +00004590
4591unsigned
Greg Clayton1be10fc2010-09-29 01:12:09 +00004592ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanan6fe64b52010-09-17 02:24:29 +00004593{
4594 assert (clang_type);
4595
4596 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4597
4598 return qual_type.getQualifiers().getCVRQualifiers();
4599}
Greg Clayton6beaaa62011-01-17 03:46:26 +00004600
4601bool
4602ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
4603{
4604 if (clang_type == NULL)
4605 return false;
4606
Greg Claytonc432c192011-01-20 04:18:48 +00004607 return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004608}
4609
4610
4611bool
4612ClangASTContext::GetCompleteType (clang_type_t clang_type)
4613{
4614 return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
4615}
4616