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