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