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