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