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