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