ClangASTContext.cpp revision 567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983c
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
18// Clang headers like to use NDEBUG inside of them to enable/disable debug
19// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing
20// or another. This is bad because it means that if clang was built in release
21// mode, it assumes that you are building in release mode which is not always
22// the case. You can end up with functions that are defined as empty in header
23// files when NDEBUG is not defined, and this can cause link errors with the
24// clang .a files that you have since you might be missing functions in the .a
25// file. So we have to define NDEBUG when including clang headers to avoid any
26// mismatches. This is covered by rdar://problem/8691220
27
28#ifndef NDEBUG
29#define LLDB_DEFINED_NDEBUG_FOR_CLANG
30#define NDEBUG
31// Need to include assert.h so it is as clang would expect it to be (disabled)
32#include <assert.h>
33#endif
34
35#include "clang/AST/ASTContext.h"
36#include "clang/AST/ASTImporter.h"
37#include "clang/AST/CXXInheritance.h"
38#include "clang/AST/DeclObjC.h"
39#include "clang/AST/RecordLayout.h"
40#include "clang/AST/Type.h"
41#include "clang/Basic/Builtins.h"
42#include "clang/Basic/FileManager.h"
43#include "clang/Basic/FileSystemOptions.h"
44#include "clang/Basic/SourceManager.h"
45#include "clang/Basic/TargetInfo.h"
46#include "clang/Basic/TargetOptions.h"
47#include "clang/Frontend/FrontendOptions.h"
48#include "clang/Frontend/LangStandard.h"
49
50#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
51#undef NDEBUG
52#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
53// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
54#include <assert.h>
55#endif
56
57#include "lldb/Core/ArchSpec.h"
58#include "lldb/Core/dwarf.h"
59#include "lldb/Core/Flags.h"
60#include "lldb/Core/Log.h"
61#include "lldb/Target/ExecutionContext.h"
62#include "lldb/Target/Process.h"
63#include "lldb/Target/ObjCLanguageRuntime.h"
64
65
66#include <stdio.h>
67
68using namespace lldb;
69using namespace lldb_private;
70using namespace llvm;
71using namespace clang;
72
73
74static bool
75GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
76{
77    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
78    switch (type_class)
79    {
80    case clang::Type::Record:
81    case clang::Type::Enum:
82        {
83            const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
84            if (tag_type)
85            {
86                clang::TagDecl *tag_decl = tag_type->getDecl();
87                if (tag_decl)
88                {
89                    if (tag_decl->getDefinition())
90                        return true;
91
92                    if (tag_decl->hasExternalLexicalStorage())
93                    {
94                        if (ast)
95                        {
96                            ExternalASTSource *external_ast_source = ast->getExternalSource();
97                            if (external_ast_source)
98                            {
99                                external_ast_source->CompleteType(tag_decl);
100                                return !tag_type->isIncompleteType();
101                            }
102                        }
103                    }
104                    return false;
105                }
106            }
107
108        }
109        break;
110
111    case clang::Type::ObjCObject:
112    case clang::Type::ObjCInterface:
113        {
114            const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
115            if (objc_class_type)
116            {
117                clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
118                // We currently can't complete objective C types through the newly added ASTContext
119                // because it only supports TagDecl objects right now...
120                if (class_interface_decl)
121                {
122                    bool is_forward_decl = class_interface_decl->isForwardDecl();
123                    if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
124                    {
125                        if (ast)
126                        {
127                            ExternalASTSource *external_ast_source = ast->getExternalSource();
128                            if (external_ast_source)
129                            {
130                                external_ast_source->CompleteType (class_interface_decl);
131                                is_forward_decl = class_interface_decl->isForwardDecl();
132                            }
133                        }
134                        return is_forward_decl == false;
135                    }
136                    return true;
137                }
138                else
139                    return false;
140            }
141        }
142        break;
143
144    case clang::Type::Typedef:
145        return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType());
146
147    case clang::Type::Elaborated:
148        return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType());
149
150    default:
151        break;
152    }
153
154    return true;
155}
156
157
158static AccessSpecifier
159ConvertAccessTypeToAccessSpecifier (AccessType access)
160{
161    switch (access)
162    {
163    default:               break;
164    case eAccessNone:      return AS_none;
165    case eAccessPublic:    return AS_public;
166    case eAccessPrivate:   return AS_private;
167    case eAccessProtected: return AS_protected;
168    }
169    return AS_none;
170}
171
172static ObjCIvarDecl::AccessControl
173ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
174{
175    switch (access)
176    {
177    default:               break;
178    case eAccessNone:      return ObjCIvarDecl::None;
179    case eAccessPublic:    return ObjCIvarDecl::Public;
180    case eAccessPrivate:   return ObjCIvarDecl::Private;
181    case eAccessProtected: return ObjCIvarDecl::Protected;
182    case eAccessPackage:   return ObjCIvarDecl::Package;
183    }
184    return ObjCIvarDecl::None;
185}
186
187
188static void
189ParseLangArgs
190(
191    LangOptions &Opts,
192    InputKind IK
193)
194{
195    // FIXME: Cleanup per-file based stuff.
196
197    // Set some properties which depend soley on the input kind; it would be nice
198    // to move these to the language standard, and have the driver resolve the
199    // input kind + language standard.
200    if (IK == IK_Asm) {
201        Opts.AsmPreprocessor = 1;
202    } else if (IK == IK_ObjC ||
203               IK == IK_ObjCXX ||
204               IK == IK_PreprocessedObjC ||
205               IK == IK_PreprocessedObjCXX) {
206        Opts.ObjC1 = Opts.ObjC2 = 1;
207    }
208
209    LangStandard::Kind LangStd = LangStandard::lang_unspecified;
210
211    if (LangStd == LangStandard::lang_unspecified) {
212        // Based on the base language, pick one.
213        switch (IK) {
214            case IK_None:
215            case IK_AST:
216            case IK_LLVM_IR:
217                assert (!"Invalid input kind!");
218            case IK_OpenCL:
219                LangStd = LangStandard::lang_opencl;
220                break;
221            case IK_CUDA:
222                LangStd = LangStandard::lang_cuda;
223                break;
224            case IK_Asm:
225            case IK_C:
226            case IK_PreprocessedC:
227            case IK_ObjC:
228            case IK_PreprocessedObjC:
229                LangStd = LangStandard::lang_gnu99;
230                break;
231            case IK_CXX:
232            case IK_PreprocessedCXX:
233            case IK_ObjCXX:
234            case IK_PreprocessedObjCXX:
235                LangStd = LangStandard::lang_gnucxx98;
236                break;
237        }
238    }
239
240    const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
241    Opts.BCPLComment = Std.hasBCPLComments();
242    Opts.C99 = Std.isC99();
243    Opts.CPlusPlus = Std.isCPlusPlus();
244    Opts.CPlusPlus0x = Std.isCPlusPlus0x();
245    Opts.Digraphs = Std.hasDigraphs();
246    Opts.GNUMode = Std.isGNUMode();
247    Opts.GNUInline = !Std.isC99();
248    Opts.HexFloats = Std.hasHexFloats();
249    Opts.ImplicitInt = Std.hasImplicitInt();
250
251    // OpenCL has some additional defaults.
252    if (LangStd == LangStandard::lang_opencl) {
253        Opts.OpenCL = 1;
254        Opts.AltiVec = 1;
255        Opts.CXXOperatorNames = 1;
256        Opts.LaxVectorConversions = 1;
257    }
258
259    // OpenCL and C++ both have bool, true, false keywords.
260    Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
261
262//    if (Opts.CPlusPlus)
263//        Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
264//
265//    if (Args.hasArg(OPT_fobjc_gc_only))
266//        Opts.setGCMode(LangOptions::GCOnly);
267//    else if (Args.hasArg(OPT_fobjc_gc))
268//        Opts.setGCMode(LangOptions::HybridGC);
269//
270//    if (Args.hasArg(OPT_print_ivar_layout))
271//        Opts.ObjCGCBitmapPrint = 1;
272//
273//    if (Args.hasArg(OPT_faltivec))
274//        Opts.AltiVec = 1;
275//
276//    if (Args.hasArg(OPT_pthread))
277//        Opts.POSIXThreads = 1;
278//
279//    llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
280//                                          "default");
281//    if (Vis == "default")
282        Opts.setVisibilityMode(DefaultVisibility);
283//    else if (Vis == "hidden")
284//        Opts.setVisibilityMode(LangOptions::Hidden);
285//    else if (Vis == "protected")
286//        Opts.setVisibilityMode(LangOptions::Protected);
287//    else
288//        Diags.Report(diag::err_drv_invalid_value)
289//        << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
290
291//    Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
292
293    // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
294    // is specified, or -std is set to a conforming mode.
295    Opts.Trigraphs = !Opts.GNUMode;
296//    if (Args.hasArg(OPT_trigraphs))
297//        Opts.Trigraphs = 1;
298//
299//    Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
300//                                     OPT_fno_dollars_in_identifiers,
301//                                     !Opts.AsmPreprocessor);
302//    Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
303//    Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
304//    Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
305//    if (Args.hasArg(OPT_fno_lax_vector_conversions))
306//        Opts.LaxVectorConversions = 0;
307//    Opts.Exceptions = Args.hasArg(OPT_fexceptions);
308//    Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
309//    Opts.Blocks = Args.hasArg(OPT_fblocks);
310//    Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
311//    Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
312//    Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
313//    Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
314//    Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
315//    Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
316//    Opts.AccessControl = Args.hasArg(OPT_faccess_control);
317//    Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
318//    Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
319//    Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
320//                                                 Diags);
321//    Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
322//    Opts.ObjCConstantStringClass = getLastArgValue(Args,
323//                                                   OPT_fconstant_string_class);
324//    Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
325//    Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
326//    Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
327//    Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
328//    Opts.Static = Args.hasArg(OPT_static_define);
329    Opts.OptimizeSize = 0;
330
331    // FIXME: Eliminate this dependency.
332//    unsigned Opt =
333//    Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
334//    Opts.Optimize = Opt != 0;
335    unsigned Opt = 0;
336
337    // This is the __NO_INLINE__ define, which just depends on things like the
338    // optimization level and -fno-inline, not actually whether the backend has
339    // inlining enabled.
340    //
341    // FIXME: This is affected by other options (-fno-inline).
342    Opts.NoInline = !Opt;
343
344//    unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
345//    switch (SSP) {
346//        default:
347//            Diags.Report(diag::err_drv_invalid_value)
348//            << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
349//            break;
350//        case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
351//        case 1: Opts.setStackProtectorMode(LangOptions::SSPOn);  break;
352//        case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
353//    }
354}
355
356
357ClangASTContext::ClangASTContext (const char *target_triple) :
358    m_target_triple(),
359    m_ast_ap(),
360    m_language_options_ap(),
361    m_source_manager_ap(),
362    m_diagnostic_ap(),
363    m_target_options_ap(),
364    m_target_info_ap(),
365    m_identifier_table_ap(),
366    m_selector_table_ap(),
367    m_builtins_ap(),
368    m_callback_tag_decl (NULL),
369    m_callback_objc_decl (NULL),
370    m_callback_baton (NULL)
371
372{
373    if (target_triple && target_triple[0])
374        SetTargetTriple (target_triple);
375}
376
377//----------------------------------------------------------------------
378// Destructor
379//----------------------------------------------------------------------
380ClangASTContext::~ClangASTContext()
381{
382    m_builtins_ap.reset();
383    m_selector_table_ap.reset();
384    m_identifier_table_ap.reset();
385    m_target_info_ap.reset();
386    m_target_options_ap.reset();
387    m_diagnostic_ap.reset();
388    m_source_manager_ap.reset();
389    m_language_options_ap.reset();
390    m_ast_ap.reset();
391}
392
393
394void
395ClangASTContext::Clear()
396{
397    m_ast_ap.reset();
398    m_language_options_ap.reset();
399    m_source_manager_ap.reset();
400    m_diagnostic_ap.reset();
401    m_target_options_ap.reset();
402    m_target_info_ap.reset();
403    m_identifier_table_ap.reset();
404    m_selector_table_ap.reset();
405    m_builtins_ap.reset();
406}
407
408const char *
409ClangASTContext::GetTargetTriple ()
410{
411    return m_target_triple.c_str();
412}
413
414void
415ClangASTContext::SetTargetTriple (const char *target_triple)
416{
417    Clear();
418    m_target_triple.assign(target_triple);
419}
420
421void
422ClangASTContext::SetArchitecture (const ArchSpec &arch)
423{
424    SetTargetTriple(arch.GetTriple().str().c_str());
425}
426
427bool
428ClangASTContext::HasExternalSource ()
429{
430    ASTContext *ast = getASTContext();
431    if (ast)
432        return ast->getExternalSource () != NULL;
433    return false;
434}
435
436void
437ClangASTContext::SetExternalSource (llvm::OwningPtr<ExternalASTSource> &ast_source_ap)
438{
439    ASTContext *ast = getASTContext();
440    if (ast)
441    {
442        ast->setExternalSource (ast_source_ap);
443        ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
444        //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
445    }
446}
447
448void
449ClangASTContext::RemoveExternalSource ()
450{
451    ASTContext *ast = getASTContext();
452
453    if (ast)
454    {
455        llvm::OwningPtr<ExternalASTSource> empty_ast_source_ap;
456        ast->setExternalSource (empty_ast_source_ap);
457        ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
458        //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
459    }
460}
461
462
463
464ASTContext *
465ClangASTContext::getASTContext()
466{
467    if (m_ast_ap.get() == NULL)
468    {
469        m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
470                                       *getSourceManager(),
471                                       *getTargetInfo(),
472                                       *getIdentifierTable(),
473                                       *getSelectorTable(),
474                                       *getBuiltinContext(),
475                                       0));
476
477        if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton)
478        {
479            m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
480            //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
481        }
482
483        m_ast_ap->getDiagnostics().setClient(getDiagnosticClient(), false);
484    }
485    return m_ast_ap.get();
486}
487
488Builtin::Context *
489ClangASTContext::getBuiltinContext()
490{
491    if (m_builtins_ap.get() == NULL)
492        m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
493    return m_builtins_ap.get();
494}
495
496IdentifierTable *
497ClangASTContext::getIdentifierTable()
498{
499    if (m_identifier_table_ap.get() == NULL)
500        m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
501    return m_identifier_table_ap.get();
502}
503
504LangOptions *
505ClangASTContext::getLanguageOptions()
506{
507    if (m_language_options_ap.get() == NULL)
508    {
509        m_language_options_ap.reset(new LangOptions());
510        ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
511//        InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
512    }
513    return m_language_options_ap.get();
514}
515
516SelectorTable *
517ClangASTContext::getSelectorTable()
518{
519    if (m_selector_table_ap.get() == NULL)
520        m_selector_table_ap.reset (new SelectorTable());
521    return m_selector_table_ap.get();
522}
523
524clang::FileManager *
525ClangASTContext::getFileManager()
526{
527    if (m_file_manager_ap.get() == NULL)
528    {
529        clang::FileSystemOptions file_system_options;
530        m_file_manager_ap.reset(new clang::FileManager(file_system_options));
531    }
532    return m_file_manager_ap.get();
533}
534
535clang::SourceManager *
536ClangASTContext::getSourceManager()
537{
538    if (m_source_manager_ap.get() == NULL)
539        m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
540    return m_source_manager_ap.get();
541}
542
543Diagnostic *
544ClangASTContext::getDiagnostic()
545{
546    if (m_diagnostic_ap.get() == NULL)
547    {
548        llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
549        m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
550    }
551    return m_diagnostic_ap.get();
552}
553
554class NullDiagnosticClient : public DiagnosticClient
555{
556public:
557    NullDiagnosticClient ()
558    {
559        m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
560    }
561
562    void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
563    {
564        if (m_log)
565        {
566            llvm::SmallVectorImpl<char> diag_str(10);
567            info.FormatDiagnostic(diag_str);
568            diag_str.push_back('\0');
569            m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
570        }
571    }
572private:
573    LogSP m_log;
574};
575
576DiagnosticClient *
577ClangASTContext::getDiagnosticClient()
578{
579    if (m_diagnostic_client_ap.get() == NULL)
580        m_diagnostic_client_ap.reset(new NullDiagnosticClient);
581
582    return m_diagnostic_client_ap.get();
583}
584
585TargetOptions *
586ClangASTContext::getTargetOptions()
587{
588    if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
589    {
590        m_target_options_ap.reset (new TargetOptions());
591        if (m_target_options_ap.get())
592            m_target_options_ap->Triple = m_target_triple;
593    }
594    return m_target_options_ap.get();
595}
596
597
598TargetInfo *
599ClangASTContext::getTargetInfo()
600{
601    // target_triple should be something like "x86_64-apple-darwin10"
602    if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
603        m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
604    return m_target_info_ap.get();
605}
606
607#pragma mark Basic Types
608
609static inline bool
610QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
611{
612    uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
613    if (qual_type_bit_size == bit_size)
614        return true;
615    return false;
616}
617
618clang_type_t
619ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
620{
621    ASTContext *ast = getASTContext();
622
623    assert (ast != NULL);
624
625    return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
626}
627
628clang_type_t
629ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
630{
631    if (!ast)
632        return NULL;
633
634    switch (encoding)
635    {
636    case eEncodingInvalid:
637        if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
638            return ast->VoidPtrTy.getAsOpaquePtr();
639        break;
640
641    case eEncodingUint:
642        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
643            return ast->UnsignedCharTy.getAsOpaquePtr();
644        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
645            return ast->UnsignedShortTy.getAsOpaquePtr();
646        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
647            return ast->UnsignedIntTy.getAsOpaquePtr();
648        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
649            return ast->UnsignedLongTy.getAsOpaquePtr();
650        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
651            return ast->UnsignedLongLongTy.getAsOpaquePtr();
652        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
653            return ast->UnsignedInt128Ty.getAsOpaquePtr();
654        break;
655
656    case eEncodingSint:
657        if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
658            return ast->CharTy.getAsOpaquePtr();
659        if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
660            return ast->ShortTy.getAsOpaquePtr();
661        if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
662            return ast->IntTy.getAsOpaquePtr();
663        if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
664            return ast->LongTy.getAsOpaquePtr();
665        if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
666            return ast->LongLongTy.getAsOpaquePtr();
667        if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
668            return ast->Int128Ty.getAsOpaquePtr();
669        break;
670
671    case eEncodingIEEE754:
672        if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
673            return ast->FloatTy.getAsOpaquePtr();
674        if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
675            return ast->DoubleTy.getAsOpaquePtr();
676        if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
677            return ast->LongDoubleTy.getAsOpaquePtr();
678        break;
679
680    case eEncodingVector:
681    default:
682        break;
683    }
684
685    return NULL;
686}
687
688clang_type_t
689ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
690{
691    ASTContext *ast = getASTContext();
692
693    #define streq(a,b) strcmp(a,b) == 0
694    assert (ast != NULL);
695    if (ast)
696    {
697        switch (dw_ate)
698        {
699        default:
700            break;
701
702        case DW_ATE_address:
703            if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
704                return ast->VoidPtrTy.getAsOpaquePtr();
705            break;
706
707        case DW_ATE_boolean:
708            if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
709                return ast->BoolTy.getAsOpaquePtr();
710            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
711                return ast->UnsignedCharTy.getAsOpaquePtr();
712            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
713                return ast->UnsignedShortTy.getAsOpaquePtr();
714            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
715                return ast->UnsignedIntTy.getAsOpaquePtr();
716            break;
717
718        case DW_ATE_lo_user:
719            // This has been seen to mean DW_AT_complex_integer
720            if (::strstr(type_name, "complex"))
721            {
722                clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
723                return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
724            }
725            break;
726
727        case DW_ATE_complex_float:
728            if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
729                return ast->FloatComplexTy.getAsOpaquePtr();
730            else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
731                return ast->DoubleComplexTy.getAsOpaquePtr();
732            else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
733                return ast->LongDoubleComplexTy.getAsOpaquePtr();
734            else
735            {
736                clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
737                return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
738            }
739            break;
740
741        case DW_ATE_float:
742            if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
743                return ast->FloatTy.getAsOpaquePtr();
744            if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
745                return ast->DoubleTy.getAsOpaquePtr();
746            if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
747                return ast->LongDoubleTy.getAsOpaquePtr();
748            break;
749
750        case DW_ATE_signed:
751            if (type_name)
752            {
753                if (strstr(type_name, "long long"))
754                {
755                    if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
756                        return ast->LongLongTy.getAsOpaquePtr();
757                }
758                else if (strstr(type_name, "long"))
759                {
760                    if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
761                        return ast->LongTy.getAsOpaquePtr();
762                }
763                else if (strstr(type_name, "short"))
764                {
765                    if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
766                        return ast->ShortTy.getAsOpaquePtr();
767                }
768                else if (strstr(type_name, "char"))
769                {
770                    if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
771                        return ast->CharTy.getAsOpaquePtr();
772                    if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
773                        return ast->SignedCharTy.getAsOpaquePtr();
774                }
775                else if (strstr(type_name, "int"))
776                {
777                    if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
778                        return ast->IntTy.getAsOpaquePtr();
779                    if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
780                        return ast->Int128Ty.getAsOpaquePtr();
781                }
782                else if (streq(type_name, "wchar_t"))
783                {
784                    if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
785                        return ast->WCharTy.getAsOpaquePtr();
786                }
787                else if (streq(type_name, "void"))
788                {
789                    if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
790                        return ast->VoidTy.getAsOpaquePtr();
791                }
792            }
793            // We weren't able to match up a type name, just search by size
794            if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
795                return ast->CharTy.getAsOpaquePtr();
796            if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
797                return ast->ShortTy.getAsOpaquePtr();
798            if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
799                return ast->IntTy.getAsOpaquePtr();
800            if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
801                return ast->LongTy.getAsOpaquePtr();
802            if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
803                return ast->LongLongTy.getAsOpaquePtr();
804            if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
805                return ast->Int128Ty.getAsOpaquePtr();
806            break;
807
808        case DW_ATE_signed_char:
809            if (type_name)
810            {
811                if (streq(type_name, "signed char"))
812                {
813                    if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
814                        return ast->SignedCharTy.getAsOpaquePtr();
815                }
816            }
817            if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
818                return ast->CharTy.getAsOpaquePtr();
819            if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
820                return ast->SignedCharTy.getAsOpaquePtr();
821            break;
822
823        case DW_ATE_unsigned:
824            if (type_name)
825            {
826                if (strstr(type_name, "long long"))
827                {
828                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
829                        return ast->UnsignedLongLongTy.getAsOpaquePtr();
830                }
831                else if (strstr(type_name, "long"))
832                {
833                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
834                        return ast->UnsignedLongTy.getAsOpaquePtr();
835                }
836                else if (strstr(type_name, "short"))
837                {
838                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
839                        return ast->UnsignedShortTy.getAsOpaquePtr();
840                }
841                else if (strstr(type_name, "char"))
842                {
843                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
844                        return ast->UnsignedCharTy.getAsOpaquePtr();
845                }
846                else if (strstr(type_name, "int"))
847                {
848                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
849                        return ast->UnsignedIntTy.getAsOpaquePtr();
850                    if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
851                        return ast->UnsignedInt128Ty.getAsOpaquePtr();
852                }
853            }
854            // We weren't able to match up a type name, just search by size
855            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
856                return ast->UnsignedCharTy.getAsOpaquePtr();
857            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
858                return ast->UnsignedShortTy.getAsOpaquePtr();
859            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
860                return ast->UnsignedIntTy.getAsOpaquePtr();
861            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
862                return ast->UnsignedLongTy.getAsOpaquePtr();
863            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
864                return ast->UnsignedLongLongTy.getAsOpaquePtr();
865            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
866                return ast->UnsignedInt128Ty.getAsOpaquePtr();
867            break;
868
869        case DW_ATE_unsigned_char:
870            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
871                return ast->UnsignedCharTy.getAsOpaquePtr();
872            if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
873                return ast->UnsignedShortTy.getAsOpaquePtr();
874            break;
875
876        case DW_ATE_imaginary_float:
877            break;
878        }
879    }
880    // This assert should fire for anything that we don't catch above so we know
881    // to fix any issues we run into.
882    if (type_name)
883    {
884        fprintf (stderr, "error: need to add support for DW_TAG_base_type '%s' encoded with DW_ATE = 0x%x, bit_size = %u\n", type_name, dw_ate, bit_size);
885    }
886    else
887    {
888        fprintf (stderr, "error: need to add support for DW_TAG_base_type encoded with DW_ATE = 0x%x, bit_size = %u\n", dw_ate, bit_size);
889    }
890    return NULL;
891}
892
893clang_type_t
894ClangASTContext::GetBuiltInType_void(ASTContext *ast)
895{
896    return ast->VoidTy.getAsOpaquePtr();
897}
898
899clang_type_t
900ClangASTContext::GetBuiltInType_bool()
901{
902    return getASTContext()->BoolTy.getAsOpaquePtr();
903}
904
905clang_type_t
906ClangASTContext::GetBuiltInType_objc_id()
907{
908    return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
909}
910
911clang_type_t
912ClangASTContext::GetBuiltInType_objc_Class()
913{
914    return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
915}
916
917clang_type_t
918ClangASTContext::GetBuiltInType_objc_selector()
919{
920    return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
921}
922
923clang_type_t
924ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
925{
926    return ast->UnknownAnyTy.getAsOpaquePtr();
927}
928
929clang_type_t
930ClangASTContext::GetCStringType (bool is_const)
931{
932    QualType char_type(getASTContext()->CharTy);
933
934    if (is_const)
935        char_type.addConst();
936
937    return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
938}
939
940clang_type_t
941ClangASTContext::GetVoidPtrType (bool is_const)
942{
943    return GetVoidPtrType(getASTContext(), is_const);
944}
945
946clang_type_t
947ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
948{
949    QualType void_ptr_type(ast->VoidPtrTy);
950
951    if (is_const)
952        void_ptr_type.addConst();
953
954    return void_ptr_type.getAsOpaquePtr();
955}
956
957clang_type_t
958ClangASTContext::CopyType (ASTContext *dst_ast,
959                           ASTContext *src_ast,
960                           clang_type_t clang_type)
961{
962    FileSystemOptions file_system_options;
963    FileManager file_manager (file_system_options);
964    ASTImporter importer(*dst_ast, file_manager,
965                         *src_ast, file_manager,
966                         false);
967
968    QualType src (QualType::getFromOpaquePtr(clang_type));
969    QualType dst (importer.Import(src));
970
971    return dst.getAsOpaquePtr();
972}
973
974
975clang::Decl *
976ClangASTContext::CopyDecl (ASTContext *dst_ast,
977                           ASTContext *src_ast,
978                           clang::Decl *source_decl)
979{
980    FileSystemOptions file_system_options;
981    FileManager file_manager (file_system_options);
982    ASTImporter importer(*dst_ast, file_manager,
983                         *src_ast, file_manager,
984                         false);
985
986    return importer.Import(source_decl);
987}
988
989bool
990ClangASTContext::AreTypesSame(ASTContext *ast,
991             clang_type_t type1,
992             clang_type_t type2)
993{
994    return ast->hasSameType (QualType::getFromOpaquePtr(type1),
995                             QualType::getFromOpaquePtr(type2));
996}
997
998#pragma mark CVR modifiers
999
1000clang_type_t
1001ClangASTContext::AddConstModifier (clang_type_t clang_type)
1002{
1003    if (clang_type)
1004    {
1005        QualType result(QualType::getFromOpaquePtr(clang_type));
1006        result.addConst();
1007        return result.getAsOpaquePtr();
1008    }
1009    return NULL;
1010}
1011
1012clang_type_t
1013ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
1014{
1015    if (clang_type)
1016    {
1017        QualType result(QualType::getFromOpaquePtr(clang_type));
1018        result.getQualifiers().setRestrict (true);
1019        return result.getAsOpaquePtr();
1020    }
1021    return NULL;
1022}
1023
1024clang_type_t
1025ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
1026{
1027    if (clang_type)
1028    {
1029        QualType result(QualType::getFromOpaquePtr(clang_type));
1030        result.getQualifiers().setVolatile (true);
1031        return result.getAsOpaquePtr();
1032    }
1033    return NULL;
1034}
1035
1036
1037clang_type_t
1038ClangASTContext::GetTypeForDecl (TagDecl *decl)
1039{
1040    // No need to call the getASTContext() accessor (which can create the AST
1041    // if it isn't created yet, because we can't have created a decl in this
1042    // AST if our AST didn't already exist...
1043    if (m_ast_ap.get())
1044        return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
1045    return NULL;
1046}
1047
1048clang_type_t
1049ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
1050{
1051    // No need to call the getASTContext() accessor (which can create the AST
1052    // if it isn't created yet, because we can't have created a decl in this
1053    // AST if our AST didn't already exist...
1054    if (m_ast_ap.get())
1055        return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
1056    return NULL;
1057}
1058
1059#pragma mark Structure, Unions, Classes
1060
1061clang_type_t
1062ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
1063{
1064    ASTContext *ast = getASTContext();
1065    assert (ast != NULL);
1066
1067    if (decl_ctx == NULL)
1068        decl_ctx = ast->getTranslationUnitDecl();
1069
1070
1071    if (language == eLanguageTypeObjC || language == eLanguageTypeObjC_plus_plus)
1072    {
1073        bool isForwardDecl = true;
1074        bool isInternal = false;
1075        return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
1076    }
1077
1078    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1079    // we will need to update this code. I was told to currently always use
1080    // the CXXRecordDecl class since we often don't know from debug information
1081    // if something is struct or a class, so we default to always use the more
1082    // complete definition just in case.
1083    CXXRecordDecl *decl = CXXRecordDecl::Create(*ast,
1084                                                (TagDecl::TagKind)kind,
1085                                                decl_ctx,
1086                                                SourceLocation(),
1087                                                SourceLocation(),
1088                                                name && name[0] ? &ast->Idents.get(name) : NULL);
1089
1090    return ast->getTagDeclType(decl).getAsOpaquePtr();
1091}
1092
1093bool
1094ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
1095{
1096    if (clang_type == NULL)
1097        return false;
1098
1099    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1100
1101    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1102    switch (type_class)
1103    {
1104    case clang::Type::Record:
1105        {
1106            CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
1107            if (cxx_record_decl)
1108            {
1109                cxx_record_decl->setHasExternalLexicalStorage (has_extern);
1110                cxx_record_decl->setHasExternalVisibleStorage (has_extern);
1111                return true;
1112            }
1113        }
1114        break;
1115
1116    case clang::Type::Enum:
1117        {
1118            EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
1119            if (enum_decl)
1120            {
1121                enum_decl->setHasExternalLexicalStorage (has_extern);
1122                enum_decl->setHasExternalVisibleStorage (has_extern);
1123                return true;
1124            }
1125        }
1126        break;
1127
1128    case clang::Type::ObjCObject:
1129    case clang::Type::ObjCInterface:
1130        {
1131            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1132            assert (objc_class_type);
1133            if (objc_class_type)
1134            {
1135                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1136
1137                if (class_interface_decl)
1138                {
1139                    class_interface_decl->setHasExternalLexicalStorage (has_extern);
1140                    class_interface_decl->setHasExternalVisibleStorage (has_extern);
1141                    return true;
1142                }
1143            }
1144        }
1145        break;
1146
1147    case clang::Type::Typedef:
1148        return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
1149
1150    case clang::Type::Elaborated:
1151        return ClangASTContext::SetHasExternalStorage (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), has_extern);
1152
1153    default:
1154        break;
1155    }
1156    return false;
1157}
1158
1159static bool
1160IsOperator (const char *name, OverloadedOperatorKind &op_kind)
1161{
1162    if (name == NULL || name[0] == '\0')
1163        return false;
1164
1165#define OPERATOR_PREFIX "operator"
1166#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
1167
1168    const char *post_op_name = NULL;
1169
1170    bool no_space = true;
1171
1172    if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
1173        return false;
1174
1175    post_op_name = name + OPERATOR_PREFIX_LENGTH;
1176
1177    if (post_op_name[0] == ' ')
1178    {
1179        post_op_name++;
1180        no_space = false;
1181    }
1182
1183#undef OPERATOR_PREFIX
1184#undef OPERATOR_PREFIX_LENGTH
1185
1186    // This is an operator, set the overloaded operator kind to invalid
1187    // in case this is a conversion operator...
1188    op_kind = NUM_OVERLOADED_OPERATORS;
1189
1190    switch (post_op_name[0])
1191    {
1192    default:
1193        if (no_space)
1194            return false;
1195        break;
1196    case 'n':
1197        if (no_space)
1198            return false;
1199        if  (strcmp (post_op_name, "new") == 0)
1200            op_kind = OO_New;
1201        else if (strcmp (post_op_name, "new[]") == 0)
1202            op_kind = OO_Array_New;
1203        break;
1204
1205    case 'd':
1206        if (no_space)
1207            return false;
1208        if (strcmp (post_op_name, "delete") == 0)
1209            op_kind = OO_Delete;
1210        else if (strcmp (post_op_name, "delete[]") == 0)
1211            op_kind = OO_Array_Delete;
1212        break;
1213
1214    case '+':
1215        if (post_op_name[1] == '\0')
1216            op_kind = OO_Plus;
1217        else if (post_op_name[2] == '\0')
1218        {
1219            if (post_op_name[1] == '=')
1220                op_kind = OO_PlusEqual;
1221            else if (post_op_name[1] == '+')
1222                op_kind = OO_PlusPlus;
1223        }
1224        break;
1225
1226    case '-':
1227        if (post_op_name[1] == '\0')
1228            op_kind = OO_Minus;
1229        else if (post_op_name[2] == '\0')
1230        {
1231            switch (post_op_name[1])
1232            {
1233            case '=': op_kind = OO_MinusEqual; break;
1234            case '-': op_kind = OO_MinusMinus; break;
1235            case '>': op_kind = OO_Arrow; break;
1236            }
1237        }
1238        else if (post_op_name[3] == '\0')
1239        {
1240            if (post_op_name[2] == '*')
1241                op_kind = OO_ArrowStar; break;
1242        }
1243        break;
1244
1245    case '*':
1246        if (post_op_name[1] == '\0')
1247            op_kind = OO_Star;
1248        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1249            op_kind = OO_StarEqual;
1250        break;
1251
1252    case '/':
1253        if (post_op_name[1] == '\0')
1254            op_kind = OO_Slash;
1255        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1256            op_kind = OO_SlashEqual;
1257        break;
1258
1259    case '%':
1260        if (post_op_name[1] == '\0')
1261            op_kind = OO_Percent;
1262        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1263            op_kind = OO_PercentEqual;
1264        break;
1265
1266
1267    case '^':
1268        if (post_op_name[1] == '\0')
1269            op_kind = OO_Caret;
1270        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1271            op_kind = OO_CaretEqual;
1272        break;
1273
1274    case '&':
1275        if (post_op_name[1] == '\0')
1276            op_kind = OO_Amp;
1277        else if (post_op_name[2] == '\0')
1278        {
1279            switch (post_op_name[1])
1280            {
1281            case '=': op_kind = OO_AmpEqual; break;
1282            case '&': op_kind = OO_AmpAmp; break;
1283            }
1284        }
1285        break;
1286
1287    case '|':
1288        if (post_op_name[1] == '\0')
1289            op_kind = OO_Pipe;
1290        else if (post_op_name[2] == '\0')
1291        {
1292            switch (post_op_name[1])
1293            {
1294            case '=': op_kind = OO_PipeEqual; break;
1295            case '|': op_kind = OO_PipePipe; break;
1296            }
1297        }
1298        break;
1299
1300    case '~':
1301        if (post_op_name[1] == '\0')
1302            op_kind = OO_Tilde;
1303        break;
1304
1305    case '!':
1306        if (post_op_name[1] == '\0')
1307            op_kind = OO_Exclaim;
1308        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1309            op_kind = OO_ExclaimEqual;
1310        break;
1311
1312    case '=':
1313        if (post_op_name[1] == '\0')
1314            op_kind = OO_Equal;
1315        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1316            op_kind = OO_EqualEqual;
1317        break;
1318
1319    case '<':
1320        if (post_op_name[1] == '\0')
1321            op_kind = OO_Less;
1322        else if (post_op_name[2] == '\0')
1323        {
1324            switch (post_op_name[1])
1325            {
1326            case '<': op_kind = OO_LessLess; break;
1327            case '=': op_kind = OO_LessEqual; break;
1328            }
1329        }
1330        else if (post_op_name[3] == '\0')
1331        {
1332            if (post_op_name[2] == '=')
1333                op_kind = OO_LessLessEqual;
1334        }
1335        break;
1336
1337    case '>':
1338        if (post_op_name[1] == '\0')
1339            op_kind = OO_Greater;
1340        else if (post_op_name[2] == '\0')
1341        {
1342            switch (post_op_name[1])
1343            {
1344            case '>': op_kind = OO_GreaterGreater; break;
1345            case '=': op_kind = OO_GreaterEqual; break;
1346            }
1347        }
1348        else if (post_op_name[1] == '>' &&
1349                 post_op_name[2] == '=' &&
1350                 post_op_name[3] == '\0')
1351        {
1352                op_kind = OO_GreaterGreaterEqual;
1353        }
1354        break;
1355
1356    case ',':
1357        if (post_op_name[1] == '\0')
1358            op_kind = OO_Comma;
1359        break;
1360
1361    case '(':
1362        if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1363            op_kind = OO_Call;
1364        break;
1365
1366    case '[':
1367        if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1368            op_kind = OO_Subscript;
1369        break;
1370    }
1371
1372    return true;
1373}
1374
1375static inline bool
1376check_op_param (bool unary, bool binary, uint32_t num_params)
1377{
1378    // The parameter count doens't include "this"
1379    if (num_params == 0)
1380        return unary;
1381    if (num_params == 1)
1382        return binary;
1383    return false;
1384}
1385
1386bool
1387ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, uint32_t num_params)
1388{
1389#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) case OO_##Name: return check_op_param (Unary, Binary, num_params);
1390    switch (op_kind)
1391    {
1392#include "clang/Basic/OperatorKinds.def"
1393        default: break;
1394    }
1395    return false;
1396}
1397
1398CXXMethodDecl *
1399ClangASTContext::AddMethodToCXXRecordType
1400(
1401    ASTContext *ast,
1402    clang_type_t record_opaque_type,
1403    const char *name,
1404    clang_type_t method_opaque_type,
1405    lldb::AccessType access,
1406    bool is_virtual,
1407    bool is_static,
1408    bool is_inline,
1409    bool is_explicit
1410)
1411{
1412    if (!record_opaque_type || !method_opaque_type || !name)
1413        return NULL;
1414
1415    assert(ast);
1416
1417    IdentifierTable *identifier_table = &ast->Idents;
1418
1419    assert(identifier_table);
1420
1421    QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
1422
1423    CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
1424
1425    if (cxx_record_decl == NULL)
1426        return NULL;
1427
1428    QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1429
1430    CXXMethodDecl *cxx_method_decl = NULL;
1431
1432    DeclarationName decl_name (&identifier_table->get(name));
1433
1434    const bool is_implicitly_declared = false;
1435
1436    const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
1437
1438    if (function_Type == NULL)
1439        return NULL;
1440
1441    const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
1442
1443    if (!method_function_prototype)
1444        return NULL;
1445
1446    unsigned int num_params = method_function_prototype->getNumArgs();
1447
1448    if (name[0] == '~')
1449    {
1450        cxx_method_decl = CXXDestructorDecl::Create (*ast,
1451                                                     cxx_record_decl,
1452                                                     SourceLocation(),
1453                                                     DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
1454                                                     method_qual_type,
1455                                                     NULL,
1456                                                     is_inline,
1457                                                     is_implicitly_declared);
1458    }
1459    else if (decl_name == cxx_record_decl->getDeclName())
1460    {
1461        cxx_method_decl = CXXConstructorDecl::Create (*ast,
1462                                                      cxx_record_decl,
1463                                                      SourceLocation(),
1464                                                      DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
1465                                                      method_qual_type,
1466                                                      NULL, // TypeSourceInfo *
1467                                                      is_explicit,
1468                                                      is_inline,
1469                                                      is_implicitly_declared);
1470    }
1471    else
1472    {
1473
1474        OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1475        if (IsOperator (name, op_kind))
1476        {
1477            if (op_kind != NUM_OVERLOADED_OPERATORS)
1478            {
1479                // Check the number of operator parameters. Sometimes we have
1480                // seen bad DWARF that doesn't correctly describe operators and
1481                // if we try to create a methed and add it to the class, clang
1482                // will assert and crash, so we need to make sure things are
1483                // acceptable.
1484                if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
1485                    return NULL;
1486                cxx_method_decl = CXXMethodDecl::Create (*ast,
1487                                                         cxx_record_decl,
1488                                                         SourceLocation(),
1489                                                         DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
1490                                                         method_qual_type,
1491                                                         NULL, // TypeSourceInfo *
1492                                                         is_static,
1493                                                         SC_None,
1494                                                         is_inline,
1495                                                         SourceLocation());
1496            }
1497            else if (num_params == 0)
1498            {
1499                // Conversion operators don't take params...
1500                cxx_method_decl = CXXConversionDecl::Create (*ast,
1501                                                             cxx_record_decl,
1502                                                             SourceLocation(),
1503                                                             DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
1504                                                             method_qual_type,
1505                                                             NULL, // TypeSourceInfo *
1506                                                             is_inline,
1507                                                             is_explicit,
1508                                                             SourceLocation());
1509            }
1510        }
1511
1512        if (cxx_method_decl == NULL)
1513        {
1514            cxx_method_decl = CXXMethodDecl::Create (*ast,
1515                                                     cxx_record_decl,
1516                                                     SourceLocation(),
1517                                                     DeclarationNameInfo (decl_name, SourceLocation()),
1518                                                     method_qual_type,
1519                                                     NULL, // TypeSourceInfo *
1520                                                     is_static,
1521                                                     SC_None,
1522                                                     is_inline,
1523                                                     SourceLocation());
1524        }
1525    }
1526
1527    AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
1528
1529    cxx_method_decl->setAccess (access_specifier);
1530    cxx_method_decl->setVirtualAsWritten (is_virtual);
1531
1532    // Populate the method decl with parameter decls
1533
1534    llvm::SmallVector<ParmVarDecl *, 12> params;
1535
1536    for (int param_index = 0;
1537         param_index < num_params;
1538         ++param_index)
1539    {
1540        params.push_back (ParmVarDecl::Create (*ast,
1541                                               cxx_method_decl,
1542                                               SourceLocation(),
1543                                               SourceLocation(),
1544                                               NULL, // anonymous
1545                                               method_function_prototype->getArgType(param_index),
1546                                               NULL,
1547                                               SC_None,
1548                                               SC_None,
1549                                               NULL));
1550    }
1551
1552    cxx_method_decl->setParams (params.data(), num_params);
1553
1554    cxx_record_decl->addDecl (cxx_method_decl);
1555
1556//    printf ("decl->isPolymorphic()             = %i\n", cxx_record_decl->isPolymorphic());
1557//    printf ("decl->isAggregate()               = %i\n", cxx_record_decl->isAggregate());
1558//    printf ("decl->isPOD()                     = %i\n", cxx_record_decl->isPOD());
1559//    printf ("decl->isEmpty()                   = %i\n", cxx_record_decl->isEmpty());
1560//    printf ("decl->isAbstract()                = %i\n", cxx_record_decl->isAbstract());
1561//    printf ("decl->hasTrivialConstructor()     = %i\n", cxx_record_decl->hasTrivialConstructor());
1562//    printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
1563//    printf ("decl->hasTrivialCopyAssignment()  = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
1564//    printf ("decl->hasTrivialDestructor()      = %i\n", cxx_record_decl->hasTrivialDestructor());
1565    return cxx_method_decl;
1566}
1567
1568bool
1569ClangASTContext::AddFieldToRecordType
1570(
1571    ASTContext *ast,
1572    clang_type_t record_clang_type,
1573    const char *name,
1574    clang_type_t field_type,
1575    AccessType access,
1576    uint32_t bitfield_bit_size
1577)
1578{
1579    if (record_clang_type == NULL || field_type == NULL)
1580        return false;
1581
1582    IdentifierTable *identifier_table = &ast->Idents;
1583
1584    assert (ast != NULL);
1585    assert (identifier_table != NULL);
1586
1587    QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1588
1589    const clang::Type *clang_type = record_qual_type.getTypePtr();
1590    if (clang_type)
1591    {
1592        const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1593
1594        if (record_type)
1595        {
1596            RecordDecl *record_decl = record_type->getDecl();
1597
1598            clang::Expr *bit_width = NULL;
1599            if (bitfield_bit_size != 0)
1600            {
1601                APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1602                bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
1603            }
1604            FieldDecl *field = FieldDecl::Create (*ast,
1605                                                  record_decl,
1606                                                  SourceLocation(),
1607                                                  SourceLocation(),
1608                                                  name ? &identifier_table->get(name) : NULL, // Identifier
1609                                                  QualType::getFromOpaquePtr(field_type), // Field type
1610                                                  NULL,       // TInfo *
1611                                                  bit_width,  // BitWidth
1612                                                  false,      // Mutable
1613                                                  false);     // HasInit
1614
1615            field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
1616
1617            if (field)
1618            {
1619                record_decl->addDecl(field);
1620            }
1621        }
1622        else
1623        {
1624            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1625            if (objc_class_type)
1626            {
1627                bool is_synthesized = false;
1628                ClangASTContext::AddObjCClassIVar (ast,
1629                                                   record_clang_type,
1630                                                   name,
1631                                                   field_type,
1632                                                   access,
1633                                                   bitfield_bit_size,
1634                                                   is_synthesized);
1635            }
1636        }
1637    }
1638    return false;
1639}
1640
1641bool
1642ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1643{
1644    return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1645}
1646
1647bool
1648ClangASTContext::FieldIsBitfield
1649(
1650    ASTContext *ast,
1651    FieldDecl* field,
1652    uint32_t& bitfield_bit_size
1653)
1654{
1655    if (ast == NULL || field == NULL)
1656        return false;
1657
1658    if (field->isBitField())
1659    {
1660        Expr* bit_width_expr = field->getBitWidth();
1661        if (bit_width_expr)
1662        {
1663            llvm::APSInt bit_width_apsint;
1664            if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
1665            {
1666                bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1667                return true;
1668            }
1669        }
1670    }
1671    return false;
1672}
1673
1674bool
1675ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1676{
1677    if (record_decl == NULL)
1678        return false;
1679
1680    if (!record_decl->field_empty())
1681        return true;
1682
1683    // No fields, lets check this is a CXX record and check the base classes
1684    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1685    if (cxx_record_decl)
1686    {
1687        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1688        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1689             base_class != base_class_end;
1690             ++base_class)
1691        {
1692            const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1693            if (RecordHasFields(base_class_decl))
1694                return true;
1695        }
1696    }
1697    return false;
1698}
1699
1700void
1701ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
1702{
1703    if (clang_type)
1704    {
1705        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1706
1707        const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
1708        if (record_type)
1709        {
1710            RecordDecl *record_decl = record_type->getDecl();
1711            if (record_decl)
1712            {
1713                uint32_t field_idx;
1714                RecordDecl::field_iterator field, field_end;
1715                for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1716                     field != field_end;
1717                     ++field, ++field_idx)
1718                {
1719                    // If no accessibility was assigned, assign the correct one
1720                    if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1721                        field->setAccess ((AccessSpecifier)default_accessibility);
1722                }
1723            }
1724        }
1725    }
1726}
1727
1728#pragma mark C++ Base Classes
1729
1730CXXBaseSpecifier *
1731ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
1732{
1733    if (base_class_type)
1734        return new CXXBaseSpecifier (SourceRange(),
1735                                     is_virtual,
1736                                     base_of_class,
1737                                     ConvertAccessTypeToAccessSpecifier (access),
1738                                     getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
1739                                     SourceLocation());
1740    return NULL;
1741}
1742
1743void
1744ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1745{
1746    for (unsigned i=0; i<num_base_classes; ++i)
1747    {
1748        delete base_classes[i];
1749        base_classes[i] = NULL;
1750    }
1751}
1752
1753bool
1754ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
1755{
1756    if (class_clang_type)
1757    {
1758        CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
1759        if (cxx_record_decl)
1760        {
1761            cxx_record_decl->setBases(base_classes, num_base_classes);
1762            return true;
1763        }
1764    }
1765    return false;
1766}
1767#pragma mark Objective C Classes
1768
1769clang_type_t
1770ClangASTContext::CreateObjCClass
1771(
1772    const char *name,
1773    DeclContext *decl_ctx,
1774    bool isForwardDecl,
1775    bool isInternal
1776)
1777{
1778    ASTContext *ast = getASTContext();
1779    assert (ast != NULL);
1780    assert (name && name[0]);
1781    if (decl_ctx == NULL)
1782        decl_ctx = ast->getTranslationUnitDecl();
1783
1784    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1785    // we will need to update this code. I was told to currently always use
1786    // the CXXRecordDecl class since we often don't know from debug information
1787    // if something is struct or a class, so we default to always use the more
1788    // complete definition just in case.
1789    ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
1790                                                         decl_ctx,
1791                                                         SourceLocation(),
1792                                                         &ast->Idents.get(name),
1793                                                         SourceLocation(),
1794                                                         isForwardDecl,
1795                                                         isInternal);
1796
1797    return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
1798}
1799
1800bool
1801ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
1802{
1803    if (class_opaque_type && super_opaque_type)
1804    {
1805        QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1806        QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1807        const clang::Type *class_type = class_qual_type.getTypePtr();
1808        const clang::Type *super_type = super_qual_type.getTypePtr();
1809        if (class_type && super_type)
1810        {
1811            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1812            const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1813            if (objc_class_type && objc_super_type)
1814            {
1815                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1816                ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1817                if (class_interface_decl && super_interface_decl)
1818                {
1819                    class_interface_decl->setSuperClass(super_interface_decl);
1820                    return true;
1821                }
1822            }
1823        }
1824    }
1825    return false;
1826}
1827
1828
1829bool
1830ClangASTContext::AddObjCClassIVar
1831(
1832    ASTContext *ast,
1833    clang_type_t class_opaque_type,
1834    const char *name,
1835    clang_type_t ivar_opaque_type,
1836    AccessType access,
1837    uint32_t bitfield_bit_size,
1838    bool is_synthesized
1839)
1840{
1841    if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1842        return false;
1843
1844    IdentifierTable *identifier_table = &ast->Idents;
1845
1846    assert (ast != NULL);
1847    assert (identifier_table != NULL);
1848
1849    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1850
1851    const clang::Type *class_type = class_qual_type.getTypePtr();
1852    if (class_type)
1853    {
1854        const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1855
1856        if (objc_class_type)
1857        {
1858            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1859
1860            if (class_interface_decl)
1861            {
1862                clang::Expr *bit_width = NULL;
1863                if (bitfield_bit_size != 0)
1864                {
1865                    APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1866                    bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
1867                }
1868
1869                ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast,
1870                                                            class_interface_decl,
1871                                                            SourceLocation(),
1872                                                            SourceLocation(),
1873                                                            &identifier_table->get(name), // Identifier
1874                                                            QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1875                                                            NULL, // TypeSourceInfo *
1876                                                            ConvertAccessTypeToObjCIvarAccessControl (access),
1877                                                            bit_width,
1878                                                            is_synthesized);
1879
1880                if (field)
1881                {
1882                    class_interface_decl->addDecl(field);
1883                    return true;
1884                }
1885            }
1886        }
1887    }
1888    return false;
1889}
1890
1891
1892bool
1893ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
1894{
1895    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1896
1897    const clang::Type *class_type = class_qual_type.getTypePtr();
1898    if (class_type)
1899    {
1900        const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1901
1902        if (objc_class_type)
1903            return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1904    }
1905    return false;
1906}
1907
1908bool
1909ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1910{
1911    while (class_interface_decl)
1912    {
1913        if (class_interface_decl->ivar_size() > 0)
1914            return true;
1915
1916        if (check_superclass)
1917            class_interface_decl = class_interface_decl->getSuperClass();
1918        else
1919            break;
1920    }
1921    return false;
1922}
1923
1924ObjCMethodDecl *
1925ClangASTContext::AddMethodToObjCObjectType
1926(
1927    ASTContext *ast,
1928    clang_type_t class_opaque_type,
1929    const char *name,  // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
1930    clang_type_t method_opaque_type,
1931    lldb::AccessType access
1932)
1933{
1934    if (class_opaque_type == NULL || method_opaque_type == NULL)
1935        return NULL;
1936
1937    IdentifierTable *identifier_table = &ast->Idents;
1938
1939    assert (ast != NULL);
1940    assert (identifier_table != NULL);
1941
1942    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1943
1944    const clang::Type *class_type = class_qual_type.getTypePtr();
1945    if (class_type == NULL)
1946        return NULL;
1947
1948    const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1949
1950    if (objc_class_type == NULL)
1951        return NULL;
1952
1953    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1954
1955    if (class_interface_decl == NULL)
1956        return NULL;
1957
1958    const char *selector_start = ::strchr (name, ' ');
1959    if (selector_start == NULL)
1960        return NULL;
1961
1962    selector_start++;
1963    if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1964        return NULL;
1965    llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1966
1967    size_t len = 0;
1968    const char *start;
1969    //printf ("name = '%s'\n", name);
1970
1971    unsigned num_selectors_with_args = 0;
1972    for (start = selector_start;
1973         start && *start != '\0' && *start != ']';
1974         start += len)
1975    {
1976        len = ::strcspn(start, ":]");
1977        bool has_arg = (start[len] == ':');
1978        if (has_arg)
1979            ++num_selectors_with_args;
1980        selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
1981        if (has_arg)
1982            len += 1;
1983    }
1984
1985
1986    if (selector_idents.size() == 0)
1987        return 0;
1988
1989    clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
1990                                                                          selector_idents.data());
1991
1992    QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1993
1994    // Populate the method decl with parameter decls
1995    const clang::Type *method_type(method_qual_type.getTypePtr());
1996
1997    if (method_type == NULL)
1998        return NULL;
1999
2000    const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
2001
2002    if (!method_function_prototype)
2003        return NULL;
2004
2005
2006    bool is_variadic = false;
2007    bool is_synthesized = false;
2008    bool is_defined = false;
2009    ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
2010
2011    const unsigned num_args = method_function_prototype->getNumArgs();
2012
2013    ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
2014                                                               SourceLocation(), // beginLoc,
2015                                                               SourceLocation(), // endLoc,
2016                                                               method_selector,
2017                                                               method_function_prototype->getResultType(),
2018                                                               NULL, // TypeSourceInfo *ResultTInfo,
2019                                                               GetDeclContextForType (class_opaque_type),
2020                                                               name[0] == '-',
2021                                                               is_variadic,
2022                                                               is_synthesized,
2023                                                               is_defined,
2024                                                               imp_control,
2025                                                               num_args);
2026
2027
2028    if (objc_method_decl == NULL)
2029        return NULL;
2030
2031    if (num_args > 0)
2032    {
2033        llvm::SmallVector<ParmVarDecl *, 12> params;
2034
2035        for (int param_index = 0; param_index < num_args; ++param_index)
2036        {
2037            params.push_back (ParmVarDecl::Create (*ast,
2038                                                   objc_method_decl,
2039                                                   SourceLocation(),
2040                                                   SourceLocation(),
2041                                                   NULL, // anonymous
2042                                                   method_function_prototype->getArgType(param_index),
2043                                                   NULL,
2044                                                   SC_Auto,
2045                                                   SC_Auto,
2046                                                   NULL));
2047        }
2048
2049        objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args);
2050    }
2051
2052    class_interface_decl->addDecl (objc_method_decl);
2053
2054
2055    return objc_method_decl;
2056}
2057
2058
2059uint32_t
2060ClangASTContext::GetTypeInfo
2061(
2062    clang_type_t clang_type,
2063    clang::ASTContext *ast,
2064    clang_type_t *pointee_or_element_clang_type
2065)
2066{
2067    if (clang_type == NULL)
2068        return 0;
2069
2070    if (pointee_or_element_clang_type)
2071        *pointee_or_element_clang_type = NULL;
2072
2073    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2074
2075    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2076    switch (type_class)
2077    {
2078    case clang::Type::Builtin:
2079        switch (cast<clang::BuiltinType>(qual_type)->getKind())
2080        {
2081        case clang::BuiltinType::ObjCId:
2082        case clang::BuiltinType::ObjCClass:
2083            if (ast && pointee_or_element_clang_type)
2084                *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
2085            return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
2086                break;
2087        case clang::BuiltinType::Bool:
2088        case clang::BuiltinType::Char_U:
2089        case clang::BuiltinType::UChar:
2090        case clang::BuiltinType::WChar_U:
2091        case clang::BuiltinType::Char16:
2092        case clang::BuiltinType::Char32:
2093        case clang::BuiltinType::UShort:
2094        case clang::BuiltinType::UInt:
2095        case clang::BuiltinType::ULong:
2096        case clang::BuiltinType::ULongLong:
2097        case clang::BuiltinType::UInt128:
2098        case clang::BuiltinType::Char_S:
2099        case clang::BuiltinType::SChar:
2100        case clang::BuiltinType::WChar_S:
2101        case clang::BuiltinType::Short:
2102        case clang::BuiltinType::Int:
2103        case clang::BuiltinType::Long:
2104        case clang::BuiltinType::LongLong:
2105        case clang::BuiltinType::Int128:
2106        case clang::BuiltinType::Float:
2107        case clang::BuiltinType::Double:
2108        case clang::BuiltinType::LongDouble:
2109                return eTypeIsBuiltIn | eTypeHasValue | eTypeIsScalar;
2110        default:
2111            break;
2112        }
2113        return eTypeIsBuiltIn | eTypeHasValue;
2114
2115    case clang::Type::BlockPointer:
2116        if (pointee_or_element_clang_type)
2117            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2118        return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
2119
2120    case clang::Type::Complex:                          return eTypeIsBuiltIn | eTypeHasValue;
2121
2122    case clang::Type::ConstantArray:
2123    case clang::Type::DependentSizedArray:
2124    case clang::Type::IncompleteArray:
2125    case clang::Type::VariableArray:
2126        if (pointee_or_element_clang_type)
2127            *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
2128        return eTypeHasChildren | eTypeIsArray;
2129
2130    case clang::Type::DependentName:                    return 0;
2131    case clang::Type::DependentSizedExtVector:          return eTypeHasChildren | eTypeIsVector;
2132    case clang::Type::DependentTemplateSpecialization:  return eTypeIsTemplate;
2133    case clang::Type::Decltype:                         return 0;
2134
2135    case clang::Type::Enum:
2136        if (pointee_or_element_clang_type)
2137            *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
2138        return eTypeIsEnumeration | eTypeHasValue;
2139
2140    case clang::Type::Elaborated:
2141        return ClangASTContext::GetTypeInfo (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2142                                             ast,
2143                                             pointee_or_element_clang_type);
2144    case clang::Type::ExtVector:                        return eTypeHasChildren | eTypeIsVector;
2145    case clang::Type::FunctionProto:                    return eTypeIsFuncPrototype | eTypeHasValue;
2146    case clang::Type::FunctionNoProto:                  return eTypeIsFuncPrototype | eTypeHasValue;
2147    case clang::Type::InjectedClassName:                return 0;
2148
2149    case clang::Type::LValueReference:
2150    case clang::Type::RValueReference:
2151        if (pointee_or_element_clang_type)
2152            *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
2153        return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
2154
2155    case clang::Type::MemberPointer:                    return eTypeIsPointer   | eTypeIsMember | eTypeHasValue;
2156
2157    case clang::Type::ObjCObjectPointer:
2158        if (pointee_or_element_clang_type)
2159            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2160        return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
2161
2162    case clang::Type::ObjCObject:                       return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2163    case clang::Type::ObjCInterface:                    return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2164
2165    case clang::Type::Pointer:
2166        if (pointee_or_element_clang_type)
2167            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2168        return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
2169
2170    case clang::Type::Record:
2171        if (qual_type->getAsCXXRecordDecl())
2172            return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
2173        else
2174            return eTypeHasChildren | eTypeIsStructUnion;
2175        break;
2176    case clang::Type::SubstTemplateTypeParm:            return eTypeIsTemplate;
2177    case clang::Type::TemplateTypeParm:                 return eTypeIsTemplate;
2178    case clang::Type::TemplateSpecialization:           return eTypeIsTemplate;
2179
2180    case clang::Type::Typedef:
2181        return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2182                                                                  ast,
2183                                                                  pointee_or_element_clang_type);
2184
2185    case clang::Type::TypeOfExpr:                       return 0;
2186    case clang::Type::TypeOf:                           return 0;
2187    case clang::Type::UnresolvedUsing:                  return 0;
2188    case clang::Type::Vector:                           return eTypeHasChildren | eTypeIsVector;
2189    default:                                            return 0;
2190    }
2191    return 0;
2192}
2193
2194
2195#pragma mark Aggregate Types
2196
2197bool
2198ClangASTContext::IsAggregateType (clang_type_t clang_type)
2199{
2200    if (clang_type == NULL)
2201        return false;
2202
2203    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2204
2205    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2206    switch (type_class)
2207    {
2208    case clang::Type::IncompleteArray:
2209    case clang::Type::VariableArray:
2210    case clang::Type::ConstantArray:
2211    case clang::Type::ExtVector:
2212    case clang::Type::Vector:
2213    case clang::Type::Record:
2214    case clang::Type::ObjCObject:
2215    case clang::Type::ObjCInterface:
2216        return true;
2217    case clang::Type::Elaborated:
2218        return ClangASTContext::IsAggregateType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2219    case clang::Type::Typedef:
2220        return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2221
2222    default:
2223        break;
2224    }
2225    // The clang type does have a value
2226    return false;
2227}
2228
2229uint32_t
2230ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
2231{
2232    if (clang_type == NULL)
2233        return 0;
2234
2235    uint32_t num_children = 0;
2236    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2237    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2238    switch (type_class)
2239    {
2240    case clang::Type::Builtin:
2241        switch (cast<clang::BuiltinType>(qual_type)->getKind())
2242        {
2243        case clang::BuiltinType::ObjCId:    // child is Class
2244        case clang::BuiltinType::ObjCClass: // child is Class
2245            num_children = 1;
2246            break;
2247
2248        default:
2249            break;
2250        }
2251        break;
2252
2253    case clang::Type::Complex: return 0;
2254
2255    case clang::Type::Record:
2256        if (GetCompleteQualType (ast, qual_type))
2257        {
2258            const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2259            const RecordDecl *record_decl = record_type->getDecl();
2260            assert(record_decl);
2261            const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2262            if (cxx_record_decl)
2263            {
2264                if (omit_empty_base_classes)
2265                {
2266                    // Check each base classes to see if it or any of its
2267                    // base classes contain any fields. This can help
2268                    // limit the noise in variable views by not having to
2269                    // show base classes that contain no members.
2270                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2271                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2272                         base_class != base_class_end;
2273                         ++base_class)
2274                    {
2275                        const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2276
2277                        // Skip empty base classes
2278                        if (RecordHasFields(base_class_decl) == false)
2279                            continue;
2280
2281                        num_children++;
2282                    }
2283                }
2284                else
2285                {
2286                    // Include all base classes
2287                    num_children += cxx_record_decl->getNumBases();
2288                }
2289
2290            }
2291            RecordDecl::field_iterator field, field_end;
2292            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2293                ++num_children;
2294        }
2295        break;
2296
2297    case clang::Type::ObjCObject:
2298    case clang::Type::ObjCInterface:
2299        if (GetCompleteQualType (ast, qual_type))
2300        {
2301            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2302            assert (objc_class_type);
2303            if (objc_class_type)
2304            {
2305                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2306
2307                if (class_interface_decl)
2308                {
2309
2310                    ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2311                    if (superclass_interface_decl)
2312                    {
2313                        if (omit_empty_base_classes)
2314                        {
2315                            if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2316                                ++num_children;
2317                        }
2318                        else
2319                            ++num_children;
2320                    }
2321
2322                    num_children += class_interface_decl->ivar_size();
2323                }
2324            }
2325        }
2326        break;
2327
2328    case clang::Type::ObjCObjectPointer:
2329        {
2330            const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
2331            QualType pointee_type = pointer_type->getPointeeType();
2332            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2333                                                                             pointee_type.getAsOpaquePtr(),
2334                                                                             omit_empty_base_classes);
2335            // If this type points to a simple type, then it has 1 child
2336            if (num_pointee_children == 0)
2337                num_children = 1;
2338            else
2339                num_children = num_pointee_children;
2340        }
2341        break;
2342
2343    case clang::Type::ConstantArray:
2344        num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2345        break;
2346
2347    case clang::Type::Pointer:
2348        {
2349            const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2350            QualType pointee_type (pointer_type->getPointeeType());
2351            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2352                                                                             pointee_type.getAsOpaquePtr(),
2353                                                                             omit_empty_base_classes);
2354            if (num_pointee_children == 0)
2355            {
2356                // We have a pointer to a pointee type that claims it has no children.
2357                // We will want to look at
2358                num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
2359            }
2360            else
2361                num_children = num_pointee_children;
2362        }
2363        break;
2364
2365    case clang::Type::LValueReference:
2366    case clang::Type::RValueReference:
2367        {
2368            const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2369            QualType pointee_type = reference_type->getPointeeType();
2370            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2371                                                                             pointee_type.getAsOpaquePtr(),
2372                                                                             omit_empty_base_classes);
2373            // If this type points to a simple type, then it has 1 child
2374            if (num_pointee_children == 0)
2375                num_children = 1;
2376            else
2377                num_children = num_pointee_children;
2378        }
2379        break;
2380
2381
2382    case clang::Type::Typedef:
2383        num_children = ClangASTContext::GetNumChildren (ast,
2384                                                        cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2385                                                        omit_empty_base_classes);
2386        break;
2387
2388    case clang::Type::Elaborated:
2389        num_children = ClangASTContext::GetNumChildren (ast,
2390                                                        cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2391                                                        omit_empty_base_classes);
2392        break;
2393
2394    default:
2395        break;
2396    }
2397    return num_children;
2398}
2399
2400uint32_t
2401ClangASTContext::GetNumDirectBaseClasses (clang::ASTContext *ast, clang_type_t clang_type)
2402{
2403    if (clang_type == NULL)
2404        return 0;
2405
2406    uint32_t count = 0;
2407    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2408    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2409    switch (type_class)
2410    {
2411        case clang::Type::Record:
2412            if (GetCompleteQualType (ast, qual_type))
2413            {
2414                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2415                if (cxx_record_decl)
2416                    count = cxx_record_decl->getNumBases();
2417            }
2418            break;
2419
2420        case clang::Type::ObjCObject:
2421        case clang::Type::ObjCInterface:
2422            if (GetCompleteQualType (ast, qual_type))
2423            {
2424                const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
2425                if (objc_class_type)
2426                {
2427                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2428
2429                    if (class_interface_decl && class_interface_decl->getSuperClass())
2430                        count = 1;
2431                }
2432            }
2433            break;
2434
2435
2436        case clang::Type::Typedef:
2437            count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2438            break;
2439
2440        case clang::Type::Elaborated:
2441            count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2442            break;
2443
2444        default:
2445            break;
2446    }
2447    return count;
2448}
2449
2450uint32_t
2451ClangASTContext::GetNumVirtualBaseClasses (clang::ASTContext *ast,
2452                                           clang_type_t clang_type)
2453{
2454    if (clang_type == NULL)
2455        return 0;
2456
2457    uint32_t count = 0;
2458    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2459    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2460    switch (type_class)
2461    {
2462        case clang::Type::Record:
2463            if (GetCompleteQualType (ast, qual_type))
2464            {
2465                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2466                if (cxx_record_decl)
2467                    count = cxx_record_decl->getNumVBases();
2468            }
2469            break;
2470
2471        case clang::Type::Typedef:
2472            count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2473            break;
2474
2475        case clang::Type::Elaborated:
2476            count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2477            break;
2478
2479        default:
2480            break;
2481    }
2482    return count;
2483}
2484
2485uint32_t
2486ClangASTContext::GetNumFields (clang::ASTContext *ast, clang_type_t clang_type)
2487{
2488    if (clang_type == NULL)
2489        return 0;
2490
2491    uint32_t count = 0;
2492    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2493    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2494    switch (type_class)
2495    {
2496        case clang::Type::Record:
2497            if (GetCompleteQualType (ast, qual_type))
2498            {
2499                const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
2500                if (record_type)
2501                {
2502                    RecordDecl *record_decl = record_type->getDecl();
2503                    if (record_decl)
2504                    {
2505                        uint32_t field_idx = 0;
2506                        RecordDecl::field_iterator field, field_end;
2507                        for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2508                            ++field_idx;
2509                        count = field_idx;
2510                    }
2511                }
2512            }
2513            break;
2514
2515        case clang::Type::Typedef:
2516            count = ClangASTContext::GetNumFields (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2517            break;
2518
2519        case clang::Type::Elaborated:
2520            count = ClangASTContext::GetNumFields (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2521            break;
2522
2523        default:
2524            break;
2525    }
2526    return count;
2527}
2528
2529clang_type_t
2530ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast,
2531                                            clang_type_t clang_type,
2532                                            uint32_t idx,
2533                                            uint32_t *byte_offset_ptr)
2534{
2535    if (clang_type == NULL)
2536        return 0;
2537
2538    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2539    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2540    switch (type_class)
2541    {
2542        case clang::Type::Record:
2543            if (GetCompleteQualType (ast, qual_type))
2544            {
2545                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2546                if (cxx_record_decl)
2547                {
2548                    uint32_t curr_idx = 0;
2549                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2550                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2551                         base_class != base_class_end;
2552                         ++base_class, ++curr_idx)
2553                    {
2554                        if (curr_idx == idx)
2555                        {
2556                            if (byte_offset_ptr)
2557                            {
2558                                const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
2559                                const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2560//                                if (base_class->isVirtual())
2561//                                    *byte_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
2562//                                else
2563                                    *byte_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
2564                            }
2565                            return base_class->getType().getAsOpaquePtr();
2566                        }
2567                    }
2568                }
2569            }
2570            break;
2571
2572        case clang::Type::ObjCObject:
2573        case clang::Type::ObjCInterface:
2574            if (idx == 0 && GetCompleteQualType (ast, qual_type))
2575            {
2576                const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
2577                if (objc_class_type)
2578                {
2579                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2580
2581                    if (class_interface_decl)
2582                    {
2583                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2584                        if (superclass_interface_decl)
2585                        {
2586                            if (byte_offset_ptr)
2587                                *byte_offset_ptr = 0;
2588                            return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr();
2589                        }
2590                    }
2591                }
2592            }
2593            break;
2594
2595
2596        case clang::Type::Typedef:
2597            return ClangASTContext::GetDirectBaseClassAtIndex (ast,
2598                                                               cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2599                                                               idx,
2600                                                               byte_offset_ptr);
2601
2602        case clang::Type::Elaborated:
2603            return  ClangASTContext::GetDirectBaseClassAtIndex (ast,
2604                                                                cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2605                                                                idx,
2606                                                                byte_offset_ptr);
2607
2608        default:
2609            break;
2610    }
2611    return NULL;
2612}
2613
2614clang_type_t
2615ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast,
2616                                             clang_type_t clang_type,
2617                                             uint32_t idx,
2618                                             uint32_t *byte_offset_ptr)
2619{
2620    if (clang_type == NULL)
2621        return 0;
2622
2623    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2624    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2625    switch (type_class)
2626    {
2627        case clang::Type::Record:
2628            if (GetCompleteQualType (ast, qual_type))
2629            {
2630                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2631                if (cxx_record_decl)
2632                {
2633                    uint32_t curr_idx = 0;
2634                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2635                    for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end();
2636                         base_class != base_class_end;
2637                         ++base_class, ++curr_idx)
2638                    {
2639                        if (curr_idx == idx)
2640                        {
2641                            if (byte_offset_ptr)
2642                            {
2643                                const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
2644                                const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2645                                *byte_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
2646
2647                            }
2648                            return base_class->getType().getAsOpaquePtr();
2649                        }
2650                    }
2651                }
2652            }
2653            break;
2654
2655        case clang::Type::Typedef:
2656            return ClangASTContext::GetVirtualBaseClassAtIndex (ast,
2657                                                                cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2658                                                                idx,
2659                                                                byte_offset_ptr);
2660
2661        case clang::Type::Elaborated:
2662            return  ClangASTContext::GetVirtualBaseClassAtIndex (ast,
2663                                                                 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2664                                                                 idx,
2665                                                                 byte_offset_ptr);
2666
2667        default:
2668            break;
2669    }
2670    return NULL;
2671}
2672
2673clang_type_t
2674ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast,
2675                                  clang_type_t clang_type,
2676                                  uint32_t idx,
2677                                  std::string& name,
2678                                  uint32_t *byte_offset_ptr)
2679{
2680    if (clang_type == NULL)
2681        return 0;
2682
2683    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2684    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2685    switch (type_class)
2686    {
2687        case clang::Type::Record:
2688            if (GetCompleteQualType (ast, qual_type))
2689            {
2690                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2691                const RecordDecl *record_decl = record_type->getDecl();
2692                uint32_t field_idx = 0;
2693                RecordDecl::field_iterator field, field_end;
2694                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
2695                {
2696                    if (idx == field_idx)
2697                    {
2698                        // Print the member type if requested
2699                        // Print the member name and equal sign
2700                        name.assign(field->getNameAsString());
2701
2702                        // Figure out the type byte size (field_type_info.first) and
2703                        // alignment (field_type_info.second) from the AST context.
2704                        if (byte_offset_ptr)
2705                        {
2706                            const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
2707                            *byte_offset_ptr = (record_layout.getFieldOffset (field_idx) + 7) / 8;
2708                        }
2709
2710                        return field->getType().getAsOpaquePtr();
2711                    }
2712                }
2713            }
2714            break;
2715
2716        case clang::Type::ObjCObject:
2717        case clang::Type::ObjCInterface:
2718            if (GetCompleteQualType (ast, qual_type))
2719            {
2720                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2721                assert (objc_class_type);
2722                if (objc_class_type)
2723                {
2724                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2725
2726                    if (class_interface_decl)
2727                    {
2728                        if (idx < (class_interface_decl->ivar_size()))
2729                        {
2730                            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2731                            uint32_t ivar_idx = 0;
2732
2733                            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx)
2734                            {
2735                                if (ivar_idx == idx)
2736                                {
2737                                    const ObjCIvarDecl* ivar_decl = *ivar_pos;
2738
2739                                    QualType ivar_qual_type(ivar_decl->getType());
2740
2741                                    name.assign(ivar_decl->getNameAsString());
2742
2743                                    if (byte_offset_ptr)
2744                                    {
2745                                        const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
2746                                        *byte_offset_ptr = (interface_layout.getFieldOffset (ivar_idx) + 7)/8;
2747                                    }
2748
2749                                    return ivar_qual_type.getAsOpaquePtr();
2750                                }
2751                            }
2752                        }
2753                    }
2754                }
2755            }
2756            break;
2757
2758
2759        case clang::Type::Typedef:
2760            return ClangASTContext::GetFieldAtIndex (ast,
2761                                                     cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2762                                                     idx,
2763                                                     name,
2764                                                     byte_offset_ptr);
2765
2766        case clang::Type::Elaborated:
2767            return  ClangASTContext::GetFieldAtIndex (ast,
2768                                                      cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
2769                                                      idx,
2770                                                      name,
2771                                                      byte_offset_ptr);
2772
2773        default:
2774            break;
2775    }
2776    return NULL;
2777}
2778
2779
2780// If a pointer to a pointee type (the clang_type arg) says that it has no
2781// children, then we either need to trust it, or override it and return a
2782// different result. For example, an "int *" has one child that is an integer,
2783// but a function pointer doesn't have any children. Likewise if a Record type
2784// claims it has no children, then there really is nothing to show.
2785uint32_t
2786ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
2787{
2788    if (clang_type == NULL)
2789        return 0;
2790
2791    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2792    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2793    switch (type_class)
2794    {
2795    case clang::Type::Builtin:
2796        switch (cast<clang::BuiltinType>(qual_type)->getKind())
2797        {
2798        case clang::BuiltinType::UnknownAny:
2799        case clang::BuiltinType::Void:
2800        case clang::BuiltinType::NullPtr:
2801            return 0;
2802        case clang::BuiltinType::Bool:
2803        case clang::BuiltinType::Char_U:
2804        case clang::BuiltinType::UChar:
2805        case clang::BuiltinType::WChar_U:
2806        case clang::BuiltinType::Char16:
2807        case clang::BuiltinType::Char32:
2808        case clang::BuiltinType::UShort:
2809        case clang::BuiltinType::UInt:
2810        case clang::BuiltinType::ULong:
2811        case clang::BuiltinType::ULongLong:
2812        case clang::BuiltinType::UInt128:
2813        case clang::BuiltinType::Char_S:
2814        case clang::BuiltinType::SChar:
2815        case clang::BuiltinType::WChar_S:
2816        case clang::BuiltinType::Short:
2817        case clang::BuiltinType::Int:
2818        case clang::BuiltinType::Long:
2819        case clang::BuiltinType::LongLong:
2820        case clang::BuiltinType::Int128:
2821        case clang::BuiltinType::Float:
2822        case clang::BuiltinType::Double:
2823        case clang::BuiltinType::LongDouble:
2824        case clang::BuiltinType::Dependent:
2825        case clang::BuiltinType::Overload:
2826        case clang::BuiltinType::ObjCId:
2827        case clang::BuiltinType::ObjCClass:
2828        case clang::BuiltinType::ObjCSel:
2829        case clang::BuiltinType::BoundMember:
2830            return 1;
2831        }
2832        break;
2833
2834    case clang::Type::Complex:                  return 1;
2835    case clang::Type::Pointer:                  return 1;
2836    case clang::Type::BlockPointer:             return 0;   // If block pointers don't have debug info, then no children for them
2837    case clang::Type::LValueReference:          return 1;
2838    case clang::Type::RValueReference:          return 1;
2839    case clang::Type::MemberPointer:            return 0;
2840    case clang::Type::ConstantArray:            return 0;
2841    case clang::Type::IncompleteArray:          return 0;
2842    case clang::Type::VariableArray:            return 0;
2843    case clang::Type::DependentSizedArray:      return 0;
2844    case clang::Type::DependentSizedExtVector:  return 0;
2845    case clang::Type::Vector:                   return 0;
2846    case clang::Type::ExtVector:                return 0;
2847    case clang::Type::FunctionProto:            return 0;   // When we function pointers, they have no children...
2848    case clang::Type::FunctionNoProto:          return 0;   // When we function pointers, they have no children...
2849    case clang::Type::UnresolvedUsing:          return 0;
2850    case clang::Type::Paren:                    return 0;
2851    case clang::Type::Typedef:                  return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2852    case clang::Type::Elaborated:               return ClangASTContext::GetNumPointeeChildren (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
2853    case clang::Type::TypeOfExpr:               return 0;
2854    case clang::Type::TypeOf:                   return 0;
2855    case clang::Type::Decltype:                 return 0;
2856    case clang::Type::Record:                   return 0;
2857    case clang::Type::Enum:                     return 1;
2858    case clang::Type::TemplateTypeParm:         return 1;
2859    case clang::Type::SubstTemplateTypeParm:    return 1;
2860    case clang::Type::TemplateSpecialization:   return 1;
2861    case clang::Type::InjectedClassName:        return 0;
2862    case clang::Type::DependentName:            return 1;
2863    case clang::Type::DependentTemplateSpecialization:  return 1;
2864    case clang::Type::ObjCObject:               return 0;
2865    case clang::Type::ObjCInterface:            return 0;
2866    case clang::Type::ObjCObjectPointer:        return 1;
2867    default:
2868        break;
2869    }
2870    return 0;
2871}
2872
2873clang_type_t
2874ClangASTContext::GetChildClangTypeAtIndex
2875(
2876    ExecutionContext *exe_ctx,
2877    const char *parent_name,
2878    clang_type_t parent_clang_type,
2879    uint32_t idx,
2880    bool transparent_pointers,
2881    bool omit_empty_base_classes,
2882    bool ignore_array_bounds,
2883    std::string& child_name,
2884    uint32_t &child_byte_size,
2885    int32_t &child_byte_offset,
2886    uint32_t &child_bitfield_bit_size,
2887    uint32_t &child_bitfield_bit_offset,
2888    bool &child_is_base_class,
2889    bool &child_is_deref_of_parent
2890)
2891{
2892    if (parent_clang_type)
2893
2894        return GetChildClangTypeAtIndex (exe_ctx,
2895                                         getASTContext(),
2896                                         parent_name,
2897                                         parent_clang_type,
2898                                         idx,
2899                                         transparent_pointers,
2900                                         omit_empty_base_classes,
2901                                         ignore_array_bounds,
2902                                         child_name,
2903                                         child_byte_size,
2904                                         child_byte_offset,
2905                                         child_bitfield_bit_size,
2906                                         child_bitfield_bit_offset,
2907                                         child_is_base_class,
2908                                         child_is_deref_of_parent);
2909    return NULL;
2910}
2911
2912clang_type_t
2913ClangASTContext::GetChildClangTypeAtIndex
2914(
2915    ExecutionContext *exe_ctx,
2916    ASTContext *ast,
2917    const char *parent_name,
2918    clang_type_t parent_clang_type,
2919    uint32_t idx,
2920    bool transparent_pointers,
2921    bool omit_empty_base_classes,
2922    bool ignore_array_bounds,
2923    std::string& child_name,
2924    uint32_t &child_byte_size,
2925    int32_t &child_byte_offset,
2926    uint32_t &child_bitfield_bit_size,
2927    uint32_t &child_bitfield_bit_offset,
2928    bool &child_is_base_class,
2929    bool &child_is_deref_of_parent
2930)
2931{
2932    if (parent_clang_type == NULL)
2933        return NULL;
2934
2935    if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
2936    {
2937        uint32_t bit_offset;
2938        child_bitfield_bit_size = 0;
2939        child_bitfield_bit_offset = 0;
2940        child_is_base_class = false;
2941        QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
2942        const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2943        switch (parent_type_class)
2944        {
2945        case clang::Type::Builtin:
2946            switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2947            {
2948            case clang::BuiltinType::ObjCId:
2949            case clang::BuiltinType::ObjCClass:
2950                child_name = "isa";
2951                child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
2952                return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
2953
2954            default:
2955                break;
2956            }
2957            break;
2958
2959        case clang::Type::Record:
2960            if (GetCompleteQualType (ast, parent_qual_type))
2961            {
2962                const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2963                const RecordDecl *record_decl = record_type->getDecl();
2964                assert(record_decl);
2965                const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
2966                uint32_t child_idx = 0;
2967
2968                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2969                if (cxx_record_decl)
2970                {
2971                    // We might have base classes to print out first
2972                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2973                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2974                         base_class != base_class_end;
2975                         ++base_class)
2976                    {
2977                        const CXXRecordDecl *base_class_decl = NULL;
2978
2979                        // Skip empty base classes
2980                        if (omit_empty_base_classes)
2981                        {
2982                            base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2983                            if (RecordHasFields(base_class_decl) == false)
2984                                continue;
2985                        }
2986
2987                        if (idx == child_idx)
2988                        {
2989                            if (base_class_decl == NULL)
2990                                base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2991
2992
2993                            if (base_class->isVirtual())
2994                                bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
2995                            else
2996                                bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
2997
2998                            // Base classes should be a multiple of 8 bits in size
2999                            child_byte_offset = bit_offset/8;
3000
3001                            child_name = ClangASTType::GetTypeNameForQualType(base_class->getType());
3002
3003                            uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
3004
3005                            // Base classes bit sizes should be a multiple of 8 bits in size
3006                            assert (clang_type_info_bit_size % 8 == 0);
3007                            child_byte_size = clang_type_info_bit_size / 8;
3008                            child_is_base_class = true;
3009                            return base_class->getType().getAsOpaquePtr();
3010                        }
3011                        // We don't increment the child index in the for loop since we might
3012                        // be skipping empty base classes
3013                        ++child_idx;
3014                    }
3015                }
3016                // Make sure index is in range...
3017                uint32_t field_idx = 0;
3018                RecordDecl::field_iterator field, field_end;
3019                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
3020                {
3021                    if (idx == child_idx)
3022                    {
3023                        // Print the member type if requested
3024                        // Print the member name and equal sign
3025                        child_name.assign(field->getNameAsString().c_str());
3026
3027                        // Figure out the type byte size (field_type_info.first) and
3028                        // alignment (field_type_info.second) from the AST context.
3029                        std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
3030                        assert(field_idx < record_layout.getFieldCount());
3031
3032                        child_byte_size = field_type_info.first / 8;
3033
3034                        // Figure out the field offset within the current struct/union/class type
3035                        bit_offset = record_layout.getFieldOffset (field_idx);
3036                        child_byte_offset = bit_offset / 8;
3037                        if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
3038                            child_bitfield_bit_offset = bit_offset % 8;
3039
3040                        return field->getType().getAsOpaquePtr();
3041                    }
3042                }
3043            }
3044            break;
3045
3046        case clang::Type::ObjCObject:
3047        case clang::Type::ObjCInterface:
3048            if (GetCompleteQualType (ast, parent_qual_type))
3049            {
3050                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
3051                assert (objc_class_type);
3052                if (objc_class_type)
3053                {
3054                    uint32_t child_idx = 0;
3055                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3056
3057                    if (class_interface_decl)
3058                    {
3059
3060                        const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
3061                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3062                        if (superclass_interface_decl)
3063                        {
3064                            if (omit_empty_base_classes)
3065                            {
3066                                if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
3067                                {
3068                                    if (idx == 0)
3069                                    {
3070                                        QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
3071
3072
3073                                        child_name.assign(superclass_interface_decl->getNameAsString().c_str());
3074
3075                                        std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
3076
3077                                        child_byte_size = ivar_type_info.first / 8;
3078                                        child_byte_offset = 0;
3079                                        child_is_base_class = true;
3080
3081                                        return ivar_qual_type.getAsOpaquePtr();
3082                                    }
3083
3084                                    ++child_idx;
3085                                }
3086                            }
3087                            else
3088                                ++child_idx;
3089                        }
3090
3091                        const uint32_t superclass_idx = child_idx;
3092
3093                        if (idx < (child_idx + class_interface_decl->ivar_size()))
3094                        {
3095                            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3096
3097                            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3098                            {
3099                                if (child_idx == idx)
3100                                {
3101                                    const ObjCIvarDecl* ivar_decl = *ivar_pos;
3102
3103                                    QualType ivar_qual_type(ivar_decl->getType());
3104
3105                                    child_name.assign(ivar_decl->getNameAsString().c_str());
3106
3107                                    std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
3108
3109                                    child_byte_size = ivar_type_info.first / 8;
3110
3111                                    // Figure out the field offset within the current struct/union/class type
3112                                    // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
3113                                    // that doesn't account for the space taken up by unbacked properties, or from
3114                                    // the changing size of base classes that are newer than this class.
3115                                    // So if we have a process around that we can ask about this object, do so.
3116                                    child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
3117                                    Process *process = NULL;
3118                                    if (exe_ctx)
3119                                        process = exe_ctx->GetProcessPtr();
3120                                    if (process)
3121                                    {
3122                                        ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
3123                                        if (objc_runtime != NULL)
3124                                        {
3125                                            ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
3126                                            child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
3127                                        }
3128                                    }
3129
3130                                    if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
3131                                    {
3132                                        bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
3133                                        child_byte_offset = bit_offset / 8;
3134                                    }
3135
3136                                    return ivar_qual_type.getAsOpaquePtr();
3137                                }
3138                                ++child_idx;
3139                            }
3140                        }
3141                    }
3142                }
3143            }
3144            break;
3145
3146        case clang::Type::ObjCObjectPointer:
3147            {
3148                const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
3149                QualType pointee_type = pointer_type->getPointeeType();
3150
3151                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3152                {
3153                    child_is_deref_of_parent = false;
3154                    bool tmp_child_is_deref_of_parent = false;
3155                    return GetChildClangTypeAtIndex (exe_ctx,
3156                                                     ast,
3157                                                     parent_name,
3158                                                     pointer_type->getPointeeType().getAsOpaquePtr(),
3159                                                     idx,
3160                                                     transparent_pointers,
3161                                                     omit_empty_base_classes,
3162                                                     ignore_array_bounds,
3163                                                     child_name,
3164                                                     child_byte_size,
3165                                                     child_byte_offset,
3166                                                     child_bitfield_bit_size,
3167                                                     child_bitfield_bit_offset,
3168                                                     child_is_base_class,
3169                                                     tmp_child_is_deref_of_parent);
3170                }
3171                else
3172                {
3173                    child_is_deref_of_parent = true;
3174                    if (parent_name)
3175                    {
3176                        child_name.assign(1, '*');
3177                        child_name += parent_name;
3178                    }
3179
3180                    // We have a pointer to an simple type
3181                    if (idx == 0)
3182                    {
3183                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
3184                        assert(clang_type_info.first % 8 == 0);
3185                        child_byte_size = clang_type_info.first / 8;
3186                        child_byte_offset = 0;
3187                        return pointee_type.getAsOpaquePtr();
3188                    }
3189                }
3190            }
3191            break;
3192
3193        case clang::Type::ConstantArray:
3194            {
3195                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3196                const uint64_t element_count = array->getSize().getLimitedValue();
3197
3198                if (ignore_array_bounds || idx < element_count)
3199                {
3200                    if (GetCompleteQualType (ast, array->getElementType()))
3201                    {
3202                        std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
3203
3204                        char element_name[64];
3205                        ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
3206
3207                        child_name.assign(element_name);
3208                        assert(field_type_info.first % 8 == 0);
3209                        child_byte_size = field_type_info.first / 8;
3210                        child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
3211                        return array->getElementType().getAsOpaquePtr();
3212                    }
3213                }
3214            }
3215            break;
3216
3217        case clang::Type::Pointer:
3218            {
3219                const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
3220                QualType pointee_type = pointer_type->getPointeeType();
3221
3222                // Don't dereference "void *" pointers
3223                if (pointee_type->isVoidType())
3224                    return NULL;
3225
3226                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3227                {
3228                    child_is_deref_of_parent = false;
3229                    bool tmp_child_is_deref_of_parent = false;
3230                    return GetChildClangTypeAtIndex (exe_ctx,
3231                                                     ast,
3232                                                     parent_name,
3233                                                     pointer_type->getPointeeType().getAsOpaquePtr(),
3234                                                     idx,
3235                                                     transparent_pointers,
3236                                                     omit_empty_base_classes,
3237                                                     ignore_array_bounds,
3238                                                     child_name,
3239                                                     child_byte_size,
3240                                                     child_byte_offset,
3241                                                     child_bitfield_bit_size,
3242                                                     child_bitfield_bit_offset,
3243                                                     child_is_base_class,
3244                                                     tmp_child_is_deref_of_parent);
3245                }
3246                else
3247                {
3248                    child_is_deref_of_parent = true;
3249
3250                    if (parent_name)
3251                    {
3252                        child_name.assign(1, '*');
3253                        child_name += parent_name;
3254                    }
3255
3256                    // We have a pointer to an simple type
3257                    if (idx == 0)
3258                    {
3259                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
3260                        assert(clang_type_info.first % 8 == 0);
3261                        child_byte_size = clang_type_info.first / 8;
3262                        child_byte_offset = 0;
3263                        return pointee_type.getAsOpaquePtr();
3264                    }
3265                }
3266            }
3267            break;
3268
3269        case clang::Type::LValueReference:
3270        case clang::Type::RValueReference:
3271            {
3272                const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
3273                QualType pointee_type(reference_type->getPointeeType());
3274                clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
3275                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
3276                {
3277                    child_is_deref_of_parent = false;
3278                    bool tmp_child_is_deref_of_parent = false;
3279                    return GetChildClangTypeAtIndex (exe_ctx,
3280                                                     ast,
3281                                                     parent_name,
3282                                                     pointee_clang_type,
3283                                                     idx,
3284                                                     transparent_pointers,
3285                                                     omit_empty_base_classes,
3286                                                     ignore_array_bounds,
3287                                                     child_name,
3288                                                     child_byte_size,
3289                                                     child_byte_offset,
3290                                                     child_bitfield_bit_size,
3291                                                     child_bitfield_bit_offset,
3292                                                     child_is_base_class,
3293                                                     tmp_child_is_deref_of_parent);
3294                }
3295                else
3296                {
3297                    if (parent_name)
3298                    {
3299                        child_name.assign(1, '&');
3300                        child_name += parent_name;
3301                    }
3302
3303                    // We have a pointer to an simple type
3304                    if (idx == 0)
3305                    {
3306                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
3307                        assert(clang_type_info.first % 8 == 0);
3308                        child_byte_size = clang_type_info.first / 8;
3309                        child_byte_offset = 0;
3310                        return pointee_type.getAsOpaquePtr();
3311                    }
3312                }
3313            }
3314            break;
3315
3316        case clang::Type::Typedef:
3317            return GetChildClangTypeAtIndex (exe_ctx,
3318                                             ast,
3319                                             parent_name,
3320                                             cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
3321                                             idx,
3322                                             transparent_pointers,
3323                                             omit_empty_base_classes,
3324                                             ignore_array_bounds,
3325                                             child_name,
3326                                             child_byte_size,
3327                                             child_byte_offset,
3328                                             child_bitfield_bit_size,
3329                                             child_bitfield_bit_offset,
3330                                             child_is_base_class,
3331                                             child_is_deref_of_parent);
3332            break;
3333
3334        case clang::Type::Elaborated:
3335            return GetChildClangTypeAtIndex (exe_ctx,
3336                                             ast,
3337                                             parent_name,
3338                                             cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
3339                                             idx,
3340                                             transparent_pointers,
3341                                             omit_empty_base_classes,
3342                                             ignore_array_bounds,
3343                                             child_name,
3344                                             child_byte_size,
3345                                             child_byte_offset,
3346                                             child_bitfield_bit_size,
3347                                             child_bitfield_bit_offset,
3348                                             child_is_base_class,
3349                                             child_is_deref_of_parent);
3350
3351        default:
3352            break;
3353        }
3354    }
3355    return NULL;
3356}
3357
3358static inline bool
3359BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
3360{
3361    return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
3362}
3363
3364static uint32_t
3365GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
3366{
3367    uint32_t num_bases = 0;
3368    if (cxx_record_decl)
3369    {
3370        if (omit_empty_base_classes)
3371        {
3372            CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3373            for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3374                 base_class != base_class_end;
3375                 ++base_class)
3376            {
3377                // Skip empty base classes
3378                if (omit_empty_base_classes)
3379                {
3380                    if (BaseSpecifierIsEmpty (base_class))
3381                        continue;
3382                }
3383                ++num_bases;
3384            }
3385        }
3386        else
3387            num_bases = cxx_record_decl->getNumBases();
3388    }
3389    return num_bases;
3390}
3391
3392
3393static uint32_t
3394GetIndexForRecordBase
3395(
3396    const RecordDecl *record_decl,
3397    const CXXBaseSpecifier *base_spec,
3398    bool omit_empty_base_classes
3399)
3400{
3401    uint32_t child_idx = 0;
3402
3403    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3404
3405//    const char *super_name = record_decl->getNameAsCString();
3406//    const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
3407//    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
3408//
3409    if (cxx_record_decl)
3410    {
3411        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3412        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3413             base_class != base_class_end;
3414             ++base_class)
3415        {
3416            if (omit_empty_base_classes)
3417            {
3418                if (BaseSpecifierIsEmpty (base_class))
3419                    continue;
3420            }
3421
3422//            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
3423//                    child_idx,
3424//                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
3425//
3426//
3427            if (base_class == base_spec)
3428                return child_idx;
3429            ++child_idx;
3430        }
3431    }
3432
3433    return UINT32_MAX;
3434}
3435
3436
3437static uint32_t
3438GetIndexForRecordChild
3439(
3440    const RecordDecl *record_decl,
3441    NamedDecl *canonical_decl,
3442    bool omit_empty_base_classes
3443)
3444{
3445    uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
3446
3447//    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3448//
3449////    printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
3450//    if (cxx_record_decl)
3451//    {
3452//        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3453//        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3454//             base_class != base_class_end;
3455//             ++base_class)
3456//        {
3457//            if (omit_empty_base_classes)
3458//            {
3459//                if (BaseSpecifierIsEmpty (base_class))
3460//                    continue;
3461//            }
3462//
3463////            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
3464////                    record_decl->getNameAsCString(),
3465////                    canonical_decl->getNameAsCString(),
3466////                    child_idx,
3467////                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
3468//
3469//
3470//            CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3471//            if (curr_base_class_decl == canonical_decl)
3472//            {
3473//                return child_idx;
3474//            }
3475//            ++child_idx;
3476//        }
3477//    }
3478//
3479//    const uint32_t num_bases = child_idx;
3480    RecordDecl::field_iterator field, field_end;
3481    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3482         field != field_end;
3483         ++field, ++child_idx)
3484    {
3485//            printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
3486//                    record_decl->getNameAsCString(),
3487//                    canonical_decl->getNameAsCString(),
3488//                    child_idx - num_bases,
3489//                    field->getNameAsCString());
3490
3491        if (field->getCanonicalDecl() == canonical_decl)
3492            return child_idx;
3493    }
3494
3495    return UINT32_MAX;
3496}
3497
3498// Look for a child member (doesn't include base classes, but it does include
3499// their members) in the type hierarchy. Returns an index path into "clang_type"
3500// on how to reach the appropriate member.
3501//
3502//    class A
3503//    {
3504//    public:
3505//        int m_a;
3506//        int m_b;
3507//    };
3508//
3509//    class B
3510//    {
3511//    };
3512//
3513//    class C :
3514//        public B,
3515//        public A
3516//    {
3517//    };
3518//
3519// If we have a clang type that describes "class C", and we wanted to looked
3520// "m_b" in it:
3521//
3522// With omit_empty_base_classes == false we would get an integer array back with:
3523// { 1,  1 }
3524// The first index 1 is the child index for "class A" within class C
3525// The second index 1 is the child index for "m_b" within class A
3526//
3527// With omit_empty_base_classes == true we would get an integer array back with:
3528// { 0,  1 }
3529// 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)
3530// The second index 1 is the child index for "m_b" within class A
3531
3532size_t
3533ClangASTContext::GetIndexOfChildMemberWithName
3534(
3535    ASTContext *ast,
3536    clang_type_t clang_type,
3537    const char *name,
3538    bool omit_empty_base_classes,
3539    std::vector<uint32_t>& child_indexes
3540)
3541{
3542    if (clang_type && name && name[0])
3543    {
3544        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
3545        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3546        switch (type_class)
3547        {
3548        case clang::Type::Record:
3549            if (GetCompleteQualType (ast, qual_type))
3550            {
3551                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3552                const RecordDecl *record_decl = record_type->getDecl();
3553
3554                assert(record_decl);
3555                uint32_t child_idx = 0;
3556
3557                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3558
3559                // Try and find a field that matches NAME
3560                RecordDecl::field_iterator field, field_end;
3561                StringRef name_sref(name);
3562                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3563                     field != field_end;
3564                     ++field, ++child_idx)
3565                {
3566                    if (field->getName().equals (name_sref))
3567                    {
3568                        // We have to add on the number of base classes to this index!
3569                        child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
3570                        return child_indexes.size();
3571                    }
3572                }
3573
3574                if (cxx_record_decl)
3575                {
3576                    const RecordDecl *parent_record_decl = cxx_record_decl;
3577
3578                    //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
3579
3580                    //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
3581                    // Didn't find things easily, lets let clang do its thang...
3582                    IdentifierInfo & ident_ref = ast->Idents.get(name_sref);
3583                    DeclarationName decl_name(&ident_ref);
3584
3585                    CXXBasePaths paths;
3586                    if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
3587                                                       decl_name.getAsOpaquePtr(),
3588                                                       paths))
3589                    {
3590                        CXXBasePaths::const_paths_iterator path, path_end = paths.end();
3591                        for (path = paths.begin(); path != path_end; ++path)
3592                        {
3593                            const size_t num_path_elements = path->size();
3594                            for (size_t e=0; e<num_path_elements; ++e)
3595                            {
3596                                CXXBasePathElement elem = (*path)[e];
3597
3598                                child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
3599                                if (child_idx == UINT32_MAX)
3600                                {
3601                                    child_indexes.clear();
3602                                    return 0;
3603                                }
3604                                else
3605                                {
3606                                    child_indexes.push_back (child_idx);
3607                                    parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
3608                                }
3609                            }
3610                            DeclContext::lookup_iterator named_decl_pos;
3611                            for (named_decl_pos = path->Decls.first;
3612                                 named_decl_pos != path->Decls.second && parent_record_decl;
3613                                 ++named_decl_pos)
3614                            {
3615                                //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
3616
3617                                child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
3618                                if (child_idx == UINT32_MAX)
3619                                {
3620                                    child_indexes.clear();
3621                                    return 0;
3622                                }
3623                                else
3624                                {
3625                                    child_indexes.push_back (child_idx);
3626                                }
3627                            }
3628                        }
3629                        return child_indexes.size();
3630                    }
3631                }
3632
3633            }
3634            break;
3635
3636        case clang::Type::ObjCObject:
3637        case clang::Type::ObjCInterface:
3638            if (GetCompleteQualType (ast, qual_type))
3639            {
3640                StringRef name_sref(name);
3641                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
3642                assert (objc_class_type);
3643                if (objc_class_type)
3644                {
3645                    uint32_t child_idx = 0;
3646                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3647
3648                    if (class_interface_decl)
3649                    {
3650                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3651                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3652
3653                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
3654                        {
3655                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
3656
3657                            if (ivar_decl->getName().equals (name_sref))
3658                            {
3659                                if ((!omit_empty_base_classes && superclass_interface_decl) ||
3660                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3661                                    ++child_idx;
3662
3663                                child_indexes.push_back (child_idx);
3664                                return child_indexes.size();
3665                            }
3666                        }
3667
3668                        if (superclass_interface_decl)
3669                        {
3670                            // The super class index is always zero for ObjC classes,
3671                            // so we push it onto the child indexes in case we find
3672                            // an ivar in our superclass...
3673                            child_indexes.push_back (0);
3674
3675                            if (GetIndexOfChildMemberWithName (ast,
3676                                                               ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
3677                                                               name,
3678                                                               omit_empty_base_classes,
3679                                                               child_indexes))
3680                            {
3681                                // We did find an ivar in a superclass so just
3682                                // return the results!
3683                                return child_indexes.size();
3684                            }
3685
3686                            // We didn't find an ivar matching "name" in our
3687                            // superclass, pop the superclass zero index that
3688                            // we pushed on above.
3689                            child_indexes.pop_back();
3690                        }
3691                    }
3692                }
3693            }
3694            break;
3695
3696        case clang::Type::ObjCObjectPointer:
3697            {
3698                return GetIndexOfChildMemberWithName (ast,
3699                                                      cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3700                                                      name,
3701                                                      omit_empty_base_classes,
3702                                                      child_indexes);
3703            }
3704            break;
3705
3706
3707        case clang::Type::ConstantArray:
3708            {
3709//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3710//                const uint64_t element_count = array->getSize().getLimitedValue();
3711//
3712//                if (idx < element_count)
3713//                {
3714//                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
3715//
3716//                    char element_name[32];
3717//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3718//
3719//                    child_name.assign(element_name);
3720//                    assert(field_type_info.first % 8 == 0);
3721//                    child_byte_size = field_type_info.first / 8;
3722//                    child_byte_offset = idx * child_byte_size;
3723//                    return array->getElementType().getAsOpaquePtr();
3724//                }
3725            }
3726            break;
3727
3728//        case clang::Type::MemberPointerType:
3729//            {
3730//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3731//                QualType pointee_type = mem_ptr_type->getPointeeType();
3732//
3733//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3734//                {
3735//                    return GetIndexOfChildWithName (ast,
3736//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3737//                                                    name);
3738//                }
3739//            }
3740//            break;
3741//
3742        case clang::Type::LValueReference:
3743        case clang::Type::RValueReference:
3744            {
3745                const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3746                QualType pointee_type = reference_type->getPointeeType();
3747
3748                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3749                {
3750                    return GetIndexOfChildMemberWithName (ast,
3751                                                          reference_type->getPointeeType().getAsOpaquePtr(),
3752                                                          name,
3753                                                          omit_empty_base_classes,
3754                                                          child_indexes);
3755                }
3756            }
3757            break;
3758
3759        case clang::Type::Pointer:
3760            {
3761                const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3762                QualType pointee_type = pointer_type->getPointeeType();
3763
3764                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3765                {
3766                    return GetIndexOfChildMemberWithName (ast,
3767                                                          pointer_type->getPointeeType().getAsOpaquePtr(),
3768                                                          name,
3769                                                          omit_empty_base_classes,
3770                                                          child_indexes);
3771                }
3772                else
3773                {
3774//                    if (parent_name)
3775//                    {
3776//                        child_name.assign(1, '*');
3777//                        child_name += parent_name;
3778//                    }
3779//
3780//                    // We have a pointer to an simple type
3781//                    if (idx == 0)
3782//                    {
3783//                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
3784//                        assert(clang_type_info.first % 8 == 0);
3785//                        child_byte_size = clang_type_info.first / 8;
3786//                        child_byte_offset = 0;
3787//                        return pointee_type.getAsOpaquePtr();
3788//                    }
3789                }
3790            }
3791            break;
3792
3793        case clang::Type::Typedef:
3794            return GetIndexOfChildMemberWithName (ast,
3795                                                  cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
3796                                                  name,
3797                                                  omit_empty_base_classes,
3798                                                  child_indexes);
3799
3800        default:
3801            break;
3802        }
3803    }
3804    return 0;
3805}
3806
3807
3808// Get the index of the child of "clang_type" whose name matches. This function
3809// doesn't descend into the children, but only looks one level deep and name
3810// matches can include base class names.
3811
3812uint32_t
3813ClangASTContext::GetIndexOfChildWithName
3814(
3815    ASTContext *ast,
3816    clang_type_t clang_type,
3817    const char *name,
3818    bool omit_empty_base_classes
3819)
3820{
3821    if (clang_type && name && name[0])
3822    {
3823        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
3824
3825        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3826
3827        switch (type_class)
3828        {
3829        case clang::Type::Record:
3830            if (GetCompleteQualType (ast, qual_type))
3831            {
3832                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3833                const RecordDecl *record_decl = record_type->getDecl();
3834
3835                assert(record_decl);
3836                uint32_t child_idx = 0;
3837
3838                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3839
3840                if (cxx_record_decl)
3841                {
3842                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3843                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3844                         base_class != base_class_end;
3845                         ++base_class)
3846                    {
3847                        // Skip empty base classes
3848                        CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3849                        if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3850                            continue;
3851
3852                        std::string base_class_type_name (ClangASTType::GetTypeNameForQualType(base_class->getType()));
3853                        if (base_class_type_name.compare (name) == 0)
3854                            return child_idx;
3855                        ++child_idx;
3856                    }
3857                }
3858
3859                // Try and find a field that matches NAME
3860                RecordDecl::field_iterator field, field_end;
3861                StringRef name_sref(name);
3862                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3863                     field != field_end;
3864                     ++field, ++child_idx)
3865                {
3866                    if (field->getName().equals (name_sref))
3867                        return child_idx;
3868                }
3869
3870            }
3871            break;
3872
3873        case clang::Type::ObjCObject:
3874        case clang::Type::ObjCInterface:
3875            if (GetCompleteQualType (ast, qual_type))
3876            {
3877                StringRef name_sref(name);
3878                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
3879                assert (objc_class_type);
3880                if (objc_class_type)
3881                {
3882                    uint32_t child_idx = 0;
3883                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3884
3885                    if (class_interface_decl)
3886                    {
3887                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3888                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3889
3890                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3891                        {
3892                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
3893
3894                            if (ivar_decl->getName().equals (name_sref))
3895                            {
3896                                if ((!omit_empty_base_classes && superclass_interface_decl) ||
3897                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3898                                    ++child_idx;
3899
3900                                return child_idx;
3901                            }
3902                        }
3903
3904                        if (superclass_interface_decl)
3905                        {
3906                            if (superclass_interface_decl->getName().equals (name_sref))
3907                                return 0;
3908                        }
3909                    }
3910                }
3911            }
3912            break;
3913
3914        case clang::Type::ObjCObjectPointer:
3915            {
3916                return GetIndexOfChildWithName (ast,
3917                                                cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3918                                                name,
3919                                                omit_empty_base_classes);
3920            }
3921            break;
3922
3923        case clang::Type::ConstantArray:
3924            {
3925//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3926//                const uint64_t element_count = array->getSize().getLimitedValue();
3927//
3928//                if (idx < element_count)
3929//                {
3930//                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
3931//
3932//                    char element_name[32];
3933//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3934//
3935//                    child_name.assign(element_name);
3936//                    assert(field_type_info.first % 8 == 0);
3937//                    child_byte_size = field_type_info.first / 8;
3938//                    child_byte_offset = idx * child_byte_size;
3939//                    return array->getElementType().getAsOpaquePtr();
3940//                }
3941            }
3942            break;
3943
3944//        case clang::Type::MemberPointerType:
3945//            {
3946//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3947//                QualType pointee_type = mem_ptr_type->getPointeeType();
3948//
3949//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3950//                {
3951//                    return GetIndexOfChildWithName (ast,
3952//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3953//                                                    name);
3954//                }
3955//            }
3956//            break;
3957//
3958        case clang::Type::LValueReference:
3959        case clang::Type::RValueReference:
3960            {
3961                const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3962                QualType pointee_type = reference_type->getPointeeType();
3963
3964                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3965                {
3966                    return GetIndexOfChildWithName (ast,
3967                                                    reference_type->getPointeeType().getAsOpaquePtr(),
3968                                                    name,
3969                                                    omit_empty_base_classes);
3970                }
3971            }
3972            break;
3973
3974        case clang::Type::Pointer:
3975            {
3976                const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3977                QualType pointee_type = pointer_type->getPointeeType();
3978
3979                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3980                {
3981                    return GetIndexOfChildWithName (ast,
3982                                                    pointer_type->getPointeeType().getAsOpaquePtr(),
3983                                                    name,
3984                                                    omit_empty_base_classes);
3985                }
3986                else
3987                {
3988//                    if (parent_name)
3989//                    {
3990//                        child_name.assign(1, '*');
3991//                        child_name += parent_name;
3992//                    }
3993//
3994//                    // We have a pointer to an simple type
3995//                    if (idx == 0)
3996//                    {
3997//                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
3998//                        assert(clang_type_info.first % 8 == 0);
3999//                        child_byte_size = clang_type_info.first / 8;
4000//                        child_byte_offset = 0;
4001//                        return pointee_type.getAsOpaquePtr();
4002//                    }
4003                }
4004            }
4005            break;
4006
4007        case clang::Type::Typedef:
4008            return GetIndexOfChildWithName (ast,
4009                                            cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
4010                                            name,
4011                                            omit_empty_base_classes);
4012
4013        default:
4014            break;
4015        }
4016    }
4017    return UINT32_MAX;
4018}
4019
4020#pragma mark TagType
4021
4022bool
4023ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
4024{
4025    if (tag_clang_type)
4026    {
4027        QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
4028        const clang::Type *clang_type = tag_qual_type.getTypePtr();
4029        if (clang_type)
4030        {
4031            const TagType *tag_type = dyn_cast<TagType>(clang_type);
4032            if (tag_type)
4033            {
4034                TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
4035                if (tag_decl)
4036                {
4037                    tag_decl->setTagKind ((TagDecl::TagKind)kind);
4038                    return true;
4039                }
4040            }
4041        }
4042    }
4043    return false;
4044}
4045
4046
4047#pragma mark DeclContext Functions
4048
4049DeclContext *
4050ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
4051{
4052    if (clang_type == NULL)
4053        return NULL;
4054
4055    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
4056    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4057    switch (type_class)
4058    {
4059    case clang::Type::UnaryTransform:           break;
4060    case clang::Type::FunctionNoProto:          break;
4061    case clang::Type::FunctionProto:            break;
4062    case clang::Type::IncompleteArray:          break;
4063    case clang::Type::VariableArray:            break;
4064    case clang::Type::ConstantArray:            break;
4065    case clang::Type::DependentSizedArray:      break;
4066    case clang::Type::ExtVector:                break;
4067    case clang::Type::DependentSizedExtVector:  break;
4068    case clang::Type::Vector:                   break;
4069    case clang::Type::Builtin:                  break;
4070    case clang::Type::BlockPointer:             break;
4071    case clang::Type::Pointer:                  break;
4072    case clang::Type::LValueReference:          break;
4073    case clang::Type::RValueReference:          break;
4074    case clang::Type::MemberPointer:            break;
4075    case clang::Type::Complex:                  break;
4076    case clang::Type::ObjCObject:               break;
4077    case clang::Type::ObjCInterface:            return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
4078    case clang::Type::ObjCObjectPointer:        return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
4079    case clang::Type::Record:                   return cast<RecordType>(qual_type)->getDecl();
4080    case clang::Type::Enum:                     return cast<EnumType>(qual_type)->getDecl();
4081    case clang::Type::Typedef:                  return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
4082    case clang::Type::Elaborated:               return ClangASTContext::GetDeclContextForType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
4083    case clang::Type::TypeOfExpr:               break;
4084    case clang::Type::TypeOf:                   break;
4085    case clang::Type::Decltype:                 break;
4086    //case clang::Type::QualifiedName:          break;
4087    case clang::Type::TemplateSpecialization:   break;
4088    case clang::Type::DependentTemplateSpecialization:  break;
4089    case clang::Type::TemplateTypeParm:         break;
4090    case clang::Type::SubstTemplateTypeParm:    break;
4091    case clang::Type::SubstTemplateTypeParmPack:break;
4092    case clang::Type::PackExpansion:            break;
4093    case clang::Type::UnresolvedUsing:          break;
4094    case clang::Type::Paren:                    break;
4095    case clang::Type::Attributed:               break;
4096    case clang::Type::Auto:                     break;
4097    case clang::Type::InjectedClassName:        break;
4098    case clang::Type::DependentName:            break;
4099    }
4100    // No DeclContext in this type...
4101    return NULL;
4102}
4103
4104#pragma mark Namespace Declarations
4105
4106NamespaceDecl *
4107ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
4108{
4109    // TODO: Do something intelligent with the Declaration object passed in
4110    // like maybe filling in the SourceLocation with it...
4111    if (name)
4112    {
4113        ASTContext *ast = getASTContext();
4114        if (decl_ctx == NULL)
4115            decl_ctx = ast->getTranslationUnitDecl();
4116        return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &ast->Idents.get(name));
4117    }
4118    return NULL;
4119}
4120
4121
4122#pragma mark Function Types
4123
4124FunctionDecl *
4125ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
4126{
4127    if (name)
4128    {
4129        ASTContext *ast = getASTContext();
4130        assert (ast != NULL);
4131
4132        if (name && name[0])
4133        {
4134            return FunctionDecl::Create(*ast,
4135                                        ast->getTranslationUnitDecl(),
4136                                        SourceLocation(),
4137                                        SourceLocation(),
4138                                        DeclarationName (&ast->Idents.get(name)),
4139                                        QualType::getFromOpaquePtr(function_clang_type),
4140                                        NULL,
4141                                        (FunctionDecl::StorageClass)storage,
4142                                        (FunctionDecl::StorageClass)storage,
4143                                        is_inline);
4144        }
4145        else
4146        {
4147            return FunctionDecl::Create(*ast,
4148                                        ast->getTranslationUnitDecl(),
4149                                        SourceLocation(),
4150                                        SourceLocation(),
4151                                        DeclarationName (),
4152                                        QualType::getFromOpaquePtr(function_clang_type),
4153                                        NULL,
4154                                        (FunctionDecl::StorageClass)storage,
4155                                        (FunctionDecl::StorageClass)storage,
4156                                        is_inline);
4157        }
4158    }
4159    return NULL;
4160}
4161
4162clang_type_t
4163ClangASTContext::CreateFunctionType (ASTContext *ast,
4164                                     clang_type_t result_type,
4165                                     clang_type_t *args,
4166                                     unsigned num_args,
4167                                     bool is_variadic,
4168                                     unsigned type_quals)
4169{
4170    assert (ast != NULL);
4171    std::vector<QualType> qual_type_args;
4172    for (unsigned i=0; i<num_args; ++i)
4173        qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
4174
4175    // TODO: Detect calling convention in DWARF?
4176    FunctionProtoType::ExtProtoInfo proto_info;
4177    proto_info.Variadic = is_variadic;
4178    proto_info.ExceptionSpecType = EST_None;
4179    proto_info.TypeQuals = type_quals;
4180    proto_info.RefQualifier = RQ_None;
4181    proto_info.NumExceptions = 0;
4182    proto_info.Exceptions = NULL;
4183
4184    return ast->getFunctionType(QualType::getFromOpaquePtr(result_type),
4185                                        qual_type_args.empty() ? NULL : &qual_type_args.front(),
4186                                        qual_type_args.size(),
4187                                        proto_info).getAsOpaquePtr();    // NoReturn);
4188}
4189
4190ParmVarDecl *
4191ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
4192{
4193    ASTContext *ast = getASTContext();
4194    assert (ast != NULL);
4195    return ParmVarDecl::Create(*ast,
4196                                ast->getTranslationUnitDecl(),
4197                                SourceLocation(),
4198                                SourceLocation(),
4199                                name && name[0] ? &ast->Idents.get(name) : NULL,
4200                                QualType::getFromOpaquePtr(param_type),
4201                                NULL,
4202                                (VarDecl::StorageClass)storage,
4203                                (VarDecl::StorageClass)storage,
4204                                0);
4205}
4206
4207void
4208ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
4209{
4210    if (function_decl)
4211        function_decl->setParams (params, num_params);
4212}
4213
4214
4215#pragma mark Array Types
4216
4217clang_type_t
4218ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
4219{
4220    if (element_type)
4221    {
4222        ASTContext *ast = getASTContext();
4223        assert (ast != NULL);
4224        llvm::APInt ap_element_count (64, element_count);
4225        return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
4226                                                 ap_element_count,
4227                                                 ArrayType::Normal,
4228                                                 0).getAsOpaquePtr(); // ElemQuals
4229    }
4230    return NULL;
4231}
4232
4233
4234#pragma mark TagDecl
4235
4236bool
4237ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
4238{
4239    if (clang_type)
4240    {
4241        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4242        const clang::Type *t = qual_type.getTypePtr();
4243        if (t)
4244        {
4245            const TagType *tag_type = dyn_cast<TagType>(t);
4246            if (tag_type)
4247            {
4248                TagDecl *tag_decl = tag_type->getDecl();
4249                if (tag_decl)
4250                {
4251                    tag_decl->startDefinition();
4252                    return true;
4253                }
4254            }
4255        }
4256    }
4257    return false;
4258}
4259
4260bool
4261ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
4262{
4263    if (clang_type)
4264    {
4265        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4266
4267        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4268
4269        if (cxx_record_decl)
4270        {
4271            cxx_record_decl->completeDefinition();
4272
4273            return true;
4274        }
4275
4276        const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
4277
4278        if (objc_class_type)
4279        {
4280            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
4281
4282            class_interface_decl->setForwardDecl(false);
4283        }
4284
4285        const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
4286
4287        if (enum_type)
4288        {
4289            EnumDecl *enum_decl = enum_type->getDecl();
4290
4291            if (enum_decl)
4292            {
4293                /// TODO This really needs to be fixed.
4294
4295                unsigned NumPositiveBits = 1;
4296                unsigned NumNegativeBits = 0;
4297
4298                ASTContext *ast = getASTContext();
4299
4300                QualType promotion_qual_type;
4301                // If the enum integer type is less than an integer in bit width,
4302                // then we must promote it to an integer size.
4303                if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
4304                {
4305                    if (enum_decl->getIntegerType()->isSignedIntegerType())
4306                        promotion_qual_type = ast->IntTy;
4307                    else
4308                        promotion_qual_type = ast->UnsignedIntTy;
4309                }
4310                else
4311                    promotion_qual_type = enum_decl->getIntegerType();
4312
4313                enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
4314                return true;
4315            }
4316        }
4317    }
4318    return false;
4319}
4320
4321
4322#pragma mark Enumeration Types
4323
4324clang_type_t
4325ClangASTContext::CreateEnumerationType
4326(
4327    const char *name,
4328    DeclContext *decl_ctx,
4329    const Declaration &decl,
4330    clang_type_t integer_qual_type
4331)
4332{
4333    // TODO: Do something intelligent with the Declaration object passed in
4334    // like maybe filling in the SourceLocation with it...
4335    ASTContext *ast = getASTContext();
4336    assert (ast != NULL);
4337
4338    // TODO: ask about these...
4339//    const bool IsScoped = false;
4340//    const bool IsFixed = false;
4341
4342    EnumDecl *enum_decl = EnumDecl::Create (*ast,
4343                                            decl_ctx,
4344                                            SourceLocation(),
4345                                            SourceLocation(),
4346                                            name && name[0] ? &ast->Idents.get(name) : NULL,
4347                                            NULL,
4348                                            false,  // IsScoped
4349                                            false,  // IsScopedUsingClassTag
4350                                            false); // IsFixed
4351
4352
4353    if (enum_decl)
4354    {
4355        // TODO: check if we should be setting the promotion type too?
4356        enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
4357
4358        enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
4359
4360        return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
4361    }
4362    return NULL;
4363}
4364
4365clang_type_t
4366ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
4367{
4368    QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
4369
4370    const clang::Type *clang_type = enum_qual_type.getTypePtr();
4371    if (clang_type)
4372    {
4373        const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
4374        if (enum_type)
4375        {
4376            EnumDecl *enum_decl = enum_type->getDecl();
4377            if (enum_decl)
4378                return enum_decl->getIntegerType().getAsOpaquePtr();
4379        }
4380    }
4381    return NULL;
4382}
4383bool
4384ClangASTContext::AddEnumerationValueToEnumerationType
4385(
4386    clang_type_t enum_clang_type,
4387    clang_type_t enumerator_clang_type,
4388    const Declaration &decl,
4389    const char *name,
4390    int64_t enum_value,
4391    uint32_t enum_value_bit_size
4392)
4393{
4394    if (enum_clang_type && enumerator_clang_type && name)
4395    {
4396        // TODO: Do something intelligent with the Declaration object passed in
4397        // like maybe filling in the SourceLocation with it...
4398        ASTContext *ast = getASTContext();
4399        IdentifierTable *identifier_table = getIdentifierTable();
4400
4401        assert (ast != NULL);
4402        assert (identifier_table != NULL);
4403        QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
4404
4405        const clang::Type *clang_type = enum_qual_type.getTypePtr();
4406        if (clang_type)
4407        {
4408            const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
4409
4410            if (enum_type)
4411            {
4412                llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
4413                enum_llvm_apsint = enum_value;
4414                EnumConstantDecl *enumerator_decl =
4415                    EnumConstantDecl::Create (*ast,
4416                                              enum_type->getDecl(),
4417                                              SourceLocation(),
4418                                              name ? &identifier_table->get(name) : NULL,    // Identifier
4419                                              QualType::getFromOpaquePtr(enumerator_clang_type),
4420                                              NULL,
4421                                              enum_llvm_apsint);
4422
4423                if (enumerator_decl)
4424                {
4425                    enum_type->getDecl()->addDecl(enumerator_decl);
4426                    return true;
4427                }
4428            }
4429        }
4430    }
4431    return false;
4432}
4433
4434#pragma mark Pointers & References
4435
4436clang_type_t
4437ClangASTContext::CreatePointerType (clang_type_t clang_type)
4438{
4439    return CreatePointerType (getASTContext(), clang_type);
4440}
4441
4442clang_type_t
4443ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
4444{
4445    if (ast && clang_type)
4446    {
4447        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4448
4449        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4450        switch (type_class)
4451        {
4452        case clang::Type::ObjCObject:
4453        case clang::Type::ObjCInterface:
4454            return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
4455
4456        default:
4457            return ast->getPointerType(qual_type).getAsOpaquePtr();
4458        }
4459    }
4460    return NULL;
4461}
4462
4463clang_type_t
4464ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
4465                                            clang_type_t clang_type)
4466{
4467    if (clang_type)
4468        return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
4469    return NULL;
4470}
4471
4472clang_type_t
4473ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
4474                                            clang_type_t clang_type)
4475{
4476    if (clang_type)
4477        return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
4478    return NULL;
4479}
4480
4481clang_type_t
4482ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
4483{
4484    if (clang_pointee_type && clang_pointee_type)
4485        return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
4486                                                     QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
4487    return NULL;
4488}
4489
4490uint32_t
4491ClangASTContext::GetPointerBitSize ()
4492{
4493    ASTContext *ast = getASTContext();
4494    return ast->getTypeSize(ast->VoidPtrTy);
4495}
4496
4497bool
4498ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
4499{
4500    QualType pointee_qual_type;
4501    if (clang_type)
4502    {
4503        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4504        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4505        bool success = false;
4506        switch (type_class)
4507        {
4508            case clang::Type::Builtin:
4509                if (cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
4510                {
4511                    if (dynamic_pointee_type)
4512                        *dynamic_pointee_type = clang_type;
4513                    return true;
4514                }
4515                break;
4516
4517            case clang::Type::ObjCObjectPointer:
4518                if (dynamic_pointee_type)
4519                    *dynamic_pointee_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4520                return true;
4521
4522            case clang::Type::Pointer:
4523                pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
4524                success = true;
4525                break;
4526
4527            case clang::Type::LValueReference:
4528            case clang::Type::RValueReference:
4529                pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
4530                success = true;
4531                break;
4532
4533            case clang::Type::Typedef:
4534                return ClangASTContext::IsPossibleDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
4535
4536            case clang::Type::Elaborated:
4537                return ClangASTContext::IsPossibleDynamicType (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), dynamic_pointee_type);
4538
4539            default:
4540                break;
4541        }
4542
4543        if (success)
4544        {
4545            // Check to make sure what we are pointing too is a possible dynamic C++ type
4546            // We currently accept any "void *" (in case we have a class that has been
4547            // watered down to an opaque pointer) and virtual C++ classes.
4548            const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
4549            switch (pointee_type_class)
4550            {
4551                case clang::Type::Builtin:
4552                    switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
4553                    {
4554                        case clang::BuiltinType::UnknownAny:
4555                        case clang::BuiltinType::Void:
4556                            if (dynamic_pointee_type)
4557                                *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4558                            return true;
4559
4560                        case clang::BuiltinType::NullPtr:
4561                        case clang::BuiltinType::Bool:
4562                        case clang::BuiltinType::Char_U:
4563                        case clang::BuiltinType::UChar:
4564                        case clang::BuiltinType::WChar_U:
4565                        case clang::BuiltinType::Char16:
4566                        case clang::BuiltinType::Char32:
4567                        case clang::BuiltinType::UShort:
4568                        case clang::BuiltinType::UInt:
4569                        case clang::BuiltinType::ULong:
4570                        case clang::BuiltinType::ULongLong:
4571                        case clang::BuiltinType::UInt128:
4572                        case clang::BuiltinType::Char_S:
4573                        case clang::BuiltinType::SChar:
4574                        case clang::BuiltinType::WChar_S:
4575                        case clang::BuiltinType::Short:
4576                        case clang::BuiltinType::Int:
4577                        case clang::BuiltinType::Long:
4578                        case clang::BuiltinType::LongLong:
4579                        case clang::BuiltinType::Int128:
4580                        case clang::BuiltinType::Float:
4581                        case clang::BuiltinType::Double:
4582                        case clang::BuiltinType::LongDouble:
4583                        case clang::BuiltinType::Dependent:
4584                        case clang::BuiltinType::Overload:
4585                        case clang::BuiltinType::ObjCId:
4586                        case clang::BuiltinType::ObjCClass:
4587                        case clang::BuiltinType::ObjCSel:
4588                        case clang::BuiltinType::BoundMember:
4589                            break;
4590                    }
4591                    break;
4592
4593                case clang::Type::Record:
4594                    {
4595                        CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
4596                        if (cxx_record_decl)
4597                        {
4598                            if (GetCompleteQualType (ast, pointee_qual_type))
4599                            {
4600                                success = cxx_record_decl->isDynamicClass();
4601                            }
4602                            else
4603                            {
4604                                // We failed to get the complete type, so we have to
4605                                // treat this as a void * which we might possibly be
4606                                // able to complete
4607                                success = true;
4608                            }
4609                            if (success)
4610                            {
4611                                if (dynamic_pointee_type)
4612                                    *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4613                                return true;
4614                            }
4615                        }
4616                    }
4617                    break;
4618
4619                case clang::Type::ObjCObject:
4620                case clang::Type::ObjCInterface:
4621                    {
4622                        const clang::ObjCObjectType *objc_class_type = pointee_qual_type->getAsObjCQualifiedInterfaceType();
4623                        if (objc_class_type)
4624                        {
4625                            GetCompleteQualType (ast, pointee_qual_type);
4626                            if (dynamic_pointee_type)
4627                                *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4628                            return true;
4629                        }
4630                    }
4631                    break;
4632
4633                default:
4634                    break;
4635            }
4636        }
4637    }
4638    if (dynamic_pointee_type)
4639        *dynamic_pointee_type = NULL;
4640    return false;
4641}
4642
4643
4644bool
4645ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
4646{
4647    QualType pointee_qual_type;
4648    if (clang_type)
4649    {
4650        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4651        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4652        bool success = false;
4653        switch (type_class)
4654        {
4655            case clang::Type::Pointer:
4656                pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
4657                success = true;
4658                break;
4659
4660            case clang::Type::LValueReference:
4661            case clang::Type::RValueReference:
4662                pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
4663                success = true;
4664                break;
4665
4666            case clang::Type::Typedef:
4667                return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
4668
4669            case clang::Type::Elaborated:
4670                return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
4671
4672            default:
4673                break;
4674        }
4675
4676        if (success)
4677        {
4678            // Check to make sure what we are pointing too is a possible dynamic C++ type
4679            // We currently accept any "void *" (in case we have a class that has been
4680            // watered down to an opaque pointer) and virtual C++ classes.
4681            const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
4682            switch (pointee_type_class)
4683            {
4684            case clang::Type::Builtin:
4685                switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
4686                {
4687                    case clang::BuiltinType::UnknownAny:
4688                    case clang::BuiltinType::Void:
4689                        if (dynamic_pointee_type)
4690                            *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4691                        return true;
4692
4693                    case clang::BuiltinType::NullPtr:
4694                    case clang::BuiltinType::Bool:
4695                    case clang::BuiltinType::Char_U:
4696                    case clang::BuiltinType::UChar:
4697                    case clang::BuiltinType::WChar_U:
4698                    case clang::BuiltinType::Char16:
4699                    case clang::BuiltinType::Char32:
4700                    case clang::BuiltinType::UShort:
4701                    case clang::BuiltinType::UInt:
4702                    case clang::BuiltinType::ULong:
4703                    case clang::BuiltinType::ULongLong:
4704                    case clang::BuiltinType::UInt128:
4705                    case clang::BuiltinType::Char_S:
4706                    case clang::BuiltinType::SChar:
4707                    case clang::BuiltinType::WChar_S:
4708                    case clang::BuiltinType::Short:
4709                    case clang::BuiltinType::Int:
4710                    case clang::BuiltinType::Long:
4711                    case clang::BuiltinType::LongLong:
4712                    case clang::BuiltinType::Int128:
4713                    case clang::BuiltinType::Float:
4714                    case clang::BuiltinType::Double:
4715                    case clang::BuiltinType::LongDouble:
4716                    case clang::BuiltinType::Dependent:
4717                    case clang::BuiltinType::Overload:
4718                    case clang::BuiltinType::ObjCId:
4719                    case clang::BuiltinType::ObjCClass:
4720                    case clang::BuiltinType::ObjCSel:
4721                    case clang::BuiltinType::BoundMember:
4722                        break;
4723                }
4724                break;
4725            case clang::Type::Record:
4726                {
4727                    CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
4728                    if (cxx_record_decl)
4729                    {
4730                        if (GetCompleteQualType (ast, pointee_qual_type))
4731                        {
4732                            success = cxx_record_decl->isDynamicClass();
4733                        }
4734                        else
4735                        {
4736                            // We failed to get the complete type, so we have to
4737                            // treat this as a void * which we might possibly be
4738                            // able to complete
4739                            success = true;
4740                        }
4741                        if (success)
4742                        {
4743                            if (dynamic_pointee_type)
4744                                *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
4745                            return true;
4746                        }
4747                    }
4748                }
4749                break;
4750
4751            default:
4752                break;
4753            }
4754        }
4755    }
4756    if (dynamic_pointee_type)
4757        *dynamic_pointee_type = NULL;
4758    return false;
4759}
4760
4761
4762bool
4763ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
4764{
4765    if (clang_type == NULL)
4766        return false;
4767
4768    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4769    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4770    switch (type_class)
4771    {
4772    case clang::Type::Builtin:
4773        switch (cast<clang::BuiltinType>(qual_type)->getKind())
4774        {
4775        default:
4776            break;
4777        case clang::BuiltinType::ObjCId:
4778        case clang::BuiltinType::ObjCClass:
4779            return true;
4780        }
4781        return false;
4782    case clang::Type::ObjCObjectPointer:
4783        if (target_type)
4784            *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4785        return true;
4786    case clang::Type::BlockPointer:
4787        if (target_type)
4788            *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4789        return true;
4790    case clang::Type::Pointer:
4791        if (target_type)
4792            *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4793        return true;
4794    case clang::Type::MemberPointer:
4795        if (target_type)
4796            *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4797        return true;
4798    case clang::Type::LValueReference:
4799        if (target_type)
4800            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4801        return true;
4802    case clang::Type::RValueReference:
4803        if (target_type)
4804            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
4805        return true;
4806    case clang::Type::Typedef:
4807        return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
4808    case clang::Type::Elaborated:
4809        return ClangASTContext::IsPointerOrReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
4810    default:
4811        break;
4812    }
4813    return false;
4814}
4815
4816bool
4817ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
4818{
4819    if (!clang_type)
4820        return false;
4821
4822    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4823    const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
4824
4825    if (builtin_type)
4826    {
4827        if (builtin_type->isInteger())
4828            is_signed = builtin_type->isSignedInteger();
4829
4830        return true;
4831    }
4832
4833    return false;
4834}
4835
4836bool
4837ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t *target_type)
4838{
4839    if (target_type)
4840        *target_type = NULL;
4841
4842    if (clang_type)
4843    {
4844        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4845        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4846        switch (type_class)
4847        {
4848        case clang::Type::Builtin:
4849            switch (cast<clang::BuiltinType>(qual_type)->getKind())
4850            {
4851            default:
4852                break;
4853            case clang::BuiltinType::ObjCId:
4854            case clang::BuiltinType::ObjCClass:
4855                return true;
4856            }
4857            return false;
4858        case clang::Type::ObjCObjectPointer:
4859            if (target_type)
4860                *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4861            return true;
4862        case clang::Type::BlockPointer:
4863            if (target_type)
4864                *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4865            return true;
4866        case clang::Type::Pointer:
4867            if (target_type)
4868                *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4869            return true;
4870        case clang::Type::MemberPointer:
4871            if (target_type)
4872                *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4873            return true;
4874        case clang::Type::Typedef:
4875            return ClangASTContext::IsPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
4876        case clang::Type::Elaborated:
4877            return ClangASTContext::IsPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), target_type);
4878        default:
4879            break;
4880        }
4881    }
4882    return false;
4883}
4884
4885bool
4886ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
4887{
4888    if (clang_type)
4889    {
4890        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4891
4892        if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
4893        {
4894            clang::BuiltinType::Kind kind = BT->getKind();
4895            if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
4896            {
4897                count = 1;
4898                is_complex = false;
4899                return true;
4900            }
4901        }
4902        else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
4903        {
4904            if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
4905            {
4906                count = 2;
4907                is_complex = true;
4908                return true;
4909            }
4910        }
4911        else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
4912        {
4913            if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
4914            {
4915                count = VT->getNumElements();
4916                is_complex = false;
4917                return true;
4918            }
4919        }
4920    }
4921    return false;
4922}
4923
4924bool
4925ClangASTContext::IsScalarType (lldb::clang_type_t clang_type)
4926{
4927    bool is_signed;
4928    if (ClangASTContext::IsIntegerType(clang_type, is_signed))
4929        return true;
4930
4931    uint32_t count;
4932    bool is_complex;
4933    return ClangASTContext::IsFloatingPointType(clang_type, count, is_complex) && !is_complex;
4934}
4935
4936bool
4937ClangASTContext::IsPointerToScalarType (lldb::clang_type_t clang_type)
4938{
4939    if (!IsPointerType(clang_type))
4940        return false;
4941
4942    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4943    lldb::clang_type_t pointee_type = qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
4944    return IsScalarType(pointee_type);
4945}
4946
4947bool
4948ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type)
4949{
4950    if (!IsArrayType(clang_type))
4951        return false;
4952
4953    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4954    lldb::clang_type_t item_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
4955    return IsScalarType(item_type);
4956}
4957
4958
4959bool
4960ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
4961{
4962    if (clang_type)
4963    {
4964        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4965
4966        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4967        if (cxx_record_decl)
4968        {
4969            class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
4970            return true;
4971        }
4972    }
4973    class_name.clear();
4974    return false;
4975}
4976
4977
4978bool
4979ClangASTContext::IsCXXClassType (clang_type_t clang_type)
4980{
4981    if (clang_type)
4982    {
4983        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4984        if (qual_type->getAsCXXRecordDecl() != NULL)
4985            return true;
4986    }
4987    return false;
4988}
4989
4990bool
4991ClangASTContext::IsObjCClassType (clang_type_t clang_type)
4992{
4993    if (clang_type)
4994    {
4995        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4996        if (qual_type->isObjCObjectOrInterfaceType())
4997            return true;
4998    }
4999    return false;
5000}
5001
5002
5003bool
5004ClangASTContext::IsCharType (clang_type_t clang_type)
5005{
5006    if (clang_type)
5007        return QualType::getFromOpaquePtr(clang_type)->isCharType();
5008    return false;
5009}
5010
5011bool
5012ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
5013{
5014    clang_type_t pointee_or_element_clang_type = NULL;
5015    Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
5016
5017    if (pointee_or_element_clang_type == NULL)
5018        return false;
5019
5020    if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
5021    {
5022        QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
5023
5024        if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
5025        {
5026            QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5027            if (type_flags.Test (eTypeIsArray))
5028            {
5029                // We know the size of the array and it could be a C string
5030                // since it is an array of characters
5031                length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
5032                return true;
5033            }
5034            else
5035            {
5036                length = 0;
5037                return true;
5038            }
5039
5040        }
5041    }
5042    return false;
5043}
5044
5045bool
5046ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
5047{
5048    if (clang_type)
5049    {
5050        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5051
5052        if (qual_type->isFunctionPointerType())
5053            return true;
5054
5055        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5056        switch (type_class)
5057        {
5058        default:
5059            break;
5060        case clang::Type::Typedef:
5061            return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
5062        case clang::Type::Elaborated:
5063            return ClangASTContext::IsFunctionPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
5064
5065        case clang::Type::LValueReference:
5066        case clang::Type::RValueReference:
5067            {
5068                const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
5069                if (reference_type)
5070                    return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
5071            }
5072            break;
5073        }
5074    }
5075    return false;
5076}
5077
5078size_t
5079ClangASTContext::GetArraySize (clang_type_t clang_type)
5080{
5081    if (clang_type)
5082    {
5083        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
5084        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5085        switch (type_class)
5086        {
5087        case clang::Type::ConstantArray:
5088            {
5089                const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
5090                if (array)
5091                    return array->getSize().getLimitedValue();
5092            }
5093            break;
5094
5095        case clang::Type::Typedef:
5096            return ClangASTContext::GetArraySize(cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
5097
5098        case clang::Type::Elaborated:
5099            return ClangASTContext::GetArraySize(cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
5100
5101        default:
5102            break;
5103        }
5104    }
5105    return 0;
5106}
5107
5108bool
5109ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
5110{
5111    if (!clang_type)
5112        return false;
5113
5114    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5115
5116    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5117    switch (type_class)
5118    {
5119    default:
5120        break;
5121
5122    case clang::Type::ConstantArray:
5123        if (member_type)
5124            *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5125        if (size)
5126            *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
5127        return true;
5128
5129    case clang::Type::IncompleteArray:
5130        if (member_type)
5131            *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5132        if (size)
5133            *size = 0;
5134        return true;
5135
5136    case clang::Type::VariableArray:
5137        if (member_type)
5138            *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5139        if (size)
5140            *size = 0;
5141        return true;
5142
5143    case clang::Type::DependentSizedArray:
5144        if (member_type)
5145            *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
5146        if (size)
5147            *size = 0;
5148        return true;
5149
5150    case clang::Type::Typedef:
5151        return ClangASTContext::IsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
5152                                             member_type,
5153                                             size);
5154
5155    case clang::Type::Elaborated:
5156        return ClangASTContext::IsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
5157                                             member_type,
5158                                             size);
5159    }
5160    return false;
5161}
5162
5163
5164#pragma mark Typedefs
5165
5166clang_type_t
5167ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
5168{
5169    if (clang_type)
5170    {
5171        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5172        ASTContext *ast = getASTContext();
5173        IdentifierTable *identifier_table = getIdentifierTable();
5174        assert (ast != NULL);
5175        assert (identifier_table != NULL);
5176        if (decl_ctx == NULL)
5177            decl_ctx = ast->getTranslationUnitDecl();
5178        TypedefDecl *decl = TypedefDecl::Create (*ast,
5179                                                 decl_ctx,
5180                                                 SourceLocation(),
5181                                                 SourceLocation(),
5182                                                 name ? &identifier_table->get(name) : NULL, // Identifier
5183                                                 ast->CreateTypeSourceInfo(qual_type));
5184
5185        decl->setAccess(AS_public); // TODO respect proper access specifier
5186
5187        // Get a uniqued QualType for the typedef decl type
5188        return ast->getTypedefType (decl).getAsOpaquePtr();
5189    }
5190    return NULL;
5191}
5192
5193// Disable this for now since I can't seem to get a nicely formatted float
5194// out of the APFloat class without just getting the float, double or quad
5195// and then using a formatted print on it which defeats the purpose. We ideally
5196// would like to get perfect string values for any kind of float semantics
5197// so we can support remote targets. The code below also requires a patch to
5198// llvm::APInt.
5199//bool
5200//ClangASTContext::ConvertFloatValueToString (ASTContext *ast, clang_type_t clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
5201//{
5202//  uint32_t count = 0;
5203//  bool is_complex = false;
5204//  if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
5205//  {
5206//      unsigned num_bytes_per_float = byte_size / count;
5207//      unsigned num_bits_per_float = num_bytes_per_float * 8;
5208//
5209//      float_str.clear();
5210//      uint32_t i;
5211//      for (i=0; i<count; i++)
5212//      {
5213//          APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
5214//          bool is_ieee = false;
5215//          APFloat ap_float(ap_int, is_ieee);
5216//          char s[1024];
5217//          unsigned int hex_digits = 0;
5218//          bool upper_case = false;
5219//
5220//          if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
5221//          {
5222//              if (i > 0)
5223//                  float_str.append(", ");
5224//              float_str.append(s);
5225//              if (i == 1 && is_complex)
5226//                  float_str.append(1, 'i');
5227//          }
5228//      }
5229//      return !float_str.empty();
5230//  }
5231//  return false;
5232//}
5233
5234size_t
5235ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
5236{
5237    if (clang_type)
5238    {
5239        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5240        uint32_t count = 0;
5241        bool is_complex = false;
5242        if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
5243        {
5244            // TODO: handle complex and vector types
5245            if (count != 1)
5246                return false;
5247
5248            StringRef s_sref(s);
5249            APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
5250
5251            const uint64_t bit_size = ast->getTypeSize (qual_type);
5252            const uint64_t byte_size = bit_size / 8;
5253            if (dst_size >= byte_size)
5254            {
5255                if (bit_size == sizeof(float)*8)
5256                {
5257                    float float32 = ap_float.convertToFloat();
5258                    ::memcpy (dst, &float32, byte_size);
5259                    return byte_size;
5260                }
5261                else if (bit_size >= 64)
5262                {
5263                    llvm::APInt ap_int(ap_float.bitcastToAPInt());
5264                    ::memcpy (dst, ap_int.getRawData(), byte_size);
5265                    return byte_size;
5266                }
5267            }
5268        }
5269    }
5270    return 0;
5271}
5272
5273unsigned
5274ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
5275{
5276    assert (clang_type);
5277
5278    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
5279
5280    return qual_type.getQualifiers().getCVRQualifiers();
5281}
5282
5283bool
5284ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
5285{
5286    if (clang_type == NULL)
5287        return false;
5288
5289    return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
5290}
5291
5292
5293bool
5294ClangASTContext::GetCompleteType (clang_type_t clang_type)
5295{
5296    return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
5297}
5298
5299bool
5300ClangASTContext::GetCompleteDecl (clang::ASTContext *ast,
5301                                  clang::Decl *decl)
5302{
5303    if (!decl)
5304        return false;
5305
5306    ExternalASTSource *ast_source = ast->getExternalSource();
5307
5308    if (!ast_source)
5309        return false;
5310
5311    if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
5312    {
5313        if (tag_decl->getDefinition())
5314            return true;
5315
5316        if (!tag_decl->hasExternalLexicalStorage())
5317            return false;
5318
5319        ast_source->CompleteType(tag_decl);
5320
5321        return !tag_decl->getTypeForDecl()->isIncompleteType();
5322    }
5323    else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
5324    {
5325        if (!objc_interface_decl->isForwardDecl())
5326            return true;
5327
5328        if (!objc_interface_decl->hasExternalLexicalStorage())
5329            return false;
5330
5331        ast_source->CompleteType(objc_interface_decl);
5332
5333        return !objc_interface_decl->isForwardDecl();
5334    }
5335    else
5336    {
5337        return false;
5338    }
5339}
5340
5341clang::DeclContext *
5342ClangASTContext::GetAsDeclContext (clang::CXXMethodDecl *cxx_method_decl)
5343{
5344    return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
5345}
5346
5347clang::DeclContext *
5348ClangASTContext::GetAsDeclContext (clang::ObjCMethodDecl *objc_method_decl)
5349{
5350    return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
5351}
5352
5353