ClangASTContext.cpp revision 6e71340988075f55c85e8bfcbc503ceaceb157c7
1//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Symbol/ClangASTContext.h"
11
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
17#define NDEBUG
18#include "clang/AST/ASTContext.h"
19#include "clang/AST/ASTImporter.h"
20#include "clang/AST/CXXInheritance.h"
21#include "clang/AST/DeclObjC.h"
22#include "clang/AST/RecordLayout.h"
23#include "clang/AST/Type.h"
24#include "clang/Basic/Builtins.h"
25#include "clang/Basic/FileManager.h"
26#include "clang/Basic/SourceManager.h"
27#include "clang/Basic/TargetInfo.h"
28#include "clang/Basic/TargetOptions.h"
29#include "clang/Frontend/FrontendOptions.h"
30#include "clang/Frontend/LangStandard.h"
31#undef NDEBUG
32
33#include "lldb/Core/dwarf.h"
34
35#include <stdio.h>
36
37using namespace lldb_private;
38using namespace llvm;
39using namespace clang;
40
41static AccessSpecifier
42ConvertAccessTypeToAccessSpecifier (ClangASTContext::AccessType access)
43{
44    switch (access)
45    {
46    default:                                break;
47    case ClangASTContext::eAccessNone:      return AS_none;
48    case ClangASTContext::eAccessPublic:    return AS_public;
49    case ClangASTContext::eAccessPrivate:   return AS_private;
50    case ClangASTContext::eAccessProtected: return AS_protected;
51    }
52    return AS_none;
53}
54
55static ObjCIvarDecl::AccessControl
56ConvertAccessTypeToObjCIvarAccessControl (ClangASTContext::AccessType access)
57{
58    switch (access)
59    {
60    default:                                break;
61    case ClangASTContext::eAccessNone:      return ObjCIvarDecl::None;
62    case ClangASTContext::eAccessPublic:    return ObjCIvarDecl::Public;
63    case ClangASTContext::eAccessPrivate:   return ObjCIvarDecl::Private;
64    case ClangASTContext::eAccessProtected: return ObjCIvarDecl::Protected;
65    case ClangASTContext::eAccessPackage:   return ObjCIvarDecl::Package;
66    }
67    return ObjCIvarDecl::None;
68}
69
70
71static void
72ParseLangArgs
73(
74    LangOptions &Opts,
75    InputKind IK
76)
77{
78    // FIXME: Cleanup per-file based stuff.
79
80    // Set some properties which depend soley on the input kind; it would be nice
81    // to move these to the language standard, and have the driver resolve the
82    // input kind + language standard.
83    if (IK == IK_Asm) {
84        Opts.AsmPreprocessor = 1;
85    } else if (IK == IK_ObjC ||
86               IK == IK_ObjCXX ||
87               IK == IK_PreprocessedObjC ||
88               IK == IK_PreprocessedObjCXX) {
89        Opts.ObjC1 = Opts.ObjC2 = 1;
90    }
91
92    LangStandard::Kind LangStd = LangStandard::lang_unspecified;
93
94    if (LangStd == LangStandard::lang_unspecified) {
95        // Based on the base language, pick one.
96        switch (IK) {
97            case IK_None:
98            case IK_AST:
99                assert(0 && "Invalid input kind!");
100            case IK_OpenCL:
101                LangStd = LangStandard::lang_opencl;
102                break;
103            case IK_Asm:
104            case IK_C:
105            case IK_PreprocessedC:
106            case IK_ObjC:
107            case IK_PreprocessedObjC:
108                LangStd = LangStandard::lang_gnu99;
109                break;
110            case IK_CXX:
111            case IK_PreprocessedCXX:
112            case IK_ObjCXX:
113            case IK_PreprocessedObjCXX:
114                LangStd = LangStandard::lang_gnucxx98;
115                break;
116        }
117    }
118
119    const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
120    Opts.BCPLComment = Std.hasBCPLComments();
121    Opts.C99 = Std.isC99();
122    Opts.CPlusPlus = Std.isCPlusPlus();
123    Opts.CPlusPlus0x = Std.isCPlusPlus0x();
124    Opts.Digraphs = Std.hasDigraphs();
125    Opts.GNUMode = Std.isGNUMode();
126    Opts.GNUInline = !Std.isC99();
127    Opts.HexFloats = Std.hasHexFloats();
128    Opts.ImplicitInt = Std.hasImplicitInt();
129
130    // OpenCL has some additional defaults.
131    if (LangStd == LangStandard::lang_opencl) {
132        Opts.OpenCL = 1;
133        Opts.AltiVec = 1;
134        Opts.CXXOperatorNames = 1;
135        Opts.LaxVectorConversions = 1;
136    }
137
138    // OpenCL and C++ both have bool, true, false keywords.
139    Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
140
141//    if (Opts.CPlusPlus)
142//        Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
143//
144//    if (Args.hasArg(OPT_fobjc_gc_only))
145//        Opts.setGCMode(LangOptions::GCOnly);
146//    else if (Args.hasArg(OPT_fobjc_gc))
147//        Opts.setGCMode(LangOptions::HybridGC);
148//
149//    if (Args.hasArg(OPT_print_ivar_layout))
150//        Opts.ObjCGCBitmapPrint = 1;
151//
152//    if (Args.hasArg(OPT_faltivec))
153//        Opts.AltiVec = 1;
154//
155//    if (Args.hasArg(OPT_pthread))
156//        Opts.POSIXThreads = 1;
157//
158//    llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
159//                                          "default");
160//    if (Vis == "default")
161        Opts.setVisibilityMode(LangOptions::Default);
162//    else if (Vis == "hidden")
163//        Opts.setVisibilityMode(LangOptions::Hidden);
164//    else if (Vis == "protected")
165//        Opts.setVisibilityMode(LangOptions::Protected);
166//    else
167//        Diags.Report(diag::err_drv_invalid_value)
168//        << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
169
170//    Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
171
172    // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
173    // is specified, or -std is set to a conforming mode.
174    Opts.Trigraphs = !Opts.GNUMode;
175//    if (Args.hasArg(OPT_trigraphs))
176//        Opts.Trigraphs = 1;
177//
178//    Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
179//                                     OPT_fno_dollars_in_identifiers,
180//                                     !Opts.AsmPreprocessor);
181//    Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
182//    Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
183//    Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
184//    if (Args.hasArg(OPT_fno_lax_vector_conversions))
185//        Opts.LaxVectorConversions = 0;
186//    Opts.Exceptions = Args.hasArg(OPT_fexceptions);
187//    Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
188//    Opts.Blocks = Args.hasArg(OPT_fblocks);
189//    Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
190//    Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
191//    Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
192//    Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
193//    Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
194//    Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
195//    Opts.AccessControl = Args.hasArg(OPT_faccess_control);
196//    Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
197//    Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
198//    Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
199//                                                 Diags);
200//    Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
201//    Opts.ObjCConstantStringClass = getLastArgValue(Args,
202//                                                   OPT_fconstant_string_class);
203//    Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
204//    Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
205//    Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
206//    Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
207//    Opts.Static = Args.hasArg(OPT_static_define);
208    Opts.OptimizeSize = 0;
209
210    // FIXME: Eliminate this dependency.
211//    unsigned Opt =
212//    Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
213//    Opts.Optimize = Opt != 0;
214    unsigned Opt = 0;
215
216    // This is the __NO_INLINE__ define, which just depends on things like the
217    // optimization level and -fno-inline, not actually whether the backend has
218    // inlining enabled.
219    //
220    // FIXME: This is affected by other options (-fno-inline).
221    Opts.NoInline = !Opt;
222
223//    unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
224//    switch (SSP) {
225//        default:
226//            Diags.Report(diag::err_drv_invalid_value)
227//            << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
228//            break;
229//        case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
230//        case 1: Opts.setStackProtectorMode(LangOptions::SSPOn);  break;
231//        case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
232//    }
233}
234
235
236ClangASTContext::ClangASTContext(const char *target_triple) :
237    m_target_triple(),
238    m_ast_context_ap(),
239    m_language_options_ap(),
240    m_source_manager_ap(),
241    m_diagnostic_ap(),
242    m_target_options_ap(),
243    m_target_info_ap(),
244    m_identifier_table_ap(),
245    m_selector_table_ap(),
246    m_builtins_ap()
247{
248    if (target_triple && target_triple[0])
249        m_target_triple.assign (target_triple);
250}
251
252//----------------------------------------------------------------------
253// Destructor
254//----------------------------------------------------------------------
255ClangASTContext::~ClangASTContext()
256{
257    m_builtins_ap.reset();
258    m_selector_table_ap.reset();
259    m_identifier_table_ap.reset();
260    m_target_info_ap.reset();
261    m_target_options_ap.reset();
262    m_diagnostic_ap.reset();
263    m_source_manager_ap.reset();
264    m_language_options_ap.reset();
265    m_ast_context_ap.reset();
266}
267
268
269void
270ClangASTContext::Clear()
271{
272    m_ast_context_ap.reset();
273    m_language_options_ap.reset();
274    m_source_manager_ap.reset();
275    m_diagnostic_ap.reset();
276    m_target_options_ap.reset();
277    m_target_info_ap.reset();
278    m_identifier_table_ap.reset();
279    m_selector_table_ap.reset();
280    m_builtins_ap.reset();
281}
282
283const char *
284ClangASTContext::GetTargetTriple ()
285{
286    return m_target_triple.c_str();
287}
288
289void
290ClangASTContext::SetTargetTriple (const char *target_triple)
291{
292    Clear();
293    m_target_triple.assign(target_triple);
294}
295
296
297ASTContext *
298ClangASTContext::getASTContext()
299{
300    if (m_ast_context_ap.get() == NULL)
301    {
302        m_ast_context_ap.reset(
303            new ASTContext(
304                *getLanguageOptions(),
305                *getSourceManager(),
306                *getTargetInfo(),
307                *getIdentifierTable(),
308                *getSelectorTable(),
309                *getBuiltinContext(),
310                0));
311    }
312    return m_ast_context_ap.get();
313}
314
315Builtin::Context *
316ClangASTContext::getBuiltinContext()
317{
318    if (m_builtins_ap.get() == NULL)
319        m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
320    return m_builtins_ap.get();
321}
322
323IdentifierTable *
324ClangASTContext::getIdentifierTable()
325{
326    if (m_identifier_table_ap.get() == NULL)
327        m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
328    return m_identifier_table_ap.get();
329}
330
331LangOptions *
332ClangASTContext::getLanguageOptions()
333{
334    if (m_language_options_ap.get() == NULL)
335    {
336        m_language_options_ap.reset(new LangOptions());
337        ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
338//        InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
339    }
340    return m_language_options_ap.get();
341}
342
343SelectorTable *
344ClangASTContext::getSelectorTable()
345{
346    if (m_selector_table_ap.get() == NULL)
347        m_selector_table_ap.reset (new SelectorTable());
348    return m_selector_table_ap.get();
349}
350
351clang::SourceManager *
352ClangASTContext::getSourceManager()
353{
354    if (m_source_manager_ap.get() == NULL)
355        m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic()));
356    return m_source_manager_ap.get();
357}
358
359Diagnostic *
360ClangASTContext::getDiagnostic()
361{
362    if (m_diagnostic_ap.get() == NULL)
363        m_diagnostic_ap.reset(new Diagnostic());
364    return m_diagnostic_ap.get();
365}
366
367TargetOptions *
368ClangASTContext::getTargetOptions()
369{
370    if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
371    {
372        m_target_options_ap.reset (new TargetOptions());
373        if (m_target_options_ap.get())
374            m_target_options_ap->Triple = m_target_triple;
375    }
376    return m_target_options_ap.get();
377}
378
379
380TargetInfo *
381ClangASTContext::getTargetInfo()
382{
383    // target_triple should be something like "x86_64-apple-darwin10"
384    if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
385        m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
386    return m_target_info_ap.get();
387}
388
389#pragma mark Basic Types
390
391static inline bool
392QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
393{
394    uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
395    if (qual_type_bit_size == bit_size)
396        return true;
397    return false;
398}
399
400void *
401ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding, uint32_t bit_size)
402{
403    ASTContext *ast_context = getASTContext();
404
405    assert (ast_context != NULL);
406
407    return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
408}
409
410void *
411ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast_context, lldb::Encoding encoding, uint32_t bit_size)
412{
413    if (!ast_context)
414        return NULL;
415
416    switch (encoding)
417    {
418    case lldb::eEncodingInvalid:
419        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
420            return ast_context->VoidPtrTy.getAsOpaquePtr();
421        break;
422
423    case lldb::eEncodingUint:
424        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
425            return ast_context->UnsignedCharTy.getAsOpaquePtr();
426        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
427            return ast_context->UnsignedShortTy.getAsOpaquePtr();
428        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
429            return ast_context->UnsignedIntTy.getAsOpaquePtr();
430        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
431            return ast_context->UnsignedLongTy.getAsOpaquePtr();
432        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
433            return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
434        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
435            return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
436        break;
437
438    case lldb::eEncodingSint:
439        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
440            return ast_context->CharTy.getAsOpaquePtr();
441        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
442            return ast_context->ShortTy.getAsOpaquePtr();
443        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
444            return ast_context->IntTy.getAsOpaquePtr();
445        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
446            return ast_context->LongTy.getAsOpaquePtr();
447        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
448            return ast_context->LongLongTy.getAsOpaquePtr();
449        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
450            return ast_context->Int128Ty.getAsOpaquePtr();
451        break;
452
453    case lldb::eEncodingIEEE754:
454        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
455            return ast_context->FloatTy.getAsOpaquePtr();
456        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
457            return ast_context->DoubleTy.getAsOpaquePtr();
458        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
459            return ast_context->LongDoubleTy.getAsOpaquePtr();
460        break;
461
462    case lldb::eEncodingVector:
463    default:
464        break;
465    }
466
467    return NULL;
468}
469
470void *
471ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
472{
473    ASTContext *ast_context = getASTContext();
474
475    #define streq(a,b) strcmp(a,b) == 0
476    assert (ast_context != NULL);
477    if (ast_context)
478    {
479        switch (dw_ate)
480        {
481        default:
482            break;
483
484        case DW_ATE_address:
485            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
486                return ast_context->VoidPtrTy.getAsOpaquePtr();
487            break;
488
489        case DW_ATE_boolean:
490            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
491                return ast_context->BoolTy.getAsOpaquePtr();
492            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
493                return ast_context->UnsignedCharTy.getAsOpaquePtr();
494            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
495                return ast_context->UnsignedShortTy.getAsOpaquePtr();
496            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
497                return ast_context->UnsignedIntTy.getAsOpaquePtr();
498            break;
499
500        case DW_ATE_complex_float:
501            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
502                return ast_context->FloatComplexTy.getAsOpaquePtr();
503            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
504                return ast_context->DoubleComplexTy.getAsOpaquePtr();
505            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
506                return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
507            break;
508
509        case DW_ATE_float:
510            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
511                return ast_context->FloatTy.getAsOpaquePtr();
512            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
513                return ast_context->DoubleTy.getAsOpaquePtr();
514            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
515                return ast_context->LongDoubleTy.getAsOpaquePtr();
516            break;
517
518        case DW_ATE_signed:
519            if (type_name)
520            {
521                if (streq(type_name, "int") ||
522                    streq(type_name, "signed int"))
523                {
524                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
525                        return ast_context->IntTy.getAsOpaquePtr();
526                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
527                        return ast_context->Int128Ty.getAsOpaquePtr();
528                }
529
530                if (streq(type_name, "long int") ||
531                    streq(type_name, "long long int") ||
532                    streq(type_name, "signed long long"))
533                {
534                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
535                        return ast_context->LongTy.getAsOpaquePtr();
536                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
537                        return ast_context->LongLongTy.getAsOpaquePtr();
538                }
539
540                if (streq(type_name, "short") ||
541                    streq(type_name, "short int") ||
542                    streq(type_name, "signed short") ||
543                    streq(type_name, "short signed int"))
544                {
545                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
546                        return ast_context->ShortTy.getAsOpaquePtr();
547                }
548
549                if (streq(type_name, "char") ||
550                    streq(type_name, "signed char"))
551                {
552                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
553                        return ast_context->CharTy.getAsOpaquePtr();
554                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
555                        return ast_context->SignedCharTy.getAsOpaquePtr();
556                }
557
558                if (streq(type_name, "wchar_t"))
559                {
560                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
561                        return ast_context->WCharTy.getAsOpaquePtr();
562                }
563
564            }
565            // We weren't able to match up a type name, just search by size
566            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
567                return ast_context->CharTy.getAsOpaquePtr();
568            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
569                return ast_context->ShortTy.getAsOpaquePtr();
570            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
571                return ast_context->IntTy.getAsOpaquePtr();
572            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
573                return ast_context->LongTy.getAsOpaquePtr();
574            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
575                return ast_context->LongLongTy.getAsOpaquePtr();
576            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
577                return ast_context->Int128Ty.getAsOpaquePtr();
578            break;
579
580        case DW_ATE_signed_char:
581            if (type_name)
582            {
583                if (streq(type_name, "signed char"))
584                {
585                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
586                        return ast_context->SignedCharTy.getAsOpaquePtr();
587                }
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            break;
594
595        case DW_ATE_unsigned:
596            if (type_name)
597            {
598                if (streq(type_name, "unsigned int"))
599                {
600                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
601                        return ast_context->UnsignedIntTy.getAsOpaquePtr();
602                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
603                        return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
604                }
605
606                if (streq(type_name, "unsigned int") ||
607                    streq(type_name, "long unsigned int") ||
608                    streq(type_name, "unsigned long long"))
609                {
610                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
611                        return ast_context->UnsignedLongTy.getAsOpaquePtr();
612                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
613                        return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
614                }
615
616                if (streq(type_name, "unsigned short") ||
617                    streq(type_name, "short unsigned int"))
618                {
619                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
620                        return ast_context->UnsignedShortTy.getAsOpaquePtr();
621                }
622                if (streq(type_name, "unsigned char"))
623                {
624                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
625                        return ast_context->UnsignedCharTy.getAsOpaquePtr();
626                }
627
628            }
629            // We weren't able to match up a type name, just search by size
630            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
631                return ast_context->UnsignedCharTy.getAsOpaquePtr();
632            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
633                return ast_context->UnsignedShortTy.getAsOpaquePtr();
634            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
635                return ast_context->UnsignedIntTy.getAsOpaquePtr();
636            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
637                return ast_context->UnsignedLongTy.getAsOpaquePtr();
638            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
639                return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
640            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
641                return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
642            break;
643
644        case DW_ATE_unsigned_char:
645            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
646                return ast_context->UnsignedCharTy.getAsOpaquePtr();
647            break;
648
649        case DW_ATE_imaginary_float:
650            break;
651        }
652    }
653    // This assert should fire for anything that we don't catch above so we know
654    // to fix any issues we run into.
655    assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
656    return NULL;
657}
658
659void *
660ClangASTContext::GetVoidBuiltInType()
661{
662    return getASTContext()->VoidTy.getAsOpaquePtr();
663}
664
665void *
666ClangASTContext::GetCStringType (bool is_const)
667{
668    QualType char_type(getASTContext()->CharTy);
669
670    if (is_const)
671        char_type.addConst();
672
673    return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
674}
675
676void *
677ClangASTContext::GetVoidPtrType (bool is_const)
678{
679    return GetVoidPtrType(getASTContext(), is_const);
680}
681
682void *
683ClangASTContext::GetVoidPtrType (clang::ASTContext *ast_context, bool is_const)
684{
685    QualType void_ptr_type(ast_context->VoidPtrTy);
686
687    if (is_const)
688        void_ptr_type.addConst();
689
690    return void_ptr_type.getAsOpaquePtr();
691}
692
693void *
694ClangASTContext::CopyType(clang::ASTContext *dest_context,
695                          clang::ASTContext *source_context,
696                          void *clang_type)
697{
698    Diagnostic diagnostics;
699    FileManager file_manager;
700    ASTImporter importer(diagnostics,
701                         *dest_context, file_manager,
702                         *source_context, file_manager);
703    QualType ret = importer.Import(QualType::getFromOpaquePtr(clang_type));
704    return ret.getAsOpaquePtr();
705}
706
707bool
708ClangASTContext::AreTypesSame(clang::ASTContext *ast_context,
709             void *type1,
710             void *type2)
711{
712    return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
713                                    QualType::getFromOpaquePtr(type2));
714}
715
716#pragma mark CVR modifiers
717
718void *
719ClangASTContext::AddConstModifier (void *clang_type)
720{
721    if (clang_type)
722    {
723        QualType result(QualType::getFromOpaquePtr(clang_type));
724        result.addConst();
725        return result.getAsOpaquePtr();
726    }
727    return NULL;
728}
729
730void *
731ClangASTContext::AddRestrictModifier (void *clang_type)
732{
733    if (clang_type)
734    {
735        QualType result(QualType::getFromOpaquePtr(clang_type));
736        result.getQualifiers().setRestrict (true);
737        return result.getAsOpaquePtr();
738    }
739    return NULL;
740}
741
742void *
743ClangASTContext::AddVolatileModifier (void *clang_type)
744{
745    if (clang_type)
746    {
747        QualType result(QualType::getFromOpaquePtr(clang_type));
748        result.getQualifiers().setVolatile (true);
749        return result.getAsOpaquePtr();
750    }
751    return NULL;
752}
753
754#pragma mark Structure, Unions, Classes
755
756void *
757ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, lldb::LanguageType language)
758{
759    ASTContext *ast_context = getASTContext();
760    assert (ast_context != NULL);
761
762    if (decl_ctx == NULL)
763        decl_ctx = ast_context->getTranslationUnitDecl();
764
765
766    if (language == lldb::eLanguageTypeObjC)
767    {
768        bool isForwardDecl = false;
769        bool isInternal = false;
770        return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
771    }
772
773    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
774    // we will need to update this code. I was told to currently always use
775    // the CXXRecordDecl class since we often don't know from debug information
776    // if something is struct or a class, so we default to always use the more
777    // complete definition just in case.
778    CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
779                                                (TagDecl::TagKind)kind,
780                                                decl_ctx,
781                                                SourceLocation(),
782                                                name && name[0] ? &ast_context->Idents.get(name) : NULL);
783
784    return ast_context->getTagDeclType(decl).getAsOpaquePtr();
785}
786
787bool
788ClangASTContext::AddFieldToRecordType
789(
790    void *record_clang_type,
791    const char *name,
792    void *field_type,
793    AccessType access,
794    uint32_t bitfield_bit_size
795)
796{
797    if (record_clang_type == NULL || field_type == NULL)
798        return false;
799
800    ASTContext *ast_context = getASTContext();
801    IdentifierTable *identifier_table = getIdentifierTable();
802
803    assert (ast_context != NULL);
804    assert (identifier_table != NULL);
805
806    QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
807
808    clang::Type *clang_type = record_qual_type.getTypePtr();
809    if (clang_type)
810    {
811        const RecordType *record_type = dyn_cast<RecordType>(clang_type);
812
813        if (record_type)
814        {
815            RecordDecl *record_decl = record_type->getDecl();
816
817            CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
818            if (cxx_record_decl)
819                cxx_record_decl->setEmpty (false);
820
821            clang::Expr *bit_width = NULL;
822            if (bitfield_bit_size != 0)
823            {
824                APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
825                bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
826            }
827            FieldDecl *field = FieldDecl::Create (*ast_context,
828                                                  record_decl,
829                                                  SourceLocation(),
830                                                  name ? &identifier_table->get(name) : NULL, // Identifier
831                                                  QualType::getFromOpaquePtr(field_type), // Field type
832                                                  NULL,       // DeclaratorInfo *
833                                                  bit_width,  // BitWidth
834                                                  false);     // Mutable
835
836            field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
837
838            if (field)
839            {
840                record_decl->addDecl(field);
841                return true;
842            }
843        }
844        else
845        {
846            ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
847            if (objc_class_type)
848            {
849                bool isSynthesized = false;
850                ClangASTContext::AddObjCClassIVar (record_clang_type,
851                                                   name,
852                                                   field_type,
853                                                   access,
854                                                   bitfield_bit_size,
855                                                   isSynthesized);
856            }
857        }
858    }
859    return false;
860}
861
862bool
863ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
864{
865    return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
866}
867
868bool
869ClangASTContext::FieldIsBitfield
870(
871    ASTContext *ast_context,
872    FieldDecl* field,
873    uint32_t& bitfield_bit_size
874)
875{
876    if (ast_context == NULL || field == NULL)
877        return false;
878
879    if (field->isBitField())
880    {
881        Expr* bit_width_expr = field->getBitWidth();
882        if (bit_width_expr)
883        {
884            llvm::APSInt bit_width_apsint;
885            if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
886            {
887                bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
888                return true;
889            }
890        }
891    }
892    return false;
893}
894
895bool
896ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
897{
898    if (record_decl == NULL)
899        return false;
900
901    if (!record_decl->field_empty())
902        return true;
903
904    // No fields, lets check this is a CXX record and check the base classes
905    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
906    if (cxx_record_decl)
907    {
908        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
909        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
910             base_class != base_class_end;
911             ++base_class)
912        {
913            const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
914            if (RecordHasFields(base_class_decl))
915                return true;
916        }
917    }
918    return false;
919}
920
921void
922ClangASTContext::SetDefaultAccessForRecordFields (void *clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
923{
924    if (clang_qual_type)
925    {
926        QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
927        clang::Type *clang_type = qual_type.getTypePtr();
928        if (clang_type)
929        {
930            RecordType *record_type = dyn_cast<RecordType>(clang_type);
931            if (record_type)
932            {
933                RecordDecl *record_decl = record_type->getDecl();
934                if (record_decl)
935                {
936                    uint32_t field_idx;
937                    RecordDecl::field_iterator field, field_end;
938                    for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
939                         field != field_end;
940                         ++field, ++field_idx)
941                    {
942                        // If no accessibility was assigned, assign the correct one
943                        if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
944                            field->setAccess ((AccessSpecifier)default_accessibility);
945                    }
946                }
947            }
948        }
949    }
950}
951
952#pragma mark C++ Base Classes
953
954CXXBaseSpecifier *
955ClangASTContext::CreateBaseClassSpecifier (void *base_class_type, AccessType access, bool is_virtual, bool base_of_class)
956{
957    if (base_class_type)
958        return new CXXBaseSpecifier (SourceRange(),
959                                     is_virtual,
960                                     base_of_class,
961                                     ConvertAccessTypeToAccessSpecifier (access),
962                                     getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
963    return NULL;
964}
965
966void
967ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
968{
969    for (unsigned i=0; i<num_base_classes; ++i)
970    {
971        delete base_classes[i];
972        base_classes[i] = NULL;
973    }
974}
975
976bool
977ClangASTContext::SetBaseClassesForClassType (void *class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
978{
979    if (class_clang_type)
980    {
981        clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
982        if (clang_type)
983        {
984            RecordType *record_type = dyn_cast<RecordType>(clang_type);
985            if (record_type)
986            {
987                CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
988                if (cxx_record_decl)
989                {
990                    //cxx_record_decl->setEmpty (false);
991                    cxx_record_decl->setBases(base_classes, num_base_classes);
992                    return true;
993                }
994            }
995        }
996    }
997    return false;
998}
999#pragma mark Objective C Classes
1000
1001void *
1002ClangASTContext::CreateObjCClass
1003(
1004    const char *name,
1005    DeclContext *decl_ctx,
1006    bool isForwardDecl,
1007    bool isInternal
1008)
1009{
1010    ASTContext *ast_context = getASTContext();
1011    assert (ast_context != NULL);
1012    assert (name && name[0]);
1013    if (decl_ctx == NULL)
1014        decl_ctx = ast_context->getTranslationUnitDecl();
1015
1016    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1017    // we will need to update this code. I was told to currently always use
1018    // the CXXRecordDecl class since we often don't know from debug information
1019    // if something is struct or a class, so we default to always use the more
1020    // complete definition just in case.
1021    ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1022                                                         decl_ctx,
1023                                                         SourceLocation(),
1024                                                         &ast_context->Idents.get(name),
1025                                                         SourceLocation(),
1026                                                         isForwardDecl,
1027                                                         isInternal);
1028
1029    return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
1030}
1031
1032bool
1033ClangASTContext::SetObjCSuperClass (void *class_opaque_type, void *super_opaque_type)
1034{
1035    if (class_opaque_type && super_opaque_type)
1036    {
1037        QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1038        QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1039        clang::Type *class_type = class_qual_type.getTypePtr();
1040        clang::Type *super_type = super_qual_type.getTypePtr();
1041        if (class_type && super_type)
1042        {
1043            ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1044            ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1045            if (objc_class_type && objc_super_type)
1046            {
1047                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1048                ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1049                if (class_interface_decl && super_interface_decl)
1050                {
1051                    class_interface_decl->setSuperClass(super_interface_decl);
1052                    return true;
1053                }
1054            }
1055        }
1056    }
1057    return false;
1058}
1059
1060
1061bool
1062ClangASTContext::AddObjCClassIVar
1063(
1064    void *class_opaque_type,
1065    const char *name,
1066    void *ivar_opaque_type,
1067    AccessType access,
1068    uint32_t bitfield_bit_size,
1069    bool isSynthesized
1070)
1071{
1072    if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1073        return false;
1074
1075    ASTContext *ast_context = getASTContext();
1076    IdentifierTable *identifier_table = getIdentifierTable();
1077
1078    assert (ast_context != NULL);
1079    assert (identifier_table != NULL);
1080
1081    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1082
1083    clang::Type *class_type = class_qual_type.getTypePtr();
1084    if (class_type)
1085    {
1086        ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1087
1088        if (objc_class_type)
1089        {
1090            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1091
1092            if (class_interface_decl)
1093            {
1094                clang::Expr *bit_width = NULL;
1095                if (bitfield_bit_size != 0)
1096                {
1097                    APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
1098                    bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
1099                }
1100
1101                ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1102                                                            class_interface_decl,
1103                                                            SourceLocation(),
1104                                                            &identifier_table->get(name), // Identifier
1105                                                            QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1106                                                            NULL, // TypeSourceInfo *
1107                                                            ConvertAccessTypeToObjCIvarAccessControl (access),
1108                                                            bit_width,
1109                                                            isSynthesized);
1110
1111                if (field)
1112                {
1113                    class_interface_decl->addDecl(field);
1114                    return true;
1115                }
1116            }
1117        }
1118    }
1119    return false;
1120}
1121
1122
1123bool
1124ClangASTContext::ObjCTypeHasIVars (void *class_opaque_type, bool check_superclass)
1125{
1126    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1127
1128    clang::Type *class_type = class_qual_type.getTypePtr();
1129    if (class_type)
1130    {
1131        ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1132
1133        if (objc_class_type)
1134            return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1135    }
1136    return false;
1137}
1138
1139bool
1140ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1141{
1142    while (class_interface_decl)
1143    {
1144        if (class_interface_decl->ivar_size() > 0)
1145            return true;
1146
1147        if (check_superclass)
1148            class_interface_decl = class_interface_decl->getSuperClass();
1149        else
1150            break;
1151    }
1152    return false;
1153}
1154
1155
1156#pragma mark Aggregate Types
1157
1158bool
1159ClangASTContext::IsAggregateType (void *clang_type)
1160{
1161    if (clang_type == NULL)
1162        return false;
1163
1164    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1165
1166    if (qual_type->isAggregateType ())
1167        return true;
1168
1169    switch (qual_type->getTypeClass())
1170    {
1171    case clang::Type::IncompleteArray:
1172    case clang::Type::VariableArray:
1173    case clang::Type::ConstantArray:
1174    case clang::Type::ExtVector:
1175    case clang::Type::Vector:
1176    case clang::Type::Record:
1177    case clang::Type::ObjCObject:
1178    case clang::Type::ObjCInterface:
1179    case clang::Type::ObjCObjectPointer:
1180        return true;
1181
1182    case clang::Type::Typedef:
1183        return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1184
1185    default:
1186        break;
1187    }
1188    // The clang type does have a value
1189    return false;
1190}
1191
1192uint32_t
1193ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_classes)
1194{
1195    if (clang_qual_type == NULL)
1196        return 0;
1197
1198    uint32_t num_children = 0;
1199    QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
1200    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1201    switch (type_class)
1202    {
1203    case clang::Type::Record:
1204        {
1205            const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1206            const RecordDecl *record_decl = record_type->getDecl();
1207            assert(record_decl);
1208            const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1209            if (cxx_record_decl)
1210            {
1211                if (omit_empty_base_classes)
1212                {
1213                    // Check each base classes to see if it or any of its
1214                    // base classes contain any fields. This can help
1215                    // limit the noise in variable views by not having to
1216                    // show base classes that contain no members.
1217                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1218                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1219                         base_class != base_class_end;
1220                         ++base_class)
1221                    {
1222                        const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1223
1224                        // Skip empty base classes
1225                        if (RecordHasFields(base_class_decl) == false)
1226                            continue;
1227
1228                        num_children++;
1229                    }
1230                }
1231                else
1232                {
1233                    // Include all base classes
1234                    num_children += cxx_record_decl->getNumBases();
1235                }
1236
1237            }
1238            RecordDecl::field_iterator field, field_end;
1239            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1240                ++num_children;
1241        }
1242        break;
1243
1244    case clang::Type::ObjCObject:
1245    case clang::Type::ObjCInterface:
1246        {
1247            ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1248            assert (objc_class_type);
1249            if (objc_class_type)
1250            {
1251                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1252
1253                if (class_interface_decl)
1254                {
1255
1256                    ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1257                    if (superclass_interface_decl)
1258                    {
1259                        if (omit_empty_base_classes)
1260                        {
1261                            if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1262                                ++num_children;
1263                        }
1264                        else
1265                            ++num_children;
1266                    }
1267
1268                    num_children += class_interface_decl->ivar_size();
1269                }
1270            }
1271        }
1272        break;
1273
1274    case clang::Type::ObjCObjectPointer:
1275        return ClangASTContext::GetNumChildren (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
1276                                                omit_empty_base_classes);
1277
1278    case clang::Type::ConstantArray:
1279        num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1280        break;
1281
1282    case clang::Type::Pointer:
1283        {
1284            PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1285            QualType pointee_type = pointer_type->getPointeeType();
1286            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1287                                                                             omit_empty_base_classes);
1288            // If this type points to a simple type, then it has 1 child
1289            if (num_pointee_children == 0)
1290                num_children = 1;
1291            else
1292                num_children = num_pointee_children;
1293        }
1294        break;
1295
1296    case clang::Type::Typedef:
1297        num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1298        break;
1299
1300    default:
1301        break;
1302    }
1303    return num_children;
1304}
1305
1306
1307void *
1308ClangASTContext::GetChildClangTypeAtIndex
1309(
1310    const char *parent_name,
1311    void *parent_clang_type,
1312    uint32_t idx,
1313    bool transparent_pointers,
1314    bool omit_empty_base_classes,
1315    std::string& child_name,
1316    uint32_t &child_byte_size,
1317    int32_t &child_byte_offset,
1318    uint32_t &child_bitfield_bit_size,
1319    uint32_t &child_bitfield_bit_offset
1320)
1321{
1322    if (parent_clang_type)
1323
1324        return GetChildClangTypeAtIndex (getASTContext(),
1325                                         parent_name,
1326                                         parent_clang_type,
1327                                         idx,
1328                                         transparent_pointers,
1329                                         omit_empty_base_classes,
1330                                         child_name,
1331                                         child_byte_size,
1332                                         child_byte_offset,
1333                                         child_bitfield_bit_size,
1334                                         child_bitfield_bit_offset);
1335    return NULL;
1336}
1337
1338void *
1339ClangASTContext::GetChildClangTypeAtIndex
1340(
1341    ASTContext *ast_context,
1342    const char *parent_name,
1343    void *parent_clang_type,
1344    uint32_t idx,
1345    bool transparent_pointers,
1346    bool omit_empty_base_classes,
1347    std::string& child_name,
1348    uint32_t &child_byte_size,
1349    int32_t &child_byte_offset,
1350    uint32_t &child_bitfield_bit_size,
1351    uint32_t &child_bitfield_bit_offset
1352)
1353{
1354    if (parent_clang_type == NULL)
1355        return NULL;
1356
1357    if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
1358    {
1359        uint32_t bit_offset;
1360        child_bitfield_bit_size = 0;
1361        child_bitfield_bit_offset = 0;
1362        QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
1363        switch (parent_qual_type->getTypeClass())
1364        {
1365        case clang::Type::Record:
1366            {
1367                const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
1368                const RecordDecl *record_decl = record_type->getDecl();
1369                assert(record_decl);
1370                const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
1371                uint32_t child_idx = 0;
1372
1373                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1374                if (cxx_record_decl)
1375                {
1376                    // We might have base classes to print out first
1377                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1378                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1379                         base_class != base_class_end;
1380                         ++base_class)
1381                    {
1382                        const CXXRecordDecl *base_class_decl = NULL;
1383
1384                        // Skip empty base classes
1385                        if (omit_empty_base_classes)
1386                        {
1387                            base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1388                            if (RecordHasFields(base_class_decl) == false)
1389                                continue;
1390                        }
1391
1392                        if (idx == child_idx)
1393                        {
1394                            if (base_class_decl == NULL)
1395                                base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1396
1397
1398                            if (base_class->isVirtual())
1399                                bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
1400                            else
1401                                bit_offset = record_layout.getBaseClassOffset(base_class_decl);
1402
1403                            // Base classes should be a multiple of 8 bits in size
1404                            assert (bit_offset % 8 == 0);
1405                            child_byte_offset = bit_offset/8;
1406                            std::string base_class_type_name(base_class->getType().getAsString());
1407
1408                            child_name.assign(base_class_type_name.c_str());
1409
1410                            uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
1411
1412                            // Base classes biut sizes should be a multiple of 8 bits in size
1413                            assert (clang_type_info_bit_size % 8 == 0);
1414                            child_byte_size = clang_type_info_bit_size / 8;
1415                            return base_class->getType().getAsOpaquePtr();
1416                        }
1417                        // We don't increment the child index in the for loop since we might
1418                        // be skipping empty base classes
1419                        ++child_idx;
1420                    }
1421                }
1422                // Make sure index is in range...
1423                uint32_t field_idx = 0;
1424                RecordDecl::field_iterator field, field_end;
1425                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
1426                {
1427                    if (idx == child_idx)
1428                    {
1429                        // Print the member type if requested
1430                        // Print the member name and equal sign
1431                        child_name.assign(field->getNameAsString().c_str());
1432
1433                        // Figure out the type byte size (field_type_info.first) and
1434                        // alignment (field_type_info.second) from the AST context.
1435                        std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
1436                        assert(field_idx < record_layout.getFieldCount());
1437
1438                        child_byte_size = field_type_info.first / 8;
1439
1440                        // Figure out the field offset within the current struct/union/class type
1441                        bit_offset = record_layout.getFieldOffset (field_idx);
1442                        child_byte_offset = bit_offset / 8;
1443                        if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
1444                            child_bitfield_bit_offset = bit_offset % 8;
1445
1446                        return field->getType().getAsOpaquePtr();
1447                    }
1448                }
1449            }
1450            break;
1451
1452        case clang::Type::ObjCObject:
1453        case clang::Type::ObjCInterface:
1454            {
1455                ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
1456                assert (objc_class_type);
1457                if (objc_class_type)
1458                {
1459                    uint32_t child_idx = 0;
1460                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1461
1462                    if (class_interface_decl)
1463                    {
1464
1465                        const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
1466                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1467                        if (superclass_interface_decl)
1468                        {
1469                            if (omit_empty_base_classes)
1470                            {
1471                                if (ClangASTContext::GetNumChildren(superclass_interface_decl, omit_empty_base_classes) > 0)
1472                                {
1473                                    if (idx == 0)
1474                                    {
1475                                        QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
1476
1477
1478                                        child_name.assign(superclass_interface_decl->getNameAsString().c_str());
1479
1480                                        std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
1481
1482                                        child_byte_size = ivar_type_info.first / 8;
1483
1484                                        // Figure out the field offset within the current struct/union/class type
1485                                        bit_offset = interface_layout.getFieldOffset (child_idx);
1486                                        child_byte_offset = bit_offset / 8;
1487
1488                                        return ivar_qual_type.getAsOpaquePtr();
1489                                    }
1490
1491                                    ++child_idx;
1492                                }
1493                            }
1494                            else
1495                                ++child_idx;
1496                        }
1497
1498                        if (idx < (child_idx + class_interface_decl->ivar_size()))
1499                        {
1500                            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
1501
1502                            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
1503                            {
1504                                if (child_idx == idx)
1505                                {
1506                                    const ObjCIvarDecl* ivar_decl = *ivar_pos;
1507
1508                                    QualType ivar_qual_type(ivar_decl->getType());
1509
1510                                    child_name.assign(ivar_decl->getNameAsString().c_str());
1511
1512                                    std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
1513
1514                                    child_byte_size = ivar_type_info.first / 8;
1515
1516                                    // Figure out the field offset within the current struct/union/class type
1517                                    bit_offset = interface_layout.getFieldOffset (child_idx);
1518                                    child_byte_offset = bit_offset / 8;
1519
1520                                    return ivar_qual_type.getAsOpaquePtr();
1521                                }
1522                                ++child_idx;
1523                            }
1524                        }
1525                    }
1526                }
1527            }
1528            break;
1529
1530        case clang::Type::ObjCObjectPointer:
1531            {
1532                return GetChildClangTypeAtIndex (ast_context,
1533                                                 parent_name,
1534                                                 cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
1535                                                 idx,
1536                                                 transparent_pointers,
1537                                                 omit_empty_base_classes,
1538                                                 child_name,
1539                                                 child_byte_size,
1540                                                 child_byte_offset,
1541                                                 child_bitfield_bit_size,
1542                                                 child_bitfield_bit_offset);
1543            }
1544            break;
1545
1546        case clang::Type::ConstantArray:
1547            {
1548                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1549                const uint64_t element_count = array->getSize().getLimitedValue();
1550
1551                if (idx < element_count)
1552                {
1553                    std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1554
1555                    char element_name[32];
1556                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1557
1558                    child_name.assign(element_name);
1559                    assert(field_type_info.first % 8 == 0);
1560                    child_byte_size = field_type_info.first / 8;
1561                    child_byte_offset = idx * child_byte_size;
1562                    return array->getElementType().getAsOpaquePtr();
1563                }
1564            }
1565            break;
1566
1567        case clang::Type::Pointer:
1568            {
1569                PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
1570                QualType pointee_type = pointer_type->getPointeeType();
1571
1572                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1573                {
1574                    return GetChildClangTypeAtIndex (ast_context,
1575                                                     parent_name,
1576                                                     pointer_type->getPointeeType().getAsOpaquePtr(),
1577                                                     idx,
1578                                                     transparent_pointers,
1579                                                     omit_empty_base_classes,
1580                                                     child_name,
1581                                                     child_byte_size,
1582                                                     child_byte_offset,
1583                                                     child_bitfield_bit_size,
1584                                                     child_bitfield_bit_offset);
1585                }
1586                else
1587                {
1588                    if (parent_name)
1589                    {
1590                        child_name.assign(1, '*');
1591                        child_name += parent_name;
1592                    }
1593
1594                    // We have a pointer to an simple type
1595                    if (idx == 0)
1596                    {
1597                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1598                        assert(clang_type_info.first % 8 == 0);
1599                        child_byte_size = clang_type_info.first / 8;
1600                        child_byte_offset = 0;
1601                        return pointee_type.getAsOpaquePtr();
1602                    }
1603                }
1604            }
1605            break;
1606
1607        case clang::Type::Typedef:
1608            return GetChildClangTypeAtIndex (ast_context,
1609                                             parent_name,
1610                                             cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1611                                             idx,
1612                                             transparent_pointers,
1613                                             omit_empty_base_classes,
1614                                             child_name,
1615                                             child_byte_size,
1616                                             child_byte_offset,
1617                                             child_bitfield_bit_size,
1618                                             child_bitfield_bit_offset);
1619            break;
1620
1621        default:
1622            break;
1623        }
1624    }
1625    return NULL;
1626}
1627
1628static inline bool
1629BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
1630{
1631    return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
1632}
1633
1634static uint32_t
1635GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
1636{
1637    uint32_t num_bases = 0;
1638    if (cxx_record_decl)
1639    {
1640        if (omit_empty_base_classes)
1641        {
1642            CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1643            for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1644                 base_class != base_class_end;
1645                 ++base_class)
1646            {
1647                // Skip empty base classes
1648                if (omit_empty_base_classes)
1649                {
1650                    if (BaseSpecifierIsEmpty (base_class))
1651                        continue;
1652                }
1653                ++num_bases;
1654            }
1655        }
1656        else
1657            num_bases = cxx_record_decl->getNumBases();
1658    }
1659    return num_bases;
1660}
1661
1662
1663static uint32_t
1664GetIndexForRecordBase
1665(
1666    const RecordDecl *record_decl,
1667    const CXXBaseSpecifier *base_spec,
1668    bool omit_empty_base_classes
1669)
1670{
1671    uint32_t child_idx = 0;
1672
1673    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1674
1675//    const char *super_name = record_decl->getNameAsCString();
1676//    const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
1677//    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
1678//
1679    if (cxx_record_decl)
1680    {
1681        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1682        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1683             base_class != base_class_end;
1684             ++base_class)
1685        {
1686            if (omit_empty_base_classes)
1687            {
1688                if (BaseSpecifierIsEmpty (base_class))
1689                    continue;
1690            }
1691
1692//            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
1693//                    child_idx,
1694//                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1695//
1696//
1697            if (base_class == base_spec)
1698                return child_idx;
1699            ++child_idx;
1700        }
1701    }
1702
1703    return UINT32_MAX;
1704}
1705
1706
1707static uint32_t
1708GetIndexForRecordChild
1709(
1710    const RecordDecl *record_decl,
1711    NamedDecl *canonical_decl,
1712    bool omit_empty_base_classes
1713)
1714{
1715    uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
1716
1717//    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1718//
1719////    printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
1720//    if (cxx_record_decl)
1721//    {
1722//        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1723//        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1724//             base_class != base_class_end;
1725//             ++base_class)
1726//        {
1727//            if (omit_empty_base_classes)
1728//            {
1729//                if (BaseSpecifierIsEmpty (base_class))
1730//                    continue;
1731//            }
1732//
1733////            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
1734////                    record_decl->getNameAsCString(),
1735////                    canonical_decl->getNameAsCString(),
1736////                    child_idx,
1737////                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1738//
1739//
1740//            CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1741//            if (curr_base_class_decl == canonical_decl)
1742//            {
1743//                return child_idx;
1744//            }
1745//            ++child_idx;
1746//        }
1747//    }
1748//
1749//    const uint32_t num_bases = child_idx;
1750    RecordDecl::field_iterator field, field_end;
1751    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1752         field != field_end;
1753         ++field, ++child_idx)
1754    {
1755//            printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
1756//                    record_decl->getNameAsCString(),
1757//                    canonical_decl->getNameAsCString(),
1758//                    child_idx - num_bases,
1759//                    field->getNameAsCString());
1760
1761        if (field->getCanonicalDecl() == canonical_decl)
1762            return child_idx;
1763    }
1764
1765    return UINT32_MAX;
1766}
1767
1768// Look for a child member (doesn't include base classes, but it does include
1769// their members) in the type hierarchy. Returns an index path into "clang_type"
1770// on how to reach the appropriate member.
1771//
1772//    class A
1773//    {
1774//    public:
1775//        int m_a;
1776//        int m_b;
1777//    };
1778//
1779//    class B
1780//    {
1781//    };
1782//
1783//    class C :
1784//        public B,
1785//        public A
1786//    {
1787//    };
1788//
1789// If we have a clang type that describes "class C", and we wanted to looked
1790// "m_b" in it:
1791//
1792// With omit_empty_base_classes == false we would get an integer array back with:
1793// { 1,  1 }
1794// The first index 1 is the child index for "class A" within class C
1795// The second index 1 is the child index for "m_b" within class A
1796//
1797// With omit_empty_base_classes == true we would get an integer array back with:
1798// { 0,  1 }
1799// 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)
1800// The second index 1 is the child index for "m_b" within class A
1801
1802size_t
1803ClangASTContext::GetIndexOfChildMemberWithName
1804(
1805    ASTContext *ast_context,
1806    void *clang_type,
1807    const char *name,
1808    bool omit_empty_base_classes,
1809    std::vector<uint32_t>& child_indexes
1810)
1811{
1812    if (clang_type && name && name[0])
1813    {
1814        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1815        switch (qual_type->getTypeClass())
1816        {
1817        case clang::Type::Record:
1818            {
1819                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1820                const RecordDecl *record_decl = record_type->getDecl();
1821
1822                assert(record_decl);
1823                uint32_t child_idx = 0;
1824
1825                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1826
1827                // Try and find a field that matches NAME
1828                RecordDecl::field_iterator field, field_end;
1829                StringRef name_sref(name);
1830                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1831                     field != field_end;
1832                     ++field, ++child_idx)
1833                {
1834                    if (field->getName().equals (name_sref))
1835                    {
1836                        // We have to add on the number of base classes to this index!
1837                        child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
1838                        return child_indexes.size();
1839                    }
1840                }
1841
1842                if (cxx_record_decl)
1843                {
1844                    const RecordDecl *parent_record_decl = cxx_record_decl;
1845
1846                    //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
1847
1848                    //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
1849                    // Didn't find things easily, lets let clang do its thang...
1850                    IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
1851                    DeclarationName decl_name(&ident_ref);
1852
1853                    CXXBasePaths paths;
1854                    if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
1855                                                       decl_name.getAsOpaquePtr(),
1856                                                       paths))
1857                    {
1858                        CXXBasePaths::const_paths_iterator path, path_end = paths.end();
1859                        for (path = paths.begin(); path != path_end; ++path)
1860                        {
1861                            const size_t num_path_elements = path->size();
1862                            for (size_t e=0; e<num_path_elements; ++e)
1863                            {
1864                                CXXBasePathElement elem = (*path)[e];
1865
1866                                child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
1867                                if (child_idx == UINT32_MAX)
1868                                {
1869                                    child_indexes.clear();
1870                                    return 0;
1871                                }
1872                                else
1873                                {
1874                                    child_indexes.push_back (child_idx);
1875                                    parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
1876                                }
1877                            }
1878                            DeclContext::lookup_iterator named_decl_pos;
1879                            for (named_decl_pos = path->Decls.first;
1880                                 named_decl_pos != path->Decls.second && parent_record_decl;
1881                                 ++named_decl_pos)
1882                            {
1883                                //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
1884
1885                                child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
1886                                if (child_idx == UINT32_MAX)
1887                                {
1888                                    child_indexes.clear();
1889                                    return 0;
1890                                }
1891                                else
1892                                {
1893                                    child_indexes.push_back (child_idx);
1894                                }
1895                            }
1896                        }
1897                        return child_indexes.size();
1898                    }
1899                }
1900
1901            }
1902            break;
1903
1904        case clang::Type::ObjCObject:
1905        case clang::Type::ObjCInterface:
1906            {
1907                StringRef name_sref(name);
1908                ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1909                assert (objc_class_type);
1910                if (objc_class_type)
1911                {
1912                    uint32_t child_idx = 0;
1913                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1914
1915                    if (class_interface_decl)
1916                    {
1917                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
1918                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1919
1920                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
1921                        {
1922                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
1923
1924                            if (ivar_decl->getName().equals (name_sref))
1925                            {
1926                                if ((!omit_empty_base_classes && superclass_interface_decl) ||
1927                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
1928                                    ++child_idx;
1929
1930                                child_indexes.push_back (child_idx);
1931                                return child_indexes.size();
1932                            }
1933                        }
1934
1935                        if (superclass_interface_decl)
1936                        {
1937                            // The super class index is always zero for ObjC classes,
1938                            // so we push it onto the child indexes in case we find
1939                            // an ivar in our superclass...
1940                            child_indexes.push_back (0);
1941
1942                            if (GetIndexOfChildMemberWithName (ast_context,
1943                                                               ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
1944                                                               name,
1945                                                               omit_empty_base_classes,
1946                                                               child_indexes))
1947                            {
1948                                // We did find an ivar in a superclass so just
1949                                // return the results!
1950                                return child_indexes.size();
1951                            }
1952
1953                            // We didn't find an ivar matching "name" in our
1954                            // superclass, pop the superclass zero index that
1955                            // we pushed on above.
1956                            child_indexes.pop_back();
1957                        }
1958                    }
1959                }
1960            }
1961            break;
1962
1963        case clang::Type::ObjCObjectPointer:
1964            {
1965                return GetIndexOfChildMemberWithName (ast_context,
1966                                                      cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
1967                                                      name,
1968                                                      omit_empty_base_classes,
1969                                                      child_indexes);
1970            }
1971            break;
1972
1973
1974        case clang::Type::ConstantArray:
1975            {
1976//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1977//                const uint64_t element_count = array->getSize().getLimitedValue();
1978//
1979//                if (idx < element_count)
1980//                {
1981//                    std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1982//
1983//                    char element_name[32];
1984//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1985//
1986//                    child_name.assign(element_name);
1987//                    assert(field_type_info.first % 8 == 0);
1988//                    child_byte_size = field_type_info.first / 8;
1989//                    child_byte_offset = idx * child_byte_size;
1990//                    return array->getElementType().getAsOpaquePtr();
1991//                }
1992            }
1993            break;
1994
1995//        case clang::Type::MemberPointerType:
1996//            {
1997//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
1998//                QualType pointee_type = mem_ptr_type->getPointeeType();
1999//
2000//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2001//                {
2002//                    return GetIndexOfChildWithName (ast_context,
2003//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2004//                                                    name);
2005//                }
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
2015                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2016                {
2017                    return GetIndexOfChildMemberWithName (ast_context,
2018                                                          reference_type->getPointeeType().getAsOpaquePtr(),
2019                                                          name,
2020                                                          omit_empty_base_classes,
2021                                                          child_indexes);
2022                }
2023            }
2024            break;
2025
2026        case clang::Type::Pointer:
2027            {
2028                PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2029                QualType pointee_type = pointer_type->getPointeeType();
2030
2031                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2032                {
2033                    return GetIndexOfChildMemberWithName (ast_context,
2034                                                          pointer_type->getPointeeType().getAsOpaquePtr(),
2035                                                          name,
2036                                                          omit_empty_base_classes,
2037                                                          child_indexes);
2038                }
2039                else
2040                {
2041//                    if (parent_name)
2042//                    {
2043//                        child_name.assign(1, '*');
2044//                        child_name += parent_name;
2045//                    }
2046//
2047//                    // We have a pointer to an simple type
2048//                    if (idx == 0)
2049//                    {
2050//                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2051//                        assert(clang_type_info.first % 8 == 0);
2052//                        child_byte_size = clang_type_info.first / 8;
2053//                        child_byte_offset = 0;
2054//                        return pointee_type.getAsOpaquePtr();
2055//                    }
2056                }
2057            }
2058            break;
2059
2060        case clang::Type::Typedef:
2061            return GetIndexOfChildMemberWithName (ast_context,
2062                                                  cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2063                                                  name,
2064                                                  omit_empty_base_classes,
2065                                                  child_indexes);
2066
2067        default:
2068            break;
2069        }
2070    }
2071    return 0;
2072}
2073
2074
2075// Get the index of the child of "clang_type" whose name matches. This function
2076// doesn't descend into the children, but only looks one level deep and name
2077// matches can include base class names.
2078
2079uint32_t
2080ClangASTContext::GetIndexOfChildWithName
2081(
2082    ASTContext *ast_context,
2083    void *clang_type,
2084    const char *name,
2085    bool omit_empty_base_classes
2086)
2087{
2088    if (clang_type && name && name[0])
2089    {
2090        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2091
2092        clang::Type::TypeClass qual_type_class = qual_type->getTypeClass();
2093
2094        switch (qual_type_class)
2095        {
2096        case clang::Type::Record:
2097            {
2098                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2099                const RecordDecl *record_decl = record_type->getDecl();
2100
2101                assert(record_decl);
2102                uint32_t child_idx = 0;
2103
2104                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2105
2106                if (cxx_record_decl)
2107                {
2108                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2109                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2110                         base_class != base_class_end;
2111                         ++base_class)
2112                    {
2113                        // Skip empty base classes
2114                        CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2115                        if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2116                            continue;
2117
2118                        if (base_class->getType().getAsString().compare (name) == 0)
2119                            return child_idx;
2120                        ++child_idx;
2121                    }
2122                }
2123
2124                // Try and find a field that matches NAME
2125                RecordDecl::field_iterator field, field_end;
2126                StringRef name_sref(name);
2127                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2128                     field != field_end;
2129                     ++field, ++child_idx)
2130                {
2131                    if (field->getName().equals (name_sref))
2132                        return child_idx;
2133                }
2134
2135            }
2136            break;
2137
2138        case clang::Type::ObjCObject:
2139        case clang::Type::ObjCInterface:
2140            {
2141                StringRef name_sref(name);
2142                ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2143                assert (objc_class_type);
2144                if (objc_class_type)
2145                {
2146                    uint32_t child_idx = 0;
2147                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2148
2149                    if (class_interface_decl)
2150                    {
2151                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2152                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2153
2154                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2155                        {
2156                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
2157
2158                            if (ivar_decl->getName().equals (name_sref))
2159                            {
2160                                if ((!omit_empty_base_classes && superclass_interface_decl) ||
2161                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2162                                    ++child_idx;
2163
2164                                return child_idx;
2165                            }
2166                        }
2167
2168                        if (superclass_interface_decl)
2169                        {
2170                            if (superclass_interface_decl->getName().equals (name_sref))
2171                                return 0;
2172                        }
2173                    }
2174                }
2175            }
2176            break;
2177
2178        case clang::Type::ObjCObjectPointer:
2179            {
2180                return GetIndexOfChildWithName (ast_context,
2181                                                cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2182                                                name,
2183                                                omit_empty_base_classes);
2184            }
2185            break;
2186
2187        case clang::Type::ConstantArray:
2188            {
2189//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2190//                const uint64_t element_count = array->getSize().getLimitedValue();
2191//
2192//                if (idx < element_count)
2193//                {
2194//                    std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2195//
2196//                    char element_name[32];
2197//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2198//
2199//                    child_name.assign(element_name);
2200//                    assert(field_type_info.first % 8 == 0);
2201//                    child_byte_size = field_type_info.first / 8;
2202//                    child_byte_offset = idx * child_byte_size;
2203//                    return array->getElementType().getAsOpaquePtr();
2204//                }
2205            }
2206            break;
2207
2208//        case clang::Type::MemberPointerType:
2209//            {
2210//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2211//                QualType pointee_type = mem_ptr_type->getPointeeType();
2212//
2213//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2214//                {
2215//                    return GetIndexOfChildWithName (ast_context,
2216//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2217//                                                    name);
2218//                }
2219//            }
2220//            break;
2221//
2222        case clang::Type::LValueReference:
2223        case clang::Type::RValueReference:
2224            {
2225                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2226                QualType pointee_type = reference_type->getPointeeType();
2227
2228                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2229                {
2230                    return GetIndexOfChildWithName (ast_context,
2231                                                    reference_type->getPointeeType().getAsOpaquePtr(),
2232                                                    name,
2233                                                    omit_empty_base_classes);
2234                }
2235            }
2236            break;
2237
2238        case clang::Type::Pointer:
2239            {
2240                PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2241                QualType pointee_type = pointer_type->getPointeeType();
2242
2243                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2244                {
2245                    return GetIndexOfChildWithName (ast_context,
2246                                                    pointer_type->getPointeeType().getAsOpaquePtr(),
2247                                                    name,
2248                                                    omit_empty_base_classes);
2249                }
2250                else
2251                {
2252//                    if (parent_name)
2253//                    {
2254//                        child_name.assign(1, '*');
2255//                        child_name += parent_name;
2256//                    }
2257//
2258//                    // We have a pointer to an simple type
2259//                    if (idx == 0)
2260//                    {
2261//                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2262//                        assert(clang_type_info.first % 8 == 0);
2263//                        child_byte_size = clang_type_info.first / 8;
2264//                        child_byte_offset = 0;
2265//                        return pointee_type.getAsOpaquePtr();
2266//                    }
2267                }
2268            }
2269            break;
2270
2271        case clang::Type::Typedef:
2272            return GetIndexOfChildWithName (ast_context,
2273                                            cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2274                                            name,
2275                                            omit_empty_base_classes);
2276
2277        default:
2278            break;
2279        }
2280    }
2281    return UINT32_MAX;
2282}
2283
2284#pragma mark TagType
2285
2286bool
2287ClangASTContext::SetTagTypeKind (void *tag_clang_type, int kind)
2288{
2289    if (tag_clang_type)
2290    {
2291        QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
2292        clang::Type *clang_type = tag_qual_type.getTypePtr();
2293        if (clang_type)
2294        {
2295            TagType *tag_type = dyn_cast<TagType>(clang_type);
2296            if (tag_type)
2297            {
2298                TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
2299                if (tag_decl)
2300                {
2301                    tag_decl->setTagKind ((TagDecl::TagKind)kind);
2302                    return true;
2303                }
2304            }
2305        }
2306    }
2307    return false;
2308}
2309
2310
2311#pragma mark DeclContext Functions
2312
2313DeclContext *
2314ClangASTContext::GetDeclContextForType (void *clang_type)
2315{
2316    if (clang_type == NULL)
2317        return NULL;
2318
2319    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2320    switch (qual_type->getTypeClass())
2321    {
2322    case clang::Type::FunctionNoProto:          break;
2323    case clang::Type::FunctionProto:            break;
2324    case clang::Type::IncompleteArray:          break;
2325    case clang::Type::VariableArray:            break;
2326    case clang::Type::ConstantArray:            break;
2327    case clang::Type::ExtVector:                break;
2328    case clang::Type::Vector:                   break;
2329    case clang::Type::Builtin:                  break;
2330    case clang::Type::BlockPointer:             break;
2331    case clang::Type::Pointer:                  break;
2332    case clang::Type::LValueReference:          break;
2333    case clang::Type::RValueReference:          break;
2334    case clang::Type::MemberPointer:            break;
2335    case clang::Type::Complex:                  break;
2336    case clang::Type::ObjCObject:               break;
2337    case clang::Type::ObjCInterface:            return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
2338    case clang::Type::ObjCObjectPointer:        return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
2339    case clang::Type::Record:                   return cast<RecordType>(qual_type)->getDecl();
2340    case clang::Type::Enum:                     return cast<EnumType>(qual_type)->getDecl();
2341    case clang::Type::Typedef:                  return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
2342
2343    case clang::Type::TypeOfExpr:               break;
2344    case clang::Type::TypeOf:                   break;
2345    case clang::Type::Decltype:                 break;
2346    //case clang::Type::QualifiedName:          break;
2347    case clang::Type::TemplateSpecialization:   break;
2348    }
2349    // No DeclContext in this type...
2350    return NULL;
2351}
2352
2353#pragma mark Namespace Declarations
2354
2355NamespaceDecl *
2356ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
2357{
2358    // TODO: Do something intelligent with the Declaration object passed in
2359    // like maybe filling in the SourceLocation with it...
2360    if (name)
2361    {
2362        ASTContext *ast_context = getASTContext();
2363        if (decl_ctx == NULL)
2364            decl_ctx = ast_context->getTranslationUnitDecl();
2365        return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
2366    }
2367    return NULL;
2368}
2369
2370
2371#pragma mark Function Types
2372
2373FunctionDecl *
2374ClangASTContext::CreateFunctionDeclaration (const char *name, void *function_clang_type, int storage, bool is_inline)
2375{
2376    if (name)
2377    {
2378        ASTContext *ast_context = getASTContext();
2379        assert (ast_context != NULL);
2380
2381        if (name && name[0])
2382        {
2383            return FunctionDecl::Create(*ast_context,
2384                                        ast_context->getTranslationUnitDecl(),
2385                                        SourceLocation(),
2386                                        DeclarationName (&ast_context->Idents.get(name)),
2387                                        QualType::getFromOpaquePtr(function_clang_type),
2388                                        NULL,
2389                                        (FunctionDecl::StorageClass)storage,
2390                                        (FunctionDecl::StorageClass)storage,
2391                                        is_inline);
2392        }
2393        else
2394        {
2395            return FunctionDecl::Create(*ast_context,
2396                                        ast_context->getTranslationUnitDecl(),
2397                                        SourceLocation(),
2398                                        DeclarationName (),
2399                                        QualType::getFromOpaquePtr(function_clang_type),
2400                                        NULL,
2401                                        (FunctionDecl::StorageClass)storage,
2402                                        (FunctionDecl::StorageClass)storage,
2403                                        is_inline);
2404        }
2405    }
2406    return NULL;
2407}
2408
2409void *
2410ClangASTContext::CreateFunctionType (void *result_type, void **args, unsigned num_args, bool isVariadic, unsigned TypeQuals)
2411{
2412    ASTContext *ast_context = getASTContext();
2413    assert (ast_context != NULL);
2414    std::vector<QualType> qual_type_args;
2415    for (unsigned i=0; i<num_args; ++i)
2416        qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
2417
2418    // TODO: Detect calling convention in DWARF?
2419    return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
2420                                        qual_type_args.empty() ? NULL : &qual_type_args.front(),
2421                                        qual_type_args.size(),
2422                                        isVariadic,
2423                                        TypeQuals,
2424                                        false,  // hasExceptionSpec
2425                                        false,  // hasAnyExceptionSpec,
2426                                        0,      // NumExs
2427                                        0,      // const QualType *ExArray
2428                                        FunctionType::ExtInfo ()).getAsOpaquePtr();    // NoReturn);
2429}
2430
2431ParmVarDecl *
2432ClangASTContext::CreateParmeterDeclaration (const char *name, void *return_type, int storage)
2433{
2434    ASTContext *ast_context = getASTContext();
2435    assert (ast_context != NULL);
2436    return ParmVarDecl::Create(*ast_context,
2437                                ast_context->getTranslationUnitDecl(),
2438                                SourceLocation(),
2439                                name && name[0] ? &ast_context->Idents.get(name) : NULL,
2440                                QualType::getFromOpaquePtr(return_type),
2441                                NULL,
2442                                (VarDecl::StorageClass)storage,
2443                                (VarDecl::StorageClass)storage,
2444                                0);
2445}
2446
2447void
2448ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
2449{
2450    if (function_decl)
2451        function_decl->setParams (params, num_params);
2452}
2453
2454
2455#pragma mark Array Types
2456
2457void *
2458ClangASTContext::CreateArrayType (void *element_type, size_t element_count, uint32_t bit_stride)
2459{
2460    if (element_type)
2461    {
2462        ASTContext *ast_context = getASTContext();
2463        assert (ast_context != NULL);
2464        llvm::APInt ap_element_count (64, element_count);
2465        return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
2466                                                 ap_element_count,
2467                                                 ArrayType::Normal,
2468                                                 0).getAsOpaquePtr(); // ElemQuals
2469    }
2470    return NULL;
2471}
2472
2473
2474#pragma mark TagDecl
2475
2476bool
2477ClangASTContext::StartTagDeclarationDefinition (void *clang_type)
2478{
2479    if (clang_type)
2480    {
2481        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2482        clang::Type *t = qual_type.getTypePtr();
2483        if (t)
2484        {
2485            TagType *tag_type = dyn_cast<TagType>(t);
2486            if (tag_type)
2487            {
2488                TagDecl *tag_decl = tag_type->getDecl();
2489                if (tag_decl)
2490                {
2491                    tag_decl->startDefinition();
2492                    return true;
2493                }
2494            }
2495        }
2496    }
2497    return false;
2498}
2499
2500bool
2501ClangASTContext::CompleteTagDeclarationDefinition (void *clang_type)
2502{
2503    if (clang_type)
2504    {
2505        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2506        clang::Type *t = qual_type.getTypePtr();
2507        if (t)
2508        {
2509            TagType *tag_type = dyn_cast<TagType>(t);
2510            if (tag_type)
2511            {
2512                TagDecl *tag_decl = tag_type->getDecl();
2513                if (tag_decl)
2514                {
2515                    tag_decl->completeDefinition();
2516                    return true;
2517                }
2518            }
2519        }
2520    }
2521    return false;
2522}
2523
2524
2525#pragma mark Enumeration Types
2526
2527void *
2528ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name)
2529{
2530    // TODO: Do something intelligent with the Declaration object passed in
2531    // like maybe filling in the SourceLocation with it...
2532    ASTContext *ast_context = getASTContext();
2533    assert (ast_context != NULL);
2534    EnumDecl *enum_decl = EnumDecl::Create(*ast_context,
2535                                           ast_context->getTranslationUnitDecl(),
2536                                           SourceLocation(),
2537                                           name && name[0] ? &ast_context->Idents.get(name) : NULL,
2538                                           SourceLocation(),
2539                                           NULL);
2540    if (enum_decl)
2541        return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
2542    return NULL;
2543}
2544
2545bool
2546ClangASTContext::AddEnumerationValueToEnumerationType
2547(
2548    void *enum_clang_type,
2549    void *enumerator_clang_type,
2550    const Declaration &decl,
2551    const char *name,
2552    int64_t enum_value,
2553    uint32_t enum_value_bit_size
2554)
2555{
2556    if (enum_clang_type && enumerator_clang_type && name)
2557    {
2558        // TODO: Do something intelligent with the Declaration object passed in
2559        // like maybe filling in the SourceLocation with it...
2560        ASTContext *ast_context = getASTContext();
2561        IdentifierTable *identifier_table = getIdentifierTable();
2562
2563        assert (ast_context != NULL);
2564        assert (identifier_table != NULL);
2565        QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
2566
2567        clang::Type *clang_type = enum_qual_type.getTypePtr();
2568        if (clang_type)
2569        {
2570            const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
2571
2572            if (enum_type)
2573            {
2574                llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
2575                enum_llvm_apsint = enum_value;
2576                EnumConstantDecl *enumerator_decl =
2577                    EnumConstantDecl::Create(*ast_context,
2578                                             enum_type->getDecl(),
2579                                             SourceLocation(),
2580                                             name ? &identifier_table->get(name) : NULL,    // Identifier
2581                                             QualType::getFromOpaquePtr(enumerator_clang_type),
2582                                             NULL,
2583                                             enum_llvm_apsint);
2584
2585                if (enumerator_decl)
2586                {
2587                    enum_type->getDecl()->addDecl(enumerator_decl);
2588                    return true;
2589                }
2590            }
2591        }
2592    }
2593    return false;
2594}
2595
2596#pragma mark Pointers & References
2597
2598void *
2599ClangASTContext::CreatePointerType (void *clang_type)
2600{
2601    if (clang_type)
2602    {
2603        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2604
2605        switch (qual_type->getTypeClass())
2606        {
2607        case clang::Type::ObjCObject:
2608        case clang::Type::ObjCInterface:
2609            return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
2610
2611        default:
2612            return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
2613        }
2614    }
2615    return NULL;
2616}
2617
2618void *
2619ClangASTContext::CreateLValueReferenceType (void *clang_type)
2620{
2621    if (clang_type)
2622        return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2623    return NULL;
2624}
2625
2626void *
2627ClangASTContext::CreateRValueReferenceType (void *clang_type)
2628{
2629    if (clang_type)
2630        return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2631    return NULL;
2632}
2633
2634void *
2635ClangASTContext::CreateMemberPointerType (void *clang_pointee_type, void *clang_class_type)
2636{
2637    if (clang_pointee_type && clang_pointee_type)
2638        return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
2639                                                     QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
2640    return NULL;
2641}
2642
2643size_t
2644ClangASTContext::GetPointerBitSize ()
2645{
2646    ASTContext *ast_context = getASTContext();
2647    return ast_context->getTypeSize(ast_context->VoidPtrTy);
2648}
2649
2650bool
2651ClangASTContext::IsPointerOrReferenceType (void *clang_type, void **target_type)
2652{
2653    if (clang_type == NULL)
2654        return false;
2655
2656    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2657    switch (qual_type->getTypeClass())
2658    {
2659    case clang::Type::ObjCObjectPointer:
2660        if (target_type)
2661            *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2662        return true;
2663    case clang::Type::BlockPointer:
2664        if (target_type)
2665            *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2666        return true;
2667    case clang::Type::Pointer:
2668        if (target_type)
2669            *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2670        return true;
2671    case clang::Type::MemberPointer:
2672        if (target_type)
2673            *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2674        return true;
2675    case clang::Type::LValueReference:
2676        if (target_type)
2677            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2678        return true;
2679    case clang::Type::RValueReference:
2680        if (target_type)
2681            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2682        return true;
2683    case clang::Type::Typedef:
2684        return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
2685    default:
2686        break;
2687    }
2688    return false;
2689}
2690
2691size_t
2692ClangASTContext::GetTypeBitSize (clang::ASTContext *ast_context, void *clang_type)
2693{
2694    if (clang_type)
2695        return ast_context->getTypeSize(QualType::getFromOpaquePtr(clang_type));
2696    return 0;
2697}
2698
2699size_t
2700ClangASTContext::GetTypeBitAlign (clang::ASTContext *ast_context, void *clang_type)
2701{
2702    if (clang_type)
2703        return ast_context->getTypeAlign(QualType::getFromOpaquePtr(clang_type));
2704    return 0;
2705}
2706
2707bool
2708ClangASTContext::IsIntegerType (void *clang_type, bool &is_signed)
2709{
2710    if (!clang_type)
2711        return false;
2712
2713    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2714    const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
2715
2716    if (builtin_type)
2717    {
2718        if (builtin_type->isInteger())
2719            is_signed = builtin_type->isSignedInteger();
2720
2721        return true;
2722    }
2723
2724    return false;
2725}
2726
2727bool
2728ClangASTContext::IsPointerType (void *clang_type, void **target_type)
2729{
2730    if (clang_type)
2731    {
2732        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2733        switch (qual_type->getTypeClass())
2734        {
2735        case clang::Type::ObjCObjectPointer:
2736            if (target_type)
2737                *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2738            return true;
2739        case clang::Type::BlockPointer:
2740            if (target_type)
2741                *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2742            return true;
2743        case clang::Type::Pointer:
2744            if (target_type)
2745                *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2746            return true;
2747        case clang::Type::MemberPointer:
2748            if (target_type)
2749                *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2750            return true;
2751        case clang::Type::Typedef:
2752            return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
2753        default:
2754            break;
2755        }
2756    }
2757    return false;
2758}
2759
2760bool
2761ClangASTContext::IsFloatingPointType (void *clang_type, uint32_t &count, bool &is_complex)
2762{
2763    if (clang_type)
2764    {
2765        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2766
2767        if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
2768        {
2769            clang::BuiltinType::Kind kind = BT->getKind();
2770            if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
2771            {
2772                count = 1;
2773                is_complex = false;
2774                return true;
2775            }
2776        }
2777        else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
2778        {
2779            if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
2780            {
2781                count = 2;
2782                is_complex = true;
2783                return true;
2784            }
2785        }
2786        else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
2787        {
2788            if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
2789            {
2790                count = VT->getNumElements();
2791                is_complex = false;
2792                return true;
2793            }
2794        }
2795    }
2796    return false;
2797}
2798
2799
2800bool
2801ClangASTContext::IsCStringType (void *clang_type, uint32_t &length)
2802{
2803    if (clang_type)
2804    {
2805        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2806        switch (qual_type->getTypeClass())
2807        {
2808        case clang::Type::ConstantArray:
2809            {
2810                ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr());
2811                QualType element_qual_type = array->getElementType();
2812                clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
2813                if (canonical_type && canonical_type->isCharType())
2814                {
2815                    // We know the size of the array and it could be a C string
2816                    // since it is an array of characters
2817                    length = array->getSize().getLimitedValue();
2818                    return true;
2819                }
2820            }
2821            break;
2822
2823        case clang::Type::Pointer:
2824            {
2825                PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2826                clang::Type *pointee_type_ptr = pointer_type->getPointeeType().getTypePtr();
2827                if (pointee_type_ptr)
2828                {
2829                    clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
2830                    length = 0; // No length info, read until a NULL terminator is received
2831                    if (canonical_type_ptr)
2832                        return canonical_type_ptr->isCharType();
2833                    else
2834                        return pointee_type_ptr->isCharType();
2835                }
2836            }
2837            break;
2838
2839        case clang::Type::Typedef:
2840            return ClangASTContext::IsCStringType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), length);
2841
2842        case clang::Type::LValueReference:
2843        case clang::Type::RValueReference:
2844            {
2845                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2846                clang::Type *pointee_type_ptr = reference_type->getPointeeType().getTypePtr();
2847                if (pointee_type_ptr)
2848                {
2849                    clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
2850                    length = 0; // No length info, read until a NULL terminator is received
2851                    if (canonical_type_ptr)
2852                        return canonical_type_ptr->isCharType();
2853                    else
2854                        return pointee_type_ptr->isCharType();
2855                }
2856            }
2857            break;
2858        }
2859    }
2860    return false;
2861}
2862
2863bool
2864ClangASTContext::IsArrayType (void *clang_type, void **member_type, uint64_t *size)
2865{
2866    if (!clang_type)
2867        return false;
2868
2869    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2870
2871    switch (qual_type->getTypeClass())
2872    {
2873    case clang::Type::ConstantArray:
2874        if (member_type)
2875            *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2876        if (size)
2877            *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
2878        return true;
2879    case clang::Type::IncompleteArray:
2880        if (member_type)
2881            *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2882        if (size)
2883            *size = 0;
2884        return true;
2885    case clang::Type::VariableArray:
2886        if (member_type)
2887            *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2888        if (size)
2889            *size = 0;
2890    case clang::Type::DependentSizedArray:
2891        if (member_type)
2892            *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2893        if (size)
2894            *size = 0;
2895        return true;
2896    }
2897    return false;
2898}
2899
2900
2901#pragma mark Typedefs
2902
2903void *
2904ClangASTContext::CreateTypedefType (const char *name, void *clang_type, DeclContext *decl_ctx)
2905{
2906    if (clang_type)
2907    {
2908        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2909        ASTContext *ast_context = getASTContext();
2910        IdentifierTable *identifier_table = getIdentifierTable();
2911        assert (ast_context != NULL);
2912        assert (identifier_table != NULL);
2913        if (decl_ctx == NULL)
2914            decl_ctx = ast_context->getTranslationUnitDecl();
2915        TypedefDecl *decl = TypedefDecl::Create(*ast_context,
2916                                                decl_ctx,
2917                                                SourceLocation(),
2918                                                name ? &identifier_table->get(name) : NULL, // Identifier
2919                                                ast_context->CreateTypeSourceInfo(qual_type));
2920
2921        // Get a uniqued QualType for the typedef decl type
2922        return ast_context->getTypedefType (decl).getAsOpaquePtr();
2923    }
2924    return NULL;
2925}
2926
2927
2928std::string
2929ClangASTContext::GetTypeName (void *opaque_qual_type)
2930{
2931    std::string return_name;
2932
2933    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_qual_type));
2934
2935    const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
2936    if (typedef_type)
2937    {
2938        const clang::TypedefDecl *typedef_decl = typedef_type->getDecl();
2939        return_name = typedef_decl->getQualifiedNameAsString();
2940    }
2941    else
2942    {
2943        return_name = qual_type.getAsString();
2944    }
2945
2946    return return_name;
2947}
2948
2949// Disable this for now since I can't seem to get a nicely formatted float
2950// out of the APFloat class without just getting the float, double or quad
2951// and then using a formatted print on it which defeats the purpose. We ideally
2952// would like to get perfect string values for any kind of float semantics
2953// so we can support remote targets. The code below also requires a patch to
2954// llvm::APInt.
2955//bool
2956//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, void *clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
2957//{
2958//  uint32_t count = 0;
2959//  bool is_complex = false;
2960//  if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
2961//  {
2962//      unsigned num_bytes_per_float = byte_size / count;
2963//      unsigned num_bits_per_float = num_bytes_per_float * 8;
2964//
2965//      float_str.clear();
2966//      uint32_t i;
2967//      for (i=0; i<count; i++)
2968//      {
2969//          APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
2970//          bool is_ieee = false;
2971//          APFloat ap_float(ap_int, is_ieee);
2972//          char s[1024];
2973//          unsigned int hex_digits = 0;
2974//          bool upper_case = false;
2975//
2976//          if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
2977//          {
2978//              if (i > 0)
2979//                  float_str.append(", ");
2980//              float_str.append(s);
2981//              if (i == 1 && is_complex)
2982//                  float_str.append(1, 'i');
2983//          }
2984//      }
2985//      return !float_str.empty();
2986//  }
2987//  return false;
2988//}
2989
2990size_t
2991ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, void *clang_type, const char *s, uint8_t *dst, size_t dst_size)
2992{
2993    if (clang_type)
2994    {
2995        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2996        uint32_t count = 0;
2997        bool is_complex = false;
2998        if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
2999        {
3000            // TODO: handle complex and vector types
3001            if (count != 1)
3002                return false;
3003
3004            StringRef s_sref(s);
3005            APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3006
3007            const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3008            const uint64_t byte_size = bit_size / 8;
3009            if (dst_size >= byte_size)
3010            {
3011                if (bit_size == sizeof(float)*8)
3012                {
3013                    float float32 = ap_float.convertToFloat();
3014                    ::memcpy (dst, &float32, byte_size);
3015                    return byte_size;
3016                }
3017                else if (bit_size >= 64)
3018                {
3019                    llvm::APInt ap_int(ap_float.bitcastToAPInt());
3020                    ::memcpy (dst, ap_int.getRawData(), byte_size);
3021                    return byte_size;
3022                }
3023            }
3024        }
3025    }
3026    return 0;
3027}
3028