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