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