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