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