ClangASTContext.cpp revision e9d0df45df0ee87623985d1e59947a2ca50c14ea
1e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch//
3e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch//                     The LLVM Compiler Infrastructure
4e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch//
5e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// This file is distributed under the University of Illinois Open Source
6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// License. See LICENSE.TXT for details.
7e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch//
8e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch//===----------------------------------------------------------------------===//
9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
10e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "lldb/Symbol/ClangASTContext.h"
11e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
12e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// C Includes
13e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// C++ Includes
14e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include <string>
15e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Other libraries and framework includes
17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/AST/ASTContext.h"
18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/AST/ASTImporter.h"
19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/AST/CXXInheritance.h"
20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/AST/RecordLayout.h"
21e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/AST/Type.h"
22e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/Basic/Builtins.h"
23e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/Basic/FileManager.h"
24e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/Basic/SourceManager.h"
25e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/Basic/TargetInfo.h"
26e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/Basic/TargetOptions.h"
27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/Frontend/FrontendOptions.h"
28e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "clang/Frontend/LangStandard.h"
29e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
30e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Project includes
31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "lldb/Core/dwarf.h"
32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
33e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include <stdio.h>
34e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochusing namespace lldb_private;
36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochusing namespace llvm;
37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochusing namespace clang;
38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
39e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochstatic void
41e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochParseLangArgs
42e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch(
43e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    LangOptions &Opts,
44e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    InputKind IK
45e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch)
46e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch{
47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // FIXME: Cleanup per-file based stuff.
48
49    // Set some properties which depend soley on the input kind; it would be nice
50    // to move these to the language standard, and have the driver resolve the
51    // input kind + language standard.
52    if (IK == IK_Asm) {
53        Opts.AsmPreprocessor = 1;
54    } else if (IK == IK_ObjC ||
55               IK == IK_ObjCXX ||
56               IK == IK_PreprocessedObjC ||
57               IK == IK_PreprocessedObjCXX) {
58        Opts.ObjC1 = Opts.ObjC2 = 1;
59    }
60
61    LangStandard::Kind LangStd = LangStandard::lang_unspecified;
62
63    if (LangStd == LangStandard::lang_unspecified) {
64        // Based on the base language, pick one.
65        switch (IK) {
66            case IK_None:
67            case IK_AST:
68                assert(0 && "Invalid input kind!");
69            case IK_OpenCL:
70                LangStd = LangStandard::lang_opencl;
71                break;
72            case IK_Asm:
73            case IK_C:
74            case IK_PreprocessedC:
75            case IK_ObjC:
76            case IK_PreprocessedObjC:
77                LangStd = LangStandard::lang_gnu99;
78                break;
79            case IK_CXX:
80            case IK_PreprocessedCXX:
81            case IK_ObjCXX:
82            case IK_PreprocessedObjCXX:
83                LangStd = LangStandard::lang_gnucxx98;
84                break;
85        }
86    }
87
88    const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
89    Opts.BCPLComment = Std.hasBCPLComments();
90    Opts.C99 = Std.isC99();
91    Opts.CPlusPlus = Std.isCPlusPlus();
92    Opts.CPlusPlus0x = Std.isCPlusPlus0x();
93    Opts.Digraphs = Std.hasDigraphs();
94    Opts.GNUMode = Std.isGNUMode();
95    Opts.GNUInline = !Std.isC99();
96    Opts.HexFloats = Std.hasHexFloats();
97    Opts.ImplicitInt = Std.hasImplicitInt();
98
99    // OpenCL has some additional defaults.
100    if (LangStd == LangStandard::lang_opencl) {
101        Opts.OpenCL = 1;
102        Opts.AltiVec = 1;
103        Opts.CXXOperatorNames = 1;
104        Opts.LaxVectorConversions = 1;
105    }
106
107    // OpenCL and C++ both have bool, true, false keywords.
108    Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
109
110//    if (Opts.CPlusPlus)
111//        Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
112//
113//    if (Args.hasArg(OPT_fobjc_gc_only))
114//        Opts.setGCMode(LangOptions::GCOnly);
115//    else if (Args.hasArg(OPT_fobjc_gc))
116//        Opts.setGCMode(LangOptions::HybridGC);
117//
118//    if (Args.hasArg(OPT_print_ivar_layout))
119//        Opts.ObjCGCBitmapPrint = 1;
120//
121//    if (Args.hasArg(OPT_faltivec))
122//        Opts.AltiVec = 1;
123//
124//    if (Args.hasArg(OPT_pthread))
125//        Opts.POSIXThreads = 1;
126//
127//    llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
128//                                          "default");
129//    if (Vis == "default")
130        Opts.setVisibilityMode(LangOptions::Default);
131//    else if (Vis == "hidden")
132//        Opts.setVisibilityMode(LangOptions::Hidden);
133//    else if (Vis == "protected")
134//        Opts.setVisibilityMode(LangOptions::Protected);
135//    else
136//        Diags.Report(diag::err_drv_invalid_value)
137//        << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
138
139//    Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
140
141    // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
142    // is specified, or -std is set to a conforming mode.
143    Opts.Trigraphs = !Opts.GNUMode;
144//    if (Args.hasArg(OPT_trigraphs))
145//        Opts.Trigraphs = 1;
146//
147//    Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
148//                                     OPT_fno_dollars_in_identifiers,
149//                                     !Opts.AsmPreprocessor);
150//    Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
151//    Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
152//    Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
153//    if (Args.hasArg(OPT_fno_lax_vector_conversions))
154//        Opts.LaxVectorConversions = 0;
155//    Opts.Exceptions = Args.hasArg(OPT_fexceptions);
156//    Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
157//    Opts.Blocks = Args.hasArg(OPT_fblocks);
158//    Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
159//    Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
160//    Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
161//    Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
162//    Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
163//    Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
164//    Opts.AccessControl = Args.hasArg(OPT_faccess_control);
165//    Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
166//    Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
167//    Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
168//                                                 Diags);
169//    Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
170//    Opts.ObjCConstantStringClass = getLastArgValue(Args,
171//                                                   OPT_fconstant_string_class);
172//    Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
173//    Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
174//    Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
175//    Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
176//    Opts.Static = Args.hasArg(OPT_static_define);
177    Opts.OptimizeSize = 0;
178
179    // FIXME: Eliminate this dependency.
180//    unsigned Opt =
181//    Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
182//    Opts.Optimize = Opt != 0;
183    unsigned Opt = 0;
184
185    // This is the __NO_INLINE__ define, which just depends on things like the
186    // optimization level and -fno-inline, not actually whether the backend has
187    // inlining enabled.
188    //
189    // FIXME: This is affected by other options (-fno-inline).
190    Opts.NoInline = !Opt;
191
192//    unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
193//    switch (SSP) {
194//        default:
195//            Diags.Report(diag::err_drv_invalid_value)
196//            << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
197//            break;
198//        case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
199//        case 1: Opts.setStackProtectorMode(LangOptions::SSPOn);  break;
200//        case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
201//    }
202}
203
204
205ClangASTContext::ClangASTContext(const char *target_triple) :
206    m_target_triple(),
207    m_ast_context_ap(),
208    m_language_options_ap(),
209    m_source_manager_ap(),
210    m_diagnostic_ap(),
211    m_target_options_ap(),
212    m_target_info_ap(),
213    m_identifier_table_ap(),
214    m_selector_table_ap(),
215    m_builtins_ap()
216{
217    if (target_triple && target_triple[0])
218        m_target_triple.assign (target_triple);
219}
220
221//----------------------------------------------------------------------
222// Destructor
223//----------------------------------------------------------------------
224ClangASTContext::~ClangASTContext()
225{
226    m_builtins_ap.reset();
227    m_selector_table_ap.reset();
228    m_identifier_table_ap.reset();
229    m_target_info_ap.reset();
230    m_target_options_ap.reset();
231    m_diagnostic_ap.reset();
232    m_source_manager_ap.reset();
233    m_language_options_ap.reset();
234    m_ast_context_ap.reset();
235}
236
237
238void
239ClangASTContext::Clear()
240{
241    m_ast_context_ap.reset();
242    m_language_options_ap.reset();
243    m_source_manager_ap.reset();
244    m_diagnostic_ap.reset();
245    m_target_options_ap.reset();
246    m_target_info_ap.reset();
247    m_identifier_table_ap.reset();
248    m_selector_table_ap.reset();
249    m_builtins_ap.reset();
250}
251
252const char *
253ClangASTContext::GetTargetTriple ()
254{
255    return m_target_triple.c_str();
256}
257
258void
259ClangASTContext::SetTargetTriple (const char *target_triple)
260{
261    Clear();
262    m_target_triple.assign(target_triple);
263}
264
265
266ASTContext *
267ClangASTContext::getASTContext()
268{
269    if (m_ast_context_ap.get() == NULL)
270    {
271        m_ast_context_ap.reset(
272            new ASTContext(
273                *getLanguageOptions(),
274                *getSourceManager(),
275                *getTargetInfo(),
276                *getIdentifierTable(),
277                *getSelectorTable(),
278                *getBuiltinContext()));
279    }
280    return m_ast_context_ap.get();
281}
282
283Builtin::Context *
284ClangASTContext::getBuiltinContext()
285{
286    if (m_builtins_ap.get() == NULL)
287        m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
288    return m_builtins_ap.get();
289}
290
291IdentifierTable *
292ClangASTContext::getIdentifierTable()
293{
294    if (m_identifier_table_ap.get() == NULL)
295        m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
296    return m_identifier_table_ap.get();
297}
298
299LangOptions *
300ClangASTContext::getLanguageOptions()
301{
302    if (m_language_options_ap.get() == NULL)
303    {
304        m_language_options_ap.reset(new LangOptions());
305        ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
306//        InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
307    }
308    return m_language_options_ap.get();
309}
310
311SelectorTable *
312ClangASTContext::getSelectorTable()
313{
314    if (m_selector_table_ap.get() == NULL)
315        m_selector_table_ap.reset (new SelectorTable());
316    return m_selector_table_ap.get();
317}
318
319SourceManager *
320ClangASTContext::getSourceManager()
321{
322    if (m_source_manager_ap.get() == NULL)
323        m_source_manager_ap.reset(new SourceManager(*getDiagnostic()));
324    return m_source_manager_ap.get();
325}
326
327Diagnostic *
328ClangASTContext::getDiagnostic()
329{
330    if (m_diagnostic_ap.get() == NULL)
331        m_diagnostic_ap.reset(new Diagnostic());
332    return m_diagnostic_ap.get();
333}
334
335TargetOptions *
336ClangASTContext::getTargetOptions()
337{
338    if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
339    {
340        m_target_options_ap.reset (new TargetOptions());
341        if (m_target_options_ap.get())
342            m_target_options_ap->Triple = m_target_triple;
343    }
344    return m_target_options_ap.get();
345}
346
347
348TargetInfo *
349ClangASTContext::getTargetInfo()
350{
351    // target_triple should be something like "x86_64-apple-darwin10"
352    if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
353        m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
354    return m_target_info_ap.get();
355}
356
357#pragma mark Basic Types
358
359static inline bool
360QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
361{
362    uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
363    if (qual_type_bit_size == bit_size)
364        return true;
365    return false;
366}
367
368void *
369ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding, uint32_t bit_size)
370{
371    ASTContext *ast_context = getASTContext();
372
373    assert (ast_context != NULL);
374
375    return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
376}
377
378void *
379ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast_context, lldb::Encoding encoding, uint32_t bit_size)
380{
381    if (!ast_context)
382        return NULL;
383
384    switch (encoding)
385    {
386    case lldb::eEncodingInvalid:
387        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
388            return ast_context->VoidPtrTy.getAsOpaquePtr();
389        break;
390
391    case lldb::eEncodingUint:
392        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
393            return ast_context->UnsignedCharTy.getAsOpaquePtr();
394        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
395            return ast_context->UnsignedShortTy.getAsOpaquePtr();
396        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
397            return ast_context->UnsignedIntTy.getAsOpaquePtr();
398        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
399            return ast_context->UnsignedLongTy.getAsOpaquePtr();
400        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
401            return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
402        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
403            return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
404        break;
405
406    case lldb::eEncodingSint:
407        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
408            return ast_context->CharTy.getAsOpaquePtr();
409        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
410            return ast_context->ShortTy.getAsOpaquePtr();
411        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
412            return ast_context->IntTy.getAsOpaquePtr();
413        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
414            return ast_context->LongTy.getAsOpaquePtr();
415        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
416            return ast_context->LongLongTy.getAsOpaquePtr();
417        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
418            return ast_context->Int128Ty.getAsOpaquePtr();
419        break;
420
421    case lldb::eEncodingIEEE754:
422        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
423            return ast_context->FloatTy.getAsOpaquePtr();
424        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
425            return ast_context->DoubleTy.getAsOpaquePtr();
426        if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
427            return ast_context->LongDoubleTy.getAsOpaquePtr();
428        break;
429
430    case lldb::eEncodingVector:
431    default:
432        break;
433    }
434
435    return NULL;
436}
437
438void *
439ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
440{
441    ASTContext *ast_context = getASTContext();
442
443    #define streq(a,b) strcmp(a,b) == 0
444    assert (ast_context != NULL);
445    if (ast_context)
446    {
447        switch (dw_ate)
448        {
449        default:
450            break;
451
452        case DW_ATE_address:
453            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
454                return ast_context->VoidPtrTy.getAsOpaquePtr();
455            break;
456
457        case DW_ATE_boolean:
458            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
459                return ast_context->BoolTy.getAsOpaquePtr();
460            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
461                return ast_context->UnsignedCharTy.getAsOpaquePtr();
462            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
463                return ast_context->UnsignedShortTy.getAsOpaquePtr();
464            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
465                return ast_context->UnsignedIntTy.getAsOpaquePtr();
466            break;
467
468        case DW_ATE_complex_float:
469            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
470                return ast_context->FloatComplexTy.getAsOpaquePtr();
471            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
472                return ast_context->DoubleComplexTy.getAsOpaquePtr();
473            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
474                return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
475            break;
476
477        case DW_ATE_float:
478            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
479                return ast_context->FloatTy.getAsOpaquePtr();
480            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
481                return ast_context->DoubleTy.getAsOpaquePtr();
482            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
483                return ast_context->LongDoubleTy.getAsOpaquePtr();
484            break;
485
486        case DW_ATE_signed:
487            if (type_name)
488            {
489                if (streq(type_name, "int") ||
490                    streq(type_name, "signed int"))
491                {
492                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
493                        return ast_context->IntTy.getAsOpaquePtr();
494                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
495                        return ast_context->Int128Ty.getAsOpaquePtr();
496                }
497
498                if (streq(type_name, "long int") ||
499                    streq(type_name, "long long int") ||
500                    streq(type_name, "signed long long"))
501                {
502                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
503                        return ast_context->LongTy.getAsOpaquePtr();
504                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
505                        return ast_context->LongLongTy.getAsOpaquePtr();
506                }
507
508                if (streq(type_name, "short") ||
509                    streq(type_name, "short int") ||
510                    streq(type_name, "signed short") ||
511                    streq(type_name, "short signed int"))
512                {
513                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
514                        return ast_context->ShortTy.getAsOpaquePtr();
515                }
516
517                if (streq(type_name, "char") ||
518                    streq(type_name, "signed char"))
519                {
520                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
521                        return ast_context->CharTy.getAsOpaquePtr();
522                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
523                        return ast_context->SignedCharTy.getAsOpaquePtr();
524                }
525
526                if (streq(type_name, "wchar_t"))
527                {
528                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
529                        return ast_context->WCharTy.getAsOpaquePtr();
530                }
531
532            }
533            // We weren't able to match up a type name, just search by size
534            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
535                return ast_context->CharTy.getAsOpaquePtr();
536            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
537                return ast_context->ShortTy.getAsOpaquePtr();
538            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
539                return ast_context->IntTy.getAsOpaquePtr();
540            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
541                return ast_context->LongTy.getAsOpaquePtr();
542            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
543                return ast_context->LongLongTy.getAsOpaquePtr();
544            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
545                return ast_context->Int128Ty.getAsOpaquePtr();
546            break;
547
548        case DW_ATE_signed_char:
549            if (type_name)
550            {
551                if (streq(type_name, "signed char"))
552                {
553                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
554                        return ast_context->SignedCharTy.getAsOpaquePtr();
555                }
556            }
557            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
558                return ast_context->CharTy.getAsOpaquePtr();
559            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
560                return ast_context->SignedCharTy.getAsOpaquePtr();
561            break;
562
563        case DW_ATE_unsigned:
564            if (type_name)
565            {
566                if (streq(type_name, "unsigned int"))
567                {
568                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
569                        return ast_context->UnsignedIntTy.getAsOpaquePtr();
570                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
571                        return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
572                }
573
574                if (streq(type_name, "unsigned int") ||
575                    streq(type_name, "long unsigned int") ||
576                    streq(type_name, "unsigned long long"))
577                {
578                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
579                        return ast_context->UnsignedLongTy.getAsOpaquePtr();
580                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
581                        return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
582                }
583
584                if (streq(type_name, "unsigned short") ||
585                    streq(type_name, "short unsigned int"))
586                {
587                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
588                        return ast_context->UnsignedShortTy.getAsOpaquePtr();
589                }
590                if (streq(type_name, "unsigned char"))
591                {
592                    if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
593                        return ast_context->UnsignedCharTy.getAsOpaquePtr();
594                }
595
596            }
597            // We weren't able to match up a type name, just search by size
598            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
599                return ast_context->UnsignedCharTy.getAsOpaquePtr();
600            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
601                return ast_context->UnsignedShortTy.getAsOpaquePtr();
602            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
603                return ast_context->UnsignedIntTy.getAsOpaquePtr();
604            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
605                return ast_context->UnsignedLongTy.getAsOpaquePtr();
606            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
607                return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
608            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
609                return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
610            break;
611
612        case DW_ATE_unsigned_char:
613            if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
614                return ast_context->UnsignedCharTy.getAsOpaquePtr();
615            break;
616
617        case DW_ATE_imaginary_float:
618            break;
619        }
620    }
621    // This assert should fire for anything that we don't catch above so we know
622    // to fix any issues we run into.
623    assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
624    return NULL;
625}
626
627void *
628ClangASTContext::GetVoidBuiltInType()
629{
630    return getASTContext()->VoidTy.getAsOpaquePtr();
631}
632
633void *
634ClangASTContext::GetCStringType (bool is_const)
635{
636    QualType char_type(getASTContext()->CharTy);
637
638    if (is_const)
639        char_type.addConst();
640
641    return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
642}
643
644void *
645ClangASTContext::GetVoidPtrType (bool is_const)
646{
647    return GetVoidPtrType(getASTContext(), is_const);
648}
649
650void *
651ClangASTContext::GetVoidPtrType (clang::ASTContext *ast_context, bool is_const)
652{
653    QualType void_ptr_type(ast_context->VoidPtrTy);
654
655    if (is_const)
656        void_ptr_type.addConst();
657
658    return void_ptr_type.getAsOpaquePtr();
659}
660
661void *
662ClangASTContext::CopyType(clang::ASTContext *dest_context,
663                          clang::ASTContext *source_context,
664                          void * clang_type)
665{
666    Diagnostic diagnostics;
667    FileManager file_manager;
668    ASTImporter importer(diagnostics,
669                         *dest_context, file_manager,
670                         *source_context, file_manager);
671    QualType ret = importer.Import(QualType::getFromOpaquePtr(clang_type));
672    return ret.getAsOpaquePtr();
673}
674
675#pragma mark CVR modifiers
676
677void *
678ClangASTContext::AddConstModifier (void *clang_type)
679{
680    if (clang_type)
681    {
682        QualType result(QualType::getFromOpaquePtr(clang_type));
683        result.addConst();
684        return result.getAsOpaquePtr();
685    }
686    return NULL;
687}
688
689void *
690ClangASTContext::AddRestrictModifier (void *clang_type)
691{
692    if (clang_type)
693    {
694        QualType result(QualType::getFromOpaquePtr(clang_type));
695        result.getQualifiers().setRestrict (true);
696        return result.getAsOpaquePtr();
697    }
698    return NULL;
699}
700
701void *
702ClangASTContext::AddVolatileModifier (void *clang_type)
703{
704    if (clang_type)
705    {
706        QualType result(QualType::getFromOpaquePtr(clang_type));
707        result.getQualifiers().setVolatile (true);
708        return result.getAsOpaquePtr();
709    }
710    return NULL;
711}
712
713#pragma mark Structure, Unions, Classes
714
715void *
716ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx)
717{
718    ASTContext *ast_context = getASTContext();
719    assert (ast_context != NULL);
720
721    if (decl_ctx == NULL)
722        decl_ctx = ast_context->getTranslationUnitDecl();
723
724    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
725    // we will need to update this code. I was told to currently always use
726    // the CXXRecordDecl class since we often don't know from debug information
727    // if something is struct or a class, so we default to always use the more
728    // complete definition just in case.
729    CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
730                                                (TagDecl::TagKind)kind,
731                                                decl_ctx,
732                                                SourceLocation(),
733                                                name && name[0] ? &ast_context->Idents.get(name) : NULL);
734
735    return ast_context->getTagDeclType(decl).getAsOpaquePtr();
736}
737
738bool
739ClangASTContext::AddFieldToRecordType (void * record_clang_type, const char *name, void * field_type, int access, uint32_t bitfield_bit_size)
740{
741    if (record_clang_type == NULL || field_type == NULL)
742        return false;
743
744    ASTContext *ast_context = getASTContext();
745    IdentifierTable *identifier_table = getIdentifierTable();
746
747    assert (ast_context != NULL);
748    assert (identifier_table != NULL);
749
750    QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
751
752    Type *clang_type = record_qual_type.getTypePtr();
753    if (clang_type)
754    {
755        const RecordType *record_type = dyn_cast<RecordType>(clang_type);
756
757        if (record_type)
758        {
759            RecordDecl *record_decl = record_type->getDecl();
760
761            CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
762            if (cxx_record_decl)
763                cxx_record_decl->setEmpty (false);
764
765            clang::Expr *bit_width = NULL;
766            if (bitfield_bit_size != 0)
767            {
768                APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
769                bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
770            }
771            FieldDecl *field = FieldDecl::Create(*ast_context,
772                                                record_decl,
773                                                SourceLocation(),
774                                                name ? &identifier_table->get(name) : NULL, // Identifier
775                                                QualType::getFromOpaquePtr(field_type), // Field type
776                                                NULL,       // DeclaratorInfo *
777                                                bit_width,  // BitWidth
778                                                false);     // Mutable
779
780            field->setAccess((AccessSpecifier)access);
781
782            if (field)
783            {
784                record_decl->addDecl(field);
785                return true;
786            }
787        }
788    }
789    return false;
790}
791
792bool
793ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
794{
795    return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
796}
797
798bool
799ClangASTContext::FieldIsBitfield
800(
801    ASTContext *ast_context,
802    FieldDecl* field,
803    uint32_t& bitfield_bit_size
804)
805{
806    if (ast_context == NULL || field == NULL)
807        return false;
808
809    if (field->isBitField())
810    {
811        Expr* bit_width_expr = field->getBitWidth();
812        if (bit_width_expr)
813        {
814            llvm::APSInt bit_width_apsint;
815            if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
816            {
817                bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
818                return true;
819            }
820        }
821    }
822    return false;
823}
824
825bool
826ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
827{
828    if (record_decl == NULL)
829        return false;
830
831    if (!record_decl->field_empty())
832        return true;
833
834    // No fields, lets check this is a CXX record and check the base classes
835    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
836    if (cxx_record_decl)
837    {
838        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
839        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
840             base_class != base_class_end;
841             ++base_class)
842        {
843            const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
844            if (RecordHasFields(base_class_decl))
845                return true;
846        }
847    }
848    return false;
849}
850
851void
852ClangASTContext::SetDefaultAccessForRecordFields (void *clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
853{
854    if (clang_qual_type)
855    {
856        QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
857        Type *clang_type = qual_type.getTypePtr();
858        if (clang_type)
859        {
860            RecordType *record_type = dyn_cast<RecordType>(clang_type);
861            if (record_type)
862            {
863                RecordDecl *record_decl = record_type->getDecl();
864                if (record_decl)
865                {
866                    uint32_t field_idx;
867                    RecordDecl::field_iterator field, field_end;
868                    for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
869                         field != field_end;
870                         ++field, ++field_idx)
871                    {
872                        // If no accessibility was assigned, assign the correct one
873                        if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
874                            field->setAccess ((AccessSpecifier)default_accessibility);
875                    }
876                }
877            }
878        }
879    }
880}
881
882#pragma mark C++ Base Classes
883
884CXXBaseSpecifier *
885ClangASTContext::CreateBaseClassSpecifier (void *base_class_type, int access, bool is_virtual, bool base_of_class)
886{
887    if (base_class_type)
888        return new CXXBaseSpecifier(SourceRange(), is_virtual, base_of_class, (AccessSpecifier)access, QualType::getFromOpaquePtr(base_class_type));
889    return NULL;
890}
891
892void
893ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
894{
895    for (unsigned i=0; i<num_base_classes; ++i)
896    {
897        delete base_classes[i];
898        base_classes[i] = NULL;
899    }
900}
901
902bool
903ClangASTContext::SetBaseClassesForClassType (void *class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
904{
905    if (class_clang_type)
906    {
907        ASTContext *ast_context = getASTContext();
908        IdentifierTable *identifier_table = getIdentifierTable();
909
910        assert (ast_context != NULL);
911        assert (identifier_table != NULL);
912
913        Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
914        if (clang_type)
915        {
916            RecordType *record_type = dyn_cast<RecordType>(clang_type);
917            if (record_type)
918            {
919                CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
920                if (cxx_record_decl)
921                {
922                    //cxx_record_decl->setEmpty (false);
923                    cxx_record_decl->setBases(base_classes, num_base_classes);
924                    return true;
925                }
926            }
927        }
928    }
929    return false;
930}
931
932
933#pragma mark Aggregate Types
934
935bool
936ClangASTContext::IsAggregateType (void *clang_type)
937{
938    if (clang_type == NULL)
939        return false;
940
941    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
942
943    if (qual_type->isAggregateType ())
944        return true;
945
946    switch (qual_type->getTypeClass())
947    {
948    case Type::IncompleteArray:
949    case Type::VariableArray:
950    case Type::ConstantArray:
951    case Type::ExtVector:
952    case Type::Vector:
953    case Type::Record:
954        return true;
955
956    case Type::Typedef:
957        return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
958
959    default:
960        break;
961    }
962    // The clang type does have a value
963    return false;
964}
965
966uint32_t
967ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_classes)
968{
969    if (clang_qual_type == NULL)
970        return 0;
971
972    uint32_t num_children = 0;
973    QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
974    switch (qual_type->getTypeClass())
975    {
976    case Type::Record:
977        {
978            const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
979            const RecordDecl *record_decl = record_type->getDecl();
980            assert(record_decl);
981            const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
982            if (cxx_record_decl)
983            {
984                if (omit_empty_base_classes)
985                {
986                    // Check each base classes to see if it or any of its
987                    // base classes contain any fields. This can help
988                    // limit the noise in variable views by not having to
989                    // show base classes that contain no members.
990                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
991                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
992                         base_class != base_class_end;
993                         ++base_class)
994                    {
995                        const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
996
997                        // Skip empty base classes
998                        if (RecordHasFields(base_class_decl) == false)
999                            continue;
1000
1001                        num_children++;
1002                    }
1003                }
1004                else
1005                {
1006                    // Include all base classes
1007                    num_children += cxx_record_decl->getNumBases();
1008                }
1009
1010            }
1011            RecordDecl::field_iterator field, field_end;
1012            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1013                ++num_children;
1014        }
1015        break;
1016
1017    case Type::ConstantArray:
1018        num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1019        break;
1020
1021    case Type::Pointer:
1022        {
1023            PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1024            QualType pointee_type = pointer_type->getPointeeType();
1025            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), omit_empty_base_classes);
1026            // If this type points to a simple type, then it has 1 child
1027            if (num_pointee_children == 0)
1028                num_children = 1;
1029            else
1030                num_children = num_pointee_children;
1031        }
1032        break;
1033
1034    case Type::Typedef:
1035        num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1036        break;
1037
1038    default:
1039        break;
1040    }
1041    return num_children;
1042}
1043
1044
1045void *
1046ClangASTContext::GetChildClangTypeAtIndex
1047(
1048    const char *parent_name,
1049    void *parent_clang_type,
1050    uint32_t idx,
1051    bool transparent_pointers,
1052    bool omit_empty_base_classes,
1053    std::string& child_name,
1054    uint32_t &child_byte_size,
1055    int32_t &child_byte_offset,
1056    uint32_t &child_bitfield_bit_size,
1057    uint32_t &child_bitfield_bit_offset
1058)
1059{
1060    if (parent_clang_type)
1061
1062        return GetChildClangTypeAtIndex (getASTContext(),
1063                                         parent_name,
1064                                         parent_clang_type,
1065                                         idx,
1066                                         transparent_pointers,
1067                                         omit_empty_base_classes,
1068                                         child_name,
1069                                         child_byte_size,
1070                                         child_byte_offset,
1071                                         child_bitfield_bit_size,
1072                                         child_bitfield_bit_offset);
1073    return NULL;
1074}
1075
1076void *
1077ClangASTContext::GetChildClangTypeAtIndex
1078(
1079    ASTContext *ast_context,
1080    const char *parent_name,
1081    void *parent_clang_type,
1082    uint32_t idx,
1083    bool transparent_pointers,
1084    bool omit_empty_base_classes,
1085    std::string& child_name,
1086    uint32_t &child_byte_size,
1087    int32_t &child_byte_offset,
1088    uint32_t &child_bitfield_bit_size,
1089    uint32_t &child_bitfield_bit_offset
1090)
1091{
1092    if (parent_clang_type == NULL)
1093        return NULL;
1094
1095    if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
1096    {
1097        uint32_t bit_offset;
1098        child_bitfield_bit_size = 0;
1099        child_bitfield_bit_offset = 0;
1100        QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
1101        switch (parent_qual_type->getTypeClass())
1102        {
1103        case Type::Record:
1104            {
1105                const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
1106                const RecordDecl *record_decl = record_type->getDecl();
1107                assert(record_decl);
1108                const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
1109                uint32_t child_idx = 0;
1110
1111                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1112                if (cxx_record_decl)
1113                {
1114                    // We might have base classes to print out first
1115                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1116                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1117                         base_class != base_class_end;
1118                         ++base_class)
1119                    {
1120                        const CXXRecordDecl *base_class_decl = NULL;
1121
1122                        // Skip empty base classes
1123                        if (omit_empty_base_classes)
1124                        {
1125                            base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1126                            if (RecordHasFields(base_class_decl) == false)
1127                                continue;
1128                        }
1129
1130                        if (idx == child_idx)
1131                        {
1132                            if (base_class_decl == NULL)
1133                                base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1134
1135
1136                            if (base_class->isVirtual())
1137                                bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
1138                            else
1139                                bit_offset = record_layout.getBaseClassOffset(base_class_decl);
1140
1141                            // Base classes should be a multiple of 8 bits in size
1142                            assert (bit_offset % 8 == 0);
1143                            child_byte_offset = bit_offset/8;
1144                            std::string base_class_type_name(base_class->getType().getAsString());
1145
1146                            child_name.assign(base_class_type_name.c_str());
1147
1148                            uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
1149
1150                            // Base classes biut sizes should be a multiple of 8 bits in size
1151                            assert (clang_type_info_bit_size % 8 == 0);
1152                            child_byte_size = clang_type_info_bit_size / 8;
1153                            return base_class->getType().getAsOpaquePtr();
1154                        }
1155                        // We don't increment the child index in the for loop since we might
1156                        // be skipping empty base classes
1157                        ++child_idx;
1158                    }
1159                }
1160                const unsigned num_fields = record_layout.getFieldCount();
1161
1162                // Make sure index is in range...
1163                uint32_t field_idx = 0;
1164                RecordDecl::field_iterator field, field_end;
1165                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
1166                {
1167                    if (idx == child_idx)
1168                    {
1169                        // Print the member type if requested
1170                        // Print the member name and equal sign
1171                        child_name.assign(field->getNameAsString().c_str());
1172
1173                        // Figure out the type byte size (field_type_info.first) and
1174                        // alignment (field_type_info.second) from the AST context.
1175                        std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
1176                        assert(field_idx < num_fields);
1177
1178                        child_byte_size = field_type_info.first / 8;
1179
1180                        // Figure out the field offset within the current struct/union/class type
1181                        bit_offset = record_layout.getFieldOffset (field_idx);
1182                        child_byte_offset = bit_offset / 8;
1183                        if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
1184                            child_bitfield_bit_offset = bit_offset % 8;
1185
1186                        return field->getType().getAsOpaquePtr();
1187                    }
1188                }
1189            }
1190            break;
1191
1192        case Type::ConstantArray:
1193            {
1194                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1195                const uint64_t element_count = array->getSize().getLimitedValue();
1196
1197                if (idx < element_count)
1198                {
1199                    std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1200
1201                    char element_name[32];
1202                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1203
1204                    child_name.assign(element_name);
1205                    assert(field_type_info.first % 8 == 0);
1206                    child_byte_size = field_type_info.first / 8;
1207                    child_byte_offset = idx * child_byte_size;
1208                    return array->getElementType().getAsOpaquePtr();
1209                }
1210            }
1211            break;
1212
1213        case Type::Pointer:
1214            {
1215                PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
1216                QualType pointee_type = pointer_type->getPointeeType();
1217
1218                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1219                {
1220                    return GetChildClangTypeAtIndex (ast_context,
1221                                                     parent_name,
1222                                                     pointer_type->getPointeeType().getAsOpaquePtr(),
1223                                                     idx,
1224                                                     transparent_pointers,
1225                                                     omit_empty_base_classes,
1226                                                     child_name,
1227                                                     child_byte_size,
1228                                                     child_byte_offset,
1229                                                     child_bitfield_bit_size,
1230                                                     child_bitfield_bit_offset);
1231                }
1232                else
1233                {
1234                    if (parent_name)
1235                    {
1236                        child_name.assign(1, '*');
1237                        child_name += parent_name;
1238                    }
1239
1240                    // We have a pointer to an simple type
1241                    if (idx == 0)
1242                    {
1243                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1244                        assert(clang_type_info.first % 8 == 0);
1245                        child_byte_size = clang_type_info.first / 8;
1246                        child_byte_offset = 0;
1247                        return pointee_type.getAsOpaquePtr();
1248                    }
1249                }
1250            }
1251            break;
1252
1253        case Type::Typedef:
1254            return GetChildClangTypeAtIndex (ast_context,
1255                                             parent_name,
1256                                             cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1257                                             idx,
1258                                             transparent_pointers,
1259                                             omit_empty_base_classes,
1260                                             child_name,
1261                                             child_byte_size,
1262                                             child_byte_offset,
1263                                             child_bitfield_bit_size,
1264                                             child_bitfield_bit_offset);
1265            break;
1266
1267        default:
1268            break;
1269        }
1270    }
1271    return false;
1272}
1273
1274static inline bool
1275BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
1276{
1277    return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
1278}
1279
1280static uint32_t
1281GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
1282{
1283    uint32_t num_bases = 0;
1284    if (cxx_record_decl)
1285    {
1286        if (omit_empty_base_classes)
1287        {
1288            CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1289            for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1290                 base_class != base_class_end;
1291                 ++base_class)
1292            {
1293                // Skip empty base classes
1294                if (omit_empty_base_classes)
1295                {
1296                    if (BaseSpecifierIsEmpty (base_class))
1297                        continue;
1298                }
1299                ++num_bases;
1300            }
1301        }
1302        else
1303            num_bases = cxx_record_decl->getNumBases();
1304    }
1305    return num_bases;
1306}
1307
1308
1309static uint32_t
1310GetIndexForRecordBase
1311(
1312    const RecordDecl *record_decl,
1313    const CXXBaseSpecifier *base_spec,
1314    bool omit_empty_base_classes
1315)
1316{
1317    uint32_t child_idx = 0;
1318
1319    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1320
1321//    const char *super_name = record_decl->getNameAsCString();
1322//    const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
1323//    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
1324//
1325    if (cxx_record_decl)
1326    {
1327        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1328        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1329             base_class != base_class_end;
1330             ++base_class)
1331        {
1332            if (omit_empty_base_classes)
1333            {
1334                if (BaseSpecifierIsEmpty (base_class))
1335                    continue;
1336            }
1337
1338//            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
1339//                    child_idx,
1340//                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1341//
1342//
1343            if (base_class == base_spec)
1344                return child_idx;
1345            ++child_idx;
1346        }
1347    }
1348
1349    return UINT32_MAX;
1350}
1351
1352
1353static uint32_t
1354GetIndexForRecordChild
1355(
1356    const RecordDecl *record_decl,
1357    NamedDecl *canonical_decl,
1358    bool omit_empty_base_classes
1359)
1360{
1361    uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
1362
1363//    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1364//
1365////    printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
1366//    if (cxx_record_decl)
1367//    {
1368//        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1369//        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1370//             base_class != base_class_end;
1371//             ++base_class)
1372//        {
1373//            if (omit_empty_base_classes)
1374//            {
1375//                if (BaseSpecifierIsEmpty (base_class))
1376//                    continue;
1377//            }
1378//
1379////            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
1380////                    record_decl->getNameAsCString(),
1381////                    canonical_decl->getNameAsCString(),
1382////                    child_idx,
1383////                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1384//
1385//
1386//            CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1387//            if (curr_base_class_decl == canonical_decl)
1388//            {
1389//                return child_idx;
1390//            }
1391//            ++child_idx;
1392//        }
1393//    }
1394//
1395//    const uint32_t num_bases = child_idx;
1396    RecordDecl::field_iterator field, field_end;
1397    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1398         field != field_end;
1399         ++field, ++child_idx)
1400    {
1401//            printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
1402//                    record_decl->getNameAsCString(),
1403//                    canonical_decl->getNameAsCString(),
1404//                    child_idx - num_bases,
1405//                    field->getNameAsCString());
1406
1407        if (field->getCanonicalDecl() == canonical_decl)
1408            return child_idx;
1409    }
1410
1411    return UINT32_MAX;
1412}
1413
1414// Look for a child member (doesn't include base classes, but it does include
1415// their members) in the type hierarchy. Returns an index path into "clang_type"
1416// on how to reach the appropriate member.
1417//
1418//    class A
1419//    {
1420//    public:
1421//        int m_a;
1422//        int m_b;
1423//    };
1424//
1425//    class B
1426//    {
1427//    };
1428//
1429//    class C :
1430//        public B,
1431//        public A
1432//    {
1433//    };
1434//
1435// If we have a clang type that describes "class C", and we wanted to looked
1436// "m_b" in it:
1437//
1438// With omit_empty_base_classes == false we would get an integer array back with:
1439// { 1,  1 }
1440// The first index 1 is the child index for "class A" within class C
1441// The second index 1 is the child index for "m_b" within class A
1442//
1443// With omit_empty_base_classes == true we would get an integer array back with:
1444// { 0,  1 }
1445// 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)
1446// The second index 1 is the child index for "m_b" within class A
1447
1448size_t
1449ClangASTContext::GetIndexOfChildMemberWithName
1450(
1451    ASTContext *ast_context,
1452    void *clang_type,
1453    const char *name,
1454    bool omit_empty_base_classes,
1455    std::vector<uint32_t>& child_indexes
1456)
1457{
1458    if (clang_type && name && name[0])
1459    {
1460        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1461        switch (qual_type->getTypeClass())
1462        {
1463        case Type::Record:
1464            {
1465                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1466                const RecordDecl *record_decl = record_type->getDecl();
1467
1468                assert(record_decl);
1469                uint32_t child_idx = 0;
1470
1471                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1472
1473                // Try and find a field that matches NAME
1474                RecordDecl::field_iterator field, field_end;
1475                StringRef name_sref(name);
1476                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1477                     field != field_end;
1478                     ++field, ++child_idx)
1479                {
1480                    if (field->getName().equals (name_sref))
1481                    {
1482                        // We have to add on the number of base classes to this index!
1483                        child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
1484                        return child_indexes.size();
1485                    }
1486                }
1487
1488                if (cxx_record_decl)
1489                {
1490                    const RecordDecl *parent_record_decl = cxx_record_decl;
1491
1492                    //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
1493
1494                    //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
1495                    // Didn't find things easily, lets let clang do its thang...
1496                    IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
1497                    DeclarationName decl_name(&ident_ref);
1498
1499                    CXXBasePaths paths;
1500                    if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
1501                                                       decl_name.getAsOpaquePtr(),
1502                                                       paths))
1503                    {
1504                        uint32_t child_idx;
1505                        CXXBasePaths::const_paths_iterator path, path_end = paths.end();
1506                        for (path = paths.begin(); path != path_end; ++path)
1507                        {
1508                            const size_t num_path_elements = path->size();
1509                            for (size_t e=0; e<num_path_elements; ++e)
1510                            {
1511                                CXXBasePathElement elem = (*path)[e];
1512
1513                                child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
1514                                if (child_idx == UINT32_MAX)
1515                                {
1516                                    child_indexes.clear();
1517                                    return 0;
1518                                }
1519                                else
1520                                {
1521                                    child_indexes.push_back (child_idx);
1522                                    parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
1523                                }
1524                            }
1525                            DeclContext::lookup_iterator named_decl_pos;
1526                            for (named_decl_pos = path->Decls.first;
1527                                 named_decl_pos != path->Decls.second && parent_record_decl;
1528                                 ++named_decl_pos)
1529                            {
1530                                //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
1531
1532                                child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
1533                                if (child_idx == UINT32_MAX)
1534                                {
1535                                    child_indexes.clear();
1536                                    return 0;
1537                                }
1538                                else
1539                                {
1540                                    child_indexes.push_back (child_idx);
1541                                }
1542                            }
1543                        }
1544                        return child_indexes.size();
1545                    }
1546                }
1547
1548            }
1549            break;
1550
1551        case Type::ConstantArray:
1552            {
1553//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1554//                const uint64_t element_count = array->getSize().getLimitedValue();
1555//
1556//                if (idx < element_count)
1557//                {
1558//                    std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1559//
1560//                    char element_name[32];
1561//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1562//
1563//                    child_name.assign(element_name);
1564//                    assert(field_type_info.first % 8 == 0);
1565//                    child_byte_size = field_type_info.first / 8;
1566//                    child_byte_offset = idx * child_byte_size;
1567//                    return array->getElementType().getAsOpaquePtr();
1568//                }
1569            }
1570            break;
1571
1572//        case Type::MemberPointerType:
1573//            {
1574//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
1575//                QualType pointee_type = mem_ptr_type->getPointeeType();
1576//
1577//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1578//                {
1579//                    return GetIndexOfChildWithName (ast_context,
1580//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
1581//                                                    name);
1582//                }
1583//            }
1584//            break;
1585//
1586        case Type::LValueReference:
1587        case Type::RValueReference:
1588            {
1589                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1590                QualType pointee_type = reference_type->getPointeeType();
1591
1592                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1593                {
1594                    return GetIndexOfChildMemberWithName (ast_context,
1595                                                          reference_type->getPointeeType().getAsOpaquePtr(),
1596                                                          name,
1597                                                          omit_empty_base_classes,
1598                                                          child_indexes);
1599                }
1600            }
1601            break;
1602
1603        case Type::Pointer:
1604            {
1605                PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1606                QualType pointee_type = pointer_type->getPointeeType();
1607
1608                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1609                {
1610                    return GetIndexOfChildMemberWithName (ast_context,
1611                                                          pointer_type->getPointeeType().getAsOpaquePtr(),
1612                                                          name,
1613                                                          omit_empty_base_classes,
1614                                                          child_indexes);
1615                }
1616                else
1617                {
1618//                    if (parent_name)
1619//                    {
1620//                        child_name.assign(1, '*');
1621//                        child_name += parent_name;
1622//                    }
1623//
1624//                    // We have a pointer to an simple type
1625//                    if (idx == 0)
1626//                    {
1627//                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1628//                        assert(clang_type_info.first % 8 == 0);
1629//                        child_byte_size = clang_type_info.first / 8;
1630//                        child_byte_offset = 0;
1631//                        return pointee_type.getAsOpaquePtr();
1632//                    }
1633                }
1634            }
1635            break;
1636
1637        case Type::Typedef:
1638            return GetIndexOfChildMemberWithName (ast_context,
1639                                                  cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1640                                                  name,
1641                                                  omit_empty_base_classes,
1642                                                  child_indexes);
1643
1644        default:
1645            break;
1646        }
1647    }
1648    return 0;
1649}
1650
1651
1652// Get the index of the child of "clang_type" whose name matches. This function
1653// doesn't descend into the children, but only looks one level deep and name
1654// matches can include base class names.
1655
1656uint32_t
1657ClangASTContext::GetIndexOfChildWithName
1658(
1659    ASTContext *ast_context,
1660    void *clang_type,
1661    const char *name,
1662    bool omit_empty_base_classes
1663)
1664{
1665    if (clang_type && name && name[0])
1666    {
1667        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1668        switch (qual_type->getTypeClass())
1669        {
1670        case Type::Record:
1671            {
1672                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1673                const RecordDecl *record_decl = record_type->getDecl();
1674
1675                assert(record_decl);
1676                uint32_t child_idx = 0;
1677
1678                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1679
1680                if (cxx_record_decl)
1681                {
1682                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1683                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1684                         base_class != base_class_end;
1685                         ++base_class)
1686                    {
1687                        // Skip empty base classes
1688                        CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1689                        if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
1690                            continue;
1691
1692                        if (base_class->getType().getAsString().compare (name) == 0)
1693                            return child_idx;
1694                        ++child_idx;
1695                    }
1696                }
1697
1698                // Try and find a field that matches NAME
1699                RecordDecl::field_iterator field, field_end;
1700                StringRef name_sref(name);
1701                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1702                     field != field_end;
1703                     ++field, ++child_idx)
1704                {
1705                    if (field->getName().equals (name_sref))
1706                        return child_idx;
1707                }
1708
1709            }
1710            break;
1711
1712        case Type::ConstantArray:
1713            {
1714//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1715//                const uint64_t element_count = array->getSize().getLimitedValue();
1716//
1717//                if (idx < element_count)
1718//                {
1719//                    std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1720//
1721//                    char element_name[32];
1722//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1723//
1724//                    child_name.assign(element_name);
1725//                    assert(field_type_info.first % 8 == 0);
1726//                    child_byte_size = field_type_info.first / 8;
1727//                    child_byte_offset = idx * child_byte_size;
1728//                    return array->getElementType().getAsOpaquePtr();
1729//                }
1730            }
1731            break;
1732
1733//        case Type::MemberPointerType:
1734//            {
1735//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
1736//                QualType pointee_type = mem_ptr_type->getPointeeType();
1737//
1738//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1739//                {
1740//                    return GetIndexOfChildWithName (ast_context,
1741//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
1742//                                                    name);
1743//                }
1744//            }
1745//            break;
1746//
1747        case Type::LValueReference:
1748        case Type::RValueReference:
1749            {
1750                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1751                QualType pointee_type = reference_type->getPointeeType();
1752
1753                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1754                {
1755                    return GetIndexOfChildWithName (ast_context,
1756                                                    reference_type->getPointeeType().getAsOpaquePtr(),
1757                                                    name,
1758                                                    omit_empty_base_classes);
1759                }
1760            }
1761            break;
1762
1763        case Type::Pointer:
1764            {
1765                PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1766                QualType pointee_type = pointer_type->getPointeeType();
1767
1768                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1769                {
1770                    return GetIndexOfChildWithName (ast_context,
1771                                                    pointer_type->getPointeeType().getAsOpaquePtr(),
1772                                                    name,
1773                                                    omit_empty_base_classes);
1774                }
1775                else
1776                {
1777//                    if (parent_name)
1778//                    {
1779//                        child_name.assign(1, '*');
1780//                        child_name += parent_name;
1781//                    }
1782//
1783//                    // We have a pointer to an simple type
1784//                    if (idx == 0)
1785//                    {
1786//                        std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1787//                        assert(clang_type_info.first % 8 == 0);
1788//                        child_byte_size = clang_type_info.first / 8;
1789//                        child_byte_offset = 0;
1790//                        return pointee_type.getAsOpaquePtr();
1791//                    }
1792                }
1793            }
1794            break;
1795
1796        case Type::Typedef:
1797            return GetIndexOfChildWithName (ast_context,
1798                                            cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1799                                            name,
1800                                            omit_empty_base_classes);
1801
1802        default:
1803            break;
1804        }
1805    }
1806    return UINT32_MAX;
1807}
1808
1809#pragma mark TagType
1810
1811bool
1812ClangASTContext::SetTagTypeKind (void *tag_clang_type, int kind)
1813{
1814    if (tag_clang_type)
1815    {
1816        QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
1817        Type *clang_type = tag_qual_type.getTypePtr();
1818        if (clang_type)
1819        {
1820            TagType *tag_type = dyn_cast<TagType>(clang_type);
1821            if (tag_type)
1822            {
1823                TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
1824                if (tag_decl)
1825                {
1826                    tag_decl->setTagKind ((TagDecl::TagKind)kind);
1827                    return true;
1828                }
1829            }
1830        }
1831    }
1832    return false;
1833}
1834
1835
1836#pragma mark DeclContext Functions
1837
1838DeclContext *
1839ClangASTContext::GetDeclContextForType (void *clang_type)
1840{
1841    if (clang_type == NULL)
1842        return NULL;
1843
1844    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1845    switch (qual_type->getTypeClass())
1846    {
1847    case Type::FunctionNoProto:         break;
1848    case Type::FunctionProto:           break;
1849    case Type::IncompleteArray:         break;
1850    case Type::VariableArray:           break;
1851    case Type::ConstantArray:           break;
1852    case Type::ExtVector:               break;
1853    case Type::Vector:                  break;
1854    case Type::Builtin:                 break;
1855    case Type::ObjCObjectPointer:       break;
1856    case Type::BlockPointer:            break;
1857    case Type::Pointer:                 break;
1858    case Type::LValueReference:         break;
1859    case Type::RValueReference:         break;
1860    case Type::MemberPointer:           break;
1861    case Type::Complex:                 break;
1862    case Type::ObjCInterface:           break;
1863    case Type::Record:
1864        return cast<RecordType>(qual_type)->getDecl();
1865    case Type::Enum:
1866        return cast<EnumType>(qual_type)->getDecl();
1867    case Type::Typedef:
1868        return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1869
1870    case Type::TypeOfExpr:              break;
1871    case Type::TypeOf:                  break;
1872    case Type::Decltype:                break;
1873    //case Type::QualifiedName:           break;
1874    case Type::TemplateSpecialization:  break;
1875    }
1876    // No DeclContext in this type...
1877    return NULL;
1878}
1879
1880#pragma mark Namespace Declarations
1881
1882NamespaceDecl *
1883ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
1884{
1885    // TODO: Do something intelligent with the Declaration object passed in
1886    // like maybe filling in the SourceLocation with it...
1887    if (name)
1888    {
1889        ASTContext *ast_context = getASTContext();
1890        if (decl_ctx == NULL)
1891            decl_ctx = ast_context->getTranslationUnitDecl();
1892        return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
1893    }
1894    return NULL;
1895}
1896
1897
1898#pragma mark Function Types
1899
1900FunctionDecl *
1901ClangASTContext::CreateFunctionDeclaration (const char *name, void *function_clang_type, int storage, bool is_inline)
1902{
1903    if (name)
1904    {
1905        ASTContext *ast_context = getASTContext();
1906        assert (ast_context != NULL);
1907
1908        if (name && name[0])
1909        {
1910            return FunctionDecl::Create(*ast_context,
1911                                        ast_context->getTranslationUnitDecl(),
1912                                        SourceLocation(),
1913                                        DeclarationName (&ast_context->Idents.get(name)),
1914                                        QualType::getFromOpaquePtr(function_clang_type),
1915                                        NULL,
1916                                        (FunctionDecl::StorageClass)storage,
1917                                        (FunctionDecl::StorageClass)storage,
1918                                        is_inline);
1919        }
1920        else
1921        {
1922            return FunctionDecl::Create(*ast_context,
1923                                        ast_context->getTranslationUnitDecl(),
1924                                        SourceLocation(),
1925                                        DeclarationName (),
1926                                        QualType::getFromOpaquePtr(function_clang_type),
1927                                        NULL,
1928                                        (FunctionDecl::StorageClass)storage,
1929                                        (FunctionDecl::StorageClass)storage,
1930                                        is_inline);
1931        }
1932    }
1933    return NULL;
1934}
1935
1936void *
1937ClangASTContext::CreateFunctionType (void *result_type, void **args, unsigned num_args, bool isVariadic, unsigned TypeQuals)
1938{
1939    ASTContext *ast_context = getASTContext();
1940    assert (ast_context != NULL);
1941    std::vector<QualType> qual_type_args;
1942    for (unsigned i=0; i<num_args; ++i)
1943        qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
1944
1945    // TODO: Detect calling convention in DWARF?
1946    return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
1947                                        qual_type_args.data(),
1948                                        qual_type_args.size(),
1949                                        isVariadic,
1950                                        TypeQuals,
1951                                        false,  // hasExceptionSpec
1952                                        false,  // hasAnyExceptionSpec,
1953                                        0,      // NumExs
1954                                        0,      // const QualType *ExArray
1955                                        FunctionType::ExtInfo ()).getAsOpaquePtr();    // NoReturn);
1956}
1957
1958ParmVarDecl *
1959ClangASTContext::CreateParmeterDeclaration (const char *name, void * return_type, int storage)
1960{
1961    ASTContext *ast_context = getASTContext();
1962    assert (ast_context != NULL);
1963    return ParmVarDecl::Create(*ast_context,
1964                                ast_context->getTranslationUnitDecl(),
1965                                SourceLocation(),
1966                                name && name[0] ? &ast_context->Idents.get(name) : NULL,
1967                                QualType::getFromOpaquePtr(return_type),
1968                                NULL,
1969                                (VarDecl::StorageClass)storage,
1970                                (VarDecl::StorageClass)storage,
1971                                0);
1972}
1973
1974void
1975ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
1976{
1977    if (function_decl)
1978        function_decl->setParams (params, num_params);
1979}
1980
1981
1982#pragma mark Array Types
1983
1984void *
1985ClangASTContext::CreateArrayType (void *element_type, size_t element_count, uint32_t bit_stride)
1986{
1987    if (element_type)
1988    {
1989        ASTContext *ast_context = getASTContext();
1990        assert (ast_context != NULL);
1991        llvm::APInt ap_element_count (64, element_count);
1992        return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
1993                                                 ap_element_count,
1994                                                 ArrayType::Normal,
1995                                                 0).getAsOpaquePtr(); // ElemQuals
1996    }
1997    return NULL;
1998}
1999
2000
2001#pragma mark TagDecl
2002
2003bool
2004ClangASTContext::StartTagDeclarationDefinition (void *clang_type)
2005{
2006    if (clang_type)
2007    {
2008        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2009        Type *t = qual_type.getTypePtr();
2010        if (t)
2011        {
2012            TagType *tag_type = dyn_cast<TagType>(t);
2013            if (tag_type)
2014            {
2015                TagDecl *tag_decl = tag_type->getDecl();
2016                if (tag_decl)
2017                {
2018                    tag_decl->startDefinition();
2019                    return true;
2020                }
2021            }
2022        }
2023    }
2024    return false;
2025}
2026
2027bool
2028ClangASTContext::CompleteTagDeclarationDefinition (void *clang_type)
2029{
2030    if (clang_type)
2031    {
2032        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2033        Type *t = qual_type.getTypePtr();
2034        if (t)
2035        {
2036            TagType *tag_type = dyn_cast<TagType>(t);
2037            if (tag_type)
2038            {
2039                TagDecl *tag_decl = tag_type->getDecl();
2040                if (tag_decl)
2041                {
2042                    tag_decl->completeDefinition();
2043                    return true;
2044                }
2045            }
2046        }
2047    }
2048    return false;
2049}
2050
2051
2052#pragma mark Enumeration Types
2053
2054void *
2055ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name)
2056{
2057    // TODO: Do something intelligent with the Declaration object passed in
2058    // like maybe filling in the SourceLocation with it...
2059    ASTContext *ast_context = getASTContext();
2060    assert (ast_context != NULL);
2061    EnumDecl *enum_decl = EnumDecl::Create(*ast_context,
2062                                           ast_context->getTranslationUnitDecl(),
2063                                           SourceLocation(),
2064                                           name && name[0] ? &ast_context->Idents.get(name) : NULL,
2065                                           SourceLocation(),
2066                                           NULL);
2067    if (enum_decl)
2068        return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
2069    return NULL;
2070}
2071
2072bool
2073ClangASTContext::AddEnumerationValueToEnumerationType
2074(
2075    void *enum_clang_type,
2076    void *enumerator_clang_type,
2077    const Declaration &decl,
2078    const char *name,
2079    int64_t enum_value,
2080    uint32_t enum_value_bit_size
2081)
2082{
2083    if (enum_clang_type && enumerator_clang_type && name)
2084    {
2085        // TODO: Do something intelligent with the Declaration object passed in
2086        // like maybe filling in the SourceLocation with it...
2087        ASTContext *ast_context = getASTContext();
2088        IdentifierTable *identifier_table = getIdentifierTable();
2089
2090        assert (ast_context != NULL);
2091        assert (identifier_table != NULL);
2092        QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
2093
2094        Type *clang_type = enum_qual_type.getTypePtr();
2095        if (clang_type)
2096        {
2097            const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
2098
2099            if (enum_type)
2100            {
2101                llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
2102                enum_llvm_apsint = enum_value;
2103                EnumConstantDecl *enumerator_decl =
2104                    EnumConstantDecl::Create(*ast_context,
2105                                             enum_type->getDecl(),
2106                                             SourceLocation(),
2107                                             name ? &identifier_table->get(name) : NULL,    // Identifier
2108                                             QualType::getFromOpaquePtr(enumerator_clang_type),
2109                                             NULL,
2110                                             enum_llvm_apsint);
2111
2112                if (enumerator_decl)
2113                {
2114                    enum_type->getDecl()->addDecl(enumerator_decl);
2115                    return true;
2116                }
2117            }
2118        }
2119    }
2120    return false;
2121}
2122
2123#pragma mark Pointers & References
2124
2125void *
2126ClangASTContext::CreatePointerType (void *clang_type)
2127{
2128    if (clang_type)
2129        return getASTContext()->getPointerType(QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2130    return NULL;
2131}
2132
2133void *
2134ClangASTContext::CreateLValueReferenceType (void *clang_type)
2135{
2136    if (clang_type)
2137        return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2138    return NULL;
2139}
2140
2141void *
2142ClangASTContext::CreateRValueReferenceType (void *clang_type)
2143{
2144    if (clang_type)
2145        return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2146    return NULL;
2147}
2148
2149void *
2150ClangASTContext::CreateMemberPointerType (void * clang_pointee_type, void * clang_class_type)
2151{
2152    if (clang_pointee_type && clang_pointee_type)
2153        return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
2154                                                     QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
2155    return NULL;
2156}
2157
2158size_t
2159ClangASTContext::GetPointerBitSize ()
2160{
2161    ASTContext *ast_context = getASTContext();
2162    return ast_context->getTypeSize(ast_context->VoidPtrTy);
2163}
2164
2165bool
2166ClangASTContext::IsPointerOrReferenceType (void *clang_type, void **target_type)
2167{
2168    if (clang_type == NULL)
2169        return false;
2170
2171    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2172    switch (qual_type->getTypeClass())
2173    {
2174    case Type::ObjCObjectPointer:
2175        if (target_type)
2176            *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2177        return true;
2178    case Type::BlockPointer:
2179        if (target_type)
2180            *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2181        return true;
2182    case Type::Pointer:
2183        if (target_type)
2184            *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2185        return true;
2186    case Type::MemberPointer:
2187        if (target_type)
2188            *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2189        return true;
2190    case Type::LValueReference:
2191        if (target_type)
2192            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2193        return true;
2194    case Type::RValueReference:
2195        if (target_type)
2196            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2197        return true;
2198    case Type::Typedef:
2199        return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
2200    default:
2201        break;
2202    }
2203    return false;
2204}
2205
2206size_t
2207ClangASTContext::GetTypeBitSize (clang::ASTContext *ast_context, void *clang_type)
2208{
2209    if (clang_type)
2210        return ast_context->getTypeSize(QualType::getFromOpaquePtr(clang_type));
2211    return 0;
2212}
2213
2214size_t
2215ClangASTContext::GetTypeBitAlign (clang::ASTContext *ast_context, void *clang_type)
2216{
2217    if (clang_type)
2218        return ast_context->getTypeAlign(QualType::getFromOpaquePtr(clang_type));
2219    return 0;
2220}
2221
2222bool
2223ClangASTContext::IsIntegerType (void * clang_type, bool &is_signed)
2224{
2225    if (!clang_type)
2226        return false;
2227
2228    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2229    const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
2230
2231    if (builtin_type)
2232    {
2233        if (builtin_type->isInteger())
2234            is_signed = builtin_type->isSignedInteger();
2235
2236        return true;
2237    }
2238
2239    return false;
2240}
2241
2242bool
2243ClangASTContext::IsPointerType (void *clang_type, void **target_type)
2244{
2245    if (clang_type)
2246    {
2247        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2248        switch (qual_type->getTypeClass())
2249        {
2250        case Type::ObjCObjectPointer:
2251            if (target_type)
2252                *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2253            return true;
2254        case Type::BlockPointer:
2255            if (target_type)
2256                *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2257            return true;
2258        case Type::Pointer:
2259            if (target_type)
2260                *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2261            return true;
2262        case Type::MemberPointer:
2263            if (target_type)
2264                *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2265            return true;
2266        case Type::Typedef:
2267            return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
2268        default:
2269            break;
2270        }
2271    }
2272    return false;
2273}
2274
2275bool
2276ClangASTContext::IsFloatingPointType (void *clang_type, uint32_t &count, bool &is_complex)
2277{
2278    if (clang_type)
2279    {
2280        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2281
2282        if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
2283        {
2284            clang::BuiltinType::Kind kind = BT->getKind();
2285            if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
2286            {
2287                count = 1;
2288                is_complex = false;
2289                return true;
2290            }
2291        }
2292        else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
2293        {
2294            if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
2295            {
2296                count = 2;
2297                is_complex = true;
2298                return true;
2299            }
2300        }
2301        else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
2302        {
2303            if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
2304            {
2305                count = VT->getNumElements();
2306                is_complex = false;
2307                return true;
2308            }
2309        }
2310    }
2311    return false;
2312}
2313
2314
2315bool
2316ClangASTContext::IsCStringType (void *clang_type, uint32_t &length)
2317{
2318    if (clang_type)
2319    {
2320        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2321        switch (qual_type->getTypeClass())
2322        {
2323        case Type::ConstantArray:
2324            {
2325                ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr());
2326                QualType element_qual_type = array->getElementType();
2327                Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
2328                if (canonical_type && canonical_type->isCharType())
2329                {
2330                    // We know the size of the array and it could be a C string
2331                    // since it is an array of characters
2332                    length = array->getSize().getLimitedValue();
2333                    return true;
2334                }
2335            }
2336            break;
2337
2338        case Type::Pointer:
2339            {
2340                PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2341                Type *pointee_type_ptr = pointer_type->getPointeeType().getTypePtr();
2342                if (pointee_type_ptr)
2343                {
2344                    Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
2345                    length = 0; // No length info, read until a NULL terminator is received
2346                    if (canonical_type_ptr)
2347                        return canonical_type_ptr->isCharType();
2348                    else
2349                        return pointee_type_ptr->isCharType();
2350                }
2351            }
2352            break;
2353
2354        case Type::Typedef:
2355            return ClangASTContext::IsCStringType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), length);
2356
2357        case Type::LValueReference:
2358        case Type::RValueReference:
2359            {
2360                ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2361                Type *pointee_type_ptr = reference_type->getPointeeType().getTypePtr();
2362                if (pointee_type_ptr)
2363                {
2364                    Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
2365                    length = 0; // No length info, read until a NULL terminator is received
2366                    if (canonical_type_ptr)
2367                        return canonical_type_ptr->isCharType();
2368                    else
2369                        return pointee_type_ptr->isCharType();
2370                }
2371            }
2372            break;
2373        }
2374    }
2375    return false;
2376}
2377
2378bool
2379ClangASTContext::IsArrayType (void * clang_type, void **member_type, uint64_t *size)
2380{
2381    if (!clang_type)
2382        return false;
2383
2384    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2385
2386    switch (qual_type->getTypeClass())
2387    {
2388    case Type::ConstantArray:
2389        if (member_type)
2390            *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2391        if (size)
2392            *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
2393        return true;
2394    case Type::IncompleteArray:
2395        if (member_type)
2396            *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2397        if (size)
2398            *size = 0;
2399        return true;
2400    case Type::VariableArray:
2401        if (member_type)
2402            *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2403        if (size)
2404            *size = 0;
2405    case Type::DependentSizedArray:
2406        if (member_type)
2407            *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2408        if (size)
2409            *size = 0;
2410        return true;
2411    }
2412    return false;
2413}
2414
2415
2416#pragma mark Typedefs
2417
2418void *
2419ClangASTContext::CreateTypedefType (const char *name, void *clang_type, DeclContext *decl_ctx)
2420{
2421    if (clang_type)
2422    {
2423        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2424        ASTContext *ast_context = getASTContext();
2425        IdentifierTable *identifier_table = getIdentifierTable();
2426        assert (ast_context != NULL);
2427        assert (identifier_table != NULL);
2428        if (decl_ctx == NULL)
2429            decl_ctx = ast_context->getTranslationUnitDecl();
2430        TypedefDecl *decl = TypedefDecl::Create(*ast_context,
2431                                                decl_ctx,
2432                                                SourceLocation(),
2433                                                name ? &identifier_table->get(name) : NULL, // Identifier
2434                                                ast_context->CreateTypeSourceInfo(qual_type));
2435
2436        // Get a uniqued QualType for the typedef decl type
2437        return ast_context->getTypedefType (decl).getAsOpaquePtr();
2438    }
2439    return NULL;
2440}
2441
2442
2443std::string
2444ClangASTContext::GetTypeName (void *opaque_qual_type)
2445{
2446    std::string return_name;
2447
2448    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_qual_type));
2449
2450    const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
2451    if (typedef_type)
2452    {
2453        const clang::TypedefDecl *typedef_decl = typedef_type->getDecl();
2454        return_name = typedef_decl->getQualifiedNameAsString();
2455    }
2456    else
2457    {
2458        return_name = qual_type.getAsString();
2459    }
2460
2461    return return_name;
2462}
2463
2464// Disable this for now since I can't seem to get a nicely formatted float
2465// out of the APFloat class without just getting the float, double or quad
2466// and then using a formatted print on it which defeats the purpose. We ideally
2467// would like to get perfect string values for any kind of float semantics
2468// so we can support remote targets. The code below also requires a patch to
2469// llvm::APInt.
2470//bool
2471//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, void *clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
2472//{
2473//  uint32_t count = 0;
2474//  bool is_complex = false;
2475//  if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
2476//  {
2477//      unsigned num_bytes_per_float = byte_size / count;
2478//      unsigned num_bits_per_float = num_bytes_per_float * 8;
2479//
2480//      float_str.clear();
2481//      uint32_t i;
2482//      for (i=0; i<count; i++)
2483//      {
2484//          APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
2485//          bool is_ieee = false;
2486//          APFloat ap_float(ap_int, is_ieee);
2487//          char s[1024];
2488//          unsigned int hex_digits = 0;
2489//          bool upper_case = false;
2490//
2491//          if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
2492//          {
2493//              if (i > 0)
2494//                  float_str.append(", ");
2495//              float_str.append(s);
2496//              if (i == 1 && is_complex)
2497//                  float_str.append(1, 'i');
2498//          }
2499//      }
2500//      return !float_str.empty();
2501//  }
2502//  return false;
2503//}
2504
2505size_t
2506ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, void *clang_type, const char *s, uint8_t *dst, size_t dst_size)
2507{
2508    if (clang_type)
2509    {
2510        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2511        uint32_t count = 0;
2512        bool is_complex = false;
2513        if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
2514        {
2515            // TODO: handle complex and vector types
2516            if (count != 1)
2517                return false;
2518
2519            StringRef s_sref(s);
2520            APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
2521
2522            const uint64_t bit_size = ast_context->getTypeSize (qual_type);
2523            const uint64_t byte_size = bit_size / 8;
2524            if (dst_size >= byte_size)
2525            {
2526                if (bit_size == sizeof(float)*8)
2527                {
2528                    float float32 = ap_float.convertToFloat();
2529                    ::memcpy (dst, &float32, byte_size);
2530                    return byte_size;
2531                }
2532                else if (bit_size >= 64)
2533                {
2534                    llvm::APInt ap_int(ap_float.bitcastToAPInt());
2535                    ::memcpy (dst, ap_int.getRawData(), byte_size);
2536                    return byte_size;
2537                }
2538            }
2539        }
2540    }
2541    return 0;
2542}
2543