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