ClangASTContext.cpp revision 839fde455820d7758685f5eb2257a83e96ca68d2
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    NullDiagnosticClient *null_client = new NullDiagnosticClient;
742    Diagnostic diagnostics(null_client);
743    FileManager file_manager;
744    ASTImporter importer(diagnostics,
745                         *dest_context, file_manager,
746                         *source_context, file_manager);
747    QualType ret = importer.Import(QualType::getFromOpaquePtr(clang_type));
748    return ret.getAsOpaquePtr();
749}
750
751bool
752ClangASTContext::AreTypesSame(ASTContext *ast_context,
753             clang_type_t type1,
754             clang_type_t type2)
755{
756    return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
757                                    QualType::getFromOpaquePtr(type2));
758}
759
760#pragma mark CVR modifiers
761
762clang_type_t
763ClangASTContext::AddConstModifier (clang_type_t clang_type)
764{
765    if (clang_type)
766    {
767        QualType result(QualType::getFromOpaquePtr(clang_type));
768        result.addConst();
769        return result.getAsOpaquePtr();
770    }
771    return NULL;
772}
773
774clang_type_t
775ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
776{
777    if (clang_type)
778    {
779        QualType result(QualType::getFromOpaquePtr(clang_type));
780        result.getQualifiers().setRestrict (true);
781        return result.getAsOpaquePtr();
782    }
783    return NULL;
784}
785
786clang_type_t
787ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
788{
789    if (clang_type)
790    {
791        QualType result(QualType::getFromOpaquePtr(clang_type));
792        result.getQualifiers().setVolatile (true);
793        return result.getAsOpaquePtr();
794    }
795    return NULL;
796}
797
798#pragma mark Structure, Unions, Classes
799
800clang_type_t
801ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
802{
803    ASTContext *ast_context = getASTContext();
804    assert (ast_context != NULL);
805
806    if (decl_ctx == NULL)
807        decl_ctx = ast_context->getTranslationUnitDecl();
808
809
810    if (language == eLanguageTypeObjC)
811    {
812        bool isForwardDecl = true;
813        bool isInternal = false;
814        return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
815    }
816
817    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
818    // we will need to update this code. I was told to currently always use
819    // the CXXRecordDecl class since we often don't know from debug information
820    // if something is struct or a class, so we default to always use the more
821    // complete definition just in case.
822    CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
823                                                (TagDecl::TagKind)kind,
824                                                decl_ctx,
825                                                SourceLocation(),
826                                                name && name[0] ? &ast_context->Idents.get(name) : NULL);
827
828    return ast_context->getTagDeclType(decl).getAsOpaquePtr();
829}
830
831static bool
832IsOperator (const char *name, OverloadedOperatorKind &op_kind)
833{
834    if (name == NULL || name[0] == '\0')
835        return false;
836
837    if (::strstr(name, "operator ") != name)
838        return false;
839
840    const char *post_op_name = name + 9;
841
842    // This is an operator, set the overloaded operator kind to invalid
843    // in case this is a conversion operator...
844    op_kind = NUM_OVERLOADED_OPERATORS;
845
846    switch (post_op_name[0])
847    {
848    case 'n':
849        if  (strcmp (post_op_name, "new") == 0)
850            op_kind = OO_New;
851        else if (strcmp (post_op_name, "new[]") == 0)
852            op_kind = OO_Array_New;
853        break;
854
855    case 'd':
856        if (strcmp (post_op_name, "delete") == 0)
857            op_kind = OO_Delete;
858        else if (strcmp (post_op_name, "delete[]") == 0)
859            op_kind = OO_Array_Delete;
860        break;
861
862    case '+':
863        if (post_op_name[1] == '\0')
864            op_kind = OO_Plus;
865        else if (post_op_name[2] == '\0')
866        {
867            if (post_op_name[1] == '=')
868                op_kind = OO_PlusEqual;
869            else if (post_op_name[1] == '+')
870                op_kind = OO_PlusPlus;
871        }
872        break;
873
874    case '-':
875        if (post_op_name[1] == '\0')
876            op_kind = OO_Minus;
877        else if (post_op_name[2] == '\0')
878        {
879            switch (post_op_name[1])
880            {
881            case '=': op_kind = OO_MinusEqual; break;
882            case '-': op_kind = OO_MinusMinus; break;
883            case '>': op_kind = OO_Arrow; break;
884            }
885        }
886        else if (post_op_name[3] == '\0')
887        {
888            if (post_op_name[2] == '*')
889                op_kind = OO_ArrowStar; break;
890        }
891        break;
892
893    case '*':
894        if (post_op_name[1] == '\0')
895            op_kind = OO_Star;
896        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
897            op_kind = OO_StarEqual;
898        break;
899
900    case '/':
901        if (post_op_name[1] == '\0')
902            op_kind = OO_Slash;
903        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
904            op_kind = OO_SlashEqual;
905        break;
906
907    case '%':
908        if (post_op_name[1] == '\0')
909            op_kind = OO_Percent;
910        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
911            op_kind = OO_PercentEqual;
912        break;
913
914
915    case '^':
916        if (post_op_name[1] == '\0')
917            op_kind = OO_Caret;
918        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
919            op_kind = OO_CaretEqual;
920        break;
921
922    case '&':
923        if (post_op_name[1] == '\0')
924            op_kind = OO_Amp;
925        else if (post_op_name[2] == '\0')
926        {
927            switch (post_op_name[1])
928            {
929            case '=': op_kind = OO_AmpEqual; break;
930            case '&': op_kind = OO_AmpAmp; break;
931            }
932        }
933        break;
934
935    case '|':
936        if (post_op_name[1] == '\0')
937            op_kind = OO_Pipe;
938        else if (post_op_name[2] == '\0')
939        {
940            switch (post_op_name[1])
941            {
942            case '=': op_kind = OO_PipeEqual; break;
943            case '|': op_kind = OO_PipePipe; break;
944            }
945        }
946        break;
947
948    case '~':
949        if (post_op_name[1] == '\0')
950            op_kind = OO_Tilde;
951        break;
952
953    case '!':
954        if (post_op_name[1] == '\0')
955            op_kind = OO_Exclaim;
956        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
957            op_kind = OO_ExclaimEqual;
958        break;
959
960    case '=':
961        if (post_op_name[1] == '\0')
962            op_kind = OO_Equal;
963        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
964            op_kind = OO_EqualEqual;
965        break;
966
967    case '<':
968        if (post_op_name[1] == '\0')
969            op_kind = OO_Less;
970        else if (post_op_name[2] == '\0')
971        {
972            switch (post_op_name[1])
973            {
974            case '<': op_kind = OO_LessLess; break;
975            case '=': op_kind = OO_LessEqual; break;
976            }
977        }
978        else if (post_op_name[3] == '\0')
979        {
980            if (post_op_name[2] == '=')
981                op_kind = OO_LessLessEqual;
982        }
983        break;
984
985    case '>':
986        if (post_op_name[1] == '\0')
987            op_kind = OO_Greater;
988        else if (post_op_name[2] == '\0')
989        {
990            switch (post_op_name[1])
991            {
992            case '>': op_kind = OO_GreaterGreater; break;
993            case '=': op_kind = OO_GreaterEqual; break;
994            }
995        }
996        else if (post_op_name[1] == '>' &&
997                 post_op_name[2] == '=' &&
998                 post_op_name[3] == '\0')
999        {
1000                op_kind = OO_GreaterGreaterEqual;
1001        }
1002        break;
1003
1004    case ',':
1005        if (post_op_name[1] == '\0')
1006            op_kind = OO_Comma;
1007        break;
1008
1009    case '(':
1010        if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1011            op_kind = OO_Call;
1012        break;
1013
1014    case '[':
1015        if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1016            op_kind = OO_Subscript;
1017        break;
1018    }
1019
1020    return true;
1021}
1022CXXMethodDecl *
1023ClangASTContext::AddMethodToCXXRecordType
1024(
1025    ASTContext *ast_context,
1026    clang_type_t record_opaque_type,
1027    const char *name,
1028    clang_type_t method_opaque_type,
1029    lldb::AccessType access,
1030    bool is_virtual,
1031    bool is_static,
1032    bool is_inline,
1033    bool is_explicit
1034)
1035{
1036    if (!record_opaque_type || !method_opaque_type || !name)
1037        return NULL;
1038
1039    assert(ast_context);
1040
1041    IdentifierTable *identifier_table = &ast_context->Idents;
1042
1043    assert(identifier_table);
1044
1045    QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
1046
1047    clang::Type *clang_type(record_qual_type.getTypePtr());
1048
1049    if (clang_type == NULL)
1050        return NULL;
1051
1052    RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
1053
1054    if (record_clang_type == NULL)
1055        return NULL;
1056
1057    RecordDecl *record_decl = record_clang_type->getDecl();
1058
1059    if (record_decl == NULL)
1060        return NULL;
1061
1062    CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1063
1064    if (cxx_record_decl == NULL)
1065        return NULL;
1066
1067    QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1068
1069    CXXMethodDecl *cxx_method_decl = NULL;
1070
1071    DeclarationName decl_name (&identifier_table->get(name));
1072
1073    const bool is_implicitly_declared = false;
1074
1075    clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
1076
1077    if (function_Type == NULL)
1078        return NULL;
1079
1080    FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
1081
1082    if (!method_function_prototype)
1083        return NULL;
1084
1085    unsigned int num_params = method_function_prototype->getNumArgs();
1086
1087    if (name[0] == '~')
1088    {
1089        cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1090                                                     cxx_record_decl,
1091                                                     DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
1092                                                     method_qual_type,
1093                                                     is_inline,
1094                                                     is_implicitly_declared);
1095    }
1096    else if (decl_name == record_decl->getDeclName())
1097    {
1098        cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1099                                                      cxx_record_decl,
1100                                                      DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
1101                                                      method_qual_type,
1102                                                      NULL, // TypeSourceInfo *
1103                                                      is_explicit,
1104                                                      is_inline,
1105                                                      is_implicitly_declared);
1106    }
1107    else
1108    {
1109
1110        OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1111        if (IsOperator (name, op_kind))
1112        {
1113            if (op_kind != NUM_OVERLOADED_OPERATORS)
1114            {
1115                cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1116                                                         cxx_record_decl,
1117                                                         DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
1118                                                         method_qual_type,
1119                                                         NULL, // TypeSourceInfo *
1120                                                         is_static,
1121                                                         SC_None,
1122                                                         is_inline);
1123            }
1124            else if (num_params == 0)
1125            {
1126                // Conversion operators don't take params...
1127                cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1128                                                             cxx_record_decl,
1129                                                             DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
1130                                                             method_qual_type,
1131                                                             NULL, // TypeSourceInfo *
1132                                                             is_inline,
1133                                                             is_explicit);
1134            }
1135        }
1136
1137        if (cxx_method_decl == NULL)
1138        {
1139            cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1140                                                     cxx_record_decl,
1141                                                     DeclarationNameInfo (decl_name, SourceLocation()),
1142                                                     method_qual_type,
1143                                                     NULL, // TypeSourceInfo *
1144                                                     is_static,
1145                                                     SC_None,
1146                                                     is_inline);
1147        }
1148    }
1149
1150    AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
1151
1152    cxx_method_decl->setAccess (access_specifier);
1153    cxx_method_decl->setVirtualAsWritten (is_virtual);
1154
1155    // Populate the method decl with parameter decls
1156
1157    ParmVarDecl *params[num_params];
1158
1159    for (int param_index = 0;
1160         param_index < num_params;
1161         ++param_index)
1162    {
1163        params[param_index] = ParmVarDecl::Create (*ast_context,
1164                                                   cxx_method_decl,
1165                                                   SourceLocation(),
1166                                                   NULL, // anonymous
1167                                                   method_function_prototype->getArgType(param_index),
1168                                                   NULL,
1169                                                   SC_None,
1170                                                   SC_None,
1171                                                   NULL);
1172    }
1173
1174    cxx_method_decl->setParams (params, num_params);
1175
1176    cxx_record_decl->addDecl (cxx_method_decl);
1177
1178    return cxx_method_decl;
1179}
1180
1181bool
1182ClangASTContext::AddFieldToRecordType
1183(
1184    ASTContext *ast_context,
1185    clang_type_t record_clang_type,
1186    const char *name,
1187    clang_type_t field_type,
1188    AccessType access,
1189    uint32_t bitfield_bit_size
1190)
1191{
1192    if (record_clang_type == NULL || field_type == NULL)
1193        return false;
1194
1195    IdentifierTable *identifier_table = &ast_context->Idents;
1196
1197    assert (ast_context != NULL);
1198    assert (identifier_table != NULL);
1199
1200    QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1201
1202    clang::Type *clang_type = record_qual_type.getTypePtr();
1203    if (clang_type)
1204    {
1205        const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1206
1207        if (record_type)
1208        {
1209            RecordDecl *record_decl = record_type->getDecl();
1210
1211            clang::Expr *bit_width = NULL;
1212            if (bitfield_bit_size != 0)
1213            {
1214                APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
1215                bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
1216            }
1217            FieldDecl *field = FieldDecl::Create (*ast_context,
1218                                                  record_decl,
1219                                                  SourceLocation(),
1220                                                  name ? &identifier_table->get(name) : NULL, // Identifier
1221                                                  QualType::getFromOpaquePtr(field_type), // Field type
1222                                                  NULL,       // DeclaratorInfo *
1223                                                  bit_width,  // BitWidth
1224                                                  false);     // Mutable
1225
1226            field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
1227
1228            if (field)
1229            {
1230                record_decl->addDecl(field);
1231            }
1232        }
1233        else
1234        {
1235            ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1236            if (objc_class_type)
1237            {
1238                bool is_synthesized = false;
1239                ClangASTContext::AddObjCClassIVar (ast_context,
1240                                                   record_clang_type,
1241                                                   name,
1242                                                   field_type,
1243                                                   access,
1244                                                   bitfield_bit_size,
1245                                                   is_synthesized);
1246            }
1247        }
1248    }
1249    return false;
1250}
1251
1252bool
1253ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1254{
1255    return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1256}
1257
1258bool
1259ClangASTContext::FieldIsBitfield
1260(
1261    ASTContext *ast_context,
1262    FieldDecl* field,
1263    uint32_t& bitfield_bit_size
1264)
1265{
1266    if (ast_context == NULL || field == NULL)
1267        return false;
1268
1269    if (field->isBitField())
1270    {
1271        Expr* bit_width_expr = field->getBitWidth();
1272        if (bit_width_expr)
1273        {
1274            llvm::APSInt bit_width_apsint;
1275            if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1276            {
1277                bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1278                return true;
1279            }
1280        }
1281    }
1282    return false;
1283}
1284
1285bool
1286ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1287{
1288    if (record_decl == NULL)
1289        return false;
1290
1291    if (!record_decl->field_empty())
1292        return true;
1293
1294    // No fields, lets check this is a CXX record and check the base classes
1295    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1296    if (cxx_record_decl)
1297    {
1298        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1299        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1300             base_class != base_class_end;
1301             ++base_class)
1302        {
1303            const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1304            if (RecordHasFields(base_class_decl))
1305                return true;
1306        }
1307    }
1308    return false;
1309}
1310
1311void
1312ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
1313{
1314    if (clang_qual_type)
1315    {
1316        QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
1317        clang::Type *clang_type = qual_type.getTypePtr();
1318        if (clang_type)
1319        {
1320            RecordType *record_type = dyn_cast<RecordType>(clang_type);
1321            if (record_type)
1322            {
1323                RecordDecl *record_decl = record_type->getDecl();
1324                if (record_decl)
1325                {
1326                    uint32_t field_idx;
1327                    RecordDecl::field_iterator field, field_end;
1328                    for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1329                         field != field_end;
1330                         ++field, ++field_idx)
1331                    {
1332                        // If no accessibility was assigned, assign the correct one
1333                        if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1334                            field->setAccess ((AccessSpecifier)default_accessibility);
1335                    }
1336                }
1337            }
1338        }
1339    }
1340}
1341
1342#pragma mark C++ Base Classes
1343
1344CXXBaseSpecifier *
1345ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
1346{
1347    if (base_class_type)
1348        return new CXXBaseSpecifier (SourceRange(),
1349                                     is_virtual,
1350                                     base_of_class,
1351                                     ConvertAccessTypeToAccessSpecifier (access),
1352                                     getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
1353    return NULL;
1354}
1355
1356void
1357ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1358{
1359    for (unsigned i=0; i<num_base_classes; ++i)
1360    {
1361        delete base_classes[i];
1362        base_classes[i] = NULL;
1363    }
1364}
1365
1366bool
1367ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
1368{
1369    if (class_clang_type)
1370    {
1371        clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
1372        if (clang_type)
1373        {
1374            RecordType *record_type = dyn_cast<RecordType>(clang_type);
1375            if (record_type)
1376            {
1377                CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1378                if (cxx_record_decl)
1379                {
1380                    cxx_record_decl->setBases(base_classes, num_base_classes);
1381                    return true;
1382                }
1383            }
1384        }
1385    }
1386    return false;
1387}
1388#pragma mark Objective C Classes
1389
1390clang_type_t
1391ClangASTContext::CreateObjCClass
1392(
1393    const char *name,
1394    DeclContext *decl_ctx,
1395    bool isForwardDecl,
1396    bool isInternal
1397)
1398{
1399    ASTContext *ast_context = getASTContext();
1400    assert (ast_context != NULL);
1401    assert (name && name[0]);
1402    if (decl_ctx == NULL)
1403        decl_ctx = ast_context->getTranslationUnitDecl();
1404
1405    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1406    // we will need to update this code. I was told to currently always use
1407    // the CXXRecordDecl class since we often don't know from debug information
1408    // if something is struct or a class, so we default to always use the more
1409    // complete definition just in case.
1410    ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1411                                                         decl_ctx,
1412                                                         SourceLocation(),
1413                                                         &ast_context->Idents.get(name),
1414                                                         SourceLocation(),
1415                                                         isForwardDecl,
1416                                                         isInternal);
1417
1418    return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
1419}
1420
1421bool
1422ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
1423{
1424    if (class_opaque_type && super_opaque_type)
1425    {
1426        QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1427        QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1428        clang::Type *class_type = class_qual_type.getTypePtr();
1429        clang::Type *super_type = super_qual_type.getTypePtr();
1430        if (class_type && super_type)
1431        {
1432            ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1433            ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1434            if (objc_class_type && objc_super_type)
1435            {
1436                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1437                ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1438                if (class_interface_decl && super_interface_decl)
1439                {
1440                    class_interface_decl->setSuperClass(super_interface_decl);
1441                    return true;
1442                }
1443            }
1444        }
1445    }
1446    return false;
1447}
1448
1449
1450bool
1451ClangASTContext::AddObjCClassIVar
1452(
1453    ASTContext *ast_context,
1454    clang_type_t class_opaque_type,
1455    const char *name,
1456    clang_type_t ivar_opaque_type,
1457    AccessType access,
1458    uint32_t bitfield_bit_size,
1459    bool is_synthesized
1460)
1461{
1462    if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1463        return false;
1464
1465    IdentifierTable *identifier_table = &ast_context->Idents;
1466
1467    assert (ast_context != NULL);
1468    assert (identifier_table != NULL);
1469
1470    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1471
1472    clang::Type *class_type = class_qual_type.getTypePtr();
1473    if (class_type)
1474    {
1475        ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1476
1477        if (objc_class_type)
1478        {
1479            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1480
1481            if (class_interface_decl)
1482            {
1483                clang::Expr *bit_width = NULL;
1484                if (bitfield_bit_size != 0)
1485                {
1486                    APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
1487                    bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
1488                }
1489
1490                ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1491                                                            class_interface_decl,
1492                                                            SourceLocation(),
1493                                                            &identifier_table->get(name), // Identifier
1494                                                            QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1495                                                            NULL, // TypeSourceInfo *
1496                                                            ConvertAccessTypeToObjCIvarAccessControl (access),
1497                                                            bit_width,
1498                                                            is_synthesized);
1499
1500                if (field)
1501                {
1502                    class_interface_decl->addDecl(field);
1503                    return true;
1504                }
1505            }
1506        }
1507    }
1508    return false;
1509}
1510
1511
1512bool
1513ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
1514{
1515    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1516
1517    clang::Type *class_type = class_qual_type.getTypePtr();
1518    if (class_type)
1519    {
1520        ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1521
1522        if (objc_class_type)
1523            return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1524    }
1525    return false;
1526}
1527
1528bool
1529ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1530{
1531    while (class_interface_decl)
1532    {
1533        if (class_interface_decl->ivar_size() > 0)
1534            return true;
1535
1536        if (check_superclass)
1537            class_interface_decl = class_interface_decl->getSuperClass();
1538        else
1539            break;
1540    }
1541    return false;
1542}
1543
1544ObjCMethodDecl *
1545ClangASTContext::AddMethodToObjCObjectType
1546(
1547    ASTContext *ast_context,
1548    clang_type_t class_opaque_type,
1549    const char *name,  // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
1550    clang_type_t method_opaque_type,
1551    lldb::AccessType access
1552)
1553{
1554    if (class_opaque_type == NULL || method_opaque_type == NULL)
1555        return NULL;
1556
1557    IdentifierTable *identifier_table = &ast_context->Idents;
1558
1559    assert (ast_context != NULL);
1560    assert (identifier_table != NULL);
1561
1562    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1563
1564    clang::Type *class_type = class_qual_type.getTypePtr();
1565    if (class_type == NULL)
1566        return NULL;
1567
1568    ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1569
1570    if (objc_class_type == NULL)
1571        return NULL;
1572
1573    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1574
1575    if (class_interface_decl == NULL)
1576        return NULL;
1577
1578    const char *selector_start = ::strchr (name, ' ');
1579    if (selector_start == NULL)
1580        return NULL;
1581
1582    selector_start++;
1583    if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1584        return NULL;
1585    llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1586
1587    size_t len = 0;
1588    const char *start;
1589    //printf ("name = '%s'\n", name);
1590
1591    unsigned num_selectors_with_args = 0;
1592    for (start = selector_start;
1593         start && *start != '\0' && *start != ']';
1594         start += len)
1595    {
1596        len = ::strcspn(start, ":]");
1597        bool has_arg = (start[len] == ':');
1598        if (has_arg)
1599            ++num_selectors_with_args;
1600        selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
1601        if (has_arg)
1602            len += 1;
1603    }
1604
1605
1606    if (selector_idents.size() == 0)
1607        return 0;
1608
1609    clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
1610                                                                          selector_idents.data());
1611
1612    QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1613
1614    // Populate the method decl with parameter decls
1615    clang::Type *method_type(method_qual_type.getTypePtr());
1616
1617    if (method_type == NULL)
1618        return NULL;
1619
1620    FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1621
1622    if (!method_function_prototype)
1623        return NULL;
1624
1625
1626    bool is_variadic = false;
1627    bool is_synthesized = false;
1628    bool is_defined = false;
1629    ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1630
1631    const unsigned num_args = method_function_prototype->getNumArgs();
1632
1633    ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1634                                                               SourceLocation(), // beginLoc,
1635                                                               SourceLocation(), // endLoc,
1636                                                               method_selector,
1637                                                               method_function_prototype->getResultType(),
1638                                                               NULL, // TypeSourceInfo *ResultTInfo,
1639                                                               GetDeclContextForType (class_opaque_type),
1640                                                               name[0] == '-',
1641                                                               is_variadic,
1642                                                               is_synthesized,
1643                                                               is_defined,
1644                                                               imp_control,
1645                                                               num_args);
1646
1647
1648    if (objc_method_decl == NULL)
1649        return NULL;
1650
1651    if (num_args > 0)
1652    {
1653        llvm::SmallVector<ParmVarDecl *, 12> params;
1654
1655        for (int param_index = 0; param_index < num_args; ++param_index)
1656        {
1657            params.push_back (ParmVarDecl::Create (*ast_context,
1658                                                   objc_method_decl,
1659                                                   SourceLocation(),
1660                                                   NULL, // anonymous
1661                                                   method_function_prototype->getArgType(param_index),
1662                                                   NULL,
1663                                                   SC_Auto,
1664                                                   SC_Auto,
1665                                                   NULL));
1666        }
1667
1668        objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1669    }
1670
1671    class_interface_decl->addDecl (objc_method_decl);
1672
1673
1674    return objc_method_decl;
1675}
1676
1677
1678uint32_t
1679ClangASTContext::GetTypeInfo
1680(
1681    clang_type_t clang_type,
1682    clang::ASTContext *ast_context,
1683    clang_type_t *pointee_or_element_clang_type
1684)
1685{
1686    if (clang_type == NULL)
1687        return 0;
1688
1689    if (pointee_or_element_clang_type)
1690        *pointee_or_element_clang_type = NULL;
1691
1692    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1693
1694    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1695    switch (type_class)
1696    {
1697    case clang::Type::Builtin:
1698        switch (cast<clang::BuiltinType>(qual_type)->getKind())
1699        {
1700        case clang::BuiltinType::ObjCId:
1701        case clang::BuiltinType::ObjCClass:
1702            if (ast_context && pointee_or_element_clang_type)
1703                *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
1704            return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
1705
1706        default:
1707            break;
1708        }
1709        return eTypeIsBuiltIn | eTypeHasValue;
1710
1711    case clang::Type::BlockPointer:
1712        if (pointee_or_element_clang_type)
1713            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1714        return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1715
1716    case clang::Type::Complex:                          return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
1717
1718    case clang::Type::ConstantArray:
1719    case clang::Type::DependentSizedArray:
1720    case clang::Type::IncompleteArray:
1721    case clang::Type::VariableArray:
1722        if (pointee_or_element_clang_type)
1723            *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1724        return eTypeHasChildren | eTypeIsArray;
1725
1726    case clang::Type::DependentName:                    return 0;
1727    case clang::Type::DependentSizedExtVector:          return eTypeHasChildren | eTypeIsVector;
1728    case clang::Type::DependentTemplateSpecialization:  return eTypeIsTemplate;
1729    case clang::Type::Decltype:                         return 0;
1730
1731    case clang::Type::Enum:
1732        if (pointee_or_element_clang_type)
1733            *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1734        return eTypeIsEnumeration | eTypeHasValue;
1735
1736    case clang::Type::Elaborated:                       return 0;
1737    case clang::Type::ExtVector:                        return eTypeHasChildren | eTypeIsVector;
1738    case clang::Type::FunctionProto:                    return eTypeIsFuncPrototype | eTypeHasValue;
1739    case clang::Type::FunctionNoProto:                  return eTypeIsFuncPrototype | eTypeHasValue;
1740    case clang::Type::InjectedClassName:                return 0;
1741
1742    case clang::Type::LValueReference:
1743    case clang::Type::RValueReference:
1744        if (pointee_or_element_clang_type)
1745            *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1746        return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1747
1748    case clang::Type::MemberPointer:                    return eTypeIsPointer   | eTypeIsMember | eTypeHasValue;
1749
1750    case clang::Type::ObjCObjectPointer:
1751        if (pointee_or_element_clang_type)
1752            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1753        return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1754
1755    case clang::Type::ObjCObject:                       return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1756    case clang::Type::ObjCInterface:                    return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1757
1758    case clang::Type::Pointer:
1759        if (pointee_or_element_clang_type)
1760            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1761        return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1762
1763    case clang::Type::Record:
1764        if (qual_type->getAsCXXRecordDecl())
1765            return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1766        else
1767            return eTypeHasChildren | eTypeIsStructUnion;
1768        break;
1769    case clang::Type::SubstTemplateTypeParm:            return eTypeIsTemplate;
1770    case clang::Type::TemplateTypeParm:                 return eTypeIsTemplate;
1771    case clang::Type::TemplateSpecialization:           return eTypeIsTemplate;
1772
1773    case clang::Type::Typedef:
1774        return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1775                                                                  ast_context,
1776                                                                  pointee_or_element_clang_type);
1777
1778    case clang::Type::TypeOfExpr:                       return 0;
1779    case clang::Type::TypeOf:                           return 0;
1780    case clang::Type::UnresolvedUsing:                  return 0;
1781    case clang::Type::Vector:                           return eTypeHasChildren | eTypeIsVector;
1782    default:                                            return 0;
1783    }
1784    return 0;
1785}
1786
1787
1788#pragma mark Aggregate Types
1789
1790bool
1791ClangASTContext::IsAggregateType (clang_type_t clang_type)
1792{
1793    if (clang_type == NULL)
1794        return false;
1795
1796    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1797
1798    if (qual_type->isAggregateType ())
1799        return true;
1800
1801    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1802    switch (type_class)
1803    {
1804    case clang::Type::IncompleteArray:
1805    case clang::Type::VariableArray:
1806    case clang::Type::ConstantArray:
1807    case clang::Type::ExtVector:
1808    case clang::Type::Vector:
1809    case clang::Type::Record:
1810    case clang::Type::ObjCObject:
1811    case clang::Type::ObjCInterface:
1812        return true;
1813
1814    case clang::Type::Typedef:
1815        return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1816
1817    default:
1818        break;
1819    }
1820    // The clang type does have a value
1821    return false;
1822}
1823
1824uint32_t
1825ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
1826{
1827    if (clang_qual_type == NULL)
1828        return 0;
1829
1830    uint32_t num_children = 0;
1831    QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
1832    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1833    switch (type_class)
1834    {
1835    case clang::Type::Builtin:
1836        switch (cast<clang::BuiltinType>(qual_type)->getKind())
1837        {
1838        case clang::BuiltinType::ObjCId:    // child is Class
1839        case clang::BuiltinType::ObjCClass: // child is Class
1840            num_children = 1;
1841            break;
1842
1843        default:
1844            break;
1845        }
1846        break;
1847
1848    case clang::Type::Record:
1849        {
1850            const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1851            const RecordDecl *record_decl = record_type->getDecl();
1852            assert(record_decl);
1853            const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1854            if (cxx_record_decl)
1855            {
1856                if (omit_empty_base_classes)
1857                {
1858                    // Check each base classes to see if it or any of its
1859                    // base classes contain any fields. This can help
1860                    // limit the noise in variable views by not having to
1861                    // show base classes that contain no members.
1862                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1863                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1864                         base_class != base_class_end;
1865                         ++base_class)
1866                    {
1867                        const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1868
1869                        // Skip empty base classes
1870                        if (RecordHasFields(base_class_decl) == false)
1871                            continue;
1872
1873                        num_children++;
1874                    }
1875                }
1876                else
1877                {
1878                    // Include all base classes
1879                    num_children += cxx_record_decl->getNumBases();
1880                }
1881
1882            }
1883            RecordDecl::field_iterator field, field_end;
1884            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1885                ++num_children;
1886        }
1887        break;
1888
1889    case clang::Type::ObjCObject:
1890    case clang::Type::ObjCInterface:
1891        {
1892            ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1893            assert (objc_class_type);
1894            if (objc_class_type)
1895            {
1896                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1897
1898                if (class_interface_decl)
1899                {
1900
1901                    ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1902                    if (superclass_interface_decl)
1903                    {
1904                        if (omit_empty_base_classes)
1905                        {
1906                            if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1907                                ++num_children;
1908                        }
1909                        else
1910                            ++num_children;
1911                    }
1912
1913                    num_children += class_interface_decl->ivar_size();
1914                }
1915            }
1916        }
1917        break;
1918
1919    case clang::Type::ObjCObjectPointer:
1920        {
1921            ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1922            QualType pointee_type = pointer_type->getPointeeType();
1923            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1924                                                                             omit_empty_base_classes);
1925            // If this type points to a simple type, then it has 1 child
1926            if (num_pointee_children == 0)
1927                num_children = 1;
1928            else
1929                num_children = num_pointee_children;
1930        }
1931        break;
1932
1933    case clang::Type::ConstantArray:
1934        num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1935        break;
1936
1937    case clang::Type::Pointer:
1938        {
1939            PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1940            QualType pointee_type = pointer_type->getPointeeType();
1941            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1942                                                                             omit_empty_base_classes);
1943            // If this type points to a simple type, then it has 1 child
1944            if (num_pointee_children == 0)
1945                num_children = 1;
1946            else
1947                num_children = num_pointee_children;
1948        }
1949        break;
1950
1951    case clang::Type::LValueReference:
1952    case clang::Type::RValueReference:
1953        {
1954            ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1955            QualType pointee_type = reference_type->getPointeeType();
1956            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1957                                                                             omit_empty_base_classes);
1958            // If this type points to a simple type, then it has 1 child
1959            if (num_pointee_children == 0)
1960                num_children = 1;
1961            else
1962                num_children = num_pointee_children;
1963        }
1964        break;
1965
1966
1967    case clang::Type::Typedef:
1968        num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1969        break;
1970
1971    default:
1972        break;
1973    }
1974    return num_children;
1975}
1976
1977
1978clang_type_t
1979ClangASTContext::GetChildClangTypeAtIndex
1980(
1981    const char *parent_name,
1982    clang_type_t parent_clang_type,
1983    uint32_t idx,
1984    bool transparent_pointers,
1985    bool omit_empty_base_classes,
1986    std::string& child_name,
1987    uint32_t &child_byte_size,
1988    int32_t &child_byte_offset,
1989    uint32_t &child_bitfield_bit_size,
1990    uint32_t &child_bitfield_bit_offset,
1991    bool &child_is_base_class
1992)
1993{
1994    if (parent_clang_type)
1995
1996        return GetChildClangTypeAtIndex (getASTContext(),
1997                                         parent_name,
1998                                         parent_clang_type,
1999                                         idx,
2000                                         transparent_pointers,
2001                                         omit_empty_base_classes,
2002                                         child_name,
2003                                         child_byte_size,
2004                                         child_byte_offset,
2005                                         child_bitfield_bit_size,
2006                                         child_bitfield_bit_offset,
2007                                         child_is_base_class);
2008    return NULL;
2009}
2010
2011clang_type_t
2012ClangASTContext::GetChildClangTypeAtIndex
2013(
2014    ASTContext *ast_context,
2015    const char *parent_name,
2016    clang_type_t parent_clang_type,
2017    uint32_t idx,
2018    bool transparent_pointers,
2019    bool omit_empty_base_classes,
2020    std::string& child_name,
2021    uint32_t &child_byte_size,
2022    int32_t &child_byte_offset,
2023    uint32_t &child_bitfield_bit_size,
2024    uint32_t &child_bitfield_bit_offset,
2025    bool &child_is_base_class
2026)
2027{
2028    if (parent_clang_type == NULL)
2029        return NULL;
2030
2031    if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2032    {
2033        uint32_t bit_offset;
2034        child_bitfield_bit_size = 0;
2035        child_bitfield_bit_offset = 0;
2036        child_is_base_class = false;
2037        QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
2038        const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2039        switch (parent_type_class)
2040        {
2041        case clang::Type::Builtin:
2042            switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2043            {
2044            case clang::BuiltinType::ObjCId:
2045            case clang::BuiltinType::ObjCClass:
2046                child_name = "isa";
2047                child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
2048                return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2049
2050            default:
2051                break;
2052            }
2053            break;
2054
2055
2056        case clang::Type::Record:
2057            {
2058                const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2059                const RecordDecl *record_decl = record_type->getDecl();
2060                assert(record_decl);
2061                const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2062                uint32_t child_idx = 0;
2063
2064                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2065                if (cxx_record_decl)
2066                {
2067                    // We might have base classes to print out first
2068                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2069                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2070                         base_class != base_class_end;
2071                         ++base_class)
2072                    {
2073                        const CXXRecordDecl *base_class_decl = NULL;
2074
2075                        // Skip empty base classes
2076                        if (omit_empty_base_classes)
2077                        {
2078                            base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2079                            if (RecordHasFields(base_class_decl) == false)
2080                                continue;
2081                        }
2082
2083                        if (idx == child_idx)
2084                        {
2085                            if (base_class_decl == NULL)
2086                                base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2087
2088
2089                            if (base_class->isVirtual())
2090                                bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
2091                            else
2092                                bit_offset = record_layout.getBaseClassOffset(base_class_decl);
2093
2094                            // Base classes should be a multiple of 8 bits in size
2095                            assert (bit_offset % 8 == 0);
2096                            child_byte_offset = bit_offset/8;
2097                            std::string base_class_type_name(base_class->getType().getAsString());
2098
2099                            child_name.assign(base_class_type_name.c_str());
2100
2101                            uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2102
2103                            // Base classes biut sizes should be a multiple of 8 bits in size
2104                            assert (clang_type_info_bit_size % 8 == 0);
2105                            child_byte_size = clang_type_info_bit_size / 8;
2106                            child_is_base_class = true;
2107                            return base_class->getType().getAsOpaquePtr();
2108                        }
2109                        // We don't increment the child index in the for loop since we might
2110                        // be skipping empty base classes
2111                        ++child_idx;
2112                    }
2113                }
2114                // Make sure index is in range...
2115                uint32_t field_idx = 0;
2116                RecordDecl::field_iterator field, field_end;
2117                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2118                {
2119                    if (idx == child_idx)
2120                    {
2121                        // Print the member type if requested
2122                        // Print the member name and equal sign
2123                        child_name.assign(field->getNameAsString().c_str());
2124
2125                        // Figure out the type byte size (field_type_info.first) and
2126                        // alignment (field_type_info.second) from the AST context.
2127                        std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
2128                        assert(field_idx < record_layout.getFieldCount());
2129
2130                        child_byte_size = field_type_info.first / 8;
2131
2132                        // Figure out the field offset within the current struct/union/class type
2133                        bit_offset = record_layout.getFieldOffset (field_idx);
2134                        child_byte_offset = bit_offset / 8;
2135                        if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2136                            child_bitfield_bit_offset = bit_offset % 8;
2137
2138                        return field->getType().getAsOpaquePtr();
2139                    }
2140                }
2141            }
2142            break;
2143
2144        case clang::Type::ObjCObject:
2145        case clang::Type::ObjCInterface:
2146            {
2147                ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2148                assert (objc_class_type);
2149                if (objc_class_type)
2150                {
2151                    uint32_t child_idx = 0;
2152                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2153
2154                    if (class_interface_decl)
2155                    {
2156
2157                        const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2158                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2159                        if (superclass_interface_decl)
2160                        {
2161                            if (omit_empty_base_classes)
2162                            {
2163                                if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
2164                                {
2165                                    if (idx == 0)
2166                                    {
2167                                        QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2168
2169
2170                                        child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2171
2172                                        std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2173
2174                                        child_byte_size = ivar_type_info.first / 8;
2175                                        child_byte_offset = 0;
2176                                        child_is_base_class = true;
2177
2178                                        return ivar_qual_type.getAsOpaquePtr();
2179                                    }
2180
2181                                    ++child_idx;
2182                                }
2183                            }
2184                            else
2185                                ++child_idx;
2186                        }
2187
2188                        const uint32_t superclass_idx = child_idx;
2189
2190                        if (idx < (child_idx + class_interface_decl->ivar_size()))
2191                        {
2192                            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2193
2194                            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2195                            {
2196                                if (child_idx == idx)
2197                                {
2198                                    const ObjCIvarDecl* ivar_decl = *ivar_pos;
2199
2200                                    QualType ivar_qual_type(ivar_decl->getType());
2201
2202                                    child_name.assign(ivar_decl->getNameAsString().c_str());
2203
2204                                    std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2205
2206                                    child_byte_size = ivar_type_info.first / 8;
2207
2208                                    // Figure out the field offset within the current struct/union/class type
2209                                    bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
2210                                    child_byte_offset = bit_offset / 8;
2211
2212                                    return ivar_qual_type.getAsOpaquePtr();
2213                                }
2214                                ++child_idx;
2215                            }
2216                        }
2217                    }
2218                }
2219            }
2220            break;
2221
2222        case clang::Type::ObjCObjectPointer:
2223            {
2224                ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2225                QualType pointee_type = pointer_type->getPointeeType();
2226
2227                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2228                {
2229                    return GetChildClangTypeAtIndex (ast_context,
2230                                                     parent_name,
2231                                                     pointer_type->getPointeeType().getAsOpaquePtr(),
2232                                                     idx,
2233                                                     transparent_pointers,
2234                                                     omit_empty_base_classes,
2235                                                     child_name,
2236                                                     child_byte_size,
2237                                                     child_byte_offset,
2238                                                     child_bitfield_bit_size,
2239                                                     child_bitfield_bit_offset,
2240                                                     child_is_base_class);
2241                }
2242                else
2243                {
2244                    if (parent_name)
2245                    {
2246                        child_name.assign(1, '*');
2247                        child_name += parent_name;
2248                    }
2249
2250                    // We have a pointer to an simple type
2251                    if (idx == 0)
2252                    {
2253                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2254                        assert(clang_type_info.first % 8 == 0);
2255                        child_byte_size = clang_type_info.first / 8;
2256                        child_byte_offset = 0;
2257                        return pointee_type.getAsOpaquePtr();
2258                    }
2259                }
2260            }
2261            break;
2262
2263        case clang::Type::ConstantArray:
2264            {
2265                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2266                const uint64_t element_count = array->getSize().getLimitedValue();
2267
2268                if (idx < element_count)
2269                {
2270                    std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2271
2272                    char element_name[64];
2273                    ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
2274
2275                    child_name.assign(element_name);
2276                    assert(field_type_info.first % 8 == 0);
2277                    child_byte_size = field_type_info.first / 8;
2278                    child_byte_offset = idx * child_byte_size;
2279                    return array->getElementType().getAsOpaquePtr();
2280                }
2281            }
2282            break;
2283
2284        case clang::Type::Pointer:
2285            {
2286                PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2287                QualType pointee_type = pointer_type->getPointeeType();
2288
2289                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2290                {
2291                    return GetChildClangTypeAtIndex (ast_context,
2292                                                     parent_name,
2293                                                     pointer_type->getPointeeType().getAsOpaquePtr(),
2294                                                     idx,
2295                                                     transparent_pointers,
2296                                                     omit_empty_base_classes,
2297                                                     child_name,
2298                                                     child_byte_size,
2299                                                     child_byte_offset,
2300                                                     child_bitfield_bit_size,
2301                                                     child_bitfield_bit_offset,
2302                                                     child_is_base_class);
2303                }
2304                else
2305                {
2306                    if (parent_name)
2307                    {
2308                        child_name.assign(1, '*');
2309                        child_name += parent_name;
2310                    }
2311
2312                    // We have a pointer to an simple type
2313                    if (idx == 0)
2314                    {
2315                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2316                        assert(clang_type_info.first % 8 == 0);
2317                        child_byte_size = clang_type_info.first / 8;
2318                        child_byte_offset = 0;
2319                        return pointee_type.getAsOpaquePtr();
2320                    }
2321                }
2322            }
2323            break;
2324
2325        case clang::Type::LValueReference:
2326        case clang::Type::RValueReference:
2327            {
2328                ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2329                QualType pointee_type(reference_type->getPointeeType());
2330                clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2331                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2332                {
2333                    return GetChildClangTypeAtIndex (ast_context,
2334                                                     parent_name,
2335                                                     pointee_clang_type,
2336                                                     idx,
2337                                                     transparent_pointers,
2338                                                     omit_empty_base_classes,
2339                                                     child_name,
2340                                                     child_byte_size,
2341                                                     child_byte_offset,
2342                                                     child_bitfield_bit_size,
2343                                                     child_bitfield_bit_offset,
2344                                                     child_is_base_class);
2345                }
2346                else
2347                {
2348                    if (parent_name)
2349                    {
2350                        child_name.assign(1, '&');
2351                        child_name += parent_name;
2352                    }
2353
2354                    // We have a pointer to an simple type
2355                    if (idx == 0)
2356                    {
2357                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2358                        assert(clang_type_info.first % 8 == 0);
2359                        child_byte_size = clang_type_info.first / 8;
2360                        child_byte_offset = 0;
2361                        return pointee_type.getAsOpaquePtr();
2362                    }
2363                }
2364            }
2365            break;
2366
2367        case clang::Type::Typedef:
2368            return GetChildClangTypeAtIndex (ast_context,
2369                                             parent_name,
2370                                             cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2371                                             idx,
2372                                             transparent_pointers,
2373                                             omit_empty_base_classes,
2374                                             child_name,
2375                                             child_byte_size,
2376                                             child_byte_offset,
2377                                             child_bitfield_bit_size,
2378                                             child_bitfield_bit_offset,
2379                                             child_is_base_class);
2380            break;
2381
2382        default:
2383            break;
2384        }
2385    }
2386    return NULL;
2387}
2388
2389static inline bool
2390BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2391{
2392    return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2393}
2394
2395static uint32_t
2396GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2397{
2398    uint32_t num_bases = 0;
2399    if (cxx_record_decl)
2400    {
2401        if (omit_empty_base_classes)
2402        {
2403            CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2404            for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2405                 base_class != base_class_end;
2406                 ++base_class)
2407            {
2408                // Skip empty base classes
2409                if (omit_empty_base_classes)
2410                {
2411                    if (BaseSpecifierIsEmpty (base_class))
2412                        continue;
2413                }
2414                ++num_bases;
2415            }
2416        }
2417        else
2418            num_bases = cxx_record_decl->getNumBases();
2419    }
2420    return num_bases;
2421}
2422
2423
2424static uint32_t
2425GetIndexForRecordBase
2426(
2427    const RecordDecl *record_decl,
2428    const CXXBaseSpecifier *base_spec,
2429    bool omit_empty_base_classes
2430)
2431{
2432    uint32_t child_idx = 0;
2433
2434    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2435
2436//    const char *super_name = record_decl->getNameAsCString();
2437//    const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2438//    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2439//
2440    if (cxx_record_decl)
2441    {
2442        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2443        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2444             base_class != base_class_end;
2445             ++base_class)
2446        {
2447            if (omit_empty_base_classes)
2448            {
2449                if (BaseSpecifierIsEmpty (base_class))
2450                    continue;
2451            }
2452
2453//            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2454//                    child_idx,
2455//                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2456//
2457//
2458            if (base_class == base_spec)
2459                return child_idx;
2460            ++child_idx;
2461        }
2462    }
2463
2464    return UINT32_MAX;
2465}
2466
2467
2468static uint32_t
2469GetIndexForRecordChild
2470(
2471    const RecordDecl *record_decl,
2472    NamedDecl *canonical_decl,
2473    bool omit_empty_base_classes
2474)
2475{
2476    uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2477
2478//    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2479//
2480////    printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2481//    if (cxx_record_decl)
2482//    {
2483//        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2484//        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2485//             base_class != base_class_end;
2486//             ++base_class)
2487//        {
2488//            if (omit_empty_base_classes)
2489//            {
2490//                if (BaseSpecifierIsEmpty (base_class))
2491//                    continue;
2492//            }
2493//
2494////            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2495////                    record_decl->getNameAsCString(),
2496////                    canonical_decl->getNameAsCString(),
2497////                    child_idx,
2498////                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2499//
2500//
2501//            CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2502//            if (curr_base_class_decl == canonical_decl)
2503//            {
2504//                return child_idx;
2505//            }
2506//            ++child_idx;
2507//        }
2508//    }
2509//
2510//    const uint32_t num_bases = child_idx;
2511    RecordDecl::field_iterator field, field_end;
2512    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2513         field != field_end;
2514         ++field, ++child_idx)
2515    {
2516//            printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2517//                    record_decl->getNameAsCString(),
2518//                    canonical_decl->getNameAsCString(),
2519//                    child_idx - num_bases,
2520//                    field->getNameAsCString());
2521
2522        if (field->getCanonicalDecl() == canonical_decl)
2523            return child_idx;
2524    }
2525
2526    return UINT32_MAX;
2527}
2528
2529// Look for a child member (doesn't include base classes, but it does include
2530// their members) in the type hierarchy. Returns an index path into "clang_type"
2531// on how to reach the appropriate member.
2532//
2533//    class A
2534//    {
2535//    public:
2536//        int m_a;
2537//        int m_b;
2538//    };
2539//
2540//    class B
2541//    {
2542//    };
2543//
2544//    class C :
2545//        public B,
2546//        public A
2547//    {
2548//    };
2549//
2550// If we have a clang type that describes "class C", and we wanted to looked
2551// "m_b" in it:
2552//
2553// With omit_empty_base_classes == false we would get an integer array back with:
2554// { 1,  1 }
2555// The first index 1 is the child index for "class A" within class C
2556// The second index 1 is the child index for "m_b" within class A
2557//
2558// With omit_empty_base_classes == true we would get an integer array back with:
2559// { 0,  1 }
2560// 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)
2561// The second index 1 is the child index for "m_b" within class A
2562
2563size_t
2564ClangASTContext::GetIndexOfChildMemberWithName
2565(
2566    ASTContext *ast_context,
2567    clang_type_t clang_type,
2568    const char *name,
2569    bool omit_empty_base_classes,
2570    std::vector<uint32_t>& child_indexes
2571)
2572{
2573    if (clang_type && name && name[0])
2574    {
2575        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2576        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2577        switch (type_class)
2578        {
2579        case clang::Type::Record:
2580            {
2581                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2582                const RecordDecl *record_decl = record_type->getDecl();
2583
2584                assert(record_decl);
2585                uint32_t child_idx = 0;
2586
2587                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2588
2589                // Try and find a field that matches NAME
2590                RecordDecl::field_iterator field, field_end;
2591                StringRef name_sref(name);
2592                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2593                     field != field_end;
2594                     ++field, ++child_idx)
2595                {
2596                    if (field->getName().equals (name_sref))
2597                    {
2598                        // We have to add on the number of base classes to this index!
2599                        child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2600                        return child_indexes.size();
2601                    }
2602                }
2603
2604                if (cxx_record_decl)
2605                {
2606                    const RecordDecl *parent_record_decl = cxx_record_decl;
2607
2608                    //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2609
2610                    //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2611                    // Didn't find things easily, lets let clang do its thang...
2612                    IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2613                    DeclarationName decl_name(&ident_ref);
2614
2615                    CXXBasePaths paths;
2616                    if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2617                                                       decl_name.getAsOpaquePtr(),
2618                                                       paths))
2619                    {
2620                        CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2621                        for (path = paths.begin(); path != path_end; ++path)
2622                        {
2623                            const size_t num_path_elements = path->size();
2624                            for (size_t e=0; e<num_path_elements; ++e)
2625                            {
2626                                CXXBasePathElement elem = (*path)[e];
2627
2628                                child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2629                                if (child_idx == UINT32_MAX)
2630                                {
2631                                    child_indexes.clear();
2632                                    return 0;
2633                                }
2634                                else
2635                                {
2636                                    child_indexes.push_back (child_idx);
2637                                    parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2638                                }
2639                            }
2640                            DeclContext::lookup_iterator named_decl_pos;
2641                            for (named_decl_pos = path->Decls.first;
2642                                 named_decl_pos != path->Decls.second && parent_record_decl;
2643                                 ++named_decl_pos)
2644                            {
2645                                //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2646
2647                                child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2648                                if (child_idx == UINT32_MAX)
2649                                {
2650                                    child_indexes.clear();
2651                                    return 0;
2652                                }
2653                                else
2654                                {
2655                                    child_indexes.push_back (child_idx);
2656                                }
2657                            }
2658                        }
2659                        return child_indexes.size();
2660                    }
2661                }
2662
2663            }
2664            break;
2665
2666        case clang::Type::ObjCObject:
2667        case clang::Type::ObjCInterface:
2668            {
2669                StringRef name_sref(name);
2670                ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2671                assert (objc_class_type);
2672                if (objc_class_type)
2673                {
2674                    uint32_t child_idx = 0;
2675                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2676
2677                    if (class_interface_decl)
2678                    {
2679                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2680                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2681
2682                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
2683                        {
2684                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
2685
2686                            if (ivar_decl->getName().equals (name_sref))
2687                            {
2688                                if ((!omit_empty_base_classes && superclass_interface_decl) ||
2689                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2690                                    ++child_idx;
2691
2692                                child_indexes.push_back (child_idx);
2693                                return child_indexes.size();
2694                            }
2695                        }
2696
2697                        if (superclass_interface_decl)
2698                        {
2699                            // The super class index is always zero for ObjC classes,
2700                            // so we push it onto the child indexes in case we find
2701                            // an ivar in our superclass...
2702                            child_indexes.push_back (0);
2703
2704                            if (GetIndexOfChildMemberWithName (ast_context,
2705                                                               ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2706                                                               name,
2707                                                               omit_empty_base_classes,
2708                                                               child_indexes))
2709                            {
2710                                // We did find an ivar in a superclass so just
2711                                // return the results!
2712                                return child_indexes.size();
2713                            }
2714
2715                            // We didn't find an ivar matching "name" in our
2716                            // superclass, pop the superclass zero index that
2717                            // we pushed on above.
2718                            child_indexes.pop_back();
2719                        }
2720                    }
2721                }
2722            }
2723            break;
2724
2725        case clang::Type::ObjCObjectPointer:
2726            {
2727                return GetIndexOfChildMemberWithName (ast_context,
2728                                                      cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2729                                                      name,
2730                                                      omit_empty_base_classes,
2731                                                      child_indexes);
2732            }
2733            break;
2734
2735
2736        case clang::Type::ConstantArray:
2737            {
2738//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2739//                const uint64_t element_count = array->getSize().getLimitedValue();
2740//
2741//                if (idx < element_count)
2742//                {
2743//                    std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2744//
2745//                    char element_name[32];
2746//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2747//
2748//                    child_name.assign(element_name);
2749//                    assert(field_type_info.first % 8 == 0);
2750//                    child_byte_size = field_type_info.first / 8;
2751//                    child_byte_offset = idx * child_byte_size;
2752//                    return array->getElementType().getAsOpaquePtr();
2753//                }
2754            }
2755            break;
2756
2757//        case clang::Type::MemberPointerType:
2758//            {
2759//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2760//                QualType pointee_type = mem_ptr_type->getPointeeType();
2761//
2762//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2763//                {
2764//                    return GetIndexOfChildWithName (ast_context,
2765//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2766//                                                    name);
2767//                }
2768//            }
2769//            break;
2770//
2771        case clang::Type::LValueReference:
2772        case clang::Type::RValueReference:
2773            {
2774                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2775                QualType pointee_type = reference_type->getPointeeType();
2776
2777                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2778                {
2779                    return GetIndexOfChildMemberWithName (ast_context,
2780                                                          reference_type->getPointeeType().getAsOpaquePtr(),
2781                                                          name,
2782                                                          omit_empty_base_classes,
2783                                                          child_indexes);
2784                }
2785            }
2786            break;
2787
2788        case clang::Type::Pointer:
2789            {
2790                PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2791                QualType pointee_type = pointer_type->getPointeeType();
2792
2793                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2794                {
2795                    return GetIndexOfChildMemberWithName (ast_context,
2796                                                          pointer_type->getPointeeType().getAsOpaquePtr(),
2797                                                          name,
2798                                                          omit_empty_base_classes,
2799                                                          child_indexes);
2800                }
2801                else
2802                {
2803//                    if (parent_name)
2804//                    {
2805//                        child_name.assign(1, '*');
2806//                        child_name += parent_name;
2807//                    }
2808//
2809//                    // We have a pointer to an simple type
2810//                    if (idx == 0)
2811//                    {
2812//                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2813//                        assert(clang_type_info.first % 8 == 0);
2814//                        child_byte_size = clang_type_info.first / 8;
2815//                        child_byte_offset = 0;
2816//                        return pointee_type.getAsOpaquePtr();
2817//                    }
2818                }
2819            }
2820            break;
2821
2822        case clang::Type::Typedef:
2823            return GetIndexOfChildMemberWithName (ast_context,
2824                                                  cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2825                                                  name,
2826                                                  omit_empty_base_classes,
2827                                                  child_indexes);
2828
2829        default:
2830            break;
2831        }
2832    }
2833    return 0;
2834}
2835
2836
2837// Get the index of the child of "clang_type" whose name matches. This function
2838// doesn't descend into the children, but only looks one level deep and name
2839// matches can include base class names.
2840
2841uint32_t
2842ClangASTContext::GetIndexOfChildWithName
2843(
2844    ASTContext *ast_context,
2845    clang_type_t clang_type,
2846    const char *name,
2847    bool omit_empty_base_classes
2848)
2849{
2850    if (clang_type && name && name[0])
2851    {
2852        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2853
2854        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2855
2856        switch (type_class)
2857        {
2858        case clang::Type::Record:
2859            {
2860                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2861                const RecordDecl *record_decl = record_type->getDecl();
2862
2863                assert(record_decl);
2864                uint32_t child_idx = 0;
2865
2866                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2867
2868                if (cxx_record_decl)
2869                {
2870                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2871                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2872                         base_class != base_class_end;
2873                         ++base_class)
2874                    {
2875                        // Skip empty base classes
2876                        CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2877                        if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2878                            continue;
2879
2880                        if (base_class->getType().getAsString().compare (name) == 0)
2881                            return child_idx;
2882                        ++child_idx;
2883                    }
2884                }
2885
2886                // Try and find a field that matches NAME
2887                RecordDecl::field_iterator field, field_end;
2888                StringRef name_sref(name);
2889                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2890                     field != field_end;
2891                     ++field, ++child_idx)
2892                {
2893                    if (field->getName().equals (name_sref))
2894                        return child_idx;
2895                }
2896
2897            }
2898            break;
2899
2900        case clang::Type::ObjCObject:
2901        case clang::Type::ObjCInterface:
2902            {
2903                StringRef name_sref(name);
2904                ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2905                assert (objc_class_type);
2906                if (objc_class_type)
2907                {
2908                    uint32_t child_idx = 0;
2909                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2910
2911                    if (class_interface_decl)
2912                    {
2913                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2914                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2915
2916                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2917                        {
2918                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
2919
2920                            if (ivar_decl->getName().equals (name_sref))
2921                            {
2922                                if ((!omit_empty_base_classes && superclass_interface_decl) ||
2923                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2924                                    ++child_idx;
2925
2926                                return child_idx;
2927                            }
2928                        }
2929
2930                        if (superclass_interface_decl)
2931                        {
2932                            if (superclass_interface_decl->getName().equals (name_sref))
2933                                return 0;
2934                        }
2935                    }
2936                }
2937            }
2938            break;
2939
2940        case clang::Type::ObjCObjectPointer:
2941            {
2942                return GetIndexOfChildWithName (ast_context,
2943                                                cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2944                                                name,
2945                                                omit_empty_base_classes);
2946            }
2947            break;
2948
2949        case clang::Type::ConstantArray:
2950            {
2951//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2952//                const uint64_t element_count = array->getSize().getLimitedValue();
2953//
2954//                if (idx < element_count)
2955//                {
2956//                    std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2957//
2958//                    char element_name[32];
2959//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2960//
2961//                    child_name.assign(element_name);
2962//                    assert(field_type_info.first % 8 == 0);
2963//                    child_byte_size = field_type_info.first / 8;
2964//                    child_byte_offset = idx * child_byte_size;
2965//                    return array->getElementType().getAsOpaquePtr();
2966//                }
2967            }
2968            break;
2969
2970//        case clang::Type::MemberPointerType:
2971//            {
2972//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2973//                QualType pointee_type = mem_ptr_type->getPointeeType();
2974//
2975//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2976//                {
2977//                    return GetIndexOfChildWithName (ast_context,
2978//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2979//                                                    name);
2980//                }
2981//            }
2982//            break;
2983//
2984        case clang::Type::LValueReference:
2985        case clang::Type::RValueReference:
2986            {
2987                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2988                QualType pointee_type = reference_type->getPointeeType();
2989
2990                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2991                {
2992                    return GetIndexOfChildWithName (ast_context,
2993                                                    reference_type->getPointeeType().getAsOpaquePtr(),
2994                                                    name,
2995                                                    omit_empty_base_classes);
2996                }
2997            }
2998            break;
2999
3000        case clang::Type::Pointer:
3001            {
3002                PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3003                QualType pointee_type = pointer_type->getPointeeType();
3004
3005                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3006                {
3007                    return GetIndexOfChildWithName (ast_context,
3008                                                    pointer_type->getPointeeType().getAsOpaquePtr(),
3009                                                    name,
3010                                                    omit_empty_base_classes);
3011                }
3012                else
3013                {
3014//                    if (parent_name)
3015//                    {
3016//                        child_name.assign(1, '*');
3017//                        child_name += parent_name;
3018//                    }
3019//
3020//                    // We have a pointer to an simple type
3021//                    if (idx == 0)
3022//                    {
3023//                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3024//                        assert(clang_type_info.first % 8 == 0);
3025//                        child_byte_size = clang_type_info.first / 8;
3026//                        child_byte_offset = 0;
3027//                        return pointee_type.getAsOpaquePtr();
3028//                    }
3029                }
3030            }
3031            break;
3032
3033        case clang::Type::Typedef:
3034            return GetIndexOfChildWithName (ast_context,
3035                                            cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3036                                            name,
3037                                            omit_empty_base_classes);
3038
3039        default:
3040            break;
3041        }
3042    }
3043    return UINT32_MAX;
3044}
3045
3046#pragma mark TagType
3047
3048bool
3049ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
3050{
3051    if (tag_clang_type)
3052    {
3053        QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
3054        clang::Type *clang_type = tag_qual_type.getTypePtr();
3055        if (clang_type)
3056        {
3057            TagType *tag_type = dyn_cast<TagType>(clang_type);
3058            if (tag_type)
3059            {
3060                TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3061                if (tag_decl)
3062                {
3063                    tag_decl->setTagKind ((TagDecl::TagKind)kind);
3064                    return true;
3065                }
3066            }
3067        }
3068    }
3069    return false;
3070}
3071
3072
3073#pragma mark DeclContext Functions
3074
3075DeclContext *
3076ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
3077{
3078    if (clang_type == NULL)
3079        return NULL;
3080
3081    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
3082    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3083    switch (type_class)
3084    {
3085    case clang::Type::FunctionNoProto:          break;
3086    case clang::Type::FunctionProto:            break;
3087    case clang::Type::IncompleteArray:          break;
3088    case clang::Type::VariableArray:            break;
3089    case clang::Type::ConstantArray:            break;
3090    case clang::Type::ExtVector:                break;
3091    case clang::Type::Vector:                   break;
3092    case clang::Type::Builtin:                  break;
3093    case clang::Type::BlockPointer:             break;
3094    case clang::Type::Pointer:                  break;
3095    case clang::Type::LValueReference:          break;
3096    case clang::Type::RValueReference:          break;
3097    case clang::Type::MemberPointer:            break;
3098    case clang::Type::Complex:                  break;
3099    case clang::Type::ObjCObject:               break;
3100    case clang::Type::ObjCInterface:            return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3101    case clang::Type::ObjCObjectPointer:        return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3102    case clang::Type::Record:                   return cast<RecordType>(qual_type)->getDecl();
3103    case clang::Type::Enum:                     return cast<EnumType>(qual_type)->getDecl();
3104    case clang::Type::Typedef:                  return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3105
3106    case clang::Type::TypeOfExpr:               break;
3107    case clang::Type::TypeOf:                   break;
3108    case clang::Type::Decltype:                 break;
3109    //case clang::Type::QualifiedName:          break;
3110    case clang::Type::TemplateSpecialization:   break;
3111    }
3112    // No DeclContext in this type...
3113    return NULL;
3114}
3115
3116#pragma mark Namespace Declarations
3117
3118NamespaceDecl *
3119ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3120{
3121    // TODO: Do something intelligent with the Declaration object passed in
3122    // like maybe filling in the SourceLocation with it...
3123    if (name)
3124    {
3125        ASTContext *ast_context = getASTContext();
3126        if (decl_ctx == NULL)
3127            decl_ctx = ast_context->getTranslationUnitDecl();
3128        return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3129    }
3130    return NULL;
3131}
3132
3133
3134#pragma mark Function Types
3135
3136FunctionDecl *
3137ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
3138{
3139    if (name)
3140    {
3141        ASTContext *ast_context = getASTContext();
3142        assert (ast_context != NULL);
3143
3144        if (name && name[0])
3145        {
3146            return FunctionDecl::Create(*ast_context,
3147                                        ast_context->getTranslationUnitDecl(),
3148                                        SourceLocation(),
3149                                        DeclarationName (&ast_context->Idents.get(name)),
3150                                        QualType::getFromOpaquePtr(function_clang_type),
3151                                        NULL,
3152                                        (FunctionDecl::StorageClass)storage,
3153                                        (FunctionDecl::StorageClass)storage,
3154                                        is_inline);
3155        }
3156        else
3157        {
3158            return FunctionDecl::Create(*ast_context,
3159                                        ast_context->getTranslationUnitDecl(),
3160                                        SourceLocation(),
3161                                        DeclarationName (),
3162                                        QualType::getFromOpaquePtr(function_clang_type),
3163                                        NULL,
3164                                        (FunctionDecl::StorageClass)storage,
3165                                        (FunctionDecl::StorageClass)storage,
3166                                        is_inline);
3167        }
3168    }
3169    return NULL;
3170}
3171
3172clang_type_t
3173ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3174                                     clang_type_t result_type,
3175                                     clang_type_t *args,
3176                                     unsigned num_args,
3177                                     bool is_variadic,
3178                                     unsigned type_quals)
3179{
3180    assert (ast_context != NULL);
3181    std::vector<QualType> qual_type_args;
3182    for (unsigned i=0; i<num_args; ++i)
3183        qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3184
3185    // TODO: Detect calling convention in DWARF?
3186    return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
3187                                        qual_type_args.empty() ? NULL : &qual_type_args.front(),
3188                                        qual_type_args.size(),
3189                                        is_variadic,
3190                                        type_quals,
3191                                        false,  // hasExceptionSpec
3192                                        false,  // hasAnyExceptionSpec,
3193                                        0,      // NumExs
3194                                        0,      // const QualType *ExArray
3195                                        FunctionType::ExtInfo ()).getAsOpaquePtr();    // NoReturn);
3196}
3197
3198ParmVarDecl *
3199ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
3200{
3201    ASTContext *ast_context = getASTContext();
3202    assert (ast_context != NULL);
3203    return ParmVarDecl::Create(*ast_context,
3204                                ast_context->getTranslationUnitDecl(),
3205                                SourceLocation(),
3206                                name && name[0] ? &ast_context->Idents.get(name) : NULL,
3207                                QualType::getFromOpaquePtr(param_type),
3208                                NULL,
3209                                (VarDecl::StorageClass)storage,
3210                                (VarDecl::StorageClass)storage,
3211                                0);
3212}
3213
3214void
3215ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3216{
3217    if (function_decl)
3218        function_decl->setParams (params, num_params);
3219}
3220
3221
3222#pragma mark Array Types
3223
3224clang_type_t
3225ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
3226{
3227    if (element_type)
3228    {
3229        ASTContext *ast_context = getASTContext();
3230        assert (ast_context != NULL);
3231        llvm::APInt ap_element_count (64, element_count);
3232        return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3233                                                 ap_element_count,
3234                                                 ArrayType::Normal,
3235                                                 0).getAsOpaquePtr(); // ElemQuals
3236    }
3237    return NULL;
3238}
3239
3240
3241#pragma mark TagDecl
3242
3243bool
3244ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
3245{
3246    if (clang_type)
3247    {
3248        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3249        clang::Type *t = qual_type.getTypePtr();
3250        if (t)
3251        {
3252            TagType *tag_type = dyn_cast<TagType>(t);
3253            if (tag_type)
3254            {
3255                TagDecl *tag_decl = tag_type->getDecl();
3256                if (tag_decl)
3257                {
3258                    tag_decl->startDefinition();
3259                    return true;
3260                }
3261            }
3262        }
3263    }
3264    return false;
3265}
3266
3267bool
3268ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
3269{
3270    if (clang_type)
3271    {
3272        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3273
3274        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3275
3276        if (cxx_record_decl)
3277        {
3278            cxx_record_decl->completeDefinition();
3279
3280            return true;
3281        }
3282
3283        ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3284
3285        if (objc_class_type)
3286        {
3287            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3288
3289            class_interface_decl->setForwardDecl(false);
3290        }
3291
3292        const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3293
3294        if (enum_type)
3295        {
3296            EnumDecl *enum_decl = enum_type->getDecl();
3297
3298            if (enum_decl)
3299            {
3300                /// TODO This really needs to be fixed.
3301
3302                unsigned NumPositiveBits = 1;
3303                unsigned NumNegativeBits = 0;
3304
3305                ASTContext *ast_context = getASTContext();
3306
3307                QualType promotion_qual_type;
3308                // If the enum integer type is less than an integer in bit width,
3309                // then we must promote it to an integer size.
3310                if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3311                {
3312                    if (enum_decl->getIntegerType()->isSignedIntegerType())
3313                        promotion_qual_type = ast_context->IntTy;
3314                    else
3315                        promotion_qual_type = ast_context->UnsignedIntTy;
3316                }
3317                else
3318                    promotion_qual_type = enum_decl->getIntegerType();
3319
3320                enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
3321                return true;
3322            }
3323        }
3324    }
3325    return false;
3326}
3327
3328
3329#pragma mark Enumeration Types
3330
3331clang_type_t
3332ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
3333{
3334    // TODO: Do something intelligent with the Declaration object passed in
3335    // like maybe filling in the SourceLocation with it...
3336    ASTContext *ast_context = getASTContext();
3337    assert (ast_context != NULL);
3338
3339    // TODO: ask about these...
3340//    const bool IsScoped = false;
3341//    const bool IsFixed = false;
3342
3343    EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3344                                            ast_context->getTranslationUnitDecl(),
3345                                            SourceLocation(),
3346                                            name && name[0] ? &ast_context->Idents.get(name) : NULL,
3347                                            SourceLocation(),
3348                                            NULL); //IsScoped, IsFixed);
3349    if (enum_decl)
3350    {
3351        // TODO: check if we should be setting the promotion type too?
3352        enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
3353        return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
3354    }
3355    return NULL;
3356}
3357
3358clang_type_t
3359ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3360{
3361    QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3362
3363    clang::Type *clang_type = enum_qual_type.getTypePtr();
3364    if (clang_type)
3365    {
3366        const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3367        if (enum_type)
3368        {
3369            EnumDecl *enum_decl = enum_type->getDecl();
3370            if (enum_decl)
3371                return enum_decl->getIntegerType().getAsOpaquePtr();
3372        }
3373    }
3374    return NULL;
3375}
3376bool
3377ClangASTContext::AddEnumerationValueToEnumerationType
3378(
3379    clang_type_t enum_clang_type,
3380    clang_type_t enumerator_clang_type,
3381    const Declaration &decl,
3382    const char *name,
3383    int64_t enum_value,
3384    uint32_t enum_value_bit_size
3385)
3386{
3387    if (enum_clang_type && enumerator_clang_type && name)
3388    {
3389        // TODO: Do something intelligent with the Declaration object passed in
3390        // like maybe filling in the SourceLocation with it...
3391        ASTContext *ast_context = getASTContext();
3392        IdentifierTable *identifier_table = getIdentifierTable();
3393
3394        assert (ast_context != NULL);
3395        assert (identifier_table != NULL);
3396        QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3397
3398        clang::Type *clang_type = enum_qual_type.getTypePtr();
3399        if (clang_type)
3400        {
3401            const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3402
3403            if (enum_type)
3404            {
3405                llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3406                enum_llvm_apsint = enum_value;
3407                EnumConstantDecl *enumerator_decl =
3408                    EnumConstantDecl::Create(*ast_context,
3409                                             enum_type->getDecl(),
3410                                             SourceLocation(),
3411                                             name ? &identifier_table->get(name) : NULL,    // Identifier
3412                                             QualType::getFromOpaquePtr(enumerator_clang_type),
3413                                             NULL,
3414                                             enum_llvm_apsint);
3415
3416                if (enumerator_decl)
3417                {
3418                    enum_type->getDecl()->addDecl(enumerator_decl);
3419                    return true;
3420                }
3421            }
3422        }
3423    }
3424    return false;
3425}
3426
3427#pragma mark Pointers & References
3428
3429clang_type_t
3430ClangASTContext::CreatePointerType (clang_type_t clang_type)
3431{
3432    if (clang_type)
3433    {
3434        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3435
3436        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3437        switch (type_class)
3438        {
3439        case clang::Type::ObjCObject:
3440        case clang::Type::ObjCInterface:
3441            return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3442
3443        default:
3444            return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3445        }
3446    }
3447    return NULL;
3448}
3449
3450clang_type_t
3451ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
3452{
3453    if (clang_type)
3454        return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3455    return NULL;
3456}
3457
3458clang_type_t
3459ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
3460{
3461    if (clang_type)
3462        return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3463    return NULL;
3464}
3465
3466clang_type_t
3467ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
3468{
3469    if (clang_pointee_type && clang_pointee_type)
3470        return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3471                                                     QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3472    return NULL;
3473}
3474
3475size_t
3476ClangASTContext::GetPointerBitSize ()
3477{
3478    ASTContext *ast_context = getASTContext();
3479    return ast_context->getTypeSize(ast_context->VoidPtrTy);
3480}
3481
3482bool
3483ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
3484{
3485    if (clang_type == NULL)
3486        return false;
3487
3488    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3489    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3490    switch (type_class)
3491    {
3492    case clang::Type::Builtin:
3493        switch (cast<clang::BuiltinType>(qual_type)->getKind())
3494        {
3495        default:
3496            break;
3497        case clang::BuiltinType::ObjCId:
3498        case clang::BuiltinType::ObjCClass:
3499            return true;
3500        }
3501        return false;
3502    case clang::Type::ObjCObjectPointer:
3503        if (target_type)
3504            *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3505        return true;
3506    case clang::Type::BlockPointer:
3507        if (target_type)
3508            *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3509        return true;
3510    case clang::Type::Pointer:
3511        if (target_type)
3512            *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3513        return true;
3514    case clang::Type::MemberPointer:
3515        if (target_type)
3516            *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3517        return true;
3518    case clang::Type::LValueReference:
3519        if (target_type)
3520            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3521        return true;
3522    case clang::Type::RValueReference:
3523        if (target_type)
3524            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3525        return true;
3526    case clang::Type::Typedef:
3527        return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3528    default:
3529        break;
3530    }
3531    return false;
3532}
3533
3534bool
3535ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
3536{
3537    if (!clang_type)
3538        return false;
3539
3540    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3541    const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3542
3543    if (builtin_type)
3544    {
3545        if (builtin_type->isInteger())
3546            is_signed = builtin_type->isSignedInteger();
3547
3548        return true;
3549    }
3550
3551    return false;
3552}
3553
3554bool
3555ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
3556{
3557    if (clang_type)
3558    {
3559        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3560        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3561        switch (type_class)
3562        {
3563        case clang::Type::Builtin:
3564            switch (cast<clang::BuiltinType>(qual_type)->getKind())
3565            {
3566            default:
3567                break;
3568            case clang::BuiltinType::ObjCId:
3569            case clang::BuiltinType::ObjCClass:
3570                return true;
3571            }
3572            return false;
3573        case clang::Type::ObjCObjectPointer:
3574            if (target_type)
3575                *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3576            return true;
3577        case clang::Type::BlockPointer:
3578            if (target_type)
3579                *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3580            return true;
3581        case clang::Type::Pointer:
3582            if (target_type)
3583                *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3584            return true;
3585        case clang::Type::MemberPointer:
3586            if (target_type)
3587                *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3588            return true;
3589        case clang::Type::Typedef:
3590            return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3591        default:
3592            break;
3593        }
3594    }
3595    return false;
3596}
3597
3598bool
3599ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
3600{
3601    if (clang_type)
3602    {
3603        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3604
3605        if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3606        {
3607            clang::BuiltinType::Kind kind = BT->getKind();
3608            if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3609            {
3610                count = 1;
3611                is_complex = false;
3612                return true;
3613            }
3614        }
3615        else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3616        {
3617            if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3618            {
3619                count = 2;
3620                is_complex = true;
3621                return true;
3622            }
3623        }
3624        else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3625        {
3626            if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3627            {
3628                count = VT->getNumElements();
3629                is_complex = false;
3630                return true;
3631            }
3632        }
3633    }
3634    return false;
3635}
3636
3637
3638bool
3639ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3640{
3641    if (clang_type)
3642    {
3643        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3644
3645        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3646        if (cxx_record_decl)
3647        {
3648            class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3649            return true;
3650        }
3651    }
3652    class_name.clear();
3653    return false;
3654}
3655
3656
3657bool
3658ClangASTContext::IsCXXClassType (clang_type_t clang_type)
3659{
3660    if (clang_type)
3661    {
3662        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3663        if (qual_type->getAsCXXRecordDecl() != NULL)
3664            return true;
3665    }
3666    return false;
3667}
3668
3669bool
3670ClangASTContext::IsObjCClassType (clang_type_t clang_type)
3671{
3672    if (clang_type)
3673    {
3674        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3675        if (qual_type->isObjCObjectOrInterfaceType())
3676            return true;
3677    }
3678    return false;
3679}
3680
3681
3682bool
3683ClangASTContext::IsCharType (clang_type_t clang_type)
3684{
3685    if (clang_type)
3686        return QualType::getFromOpaquePtr(clang_type)->isCharType();
3687    return false;
3688}
3689
3690bool
3691ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
3692{
3693    clang_type_t pointee_or_element_clang_type = NULL;
3694    Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3695
3696    if (pointee_or_element_clang_type == NULL)
3697        return false;
3698
3699    if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
3700    {
3701        QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3702
3703        if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
3704        {
3705            QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3706            if (type_flags.Test (eTypeIsArray))
3707            {
3708                // We know the size of the array and it could be a C string
3709                // since it is an array of characters
3710                length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3711                return true;
3712            }
3713            else
3714            {
3715                length = 0;
3716                return true;
3717            }
3718
3719        }
3720    }
3721    return false;
3722}
3723
3724bool
3725ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
3726{
3727    if (clang_type)
3728    {
3729        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3730
3731        if (qual_type->isFunctionPointerType())
3732            return true;
3733
3734        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3735        switch (type_class)
3736        {
3737        case clang::Type::Typedef:
3738            return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3739
3740        case clang::Type::LValueReference:
3741        case clang::Type::RValueReference:
3742            {
3743                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3744                if (reference_type)
3745                    return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3746            }
3747            break;
3748        }
3749    }
3750    return false;
3751}
3752
3753size_t
3754ClangASTContext::GetArraySize (clang_type_t clang_type)
3755{
3756    if (clang_type)
3757    {
3758        ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3759        if (array)
3760            return array->getSize().getLimitedValue();
3761    }
3762    return 0;
3763}
3764
3765bool
3766ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
3767{
3768    if (!clang_type)
3769        return false;
3770
3771    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3772
3773    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3774    switch (type_class)
3775    {
3776    case clang::Type::ConstantArray:
3777        if (member_type)
3778            *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3779        if (size)
3780            *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3781        return true;
3782    case clang::Type::IncompleteArray:
3783        if (member_type)
3784            *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3785        if (size)
3786            *size = 0;
3787        return true;
3788    case clang::Type::VariableArray:
3789        if (member_type)
3790            *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3791        if (size)
3792            *size = 0;
3793    case clang::Type::DependentSizedArray:
3794        if (member_type)
3795            *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3796        if (size)
3797            *size = 0;
3798        return true;
3799    }
3800    return false;
3801}
3802
3803
3804#pragma mark Typedefs
3805
3806clang_type_t
3807ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
3808{
3809    if (clang_type)
3810    {
3811        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3812        ASTContext *ast_context = getASTContext();
3813        IdentifierTable *identifier_table = getIdentifierTable();
3814        assert (ast_context != NULL);
3815        assert (identifier_table != NULL);
3816        if (decl_ctx == NULL)
3817            decl_ctx = ast_context->getTranslationUnitDecl();
3818        TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3819                                                decl_ctx,
3820                                                SourceLocation(),
3821                                                name ? &identifier_table->get(name) : NULL, // Identifier
3822                                                ast_context->CreateTypeSourceInfo(qual_type));
3823
3824        // Get a uniqued QualType for the typedef decl type
3825        return ast_context->getTypedefType (decl).getAsOpaquePtr();
3826    }
3827    return NULL;
3828}
3829
3830
3831std::string
3832ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
3833{
3834    std::string return_name;
3835
3836    QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
3837
3838    const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
3839    if (typedef_type)
3840    {
3841        const TypedefDecl *typedef_decl = typedef_type->getDecl();
3842        return_name = typedef_decl->getQualifiedNameAsString();
3843    }
3844    else
3845    {
3846        return_name = qual_type.getAsString();
3847    }
3848
3849    return return_name;
3850}
3851
3852// Disable this for now since I can't seem to get a nicely formatted float
3853// out of the APFloat class without just getting the float, double or quad
3854// and then using a formatted print on it which defeats the purpose. We ideally
3855// would like to get perfect string values for any kind of float semantics
3856// so we can support remote targets. The code below also requires a patch to
3857// llvm::APInt.
3858//bool
3859//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)
3860//{
3861//  uint32_t count = 0;
3862//  bool is_complex = false;
3863//  if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3864//  {
3865//      unsigned num_bytes_per_float = byte_size / count;
3866//      unsigned num_bits_per_float = num_bytes_per_float * 8;
3867//
3868//      float_str.clear();
3869//      uint32_t i;
3870//      for (i=0; i<count; i++)
3871//      {
3872//          APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3873//          bool is_ieee = false;
3874//          APFloat ap_float(ap_int, is_ieee);
3875//          char s[1024];
3876//          unsigned int hex_digits = 0;
3877//          bool upper_case = false;
3878//
3879//          if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3880//          {
3881//              if (i > 0)
3882//                  float_str.append(", ");
3883//              float_str.append(s);
3884//              if (i == 1 && is_complex)
3885//                  float_str.append(1, 'i');
3886//          }
3887//      }
3888//      return !float_str.empty();
3889//  }
3890//  return false;
3891//}
3892
3893size_t
3894ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
3895{
3896    if (clang_type)
3897    {
3898        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3899        uint32_t count = 0;
3900        bool is_complex = false;
3901        if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3902        {
3903            // TODO: handle complex and vector types
3904            if (count != 1)
3905                return false;
3906
3907            StringRef s_sref(s);
3908            APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3909
3910            const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3911            const uint64_t byte_size = bit_size / 8;
3912            if (dst_size >= byte_size)
3913            {
3914                if (bit_size == sizeof(float)*8)
3915                {
3916                    float float32 = ap_float.convertToFloat();
3917                    ::memcpy (dst, &float32, byte_size);
3918                    return byte_size;
3919                }
3920                else if (bit_size >= 64)
3921                {
3922                    llvm::APInt ap_int(ap_float.bitcastToAPInt());
3923                    ::memcpy (dst, ap_int.getRawData(), byte_size);
3924                    return byte_size;
3925                }
3926            }
3927        }
3928    }
3929    return 0;
3930}
3931
3932unsigned
3933ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
3934{
3935    assert (clang_type);
3936
3937    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3938
3939    return qual_type.getQualifiers().getCVRQualifiers();
3940}
3941