blob: 57d25b9c94e442678c0f3f682aaa170c987348c6 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedman932197d2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Greg Clayton6beaaa62011-01-17 03:46:26 +000017
18// Clang headers like to use NDEBUG inside of them to enable/disable debug
19// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing
20// or another. This is bad because it means that if clang was built in release
21// mode, it assumes that you are building in release mode which is not always
22// the case. You can end up with functions that are defined as empty in header
23// files when NDEBUG is not defined, and this can cause link errors with the
24// clang .a files that you have since you might be missing functions in the .a
25// file. So we have to define NDEBUG when including clang headers to avoid any
26// mismatches. This is covered by rdar://problem/8691220
27
28#ifndef NDEBUG
29#define LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000030#define NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000031// Need to include assert.h so it is as clang would expect it to be (disabled)
32#include <assert.h>
33#endif
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "clang/AST/ASTContext.h"
36#include "clang/AST/ASTImporter.h"
37#include "clang/AST/CXXInheritance.h"
Greg Clayton8cf05932010-07-22 18:30:50 +000038#include "clang/AST/DeclObjC.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "clang/AST/RecordLayout.h"
40#include "clang/AST/Type.h"
41#include "clang/Basic/Builtins.h"
42#include "clang/Basic/FileManager.h"
Sean Callanan79439e82010-11-18 02:56:27 +000043#include "clang/Basic/FileSystemOptions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044#include "clang/Basic/SourceManager.h"
45#include "clang/Basic/TargetInfo.h"
46#include "clang/Basic/TargetOptions.h"
47#include "clang/Frontend/FrontendOptions.h"
48#include "clang/Frontend/LangStandard.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000049
50#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000051#undef NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000052#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
53// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
54#include <assert.h>
55#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056
Greg Clayton514487e2011-02-15 21:59:32 +000057#include "lldb/Core/ArchSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058#include "lldb/Core/dwarf.h"
Greg Clayton73b472d2010-10-27 03:32:59 +000059#include "lldb/Core/Flags.h"
Sean Callananfb8b7092010-10-28 18:19:36 +000060#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061
Eli Friedman932197d2010-06-13 19:06:42 +000062#include <stdio.h>
63
Greg Claytonc86103d2010-08-05 01:57:25 +000064using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065using namespace lldb_private;
66using namespace llvm;
67using namespace clang;
68
Greg Clayton6beaaa62011-01-17 03:46:26 +000069
70static bool
71GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
72{
73 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
74 switch (type_class)
75 {
76 case clang::Type::Record:
77 case clang::Type::Enum:
78 {
Sean Callanan78e37602011-01-27 04:42:51 +000079 const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +000080 if (tag_type)
81 {
82 clang::TagDecl *tag_decl = tag_type->getDecl();
83 if (tag_decl)
84 {
85 if (tag_decl->getDefinition())
86 return true;
87
88 if (tag_decl->hasExternalLexicalStorage())
89 {
90 ExternalASTSource *external_ast_source = ast->getExternalSource();
91 if (external_ast_source)
92 {
93 external_ast_source->CompleteType(tag_decl);
94 return !tag_type->isIncompleteType();
95 }
96 }
97 return false;
98 }
99 }
100
101 }
102 break;
103
104 case clang::Type::ObjCObject:
105 case clang::Type::ObjCInterface:
106 {
Sean Callanan78e37602011-01-27 04:42:51 +0000107 const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000108 if (objc_class_type)
109 {
110 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
111 // We currently can't complete objective C types through the newly added ASTContext
112 // because it only supports TagDecl objects right now...
113 bool is_forward_decl = class_interface_decl->isForwardDecl();
114 if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
115 {
116 ExternalASTSource *external_ast_source = ast->getExternalSource();
117 if (external_ast_source)
118 {
119 external_ast_source->CompleteType (class_interface_decl);
120 is_forward_decl = class_interface_decl->isForwardDecl();
121 }
Greg Claytonc432c192011-01-20 04:18:48 +0000122 return is_forward_decl == false;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000123 }
Greg Claytonc432c192011-01-20 04:18:48 +0000124 return true;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000125 }
126 }
127 break;
128
129 case clang::Type::Typedef:
130 return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType());
131
132 default:
133 break;
134 }
135
136 return true;
137}
138
139
Greg Clayton8cf05932010-07-22 18:30:50 +0000140static AccessSpecifier
Greg Claytonc86103d2010-08-05 01:57:25 +0000141ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000142{
143 switch (access)
144 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000145 default: break;
146 case eAccessNone: return AS_none;
147 case eAccessPublic: return AS_public;
148 case eAccessPrivate: return AS_private;
149 case eAccessProtected: return AS_protected;
Greg Clayton8cf05932010-07-22 18:30:50 +0000150 }
151 return AS_none;
152}
153
154static ObjCIvarDecl::AccessControl
Greg Claytonc86103d2010-08-05 01:57:25 +0000155ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000156{
157 switch (access)
158 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000159 default: break;
160 case eAccessNone: return ObjCIvarDecl::None;
161 case eAccessPublic: return ObjCIvarDecl::Public;
162 case eAccessPrivate: return ObjCIvarDecl::Private;
163 case eAccessProtected: return ObjCIvarDecl::Protected;
164 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton8cf05932010-07-22 18:30:50 +0000165 }
166 return ObjCIvarDecl::None;
167}
168
169
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170static void
171ParseLangArgs
172(
173 LangOptions &Opts,
Greg Clayton94e5d782010-06-13 17:34:29 +0000174 InputKind IK
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175)
176{
177 // FIXME: Cleanup per-file based stuff.
178
179 // Set some properties which depend soley on the input kind; it would be nice
180 // to move these to the language standard, and have the driver resolve the
181 // input kind + language standard.
Greg Clayton94e5d782010-06-13 17:34:29 +0000182 if (IK == IK_Asm) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183 Opts.AsmPreprocessor = 1;
Greg Clayton94e5d782010-06-13 17:34:29 +0000184 } else if (IK == IK_ObjC ||
185 IK == IK_ObjCXX ||
186 IK == IK_PreprocessedObjC ||
187 IK == IK_PreprocessedObjCXX) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188 Opts.ObjC1 = Opts.ObjC2 = 1;
189 }
190
191 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
192
193 if (LangStd == LangStandard::lang_unspecified) {
194 // Based on the base language, pick one.
195 switch (IK) {
Greg Clayton94e5d782010-06-13 17:34:29 +0000196 case IK_None:
197 case IK_AST:
Sean Callananfb0b7582011-03-15 00:17:19 +0000198 case IK_LLVM_IR:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000199 assert (!"Invalid input kind!");
Greg Clayton94e5d782010-06-13 17:34:29 +0000200 case IK_OpenCL:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201 LangStd = LangStandard::lang_opencl;
202 break;
Sean Callananfb0b7582011-03-15 00:17:19 +0000203 case IK_CUDA:
204 LangStd = LangStandard::lang_cuda;
205 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000206 case IK_Asm:
207 case IK_C:
208 case IK_PreprocessedC:
209 case IK_ObjC:
210 case IK_PreprocessedObjC:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211 LangStd = LangStandard::lang_gnu99;
212 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000213 case IK_CXX:
214 case IK_PreprocessedCXX:
215 case IK_ObjCXX:
216 case IK_PreprocessedObjCXX:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217 LangStd = LangStandard::lang_gnucxx98;
218 break;
219 }
220 }
221
222 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
223 Opts.BCPLComment = Std.hasBCPLComments();
224 Opts.C99 = Std.isC99();
225 Opts.CPlusPlus = Std.isCPlusPlus();
226 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
227 Opts.Digraphs = Std.hasDigraphs();
228 Opts.GNUMode = Std.isGNUMode();
229 Opts.GNUInline = !Std.isC99();
230 Opts.HexFloats = Std.hasHexFloats();
231 Opts.ImplicitInt = Std.hasImplicitInt();
232
233 // OpenCL has some additional defaults.
234 if (LangStd == LangStandard::lang_opencl) {
235 Opts.OpenCL = 1;
236 Opts.AltiVec = 1;
237 Opts.CXXOperatorNames = 1;
238 Opts.LaxVectorConversions = 1;
239 }
240
241 // OpenCL and C++ both have bool, true, false keywords.
242 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
243
244// if (Opts.CPlusPlus)
245// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
246//
247// if (Args.hasArg(OPT_fobjc_gc_only))
248// Opts.setGCMode(LangOptions::GCOnly);
249// else if (Args.hasArg(OPT_fobjc_gc))
250// Opts.setGCMode(LangOptions::HybridGC);
251//
252// if (Args.hasArg(OPT_print_ivar_layout))
253// Opts.ObjCGCBitmapPrint = 1;
254//
255// if (Args.hasArg(OPT_faltivec))
256// Opts.AltiVec = 1;
257//
258// if (Args.hasArg(OPT_pthread))
259// Opts.POSIXThreads = 1;
260//
261// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
262// "default");
263// if (Vis == "default")
Sean Callanan31e851c2010-10-29 18:38:40 +0000264 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265// else if (Vis == "hidden")
266// Opts.setVisibilityMode(LangOptions::Hidden);
267// else if (Vis == "protected")
268// Opts.setVisibilityMode(LangOptions::Protected);
269// else
270// Diags.Report(diag::err_drv_invalid_value)
271// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
272
273// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
274
275 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
276 // is specified, or -std is set to a conforming mode.
277 Opts.Trigraphs = !Opts.GNUMode;
278// if (Args.hasArg(OPT_trigraphs))
279// Opts.Trigraphs = 1;
280//
281// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
282// OPT_fno_dollars_in_identifiers,
283// !Opts.AsmPreprocessor);
284// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
285// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
286// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
287// if (Args.hasArg(OPT_fno_lax_vector_conversions))
288// Opts.LaxVectorConversions = 0;
289// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
290// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
291// Opts.Blocks = Args.hasArg(OPT_fblocks);
292// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
293// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
294// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
295// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
296// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
297// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
298// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
299// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
300// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
301// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
302// Diags);
303// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
304// Opts.ObjCConstantStringClass = getLastArgValue(Args,
305// OPT_fconstant_string_class);
306// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
307// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
308// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
309// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
310// Opts.Static = Args.hasArg(OPT_static_define);
311 Opts.OptimizeSize = 0;
312
313 // FIXME: Eliminate this dependency.
314// unsigned Opt =
315// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
316// Opts.Optimize = Opt != 0;
317 unsigned Opt = 0;
318
319 // This is the __NO_INLINE__ define, which just depends on things like the
320 // optimization level and -fno-inline, not actually whether the backend has
321 // inlining enabled.
322 //
323 // FIXME: This is affected by other options (-fno-inline).
324 Opts.NoInline = !Opt;
325
326// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
327// switch (SSP) {
328// default:
329// Diags.Report(diag::err_drv_invalid_value)
330// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
331// break;
332// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
333// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
334// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
335// }
336}
337
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000338
Greg Clayton6beaaa62011-01-17 03:46:26 +0000339ClangASTContext::ClangASTContext (const char *target_triple) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 m_target_triple(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000341 m_ast_ap(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 m_language_options_ap(),
343 m_source_manager_ap(),
344 m_diagnostic_ap(),
345 m_target_options_ap(),
346 m_target_info_ap(),
347 m_identifier_table_ap(),
348 m_selector_table_ap(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000349 m_builtins_ap(),
350 m_callback_tag_decl (NULL),
351 m_callback_objc_decl (NULL),
352 m_callback_baton (NULL)
353
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000354{
355 if (target_triple && target_triple[0])
356 m_target_triple.assign (target_triple);
357}
358
359//----------------------------------------------------------------------
360// Destructor
361//----------------------------------------------------------------------
362ClangASTContext::~ClangASTContext()
363{
364 m_builtins_ap.reset();
365 m_selector_table_ap.reset();
366 m_identifier_table_ap.reset();
367 m_target_info_ap.reset();
368 m_target_options_ap.reset();
369 m_diagnostic_ap.reset();
370 m_source_manager_ap.reset();
371 m_language_options_ap.reset();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000372 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373}
374
375
376void
377ClangASTContext::Clear()
378{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000379 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380 m_language_options_ap.reset();
381 m_source_manager_ap.reset();
382 m_diagnostic_ap.reset();
383 m_target_options_ap.reset();
384 m_target_info_ap.reset();
385 m_identifier_table_ap.reset();
386 m_selector_table_ap.reset();
387 m_builtins_ap.reset();
388}
389
390const char *
391ClangASTContext::GetTargetTriple ()
392{
393 return m_target_triple.c_str();
394}
395
396void
397ClangASTContext::SetTargetTriple (const char *target_triple)
398{
399 Clear();
400 m_target_triple.assign(target_triple);
401}
402
Greg Clayton514487e2011-02-15 21:59:32 +0000403void
404ClangASTContext::SetArchitecture (const ArchSpec &arch)
405{
406 Clear();
407 m_target_triple.assign(arch.GetTriple().str());
408}
409
Greg Clayton6beaaa62011-01-17 03:46:26 +0000410bool
411ClangASTContext::HasExternalSource ()
412{
413 ASTContext *ast = getASTContext();
414 if (ast)
415 return ast->getExternalSource () != NULL;
416 return false;
417}
418
419void
420ClangASTContext::SetExternalSource (llvm::OwningPtr<ExternalASTSource> &ast_source_ap)
421{
422 ASTContext *ast = getASTContext();
423 if (ast)
424 {
425 ast->setExternalSource (ast_source_ap);
426 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
427 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
428 }
429}
430
431void
432ClangASTContext::RemoveExternalSource ()
433{
434 ASTContext *ast = getASTContext();
435
436 if (ast)
437 {
438 llvm::OwningPtr<ExternalASTSource> empty_ast_source_ap;
439 ast->setExternalSource (empty_ast_source_ap);
440 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
441 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
442 }
443}
444
445
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446
447ASTContext *
448ClangASTContext::getASTContext()
449{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000450 if (m_ast_ap.get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000452 m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
453 *getSourceManager(),
454 *getTargetInfo(),
455 *getIdentifierTable(),
456 *getSelectorTable(),
457 *getBuiltinContext(),
458 0));
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000459
Greg Clayton6beaaa62011-01-17 03:46:26 +0000460 if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton)
461 {
462 m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
463 //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
464 }
465
466 m_ast_ap->getDiagnostics().setClient(getDiagnosticClient(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000468 return m_ast_ap.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469}
470
471Builtin::Context *
472ClangASTContext::getBuiltinContext()
473{
474 if (m_builtins_ap.get() == NULL)
475 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
476 return m_builtins_ap.get();
477}
478
479IdentifierTable *
480ClangASTContext::getIdentifierTable()
481{
482 if (m_identifier_table_ap.get() == NULL)
483 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
484 return m_identifier_table_ap.get();
485}
486
487LangOptions *
488ClangASTContext::getLanguageOptions()
489{
490 if (m_language_options_ap.get() == NULL)
491 {
492 m_language_options_ap.reset(new LangOptions());
Greg Clayton94e5d782010-06-13 17:34:29 +0000493 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
494// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000495 }
496 return m_language_options_ap.get();
497}
498
499SelectorTable *
500ClangASTContext::getSelectorTable()
501{
502 if (m_selector_table_ap.get() == NULL)
503 m_selector_table_ap.reset (new SelectorTable());
504 return m_selector_table_ap.get();
505}
506
Sean Callanan79439e82010-11-18 02:56:27 +0000507clang::FileManager *
508ClangASTContext::getFileManager()
509{
510 if (m_file_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000511 {
512 clang::FileSystemOptions file_system_options;
513 m_file_manager_ap.reset(new clang::FileManager(file_system_options));
514 }
Sean Callanan79439e82010-11-18 02:56:27 +0000515 return m_file_manager_ap.get();
516}
517
Greg Claytone1a916a2010-07-21 22:12:05 +0000518clang::SourceManager *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519ClangASTContext::getSourceManager()
520{
521 if (m_source_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000522 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523 return m_source_manager_ap.get();
524}
525
526Diagnostic *
527ClangASTContext::getDiagnostic()
528{
529 if (m_diagnostic_ap.get() == NULL)
Greg Claytona651b532010-11-19 21:46:54 +0000530 {
531 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
532 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
533 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534 return m_diagnostic_ap.get();
535}
536
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000537class NullDiagnosticClient : public DiagnosticClient
538{
539public:
540 NullDiagnosticClient ()
541 {
542 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
543 }
544
545 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
546 {
547 if (m_log)
548 {
549 llvm::SmallVectorImpl<char> diag_str(10);
550 info.FormatDiagnostic(diag_str);
551 diag_str.push_back('\0');
552 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
553 }
554 }
555private:
556 LogSP m_log;
557};
558
559DiagnosticClient *
560ClangASTContext::getDiagnosticClient()
561{
562 if (m_diagnostic_client_ap.get() == NULL)
563 m_diagnostic_client_ap.reset(new NullDiagnosticClient);
564
565 return m_diagnostic_client_ap.get();
566}
567
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000568TargetOptions *
569ClangASTContext::getTargetOptions()
570{
571 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
572 {
573 m_target_options_ap.reset (new TargetOptions());
574 if (m_target_options_ap.get())
575 m_target_options_ap->Triple = m_target_triple;
576 }
577 return m_target_options_ap.get();
578}
579
580
581TargetInfo *
582ClangASTContext::getTargetInfo()
583{
584 // target_triple should be something like "x86_64-apple-darwin10"
585 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
586 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
587 return m_target_info_ap.get();
588}
589
590#pragma mark Basic Types
591
592static inline bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000593QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000595 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 if (qual_type_bit_size == bit_size)
597 return true;
598 return false;
599}
600
Greg Clayton1be10fc2010-09-29 01:12:09 +0000601clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +0000602ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000603{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000604 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605
Greg Clayton6beaaa62011-01-17 03:46:26 +0000606 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607
Greg Clayton6beaaa62011-01-17 03:46:26 +0000608 return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000609}
610
Greg Clayton1be10fc2010-09-29 01:12:09 +0000611clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000612ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000613{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000614 if (!ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000615 return NULL;
616
617 switch (encoding)
618 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000619 case eEncodingInvalid:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000620 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
621 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622 break;
623
Greg Claytonc86103d2010-08-05 01:57:25 +0000624 case eEncodingUint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000625 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
626 return ast->UnsignedCharTy.getAsOpaquePtr();
627 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
628 return ast->UnsignedShortTy.getAsOpaquePtr();
629 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
630 return ast->UnsignedIntTy.getAsOpaquePtr();
631 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
632 return ast->UnsignedLongTy.getAsOpaquePtr();
633 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
634 return ast->UnsignedLongLongTy.getAsOpaquePtr();
635 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
636 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000637 break;
638
Greg Claytonc86103d2010-08-05 01:57:25 +0000639 case eEncodingSint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000640 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
641 return ast->CharTy.getAsOpaquePtr();
642 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
643 return ast->ShortTy.getAsOpaquePtr();
644 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
645 return ast->IntTy.getAsOpaquePtr();
646 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
647 return ast->LongTy.getAsOpaquePtr();
648 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
649 return ast->LongLongTy.getAsOpaquePtr();
650 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
651 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652 break;
653
Greg Claytonc86103d2010-08-05 01:57:25 +0000654 case eEncodingIEEE754:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000655 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
656 return ast->FloatTy.getAsOpaquePtr();
657 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
658 return ast->DoubleTy.getAsOpaquePtr();
659 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
660 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000661 break;
662
Greg Claytonc86103d2010-08-05 01:57:25 +0000663 case eEncodingVector:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000664 default:
665 break;
666 }
667
668 return NULL;
669}
670
Greg Clayton1be10fc2010-09-29 01:12:09 +0000671clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
673{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000674 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000675
676 #define streq(a,b) strcmp(a,b) == 0
Greg Clayton6beaaa62011-01-17 03:46:26 +0000677 assert (ast != NULL);
678 if (ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000679 {
680 switch (dw_ate)
681 {
682 default:
683 break;
684
685 case DW_ATE_address:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000686 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
687 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000688 break;
689
690 case DW_ATE_boolean:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000691 if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
692 return ast->BoolTy.getAsOpaquePtr();
693 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
694 return ast->UnsignedCharTy.getAsOpaquePtr();
695 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
696 return ast->UnsignedShortTy.getAsOpaquePtr();
697 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
698 return ast->UnsignedIntTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000699 break;
700
Greg Clayton49462ea2011-01-15 02:52:14 +0000701 case DW_ATE_lo_user:
702 // This has been seen to mean DW_AT_complex_integer
Greg Clayton5732f242011-01-27 09:15:11 +0000703 if (::strstr(type_name, "complex"))
Greg Clayton49462ea2011-01-15 02:52:14 +0000704 {
705 clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000706 return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000707 }
708 break;
709
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000710 case DW_ATE_complex_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000711 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
712 return ast->FloatComplexTy.getAsOpaquePtr();
713 else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
714 return ast->DoubleComplexTy.getAsOpaquePtr();
715 else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
716 return ast->LongDoubleComplexTy.getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000717 else
718 {
719 clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000720 return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000721 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000722 break;
723
724 case DW_ATE_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000725 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
726 return ast->FloatTy.getAsOpaquePtr();
727 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
728 return ast->DoubleTy.getAsOpaquePtr();
729 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
730 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731 break;
732
733 case DW_ATE_signed:
734 if (type_name)
735 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000736 if (strstr(type_name, "long long"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000738 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
739 return ast->LongLongTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000740 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000741 else if (strstr(type_name, "long"))
742 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000743 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
744 return ast->LongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000745 }
746 else if (strstr(type_name, "short"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000747 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000748 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
749 return ast->ShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000750 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000751 else if (strstr(type_name, "char"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000752 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000753 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
754 return ast->CharTy.getAsOpaquePtr();
755 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
756 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000758 else if (strstr(type_name, "int"))
759 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000760 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
761 return ast->IntTy.getAsOpaquePtr();
762 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
763 return ast->Int128Ty.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000764 }
765 else if (streq(type_name, "wchar_t"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000766 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000767 if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
768 return ast->WCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000769 }
Greg Clayton7bd65b92011-02-09 23:39:34 +0000770 else if (streq(type_name, "void"))
771 {
772 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
773 return ast->VoidTy.getAsOpaquePtr();
774 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000775 }
776 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000777 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
778 return ast->CharTy.getAsOpaquePtr();
779 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
780 return ast->ShortTy.getAsOpaquePtr();
781 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
782 return ast->IntTy.getAsOpaquePtr();
783 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
784 return ast->LongTy.getAsOpaquePtr();
785 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
786 return ast->LongLongTy.getAsOpaquePtr();
787 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
788 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000789 break;
790
791 case DW_ATE_signed_char:
792 if (type_name)
793 {
794 if (streq(type_name, "signed char"))
795 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000796 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
797 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000798 }
799 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000800 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
801 return ast->CharTy.getAsOpaquePtr();
802 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
803 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000804 break;
805
806 case DW_ATE_unsigned:
807 if (type_name)
808 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000809 if (strstr(type_name, "long long"))
810 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000811 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
812 return ast->UnsignedLongLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000813 }
814 else if (strstr(type_name, "long"))
815 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000816 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
817 return ast->UnsignedLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000818 }
819 else if (strstr(type_name, "short"))
820 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000821 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
822 return ast->UnsignedShortTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000823 }
824 else if (strstr(type_name, "char"))
825 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000826 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
827 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000828 }
829 else if (strstr(type_name, "int"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000830 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000831 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
832 return ast->UnsignedIntTy.getAsOpaquePtr();
833 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
834 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000835 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000836 }
837 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000838 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
839 return ast->UnsignedCharTy.getAsOpaquePtr();
840 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
841 return ast->UnsignedShortTy.getAsOpaquePtr();
842 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
843 return ast->UnsignedIntTy.getAsOpaquePtr();
844 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
845 return ast->UnsignedLongTy.getAsOpaquePtr();
846 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
847 return ast->UnsignedLongLongTy.getAsOpaquePtr();
848 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
849 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000850 break;
851
852 case DW_ATE_unsigned_char:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000853 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
854 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton7bd65b92011-02-09 23:39:34 +0000855 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
856 return ast->UnsignedShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857 break;
858
859 case DW_ATE_imaginary_float:
860 break;
861 }
862 }
863 // This assert should fire for anything that we don't catch above so we know
864 // to fix any issues we run into.
865 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
866 return NULL;
867}
868
Greg Clayton1be10fc2010-09-29 01:12:09 +0000869clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000870ClangASTContext::GetBuiltInType_void(ASTContext *ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000871{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000872 return ast->VoidTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000873}
874
Greg Clayton1be10fc2010-09-29 01:12:09 +0000875clang_type_t
Sean Callananf7c3e272010-11-19 02:52:21 +0000876ClangASTContext::GetBuiltInType_bool()
877{
878 return getASTContext()->BoolTy.getAsOpaquePtr();
879}
880
881clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000882ClangASTContext::GetBuiltInType_objc_id()
883{
Sean Callananf6c73082010-12-06 23:53:20 +0000884 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000885}
886
Greg Clayton1be10fc2010-09-29 01:12:09 +0000887clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000888ClangASTContext::GetBuiltInType_objc_Class()
889{
Sean Callanana2424172010-10-25 00:29:48 +0000890 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000891}
892
Greg Clayton1be10fc2010-09-29 01:12:09 +0000893clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000894ClangASTContext::GetBuiltInType_objc_selector()
895{
Sean Callananf6c73082010-12-06 23:53:20 +0000896 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000897}
898
Greg Clayton1be10fc2010-09-29 01:12:09 +0000899clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000900ClangASTContext::GetCStringType (bool is_const)
901{
902 QualType char_type(getASTContext()->CharTy);
903
904 if (is_const)
905 char_type.addConst();
906
907 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
908}
909
Greg Clayton1be10fc2010-09-29 01:12:09 +0000910clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911ClangASTContext::GetVoidPtrType (bool is_const)
912{
913 return GetVoidPtrType(getASTContext(), is_const);
914}
915
Greg Clayton1be10fc2010-09-29 01:12:09 +0000916clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000917ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000918{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000919 QualType void_ptr_type(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000920
921 if (is_const)
922 void_ptr_type.addConst();
923
924 return void_ptr_type.getAsOpaquePtr();
925}
926
Greg Clayton1be10fc2010-09-29 01:12:09 +0000927clang_type_t
Greg Clayton38a61402010-12-02 23:20:03 +0000928ClangASTContext::CopyType (ASTContext *dst_ast,
929 ASTContext *src_ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000930 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931{
Sean Callanan79439e82010-11-18 02:56:27 +0000932 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000933 FileManager file_manager (file_system_options);
934 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000935 *src_ast, file_manager,
936 false);
Sean Callanan0617fcb2010-11-09 22:37:10 +0000937
Greg Clayton38a61402010-12-02 23:20:03 +0000938 QualType src (QualType::getFromOpaquePtr(clang_type));
939 QualType dst (importer.Import(src));
Sean Callanan0617fcb2010-11-09 22:37:10 +0000940
941 return dst.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000942}
943
Greg Clayton526e5af2010-11-13 03:52:47 +0000944
945clang::Decl *
Greg Clayton38a61402010-12-02 23:20:03 +0000946ClangASTContext::CopyDecl (ASTContext *dst_ast,
947 ASTContext *src_ast,
Greg Clayton526e5af2010-11-13 03:52:47 +0000948 clang::Decl *source_decl)
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000949{
Sean Callanan79439e82010-11-18 02:56:27 +0000950 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000951 FileManager file_manager (file_system_options);
952 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000953 *src_ast, file_manager,
954 false);
Greg Clayton526e5af2010-11-13 03:52:47 +0000955
956 return importer.Import(source_decl);
957}
958
Sean Callanan23a30272010-07-16 00:00:27 +0000959bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000960ClangASTContext::AreTypesSame(ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000961 clang_type_t type1,
962 clang_type_t type2)
Sean Callanan4dcca2622010-07-15 22:30:52 +0000963{
Greg Claytonf4ecaa52011-02-16 23:00:21 +0000964 return ast->hasSameType (QualType::getFromOpaquePtr(type1),
965 QualType::getFromOpaquePtr(type2));
Sean Callanan4dcca2622010-07-15 22:30:52 +0000966}
967
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000968#pragma mark CVR modifiers
969
Greg Clayton1be10fc2010-09-29 01:12:09 +0000970clang_type_t
971ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000972{
973 if (clang_type)
974 {
975 QualType result(QualType::getFromOpaquePtr(clang_type));
976 result.addConst();
977 return result.getAsOpaquePtr();
978 }
979 return NULL;
980}
981
Greg Clayton1be10fc2010-09-29 01:12:09 +0000982clang_type_t
983ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000984{
985 if (clang_type)
986 {
987 QualType result(QualType::getFromOpaquePtr(clang_type));
988 result.getQualifiers().setRestrict (true);
989 return result.getAsOpaquePtr();
990 }
991 return NULL;
992}
993
Greg Clayton1be10fc2010-09-29 01:12:09 +0000994clang_type_t
995ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000996{
997 if (clang_type)
998 {
999 QualType result(QualType::getFromOpaquePtr(clang_type));
1000 result.getQualifiers().setVolatile (true);
1001 return result.getAsOpaquePtr();
1002 }
1003 return NULL;
1004}
1005
Greg Clayton6beaaa62011-01-17 03:46:26 +00001006
1007clang_type_t
1008ClangASTContext::GetTypeForDecl (TagDecl *decl)
1009{
1010 // No need to call the getASTContext() accessor (which can create the AST
1011 // if it isn't created yet, because we can't have created a decl in this
1012 // AST if our AST didn't already exist...
1013 if (m_ast_ap.get())
1014 return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
1015 return NULL;
1016}
1017
1018clang_type_t
1019ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
1020{
1021 // No need to call the getASTContext() accessor (which can create the AST
1022 // if it isn't created yet, because we can't have created a decl in this
1023 // AST if our AST didn't already exist...
1024 if (m_ast_ap.get())
1025 return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
1026 return NULL;
1027}
1028
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029#pragma mark Structure, Unions, Classes
1030
Greg Clayton1be10fc2010-09-29 01:12:09 +00001031clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +00001032ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001033{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001034 ASTContext *ast = getASTContext();
1035 assert (ast != NULL);
Sean Callanana2424172010-10-25 00:29:48 +00001036
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001037 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001038 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001039
Greg Clayton9e409562010-07-28 02:04:09 +00001040
Greg Claytonc86103d2010-08-05 01:57:25 +00001041 if (language == eLanguageTypeObjC)
Greg Clayton9e409562010-07-28 02:04:09 +00001042 {
Greg Claytonaaf99e02010-10-11 02:25:34 +00001043 bool isForwardDecl = true;
Greg Clayton9e409562010-07-28 02:04:09 +00001044 bool isInternal = false;
1045 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
1046 }
1047
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001048 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1049 // we will need to update this code. I was told to currently always use
1050 // the CXXRecordDecl class since we often don't know from debug information
1051 // if something is struct or a class, so we default to always use the more
1052 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001053 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054 (TagDecl::TagKind)kind,
1055 decl_ctx,
1056 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001057 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001058 name && name[0] ? &ast->Idents.get(name) : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001059
Greg Clayton6beaaa62011-01-17 03:46:26 +00001060 return ast->getTagDeclType(decl).getAsOpaquePtr();
1061}
1062
1063bool
1064ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
1065{
1066 if (clang_type == NULL)
1067 return false;
1068
1069 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1070
1071 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1072 switch (type_class)
1073 {
1074 case clang::Type::Record:
1075 {
1076 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
1077 if (cxx_record_decl)
1078 {
1079 cxx_record_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001080 cxx_record_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001081 return true;
1082 }
1083 }
1084 break;
1085
1086 case clang::Type::Enum:
1087 {
1088 EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
1089 if (enum_decl)
1090 {
1091 enum_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001092 enum_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001093 return true;
1094 }
1095 }
1096 break;
1097
1098 case clang::Type::ObjCObject:
1099 case clang::Type::ObjCInterface:
1100 {
Sean Callanan78e37602011-01-27 04:42:51 +00001101 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001102 assert (objc_class_type);
1103 if (objc_class_type)
1104 {
1105 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1106
1107 if (class_interface_decl)
1108 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001109 class_interface_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001110 class_interface_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001111 return true;
1112 }
1113 }
1114 }
1115 break;
1116
1117 case clang::Type::Typedef:
1118 return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
1119
1120 default:
1121 break;
1122 }
1123 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001124}
1125
Greg Claytona3c444a2010-10-01 23:13:49 +00001126static bool
1127IsOperator (const char *name, OverloadedOperatorKind &op_kind)
1128{
1129 if (name == NULL || name[0] == '\0')
1130 return false;
1131
Sean Callanana43f20d2010-12-10 19:51:54 +00001132#define OPERATOR_PREFIX "operator"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001133#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
Sean Callananbfeff8c2010-12-10 02:15:55 +00001134
1135 const char *post_op_name = NULL;
1136
Sean Callanana43f20d2010-12-10 19:51:54 +00001137 bool no_space = true;
Sean Callananbfeff8c2010-12-10 02:15:55 +00001138
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001139 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
Greg Claytona3c444a2010-10-01 23:13:49 +00001140 return false;
1141
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001142 post_op_name = name + OPERATOR_PREFIX_LENGTH;
1143
Sean Callanana43f20d2010-12-10 19:51:54 +00001144 if (post_op_name[0] == ' ')
1145 {
1146 post_op_name++;
1147 no_space = false;
1148 }
1149
1150#undef OPERATOR_PREFIX
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001151#undef OPERATOR_PREFIX_LENGTH
Sean Callanana43f20d2010-12-10 19:51:54 +00001152
Greg Claytona3c444a2010-10-01 23:13:49 +00001153 // This is an operator, set the overloaded operator kind to invalid
1154 // in case this is a conversion operator...
1155 op_kind = NUM_OVERLOADED_OPERATORS;
1156
1157 switch (post_op_name[0])
1158 {
Sean Callananbfeff8c2010-12-10 02:15:55 +00001159 default:
1160 if (no_space)
1161 return false;
1162 break;
Greg Claytona3c444a2010-10-01 23:13:49 +00001163 case 'n':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001164 if (no_space)
1165 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001166 if (strcmp (post_op_name, "new") == 0)
1167 op_kind = OO_New;
1168 else if (strcmp (post_op_name, "new[]") == 0)
1169 op_kind = OO_Array_New;
1170 break;
1171
1172 case 'd':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001173 if (no_space)
1174 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001175 if (strcmp (post_op_name, "delete") == 0)
1176 op_kind = OO_Delete;
1177 else if (strcmp (post_op_name, "delete[]") == 0)
1178 op_kind = OO_Array_Delete;
1179 break;
1180
1181 case '+':
1182 if (post_op_name[1] == '\0')
1183 op_kind = OO_Plus;
1184 else if (post_op_name[2] == '\0')
1185 {
1186 if (post_op_name[1] == '=')
1187 op_kind = OO_PlusEqual;
1188 else if (post_op_name[1] == '+')
1189 op_kind = OO_PlusPlus;
1190 }
1191 break;
1192
1193 case '-':
1194 if (post_op_name[1] == '\0')
1195 op_kind = OO_Minus;
1196 else if (post_op_name[2] == '\0')
1197 {
1198 switch (post_op_name[1])
1199 {
1200 case '=': op_kind = OO_MinusEqual; break;
1201 case '-': op_kind = OO_MinusMinus; break;
1202 case '>': op_kind = OO_Arrow; break;
1203 }
1204 }
1205 else if (post_op_name[3] == '\0')
1206 {
1207 if (post_op_name[2] == '*')
1208 op_kind = OO_ArrowStar; break;
1209 }
1210 break;
1211
1212 case '*':
1213 if (post_op_name[1] == '\0')
1214 op_kind = OO_Star;
1215 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1216 op_kind = OO_StarEqual;
1217 break;
1218
1219 case '/':
1220 if (post_op_name[1] == '\0')
1221 op_kind = OO_Slash;
1222 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1223 op_kind = OO_SlashEqual;
1224 break;
1225
1226 case '%':
1227 if (post_op_name[1] == '\0')
1228 op_kind = OO_Percent;
1229 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1230 op_kind = OO_PercentEqual;
1231 break;
1232
1233
1234 case '^':
1235 if (post_op_name[1] == '\0')
1236 op_kind = OO_Caret;
1237 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1238 op_kind = OO_CaretEqual;
1239 break;
1240
1241 case '&':
1242 if (post_op_name[1] == '\0')
1243 op_kind = OO_Amp;
1244 else if (post_op_name[2] == '\0')
1245 {
1246 switch (post_op_name[1])
1247 {
1248 case '=': op_kind = OO_AmpEqual; break;
1249 case '&': op_kind = OO_AmpAmp; break;
1250 }
1251 }
1252 break;
1253
1254 case '|':
1255 if (post_op_name[1] == '\0')
1256 op_kind = OO_Pipe;
1257 else if (post_op_name[2] == '\0')
1258 {
1259 switch (post_op_name[1])
1260 {
1261 case '=': op_kind = OO_PipeEqual; break;
1262 case '|': op_kind = OO_PipePipe; break;
1263 }
1264 }
1265 break;
1266
1267 case '~':
1268 if (post_op_name[1] == '\0')
1269 op_kind = OO_Tilde;
1270 break;
1271
1272 case '!':
1273 if (post_op_name[1] == '\0')
1274 op_kind = OO_Exclaim;
1275 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1276 op_kind = OO_ExclaimEqual;
1277 break;
1278
1279 case '=':
1280 if (post_op_name[1] == '\0')
1281 op_kind = OO_Equal;
1282 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1283 op_kind = OO_EqualEqual;
1284 break;
1285
1286 case '<':
1287 if (post_op_name[1] == '\0')
1288 op_kind = OO_Less;
1289 else if (post_op_name[2] == '\0')
1290 {
1291 switch (post_op_name[1])
1292 {
1293 case '<': op_kind = OO_LessLess; break;
1294 case '=': op_kind = OO_LessEqual; break;
1295 }
1296 }
1297 else if (post_op_name[3] == '\0')
1298 {
1299 if (post_op_name[2] == '=')
1300 op_kind = OO_LessLessEqual;
1301 }
1302 break;
1303
1304 case '>':
1305 if (post_op_name[1] == '\0')
1306 op_kind = OO_Greater;
1307 else if (post_op_name[2] == '\0')
1308 {
1309 switch (post_op_name[1])
1310 {
1311 case '>': op_kind = OO_GreaterGreater; break;
1312 case '=': op_kind = OO_GreaterEqual; break;
1313 }
1314 }
1315 else if (post_op_name[1] == '>' &&
1316 post_op_name[2] == '=' &&
1317 post_op_name[3] == '\0')
1318 {
1319 op_kind = OO_GreaterGreaterEqual;
1320 }
1321 break;
1322
1323 case ',':
1324 if (post_op_name[1] == '\0')
1325 op_kind = OO_Comma;
1326 break;
1327
1328 case '(':
1329 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1330 op_kind = OO_Call;
1331 break;
1332
1333 case '[':
1334 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1335 op_kind = OO_Subscript;
1336 break;
1337 }
1338
1339 return true;
1340}
Greg Clayton6beaaa62011-01-17 03:46:26 +00001341
Greg Claytona51ed9b2010-09-23 01:09:21 +00001342CXXMethodDecl *
Sean Callanan61da09b2010-09-17 02:58:26 +00001343ClangASTContext::AddMethodToCXXRecordType
1344(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001345 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001346 clang_type_t record_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001347 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001348 clang_type_t method_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001349 lldb::AccessType access,
Greg Clayton0fffff52010-09-24 05:15:53 +00001350 bool is_virtual,
1351 bool is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00001352 bool is_inline,
1353 bool is_explicit
Greg Claytona51ed9b2010-09-23 01:09:21 +00001354)
Sean Callanan61da09b2010-09-17 02:58:26 +00001355{
Sean Callananfc55f5d2010-09-21 00:44:12 +00001356 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chend440bcc2010-09-28 16:10:54 +00001357 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001358
Greg Clayton6beaaa62011-01-17 03:46:26 +00001359 assert(ast);
Sean Callanan61da09b2010-09-17 02:58:26 +00001360
Greg Clayton6beaaa62011-01-17 03:46:26 +00001361 IdentifierTable *identifier_table = &ast->Idents;
Sean Callanan61da09b2010-09-17 02:58:26 +00001362
1363 assert(identifier_table);
1364
Sean Callananfc55f5d2010-09-21 00:44:12 +00001365 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001366
Greg Clayton6beaaa62011-01-17 03:46:26 +00001367 CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
Sean Callanan61da09b2010-09-17 02:58:26 +00001368
Greg Clayton0fffff52010-09-24 05:15:53 +00001369 if (cxx_record_decl == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001370 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001371
Greg Clayton0fffff52010-09-24 05:15:53 +00001372 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001373
Greg Claytonf51de672010-10-01 02:31:07 +00001374 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001375
Greg Claytonf51de672010-10-01 02:31:07 +00001376 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton878eaf12010-10-01 03:45:20 +00001377
Greg Clayton878eaf12010-10-01 03:45:20 +00001378 const bool is_implicitly_declared = false;
Greg Claytonf51de672010-10-01 02:31:07 +00001379
Sean Callanan78e37602011-01-27 04:42:51 +00001380 const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton878eaf12010-10-01 03:45:20 +00001381
Greg Clayton90a2acd2010-10-02 01:40:05 +00001382 if (function_Type == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001383 return NULL;
1384
Sean Callanan78e37602011-01-27 04:42:51 +00001385 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton878eaf12010-10-01 03:45:20 +00001386
1387 if (!method_function_prototype)
1388 return NULL;
1389
1390 unsigned int num_params = method_function_prototype->getNumArgs();
1391
1392 if (name[0] == '~')
Greg Claytonf51de672010-10-01 02:31:07 +00001393 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001394 cxx_method_decl = CXXDestructorDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001395 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001396 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001397 DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001398 method_qual_type,
Sean Callanan31e851c2010-10-29 18:38:40 +00001399 NULL,
Greg Clayton878eaf12010-10-01 03:45:20 +00001400 is_inline,
1401 is_implicitly_declared);
1402 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001403 else if (decl_name == cxx_record_decl->getDeclName())
Greg Clayton878eaf12010-10-01 03:45:20 +00001404 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001405 cxx_method_decl = CXXConstructorDecl::Create (*ast,
Greg Claytonf51de672010-10-01 02:31:07 +00001406 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001407 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001408 DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Claytonf51de672010-10-01 02:31:07 +00001409 method_qual_type,
1410 NULL, // TypeSourceInfo *
1411 is_explicit,
1412 is_inline,
1413 is_implicitly_declared);
1414 }
1415 else
Greg Clayton878eaf12010-10-01 03:45:20 +00001416 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001417
1418 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1419 if (IsOperator (name, op_kind))
Greg Clayton878eaf12010-10-01 03:45:20 +00001420 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001421 if (op_kind != NUM_OVERLOADED_OPERATORS)
1422 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001423 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001424 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001425 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001426 DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001427 method_qual_type,
1428 NULL, // TypeSourceInfo *
Greg Claytona3c444a2010-10-01 23:13:49 +00001429 is_static,
1430 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001431 is_inline,
1432 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001433 }
1434 else if (num_params == 0)
1435 {
1436 // Conversion operators don't take params...
Greg Clayton6beaaa62011-01-17 03:46:26 +00001437 cxx_method_decl = CXXConversionDecl::Create (*ast,
Greg Claytona3c444a2010-10-01 23:13:49 +00001438 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001439 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001440 DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytona3c444a2010-10-01 23:13:49 +00001441 method_qual_type,
1442 NULL, // TypeSourceInfo *
1443 is_inline,
Sean Callananfb0b7582011-03-15 00:17:19 +00001444 is_explicit,
1445 SourceLocation());
Greg Claytona3c444a2010-10-01 23:13:49 +00001446 }
Greg Clayton878eaf12010-10-01 03:45:20 +00001447 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001448
1449 if (cxx_method_decl == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001450 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001451 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001452 cxx_record_decl,
Sean Callananfb0b7582011-03-15 00:17:19 +00001453 SourceLocation(),
Greg Claytona3c444a2010-10-01 23:13:49 +00001454 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001455 method_qual_type,
1456 NULL, // TypeSourceInfo *
1457 is_static,
1458 SC_None,
Sean Callananfb0b7582011-03-15 00:17:19 +00001459 is_inline,
1460 SourceLocation());
Greg Clayton878eaf12010-10-01 03:45:20 +00001461 }
Greg Claytonf51de672010-10-01 02:31:07 +00001462 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001463
Greg Clayton1be10fc2010-09-29 01:12:09 +00001464 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton0fffff52010-09-24 05:15:53 +00001465
1466 cxx_method_decl->setAccess (access_specifier);
1467 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001468
Sean Callananfc55f5d2010-09-21 00:44:12 +00001469 // Populate the method decl with parameter decls
Sean Callananfc55f5d2010-09-21 00:44:12 +00001470
1471 ParmVarDecl *params[num_params];
1472
1473 for (int param_index = 0;
1474 param_index < num_params;
1475 ++param_index)
1476 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001477 params[param_index] = ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001478 cxx_method_decl,
1479 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001480 SourceLocation(),
Greg Clayton0fffff52010-09-24 05:15:53 +00001481 NULL, // anonymous
1482 method_function_prototype->getArgType(param_index),
1483 NULL,
1484 SC_None,
1485 SC_None,
1486 NULL);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001487 }
1488
Greg Clayton0fffff52010-09-24 05:15:53 +00001489 cxx_method_decl->setParams (params, num_params);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001490
Greg Clayton0fffff52010-09-24 05:15:53 +00001491 cxx_record_decl->addDecl (cxx_method_decl);
Greg Claytonc432c192011-01-20 04:18:48 +00001492
1493// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic());
1494// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate());
1495// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD());
1496// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty());
1497// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract());
1498// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor());
1499// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
1500// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
1501// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor());
Greg Claytona51ed9b2010-09-23 01:09:21 +00001502 return cxx_method_decl;
Sean Callanan61da09b2010-09-17 02:58:26 +00001503}
1504
1505bool
Greg Clayton8cf05932010-07-22 18:30:50 +00001506ClangASTContext::AddFieldToRecordType
1507(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001508 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001509 clang_type_t record_clang_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001510 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001511 clang_type_t field_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001512 AccessType access,
1513 uint32_t bitfield_bit_size
1514)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001515{
1516 if (record_clang_type == NULL || field_type == NULL)
1517 return false;
1518
Greg Clayton6beaaa62011-01-17 03:46:26 +00001519 IdentifierTable *identifier_table = &ast->Idents;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001520
Greg Clayton6beaaa62011-01-17 03:46:26 +00001521 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001522 assert (identifier_table != NULL);
1523
1524 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1525
Sean Callanan78e37602011-01-27 04:42:51 +00001526 const clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001527 if (clang_type)
1528 {
1529 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1530
1531 if (record_type)
1532 {
1533 RecordDecl *record_decl = record_type->getDecl();
1534
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001535 clang::Expr *bit_width = NULL;
1536 if (bitfield_bit_size != 0)
1537 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001538 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1539 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001540 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001541 FieldDecl *field = FieldDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001542 record_decl,
1543 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001544 SourceLocation(),
Greg Clayton8cf05932010-07-22 18:30:50 +00001545 name ? &identifier_table->get(name) : NULL, // Identifier
1546 QualType::getFromOpaquePtr(field_type), // Field type
1547 NULL, // DeclaratorInfo *
1548 bit_width, // BitWidth
1549 false); // Mutable
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001550
Greg Clayton8cf05932010-07-22 18:30:50 +00001551 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001552
1553 if (field)
1554 {
1555 record_decl->addDecl(field);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001556 }
1557 }
Greg Clayton9e409562010-07-28 02:04:09 +00001558 else
1559 {
Sean Callanan78e37602011-01-27 04:42:51 +00001560 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001561 if (objc_class_type)
1562 {
Greg Clayton0fffff52010-09-24 05:15:53 +00001563 bool is_synthesized = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001564 ClangASTContext::AddObjCClassIVar (ast,
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001565 record_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001566 name,
1567 field_type,
1568 access,
1569 bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001570 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001571 }
1572 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001573 }
1574 return false;
1575}
1576
1577bool
1578ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1579{
1580 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1581}
1582
1583bool
1584ClangASTContext::FieldIsBitfield
1585(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001586 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001587 FieldDecl* field,
1588 uint32_t& bitfield_bit_size
1589)
1590{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001591 if (ast == NULL || field == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001592 return false;
1593
1594 if (field->isBitField())
1595 {
1596 Expr* bit_width_expr = field->getBitWidth();
1597 if (bit_width_expr)
1598 {
1599 llvm::APSInt bit_width_apsint;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001600 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001601 {
1602 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1603 return true;
1604 }
1605 }
1606 }
1607 return false;
1608}
1609
1610bool
1611ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1612{
1613 if (record_decl == NULL)
1614 return false;
1615
1616 if (!record_decl->field_empty())
1617 return true;
1618
1619 // No fields, lets check this is a CXX record and check the base classes
1620 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1621 if (cxx_record_decl)
1622 {
1623 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1624 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1625 base_class != base_class_end;
1626 ++base_class)
1627 {
1628 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1629 if (RecordHasFields(base_class_decl))
1630 return true;
1631 }
1632 }
1633 return false;
1634}
1635
1636void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001637ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001638{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001639 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001640 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001641 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1642
Sean Callanan78e37602011-01-27 04:42:51 +00001643 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001644 if (record_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001645 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001646 RecordDecl *record_decl = record_type->getDecl();
1647 if (record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001648 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001649 uint32_t field_idx;
1650 RecordDecl::field_iterator field, field_end;
1651 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1652 field != field_end;
1653 ++field, ++field_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001654 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001655 // If no accessibility was assigned, assign the correct one
1656 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1657 field->setAccess ((AccessSpecifier)default_accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001658 }
1659 }
1660 }
1661 }
1662}
1663
1664#pragma mark C++ Base Classes
1665
1666CXXBaseSpecifier *
Greg Clayton1be10fc2010-09-29 01:12:09 +00001667ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001668{
1669 if (base_class_type)
Greg Claytone6371122010-07-30 20:30:44 +00001670 return new CXXBaseSpecifier (SourceRange(),
1671 is_virtual,
1672 base_of_class,
1673 ConvertAccessTypeToAccessSpecifier (access),
Sean Callanan2c777c42011-01-18 23:32:05 +00001674 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
1675 SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001676 return NULL;
1677}
1678
Greg Clayton0b42ac32010-07-02 01:29:13 +00001679void
1680ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1681{
1682 for (unsigned i=0; i<num_base_classes; ++i)
1683 {
1684 delete base_classes[i];
1685 base_classes[i] = NULL;
1686 }
1687}
1688
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001689bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001690ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001691{
1692 if (class_clang_type)
1693 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001694 CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
1695 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001696 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001697 cxx_record_decl->setBases(base_classes, num_base_classes);
1698 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001699 }
1700 }
1701 return false;
1702}
Greg Clayton8cf05932010-07-22 18:30:50 +00001703#pragma mark Objective C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001704
Greg Clayton1be10fc2010-09-29 01:12:09 +00001705clang_type_t
Greg Clayton8cf05932010-07-22 18:30:50 +00001706ClangASTContext::CreateObjCClass
1707(
1708 const char *name,
1709 DeclContext *decl_ctx,
1710 bool isForwardDecl,
1711 bool isInternal
1712)
1713{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001714 ASTContext *ast = getASTContext();
1715 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001716 assert (name && name[0]);
1717 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001718 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001719
1720 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1721 // we will need to update this code. I was told to currently always use
1722 // the CXXRecordDecl class since we often don't know from debug information
1723 // if something is struct or a class, so we default to always use the more
1724 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001725 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001726 decl_ctx,
1727 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001728 &ast->Idents.get(name),
Greg Clayton8cf05932010-07-22 18:30:50 +00001729 SourceLocation(),
1730 isForwardDecl,
1731 isInternal);
Greg Clayton9e409562010-07-28 02:04:09 +00001732
Greg Clayton6beaaa62011-01-17 03:46:26 +00001733 return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001734}
1735
1736bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001737ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton8cf05932010-07-22 18:30:50 +00001738{
1739 if (class_opaque_type && super_opaque_type)
1740 {
1741 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1742 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
Sean Callanan78e37602011-01-27 04:42:51 +00001743 const clang::Type *class_type = class_qual_type.getTypePtr();
1744 const clang::Type *super_type = super_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001745 if (class_type && super_type)
1746 {
Sean Callanan78e37602011-01-27 04:42:51 +00001747 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1748 const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001749 if (objc_class_type && objc_super_type)
1750 {
1751 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1752 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1753 if (class_interface_decl && super_interface_decl)
1754 {
1755 class_interface_decl->setSuperClass(super_interface_decl);
1756 return true;
1757 }
1758 }
1759 }
1760 }
1761 return false;
1762}
1763
1764
1765bool
1766ClangASTContext::AddObjCClassIVar
1767(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001768 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001769 clang_type_t class_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001770 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001771 clang_type_t ivar_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001772 AccessType access,
1773 uint32_t bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001774 bool is_synthesized
Greg Clayton8cf05932010-07-22 18:30:50 +00001775)
1776{
1777 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1778 return false;
1779
Greg Clayton6beaaa62011-01-17 03:46:26 +00001780 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton8cf05932010-07-22 18:30:50 +00001781
Greg Clayton6beaaa62011-01-17 03:46:26 +00001782 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001783 assert (identifier_table != NULL);
1784
1785 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1786
Sean Callanan78e37602011-01-27 04:42:51 +00001787 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001788 if (class_type)
1789 {
Sean Callanan78e37602011-01-27 04:42:51 +00001790 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001791
1792 if (objc_class_type)
1793 {
1794 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1795
1796 if (class_interface_decl)
1797 {
1798 clang::Expr *bit_width = NULL;
1799 if (bitfield_bit_size != 0)
1800 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001801 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1802 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Greg Clayton8cf05932010-07-22 18:30:50 +00001803 }
1804
Greg Clayton6beaaa62011-01-17 03:46:26 +00001805 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast,
Greg Clayton9e409562010-07-28 02:04:09 +00001806 class_interface_decl,
1807 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001808 SourceLocation(),
Greg Clayton9e409562010-07-28 02:04:09 +00001809 &identifier_table->get(name), // Identifier
1810 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1811 NULL, // TypeSourceInfo *
1812 ConvertAccessTypeToObjCIvarAccessControl (access),
1813 bit_width,
Greg Clayton0fffff52010-09-24 05:15:53 +00001814 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001815
1816 if (field)
1817 {
1818 class_interface_decl->addDecl(field);
1819 return true;
1820 }
Greg Clayton8cf05932010-07-22 18:30:50 +00001821 }
1822 }
1823 }
1824 return false;
1825}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001826
Greg Clayton9e409562010-07-28 02:04:09 +00001827
1828bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001829ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9e409562010-07-28 02:04:09 +00001830{
1831 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1832
Sean Callanan78e37602011-01-27 04:42:51 +00001833 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton9e409562010-07-28 02:04:09 +00001834 if (class_type)
1835 {
Sean Callanan78e37602011-01-27 04:42:51 +00001836 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001837
1838 if (objc_class_type)
1839 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1840 }
1841 return false;
1842}
1843
1844bool
1845ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1846{
1847 while (class_interface_decl)
1848 {
1849 if (class_interface_decl->ivar_size() > 0)
1850 return true;
1851
1852 if (check_superclass)
1853 class_interface_decl = class_interface_decl->getSuperClass();
1854 else
1855 break;
1856 }
1857 return false;
1858}
Greg Clayton0fffff52010-09-24 05:15:53 +00001859
Greg Clayton1be10fc2010-09-29 01:12:09 +00001860ObjCMethodDecl *
Greg Clayton0fffff52010-09-24 05:15:53 +00001861ClangASTContext::AddMethodToObjCObjectType
1862(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001863 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001864 clang_type_t class_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001865 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton1be10fc2010-09-29 01:12:09 +00001866 clang_type_t method_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001867 lldb::AccessType access
1868)
1869{
1870 if (class_opaque_type == NULL || method_opaque_type == NULL)
1871 return NULL;
1872
Greg Clayton6beaaa62011-01-17 03:46:26 +00001873 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton0fffff52010-09-24 05:15:53 +00001874
Greg Clayton6beaaa62011-01-17 03:46:26 +00001875 assert (ast != NULL);
Greg Clayton0fffff52010-09-24 05:15:53 +00001876 assert (identifier_table != NULL);
1877
1878 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1879
Sean Callanan78e37602011-01-27 04:42:51 +00001880 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton0fffff52010-09-24 05:15:53 +00001881 if (class_type == NULL)
1882 return NULL;
1883
Sean Callanan78e37602011-01-27 04:42:51 +00001884 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton0fffff52010-09-24 05:15:53 +00001885
1886 if (objc_class_type == NULL)
1887 return NULL;
1888
1889 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1890
1891 if (class_interface_decl == NULL)
1892 return NULL;
Greg Clayton9e409562010-07-28 02:04:09 +00001893
Greg Clayton0fffff52010-09-24 05:15:53 +00001894 const char *selector_start = ::strchr (name, ' ');
1895 if (selector_start == NULL)
1896 return NULL;
1897
1898 selector_start++;
1899 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1900 return NULL;
1901 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1902
Greg Clayton450e3f32010-10-12 02:24:53 +00001903 size_t len = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +00001904 const char *start;
Greg Clayton450e3f32010-10-12 02:24:53 +00001905 //printf ("name = '%s'\n", name);
1906
1907 unsigned num_selectors_with_args = 0;
1908 for (start = selector_start;
Greg Clayton0fffff52010-09-24 05:15:53 +00001909 start && *start != '\0' && *start != ']';
Greg Clayton450e3f32010-10-12 02:24:53 +00001910 start += len)
Greg Clayton0fffff52010-09-24 05:15:53 +00001911 {
Greg Clayton450e3f32010-10-12 02:24:53 +00001912 len = ::strcspn(start, ":]");
Greg Clayton90f90cd2010-10-27 04:01:14 +00001913 bool has_arg = (start[len] == ':');
1914 if (has_arg)
Greg Clayton450e3f32010-10-12 02:24:53 +00001915 ++num_selectors_with_args;
Greg Clayton0fffff52010-09-24 05:15:53 +00001916 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton90f90cd2010-10-27 04:01:14 +00001917 if (has_arg)
1918 len += 1;
Greg Clayton0fffff52010-09-24 05:15:53 +00001919 }
1920
1921
1922 if (selector_idents.size() == 0)
1923 return 0;
1924
Greg Clayton6beaaa62011-01-17 03:46:26 +00001925 clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton0fffff52010-09-24 05:15:53 +00001926 selector_idents.data());
1927
1928 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1929
1930 // Populate the method decl with parameter decls
Sean Callanan78e37602011-01-27 04:42:51 +00001931 const clang::Type *method_type(method_qual_type.getTypePtr());
Greg Clayton0fffff52010-09-24 05:15:53 +00001932
1933 if (method_type == NULL)
1934 return NULL;
1935
Sean Callanan78e37602011-01-27 04:42:51 +00001936 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001937
1938 if (!method_function_prototype)
1939 return NULL;
1940
1941
1942 bool is_variadic = false;
1943 bool is_synthesized = false;
1944 bool is_defined = false;
1945 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1946
1947 const unsigned num_args = method_function_prototype->getNumArgs();
1948
Greg Clayton6beaaa62011-01-17 03:46:26 +00001949 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001950 SourceLocation(), // beginLoc,
1951 SourceLocation(), // endLoc,
1952 method_selector,
1953 method_function_prototype->getResultType(),
1954 NULL, // TypeSourceInfo *ResultTInfo,
1955 GetDeclContextForType (class_opaque_type),
1956 name[0] == '-',
1957 is_variadic,
1958 is_synthesized,
1959 is_defined,
1960 imp_control,
1961 num_args);
1962
1963
1964 if (objc_method_decl == NULL)
1965 return NULL;
1966
1967 if (num_args > 0)
1968 {
1969 llvm::SmallVector<ParmVarDecl *, 12> params;
1970
1971 for (int param_index = 0; param_index < num_args; ++param_index)
1972 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001973 params.push_back (ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001974 objc_method_decl,
1975 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00001976 SourceLocation(),
Greg Clayton0fffff52010-09-24 05:15:53 +00001977 NULL, // anonymous
1978 method_function_prototype->getArgType(param_index),
1979 NULL,
1980 SC_Auto,
1981 SC_Auto,
1982 NULL));
1983 }
1984
Greg Clayton6beaaa62011-01-17 03:46:26 +00001985 objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args);
Greg Clayton0fffff52010-09-24 05:15:53 +00001986 }
1987
1988 class_interface_decl->addDecl (objc_method_decl);
1989
1990
1991 return objc_method_decl;
1992}
1993
1994
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001995uint32_t
Greg Clayton73b472d2010-10-27 03:32:59 +00001996ClangASTContext::GetTypeInfo
1997(
1998 clang_type_t clang_type,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001999 clang::ASTContext *ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002000 clang_type_t *pointee_or_element_clang_type
2001)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002002{
2003 if (clang_type == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00002004 return 0;
2005
2006 if (pointee_or_element_clang_type)
2007 *pointee_or_element_clang_type = NULL;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002008
2009 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2010
2011 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2012 switch (type_class)
2013 {
Sean Callanana2424172010-10-25 00:29:48 +00002014 case clang::Type::Builtin:
2015 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2016 {
Sean Callanana2424172010-10-25 00:29:48 +00002017 case clang::BuiltinType::ObjCId:
2018 case clang::BuiltinType::ObjCClass:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002019 if (ast && pointee_or_element_clang_type)
2020 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanana2424172010-10-25 00:29:48 +00002021 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002022
2023 default:
2024 break;
Sean Callanana2424172010-10-25 00:29:48 +00002025 }
2026 return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002027
2028 case clang::Type::BlockPointer:
2029 if (pointee_or_element_clang_type)
2030 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2031 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
2032
Greg Clayton49462ea2011-01-15 02:52:14 +00002033 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002034
2035 case clang::Type::ConstantArray:
2036 case clang::Type::DependentSizedArray:
2037 case clang::Type::IncompleteArray:
2038 case clang::Type::VariableArray:
2039 if (pointee_or_element_clang_type)
2040 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
2041 return eTypeHasChildren | eTypeIsArray;
2042
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002043 case clang::Type::DependentName: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002044 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
2045 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
2046 case clang::Type::Decltype: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002047
2048 case clang::Type::Enum:
2049 if (pointee_or_element_clang_type)
2050 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
2051 return eTypeIsEnumeration | eTypeHasValue;
2052
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002053 case clang::Type::Elaborated: return 0;
2054 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
2055 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
2056 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002057 case clang::Type::InjectedClassName: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002058
2059 case clang::Type::LValueReference:
2060 case clang::Type::RValueReference:
2061 if (pointee_or_element_clang_type)
2062 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
2063 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
2064
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002065 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002066
2067 case clang::Type::ObjCObjectPointer:
2068 if (pointee_or_element_clang_type)
2069 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2070 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
2071
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002072 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2073 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Clayton73b472d2010-10-27 03:32:59 +00002074
2075 case clang::Type::Pointer:
2076 if (pointee_or_element_clang_type)
2077 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2078 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
2079
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002080 case clang::Type::Record:
2081 if (qual_type->getAsCXXRecordDecl())
2082 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
2083 else
2084 return eTypeHasChildren | eTypeIsStructUnion;
2085 break;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002086 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
2087 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
2088 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Clayton73b472d2010-10-27 03:32:59 +00002089
2090 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002091 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00002092 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002093 pointee_or_element_clang_type);
2094
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002095 case clang::Type::TypeOfExpr: return 0;
2096 case clang::Type::TypeOf: return 0;
2097 case clang::Type::UnresolvedUsing: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002098 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
2099 default: return 0;
2100 }
2101 return 0;
2102}
2103
Greg Clayton9e409562010-07-28 02:04:09 +00002104
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002105#pragma mark Aggregate Types
2106
2107bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00002108ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002109{
2110 if (clang_type == NULL)
2111 return false;
2112
2113 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2114
Greg Clayton737b9322010-09-13 03:32:57 +00002115 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2116 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002117 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002118 case clang::Type::IncompleteArray:
2119 case clang::Type::VariableArray:
2120 case clang::Type::ConstantArray:
2121 case clang::Type::ExtVector:
2122 case clang::Type::Vector:
2123 case clang::Type::Record:
Greg Clayton9e409562010-07-28 02:04:09 +00002124 case clang::Type::ObjCObject:
2125 case clang::Type::ObjCInterface:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002126 return true;
2127
Greg Claytone1a916a2010-07-21 22:12:05 +00002128 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002129 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002130
2131 default:
2132 break;
2133 }
2134 // The clang type does have a value
2135 return false;
2136}
2137
2138uint32_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00002139ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002140{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002141 if (clang_type == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002142 return 0;
2143
2144 uint32_t num_children = 0;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002145 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00002146 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2147 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002148 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002149 case clang::Type::Builtin:
2150 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2151 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002152 case clang::BuiltinType::ObjCId: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002153 case clang::BuiltinType::ObjCClass: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002154 num_children = 1;
Greg Clayton73b472d2010-10-27 03:32:59 +00002155 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002156
2157 default:
2158 break;
2159 }
2160 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002161
Greg Clayton49462ea2011-01-15 02:52:14 +00002162 case clang::Type::Complex: return 0;
Greg Clayton54979cd2010-12-15 05:08:08 +00002163
Greg Claytone1a916a2010-07-21 22:12:05 +00002164 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002165 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002166 {
2167 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2168 const RecordDecl *record_decl = record_type->getDecl();
2169 assert(record_decl);
2170 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2171 if (cxx_record_decl)
2172 {
2173 if (omit_empty_base_classes)
2174 {
2175 // Check each base classes to see if it or any of its
2176 // base classes contain any fields. This can help
2177 // limit the noise in variable views by not having to
2178 // show base classes that contain no members.
2179 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2180 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2181 base_class != base_class_end;
2182 ++base_class)
2183 {
2184 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2185
2186 // Skip empty base classes
2187 if (RecordHasFields(base_class_decl) == false)
2188 continue;
2189
2190 num_children++;
2191 }
2192 }
2193 else
2194 {
2195 // Include all base classes
2196 num_children += cxx_record_decl->getNumBases();
2197 }
2198
2199 }
2200 RecordDecl::field_iterator field, field_end;
2201 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2202 ++num_children;
2203 }
2204 break;
2205
Greg Clayton9e409562010-07-28 02:04:09 +00002206 case clang::Type::ObjCObject:
2207 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002208 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002209 {
Sean Callanan78e37602011-01-27 04:42:51 +00002210 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002211 assert (objc_class_type);
2212 if (objc_class_type)
2213 {
2214 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2215
2216 if (class_interface_decl)
2217 {
2218
2219 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2220 if (superclass_interface_decl)
2221 {
2222 if (omit_empty_base_classes)
2223 {
2224 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2225 ++num_children;
2226 }
2227 else
2228 ++num_children;
2229 }
2230
2231 num_children += class_interface_decl->ivar_size();
2232 }
2233 }
2234 }
2235 break;
2236
2237 case clang::Type::ObjCObjectPointer:
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002238 {
Sean Callanan78e37602011-01-27 04:42:51 +00002239 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002240 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002241 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2242 pointee_type.getAsOpaquePtr(),
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002243 omit_empty_base_classes);
2244 // If this type points to a simple type, then it has 1 child
2245 if (num_pointee_children == 0)
2246 num_children = 1;
2247 else
2248 num_children = num_pointee_children;
2249 }
2250 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002251
Greg Claytone1a916a2010-07-21 22:12:05 +00002252 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002253 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2254 break;
2255
Greg Claytone1a916a2010-07-21 22:12:05 +00002256 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002257 {
Sean Callanan78e37602011-01-27 04:42:51 +00002258 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002259 QualType pointee_type (pointer_type->getPointeeType());
Greg Clayton6beaaa62011-01-17 03:46:26 +00002260 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2261 pointee_type.getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00002262 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002263 if (num_pointee_children == 0)
Greg Clayton54979cd2010-12-15 05:08:08 +00002264 {
2265 // We have a pointer to a pointee type that claims it has no children.
2266 // We will want to look at
2267 num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
2268 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002269 else
2270 num_children = num_pointee_children;
2271 }
2272 break;
2273
Greg Clayton73b472d2010-10-27 03:32:59 +00002274 case clang::Type::LValueReference:
2275 case clang::Type::RValueReference:
2276 {
Sean Callanan78e37602011-01-27 04:42:51 +00002277 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002278 QualType pointee_type = reference_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002279 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2280 pointee_type.getAsOpaquePtr(),
Greg Clayton73b472d2010-10-27 03:32:59 +00002281 omit_empty_base_classes);
2282 // If this type points to a simple type, then it has 1 child
2283 if (num_pointee_children == 0)
2284 num_children = 1;
2285 else
2286 num_children = num_pointee_children;
2287 }
2288 break;
2289
2290
Greg Claytone1a916a2010-07-21 22:12:05 +00002291 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002292 num_children = ClangASTContext::GetNumChildren (ast,
2293 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2294 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002295 break;
2296
2297 default:
2298 break;
2299 }
2300 return num_children;
2301}
2302
Greg Clayton54979cd2010-12-15 05:08:08 +00002303// If a pointer to a pointee type (the clang_type arg) says that it has no
2304// children, then we either need to trust it, or override it and return a
2305// different result. For example, an "int *" has one child that is an integer,
2306// but a function pointer doesn't have any children. Likewise if a Record type
2307// claims it has no children, then there really is nothing to show.
2308uint32_t
2309ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
2310{
2311 if (clang_type == NULL)
2312 return 0;
2313
2314 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2315 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2316 switch (type_class)
2317 {
Greg Clayton97a43712011-01-08 22:26:47 +00002318 case clang::Type::Builtin:
2319 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2320 {
2321 case clang::BuiltinType::Void:
2322 case clang::BuiltinType::NullPtr:
2323 return 0;
2324 case clang::BuiltinType::Bool:
2325 case clang::BuiltinType::Char_U:
2326 case clang::BuiltinType::UChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002327 case clang::BuiltinType::WChar_U:
Greg Clayton97a43712011-01-08 22:26:47 +00002328 case clang::BuiltinType::Char16:
2329 case clang::BuiltinType::Char32:
2330 case clang::BuiltinType::UShort:
2331 case clang::BuiltinType::UInt:
2332 case clang::BuiltinType::ULong:
2333 case clang::BuiltinType::ULongLong:
2334 case clang::BuiltinType::UInt128:
2335 case clang::BuiltinType::Char_S:
2336 case clang::BuiltinType::SChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002337 case clang::BuiltinType::WChar_S:
Greg Clayton97a43712011-01-08 22:26:47 +00002338 case clang::BuiltinType::Short:
2339 case clang::BuiltinType::Int:
2340 case clang::BuiltinType::Long:
2341 case clang::BuiltinType::LongLong:
2342 case clang::BuiltinType::Int128:
2343 case clang::BuiltinType::Float:
2344 case clang::BuiltinType::Double:
2345 case clang::BuiltinType::LongDouble:
2346 case clang::BuiltinType::Dependent:
2347 case clang::BuiltinType::Overload:
Greg Clayton97a43712011-01-08 22:26:47 +00002348 case clang::BuiltinType::ObjCId:
2349 case clang::BuiltinType::ObjCClass:
2350 case clang::BuiltinType::ObjCSel:
2351 return 1;
2352 }
2353 break;
2354
Greg Clayton49462ea2011-01-15 02:52:14 +00002355 case clang::Type::Complex: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00002356 case clang::Type::Pointer: return 1;
2357 case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
2358 case clang::Type::LValueReference: return 1;
2359 case clang::Type::RValueReference: return 1;
2360 case clang::Type::MemberPointer: return 0;
2361 case clang::Type::ConstantArray: return 0;
2362 case clang::Type::IncompleteArray: return 0;
2363 case clang::Type::VariableArray: return 0;
2364 case clang::Type::DependentSizedArray: return 0;
2365 case clang::Type::DependentSizedExtVector: return 0;
2366 case clang::Type::Vector: return 0;
2367 case clang::Type::ExtVector: return 0;
2368 case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
2369 case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
2370 case clang::Type::UnresolvedUsing: return 0;
2371 case clang::Type::Paren: return 0;
2372 case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2373 case clang::Type::TypeOfExpr: return 0;
2374 case clang::Type::TypeOf: return 0;
2375 case clang::Type::Decltype: return 0;
2376 case clang::Type::Record: return 0;
2377 case clang::Type::Enum: return 1;
2378 case clang::Type::Elaborated: return 1;
2379 case clang::Type::TemplateTypeParm: return 1;
2380 case clang::Type::SubstTemplateTypeParm: return 1;
2381 case clang::Type::TemplateSpecialization: return 1;
2382 case clang::Type::InjectedClassName: return 0;
2383 case clang::Type::DependentName: return 1;
2384 case clang::Type::DependentTemplateSpecialization: return 1;
2385 case clang::Type::ObjCObject: return 0;
2386 case clang::Type::ObjCInterface: return 0;
2387 case clang::Type::ObjCObjectPointer: return 1;
2388 default:
2389 break;
2390 }
2391 return 0;
2392}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002393
Greg Clayton1be10fc2010-09-29 01:12:09 +00002394clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002395ClangASTContext::GetChildClangTypeAtIndex
2396(
2397 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002398 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002399 uint32_t idx,
2400 bool transparent_pointers,
2401 bool omit_empty_base_classes,
2402 std::string& child_name,
2403 uint32_t &child_byte_size,
2404 int32_t &child_byte_offset,
2405 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002406 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002407 bool &child_is_base_class,
2408 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002409)
2410{
2411 if (parent_clang_type)
2412
2413 return GetChildClangTypeAtIndex (getASTContext(),
2414 parent_name,
2415 parent_clang_type,
2416 idx,
2417 transparent_pointers,
2418 omit_empty_base_classes,
2419 child_name,
2420 child_byte_size,
2421 child_byte_offset,
2422 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002423 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002424 child_is_base_class,
2425 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002426 return NULL;
2427}
2428
Greg Clayton1be10fc2010-09-29 01:12:09 +00002429clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002430ClangASTContext::GetChildClangTypeAtIndex
2431(
Greg Clayton6beaaa62011-01-17 03:46:26 +00002432 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002433 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002434 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002435 uint32_t idx,
2436 bool transparent_pointers,
2437 bool omit_empty_base_classes,
2438 std::string& child_name,
2439 uint32_t &child_byte_size,
2440 int32_t &child_byte_offset,
2441 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002442 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002443 bool &child_is_base_class,
2444 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002445)
2446{
2447 if (parent_clang_type == NULL)
2448 return NULL;
2449
Greg Clayton6beaaa62011-01-17 03:46:26 +00002450 if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002451 {
2452 uint32_t bit_offset;
2453 child_bitfield_bit_size = 0;
2454 child_bitfield_bit_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002455 child_is_base_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002456 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00002457 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2458 switch (parent_type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002459 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002460 case clang::Type::Builtin:
2461 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2462 {
2463 case clang::BuiltinType::ObjCId:
2464 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00002465 child_name = "isa";
Greg Clayton6beaaa62011-01-17 03:46:26 +00002466 child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
2467 return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002468
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002469 default:
2470 break;
2471 }
2472 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002473
Greg Claytone1a916a2010-07-21 22:12:05 +00002474 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002475 if (GetCompleteQualType (ast, parent_qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002476 {
2477 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2478 const RecordDecl *record_decl = record_type->getDecl();
2479 assert(record_decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00002480 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002481 uint32_t child_idx = 0;
2482
2483 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2484 if (cxx_record_decl)
2485 {
2486 // We might have base classes to print out first
2487 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2488 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2489 base_class != base_class_end;
2490 ++base_class)
2491 {
2492 const CXXRecordDecl *base_class_decl = NULL;
2493
2494 // Skip empty base classes
2495 if (omit_empty_base_classes)
2496 {
2497 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2498 if (RecordHasFields(base_class_decl) == false)
2499 continue;
2500 }
2501
2502 if (idx == child_idx)
2503 {
2504 if (base_class_decl == NULL)
2505 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2506
2507
2508 if (base_class->isVirtual())
Greg Clayton6ed95942011-01-22 07:12:45 +00002509 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002510 else
Greg Clayton6ed95942011-01-22 07:12:45 +00002511 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002512
2513 // Base classes should be a multiple of 8 bits in size
2514 assert (bit_offset % 8 == 0);
2515 child_byte_offset = bit_offset/8;
2516 std::string base_class_type_name(base_class->getType().getAsString());
2517
2518 child_name.assign(base_class_type_name.c_str());
2519
Greg Clayton6beaaa62011-01-17 03:46:26 +00002520 uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002521
Jim Inghamf46b3382011-04-15 23:42:06 +00002522 // Base classes bit sizes should be a multiple of 8 bits in size
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002523 assert (clang_type_info_bit_size % 8 == 0);
2524 child_byte_size = clang_type_info_bit_size / 8;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002525 child_is_base_class = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002526 return base_class->getType().getAsOpaquePtr();
2527 }
2528 // We don't increment the child index in the for loop since we might
2529 // be skipping empty base classes
2530 ++child_idx;
2531 }
2532 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002533 // Make sure index is in range...
2534 uint32_t field_idx = 0;
2535 RecordDecl::field_iterator field, field_end;
2536 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2537 {
2538 if (idx == child_idx)
2539 {
2540 // Print the member type if requested
2541 // Print the member name and equal sign
2542 child_name.assign(field->getNameAsString().c_str());
2543
2544 // Figure out the type byte size (field_type_info.first) and
2545 // alignment (field_type_info.second) from the AST context.
Greg Clayton6beaaa62011-01-17 03:46:26 +00002546 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
Greg Claytonc982c762010-07-09 20:39:50 +00002547 assert(field_idx < record_layout.getFieldCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002548
2549 child_byte_size = field_type_info.first / 8;
2550
2551 // Figure out the field offset within the current struct/union/class type
2552 bit_offset = record_layout.getFieldOffset (field_idx);
2553 child_byte_offset = bit_offset / 8;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002554 if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002555 child_bitfield_bit_offset = bit_offset % 8;
2556
2557 return field->getType().getAsOpaquePtr();
2558 }
2559 }
2560 }
2561 break;
2562
Greg Clayton9e409562010-07-28 02:04:09 +00002563 case clang::Type::ObjCObject:
2564 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002565 if (GetCompleteQualType (ast, parent_qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002566 {
Sean Callanan78e37602011-01-27 04:42:51 +00002567 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002568 assert (objc_class_type);
2569 if (objc_class_type)
2570 {
2571 uint32_t child_idx = 0;
2572 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2573
2574 if (class_interface_decl)
2575 {
2576
Greg Clayton6beaaa62011-01-17 03:46:26 +00002577 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
Greg Clayton9e409562010-07-28 02:04:09 +00002578 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2579 if (superclass_interface_decl)
2580 {
2581 if (omit_empty_base_classes)
2582 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002583 if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9e409562010-07-28 02:04:09 +00002584 {
2585 if (idx == 0)
2586 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002587 QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
Greg Clayton9e409562010-07-28 02:04:09 +00002588
2589
2590 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2591
Greg Clayton6beaaa62011-01-17 03:46:26 +00002592 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002593
2594 child_byte_size = ivar_type_info.first / 8;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002595 child_byte_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002596 child_is_base_class = true;
Greg Clayton9e409562010-07-28 02:04:09 +00002597
2598 return ivar_qual_type.getAsOpaquePtr();
2599 }
2600
2601 ++child_idx;
2602 }
2603 }
2604 else
2605 ++child_idx;
2606 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002607
2608 const uint32_t superclass_idx = child_idx;
Greg Clayton9e409562010-07-28 02:04:09 +00002609
2610 if (idx < (child_idx + class_interface_decl->ivar_size()))
2611 {
2612 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2613
2614 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2615 {
2616 if (child_idx == idx)
2617 {
2618 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2619
2620 QualType ivar_qual_type(ivar_decl->getType());
2621
2622 child_name.assign(ivar_decl->getNameAsString().c_str());
2623
Greg Clayton6beaaa62011-01-17 03:46:26 +00002624 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002625
2626 child_byte_size = ivar_type_info.first / 8;
2627
2628 // Figure out the field offset within the current struct/union/class type
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002629 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9e409562010-07-28 02:04:09 +00002630 child_byte_offset = bit_offset / 8;
2631
2632 return ivar_qual_type.getAsOpaquePtr();
2633 }
2634 ++child_idx;
2635 }
2636 }
2637 }
2638 }
2639 }
2640 break;
2641
2642 case clang::Type::ObjCObjectPointer:
2643 {
Sean Callanan78e37602011-01-27 04:42:51 +00002644 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002645 QualType pointee_type = pointer_type->getPointeeType();
2646
2647 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2648 {
Greg Claytone221f822011-01-21 01:59:00 +00002649 child_is_deref_of_parent = false;
2650 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002651 return GetChildClangTypeAtIndex (ast,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002652 parent_name,
2653 pointer_type->getPointeeType().getAsOpaquePtr(),
2654 idx,
2655 transparent_pointers,
2656 omit_empty_base_classes,
2657 child_name,
2658 child_byte_size,
2659 child_byte_offset,
2660 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002661 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002662 child_is_base_class,
2663 tmp_child_is_deref_of_parent);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002664 }
2665 else
2666 {
Greg Claytone221f822011-01-21 01:59:00 +00002667 child_is_deref_of_parent = true;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002668 if (parent_name)
2669 {
2670 child_name.assign(1, '*');
2671 child_name += parent_name;
2672 }
2673
2674 // We have a pointer to an simple type
2675 if (idx == 0)
2676 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002677 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002678 assert(clang_type_info.first % 8 == 0);
2679 child_byte_size = clang_type_info.first / 8;
2680 child_byte_offset = 0;
2681 return pointee_type.getAsOpaquePtr();
2682 }
2683 }
Greg Clayton9e409562010-07-28 02:04:09 +00002684 }
2685 break;
2686
Greg Claytone1a916a2010-07-21 22:12:05 +00002687 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002688 {
2689 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2690 const uint64_t element_count = array->getSize().getLimitedValue();
2691
2692 if (idx < element_count)
2693 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002694 if (GetCompleteQualType (ast, array->getElementType()))
2695 {
2696 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002697
Greg Clayton6beaaa62011-01-17 03:46:26 +00002698 char element_name[64];
2699 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002700
Greg Clayton6beaaa62011-01-17 03:46:26 +00002701 child_name.assign(element_name);
2702 assert(field_type_info.first % 8 == 0);
2703 child_byte_size = field_type_info.first / 8;
2704 child_byte_offset = idx * child_byte_size;
2705 return array->getElementType().getAsOpaquePtr();
2706 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002707 }
2708 }
2709 break;
2710
Greg Claytone1a916a2010-07-21 22:12:05 +00002711 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002712 {
Sean Callanan78e37602011-01-27 04:42:51 +00002713 const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002714 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton97a43712011-01-08 22:26:47 +00002715
2716 // Don't dereference "void *" pointers
2717 if (pointee_type->isVoidType())
2718 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002719
2720 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2721 {
Greg Claytone221f822011-01-21 01:59:00 +00002722 child_is_deref_of_parent = false;
2723 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002724 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002725 parent_name,
2726 pointer_type->getPointeeType().getAsOpaquePtr(),
2727 idx,
2728 transparent_pointers,
2729 omit_empty_base_classes,
2730 child_name,
2731 child_byte_size,
2732 child_byte_offset,
2733 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002734 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002735 child_is_base_class,
2736 tmp_child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002737 }
2738 else
2739 {
Greg Claytone221f822011-01-21 01:59:00 +00002740 child_is_deref_of_parent = true;
2741
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002742 if (parent_name)
2743 {
2744 child_name.assign(1, '*');
2745 child_name += parent_name;
2746 }
2747
2748 // We have a pointer to an simple type
2749 if (idx == 0)
2750 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002751 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002752 assert(clang_type_info.first % 8 == 0);
2753 child_byte_size = clang_type_info.first / 8;
2754 child_byte_offset = 0;
2755 return pointee_type.getAsOpaquePtr();
2756 }
2757 }
2758 }
2759 break;
2760
Greg Clayton73b472d2010-10-27 03:32:59 +00002761 case clang::Type::LValueReference:
2762 case clang::Type::RValueReference:
2763 {
Sean Callanan78e37602011-01-27 04:42:51 +00002764 const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002765 QualType pointee_type(reference_type->getPointeeType());
2766 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2767 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2768 {
Greg Claytone221f822011-01-21 01:59:00 +00002769 child_is_deref_of_parent = false;
2770 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002771 return GetChildClangTypeAtIndex (ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002772 parent_name,
2773 pointee_clang_type,
2774 idx,
2775 transparent_pointers,
2776 omit_empty_base_classes,
2777 child_name,
2778 child_byte_size,
2779 child_byte_offset,
2780 child_bitfield_bit_size,
2781 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002782 child_is_base_class,
2783 tmp_child_is_deref_of_parent);
Greg Clayton73b472d2010-10-27 03:32:59 +00002784 }
2785 else
2786 {
2787 if (parent_name)
2788 {
2789 child_name.assign(1, '&');
2790 child_name += parent_name;
2791 }
2792
2793 // We have a pointer to an simple type
2794 if (idx == 0)
2795 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002796 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Clayton73b472d2010-10-27 03:32:59 +00002797 assert(clang_type_info.first % 8 == 0);
2798 child_byte_size = clang_type_info.first / 8;
2799 child_byte_offset = 0;
2800 return pointee_type.getAsOpaquePtr();
2801 }
2802 }
2803 }
2804 break;
2805
Greg Claytone1a916a2010-07-21 22:12:05 +00002806 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002807 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002808 parent_name,
Sean Callanan48114472010-12-13 01:26:27 +00002809 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002810 idx,
2811 transparent_pointers,
2812 omit_empty_base_classes,
2813 child_name,
2814 child_byte_size,
2815 child_byte_offset,
2816 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002817 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002818 child_is_base_class,
2819 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002820 break;
2821
2822 default:
2823 break;
2824 }
2825 }
Greg Clayton19503a22010-07-23 15:37:46 +00002826 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002827}
2828
2829static inline bool
2830BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2831{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002832 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002833}
2834
2835static uint32_t
2836GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2837{
2838 uint32_t num_bases = 0;
2839 if (cxx_record_decl)
2840 {
2841 if (omit_empty_base_classes)
2842 {
2843 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2844 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2845 base_class != base_class_end;
2846 ++base_class)
2847 {
2848 // Skip empty base classes
2849 if (omit_empty_base_classes)
2850 {
2851 if (BaseSpecifierIsEmpty (base_class))
2852 continue;
2853 }
2854 ++num_bases;
2855 }
2856 }
2857 else
2858 num_bases = cxx_record_decl->getNumBases();
2859 }
2860 return num_bases;
2861}
2862
2863
2864static uint32_t
2865GetIndexForRecordBase
2866(
2867 const RecordDecl *record_decl,
2868 const CXXBaseSpecifier *base_spec,
2869 bool omit_empty_base_classes
2870)
2871{
2872 uint32_t child_idx = 0;
2873
2874 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2875
2876// const char *super_name = record_decl->getNameAsCString();
2877// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2878// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2879//
2880 if (cxx_record_decl)
2881 {
2882 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2883 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2884 base_class != base_class_end;
2885 ++base_class)
2886 {
2887 if (omit_empty_base_classes)
2888 {
2889 if (BaseSpecifierIsEmpty (base_class))
2890 continue;
2891 }
2892
2893// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2894// child_idx,
2895// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2896//
2897//
2898 if (base_class == base_spec)
2899 return child_idx;
2900 ++child_idx;
2901 }
2902 }
2903
2904 return UINT32_MAX;
2905}
2906
2907
2908static uint32_t
2909GetIndexForRecordChild
2910(
2911 const RecordDecl *record_decl,
2912 NamedDecl *canonical_decl,
2913 bool omit_empty_base_classes
2914)
2915{
2916 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2917
2918// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2919//
2920//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2921// if (cxx_record_decl)
2922// {
2923// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2924// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2925// base_class != base_class_end;
2926// ++base_class)
2927// {
2928// if (omit_empty_base_classes)
2929// {
2930// if (BaseSpecifierIsEmpty (base_class))
2931// continue;
2932// }
2933//
2934//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2935//// record_decl->getNameAsCString(),
2936//// canonical_decl->getNameAsCString(),
2937//// child_idx,
2938//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2939//
2940//
2941// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2942// if (curr_base_class_decl == canonical_decl)
2943// {
2944// return child_idx;
2945// }
2946// ++child_idx;
2947// }
2948// }
2949//
2950// const uint32_t num_bases = child_idx;
2951 RecordDecl::field_iterator field, field_end;
2952 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2953 field != field_end;
2954 ++field, ++child_idx)
2955 {
2956// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2957// record_decl->getNameAsCString(),
2958// canonical_decl->getNameAsCString(),
2959// child_idx - num_bases,
2960// field->getNameAsCString());
2961
2962 if (field->getCanonicalDecl() == canonical_decl)
2963 return child_idx;
2964 }
2965
2966 return UINT32_MAX;
2967}
2968
2969// Look for a child member (doesn't include base classes, but it does include
2970// their members) in the type hierarchy. Returns an index path into "clang_type"
2971// on how to reach the appropriate member.
2972//
2973// class A
2974// {
2975// public:
2976// int m_a;
2977// int m_b;
2978// };
2979//
2980// class B
2981// {
2982// };
2983//
2984// class C :
2985// public B,
2986// public A
2987// {
2988// };
2989//
2990// If we have a clang type that describes "class C", and we wanted to looked
2991// "m_b" in it:
2992//
2993// With omit_empty_base_classes == false we would get an integer array back with:
2994// { 1, 1 }
2995// The first index 1 is the child index for "class A" within class C
2996// The second index 1 is the child index for "m_b" within class A
2997//
2998// With omit_empty_base_classes == true we would get an integer array back with:
2999// { 0, 1 }
3000// 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)
3001// The second index 1 is the child index for "m_b" within class A
3002
3003size_t
3004ClangASTContext::GetIndexOfChildMemberWithName
3005(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003006 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003007 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003008 const char *name,
3009 bool omit_empty_base_classes,
3010 std::vector<uint32_t>& child_indexes
3011)
3012{
3013 if (clang_type && name && name[0])
3014 {
3015 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003016 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3017 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003018 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003019 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003020 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003021 {
3022 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3023 const RecordDecl *record_decl = record_type->getDecl();
3024
3025 assert(record_decl);
3026 uint32_t child_idx = 0;
3027
3028 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3029
3030 // Try and find a field that matches NAME
3031 RecordDecl::field_iterator field, field_end;
3032 StringRef name_sref(name);
3033 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3034 field != field_end;
3035 ++field, ++child_idx)
3036 {
3037 if (field->getName().equals (name_sref))
3038 {
3039 // We have to add on the number of base classes to this index!
3040 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
3041 return child_indexes.size();
3042 }
3043 }
3044
3045 if (cxx_record_decl)
3046 {
3047 const RecordDecl *parent_record_decl = cxx_record_decl;
3048
3049 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
3050
3051 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
3052 // Didn't find things easily, lets let clang do its thang...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003053 IdentifierInfo & ident_ref = ast->Idents.get(name, name + strlen (name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003054 DeclarationName decl_name(&ident_ref);
3055
3056 CXXBasePaths paths;
3057 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
3058 decl_name.getAsOpaquePtr(),
3059 paths))
3060 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003061 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
3062 for (path = paths.begin(); path != path_end; ++path)
3063 {
3064 const size_t num_path_elements = path->size();
3065 for (size_t e=0; e<num_path_elements; ++e)
3066 {
3067 CXXBasePathElement elem = (*path)[e];
3068
3069 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
3070 if (child_idx == UINT32_MAX)
3071 {
3072 child_indexes.clear();
3073 return 0;
3074 }
3075 else
3076 {
3077 child_indexes.push_back (child_idx);
3078 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
3079 }
3080 }
3081 DeclContext::lookup_iterator named_decl_pos;
3082 for (named_decl_pos = path->Decls.first;
3083 named_decl_pos != path->Decls.second && parent_record_decl;
3084 ++named_decl_pos)
3085 {
3086 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
3087
3088 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
3089 if (child_idx == UINT32_MAX)
3090 {
3091 child_indexes.clear();
3092 return 0;
3093 }
3094 else
3095 {
3096 child_indexes.push_back (child_idx);
3097 }
3098 }
3099 }
3100 return child_indexes.size();
3101 }
3102 }
3103
3104 }
3105 break;
3106
Greg Clayton9e409562010-07-28 02:04:09 +00003107 case clang::Type::ObjCObject:
3108 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003109 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003110 {
3111 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003112 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003113 assert (objc_class_type);
3114 if (objc_class_type)
3115 {
3116 uint32_t child_idx = 0;
3117 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3118
3119 if (class_interface_decl)
3120 {
3121 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3122 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3123
Greg Clayton6ba78152010-09-18 02:11:07 +00003124 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9e409562010-07-28 02:04:09 +00003125 {
3126 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3127
3128 if (ivar_decl->getName().equals (name_sref))
3129 {
3130 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3131 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3132 ++child_idx;
3133
3134 child_indexes.push_back (child_idx);
3135 return child_indexes.size();
3136 }
3137 }
3138
3139 if (superclass_interface_decl)
3140 {
3141 // The super class index is always zero for ObjC classes,
3142 // so we push it onto the child indexes in case we find
3143 // an ivar in our superclass...
3144 child_indexes.push_back (0);
3145
Greg Clayton6beaaa62011-01-17 03:46:26 +00003146 if (GetIndexOfChildMemberWithName (ast,
3147 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00003148 name,
3149 omit_empty_base_classes,
3150 child_indexes))
3151 {
3152 // We did find an ivar in a superclass so just
3153 // return the results!
3154 return child_indexes.size();
3155 }
3156
3157 // We didn't find an ivar matching "name" in our
3158 // superclass, pop the superclass zero index that
3159 // we pushed on above.
3160 child_indexes.pop_back();
3161 }
3162 }
3163 }
3164 }
3165 break;
3166
3167 case clang::Type::ObjCObjectPointer:
3168 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003169 return GetIndexOfChildMemberWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003170 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3171 name,
3172 omit_empty_base_classes,
3173 child_indexes);
3174 }
3175 break;
3176
3177
Greg Claytone1a916a2010-07-21 22:12:05 +00003178 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003179 {
3180// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3181// const uint64_t element_count = array->getSize().getLimitedValue();
3182//
3183// if (idx < element_count)
3184// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003185// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003186//
3187// char element_name[32];
3188// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3189//
3190// child_name.assign(element_name);
3191// assert(field_type_info.first % 8 == 0);
3192// child_byte_size = field_type_info.first / 8;
3193// child_byte_offset = idx * child_byte_size;
3194// return array->getElementType().getAsOpaquePtr();
3195// }
3196 }
3197 break;
3198
Greg Claytone1a916a2010-07-21 22:12:05 +00003199// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003200// {
3201// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3202// QualType pointee_type = mem_ptr_type->getPointeeType();
3203//
3204// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3205// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003206// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003207// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3208// name);
3209// }
3210// }
3211// break;
3212//
Greg Claytone1a916a2010-07-21 22:12:05 +00003213 case clang::Type::LValueReference:
3214 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003215 {
Sean Callanan78e37602011-01-27 04:42:51 +00003216 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003217 QualType pointee_type = reference_type->getPointeeType();
3218
3219 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3220 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003221 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003222 reference_type->getPointeeType().getAsOpaquePtr(),
3223 name,
3224 omit_empty_base_classes,
3225 child_indexes);
3226 }
3227 }
3228 break;
3229
Greg Claytone1a916a2010-07-21 22:12:05 +00003230 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003231 {
Sean Callanan78e37602011-01-27 04:42:51 +00003232 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003233 QualType pointee_type = pointer_type->getPointeeType();
3234
3235 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3236 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003237 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003238 pointer_type->getPointeeType().getAsOpaquePtr(),
3239 name,
3240 omit_empty_base_classes,
3241 child_indexes);
3242 }
3243 else
3244 {
3245// if (parent_name)
3246// {
3247// child_name.assign(1, '*');
3248// child_name += parent_name;
3249// }
3250//
3251// // We have a pointer to an simple type
3252// if (idx == 0)
3253// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003254// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003255// assert(clang_type_info.first % 8 == 0);
3256// child_byte_size = clang_type_info.first / 8;
3257// child_byte_offset = 0;
3258// return pointee_type.getAsOpaquePtr();
3259// }
3260 }
3261 }
3262 break;
3263
Greg Claytone1a916a2010-07-21 22:12:05 +00003264 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003265 return GetIndexOfChildMemberWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003266 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003267 name,
3268 omit_empty_base_classes,
3269 child_indexes);
3270
3271 default:
3272 break;
3273 }
3274 }
3275 return 0;
3276}
3277
3278
3279// Get the index of the child of "clang_type" whose name matches. This function
3280// doesn't descend into the children, but only looks one level deep and name
3281// matches can include base class names.
3282
3283uint32_t
3284ClangASTContext::GetIndexOfChildWithName
3285(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003286 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003287 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003288 const char *name,
3289 bool omit_empty_base_classes
3290)
3291{
3292 if (clang_type && name && name[0])
3293 {
3294 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00003295
Greg Clayton737b9322010-09-13 03:32:57 +00003296 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9e409562010-07-28 02:04:09 +00003297
Greg Clayton737b9322010-09-13 03:32:57 +00003298 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003299 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003300 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003301 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003302 {
3303 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3304 const RecordDecl *record_decl = record_type->getDecl();
3305
3306 assert(record_decl);
3307 uint32_t child_idx = 0;
3308
3309 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3310
3311 if (cxx_record_decl)
3312 {
3313 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3314 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3315 base_class != base_class_end;
3316 ++base_class)
3317 {
3318 // Skip empty base classes
3319 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3320 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3321 continue;
3322
3323 if (base_class->getType().getAsString().compare (name) == 0)
3324 return child_idx;
3325 ++child_idx;
3326 }
3327 }
3328
3329 // Try and find a field that matches NAME
3330 RecordDecl::field_iterator field, field_end;
3331 StringRef name_sref(name);
3332 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3333 field != field_end;
3334 ++field, ++child_idx)
3335 {
3336 if (field->getName().equals (name_sref))
3337 return child_idx;
3338 }
3339
3340 }
3341 break;
3342
Greg Clayton9e409562010-07-28 02:04:09 +00003343 case clang::Type::ObjCObject:
3344 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003345 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003346 {
3347 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003348 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003349 assert (objc_class_type);
3350 if (objc_class_type)
3351 {
3352 uint32_t child_idx = 0;
3353 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3354
3355 if (class_interface_decl)
3356 {
3357 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3358 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3359
3360 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3361 {
3362 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3363
3364 if (ivar_decl->getName().equals (name_sref))
3365 {
3366 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3367 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3368 ++child_idx;
3369
3370 return child_idx;
3371 }
3372 }
3373
3374 if (superclass_interface_decl)
3375 {
3376 if (superclass_interface_decl->getName().equals (name_sref))
3377 return 0;
3378 }
3379 }
3380 }
3381 }
3382 break;
3383
3384 case clang::Type::ObjCObjectPointer:
3385 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003386 return GetIndexOfChildWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003387 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3388 name,
3389 omit_empty_base_classes);
3390 }
3391 break;
3392
Greg Claytone1a916a2010-07-21 22:12:05 +00003393 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003394 {
3395// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3396// const uint64_t element_count = array->getSize().getLimitedValue();
3397//
3398// if (idx < element_count)
3399// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003400// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003401//
3402// char element_name[32];
3403// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3404//
3405// child_name.assign(element_name);
3406// assert(field_type_info.first % 8 == 0);
3407// child_byte_size = field_type_info.first / 8;
3408// child_byte_offset = idx * child_byte_size;
3409// return array->getElementType().getAsOpaquePtr();
3410// }
3411 }
3412 break;
3413
Greg Claytone1a916a2010-07-21 22:12:05 +00003414// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003415// {
3416// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3417// QualType pointee_type = mem_ptr_type->getPointeeType();
3418//
3419// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3420// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003421// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003422// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3423// name);
3424// }
3425// }
3426// break;
3427//
Greg Claytone1a916a2010-07-21 22:12:05 +00003428 case clang::Type::LValueReference:
3429 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003430 {
Sean Callanan78e37602011-01-27 04:42:51 +00003431 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003432 QualType pointee_type = reference_type->getPointeeType();
3433
3434 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3435 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003436 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003437 reference_type->getPointeeType().getAsOpaquePtr(),
3438 name,
3439 omit_empty_base_classes);
3440 }
3441 }
3442 break;
3443
Greg Claytone1a916a2010-07-21 22:12:05 +00003444 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003445 {
Sean Callanan78e37602011-01-27 04:42:51 +00003446 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003447 QualType pointee_type = pointer_type->getPointeeType();
3448
3449 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3450 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003451 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003452 pointer_type->getPointeeType().getAsOpaquePtr(),
3453 name,
3454 omit_empty_base_classes);
3455 }
3456 else
3457 {
3458// if (parent_name)
3459// {
3460// child_name.assign(1, '*');
3461// child_name += parent_name;
3462// }
3463//
3464// // We have a pointer to an simple type
3465// if (idx == 0)
3466// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003467// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003468// assert(clang_type_info.first % 8 == 0);
3469// child_byte_size = clang_type_info.first / 8;
3470// child_byte_offset = 0;
3471// return pointee_type.getAsOpaquePtr();
3472// }
3473 }
3474 }
3475 break;
3476
Greg Claytone1a916a2010-07-21 22:12:05 +00003477 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003478 return GetIndexOfChildWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003479 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003480 name,
3481 omit_empty_base_classes);
3482
3483 default:
3484 break;
3485 }
3486 }
3487 return UINT32_MAX;
3488}
3489
3490#pragma mark TagType
3491
3492bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003493ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003494{
3495 if (tag_clang_type)
3496 {
3497 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00003498 const clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003499 if (clang_type)
3500 {
Sean Callanan78e37602011-01-27 04:42:51 +00003501 const TagType *tag_type = dyn_cast<TagType>(clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003502 if (tag_type)
3503 {
3504 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3505 if (tag_decl)
3506 {
3507 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3508 return true;
3509 }
3510 }
3511 }
3512 }
3513 return false;
3514}
3515
3516
3517#pragma mark DeclContext Functions
3518
3519DeclContext *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003520ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003521{
3522 if (clang_type == NULL)
3523 return NULL;
3524
3525 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003526 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3527 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003528 {
Greg Clayton9e409562010-07-28 02:04:09 +00003529 case clang::Type::FunctionNoProto: break;
3530 case clang::Type::FunctionProto: break;
3531 case clang::Type::IncompleteArray: break;
3532 case clang::Type::VariableArray: break;
3533 case clang::Type::ConstantArray: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003534 case clang::Type::DependentSizedArray: break;
Greg Clayton9e409562010-07-28 02:04:09 +00003535 case clang::Type::ExtVector: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003536 case clang::Type::DependentSizedExtVector: break;
Greg Clayton9e409562010-07-28 02:04:09 +00003537 case clang::Type::Vector: break;
3538 case clang::Type::Builtin: break;
3539 case clang::Type::BlockPointer: break;
3540 case clang::Type::Pointer: break;
3541 case clang::Type::LValueReference: break;
3542 case clang::Type::RValueReference: break;
3543 case clang::Type::MemberPointer: break;
3544 case clang::Type::Complex: break;
3545 case clang::Type::ObjCObject: break;
3546 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3547 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3548 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3549 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
Sean Callanan48114472010-12-13 01:26:27 +00003550 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003551
Greg Clayton9e409562010-07-28 02:04:09 +00003552 case clang::Type::TypeOfExpr: break;
3553 case clang::Type::TypeOf: break;
3554 case clang::Type::Decltype: break;
3555 //case clang::Type::QualifiedName: break;
3556 case clang::Type::TemplateSpecialization: break;
Sean Callananfb0b7582011-03-15 00:17:19 +00003557 case clang::Type::DependentTemplateSpecialization: break;
3558 case clang::Type::TemplateTypeParm: break;
3559 case clang::Type::SubstTemplateTypeParm: break;
3560 case clang::Type::SubstTemplateTypeParmPack:break;
3561 case clang::Type::PackExpansion: break;
3562 case clang::Type::UnresolvedUsing: break;
3563 case clang::Type::Paren: break;
3564 case clang::Type::Elaborated: break;
3565 case clang::Type::Attributed: break;
3566 case clang::Type::Auto: break;
3567 case clang::Type::InjectedClassName: break;
3568 case clang::Type::DependentName: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003569 }
3570 // No DeclContext in this type...
3571 return NULL;
3572}
3573
3574#pragma mark Namespace Declarations
3575
3576NamespaceDecl *
3577ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3578{
3579 // TODO: Do something intelligent with the Declaration object passed in
3580 // like maybe filling in the SourceLocation with it...
3581 if (name)
3582 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003583 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003584 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00003585 decl_ctx = ast->getTranslationUnitDecl();
Sean Callananfb0b7582011-03-15 00:17:19 +00003586 return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &ast->Idents.get(name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003587 }
3588 return NULL;
3589}
3590
3591
3592#pragma mark Function Types
3593
3594FunctionDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003595ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003596{
3597 if (name)
3598 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003599 ASTContext *ast = getASTContext();
3600 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003601
3602 if (name && name[0])
3603 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003604 return FunctionDecl::Create(*ast,
3605 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003606 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003607 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003608 DeclarationName (&ast->Idents.get(name)),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003609 QualType::getFromOpaquePtr(function_clang_type),
3610 NULL,
3611 (FunctionDecl::StorageClass)storage,
3612 (FunctionDecl::StorageClass)storage,
3613 is_inline);
3614 }
3615 else
3616 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003617 return FunctionDecl::Create(*ast,
3618 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003619 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003620 SourceLocation(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003621 DeclarationName (),
3622 QualType::getFromOpaquePtr(function_clang_type),
3623 NULL,
3624 (FunctionDecl::StorageClass)storage,
3625 (FunctionDecl::StorageClass)storage,
3626 is_inline);
3627 }
3628 }
3629 return NULL;
3630}
3631
Greg Clayton1be10fc2010-09-29 01:12:09 +00003632clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00003633ClangASTContext::CreateFunctionType (ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003634 clang_type_t result_type,
3635 clang_type_t *args,
Sean Callananc81256a2010-09-16 20:40:25 +00003636 unsigned num_args,
3637 bool is_variadic,
3638 unsigned type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003639{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003640 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003641 std::vector<QualType> qual_type_args;
3642 for (unsigned i=0; i<num_args; ++i)
3643 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3644
3645 // TODO: Detect calling convention in DWARF?
Sean Callanan2c777c42011-01-18 23:32:05 +00003646 FunctionProtoType::ExtProtoInfo proto_info;
3647 proto_info.Variadic = is_variadic;
Sean Callananfb0b7582011-03-15 00:17:19 +00003648 proto_info.ExceptionSpecType = EST_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00003649 proto_info.TypeQuals = type_quals;
Sean Callananfb0b7582011-03-15 00:17:19 +00003650 proto_info.RefQualifier = RQ_None;
Sean Callanan2c777c42011-01-18 23:32:05 +00003651 proto_info.NumExceptions = 0;
3652 proto_info.Exceptions = NULL;
3653
Greg Clayton6beaaa62011-01-17 03:46:26 +00003654 return ast->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton471b31c2010-07-20 22:52:08 +00003655 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003656 qual_type_args.size(),
Sean Callanan2c777c42011-01-18 23:32:05 +00003657 proto_info).getAsOpaquePtr(); // NoReturn);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003658}
3659
3660ParmVarDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003661ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003662{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003663 ASTContext *ast = getASTContext();
3664 assert (ast != NULL);
3665 return ParmVarDecl::Create(*ast,
3666 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003667 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003668 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003669 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callananc81256a2010-09-16 20:40:25 +00003670 QualType::getFromOpaquePtr(param_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003671 NULL,
3672 (VarDecl::StorageClass)storage,
3673 (VarDecl::StorageClass)storage,
3674 0);
3675}
3676
3677void
3678ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3679{
3680 if (function_decl)
3681 function_decl->setParams (params, num_params);
3682}
3683
3684
3685#pragma mark Array Types
3686
Greg Clayton1be10fc2010-09-29 01:12:09 +00003687clang_type_t
3688ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003689{
3690 if (element_type)
3691 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003692 ASTContext *ast = getASTContext();
3693 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003694 llvm::APInt ap_element_count (64, element_count);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003695 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003696 ap_element_count,
3697 ArrayType::Normal,
3698 0).getAsOpaquePtr(); // ElemQuals
3699 }
3700 return NULL;
3701}
3702
3703
3704#pragma mark TagDecl
3705
3706bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003707ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003708{
3709 if (clang_type)
3710 {
3711 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00003712 const clang::Type *t = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003713 if (t)
3714 {
Sean Callanan78e37602011-01-27 04:42:51 +00003715 const TagType *tag_type = dyn_cast<TagType>(t);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003716 if (tag_type)
3717 {
3718 TagDecl *tag_decl = tag_type->getDecl();
3719 if (tag_decl)
3720 {
3721 tag_decl->startDefinition();
3722 return true;
3723 }
3724 }
3725 }
3726 }
3727 return false;
3728}
3729
3730bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003731ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003732{
3733 if (clang_type)
3734 {
3735 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton14372242010-09-29 03:44:17 +00003736
3737 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3738
3739 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003740 {
Greg Clayton14372242010-09-29 03:44:17 +00003741 cxx_record_decl->completeDefinition();
3742
3743 return true;
3744 }
3745
Sean Callanan78e37602011-01-27 04:42:51 +00003746 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
Sean Callanana2424172010-10-25 00:29:48 +00003747
3748 if (objc_class_type)
3749 {
3750 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3751
3752 class_interface_decl->setForwardDecl(false);
3753 }
3754
Greg Clayton14372242010-09-29 03:44:17 +00003755 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3756
3757 if (enum_type)
3758 {
3759 EnumDecl *enum_decl = enum_type->getDecl();
3760
3761 if (enum_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003762 {
Greg Clayton14372242010-09-29 03:44:17 +00003763 /// TODO This really needs to be fixed.
3764
3765 unsigned NumPositiveBits = 1;
3766 unsigned NumNegativeBits = 0;
3767
Greg Clayton6beaaa62011-01-17 03:46:26 +00003768 ASTContext *ast = getASTContext();
Greg Claytone02b8502010-10-12 04:29:14 +00003769
3770 QualType promotion_qual_type;
3771 // If the enum integer type is less than an integer in bit width,
3772 // then we must promote it to an integer size.
Greg Clayton6beaaa62011-01-17 03:46:26 +00003773 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
Greg Claytone02b8502010-10-12 04:29:14 +00003774 {
3775 if (enum_decl->getIntegerType()->isSignedIntegerType())
Greg Clayton6beaaa62011-01-17 03:46:26 +00003776 promotion_qual_type = ast->IntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003777 else
Greg Clayton6beaaa62011-01-17 03:46:26 +00003778 promotion_qual_type = ast->UnsignedIntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003779 }
3780 else
3781 promotion_qual_type = enum_decl->getIntegerType();
3782
3783 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton14372242010-09-29 03:44:17 +00003784 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003785 }
3786 }
3787 }
3788 return false;
3789}
3790
3791
3792#pragma mark Enumeration Types
3793
Greg Clayton1be10fc2010-09-29 01:12:09 +00003794clang_type_t
Greg Claytonca512b32011-01-14 04:54:56 +00003795ClangASTContext::CreateEnumerationType
3796(
3797 const char *name,
3798 DeclContext *decl_ctx,
3799 const Declaration &decl,
3800 clang_type_t integer_qual_type
3801)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003802{
3803 // TODO: Do something intelligent with the Declaration object passed in
3804 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003805 ASTContext *ast = getASTContext();
3806 assert (ast != NULL);
Greg Claytone02b8502010-10-12 04:29:14 +00003807
3808 // TODO: ask about these...
3809// const bool IsScoped = false;
3810// const bool IsFixed = false;
3811
Greg Clayton6beaaa62011-01-17 03:46:26 +00003812 EnumDecl *enum_decl = EnumDecl::Create (*ast,
Greg Claytonca512b32011-01-14 04:54:56 +00003813 decl_ctx,
Greg Claytone02b8502010-10-12 04:29:14 +00003814 SourceLocation(),
Greg Claytone02b8502010-10-12 04:29:14 +00003815 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00003816 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callanan48114472010-12-13 01:26:27 +00003817 NULL,
3818 false, // IsScoped
3819 false, // IsScopedUsingClassTag
3820 false); // IsFixed
Sean Callanan2652ad22011-01-18 01:03:44 +00003821
3822
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003823 if (enum_decl)
Greg Clayton83ff3892010-09-12 23:17:56 +00003824 {
3825 // TODO: check if we should be setting the promotion type too?
3826 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00003827
3828 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
3829
Greg Clayton6beaaa62011-01-17 03:46:26 +00003830 return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Clayton83ff3892010-09-12 23:17:56 +00003831 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003832 return NULL;
3833}
3834
Greg Clayton1be10fc2010-09-29 01:12:09 +00003835clang_type_t
3836ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3837{
3838 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3839
Sean Callanan78e37602011-01-27 04:42:51 +00003840 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003841 if (clang_type)
3842 {
3843 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3844 if (enum_type)
3845 {
3846 EnumDecl *enum_decl = enum_type->getDecl();
3847 if (enum_decl)
3848 return enum_decl->getIntegerType().getAsOpaquePtr();
3849 }
3850 }
3851 return NULL;
3852}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003853bool
3854ClangASTContext::AddEnumerationValueToEnumerationType
3855(
Greg Clayton1be10fc2010-09-29 01:12:09 +00003856 clang_type_t enum_clang_type,
3857 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003858 const Declaration &decl,
3859 const char *name,
3860 int64_t enum_value,
3861 uint32_t enum_value_bit_size
3862)
3863{
3864 if (enum_clang_type && enumerator_clang_type && name)
3865 {
3866 // TODO: Do something intelligent with the Declaration object passed in
3867 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003868 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003869 IdentifierTable *identifier_table = getIdentifierTable();
3870
Greg Clayton6beaaa62011-01-17 03:46:26 +00003871 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003872 assert (identifier_table != NULL);
3873 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3874
Sean Callanan78e37602011-01-27 04:42:51 +00003875 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003876 if (clang_type)
3877 {
3878 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3879
3880 if (enum_type)
3881 {
3882 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3883 enum_llvm_apsint = enum_value;
3884 EnumConstantDecl *enumerator_decl =
Greg Clayton6beaaa62011-01-17 03:46:26 +00003885 EnumConstantDecl::Create (*ast,
3886 enum_type->getDecl(),
3887 SourceLocation(),
3888 name ? &identifier_table->get(name) : NULL, // Identifier
3889 QualType::getFromOpaquePtr(enumerator_clang_type),
3890 NULL,
3891 enum_llvm_apsint);
3892
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003893 if (enumerator_decl)
3894 {
3895 enum_type->getDecl()->addDecl(enumerator_decl);
3896 return true;
3897 }
3898 }
3899 }
3900 }
3901 return false;
3902}
3903
3904#pragma mark Pointers & References
3905
Greg Clayton1be10fc2010-09-29 01:12:09 +00003906clang_type_t
3907ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003908{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003909 return CreatePointerType (getASTContext(), clang_type);
3910}
3911
3912clang_type_t
3913ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
3914{
3915 if (ast && clang_type)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003916 {
3917 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3918
Greg Clayton737b9322010-09-13 03:32:57 +00003919 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3920 switch (type_class)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003921 {
3922 case clang::Type::ObjCObject:
3923 case clang::Type::ObjCInterface:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003924 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003925
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003926 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003927 return ast->getPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003928 }
3929 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003930 return NULL;
3931}
3932
Greg Clayton1be10fc2010-09-29 01:12:09 +00003933clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003934ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
3935 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003936{
3937 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003938 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003939 return NULL;
3940}
3941
Greg Clayton1be10fc2010-09-29 01:12:09 +00003942clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003943ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
3944 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003945{
3946 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003947 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003948 return NULL;
3949}
3950
Greg Clayton1be10fc2010-09-29 01:12:09 +00003951clang_type_t
3952ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Clayton9b81a312010-06-12 01:20:30 +00003953{
3954 if (clang_pointee_type && clang_pointee_type)
3955 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3956 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3957 return NULL;
3958}
3959
Greg Clayton1a65ae12011-01-25 23:55:37 +00003960uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003961ClangASTContext::GetPointerBitSize ()
3962{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003963 ASTContext *ast = getASTContext();
3964 return ast->getTypeSize(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003965}
3966
3967bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003968ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003969{
3970 if (clang_type == NULL)
3971 return false;
3972
3973 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003974 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3975 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003976 {
Sean Callanana2424172010-10-25 00:29:48 +00003977 case clang::Type::Builtin:
3978 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3979 {
3980 default:
3981 break;
3982 case clang::BuiltinType::ObjCId:
3983 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00003984 return true;
3985 }
3986 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00003987 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003988 if (target_type)
3989 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3990 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003991 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003992 if (target_type)
3993 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3994 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003995 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003996 if (target_type)
3997 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3998 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003999 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004000 if (target_type)
4001 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4002 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004003 case clang::Type::LValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004004 if (target_type)
4005 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4006 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004007 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004008 if (target_type)
4009 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4010 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004011 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004012 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004013 default:
4014 break;
4015 }
4016 return false;
4017}
4018
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004019bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004020ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004021{
4022 if (!clang_type)
4023 return false;
4024
4025 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4026 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
4027
4028 if (builtin_type)
4029 {
4030 if (builtin_type->isInteger())
4031 is_signed = builtin_type->isSignedInteger();
4032
4033 return true;
4034 }
4035
4036 return false;
4037}
4038
4039bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004040ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004041{
4042 if (clang_type)
4043 {
4044 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004045 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4046 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004047 {
Sean Callanana2424172010-10-25 00:29:48 +00004048 case clang::Type::Builtin:
4049 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4050 {
4051 default:
4052 break;
4053 case clang::BuiltinType::ObjCId:
4054 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004055 return true;
4056 }
4057 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004058 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004059 if (target_type)
4060 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4061 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004062 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004063 if (target_type)
4064 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4065 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004066 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004067 if (target_type)
4068 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4069 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004070 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004071 if (target_type)
4072 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4073 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004074 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004075 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004076 default:
4077 break;
4078 }
4079 }
4080 return false;
4081}
4082
4083bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004084ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004085{
4086 if (clang_type)
4087 {
4088 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4089
4090 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
4091 {
4092 clang::BuiltinType::Kind kind = BT->getKind();
4093 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
4094 {
4095 count = 1;
4096 is_complex = false;
4097 return true;
4098 }
4099 }
4100 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
4101 {
4102 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
4103 {
4104 count = 2;
4105 is_complex = true;
4106 return true;
4107 }
4108 }
4109 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
4110 {
4111 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
4112 {
4113 count = VT->getNumElements();
4114 is_complex = false;
4115 return true;
4116 }
4117 }
4118 }
4119 return false;
4120}
4121
Greg Clayton8f92f0a2010-10-14 22:52:14 +00004122
4123bool
4124ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
4125{
4126 if (clang_type)
4127 {
4128 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4129
4130 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4131 if (cxx_record_decl)
4132 {
4133 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
4134 return true;
4135 }
4136 }
4137 class_name.clear();
4138 return false;
4139}
4140
4141
Greg Clayton0fffff52010-09-24 05:15:53 +00004142bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004143ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004144{
4145 if (clang_type)
4146 {
4147 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4148 if (qual_type->getAsCXXRecordDecl() != NULL)
4149 return true;
4150 }
4151 return false;
4152}
4153
4154bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004155ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004156{
4157 if (clang_type)
4158 {
4159 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4160 if (qual_type->isObjCObjectOrInterfaceType())
4161 return true;
4162 }
4163 return false;
4164}
4165
4166
Greg Clayton73b472d2010-10-27 03:32:59 +00004167bool
4168ClangASTContext::IsCharType (clang_type_t clang_type)
4169{
4170 if (clang_type)
4171 return QualType::getFromOpaquePtr(clang_type)->isCharType();
4172 return false;
4173}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004174
4175bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004176ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004177{
Greg Clayton73b472d2010-10-27 03:32:59 +00004178 clang_type_t pointee_or_element_clang_type = NULL;
4179 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
4180
4181 if (pointee_or_element_clang_type == NULL)
4182 return false;
4183
4184 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004185 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004186 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
4187
4188 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004189 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004190 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4191 if (type_flags.Test (eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004192 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004193 // We know the size of the array and it could be a C string
4194 // since it is an array of characters
4195 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
4196 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004197 }
Greg Clayton73b472d2010-10-27 03:32:59 +00004198 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004199 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004200 length = 0;
4201 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004202 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004203
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004204 }
4205 }
4206 return false;
4207}
4208
4209bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004210ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton737b9322010-09-13 03:32:57 +00004211{
4212 if (clang_type)
4213 {
4214 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4215
4216 if (qual_type->isFunctionPointerType())
4217 return true;
4218
4219 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4220 switch (type_class)
4221 {
Sean Callananfb0b7582011-03-15 00:17:19 +00004222 default:
4223 break;
Greg Clayton737b9322010-09-13 03:32:57 +00004224 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004225 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004226
4227 case clang::Type::LValueReference:
4228 case clang::Type::RValueReference:
4229 {
Sean Callanan78e37602011-01-27 04:42:51 +00004230 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004231 if (reference_type)
4232 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
4233 }
4234 break;
4235 }
4236 }
4237 return false;
4238}
4239
Greg Clayton73b472d2010-10-27 03:32:59 +00004240size_t
4241ClangASTContext::GetArraySize (clang_type_t clang_type)
4242{
4243 if (clang_type)
4244 {
Sean Callanan78e37602011-01-27 04:42:51 +00004245 const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00004246 if (array)
4247 return array->getSize().getLimitedValue();
4248 }
4249 return 0;
4250}
Greg Clayton737b9322010-09-13 03:32:57 +00004251
4252bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004253ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004254{
4255 if (!clang_type)
4256 return false;
4257
4258 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4259
Greg Clayton737b9322010-09-13 03:32:57 +00004260 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4261 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004262 {
Sean Callananfb0b7582011-03-15 00:17:19 +00004263 default:
4264 break;
Greg Claytone1a916a2010-07-21 22:12:05 +00004265 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004266 if (member_type)
4267 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4268 if (size)
Greg Claytonac4827f2011-04-01 18:14:08 +00004269 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004270 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004271 case clang::Type::IncompleteArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004272 if (member_type)
4273 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4274 if (size)
4275 *size = 0;
4276 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004277 case clang::Type::VariableArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004278 if (member_type)
4279 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4280 if (size)
4281 *size = 0;
Greg Clayton03dbf2e2011-02-02 00:52:14 +00004282 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004283 case clang::Type::DependentSizedArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004284 if (member_type)
4285 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4286 if (size)
4287 *size = 0;
4288 return true;
4289 }
4290 return false;
4291}
4292
4293
4294#pragma mark Typedefs
4295
Greg Clayton1be10fc2010-09-29 01:12:09 +00004296clang_type_t
4297ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004298{
4299 if (clang_type)
4300 {
4301 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004302 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004303 IdentifierTable *identifier_table = getIdentifierTable();
Greg Clayton6beaaa62011-01-17 03:46:26 +00004304 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004305 assert (identifier_table != NULL);
4306 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00004307 decl_ctx = ast->getTranslationUnitDecl();
4308 TypedefDecl *decl = TypedefDecl::Create (*ast,
4309 decl_ctx,
4310 SourceLocation(),
Sean Callananfb0b7582011-03-15 00:17:19 +00004311 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00004312 name ? &identifier_table->get(name) : NULL, // Identifier
4313 ast->CreateTypeSourceInfo(qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00004314
4315 decl->setAccess(AS_public); // TODO respect proper access specifier
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004316
4317 // Get a uniqued QualType for the typedef decl type
Greg Clayton6beaaa62011-01-17 03:46:26 +00004318 return ast->getTypedefType (decl).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004319 }
4320 return NULL;
4321}
4322
4323
4324std::string
Greg Clayton1be10fc2010-09-29 01:12:09 +00004325ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004326{
4327 std::string return_name;
4328
Greg Clayton1be10fc2010-09-29 01:12:09 +00004329 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004330
Greg Clayton1be10fc2010-09-29 01:12:09 +00004331 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004332 if (typedef_type)
4333 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00004334 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004335 return_name = typedef_decl->getQualifiedNameAsString();
4336 }
4337 else
4338 {
4339 return_name = qual_type.getAsString();
4340 }
4341
4342 return return_name;
4343}
4344
4345// Disable this for now since I can't seem to get a nicely formatted float
4346// out of the APFloat class without just getting the float, double or quad
4347// and then using a formatted print on it which defeats the purpose. We ideally
4348// would like to get perfect string values for any kind of float semantics
4349// so we can support remote targets. The code below also requires a patch to
4350// llvm::APInt.
4351//bool
Greg Clayton6beaaa62011-01-17 03:46:26 +00004352//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 +00004353//{
4354// uint32_t count = 0;
4355// bool is_complex = false;
4356// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4357// {
4358// unsigned num_bytes_per_float = byte_size / count;
4359// unsigned num_bits_per_float = num_bytes_per_float * 8;
4360//
4361// float_str.clear();
4362// uint32_t i;
4363// for (i=0; i<count; i++)
4364// {
4365// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
4366// bool is_ieee = false;
4367// APFloat ap_float(ap_int, is_ieee);
4368// char s[1024];
4369// unsigned int hex_digits = 0;
4370// bool upper_case = false;
4371//
4372// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
4373// {
4374// if (i > 0)
4375// float_str.append(", ");
4376// float_str.append(s);
4377// if (i == 1 && is_complex)
4378// float_str.append(1, 'i');
4379// }
4380// }
4381// return !float_str.empty();
4382// }
4383// return false;
4384//}
4385
4386size_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00004387ClangASTContext::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 +00004388{
4389 if (clang_type)
4390 {
4391 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4392 uint32_t count = 0;
4393 bool is_complex = false;
4394 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4395 {
4396 // TODO: handle complex and vector types
4397 if (count != 1)
4398 return false;
4399
4400 StringRef s_sref(s);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004401 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004402
Greg Clayton6beaaa62011-01-17 03:46:26 +00004403 const uint64_t bit_size = ast->getTypeSize (qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004404 const uint64_t byte_size = bit_size / 8;
4405 if (dst_size >= byte_size)
4406 {
4407 if (bit_size == sizeof(float)*8)
4408 {
4409 float float32 = ap_float.convertToFloat();
4410 ::memcpy (dst, &float32, byte_size);
4411 return byte_size;
4412 }
4413 else if (bit_size >= 64)
4414 {
4415 llvm::APInt ap_int(ap_float.bitcastToAPInt());
4416 ::memcpy (dst, ap_int.getRawData(), byte_size);
4417 return byte_size;
4418 }
4419 }
4420 }
4421 }
4422 return 0;
4423}
Sean Callanan6fe64b52010-09-17 02:24:29 +00004424
4425unsigned
Greg Clayton1be10fc2010-09-29 01:12:09 +00004426ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanan6fe64b52010-09-17 02:24:29 +00004427{
4428 assert (clang_type);
4429
4430 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4431
4432 return qual_type.getQualifiers().getCVRQualifiers();
4433}
Greg Clayton6beaaa62011-01-17 03:46:26 +00004434
4435bool
4436ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
4437{
4438 if (clang_type == NULL)
4439 return false;
4440
Greg Claytonc432c192011-01-20 04:18:48 +00004441 return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004442}
4443
4444
4445bool
4446ClangASTContext::GetCompleteType (clang_type_t clang_type)
4447{
4448 return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
4449}
4450