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