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