ClangASTContext.cpp revision ad29309ac7a29db2cc363bd4ace20fbf862a42d3
1//===-- 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
10#include "lldb/Symbol/ClangASTContext.h"
11
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
17
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
30#define NDEBUG
31// Need to include assert.h so it is as clang would expect it to be (disabled)
32#include <assert.h>
33#endif
34
35#include "clang/AST/ASTContext.h"
36#include "clang/AST/ASTImporter.h"
37#include "clang/AST/CXXInheritance.h"
38#include "clang/AST/DeclObjC.h"
39#include "clang/AST/RecordLayout.h"
40#include "clang/AST/Type.h"
41#include "clang/Basic/Builtins.h"
42#include "clang/Basic/FileManager.h"
43#include "clang/Basic/FileSystemOptions.h"
44#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"
49
50#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
51#undef NDEBUG
52#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
56
57#include "lldb/Core/dwarf.h"
58#include "lldb/Core/Flags.h"
59#include "lldb/Core/Log.h"
60
61#include <stdio.h>
62
63using namespace lldb;
64using namespace lldb_private;
65using namespace llvm;
66using namespace clang;
67
68
69static bool
70GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
71{
72    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
73    switch (type_class)
74    {
75    case clang::Type::Record:
76    case clang::Type::Enum:
77        {
78            clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
79            if (tag_type)
80            {
81                clang::TagDecl *tag_decl = tag_type->getDecl();
82                if (tag_decl)
83                {
84                    if (tag_decl->getDefinition())
85                        return true;
86
87                    if (tag_decl->hasExternalLexicalStorage())
88                    {
89                        ExternalASTSource *external_ast_source = ast->getExternalSource();
90                        if (external_ast_source)
91                        {
92                            external_ast_source->CompleteType(tag_decl);
93                            return !tag_type->isIncompleteType();
94                        }
95                    }
96                    return false;
97                }
98            }
99
100        }
101        break;
102
103    case clang::Type::ObjCObject:
104    case clang::Type::ObjCInterface:
105        {
106            clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
107            if (objc_class_type)
108            {
109                clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
110                // We currently can't complete objective C types through the newly added ASTContext
111                // because it only supports TagDecl objects right now...
112                bool is_forward_decl = class_interface_decl->isForwardDecl();
113                if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
114                {
115                    ExternalASTSource *external_ast_source = ast->getExternalSource();
116                    if (external_ast_source)
117                    {
118                        external_ast_source->CompleteType (class_interface_decl);
119                        is_forward_decl = class_interface_decl->isForwardDecl();
120                    }
121                }
122                return is_forward_decl;
123            }
124        }
125        break;
126
127    case clang::Type::Typedef:
128        return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType());
129
130    default:
131        break;
132    }
133
134    return true;
135}
136
137
138static AccessSpecifier
139ConvertAccessTypeToAccessSpecifier (AccessType access)
140{
141    switch (access)
142    {
143    default:               break;
144    case eAccessNone:      return AS_none;
145    case eAccessPublic:    return AS_public;
146    case eAccessPrivate:   return AS_private;
147    case eAccessProtected: return AS_protected;
148    }
149    return AS_none;
150}
151
152static ObjCIvarDecl::AccessControl
153ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
154{
155    switch (access)
156    {
157    default:               break;
158    case eAccessNone:      return ObjCIvarDecl::None;
159    case eAccessPublic:    return ObjCIvarDecl::Public;
160    case eAccessPrivate:   return ObjCIvarDecl::Private;
161    case eAccessProtected: return ObjCIvarDecl::Protected;
162    case eAccessPackage:   return ObjCIvarDecl::Package;
163    }
164    return ObjCIvarDecl::None;
165}
166
167
168static void
169ParseLangArgs
170(
171    LangOptions &Opts,
172    InputKind IK
173)
174{
175    // FIXME: Cleanup per-file based stuff.
176
177    // Set some properties which depend soley on the input kind; it would be nice
178    // to move these to the language standard, and have the driver resolve the
179    // input kind + language standard.
180    if (IK == IK_Asm) {
181        Opts.AsmPreprocessor = 1;
182    } else if (IK == IK_ObjC ||
183               IK == IK_ObjCXX ||
184               IK == IK_PreprocessedObjC ||
185               IK == IK_PreprocessedObjCXX) {
186        Opts.ObjC1 = Opts.ObjC2 = 1;
187    }
188
189    LangStandard::Kind LangStd = LangStandard::lang_unspecified;
190
191    if (LangStd == LangStandard::lang_unspecified) {
192        // Based on the base language, pick one.
193        switch (IK) {
194            case IK_None:
195            case IK_AST:
196                assert (!"Invalid input kind!");
197            case IK_OpenCL:
198                LangStd = LangStandard::lang_opencl;
199                break;
200            case IK_Asm:
201            case IK_C:
202            case IK_PreprocessedC:
203            case IK_ObjC:
204            case IK_PreprocessedObjC:
205                LangStd = LangStandard::lang_gnu99;
206                break;
207            case IK_CXX:
208            case IK_PreprocessedCXX:
209            case IK_ObjCXX:
210            case IK_PreprocessedObjCXX:
211                LangStd = LangStandard::lang_gnucxx98;
212                break;
213        }
214    }
215
216    const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
217    Opts.BCPLComment = Std.hasBCPLComments();
218    Opts.C99 = Std.isC99();
219    Opts.CPlusPlus = Std.isCPlusPlus();
220    Opts.CPlusPlus0x = Std.isCPlusPlus0x();
221    Opts.Digraphs = Std.hasDigraphs();
222    Opts.GNUMode = Std.isGNUMode();
223    Opts.GNUInline = !Std.isC99();
224    Opts.HexFloats = Std.hasHexFloats();
225    Opts.ImplicitInt = Std.hasImplicitInt();
226
227    // OpenCL has some additional defaults.
228    if (LangStd == LangStandard::lang_opencl) {
229        Opts.OpenCL = 1;
230        Opts.AltiVec = 1;
231        Opts.CXXOperatorNames = 1;
232        Opts.LaxVectorConversions = 1;
233    }
234
235    // OpenCL and C++ both have bool, true, false keywords.
236    Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
237
238//    if (Opts.CPlusPlus)
239//        Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
240//
241//    if (Args.hasArg(OPT_fobjc_gc_only))
242//        Opts.setGCMode(LangOptions::GCOnly);
243//    else if (Args.hasArg(OPT_fobjc_gc))
244//        Opts.setGCMode(LangOptions::HybridGC);
245//
246//    if (Args.hasArg(OPT_print_ivar_layout))
247//        Opts.ObjCGCBitmapPrint = 1;
248//
249//    if (Args.hasArg(OPT_faltivec))
250//        Opts.AltiVec = 1;
251//
252//    if (Args.hasArg(OPT_pthread))
253//        Opts.POSIXThreads = 1;
254//
255//    llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
256//                                          "default");
257//    if (Vis == "default")
258        Opts.setVisibilityMode(DefaultVisibility);
259//    else if (Vis == "hidden")
260//        Opts.setVisibilityMode(LangOptions::Hidden);
261//    else if (Vis == "protected")
262//        Opts.setVisibilityMode(LangOptions::Protected);
263//    else
264//        Diags.Report(diag::err_drv_invalid_value)
265//        << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
266
267//    Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
268
269    // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
270    // is specified, or -std is set to a conforming mode.
271    Opts.Trigraphs = !Opts.GNUMode;
272//    if (Args.hasArg(OPT_trigraphs))
273//        Opts.Trigraphs = 1;
274//
275//    Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
276//                                     OPT_fno_dollars_in_identifiers,
277//                                     !Opts.AsmPreprocessor);
278//    Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
279//    Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
280//    Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
281//    if (Args.hasArg(OPT_fno_lax_vector_conversions))
282//        Opts.LaxVectorConversions = 0;
283//    Opts.Exceptions = Args.hasArg(OPT_fexceptions);
284//    Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
285//    Opts.Blocks = Args.hasArg(OPT_fblocks);
286//    Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
287//    Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
288//    Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
289//    Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
290//    Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
291//    Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
292//    Opts.AccessControl = Args.hasArg(OPT_faccess_control);
293//    Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
294//    Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
295//    Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
296//                                                 Diags);
297//    Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
298//    Opts.ObjCConstantStringClass = getLastArgValue(Args,
299//                                                   OPT_fconstant_string_class);
300//    Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
301//    Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
302//    Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
303//    Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
304//    Opts.Static = Args.hasArg(OPT_static_define);
305    Opts.OptimizeSize = 0;
306
307    // FIXME: Eliminate this dependency.
308//    unsigned Opt =
309//    Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
310//    Opts.Optimize = Opt != 0;
311    unsigned Opt = 0;
312
313    // This is the __NO_INLINE__ define, which just depends on things like the
314    // optimization level and -fno-inline, not actually whether the backend has
315    // inlining enabled.
316    //
317    // FIXME: This is affected by other options (-fno-inline).
318    Opts.NoInline = !Opt;
319
320//    unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
321//    switch (SSP) {
322//        default:
323//            Diags.Report(diag::err_drv_invalid_value)
324//            << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
325//            break;
326//        case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
327//        case 1: Opts.setStackProtectorMode(LangOptions::SSPOn);  break;
328//        case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
329//    }
330}
331
332
333ClangASTContext::ClangASTContext (const char *target_triple) :
334    m_target_triple(),
335    m_ast_ap(),
336    m_language_options_ap(),
337    m_source_manager_ap(),
338    m_diagnostic_ap(),
339    m_target_options_ap(),
340    m_target_info_ap(),
341    m_identifier_table_ap(),
342    m_selector_table_ap(),
343    m_builtins_ap(),
344    m_callback_tag_decl (NULL),
345    m_callback_objc_decl (NULL),
346    m_callback_baton (NULL)
347
348{
349    if (target_triple && target_triple[0])
350        m_target_triple.assign (target_triple);
351}
352
353//----------------------------------------------------------------------
354// Destructor
355//----------------------------------------------------------------------
356ClangASTContext::~ClangASTContext()
357{
358    m_builtins_ap.reset();
359    m_selector_table_ap.reset();
360    m_identifier_table_ap.reset();
361    m_target_info_ap.reset();
362    m_target_options_ap.reset();
363    m_diagnostic_ap.reset();
364    m_source_manager_ap.reset();
365    m_language_options_ap.reset();
366    m_ast_ap.reset();
367}
368
369
370void
371ClangASTContext::Clear()
372{
373    m_ast_ap.reset();
374    m_language_options_ap.reset();
375    m_source_manager_ap.reset();
376    m_diagnostic_ap.reset();
377    m_target_options_ap.reset();
378    m_target_info_ap.reset();
379    m_identifier_table_ap.reset();
380    m_selector_table_ap.reset();
381    m_builtins_ap.reset();
382}
383
384const char *
385ClangASTContext::GetTargetTriple ()
386{
387    return m_target_triple.c_str();
388}
389
390void
391ClangASTContext::SetTargetTriple (const char *target_triple)
392{
393    Clear();
394    m_target_triple.assign(target_triple);
395}
396
397bool
398ClangASTContext::HasExternalSource ()
399{
400    ASTContext *ast = getASTContext();
401    if (ast)
402        return ast->getExternalSource () != NULL;
403    return false;
404}
405
406void
407ClangASTContext::SetExternalSource (llvm::OwningPtr<ExternalASTSource> &ast_source_ap)
408{
409    ASTContext *ast = getASTContext();
410    if (ast)
411    {
412        ast->setExternalSource (ast_source_ap);
413        ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
414        //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
415    }
416}
417
418void
419ClangASTContext::RemoveExternalSource ()
420{
421    ASTContext *ast = getASTContext();
422
423    if (ast)
424    {
425        llvm::OwningPtr<ExternalASTSource> empty_ast_source_ap;
426        ast->setExternalSource (empty_ast_source_ap);
427        ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
428        //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
429    }
430}
431
432
433
434ASTContext *
435ClangASTContext::getASTContext()
436{
437    if (m_ast_ap.get() == NULL)
438    {
439        m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
440                                       *getSourceManager(),
441                                       *getTargetInfo(),
442                                       *getIdentifierTable(),
443                                       *getSelectorTable(),
444                                       *getBuiltinContext(),
445                                       0));
446
447        if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton)
448        {
449            m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
450            //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
451        }
452
453        m_ast_ap->getDiagnostics().setClient(getDiagnosticClient(), false);
454    }
455    return m_ast_ap.get();
456}
457
458Builtin::Context *
459ClangASTContext::getBuiltinContext()
460{
461    if (m_builtins_ap.get() == NULL)
462        m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
463    return m_builtins_ap.get();
464}
465
466IdentifierTable *
467ClangASTContext::getIdentifierTable()
468{
469    if (m_identifier_table_ap.get() == NULL)
470        m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
471    return m_identifier_table_ap.get();
472}
473
474LangOptions *
475ClangASTContext::getLanguageOptions()
476{
477    if (m_language_options_ap.get() == NULL)
478    {
479        m_language_options_ap.reset(new LangOptions());
480        ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
481//        InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
482    }
483    return m_language_options_ap.get();
484}
485
486SelectorTable *
487ClangASTContext::getSelectorTable()
488{
489    if (m_selector_table_ap.get() == NULL)
490        m_selector_table_ap.reset (new SelectorTable());
491    return m_selector_table_ap.get();
492}
493
494clang::FileManager *
495ClangASTContext::getFileManager()
496{
497    if (m_file_manager_ap.get() == NULL)
498    {
499        clang::FileSystemOptions file_system_options;
500        m_file_manager_ap.reset(new clang::FileManager(file_system_options));
501    }
502    return m_file_manager_ap.get();
503}
504
505clang::SourceManager *
506ClangASTContext::getSourceManager()
507{
508    if (m_source_manager_ap.get() == NULL)
509        m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
510    return m_source_manager_ap.get();
511}
512
513Diagnostic *
514ClangASTContext::getDiagnostic()
515{
516    if (m_diagnostic_ap.get() == NULL)
517    {
518        llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
519        m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
520    }
521    return m_diagnostic_ap.get();
522}
523
524class NullDiagnosticClient : public DiagnosticClient
525{
526public:
527    NullDiagnosticClient ()
528    {
529        m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
530    }
531
532    void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
533    {
534        if (m_log)
535        {
536            llvm::SmallVectorImpl<char> diag_str(10);
537            info.FormatDiagnostic(diag_str);
538            diag_str.push_back('\0');
539            m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
540        }
541    }
542private:
543    LogSP m_log;
544};
545
546DiagnosticClient *
547ClangASTContext::getDiagnosticClient()
548{
549    if (m_diagnostic_client_ap.get() == NULL)
550        m_diagnostic_client_ap.reset(new NullDiagnosticClient);
551
552    return m_diagnostic_client_ap.get();
553}
554
555TargetOptions *
556ClangASTContext::getTargetOptions()
557{
558    if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
559    {
560        m_target_options_ap.reset (new TargetOptions());
561        if (m_target_options_ap.get())
562            m_target_options_ap->Triple = m_target_triple;
563    }
564    return m_target_options_ap.get();
565}
566
567
568TargetInfo *
569ClangASTContext::getTargetInfo()
570{
571    // target_triple should be something like "x86_64-apple-darwin10"
572    if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
573        m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
574    return m_target_info_ap.get();
575}
576
577#pragma mark Basic Types
578
579static inline bool
580QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
581{
582    uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
583    if (qual_type_bit_size == bit_size)
584        return true;
585    return false;
586}
587
588clang_type_t
589ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
590{
591    ASTContext *ast = getASTContext();
592
593    assert (ast != NULL);
594
595    return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
596}
597
598clang_type_t
599ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
600{
601    if (!ast)
602        return NULL;
603
604    switch (encoding)
605    {
606    case eEncodingInvalid:
607        if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
608            return ast->VoidPtrTy.getAsOpaquePtr();
609        break;
610
611    case eEncodingUint:
612        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
613            return ast->UnsignedCharTy.getAsOpaquePtr();
614        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
615            return ast->UnsignedShortTy.getAsOpaquePtr();
616        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
617            return ast->UnsignedIntTy.getAsOpaquePtr();
618        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
619            return ast->UnsignedLongTy.getAsOpaquePtr();
620        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
621            return ast->UnsignedLongLongTy.getAsOpaquePtr();
622        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
623            return ast->UnsignedInt128Ty.getAsOpaquePtr();
624        break;
625
626    case eEncodingSint:
627        if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
628            return ast->CharTy.getAsOpaquePtr();
629        if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
630            return ast->ShortTy.getAsOpaquePtr();
631        if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
632            return ast->IntTy.getAsOpaquePtr();
633        if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
634            return ast->LongTy.getAsOpaquePtr();
635        if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
636            return ast->LongLongTy.getAsOpaquePtr();
637        if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
638            return ast->Int128Ty.getAsOpaquePtr();
639        break;
640
641    case eEncodingIEEE754:
642        if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
643            return ast->FloatTy.getAsOpaquePtr();
644        if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
645            return ast->DoubleTy.getAsOpaquePtr();
646        if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
647            return ast->LongDoubleTy.getAsOpaquePtr();
648        break;
649
650    case eEncodingVector:
651    default:
652        break;
653    }
654
655    return NULL;
656}
657
658clang_type_t
659ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
660{
661    ASTContext *ast = getASTContext();
662
663    #define streq(a,b) strcmp(a,b) == 0
664    assert (ast != NULL);
665    if (ast)
666    {
667        switch (dw_ate)
668        {
669        default:
670            break;
671
672        case DW_ATE_address:
673            if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
674                return ast->VoidPtrTy.getAsOpaquePtr();
675            break;
676
677        case DW_ATE_boolean:
678            if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
679                return ast->BoolTy.getAsOpaquePtr();
680            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
681                return ast->UnsignedCharTy.getAsOpaquePtr();
682            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
683                return ast->UnsignedShortTy.getAsOpaquePtr();
684            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
685                return ast->UnsignedIntTy.getAsOpaquePtr();
686            break;
687
688        case DW_ATE_lo_user:
689            // This has been seen to mean DW_AT_complex_integer
690            if (strcmp(type_name, "complex") == 0)
691            {
692                clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
693                return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
694            }
695            break;
696
697        case DW_ATE_complex_float:
698            if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
699                return ast->FloatComplexTy.getAsOpaquePtr();
700            else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
701                return ast->DoubleComplexTy.getAsOpaquePtr();
702            else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
703                return ast->LongDoubleComplexTy.getAsOpaquePtr();
704            else
705            {
706                clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
707                return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
708            }
709            break;
710
711        case DW_ATE_float:
712            if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
713                return ast->FloatTy.getAsOpaquePtr();
714            if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
715                return ast->DoubleTy.getAsOpaquePtr();
716            if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
717                return ast->LongDoubleTy.getAsOpaquePtr();
718            break;
719
720        case DW_ATE_signed:
721            if (type_name)
722            {
723                if (strstr(type_name, "long long"))
724                {
725                    if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
726                        return ast->LongLongTy.getAsOpaquePtr();
727                }
728                else if (strstr(type_name, "long"))
729                {
730                    if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
731                        return ast->LongTy.getAsOpaquePtr();
732                }
733                else if (strstr(type_name, "short"))
734                {
735                    if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
736                        return ast->ShortTy.getAsOpaquePtr();
737                }
738                else if (strstr(type_name, "char"))
739                {
740                    if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
741                        return ast->CharTy.getAsOpaquePtr();
742                    if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
743                        return ast->SignedCharTy.getAsOpaquePtr();
744                }
745                else if (strstr(type_name, "int"))
746                {
747                    if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
748                        return ast->IntTy.getAsOpaquePtr();
749                    if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
750                        return ast->Int128Ty.getAsOpaquePtr();
751                }
752                else if (streq(type_name, "wchar_t"))
753                {
754                    if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
755                        return ast->WCharTy.getAsOpaquePtr();
756                }
757            }
758            // We weren't able to match up a type name, just search by size
759            if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
760                return ast->CharTy.getAsOpaquePtr();
761            if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
762                return ast->ShortTy.getAsOpaquePtr();
763            if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
764                return ast->IntTy.getAsOpaquePtr();
765            if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
766                return ast->LongTy.getAsOpaquePtr();
767            if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
768                return ast->LongLongTy.getAsOpaquePtr();
769            if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
770                return ast->Int128Ty.getAsOpaquePtr();
771            break;
772
773        case DW_ATE_signed_char:
774            if (type_name)
775            {
776                if (streq(type_name, "signed char"))
777                {
778                    if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
779                        return ast->SignedCharTy.getAsOpaquePtr();
780                }
781            }
782            if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
783                return ast->CharTy.getAsOpaquePtr();
784            if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
785                return ast->SignedCharTy.getAsOpaquePtr();
786            break;
787
788        case DW_ATE_unsigned:
789            if (type_name)
790            {
791                if (strstr(type_name, "long long"))
792                {
793                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
794                        return ast->UnsignedLongLongTy.getAsOpaquePtr();
795                }
796                else if (strstr(type_name, "long"))
797                {
798                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
799                        return ast->UnsignedLongTy.getAsOpaquePtr();
800                }
801                else if (strstr(type_name, "short"))
802                {
803                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
804                        return ast->UnsignedShortTy.getAsOpaquePtr();
805                }
806                else if (strstr(type_name, "char"))
807                {
808                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
809                        return ast->UnsignedCharTy.getAsOpaquePtr();
810                }
811                else if (strstr(type_name, "int"))
812                {
813                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
814                        return ast->UnsignedIntTy.getAsOpaquePtr();
815                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
816                        return ast->UnsignedInt128Ty.getAsOpaquePtr();
817                }
818            }
819            // We weren't able to match up a type name, just search by size
820            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
821                return ast->UnsignedCharTy.getAsOpaquePtr();
822            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
823                return ast->UnsignedShortTy.getAsOpaquePtr();
824            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
825                return ast->UnsignedIntTy.getAsOpaquePtr();
826            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
827                return ast->UnsignedLongTy.getAsOpaquePtr();
828            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
829                return ast->UnsignedLongLongTy.getAsOpaquePtr();
830            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
831                return ast->UnsignedInt128Ty.getAsOpaquePtr();
832            break;
833
834        case DW_ATE_unsigned_char:
835            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
836                return ast->UnsignedCharTy.getAsOpaquePtr();
837            break;
838
839        case DW_ATE_imaginary_float:
840            break;
841        }
842    }
843    // This assert should fire for anything that we don't catch above so we know
844    // to fix any issues we run into.
845    assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
846    return NULL;
847}
848
849clang_type_t
850ClangASTContext::GetBuiltInType_void(ASTContext *ast)
851{
852    return ast->VoidTy.getAsOpaquePtr();
853}
854
855clang_type_t
856ClangASTContext::GetBuiltInType_bool()
857{
858    return getASTContext()->BoolTy.getAsOpaquePtr();
859}
860
861clang_type_t
862ClangASTContext::GetBuiltInType_objc_id()
863{
864    return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
865}
866
867clang_type_t
868ClangASTContext::GetBuiltInType_objc_Class()
869{
870    return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
871}
872
873clang_type_t
874ClangASTContext::GetBuiltInType_objc_selector()
875{
876    return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
877}
878
879clang_type_t
880ClangASTContext::GetCStringType (bool is_const)
881{
882    QualType char_type(getASTContext()->CharTy);
883
884    if (is_const)
885        char_type.addConst();
886
887    return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
888}
889
890clang_type_t
891ClangASTContext::GetVoidPtrType (bool is_const)
892{
893    return GetVoidPtrType(getASTContext(), is_const);
894}
895
896clang_type_t
897ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
898{
899    QualType void_ptr_type(ast->VoidPtrTy);
900
901    if (is_const)
902        void_ptr_type.addConst();
903
904    return void_ptr_type.getAsOpaquePtr();
905}
906
907clang_type_t
908ClangASTContext::CopyType (ASTContext *dst_ast,
909                           ASTContext *src_ast,
910                           clang_type_t clang_type)
911{
912    FileSystemOptions file_system_options;
913    FileManager file_manager (file_system_options);
914    ASTImporter importer(*dst_ast, file_manager,
915                         *src_ast, file_manager,
916                         false);
917
918    QualType src (QualType::getFromOpaquePtr(clang_type));
919    QualType dst (importer.Import(src));
920
921    return dst.getAsOpaquePtr();
922}
923
924
925clang::Decl *
926ClangASTContext::CopyDecl (ASTContext *dst_ast,
927                           ASTContext *src_ast,
928                           clang::Decl *source_decl)
929{
930    FileSystemOptions file_system_options;
931    FileManager file_manager (file_system_options);
932    ASTImporter importer(*dst_ast, file_manager,
933                         *src_ast, file_manager,
934                         false);
935
936    return importer.Import(source_decl);
937}
938
939bool
940ClangASTContext::AreTypesSame(ASTContext *ast,
941             clang_type_t type1,
942             clang_type_t type2)
943{
944    return ast->hasSameType(QualType::getFromOpaquePtr(type1),
945                                    QualType::getFromOpaquePtr(type2));
946}
947
948#pragma mark CVR modifiers
949
950clang_type_t
951ClangASTContext::AddConstModifier (clang_type_t clang_type)
952{
953    if (clang_type)
954    {
955        QualType result(QualType::getFromOpaquePtr(clang_type));
956        result.addConst();
957        return result.getAsOpaquePtr();
958    }
959    return NULL;
960}
961
962clang_type_t
963ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
964{
965    if (clang_type)
966    {
967        QualType result(QualType::getFromOpaquePtr(clang_type));
968        result.getQualifiers().setRestrict (true);
969        return result.getAsOpaquePtr();
970    }
971    return NULL;
972}
973
974clang_type_t
975ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
976{
977    if (clang_type)
978    {
979        QualType result(QualType::getFromOpaquePtr(clang_type));
980        result.getQualifiers().setVolatile (true);
981        return result.getAsOpaquePtr();
982    }
983    return NULL;
984}
985
986
987clang_type_t
988ClangASTContext::GetTypeForDecl (TagDecl *decl)
989{
990    // No need to call the getASTContext() accessor (which can create the AST
991    // if it isn't created yet, because we can't have created a decl in this
992    // AST if our AST didn't already exist...
993    if (m_ast_ap.get())
994        return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
995    return NULL;
996}
997
998clang_type_t
999ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
1000{
1001    // No need to call the getASTContext() accessor (which can create the AST
1002    // if it isn't created yet, because we can't have created a decl in this
1003    // AST if our AST didn't already exist...
1004    if (m_ast_ap.get())
1005        return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
1006    return NULL;
1007}
1008
1009#pragma mark Structure, Unions, Classes
1010
1011clang_type_t
1012ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
1013{
1014    ASTContext *ast = getASTContext();
1015    assert (ast != NULL);
1016
1017    if (decl_ctx == NULL)
1018        decl_ctx = ast->getTranslationUnitDecl();
1019
1020
1021    if (language == eLanguageTypeObjC)
1022    {
1023        bool isForwardDecl = true;
1024        bool isInternal = false;
1025        return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
1026    }
1027
1028    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1029    // we will need to update this code. I was told to currently always use
1030    // the CXXRecordDecl class since we often don't know from debug information
1031    // if something is struct or a class, so we default to always use the more
1032    // complete definition just in case.
1033    CXXRecordDecl *decl = CXXRecordDecl::Create(*ast,
1034                                                (TagDecl::TagKind)kind,
1035                                                decl_ctx,
1036                                                SourceLocation(),
1037                                                name && name[0] ? &ast->Idents.get(name) : NULL);
1038
1039    return ast->getTagDeclType(decl).getAsOpaquePtr();
1040}
1041
1042bool
1043ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
1044{
1045    if (clang_type == NULL)
1046        return false;
1047
1048    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1049
1050    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1051    switch (type_class)
1052    {
1053    case clang::Type::Record:
1054        {
1055            CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
1056            if (cxx_record_decl)
1057            {
1058                cxx_record_decl->setHasExternalLexicalStorage (has_extern);
1059                //cxx_record_decl->setHasExternalVisibleStorage (has_extern);
1060                return true;
1061            }
1062        }
1063        break;
1064
1065    case clang::Type::Enum:
1066        {
1067            EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
1068            if (enum_decl)
1069            {
1070                enum_decl->setHasExternalLexicalStorage (has_extern);
1071                //enum_decl->setHasExternalVisibleStorage (has_extern);
1072                return true;
1073            }
1074        }
1075        break;
1076
1077    case clang::Type::ObjCObject:
1078    case clang::Type::ObjCInterface:
1079        {
1080            ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1081            assert (objc_class_type);
1082            if (objc_class_type)
1083            {
1084                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1085
1086                if (class_interface_decl)
1087                {
1088                    class_interface_decl->setHasExternalLexicalStorage (has_extern);
1089                    //class_interface_decl->setHasExternalVisibleStorage (has_extern);
1090                    return true;
1091                }
1092            }
1093        }
1094        break;
1095
1096    case clang::Type::Typedef:
1097        return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
1098
1099    default:
1100        break;
1101    }
1102    return false;
1103}
1104
1105static bool
1106IsOperator (const char *name, OverloadedOperatorKind &op_kind)
1107{
1108    if (name == NULL || name[0] == '\0')
1109        return false;
1110
1111#define OPERATOR_PREFIX "operator"
1112#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
1113
1114    const char *post_op_name = NULL;
1115
1116    bool no_space = true;
1117
1118    if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
1119        return false;
1120
1121    post_op_name = name + OPERATOR_PREFIX_LENGTH;
1122
1123    if (post_op_name[0] == ' ')
1124    {
1125        post_op_name++;
1126        no_space = false;
1127    }
1128
1129#undef OPERATOR_PREFIX
1130#undef OPERATOR_PREFIX_LENGTH
1131
1132    // This is an operator, set the overloaded operator kind to invalid
1133    // in case this is a conversion operator...
1134    op_kind = NUM_OVERLOADED_OPERATORS;
1135
1136    switch (post_op_name[0])
1137    {
1138    default:
1139        if (no_space)
1140            return false;
1141        break;
1142    case 'n':
1143        if (no_space)
1144            return false;
1145        if  (strcmp (post_op_name, "new") == 0)
1146            op_kind = OO_New;
1147        else if (strcmp (post_op_name, "new[]") == 0)
1148            op_kind = OO_Array_New;
1149        break;
1150
1151    case 'd':
1152        if (no_space)
1153            return false;
1154        if (strcmp (post_op_name, "delete") == 0)
1155            op_kind = OO_Delete;
1156        else if (strcmp (post_op_name, "delete[]") == 0)
1157            op_kind = OO_Array_Delete;
1158        break;
1159
1160    case '+':
1161        if (post_op_name[1] == '\0')
1162            op_kind = OO_Plus;
1163        else if (post_op_name[2] == '\0')
1164        {
1165            if (post_op_name[1] == '=')
1166                op_kind = OO_PlusEqual;
1167            else if (post_op_name[1] == '+')
1168                op_kind = OO_PlusPlus;
1169        }
1170        break;
1171
1172    case '-':
1173        if (post_op_name[1] == '\0')
1174            op_kind = OO_Minus;
1175        else if (post_op_name[2] == '\0')
1176        {
1177            switch (post_op_name[1])
1178            {
1179            case '=': op_kind = OO_MinusEqual; break;
1180            case '-': op_kind = OO_MinusMinus; break;
1181            case '>': op_kind = OO_Arrow; break;
1182            }
1183        }
1184        else if (post_op_name[3] == '\0')
1185        {
1186            if (post_op_name[2] == '*')
1187                op_kind = OO_ArrowStar; break;
1188        }
1189        break;
1190
1191    case '*':
1192        if (post_op_name[1] == '\0')
1193            op_kind = OO_Star;
1194        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1195            op_kind = OO_StarEqual;
1196        break;
1197
1198    case '/':
1199        if (post_op_name[1] == '\0')
1200            op_kind = OO_Slash;
1201        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1202            op_kind = OO_SlashEqual;
1203        break;
1204
1205    case '%':
1206        if (post_op_name[1] == '\0')
1207            op_kind = OO_Percent;
1208        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1209            op_kind = OO_PercentEqual;
1210        break;
1211
1212
1213    case '^':
1214        if (post_op_name[1] == '\0')
1215            op_kind = OO_Caret;
1216        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1217            op_kind = OO_CaretEqual;
1218        break;
1219
1220    case '&':
1221        if (post_op_name[1] == '\0')
1222            op_kind = OO_Amp;
1223        else if (post_op_name[2] == '\0')
1224        {
1225            switch (post_op_name[1])
1226            {
1227            case '=': op_kind = OO_AmpEqual; break;
1228            case '&': op_kind = OO_AmpAmp; break;
1229            }
1230        }
1231        break;
1232
1233    case '|':
1234        if (post_op_name[1] == '\0')
1235            op_kind = OO_Pipe;
1236        else if (post_op_name[2] == '\0')
1237        {
1238            switch (post_op_name[1])
1239            {
1240            case '=': op_kind = OO_PipeEqual; break;
1241            case '|': op_kind = OO_PipePipe; break;
1242            }
1243        }
1244        break;
1245
1246    case '~':
1247        if (post_op_name[1] == '\0')
1248            op_kind = OO_Tilde;
1249        break;
1250
1251    case '!':
1252        if (post_op_name[1] == '\0')
1253            op_kind = OO_Exclaim;
1254        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1255            op_kind = OO_ExclaimEqual;
1256        break;
1257
1258    case '=':
1259        if (post_op_name[1] == '\0')
1260            op_kind = OO_Equal;
1261        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1262            op_kind = OO_EqualEqual;
1263        break;
1264
1265    case '<':
1266        if (post_op_name[1] == '\0')
1267            op_kind = OO_Less;
1268        else if (post_op_name[2] == '\0')
1269        {
1270            switch (post_op_name[1])
1271            {
1272            case '<': op_kind = OO_LessLess; break;
1273            case '=': op_kind = OO_LessEqual; break;
1274            }
1275        }
1276        else if (post_op_name[3] == '\0')
1277        {
1278            if (post_op_name[2] == '=')
1279                op_kind = OO_LessLessEqual;
1280        }
1281        break;
1282
1283    case '>':
1284        if (post_op_name[1] == '\0')
1285            op_kind = OO_Greater;
1286        else if (post_op_name[2] == '\0')
1287        {
1288            switch (post_op_name[1])
1289            {
1290            case '>': op_kind = OO_GreaterGreater; break;
1291            case '=': op_kind = OO_GreaterEqual; break;
1292            }
1293        }
1294        else if (post_op_name[1] == '>' &&
1295                 post_op_name[2] == '=' &&
1296                 post_op_name[3] == '\0')
1297        {
1298                op_kind = OO_GreaterGreaterEqual;
1299        }
1300        break;
1301
1302    case ',':
1303        if (post_op_name[1] == '\0')
1304            op_kind = OO_Comma;
1305        break;
1306
1307    case '(':
1308        if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1309            op_kind = OO_Call;
1310        break;
1311
1312    case '[':
1313        if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1314            op_kind = OO_Subscript;
1315        break;
1316    }
1317
1318    return true;
1319}
1320
1321CXXMethodDecl *
1322ClangASTContext::AddMethodToCXXRecordType
1323(
1324    ASTContext *ast,
1325    clang_type_t record_opaque_type,
1326    const char *name,
1327    clang_type_t method_opaque_type,
1328    lldb::AccessType access,
1329    bool is_virtual,
1330    bool is_static,
1331    bool is_inline,
1332    bool is_explicit
1333)
1334{
1335    if (!record_opaque_type || !method_opaque_type || !name)
1336        return NULL;
1337
1338    assert(ast);
1339
1340    IdentifierTable *identifier_table = &ast->Idents;
1341
1342    assert(identifier_table);
1343
1344    QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
1345
1346    CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
1347
1348    if (cxx_record_decl == NULL)
1349        return NULL;
1350
1351    QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1352
1353    CXXMethodDecl *cxx_method_decl = NULL;
1354
1355    DeclarationName decl_name (&identifier_table->get(name));
1356
1357    const bool is_implicitly_declared = false;
1358
1359    clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
1360
1361    if (function_Type == NULL)
1362        return NULL;
1363
1364    FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
1365
1366    if (!method_function_prototype)
1367        return NULL;
1368
1369    unsigned int num_params = method_function_prototype->getNumArgs();
1370
1371    if (name[0] == '~')
1372    {
1373        cxx_method_decl = CXXDestructorDecl::Create (*ast,
1374                                                     cxx_record_decl,
1375                                                     DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
1376                                                     method_qual_type,
1377                                                     NULL,
1378                                                     is_inline,
1379                                                     is_implicitly_declared);
1380    }
1381    else if (decl_name == cxx_record_decl->getDeclName())
1382    {
1383        cxx_method_decl = CXXConstructorDecl::Create (*ast,
1384                                                      cxx_record_decl,
1385                                                      DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
1386                                                      method_qual_type,
1387                                                      NULL, // TypeSourceInfo *
1388                                                      is_explicit,
1389                                                      is_inline,
1390                                                      is_implicitly_declared);
1391    }
1392    else
1393    {
1394
1395        OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1396        if (IsOperator (name, op_kind))
1397        {
1398            if (op_kind != NUM_OVERLOADED_OPERATORS)
1399            {
1400                cxx_method_decl = CXXMethodDecl::Create (*ast,
1401                                                         cxx_record_decl,
1402                                                         DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
1403                                                         method_qual_type,
1404                                                         NULL, // TypeSourceInfo *
1405                                                         is_static,
1406                                                         SC_None,
1407                                                         is_inline);
1408            }
1409            else if (num_params == 0)
1410            {
1411                // Conversion operators don't take params...
1412                cxx_method_decl = CXXConversionDecl::Create (*ast,
1413                                                             cxx_record_decl,
1414                                                             DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
1415                                                             method_qual_type,
1416                                                             NULL, // TypeSourceInfo *
1417                                                             is_inline,
1418                                                             is_explicit);
1419            }
1420        }
1421
1422        if (cxx_method_decl == NULL)
1423        {
1424            cxx_method_decl = CXXMethodDecl::Create (*ast,
1425                                                     cxx_record_decl,
1426                                                     DeclarationNameInfo (decl_name, SourceLocation()),
1427                                                     method_qual_type,
1428                                                     NULL, // TypeSourceInfo *
1429                                                     is_static,
1430                                                     SC_None,
1431                                                     is_inline);
1432        }
1433    }
1434
1435    AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
1436
1437    cxx_method_decl->setAccess (access_specifier);
1438    cxx_method_decl->setVirtualAsWritten (is_virtual);
1439
1440    // Populate the method decl with parameter decls
1441
1442    ParmVarDecl *params[num_params];
1443
1444    for (int param_index = 0;
1445         param_index < num_params;
1446         ++param_index)
1447    {
1448        params[param_index] = ParmVarDecl::Create (*ast,
1449                                                   cxx_method_decl,
1450                                                   SourceLocation(),
1451                                                   NULL, // anonymous
1452                                                   method_function_prototype->getArgType(param_index),
1453                                                   NULL,
1454                                                   SC_None,
1455                                                   SC_None,
1456                                                   NULL);
1457    }
1458
1459    cxx_method_decl->setParams (params, num_params);
1460
1461    cxx_record_decl->addDecl (cxx_method_decl);
1462
1463    return cxx_method_decl;
1464}
1465
1466bool
1467ClangASTContext::AddFieldToRecordType
1468(
1469    ASTContext *ast,
1470    clang_type_t record_clang_type,
1471    const char *name,
1472    clang_type_t field_type,
1473    AccessType access,
1474    uint32_t bitfield_bit_size
1475)
1476{
1477    if (record_clang_type == NULL || field_type == NULL)
1478        return false;
1479
1480    IdentifierTable *identifier_table = &ast->Idents;
1481
1482    assert (ast != NULL);
1483    assert (identifier_table != NULL);
1484
1485    QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1486
1487    clang::Type *clang_type = record_qual_type.getTypePtr();
1488    if (clang_type)
1489    {
1490        const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1491
1492        if (record_type)
1493        {
1494            RecordDecl *record_decl = record_type->getDecl();
1495
1496            clang::Expr *bit_width = NULL;
1497            if (bitfield_bit_size != 0)
1498            {
1499                APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1500                bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
1501            }
1502            FieldDecl *field = FieldDecl::Create (*ast,
1503                                                  record_decl,
1504                                                  SourceLocation(),
1505                                                  name ? &identifier_table->get(name) : NULL, // Identifier
1506                                                  QualType::getFromOpaquePtr(field_type), // Field type
1507                                                  NULL,       // DeclaratorInfo *
1508                                                  bit_width,  // BitWidth
1509                                                  false);     // Mutable
1510
1511            field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
1512
1513            if (field)
1514            {
1515                record_decl->addDecl(field);
1516            }
1517        }
1518        else
1519        {
1520            ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1521            if (objc_class_type)
1522            {
1523                bool is_synthesized = false;
1524                ClangASTContext::AddObjCClassIVar (ast,
1525                                                   record_clang_type,
1526                                                   name,
1527                                                   field_type,
1528                                                   access,
1529                                                   bitfield_bit_size,
1530                                                   is_synthesized);
1531            }
1532        }
1533    }
1534    return false;
1535}
1536
1537bool
1538ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1539{
1540    return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1541}
1542
1543bool
1544ClangASTContext::FieldIsBitfield
1545(
1546    ASTContext *ast,
1547    FieldDecl* field,
1548    uint32_t& bitfield_bit_size
1549)
1550{
1551    if (ast == NULL || field == NULL)
1552        return false;
1553
1554    if (field->isBitField())
1555    {
1556        Expr* bit_width_expr = field->getBitWidth();
1557        if (bit_width_expr)
1558        {
1559            llvm::APSInt bit_width_apsint;
1560            if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
1561            {
1562                bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1563                return true;
1564            }
1565        }
1566    }
1567    return false;
1568}
1569
1570bool
1571ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1572{
1573    if (record_decl == NULL)
1574        return false;
1575
1576    if (!record_decl->field_empty())
1577        return true;
1578
1579    // No fields, lets check this is a CXX record and check the base classes
1580    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1581    if (cxx_record_decl)
1582    {
1583        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1584        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1585             base_class != base_class_end;
1586             ++base_class)
1587        {
1588            const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1589            if (RecordHasFields(base_class_decl))
1590                return true;
1591        }
1592    }
1593    return false;
1594}
1595
1596void
1597ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
1598{
1599    if (clang_type)
1600    {
1601        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1602
1603        RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
1604        if (record_type)
1605        {
1606            RecordDecl *record_decl = record_type->getDecl();
1607            if (record_decl)
1608            {
1609                uint32_t field_idx;
1610                RecordDecl::field_iterator field, field_end;
1611                for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1612                     field != field_end;
1613                     ++field, ++field_idx)
1614                {
1615                    // If no accessibility was assigned, assign the correct one
1616                    if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1617                        field->setAccess ((AccessSpecifier)default_accessibility);
1618                }
1619            }
1620        }
1621    }
1622}
1623
1624#pragma mark C++ Base Classes
1625
1626CXXBaseSpecifier *
1627ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
1628{
1629    if (base_class_type)
1630        return new CXXBaseSpecifier (SourceRange(),
1631                                     is_virtual,
1632                                     base_of_class,
1633                                     ConvertAccessTypeToAccessSpecifier (access),
1634                                     getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
1635                                     SourceLocation());
1636    return NULL;
1637}
1638
1639void
1640ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1641{
1642    for (unsigned i=0; i<num_base_classes; ++i)
1643    {
1644        delete base_classes[i];
1645        base_classes[i] = NULL;
1646    }
1647}
1648
1649bool
1650ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
1651{
1652    if (class_clang_type)
1653    {
1654        CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
1655        if (cxx_record_decl)
1656        {
1657            cxx_record_decl->setBases(base_classes, num_base_classes);
1658            return true;
1659        }
1660    }
1661    return false;
1662}
1663#pragma mark Objective C Classes
1664
1665clang_type_t
1666ClangASTContext::CreateObjCClass
1667(
1668    const char *name,
1669    DeclContext *decl_ctx,
1670    bool isForwardDecl,
1671    bool isInternal
1672)
1673{
1674    ASTContext *ast = getASTContext();
1675    assert (ast != NULL);
1676    assert (name && name[0]);
1677    if (decl_ctx == NULL)
1678        decl_ctx = ast->getTranslationUnitDecl();
1679
1680    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1681    // we will need to update this code. I was told to currently always use
1682    // the CXXRecordDecl class since we often don't know from debug information
1683    // if something is struct or a class, so we default to always use the more
1684    // complete definition just in case.
1685    ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
1686                                                         decl_ctx,
1687                                                         SourceLocation(),
1688                                                         &ast->Idents.get(name),
1689                                                         SourceLocation(),
1690                                                         isForwardDecl,
1691                                                         isInternal);
1692
1693    return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
1694}
1695
1696bool
1697ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
1698{
1699    if (class_opaque_type && super_opaque_type)
1700    {
1701        QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1702        QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1703        clang::Type *class_type = class_qual_type.getTypePtr();
1704        clang::Type *super_type = super_qual_type.getTypePtr();
1705        if (class_type && super_type)
1706        {
1707            ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1708            ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1709            if (objc_class_type && objc_super_type)
1710            {
1711                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1712                ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1713                if (class_interface_decl && super_interface_decl)
1714                {
1715                    class_interface_decl->setSuperClass(super_interface_decl);
1716                    return true;
1717                }
1718            }
1719        }
1720    }
1721    return false;
1722}
1723
1724
1725bool
1726ClangASTContext::AddObjCClassIVar
1727(
1728    ASTContext *ast,
1729    clang_type_t class_opaque_type,
1730    const char *name,
1731    clang_type_t ivar_opaque_type,
1732    AccessType access,
1733    uint32_t bitfield_bit_size,
1734    bool is_synthesized
1735)
1736{
1737    if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1738        return false;
1739
1740    IdentifierTable *identifier_table = &ast->Idents;
1741
1742    assert (ast != NULL);
1743    assert (identifier_table != NULL);
1744
1745    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1746
1747    clang::Type *class_type = class_qual_type.getTypePtr();
1748    if (class_type)
1749    {
1750        ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1751
1752        if (objc_class_type)
1753        {
1754            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1755
1756            if (class_interface_decl)
1757            {
1758                clang::Expr *bit_width = NULL;
1759                if (bitfield_bit_size != 0)
1760                {
1761                    APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1762                    bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
1763                }
1764
1765                ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast,
1766                                                            class_interface_decl,
1767                                                            SourceLocation(),
1768                                                            &identifier_table->get(name), // Identifier
1769                                                            QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1770                                                            NULL, // TypeSourceInfo *
1771                                                            ConvertAccessTypeToObjCIvarAccessControl (access),
1772                                                            bit_width,
1773                                                            is_synthesized);
1774
1775                if (field)
1776                {
1777                    class_interface_decl->addDecl(field);
1778                    return true;
1779                }
1780            }
1781        }
1782    }
1783    return false;
1784}
1785
1786
1787bool
1788ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
1789{
1790    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1791
1792    clang::Type *class_type = class_qual_type.getTypePtr();
1793    if (class_type)
1794    {
1795        ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1796
1797        if (objc_class_type)
1798            return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1799    }
1800    return false;
1801}
1802
1803bool
1804ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1805{
1806    while (class_interface_decl)
1807    {
1808        if (class_interface_decl->ivar_size() > 0)
1809            return true;
1810
1811        if (check_superclass)
1812            class_interface_decl = class_interface_decl->getSuperClass();
1813        else
1814            break;
1815    }
1816    return false;
1817}
1818
1819ObjCMethodDecl *
1820ClangASTContext::AddMethodToObjCObjectType
1821(
1822    ASTContext *ast,
1823    clang_type_t class_opaque_type,
1824    const char *name,  // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
1825    clang_type_t method_opaque_type,
1826    lldb::AccessType access
1827)
1828{
1829    if (class_opaque_type == NULL || method_opaque_type == NULL)
1830        return NULL;
1831
1832    IdentifierTable *identifier_table = &ast->Idents;
1833
1834    assert (ast != NULL);
1835    assert (identifier_table != NULL);
1836
1837    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1838
1839    clang::Type *class_type = class_qual_type.getTypePtr();
1840    if (class_type == NULL)
1841        return NULL;
1842
1843    ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1844
1845    if (objc_class_type == NULL)
1846        return NULL;
1847
1848    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1849
1850    if (class_interface_decl == NULL)
1851        return NULL;
1852
1853    const char *selector_start = ::strchr (name, ' ');
1854    if (selector_start == NULL)
1855        return NULL;
1856
1857    selector_start++;
1858    if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1859        return NULL;
1860    llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1861
1862    size_t len = 0;
1863    const char *start;
1864    //printf ("name = '%s'\n", name);
1865
1866    unsigned num_selectors_with_args = 0;
1867    for (start = selector_start;
1868         start && *start != '\0' && *start != ']';
1869         start += len)
1870    {
1871        len = ::strcspn(start, ":]");
1872        bool has_arg = (start[len] == ':');
1873        if (has_arg)
1874            ++num_selectors_with_args;
1875        selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
1876        if (has_arg)
1877            len += 1;
1878    }
1879
1880
1881    if (selector_idents.size() == 0)
1882        return 0;
1883
1884    clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
1885                                                                          selector_idents.data());
1886
1887    QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1888
1889    // Populate the method decl with parameter decls
1890    clang::Type *method_type(method_qual_type.getTypePtr());
1891
1892    if (method_type == NULL)
1893        return NULL;
1894
1895    FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1896
1897    if (!method_function_prototype)
1898        return NULL;
1899
1900
1901    bool is_variadic = false;
1902    bool is_synthesized = false;
1903    bool is_defined = false;
1904    ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1905
1906    const unsigned num_args = method_function_prototype->getNumArgs();
1907
1908    ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
1909                                                               SourceLocation(), // beginLoc,
1910                                                               SourceLocation(), // endLoc,
1911                                                               method_selector,
1912                                                               method_function_prototype->getResultType(),
1913                                                               NULL, // TypeSourceInfo *ResultTInfo,
1914                                                               GetDeclContextForType (class_opaque_type),
1915                                                               name[0] == '-',
1916                                                               is_variadic,
1917                                                               is_synthesized,
1918                                                               is_defined,
1919                                                               imp_control,
1920                                                               num_args);
1921
1922
1923    if (objc_method_decl == NULL)
1924        return NULL;
1925
1926    if (num_args > 0)
1927    {
1928        llvm::SmallVector<ParmVarDecl *, 12> params;
1929
1930        for (int param_index = 0; param_index < num_args; ++param_index)
1931        {
1932            params.push_back (ParmVarDecl::Create (*ast,
1933                                                   objc_method_decl,
1934                                                   SourceLocation(),
1935                                                   NULL, // anonymous
1936                                                   method_function_prototype->getArgType(param_index),
1937                                                   NULL,
1938                                                   SC_Auto,
1939                                                   SC_Auto,
1940                                                   NULL));
1941        }
1942
1943        objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args);
1944    }
1945
1946    class_interface_decl->addDecl (objc_method_decl);
1947
1948
1949    return objc_method_decl;
1950}
1951
1952
1953uint32_t
1954ClangASTContext::GetTypeInfo
1955(
1956    clang_type_t clang_type,
1957    clang::ASTContext *ast,
1958    clang_type_t *pointee_or_element_clang_type
1959)
1960{
1961    if (clang_type == NULL)
1962        return 0;
1963
1964    if (pointee_or_element_clang_type)
1965        *pointee_or_element_clang_type = NULL;
1966
1967    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1968
1969    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1970    switch (type_class)
1971    {
1972    case clang::Type::Builtin:
1973        switch (cast<clang::BuiltinType>(qual_type)->getKind())
1974        {
1975        case clang::BuiltinType::ObjCId:
1976        case clang::BuiltinType::ObjCClass:
1977            if (ast && pointee_or_element_clang_type)
1978                *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
1979            return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
1980
1981        default:
1982            break;
1983        }
1984        return eTypeIsBuiltIn | eTypeHasValue;
1985
1986    case clang::Type::BlockPointer:
1987        if (pointee_or_element_clang_type)
1988            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1989        return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1990
1991    case clang::Type::Complex:                          return eTypeIsBuiltIn | eTypeHasValue;
1992
1993    case clang::Type::ConstantArray:
1994    case clang::Type::DependentSizedArray:
1995    case clang::Type::IncompleteArray:
1996    case clang::Type::VariableArray:
1997        if (pointee_or_element_clang_type)
1998            *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1999        return eTypeHasChildren | eTypeIsArray;
2000
2001    case clang::Type::DependentName:                    return 0;
2002    case clang::Type::DependentSizedExtVector:          return eTypeHasChildren | eTypeIsVector;
2003    case clang::Type::DependentTemplateSpecialization:  return eTypeIsTemplate;
2004    case clang::Type::Decltype:                         return 0;
2005
2006    case clang::Type::Enum:
2007        if (pointee_or_element_clang_type)
2008            *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
2009        return eTypeIsEnumeration | eTypeHasValue;
2010
2011    case clang::Type::Elaborated:                       return 0;
2012    case clang::Type::ExtVector:                        return eTypeHasChildren | eTypeIsVector;
2013    case clang::Type::FunctionProto:                    return eTypeIsFuncPrototype | eTypeHasValue;
2014    case clang::Type::FunctionNoProto:                  return eTypeIsFuncPrototype | eTypeHasValue;
2015    case clang::Type::InjectedClassName:                return 0;
2016
2017    case clang::Type::LValueReference:
2018    case clang::Type::RValueReference:
2019        if (pointee_or_element_clang_type)
2020            *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
2021        return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
2022
2023    case clang::Type::MemberPointer:                    return eTypeIsPointer   | eTypeIsMember | eTypeHasValue;
2024
2025    case clang::Type::ObjCObjectPointer:
2026        if (pointee_or_element_clang_type)
2027            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2028        return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
2029
2030    case clang::Type::ObjCObject:                       return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2031    case clang::Type::ObjCInterface:                    return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2032
2033    case clang::Type::Pointer:
2034        if (pointee_or_element_clang_type)
2035            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2036        return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
2037
2038    case clang::Type::Record:
2039        if (qual_type->getAsCXXRecordDecl())
2040            return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
2041        else
2042            return eTypeHasChildren | eTypeIsStructUnion;
2043        break;
2044    case clang::Type::SubstTemplateTypeParm:            return eTypeIsTemplate;
2045    case clang::Type::TemplateTypeParm:                 return eTypeIsTemplate;
2046    case clang::Type::TemplateSpecialization:           return eTypeIsTemplate;
2047
2048    case clang::Type::Typedef:
2049        return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2050                                                                  ast,
2051                                                                  pointee_or_element_clang_type);
2052
2053    case clang::Type::TypeOfExpr:                       return 0;
2054    case clang::Type::TypeOf:                           return 0;
2055    case clang::Type::UnresolvedUsing:                  return 0;
2056    case clang::Type::Vector:                           return eTypeHasChildren | eTypeIsVector;
2057    default:                                            return 0;
2058    }
2059    return 0;
2060}
2061
2062
2063#pragma mark Aggregate Types
2064
2065bool
2066ClangASTContext::IsAggregateType (clang_type_t clang_type)
2067{
2068    if (clang_type == NULL)
2069        return false;
2070
2071    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2072
2073    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2074    switch (type_class)
2075    {
2076    case clang::Type::IncompleteArray:
2077    case clang::Type::VariableArray:
2078    case clang::Type::ConstantArray:
2079    case clang::Type::ExtVector:
2080    case clang::Type::Vector:
2081    case clang::Type::Record:
2082    case clang::Type::ObjCObject:
2083    case clang::Type::ObjCInterface:
2084        return true;
2085
2086    case clang::Type::Typedef:
2087        return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2088
2089    default:
2090        break;
2091    }
2092    // The clang type does have a value
2093    return false;
2094}
2095
2096uint32_t
2097ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
2098{
2099    if (clang_type == NULL)
2100        return 0;
2101
2102    uint32_t num_children = 0;
2103    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2104    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2105    switch (type_class)
2106    {
2107    case clang::Type::Builtin:
2108        switch (cast<clang::BuiltinType>(qual_type)->getKind())
2109        {
2110        case clang::BuiltinType::ObjCId:    // child is Class
2111        case clang::BuiltinType::ObjCClass: // child is Class
2112            num_children = 1;
2113            break;
2114
2115        default:
2116            break;
2117        }
2118        break;
2119
2120    case clang::Type::Complex: return 0;
2121
2122    case clang::Type::Record:
2123        if (ClangASTContext::GetCompleteType (ast, clang_type))
2124        {
2125            const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2126            const RecordDecl *record_decl = record_type->getDecl();
2127            assert(record_decl);
2128            const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2129            if (cxx_record_decl)
2130            {
2131                if (omit_empty_base_classes)
2132                {
2133                    // Check each base classes to see if it or any of its
2134                    // base classes contain any fields. This can help
2135                    // limit the noise in variable views by not having to
2136                    // show base classes that contain no members.
2137                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2138                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2139                         base_class != base_class_end;
2140                         ++base_class)
2141                    {
2142                        const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2143
2144                        // Skip empty base classes
2145                        if (RecordHasFields(base_class_decl) == false)
2146                            continue;
2147
2148                        num_children++;
2149                    }
2150                }
2151                else
2152                {
2153                    // Include all base classes
2154                    num_children += cxx_record_decl->getNumBases();
2155                }
2156
2157            }
2158            RecordDecl::field_iterator field, field_end;
2159            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2160                ++num_children;
2161        }
2162        break;
2163
2164    case clang::Type::ObjCObject:
2165    case clang::Type::ObjCInterface:
2166        {
2167            ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2168            assert (objc_class_type);
2169            if (objc_class_type)
2170            {
2171                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2172
2173                if (class_interface_decl)
2174                {
2175
2176                    ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2177                    if (superclass_interface_decl)
2178                    {
2179                        if (omit_empty_base_classes)
2180                        {
2181                            if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2182                                ++num_children;
2183                        }
2184                        else
2185                            ++num_children;
2186                    }
2187
2188                    num_children += class_interface_decl->ivar_size();
2189                }
2190            }
2191        }
2192        break;
2193
2194    case clang::Type::ObjCObjectPointer:
2195        {
2196            ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
2197            QualType pointee_type = pointer_type->getPointeeType();
2198            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2199                                                                             pointee_type.getAsOpaquePtr(),
2200                                                                             omit_empty_base_classes);
2201            // If this type points to a simple type, then it has 1 child
2202            if (num_pointee_children == 0)
2203                num_children = 1;
2204            else
2205                num_children = num_pointee_children;
2206        }
2207        break;
2208
2209    case clang::Type::ConstantArray:
2210        num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2211        break;
2212
2213    case clang::Type::Pointer:
2214        {
2215            PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2216            QualType pointee_type (pointer_type->getPointeeType());
2217            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2218                                                                             pointee_type.getAsOpaquePtr(),
2219                                                                             omit_empty_base_classes);
2220            if (num_pointee_children == 0)
2221            {
2222                // We have a pointer to a pointee type that claims it has no children.
2223                // We will want to look at
2224                num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
2225            }
2226            else
2227                num_children = num_pointee_children;
2228        }
2229        break;
2230
2231    case clang::Type::LValueReference:
2232    case clang::Type::RValueReference:
2233        {
2234            ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2235            QualType pointee_type = reference_type->getPointeeType();
2236            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2237                                                                             pointee_type.getAsOpaquePtr(),
2238                                                                             omit_empty_base_classes);
2239            // If this type points to a simple type, then it has 1 child
2240            if (num_pointee_children == 0)
2241                num_children = 1;
2242            else
2243                num_children = num_pointee_children;
2244        }
2245        break;
2246
2247
2248    case clang::Type::Typedef:
2249        num_children = ClangASTContext::GetNumChildren (ast,
2250                                                        cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2251                                                        omit_empty_base_classes);
2252        break;
2253
2254    default:
2255        break;
2256    }
2257    return num_children;
2258}
2259
2260// If a pointer to a pointee type (the clang_type arg) says that it has no
2261// children, then we either need to trust it, or override it and return a
2262// different result. For example, an "int *" has one child that is an integer,
2263// but a function pointer doesn't have any children. Likewise if a Record type
2264// claims it has no children, then there really is nothing to show.
2265uint32_t
2266ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
2267{
2268    if (clang_type == NULL)
2269        return 0;
2270
2271    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2272    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2273    switch (type_class)
2274    {
2275    case clang::Type::Builtin:
2276        switch (cast<clang::BuiltinType>(qual_type)->getKind())
2277        {
2278        case clang::BuiltinType::Void:
2279        case clang::BuiltinType::NullPtr:
2280            return 0;
2281        case clang::BuiltinType::Bool:
2282        case clang::BuiltinType::Char_U:
2283        case clang::BuiltinType::UChar:
2284        case clang::BuiltinType::WChar_U:
2285        case clang::BuiltinType::Char16:
2286        case clang::BuiltinType::Char32:
2287        case clang::BuiltinType::UShort:
2288        case clang::BuiltinType::UInt:
2289        case clang::BuiltinType::ULong:
2290        case clang::BuiltinType::ULongLong:
2291        case clang::BuiltinType::UInt128:
2292        case clang::BuiltinType::Char_S:
2293        case clang::BuiltinType::SChar:
2294        case clang::BuiltinType::WChar_S:
2295        case clang::BuiltinType::Short:
2296        case clang::BuiltinType::Int:
2297        case clang::BuiltinType::Long:
2298        case clang::BuiltinType::LongLong:
2299        case clang::BuiltinType::Int128:
2300        case clang::BuiltinType::Float:
2301        case clang::BuiltinType::Double:
2302        case clang::BuiltinType::LongDouble:
2303        case clang::BuiltinType::Dependent:
2304        case clang::BuiltinType::Overload:
2305        case clang::BuiltinType::UndeducedAuto:
2306        case clang::BuiltinType::ObjCId:
2307        case clang::BuiltinType::ObjCClass:
2308        case clang::BuiltinType::ObjCSel:
2309            return 1;
2310        }
2311        break;
2312
2313    case clang::Type::Complex:                  return 1;
2314    case clang::Type::Pointer:                  return 1;
2315    case clang::Type::BlockPointer:             return 0;   // If block pointers don't have debug info, then no children for them
2316    case clang::Type::LValueReference:          return 1;
2317    case clang::Type::RValueReference:          return 1;
2318    case clang::Type::MemberPointer:            return 0;
2319    case clang::Type::ConstantArray:            return 0;
2320    case clang::Type::IncompleteArray:          return 0;
2321    case clang::Type::VariableArray:            return 0;
2322    case clang::Type::DependentSizedArray:      return 0;
2323    case clang::Type::DependentSizedExtVector:  return 0;
2324    case clang::Type::Vector:                   return 0;
2325    case clang::Type::ExtVector:                return 0;
2326    case clang::Type::FunctionProto:            return 0;   // When we function pointers, they have no children...
2327    case clang::Type::FunctionNoProto:          return 0;   // When we function pointers, they have no children...
2328    case clang::Type::UnresolvedUsing:          return 0;
2329    case clang::Type::Paren:                    return 0;
2330    case clang::Type::Typedef:                  return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2331    case clang::Type::TypeOfExpr:               return 0;
2332    case clang::Type::TypeOf:                   return 0;
2333    case clang::Type::Decltype:                 return 0;
2334    case clang::Type::Record:                   return 0;
2335    case clang::Type::Enum:                     return 1;
2336    case clang::Type::Elaborated:               return 1;
2337    case clang::Type::TemplateTypeParm:         return 1;
2338    case clang::Type::SubstTemplateTypeParm:    return 1;
2339    case clang::Type::TemplateSpecialization:   return 1;
2340    case clang::Type::InjectedClassName:        return 0;
2341    case clang::Type::DependentName:            return 1;
2342    case clang::Type::DependentTemplateSpecialization:  return 1;
2343    case clang::Type::ObjCObject:               return 0;
2344    case clang::Type::ObjCInterface:            return 0;
2345    case clang::Type::ObjCObjectPointer:        return 1;
2346    default:
2347        break;
2348    }
2349    return 0;
2350}
2351
2352clang_type_t
2353ClangASTContext::GetChildClangTypeAtIndex
2354(
2355    const char *parent_name,
2356    clang_type_t parent_clang_type,
2357    uint32_t idx,
2358    bool transparent_pointers,
2359    bool omit_empty_base_classes,
2360    std::string& child_name,
2361    uint32_t &child_byte_size,
2362    int32_t &child_byte_offset,
2363    uint32_t &child_bitfield_bit_size,
2364    uint32_t &child_bitfield_bit_offset,
2365    bool &child_is_base_class
2366)
2367{
2368    if (parent_clang_type)
2369
2370        return GetChildClangTypeAtIndex (getASTContext(),
2371                                         parent_name,
2372                                         parent_clang_type,
2373                                         idx,
2374                                         transparent_pointers,
2375                                         omit_empty_base_classes,
2376                                         child_name,
2377                                         child_byte_size,
2378                                         child_byte_offset,
2379                                         child_bitfield_bit_size,
2380                                         child_bitfield_bit_offset,
2381                                         child_is_base_class);
2382    return NULL;
2383}
2384
2385clang_type_t
2386ClangASTContext::GetChildClangTypeAtIndex
2387(
2388    ASTContext *ast,
2389    const char *parent_name,
2390    clang_type_t parent_clang_type,
2391    uint32_t idx,
2392    bool transparent_pointers,
2393    bool omit_empty_base_classes,
2394    std::string& child_name,
2395    uint32_t &child_byte_size,
2396    int32_t &child_byte_offset,
2397    uint32_t &child_bitfield_bit_size,
2398    uint32_t &child_bitfield_bit_offset,
2399    bool &child_is_base_class
2400)
2401{
2402    if (parent_clang_type == NULL)
2403        return NULL;
2404
2405    if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
2406    {
2407        uint32_t bit_offset;
2408        child_bitfield_bit_size = 0;
2409        child_bitfield_bit_offset = 0;
2410        child_is_base_class = false;
2411        QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
2412        const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2413        switch (parent_type_class)
2414        {
2415        case clang::Type::Builtin:
2416            switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2417            {
2418            case clang::BuiltinType::ObjCId:
2419            case clang::BuiltinType::ObjCClass:
2420                child_name = "isa";
2421                child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
2422                return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
2423
2424            default:
2425                break;
2426            }
2427            break;
2428
2429        case clang::Type::Record:
2430            if (ClangASTContext::GetCompleteType (ast, parent_clang_type))
2431            {
2432                const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2433                const RecordDecl *record_decl = record_type->getDecl();
2434                assert(record_decl);
2435                const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
2436                uint32_t child_idx = 0;
2437
2438                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2439                if (cxx_record_decl)
2440                {
2441                    // We might have base classes to print out first
2442                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2443                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2444                         base_class != base_class_end;
2445                         ++base_class)
2446                    {
2447                        const CXXRecordDecl *base_class_decl = NULL;
2448
2449                        // Skip empty base classes
2450                        if (omit_empty_base_classes)
2451                        {
2452                            base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2453                            if (RecordHasFields(base_class_decl) == false)
2454                                continue;
2455                        }
2456
2457                        if (idx == child_idx)
2458                        {
2459                            if (base_class_decl == NULL)
2460                                base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2461
2462
2463                            if (base_class->isVirtual())
2464                                bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
2465                            else
2466                                bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
2467
2468                            // Base classes should be a multiple of 8 bits in size
2469                            assert (bit_offset % 8 == 0);
2470                            child_byte_offset = bit_offset/8;
2471                            std::string base_class_type_name(base_class->getType().getAsString());
2472
2473                            child_name.assign(base_class_type_name.c_str());
2474
2475                            uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
2476
2477                            // Base classes biut sizes should be a multiple of 8 bits in size
2478                            assert (clang_type_info_bit_size % 8 == 0);
2479                            child_byte_size = clang_type_info_bit_size / 8;
2480                            child_is_base_class = true;
2481                            return base_class->getType().getAsOpaquePtr();
2482                        }
2483                        // We don't increment the child index in the for loop since we might
2484                        // be skipping empty base classes
2485                        ++child_idx;
2486                    }
2487                }
2488                // Make sure index is in range...
2489                uint32_t field_idx = 0;
2490                RecordDecl::field_iterator field, field_end;
2491                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2492                {
2493                    if (idx == child_idx)
2494                    {
2495                        // Print the member type if requested
2496                        // Print the member name and equal sign
2497                        child_name.assign(field->getNameAsString().c_str());
2498
2499                        // Figure out the type byte size (field_type_info.first) and
2500                        // alignment (field_type_info.second) from the AST context.
2501                        std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
2502                        assert(field_idx < record_layout.getFieldCount());
2503
2504                        child_byte_size = field_type_info.first / 8;
2505
2506                        // Figure out the field offset within the current struct/union/class type
2507                        bit_offset = record_layout.getFieldOffset (field_idx);
2508                        child_byte_offset = bit_offset / 8;
2509                        if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
2510                            child_bitfield_bit_offset = bit_offset % 8;
2511
2512                        return field->getType().getAsOpaquePtr();
2513                    }
2514                }
2515            }
2516            break;
2517
2518        case clang::Type::ObjCObject:
2519        case clang::Type::ObjCInterface:
2520            {
2521                ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2522                assert (objc_class_type);
2523                if (objc_class_type)
2524                {
2525                    uint32_t child_idx = 0;
2526                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2527
2528                    if (class_interface_decl)
2529                    {
2530
2531                        const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
2532                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2533                        if (superclass_interface_decl)
2534                        {
2535                            if (omit_empty_base_classes)
2536                            {
2537                                if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
2538                                {
2539                                    if (idx == 0)
2540                                    {
2541                                        QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
2542
2543
2544                                        child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2545
2546                                        std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
2547
2548                                        child_byte_size = ivar_type_info.first / 8;
2549                                        child_byte_offset = 0;
2550                                        child_is_base_class = true;
2551
2552                                        return ivar_qual_type.getAsOpaquePtr();
2553                                    }
2554
2555                                    ++child_idx;
2556                                }
2557                            }
2558                            else
2559                                ++child_idx;
2560                        }
2561
2562                        const uint32_t superclass_idx = child_idx;
2563
2564                        if (idx < (child_idx + class_interface_decl->ivar_size()))
2565                        {
2566                            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2567
2568                            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2569                            {
2570                                if (child_idx == idx)
2571                                {
2572                                    const ObjCIvarDecl* ivar_decl = *ivar_pos;
2573
2574                                    QualType ivar_qual_type(ivar_decl->getType());
2575
2576                                    child_name.assign(ivar_decl->getNameAsString().c_str());
2577
2578                                    std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
2579
2580                                    child_byte_size = ivar_type_info.first / 8;
2581
2582                                    // Figure out the field offset within the current struct/union/class type
2583                                    bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
2584                                    child_byte_offset = bit_offset / 8;
2585
2586                                    return ivar_qual_type.getAsOpaquePtr();
2587                                }
2588                                ++child_idx;
2589                            }
2590                        }
2591                    }
2592                }
2593            }
2594            break;
2595
2596        case clang::Type::ObjCObjectPointer:
2597            {
2598                ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2599                QualType pointee_type = pointer_type->getPointeeType();
2600
2601                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2602                {
2603                    return GetChildClangTypeAtIndex (ast,
2604                                                     parent_name,
2605                                                     pointer_type->getPointeeType().getAsOpaquePtr(),
2606                                                     idx,
2607                                                     transparent_pointers,
2608                                                     omit_empty_base_classes,
2609                                                     child_name,
2610                                                     child_byte_size,
2611                                                     child_byte_offset,
2612                                                     child_bitfield_bit_size,
2613                                                     child_bitfield_bit_offset,
2614                                                     child_is_base_class);
2615                }
2616                else
2617                {
2618                    if (parent_name)
2619                    {
2620                        child_name.assign(1, '*');
2621                        child_name += parent_name;
2622                    }
2623
2624                    // We have a pointer to an simple type
2625                    if (idx == 0)
2626                    {
2627                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
2628                        assert(clang_type_info.first % 8 == 0);
2629                        child_byte_size = clang_type_info.first / 8;
2630                        child_byte_offset = 0;
2631                        return pointee_type.getAsOpaquePtr();
2632                    }
2633                }
2634            }
2635            break;
2636
2637        case clang::Type::ConstantArray:
2638            {
2639                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2640                const uint64_t element_count = array->getSize().getLimitedValue();
2641
2642                if (idx < element_count)
2643                {
2644                    if (GetCompleteQualType (ast, array->getElementType()))
2645                    {
2646                        std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
2647
2648                        char element_name[64];
2649                        ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
2650
2651                        child_name.assign(element_name);
2652                        assert(field_type_info.first % 8 == 0);
2653                        child_byte_size = field_type_info.first / 8;
2654                        child_byte_offset = idx * child_byte_size;
2655                        return array->getElementType().getAsOpaquePtr();
2656                    }
2657                }
2658            }
2659            break;
2660
2661        case clang::Type::Pointer:
2662            {
2663                PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2664                QualType pointee_type = pointer_type->getPointeeType();
2665
2666                // Don't dereference "void *" pointers
2667                if (pointee_type->isVoidType())
2668                    return NULL;
2669
2670                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2671                {
2672                    return GetChildClangTypeAtIndex (ast,
2673                                                     parent_name,
2674                                                     pointer_type->getPointeeType().getAsOpaquePtr(),
2675                                                     idx,
2676                                                     transparent_pointers,
2677                                                     omit_empty_base_classes,
2678                                                     child_name,
2679                                                     child_byte_size,
2680                                                     child_byte_offset,
2681                                                     child_bitfield_bit_size,
2682                                                     child_bitfield_bit_offset,
2683                                                     child_is_base_class);
2684                }
2685                else
2686                {
2687                    if (parent_name)
2688                    {
2689                        child_name.assign(1, '*');
2690                        child_name += parent_name;
2691                    }
2692
2693                    // We have a pointer to an simple type
2694                    if (idx == 0)
2695                    {
2696                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
2697                        assert(clang_type_info.first % 8 == 0);
2698                        child_byte_size = clang_type_info.first / 8;
2699                        child_byte_offset = 0;
2700                        return pointee_type.getAsOpaquePtr();
2701                    }
2702                }
2703            }
2704            break;
2705
2706        case clang::Type::LValueReference:
2707        case clang::Type::RValueReference:
2708            {
2709                ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2710                QualType pointee_type(reference_type->getPointeeType());
2711                clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2712                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2713                {
2714                    return GetChildClangTypeAtIndex (ast,
2715                                                     parent_name,
2716                                                     pointee_clang_type,
2717                                                     idx,
2718                                                     transparent_pointers,
2719                                                     omit_empty_base_classes,
2720                                                     child_name,
2721                                                     child_byte_size,
2722                                                     child_byte_offset,
2723                                                     child_bitfield_bit_size,
2724                                                     child_bitfield_bit_offset,
2725                                                     child_is_base_class);
2726                }
2727                else
2728                {
2729                    if (parent_name)
2730                    {
2731                        child_name.assign(1, '&');
2732                        child_name += parent_name;
2733                    }
2734
2735                    // We have a pointer to an simple type
2736                    if (idx == 0)
2737                    {
2738                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
2739                        assert(clang_type_info.first % 8 == 0);
2740                        child_byte_size = clang_type_info.first / 8;
2741                        child_byte_offset = 0;
2742                        return pointee_type.getAsOpaquePtr();
2743                    }
2744                }
2745            }
2746            break;
2747
2748        case clang::Type::Typedef:
2749            return GetChildClangTypeAtIndex (ast,
2750                                             parent_name,
2751                                             cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2752                                             idx,
2753                                             transparent_pointers,
2754                                             omit_empty_base_classes,
2755                                             child_name,
2756                                             child_byte_size,
2757                                             child_byte_offset,
2758                                             child_bitfield_bit_size,
2759                                             child_bitfield_bit_offset,
2760                                             child_is_base_class);
2761            break;
2762
2763        default:
2764            break;
2765        }
2766    }
2767    return NULL;
2768}
2769
2770static inline bool
2771BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2772{
2773    return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
2774}
2775
2776static uint32_t
2777GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2778{
2779    uint32_t num_bases = 0;
2780    if (cxx_record_decl)
2781    {
2782        if (omit_empty_base_classes)
2783        {
2784            CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2785            for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2786                 base_class != base_class_end;
2787                 ++base_class)
2788            {
2789                // Skip empty base classes
2790                if (omit_empty_base_classes)
2791                {
2792                    if (BaseSpecifierIsEmpty (base_class))
2793                        continue;
2794                }
2795                ++num_bases;
2796            }
2797        }
2798        else
2799            num_bases = cxx_record_decl->getNumBases();
2800    }
2801    return num_bases;
2802}
2803
2804
2805static uint32_t
2806GetIndexForRecordBase
2807(
2808    const RecordDecl *record_decl,
2809    const CXXBaseSpecifier *base_spec,
2810    bool omit_empty_base_classes
2811)
2812{
2813    uint32_t child_idx = 0;
2814
2815    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2816
2817//    const char *super_name = record_decl->getNameAsCString();
2818//    const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2819//    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2820//
2821    if (cxx_record_decl)
2822    {
2823        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2824        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2825             base_class != base_class_end;
2826             ++base_class)
2827        {
2828            if (omit_empty_base_classes)
2829            {
2830                if (BaseSpecifierIsEmpty (base_class))
2831                    continue;
2832            }
2833
2834//            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2835//                    child_idx,
2836//                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2837//
2838//
2839            if (base_class == base_spec)
2840                return child_idx;
2841            ++child_idx;
2842        }
2843    }
2844
2845    return UINT32_MAX;
2846}
2847
2848
2849static uint32_t
2850GetIndexForRecordChild
2851(
2852    const RecordDecl *record_decl,
2853    NamedDecl *canonical_decl,
2854    bool omit_empty_base_classes
2855)
2856{
2857    uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2858
2859//    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2860//
2861////    printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2862//    if (cxx_record_decl)
2863//    {
2864//        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2865//        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2866//             base_class != base_class_end;
2867//             ++base_class)
2868//        {
2869//            if (omit_empty_base_classes)
2870//            {
2871//                if (BaseSpecifierIsEmpty (base_class))
2872//                    continue;
2873//            }
2874//
2875////            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2876////                    record_decl->getNameAsCString(),
2877////                    canonical_decl->getNameAsCString(),
2878////                    child_idx,
2879////                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2880//
2881//
2882//            CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2883//            if (curr_base_class_decl == canonical_decl)
2884//            {
2885//                return child_idx;
2886//            }
2887//            ++child_idx;
2888//        }
2889//    }
2890//
2891//    const uint32_t num_bases = child_idx;
2892    RecordDecl::field_iterator field, field_end;
2893    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2894         field != field_end;
2895         ++field, ++child_idx)
2896    {
2897//            printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2898//                    record_decl->getNameAsCString(),
2899//                    canonical_decl->getNameAsCString(),
2900//                    child_idx - num_bases,
2901//                    field->getNameAsCString());
2902
2903        if (field->getCanonicalDecl() == canonical_decl)
2904            return child_idx;
2905    }
2906
2907    return UINT32_MAX;
2908}
2909
2910// Look for a child member (doesn't include base classes, but it does include
2911// their members) in the type hierarchy. Returns an index path into "clang_type"
2912// on how to reach the appropriate member.
2913//
2914//    class A
2915//    {
2916//    public:
2917//        int m_a;
2918//        int m_b;
2919//    };
2920//
2921//    class B
2922//    {
2923//    };
2924//
2925//    class C :
2926//        public B,
2927//        public A
2928//    {
2929//    };
2930//
2931// If we have a clang type that describes "class C", and we wanted to looked
2932// "m_b" in it:
2933//
2934// With omit_empty_base_classes == false we would get an integer array back with:
2935// { 1,  1 }
2936// The first index 1 is the child index for "class A" within class C
2937// The second index 1 is the child index for "m_b" within class A
2938//
2939// With omit_empty_base_classes == true we would get an integer array back with:
2940// { 0,  1 }
2941// 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)
2942// The second index 1 is the child index for "m_b" within class A
2943
2944size_t
2945ClangASTContext::GetIndexOfChildMemberWithName
2946(
2947    ASTContext *ast,
2948    clang_type_t clang_type,
2949    const char *name,
2950    bool omit_empty_base_classes,
2951    std::vector<uint32_t>& child_indexes
2952)
2953{
2954    if (clang_type && name && name[0])
2955    {
2956        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2957        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2958        switch (type_class)
2959        {
2960        case clang::Type::Record:
2961            if (ClangASTContext::GetCompleteType (ast, clang_type))
2962            {
2963                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2964                const RecordDecl *record_decl = record_type->getDecl();
2965
2966                assert(record_decl);
2967                uint32_t child_idx = 0;
2968
2969                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2970
2971                // Try and find a field that matches NAME
2972                RecordDecl::field_iterator field, field_end;
2973                StringRef name_sref(name);
2974                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2975                     field != field_end;
2976                     ++field, ++child_idx)
2977                {
2978                    if (field->getName().equals (name_sref))
2979                    {
2980                        // We have to add on the number of base classes to this index!
2981                        child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2982                        return child_indexes.size();
2983                    }
2984                }
2985
2986                if (cxx_record_decl)
2987                {
2988                    const RecordDecl *parent_record_decl = cxx_record_decl;
2989
2990                    //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2991
2992                    //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2993                    // Didn't find things easily, lets let clang do its thang...
2994                    IdentifierInfo & ident_ref = ast->Idents.get(name, name + strlen (name));
2995                    DeclarationName decl_name(&ident_ref);
2996
2997                    CXXBasePaths paths;
2998                    if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2999                                                       decl_name.getAsOpaquePtr(),
3000                                                       paths))
3001                    {
3002                        CXXBasePaths::const_paths_iterator path, path_end = paths.end();
3003                        for (path = paths.begin(); path != path_end; ++path)
3004                        {
3005                            const size_t num_path_elements = path->size();
3006                            for (size_t e=0; e<num_path_elements; ++e)
3007                            {
3008                                CXXBasePathElement elem = (*path)[e];
3009
3010                                child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
3011                                if (child_idx == UINT32_MAX)
3012                                {
3013                                    child_indexes.clear();
3014                                    return 0;
3015                                }
3016                                else
3017                                {
3018                                    child_indexes.push_back (child_idx);
3019                                    parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
3020                                }
3021                            }
3022                            DeclContext::lookup_iterator named_decl_pos;
3023                            for (named_decl_pos = path->Decls.first;
3024                                 named_decl_pos != path->Decls.second && parent_record_decl;
3025                                 ++named_decl_pos)
3026                            {
3027                                //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
3028
3029                                child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
3030                                if (child_idx == UINT32_MAX)
3031                                {
3032                                    child_indexes.clear();
3033                                    return 0;
3034                                }
3035                                else
3036                                {
3037                                    child_indexes.push_back (child_idx);
3038                                }
3039                            }
3040                        }
3041                        return child_indexes.size();
3042                    }
3043                }
3044
3045            }
3046            break;
3047
3048        case clang::Type::ObjCObject:
3049        case clang::Type::ObjCInterface:
3050            {
3051                StringRef name_sref(name);
3052                ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
3053                assert (objc_class_type);
3054                if (objc_class_type)
3055                {
3056                    uint32_t child_idx = 0;
3057                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3058
3059                    if (class_interface_decl)
3060                    {
3061                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3062                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3063
3064                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
3065                        {
3066                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
3067
3068                            if (ivar_decl->getName().equals (name_sref))
3069                            {
3070                                if ((!omit_empty_base_classes && superclass_interface_decl) ||
3071                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3072                                    ++child_idx;
3073
3074                                child_indexes.push_back (child_idx);
3075                                return child_indexes.size();
3076                            }
3077                        }
3078
3079                        if (superclass_interface_decl)
3080                        {
3081                            // The super class index is always zero for ObjC classes,
3082                            // so we push it onto the child indexes in case we find
3083                            // an ivar in our superclass...
3084                            child_indexes.push_back (0);
3085
3086                            if (GetIndexOfChildMemberWithName (ast,
3087                                                               ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
3088                                                               name,
3089                                                               omit_empty_base_classes,
3090                                                               child_indexes))
3091                            {
3092                                // We did find an ivar in a superclass so just
3093                                // return the results!
3094                                return child_indexes.size();
3095                            }
3096
3097                            // We didn't find an ivar matching "name" in our
3098                            // superclass, pop the superclass zero index that
3099                            // we pushed on above.
3100                            child_indexes.pop_back();
3101                        }
3102                    }
3103                }
3104            }
3105            break;
3106
3107        case clang::Type::ObjCObjectPointer:
3108            {
3109                return GetIndexOfChildMemberWithName (ast,
3110                                                      cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3111                                                      name,
3112                                                      omit_empty_base_classes,
3113                                                      child_indexes);
3114            }
3115            break;
3116
3117
3118        case clang::Type::ConstantArray:
3119            {
3120//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3121//                const uint64_t element_count = array->getSize().getLimitedValue();
3122//
3123//                if (idx < element_count)
3124//                {
3125//                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
3126//
3127//                    char element_name[32];
3128//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3129//
3130//                    child_name.assign(element_name);
3131//                    assert(field_type_info.first % 8 == 0);
3132//                    child_byte_size = field_type_info.first / 8;
3133//                    child_byte_offset = idx * child_byte_size;
3134//                    return array->getElementType().getAsOpaquePtr();
3135//                }
3136            }
3137            break;
3138
3139//        case clang::Type::MemberPointerType:
3140//            {
3141//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3142//                QualType pointee_type = mem_ptr_type->getPointeeType();
3143//
3144//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3145//                {
3146//                    return GetIndexOfChildWithName (ast,
3147//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3148//                                                    name);
3149//                }
3150//            }
3151//            break;
3152//
3153        case clang::Type::LValueReference:
3154        case clang::Type::RValueReference:
3155            {
3156                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3157                QualType pointee_type = reference_type->getPointeeType();
3158
3159                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3160                {
3161                    return GetIndexOfChildMemberWithName (ast,
3162                                                          reference_type->getPointeeType().getAsOpaquePtr(),
3163                                                          name,
3164                                                          omit_empty_base_classes,
3165                                                          child_indexes);
3166                }
3167            }
3168            break;
3169
3170        case clang::Type::Pointer:
3171            {
3172                PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3173                QualType pointee_type = pointer_type->getPointeeType();
3174
3175                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3176                {
3177                    return GetIndexOfChildMemberWithName (ast,
3178                                                          pointer_type->getPointeeType().getAsOpaquePtr(),
3179                                                          name,
3180                                                          omit_empty_base_classes,
3181                                                          child_indexes);
3182                }
3183                else
3184                {
3185//                    if (parent_name)
3186//                    {
3187//                        child_name.assign(1, '*');
3188//                        child_name += parent_name;
3189//                    }
3190//
3191//                    // We have a pointer to an simple type
3192//                    if (idx == 0)
3193//                    {
3194//                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
3195//                        assert(clang_type_info.first % 8 == 0);
3196//                        child_byte_size = clang_type_info.first / 8;
3197//                        child_byte_offset = 0;
3198//                        return pointee_type.getAsOpaquePtr();
3199//                    }
3200                }
3201            }
3202            break;
3203
3204        case clang::Type::Typedef:
3205            return GetIndexOfChildMemberWithName (ast,
3206                                                  cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
3207                                                  name,
3208                                                  omit_empty_base_classes,
3209                                                  child_indexes);
3210
3211        default:
3212            break;
3213        }
3214    }
3215    return 0;
3216}
3217
3218
3219// Get the index of the child of "clang_type" whose name matches. This function
3220// doesn't descend into the children, but only looks one level deep and name
3221// matches can include base class names.
3222
3223uint32_t
3224ClangASTContext::GetIndexOfChildWithName
3225(
3226    ASTContext *ast,
3227    clang_type_t clang_type,
3228    const char *name,
3229    bool omit_empty_base_classes
3230)
3231{
3232    if (clang_type && name && name[0])
3233    {
3234        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
3235
3236        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3237
3238        switch (type_class)
3239        {
3240        case clang::Type::Record:
3241            if (ClangASTContext::GetCompleteType (ast, clang_type))
3242            {
3243                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3244                const RecordDecl *record_decl = record_type->getDecl();
3245
3246                assert(record_decl);
3247                uint32_t child_idx = 0;
3248
3249                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3250
3251                if (cxx_record_decl)
3252                {
3253                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3254                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3255                         base_class != base_class_end;
3256                         ++base_class)
3257                    {
3258                        // Skip empty base classes
3259                        CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3260                        if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3261                            continue;
3262
3263                        if (base_class->getType().getAsString().compare (name) == 0)
3264                            return child_idx;
3265                        ++child_idx;
3266                    }
3267                }
3268
3269                // Try and find a field that matches NAME
3270                RecordDecl::field_iterator field, field_end;
3271                StringRef name_sref(name);
3272                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3273                     field != field_end;
3274                     ++field, ++child_idx)
3275                {
3276                    if (field->getName().equals (name_sref))
3277                        return child_idx;
3278                }
3279
3280            }
3281            break;
3282
3283        case clang::Type::ObjCObject:
3284        case clang::Type::ObjCInterface:
3285            {
3286                StringRef name_sref(name);
3287                ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
3288                assert (objc_class_type);
3289                if (objc_class_type)
3290                {
3291                    uint32_t child_idx = 0;
3292                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3293
3294                    if (class_interface_decl)
3295                    {
3296                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3297                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3298
3299                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3300                        {
3301                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
3302
3303                            if (ivar_decl->getName().equals (name_sref))
3304                            {
3305                                if ((!omit_empty_base_classes && superclass_interface_decl) ||
3306                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3307                                    ++child_idx;
3308
3309                                return child_idx;
3310                            }
3311                        }
3312
3313                        if (superclass_interface_decl)
3314                        {
3315                            if (superclass_interface_decl->getName().equals (name_sref))
3316                                return 0;
3317                        }
3318                    }
3319                }
3320            }
3321            break;
3322
3323        case clang::Type::ObjCObjectPointer:
3324            {
3325                return GetIndexOfChildWithName (ast,
3326                                                cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3327                                                name,
3328                                                omit_empty_base_classes);
3329            }
3330            break;
3331
3332        case clang::Type::ConstantArray:
3333            {
3334//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3335//                const uint64_t element_count = array->getSize().getLimitedValue();
3336//
3337//                if (idx < element_count)
3338//                {
3339//                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
3340//
3341//                    char element_name[32];
3342//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3343//
3344//                    child_name.assign(element_name);
3345//                    assert(field_type_info.first % 8 == 0);
3346//                    child_byte_size = field_type_info.first / 8;
3347//                    child_byte_offset = idx * child_byte_size;
3348//                    return array->getElementType().getAsOpaquePtr();
3349//                }
3350            }
3351            break;
3352
3353//        case clang::Type::MemberPointerType:
3354//            {
3355//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3356//                QualType pointee_type = mem_ptr_type->getPointeeType();
3357//
3358//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3359//                {
3360//                    return GetIndexOfChildWithName (ast,
3361//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3362//                                                    name);
3363//                }
3364//            }
3365//            break;
3366//
3367        case clang::Type::LValueReference:
3368        case clang::Type::RValueReference:
3369            {
3370                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3371                QualType pointee_type = reference_type->getPointeeType();
3372
3373                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3374                {
3375                    return GetIndexOfChildWithName (ast,
3376                                                    reference_type->getPointeeType().getAsOpaquePtr(),
3377                                                    name,
3378                                                    omit_empty_base_classes);
3379                }
3380            }
3381            break;
3382
3383        case clang::Type::Pointer:
3384            {
3385                PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3386                QualType pointee_type = pointer_type->getPointeeType();
3387
3388                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3389                {
3390                    return GetIndexOfChildWithName (ast,
3391                                                    pointer_type->getPointeeType().getAsOpaquePtr(),
3392                                                    name,
3393                                                    omit_empty_base_classes);
3394                }
3395                else
3396                {
3397//                    if (parent_name)
3398//                    {
3399//                        child_name.assign(1, '*');
3400//                        child_name += parent_name;
3401//                    }
3402//
3403//                    // We have a pointer to an simple type
3404//                    if (idx == 0)
3405//                    {
3406//                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
3407//                        assert(clang_type_info.first % 8 == 0);
3408//                        child_byte_size = clang_type_info.first / 8;
3409//                        child_byte_offset = 0;
3410//                        return pointee_type.getAsOpaquePtr();
3411//                    }
3412                }
3413            }
3414            break;
3415
3416        case clang::Type::Typedef:
3417            return GetIndexOfChildWithName (ast,
3418                                            cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
3419                                            name,
3420                                            omit_empty_base_classes);
3421
3422        default:
3423            break;
3424        }
3425    }
3426    return UINT32_MAX;
3427}
3428
3429#pragma mark TagType
3430
3431bool
3432ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
3433{
3434    if (tag_clang_type)
3435    {
3436        QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
3437        clang::Type *clang_type = tag_qual_type.getTypePtr();
3438        if (clang_type)
3439        {
3440            TagType *tag_type = dyn_cast<TagType>(clang_type);
3441            if (tag_type)
3442            {
3443                TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3444                if (tag_decl)
3445                {
3446                    tag_decl->setTagKind ((TagDecl::TagKind)kind);
3447                    return true;
3448                }
3449            }
3450        }
3451    }
3452    return false;
3453}
3454
3455
3456#pragma mark DeclContext Functions
3457
3458DeclContext *
3459ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
3460{
3461    if (clang_type == NULL)
3462        return NULL;
3463
3464    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
3465    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3466    switch (type_class)
3467    {
3468    case clang::Type::FunctionNoProto:          break;
3469    case clang::Type::FunctionProto:            break;
3470    case clang::Type::IncompleteArray:          break;
3471    case clang::Type::VariableArray:            break;
3472    case clang::Type::ConstantArray:            break;
3473    case clang::Type::ExtVector:                break;
3474    case clang::Type::Vector:                   break;
3475    case clang::Type::Builtin:                  break;
3476    case clang::Type::BlockPointer:             break;
3477    case clang::Type::Pointer:                  break;
3478    case clang::Type::LValueReference:          break;
3479    case clang::Type::RValueReference:          break;
3480    case clang::Type::MemberPointer:            break;
3481    case clang::Type::Complex:                  break;
3482    case clang::Type::ObjCObject:               break;
3483    case clang::Type::ObjCInterface:            return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3484    case clang::Type::ObjCObjectPointer:        return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3485    case clang::Type::Record:                   return cast<RecordType>(qual_type)->getDecl();
3486    case clang::Type::Enum:                     return cast<EnumType>(qual_type)->getDecl();
3487    case clang::Type::Typedef:                  return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
3488
3489    case clang::Type::TypeOfExpr:               break;
3490    case clang::Type::TypeOf:                   break;
3491    case clang::Type::Decltype:                 break;
3492    //case clang::Type::QualifiedName:          break;
3493    case clang::Type::TemplateSpecialization:   break;
3494    }
3495    // No DeclContext in this type...
3496    return NULL;
3497}
3498
3499#pragma mark Namespace Declarations
3500
3501NamespaceDecl *
3502ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3503{
3504    // TODO: Do something intelligent with the Declaration object passed in
3505    // like maybe filling in the SourceLocation with it...
3506    if (name)
3507    {
3508        ASTContext *ast = getASTContext();
3509        if (decl_ctx == NULL)
3510            decl_ctx = ast->getTranslationUnitDecl();
3511        return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), &ast->Idents.get(name));
3512    }
3513    return NULL;
3514}
3515
3516
3517#pragma mark Function Types
3518
3519FunctionDecl *
3520ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
3521{
3522    if (name)
3523    {
3524        ASTContext *ast = getASTContext();
3525        assert (ast != NULL);
3526
3527        if (name && name[0])
3528        {
3529            return FunctionDecl::Create(*ast,
3530                                        ast->getTranslationUnitDecl(),
3531                                        SourceLocation(),
3532                                        DeclarationName (&ast->Idents.get(name)),
3533                                        QualType::getFromOpaquePtr(function_clang_type),
3534                                        NULL,
3535                                        (FunctionDecl::StorageClass)storage,
3536                                        (FunctionDecl::StorageClass)storage,
3537                                        is_inline);
3538        }
3539        else
3540        {
3541            return FunctionDecl::Create(*ast,
3542                                        ast->getTranslationUnitDecl(),
3543                                        SourceLocation(),
3544                                        DeclarationName (),
3545                                        QualType::getFromOpaquePtr(function_clang_type),
3546                                        NULL,
3547                                        (FunctionDecl::StorageClass)storage,
3548                                        (FunctionDecl::StorageClass)storage,
3549                                        is_inline);
3550        }
3551    }
3552    return NULL;
3553}
3554
3555clang_type_t
3556ClangASTContext::CreateFunctionType (ASTContext *ast,
3557                                     clang_type_t result_type,
3558                                     clang_type_t *args,
3559                                     unsigned num_args,
3560                                     bool is_variadic,
3561                                     unsigned type_quals)
3562{
3563    assert (ast != NULL);
3564    std::vector<QualType> qual_type_args;
3565    for (unsigned i=0; i<num_args; ++i)
3566        qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3567
3568    // TODO: Detect calling convention in DWARF?
3569    FunctionProtoType::ExtProtoInfo proto_info;
3570    proto_info.Variadic = is_variadic;
3571    proto_info.HasExceptionSpec = false;
3572    proto_info.HasAnyExceptionSpec = false;
3573    proto_info.TypeQuals = type_quals;
3574    proto_info.NumExceptions = 0;
3575    proto_info.Exceptions = NULL;
3576
3577    return ast->getFunctionType(QualType::getFromOpaquePtr(result_type),
3578                                        qual_type_args.empty() ? NULL : &qual_type_args.front(),
3579                                        qual_type_args.size(),
3580                                        proto_info).getAsOpaquePtr();    // NoReturn);
3581}
3582
3583ParmVarDecl *
3584ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
3585{
3586    ASTContext *ast = getASTContext();
3587    assert (ast != NULL);
3588    return ParmVarDecl::Create(*ast,
3589                                ast->getTranslationUnitDecl(),
3590                                SourceLocation(),
3591                                name && name[0] ? &ast->Idents.get(name) : NULL,
3592                                QualType::getFromOpaquePtr(param_type),
3593                                NULL,
3594                                (VarDecl::StorageClass)storage,
3595                                (VarDecl::StorageClass)storage,
3596                                0);
3597}
3598
3599void
3600ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3601{
3602    if (function_decl)
3603        function_decl->setParams (params, num_params);
3604}
3605
3606
3607#pragma mark Array Types
3608
3609clang_type_t
3610ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
3611{
3612    if (element_type)
3613    {
3614        ASTContext *ast = getASTContext();
3615        assert (ast != NULL);
3616        llvm::APInt ap_element_count (64, element_count);
3617        return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3618                                                 ap_element_count,
3619                                                 ArrayType::Normal,
3620                                                 0).getAsOpaquePtr(); // ElemQuals
3621    }
3622    return NULL;
3623}
3624
3625
3626#pragma mark TagDecl
3627
3628bool
3629ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
3630{
3631    if (clang_type)
3632    {
3633        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3634        clang::Type *t = qual_type.getTypePtr();
3635        if (t)
3636        {
3637            TagType *tag_type = dyn_cast<TagType>(t);
3638            if (tag_type)
3639            {
3640                TagDecl *tag_decl = tag_type->getDecl();
3641                if (tag_decl)
3642                {
3643                    tag_decl->startDefinition();
3644                    return true;
3645                }
3646            }
3647        }
3648    }
3649    return false;
3650}
3651
3652bool
3653ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
3654{
3655    if (clang_type)
3656    {
3657        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3658
3659        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3660
3661        if (cxx_record_decl)
3662        {
3663            cxx_record_decl->completeDefinition();
3664
3665            return true;
3666        }
3667
3668        ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3669
3670        if (objc_class_type)
3671        {
3672            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3673
3674            class_interface_decl->setForwardDecl(false);
3675        }
3676
3677        const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3678
3679        if (enum_type)
3680        {
3681            EnumDecl *enum_decl = enum_type->getDecl();
3682
3683            if (enum_decl)
3684            {
3685                /// TODO This really needs to be fixed.
3686
3687                unsigned NumPositiveBits = 1;
3688                unsigned NumNegativeBits = 0;
3689
3690                ASTContext *ast = getASTContext();
3691
3692                QualType promotion_qual_type;
3693                // If the enum integer type is less than an integer in bit width,
3694                // then we must promote it to an integer size.
3695                if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
3696                {
3697                    if (enum_decl->getIntegerType()->isSignedIntegerType())
3698                        promotion_qual_type = ast->IntTy;
3699                    else
3700                        promotion_qual_type = ast->UnsignedIntTy;
3701                }
3702                else
3703                    promotion_qual_type = enum_decl->getIntegerType();
3704
3705                enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
3706                return true;
3707            }
3708        }
3709    }
3710    return false;
3711}
3712
3713
3714#pragma mark Enumeration Types
3715
3716clang_type_t
3717ClangASTContext::CreateEnumerationType
3718(
3719    const char *name,
3720    DeclContext *decl_ctx,
3721    const Declaration &decl,
3722    clang_type_t integer_qual_type
3723)
3724{
3725    // TODO: Do something intelligent with the Declaration object passed in
3726    // like maybe filling in the SourceLocation with it...
3727    ASTContext *ast = getASTContext();
3728    assert (ast != NULL);
3729
3730    // TODO: ask about these...
3731//    const bool IsScoped = false;
3732//    const bool IsFixed = false;
3733
3734    EnumDecl *enum_decl = EnumDecl::Create (*ast,
3735                                            decl_ctx,
3736                                            SourceLocation(),
3737                                            name && name[0] ? &ast->Idents.get(name) : NULL,
3738                                            SourceLocation(),
3739                                            NULL,
3740                                            false,  // IsScoped
3741                                            false,  // IsScopedUsingClassTag
3742                                            false); // IsFixed
3743
3744
3745    if (enum_decl)
3746    {
3747        // TODO: check if we should be setting the promotion type too?
3748        enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
3749
3750        enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
3751
3752        return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
3753    }
3754    return NULL;
3755}
3756
3757clang_type_t
3758ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3759{
3760    QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3761
3762    clang::Type *clang_type = enum_qual_type.getTypePtr();
3763    if (clang_type)
3764    {
3765        const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3766        if (enum_type)
3767        {
3768            EnumDecl *enum_decl = enum_type->getDecl();
3769            if (enum_decl)
3770                return enum_decl->getIntegerType().getAsOpaquePtr();
3771        }
3772    }
3773    return NULL;
3774}
3775bool
3776ClangASTContext::AddEnumerationValueToEnumerationType
3777(
3778    clang_type_t enum_clang_type,
3779    clang_type_t enumerator_clang_type,
3780    const Declaration &decl,
3781    const char *name,
3782    int64_t enum_value,
3783    uint32_t enum_value_bit_size
3784)
3785{
3786    if (enum_clang_type && enumerator_clang_type && name)
3787    {
3788        // TODO: Do something intelligent with the Declaration object passed in
3789        // like maybe filling in the SourceLocation with it...
3790        ASTContext *ast = getASTContext();
3791        IdentifierTable *identifier_table = getIdentifierTable();
3792
3793        assert (ast != NULL);
3794        assert (identifier_table != NULL);
3795        QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3796
3797        clang::Type *clang_type = enum_qual_type.getTypePtr();
3798        if (clang_type)
3799        {
3800            const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3801
3802            if (enum_type)
3803            {
3804                llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3805                enum_llvm_apsint = enum_value;
3806                EnumConstantDecl *enumerator_decl =
3807                    EnumConstantDecl::Create (*ast,
3808                                              enum_type->getDecl(),
3809                                              SourceLocation(),
3810                                              name ? &identifier_table->get(name) : NULL,    // Identifier
3811                                              QualType::getFromOpaquePtr(enumerator_clang_type),
3812                                              NULL,
3813                                              enum_llvm_apsint);
3814
3815                if (enumerator_decl)
3816                {
3817                    enum_type->getDecl()->addDecl(enumerator_decl);
3818                    return true;
3819                }
3820            }
3821        }
3822    }
3823    return false;
3824}
3825
3826#pragma mark Pointers & References
3827
3828clang_type_t
3829ClangASTContext::CreatePointerType (clang_type_t clang_type)
3830{
3831    return CreatePointerType (getASTContext(), clang_type);
3832}
3833
3834clang_type_t
3835ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
3836{
3837    if (ast && clang_type)
3838    {
3839        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3840
3841        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3842        switch (type_class)
3843        {
3844        case clang::Type::ObjCObject:
3845        case clang::Type::ObjCInterface:
3846            return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3847
3848        default:
3849            return ast->getPointerType(qual_type).getAsOpaquePtr();
3850        }
3851    }
3852    return NULL;
3853}
3854
3855clang_type_t
3856ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
3857                                            clang_type_t clang_type)
3858{
3859    if (clang_type)
3860        return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3861    return NULL;
3862}
3863
3864clang_type_t
3865ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
3866                                            clang_type_t clang_type)
3867{
3868    if (clang_type)
3869        return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3870    return NULL;
3871}
3872
3873clang_type_t
3874ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
3875{
3876    if (clang_pointee_type && clang_pointee_type)
3877        return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3878                                                     QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3879    return NULL;
3880}
3881
3882size_t
3883ClangASTContext::GetPointerBitSize ()
3884{
3885    ASTContext *ast = getASTContext();
3886    return ast->getTypeSize(ast->VoidPtrTy);
3887}
3888
3889bool
3890ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
3891{
3892    if (clang_type == NULL)
3893        return false;
3894
3895    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3896    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3897    switch (type_class)
3898    {
3899    case clang::Type::Builtin:
3900        switch (cast<clang::BuiltinType>(qual_type)->getKind())
3901        {
3902        default:
3903            break;
3904        case clang::BuiltinType::ObjCId:
3905        case clang::BuiltinType::ObjCClass:
3906            return true;
3907        }
3908        return false;
3909    case clang::Type::ObjCObjectPointer:
3910        if (target_type)
3911            *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3912        return true;
3913    case clang::Type::BlockPointer:
3914        if (target_type)
3915            *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3916        return true;
3917    case clang::Type::Pointer:
3918        if (target_type)
3919            *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3920        return true;
3921    case clang::Type::MemberPointer:
3922        if (target_type)
3923            *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3924        return true;
3925    case clang::Type::LValueReference:
3926        if (target_type)
3927            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3928        return true;
3929    case clang::Type::RValueReference:
3930        if (target_type)
3931            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3932        return true;
3933    case clang::Type::Typedef:
3934        return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
3935    default:
3936        break;
3937    }
3938    return false;
3939}
3940
3941bool
3942ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
3943{
3944    if (!clang_type)
3945        return false;
3946
3947    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3948    const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3949
3950    if (builtin_type)
3951    {
3952        if (builtin_type->isInteger())
3953            is_signed = builtin_type->isSignedInteger();
3954
3955        return true;
3956    }
3957
3958    return false;
3959}
3960
3961bool
3962ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
3963{
3964    if (clang_type)
3965    {
3966        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3967        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3968        switch (type_class)
3969        {
3970        case clang::Type::Builtin:
3971            switch (cast<clang::BuiltinType>(qual_type)->getKind())
3972            {
3973            default:
3974                break;
3975            case clang::BuiltinType::ObjCId:
3976            case clang::BuiltinType::ObjCClass:
3977                return true;
3978            }
3979            return false;
3980        case clang::Type::ObjCObjectPointer:
3981            if (target_type)
3982                *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3983            return true;
3984        case clang::Type::BlockPointer:
3985            if (target_type)
3986                *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3987            return true;
3988        case clang::Type::Pointer:
3989            if (target_type)
3990                *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3991            return true;
3992        case clang::Type::MemberPointer:
3993            if (target_type)
3994                *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3995            return true;
3996        case clang::Type::Typedef:
3997            return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
3998        default:
3999            break;
4000        }
4001    }
4002    return false;
4003}
4004
4005bool
4006ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
4007{
4008    if (clang_type)
4009    {
4010        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4011
4012        if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
4013        {
4014            clang::BuiltinType::Kind kind = BT->getKind();
4015            if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
4016            {
4017                count = 1;
4018                is_complex = false;
4019                return true;
4020            }
4021        }
4022        else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
4023        {
4024            if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
4025            {
4026                count = 2;
4027                is_complex = true;
4028                return true;
4029            }
4030        }
4031        else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
4032        {
4033            if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
4034            {
4035                count = VT->getNumElements();
4036                is_complex = false;
4037                return true;
4038            }
4039        }
4040    }
4041    return false;
4042}
4043
4044
4045bool
4046ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
4047{
4048    if (clang_type)
4049    {
4050        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4051
4052        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4053        if (cxx_record_decl)
4054        {
4055            class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
4056            return true;
4057        }
4058    }
4059    class_name.clear();
4060    return false;
4061}
4062
4063
4064bool
4065ClangASTContext::IsCXXClassType (clang_type_t clang_type)
4066{
4067    if (clang_type)
4068    {
4069        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4070        if (qual_type->getAsCXXRecordDecl() != NULL)
4071            return true;
4072    }
4073    return false;
4074}
4075
4076bool
4077ClangASTContext::IsObjCClassType (clang_type_t clang_type)
4078{
4079    if (clang_type)
4080    {
4081        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4082        if (qual_type->isObjCObjectOrInterfaceType())
4083            return true;
4084    }
4085    return false;
4086}
4087
4088
4089bool
4090ClangASTContext::IsCharType (clang_type_t clang_type)
4091{
4092    if (clang_type)
4093        return QualType::getFromOpaquePtr(clang_type)->isCharType();
4094    return false;
4095}
4096
4097bool
4098ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
4099{
4100    clang_type_t pointee_or_element_clang_type = NULL;
4101    Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
4102
4103    if (pointee_or_element_clang_type == NULL)
4104        return false;
4105
4106    if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
4107    {
4108        QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
4109
4110        if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
4111        {
4112            QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4113            if (type_flags.Test (eTypeIsArray))
4114            {
4115                // We know the size of the array and it could be a C string
4116                // since it is an array of characters
4117                length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
4118                return true;
4119            }
4120            else
4121            {
4122                length = 0;
4123                return true;
4124            }
4125
4126        }
4127    }
4128    return false;
4129}
4130
4131bool
4132ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
4133{
4134    if (clang_type)
4135    {
4136        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4137
4138        if (qual_type->isFunctionPointerType())
4139            return true;
4140
4141        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4142        switch (type_class)
4143        {
4144        case clang::Type::Typedef:
4145            return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
4146
4147        case clang::Type::LValueReference:
4148        case clang::Type::RValueReference:
4149            {
4150                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
4151                if (reference_type)
4152                    return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
4153            }
4154            break;
4155        }
4156    }
4157    return false;
4158}
4159
4160size_t
4161ClangASTContext::GetArraySize (clang_type_t clang_type)
4162{
4163    if (clang_type)
4164    {
4165        ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
4166        if (array)
4167            return array->getSize().getLimitedValue();
4168    }
4169    return 0;
4170}
4171
4172bool
4173ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
4174{
4175    if (!clang_type)
4176        return false;
4177
4178    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4179
4180    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4181    switch (type_class)
4182    {
4183    case clang::Type::ConstantArray:
4184        if (member_type)
4185            *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4186        if (size)
4187            *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
4188        return true;
4189    case clang::Type::IncompleteArray:
4190        if (member_type)
4191            *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4192        if (size)
4193            *size = 0;
4194        return true;
4195    case clang::Type::VariableArray:
4196        if (member_type)
4197            *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4198        if (size)
4199            *size = 0;
4200    case clang::Type::DependentSizedArray:
4201        if (member_type)
4202            *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4203        if (size)
4204            *size = 0;
4205        return true;
4206    }
4207    return false;
4208}
4209
4210
4211#pragma mark Typedefs
4212
4213clang_type_t
4214ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
4215{
4216    if (clang_type)
4217    {
4218        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4219        ASTContext *ast = getASTContext();
4220        IdentifierTable *identifier_table = getIdentifierTable();
4221        assert (ast != NULL);
4222        assert (identifier_table != NULL);
4223        if (decl_ctx == NULL)
4224            decl_ctx = ast->getTranslationUnitDecl();
4225        TypedefDecl *decl = TypedefDecl::Create (*ast,
4226                                                 decl_ctx,
4227                                                 SourceLocation(),
4228                                                 name ? &identifier_table->get(name) : NULL, // Identifier
4229                                                 ast->CreateTypeSourceInfo(qual_type));
4230
4231        decl->setAccess(AS_public); // TODO respect proper access specifier
4232
4233        // Get a uniqued QualType for the typedef decl type
4234        return ast->getTypedefType (decl).getAsOpaquePtr();
4235    }
4236    return NULL;
4237}
4238
4239
4240std::string
4241ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
4242{
4243    std::string return_name;
4244
4245    QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
4246
4247    const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
4248    if (typedef_type)
4249    {
4250        const TypedefDecl *typedef_decl = typedef_type->getDecl();
4251        return_name = typedef_decl->getQualifiedNameAsString();
4252    }
4253    else
4254    {
4255        return_name = qual_type.getAsString();
4256    }
4257
4258    return return_name;
4259}
4260
4261// Disable this for now since I can't seem to get a nicely formatted float
4262// out of the APFloat class without just getting the float, double or quad
4263// and then using a formatted print on it which defeats the purpose. We ideally
4264// would like to get perfect string values for any kind of float semantics
4265// so we can support remote targets. The code below also requires a patch to
4266// llvm::APInt.
4267//bool
4268//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)
4269//{
4270//  uint32_t count = 0;
4271//  bool is_complex = false;
4272//  if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4273//  {
4274//      unsigned num_bytes_per_float = byte_size / count;
4275//      unsigned num_bits_per_float = num_bytes_per_float * 8;
4276//
4277//      float_str.clear();
4278//      uint32_t i;
4279//      for (i=0; i<count; i++)
4280//      {
4281//          APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
4282//          bool is_ieee = false;
4283//          APFloat ap_float(ap_int, is_ieee);
4284//          char s[1024];
4285//          unsigned int hex_digits = 0;
4286//          bool upper_case = false;
4287//
4288//          if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
4289//          {
4290//              if (i > 0)
4291//                  float_str.append(", ");
4292//              float_str.append(s);
4293//              if (i == 1 && is_complex)
4294//                  float_str.append(1, 'i');
4295//          }
4296//      }
4297//      return !float_str.empty();
4298//  }
4299//  return false;
4300//}
4301
4302size_t
4303ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
4304{
4305    if (clang_type)
4306    {
4307        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4308        uint32_t count = 0;
4309        bool is_complex = false;
4310        if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4311        {
4312            // TODO: handle complex and vector types
4313            if (count != 1)
4314                return false;
4315
4316            StringRef s_sref(s);
4317            APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
4318
4319            const uint64_t bit_size = ast->getTypeSize (qual_type);
4320            const uint64_t byte_size = bit_size / 8;
4321            if (dst_size >= byte_size)
4322            {
4323                if (bit_size == sizeof(float)*8)
4324                {
4325                    float float32 = ap_float.convertToFloat();
4326                    ::memcpy (dst, &float32, byte_size);
4327                    return byte_size;
4328                }
4329                else if (bit_size >= 64)
4330                {
4331                    llvm::APInt ap_int(ap_float.bitcastToAPInt());
4332                    ::memcpy (dst, ap_int.getRawData(), byte_size);
4333                    return byte_size;
4334                }
4335            }
4336        }
4337    }
4338    return 0;
4339}
4340
4341unsigned
4342ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
4343{
4344    assert (clang_type);
4345
4346    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4347
4348    return qual_type.getQualifiers().getCVRQualifiers();
4349}
4350
4351bool
4352ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
4353{
4354    if (clang_type == NULL)
4355        return false;
4356
4357    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
4358    return GetCompleteQualType (ast, qual_type);
4359}
4360
4361
4362bool
4363ClangASTContext::GetCompleteType (clang_type_t clang_type)
4364{
4365    return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
4366}
4367
4368