blob: e2b09f1aaae397fd8d447dfe0cc814710d287d54 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedman932197d2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Greg Clayton6beaaa62011-01-17 03:46:26 +000017
18// Clang headers like to use NDEBUG inside of them to enable/disable debug
19// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing
20// or another. This is bad because it means that if clang was built in release
21// mode, it assumes that you are building in release mode which is not always
22// the case. You can end up with functions that are defined as empty in header
23// files when NDEBUG is not defined, and this can cause link errors with the
24// clang .a files that you have since you might be missing functions in the .a
25// file. So we have to define NDEBUG when including clang headers to avoid any
26// mismatches. This is covered by rdar://problem/8691220
27
28#ifndef NDEBUG
29#define LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000030#define NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000031// Need to include assert.h so it is as clang would expect it to be (disabled)
32#include <assert.h>
33#endif
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "clang/AST/ASTContext.h"
36#include "clang/AST/ASTImporter.h"
37#include "clang/AST/CXXInheritance.h"
Greg Clayton8cf05932010-07-22 18:30:50 +000038#include "clang/AST/DeclObjC.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "clang/AST/RecordLayout.h"
40#include "clang/AST/Type.h"
41#include "clang/Basic/Builtins.h"
42#include "clang/Basic/FileManager.h"
Sean Callanan79439e82010-11-18 02:56:27 +000043#include "clang/Basic/FileSystemOptions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044#include "clang/Basic/SourceManager.h"
45#include "clang/Basic/TargetInfo.h"
46#include "clang/Basic/TargetOptions.h"
47#include "clang/Frontend/FrontendOptions.h"
48#include "clang/Frontend/LangStandard.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000049
50#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000051#undef NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000052#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
53// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
54#include <assert.h>
55#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057#include "lldb/Core/dwarf.h"
Greg Clayton73b472d2010-10-27 03:32:59 +000058#include "lldb/Core/Flags.h"
Sean Callananfb8b7092010-10-28 18:19:36 +000059#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060
Eli Friedman932197d2010-06-13 19:06:42 +000061#include <stdio.h>
62
Greg Claytonc86103d2010-08-05 01:57:25 +000063using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064using namespace lldb_private;
65using namespace llvm;
66using namespace clang;
67
Greg Clayton6beaaa62011-01-17 03:46:26 +000068
69static bool
70GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
71{
72 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
73 switch (type_class)
74 {
75 case clang::Type::Record:
76 case clang::Type::Enum:
77 {
78 clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
79 if (tag_type)
80 {
81 clang::TagDecl *tag_decl = tag_type->getDecl();
82 if (tag_decl)
83 {
84 if (tag_decl->getDefinition())
85 return true;
86
87 if (tag_decl->hasExternalLexicalStorage())
88 {
89 ExternalASTSource *external_ast_source = ast->getExternalSource();
90 if (external_ast_source)
91 {
92 external_ast_source->CompleteType(tag_decl);
93 return !tag_type->isIncompleteType();
94 }
95 }
96 return false;
97 }
98 }
99
100 }
101 break;
102
103 case clang::Type::ObjCObject:
104 case clang::Type::ObjCInterface:
105 {
106 clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
107 if (objc_class_type)
108 {
109 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
110 // We currently can't complete objective C types through the newly added ASTContext
111 // because it only supports TagDecl objects right now...
112 bool is_forward_decl = class_interface_decl->isForwardDecl();
113 if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
114 {
115 ExternalASTSource *external_ast_source = ast->getExternalSource();
116 if (external_ast_source)
117 {
118 external_ast_source->CompleteType (class_interface_decl);
119 is_forward_decl = class_interface_decl->isForwardDecl();
120 }
121 }
122 return is_forward_decl;
123 }
124 }
125 break;
126
127 case clang::Type::Typedef:
128 return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType());
129
130 default:
131 break;
132 }
133
134 return true;
135}
136
137
Greg Clayton8cf05932010-07-22 18:30:50 +0000138static AccessSpecifier
Greg Claytonc86103d2010-08-05 01:57:25 +0000139ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000140{
141 switch (access)
142 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000143 default: break;
144 case eAccessNone: return AS_none;
145 case eAccessPublic: return AS_public;
146 case eAccessPrivate: return AS_private;
147 case eAccessProtected: return AS_protected;
Greg Clayton8cf05932010-07-22 18:30:50 +0000148 }
149 return AS_none;
150}
151
152static ObjCIvarDecl::AccessControl
Greg Claytonc86103d2010-08-05 01:57:25 +0000153ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000154{
155 switch (access)
156 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000157 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;
Greg Clayton8cf05932010-07-22 18:30:50 +0000163 }
164 return ObjCIvarDecl::None;
165}
166
167
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168static void
169ParseLangArgs
170(
171 LangOptions &Opts,
Greg Clayton94e5d782010-06-13 17:34:29 +0000172 InputKind IK
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000173)
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.
Greg Clayton94e5d782010-06-13 17:34:29 +0000180 if (IK == IK_Asm) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181 Opts.AsmPreprocessor = 1;
Greg Clayton94e5d782010-06-13 17:34:29 +0000182 } else if (IK == IK_ObjC ||
183 IK == IK_ObjCXX ||
184 IK == IK_PreprocessedObjC ||
185 IK == IK_PreprocessedObjCXX) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186 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) {
Greg Clayton94e5d782010-06-13 17:34:29 +0000194 case IK_None:
195 case IK_AST:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000196 assert (!"Invalid input kind!");
Greg Clayton94e5d782010-06-13 17:34:29 +0000197 case IK_OpenCL:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000198 LangStd = LangStandard::lang_opencl;
199 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000200 case IK_Asm:
201 case IK_C:
202 case IK_PreprocessedC:
203 case IK_ObjC:
204 case IK_PreprocessedObjC:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205 LangStd = LangStandard::lang_gnu99;
206 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000207 case IK_CXX:
208 case IK_PreprocessedCXX:
209 case IK_ObjCXX:
210 case IK_PreprocessedObjCXX:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211 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")
Sean Callanan31e851c2010-10-29 18:38:40 +0000258 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259// 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332
Greg Clayton6beaaa62011-01-17 03:46:26 +0000333ClangASTContext::ClangASTContext (const char *target_triple) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000334 m_target_triple(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000335 m_ast_ap(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336 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(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000343 m_builtins_ap(),
344 m_callback_tag_decl (NULL),
345 m_callback_objc_decl (NULL),
346 m_callback_baton (NULL)
347
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348{
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();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000366 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367}
368
369
370void
371ClangASTContext::Clear()
372{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000373 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374 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
Greg Clayton6beaaa62011-01-17 03:46:26 +0000397bool
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
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000433
434ASTContext *
435ClangASTContext::getASTContext()
436{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000437 if (m_ast_ap.get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000439 m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
440 *getSourceManager(),
441 *getTargetInfo(),
442 *getIdentifierTable(),
443 *getSelectorTable(),
444 *getBuiltinContext(),
445 0));
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000446
Greg Clayton6beaaa62011-01-17 03:46:26 +0000447 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);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000454 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000455 return m_ast_ap.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456}
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());
Greg Clayton94e5d782010-06-13 17:34:29 +0000480 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
481// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482 }
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
Sean Callanan79439e82010-11-18 02:56:27 +0000494clang::FileManager *
495ClangASTContext::getFileManager()
496{
497 if (m_file_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000498 {
499 clang::FileSystemOptions file_system_options;
500 m_file_manager_ap.reset(new clang::FileManager(file_system_options));
501 }
Sean Callanan79439e82010-11-18 02:56:27 +0000502 return m_file_manager_ap.get();
503}
504
Greg Claytone1a916a2010-07-21 22:12:05 +0000505clang::SourceManager *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000506ClangASTContext::getSourceManager()
507{
508 if (m_source_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000509 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510 return m_source_manager_ap.get();
511}
512
513Diagnostic *
514ClangASTContext::getDiagnostic()
515{
516 if (m_diagnostic_ap.get() == NULL)
Greg Claytona651b532010-11-19 21:46:54 +0000517 {
518 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
519 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
520 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521 return m_diagnostic_ap.get();
522}
523
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000524class 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000555TargetOptions *
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
Greg Clayton6beaaa62011-01-17 03:46:26 +0000580QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000581{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000582 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000583 if (qual_type_bit_size == bit_size)
584 return true;
585 return false;
586}
587
Greg Clayton1be10fc2010-09-29 01:12:09 +0000588clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +0000589ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000590{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000591 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000592
Greg Clayton6beaaa62011-01-17 03:46:26 +0000593 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594
Greg Clayton6beaaa62011-01-17 03:46:26 +0000595 return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596}
597
Greg Clayton1be10fc2010-09-29 01:12:09 +0000598clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000599ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000601 if (!ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602 return NULL;
603
604 switch (encoding)
605 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000606 case eEncodingInvalid:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000607 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
608 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000609 break;
610
Greg Claytonc86103d2010-08-05 01:57:25 +0000611 case eEncodingUint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000612 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000624 break;
625
Greg Claytonc86103d2010-08-05 01:57:25 +0000626 case eEncodingSint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000627 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639 break;
640
Greg Claytonc86103d2010-08-05 01:57:25 +0000641 case eEncodingIEEE754:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000642 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000648 break;
649
Greg Claytonc86103d2010-08-05 01:57:25 +0000650 case eEncodingVector:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000651 default:
652 break;
653 }
654
655 return NULL;
656}
657
Greg Clayton1be10fc2010-09-29 01:12:09 +0000658clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000659ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
660{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000661 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000662
663 #define streq(a,b) strcmp(a,b) == 0
Greg Clayton6beaaa62011-01-17 03:46:26 +0000664 assert (ast != NULL);
665 if (ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666 {
667 switch (dw_ate)
668 {
669 default:
670 break;
671
672 case DW_ATE_address:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000673 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
674 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000675 break;
676
677 case DW_ATE_boolean:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000678 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000686 break;
687
Greg Clayton49462ea2011-01-15 02:52:14 +0000688 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);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000693 return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000694 }
695 break;
696
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697 case DW_ATE_complex_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000698 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();
Greg Clayton49462ea2011-01-15 02:52:14 +0000704 else
705 {
706 clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000707 return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000708 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000709 break;
710
711 case DW_ATE_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000712 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 break;
719
720 case DW_ATE_signed:
721 if (type_name)
722 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000723 if (strstr(type_name, "long long"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000724 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000725 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
726 return ast->LongLongTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000728 else if (strstr(type_name, "long"))
729 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000730 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
731 return ast->LongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000732 }
733 else if (strstr(type_name, "short"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000735 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
736 return ast->ShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000738 else if (strstr(type_name, "char"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000739 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000740 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000744 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000745 else if (strstr(type_name, "int"))
746 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000747 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();
Greg Clayton19de37f2010-11-02 03:48:39 +0000751 }
752 else if (streq(type_name, "wchar_t"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000753 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000754 if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
755 return ast->WCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757 }
758 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000759 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000771 break;
772
773 case DW_ATE_signed_char:
774 if (type_name)
775 {
776 if (streq(type_name, "signed char"))
777 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000778 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
779 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000780 }
781 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000782 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000786 break;
787
788 case DW_ATE_unsigned:
789 if (type_name)
790 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000791 if (strstr(type_name, "long long"))
792 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000793 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
794 return ast->UnsignedLongLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000795 }
796 else if (strstr(type_name, "long"))
797 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000798 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
799 return ast->UnsignedLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000800 }
801 else if (strstr(type_name, "short"))
802 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000803 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
804 return ast->UnsignedShortTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000805 }
806 else if (strstr(type_name, "char"))
807 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000808 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
809 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000810 }
811 else if (strstr(type_name, "int"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000812 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000813 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000817 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000818 }
819 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000820 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();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000832 break;
833
834 case DW_ATE_unsigned_char:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000835 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
836 return ast->UnsignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837 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
Greg Clayton1be10fc2010-09-29 01:12:09 +0000849clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000850ClangASTContext::GetBuiltInType_void(ASTContext *ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000852 return ast->VoidTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853}
854
Greg Clayton1be10fc2010-09-29 01:12:09 +0000855clang_type_t
Sean Callananf7c3e272010-11-19 02:52:21 +0000856ClangASTContext::GetBuiltInType_bool()
857{
858 return getASTContext()->BoolTy.getAsOpaquePtr();
859}
860
861clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000862ClangASTContext::GetBuiltInType_objc_id()
863{
Sean Callananf6c73082010-12-06 23:53:20 +0000864 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000865}
866
Greg Clayton1be10fc2010-09-29 01:12:09 +0000867clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000868ClangASTContext::GetBuiltInType_objc_Class()
869{
Sean Callanana2424172010-10-25 00:29:48 +0000870 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000871}
872
Greg Clayton1be10fc2010-09-29 01:12:09 +0000873clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000874ClangASTContext::GetBuiltInType_objc_selector()
875{
Sean Callananf6c73082010-12-06 23:53:20 +0000876 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000877}
878
Greg Clayton1be10fc2010-09-29 01:12:09 +0000879clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000880ClangASTContext::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
Greg Clayton1be10fc2010-09-29 01:12:09 +0000890clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000891ClangASTContext::GetVoidPtrType (bool is_const)
892{
893 return GetVoidPtrType(getASTContext(), is_const);
894}
895
Greg Clayton1be10fc2010-09-29 01:12:09 +0000896clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000897ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000898{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000899 QualType void_ptr_type(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000900
901 if (is_const)
902 void_ptr_type.addConst();
903
904 return void_ptr_type.getAsOpaquePtr();
905}
906
Greg Clayton1be10fc2010-09-29 01:12:09 +0000907clang_type_t
Greg Clayton38a61402010-12-02 23:20:03 +0000908ClangASTContext::CopyType (ASTContext *dst_ast,
909 ASTContext *src_ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000910 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911{
Sean Callanan79439e82010-11-18 02:56:27 +0000912 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000913 FileManager file_manager (file_system_options);
914 ASTImporter importer(*dst_ast, file_manager,
915 *src_ast, file_manager);
Sean Callanan0617fcb2010-11-09 22:37:10 +0000916
Greg Clayton38a61402010-12-02 23:20:03 +0000917 QualType src (QualType::getFromOpaquePtr(clang_type));
918 QualType dst (importer.Import(src));
Sean Callanan0617fcb2010-11-09 22:37:10 +0000919
920 return dst.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000921}
922
Greg Clayton526e5af2010-11-13 03:52:47 +0000923
924clang::Decl *
Greg Clayton38a61402010-12-02 23:20:03 +0000925ClangASTContext::CopyDecl (ASTContext *dst_ast,
926 ASTContext *src_ast,
Greg Clayton526e5af2010-11-13 03:52:47 +0000927 clang::Decl *source_decl)
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000928{
Sean Callanan79439e82010-11-18 02:56:27 +0000929 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000930 FileManager file_manager (file_system_options);
931 ASTImporter importer(*dst_ast, file_manager,
932 *src_ast, file_manager);
Greg Clayton526e5af2010-11-13 03:52:47 +0000933
934 return importer.Import(source_decl);
935}
936
Sean Callanan23a30272010-07-16 00:00:27 +0000937bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000938ClangASTContext::AreTypesSame(ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000939 clang_type_t type1,
940 clang_type_t type2)
Sean Callanan4dcca2622010-07-15 22:30:52 +0000941{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000942 return ast->hasSameType(QualType::getFromOpaquePtr(type1),
Sean Callanan4dcca2622010-07-15 22:30:52 +0000943 QualType::getFromOpaquePtr(type2));
944}
945
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000946#pragma mark CVR modifiers
947
Greg Clayton1be10fc2010-09-29 01:12:09 +0000948clang_type_t
949ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950{
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
Greg Clayton1be10fc2010-09-29 01:12:09 +0000960clang_type_t
961ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000962{
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
Greg Clayton1be10fc2010-09-29 01:12:09 +0000972clang_type_t
973ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000974{
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
Greg Clayton6beaaa62011-01-17 03:46:26 +0000984
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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007#pragma mark Structure, Unions, Classes
1008
Greg Clayton1be10fc2010-09-29 01:12:09 +00001009clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +00001010ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001012 ASTContext *ast = getASTContext();
1013 assert (ast != NULL);
Sean Callanana2424172010-10-25 00:29:48 +00001014
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001016 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017
Greg Clayton9e409562010-07-28 02:04:09 +00001018
Greg Claytonc86103d2010-08-05 01:57:25 +00001019 if (language == eLanguageTypeObjC)
Greg Clayton9e409562010-07-28 02:04:09 +00001020 {
Greg Claytonaaf99e02010-10-11 02:25:34 +00001021 bool isForwardDecl = true;
Greg Clayton9e409562010-07-28 02:04:09 +00001022 bool isInternal = false;
1023 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
1024 }
1025
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026 // 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.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001031 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001032 (TagDecl::TagKind)kind,
1033 decl_ctx,
1034 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001035 name && name[0] ? &ast->Idents.get(name) : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001036
Greg Clayton6beaaa62011-01-17 03:46:26 +00001037 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;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001103}
1104
Greg Claytona3c444a2010-10-01 23:13:49 +00001105static bool
1106IsOperator (const char *name, OverloadedOperatorKind &op_kind)
1107{
1108 if (name == NULL || name[0] == '\0')
1109 return false;
1110
Sean Callanana43f20d2010-12-10 19:51:54 +00001111#define OPERATOR_PREFIX "operator"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001112#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
Sean Callananbfeff8c2010-12-10 02:15:55 +00001113
1114 const char *post_op_name = NULL;
1115
Sean Callanana43f20d2010-12-10 19:51:54 +00001116 bool no_space = true;
Sean Callananbfeff8c2010-12-10 02:15:55 +00001117
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001118 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
Greg Claytona3c444a2010-10-01 23:13:49 +00001119 return false;
1120
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001121 post_op_name = name + OPERATOR_PREFIX_LENGTH;
1122
Sean Callanana43f20d2010-12-10 19:51:54 +00001123 if (post_op_name[0] == ' ')
1124 {
1125 post_op_name++;
1126 no_space = false;
1127 }
1128
1129#undef OPERATOR_PREFIX
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001130#undef OPERATOR_PREFIX_LENGTH
Sean Callanana43f20d2010-12-10 19:51:54 +00001131
Greg Claytona3c444a2010-10-01 23:13:49 +00001132 // 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 {
Sean Callananbfeff8c2010-12-10 02:15:55 +00001138 default:
1139 if (no_space)
1140 return false;
1141 break;
Greg Claytona3c444a2010-10-01 23:13:49 +00001142 case 'n':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001143 if (no_space)
1144 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001145 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':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001152 if (no_space)
1153 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001154 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}
Greg Clayton6beaaa62011-01-17 03:46:26 +00001320
Greg Claytona51ed9b2010-09-23 01:09:21 +00001321CXXMethodDecl *
Sean Callanan61da09b2010-09-17 02:58:26 +00001322ClangASTContext::AddMethodToCXXRecordType
1323(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001324 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001325 clang_type_t record_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001326 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001327 clang_type_t method_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001328 lldb::AccessType access,
Greg Clayton0fffff52010-09-24 05:15:53 +00001329 bool is_virtual,
1330 bool is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00001331 bool is_inline,
1332 bool is_explicit
Greg Claytona51ed9b2010-09-23 01:09:21 +00001333)
Sean Callanan61da09b2010-09-17 02:58:26 +00001334{
Sean Callananfc55f5d2010-09-21 00:44:12 +00001335 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chend440bcc2010-09-28 16:10:54 +00001336 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001337
Greg Clayton6beaaa62011-01-17 03:46:26 +00001338 assert(ast);
Sean Callanan61da09b2010-09-17 02:58:26 +00001339
Greg Clayton6beaaa62011-01-17 03:46:26 +00001340 IdentifierTable *identifier_table = &ast->Idents;
Sean Callanan61da09b2010-09-17 02:58:26 +00001341
1342 assert(identifier_table);
1343
Sean Callananfc55f5d2010-09-21 00:44:12 +00001344 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001345
Greg Clayton6beaaa62011-01-17 03:46:26 +00001346 CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
Sean Callanan61da09b2010-09-17 02:58:26 +00001347
Greg Clayton0fffff52010-09-24 05:15:53 +00001348 if (cxx_record_decl == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001349 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001350
Greg Clayton0fffff52010-09-24 05:15:53 +00001351 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001352
Greg Claytonf51de672010-10-01 02:31:07 +00001353 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001354
Greg Claytonf51de672010-10-01 02:31:07 +00001355 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton878eaf12010-10-01 03:45:20 +00001356
Greg Clayton878eaf12010-10-01 03:45:20 +00001357 const bool is_implicitly_declared = false;
Greg Claytonf51de672010-10-01 02:31:07 +00001358
Greg Clayton90a2acd2010-10-02 01:40:05 +00001359 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton878eaf12010-10-01 03:45:20 +00001360
Greg Clayton90a2acd2010-10-02 01:40:05 +00001361 if (function_Type == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001362 return NULL;
1363
Greg Clayton90a2acd2010-10-02 01:40:05 +00001364 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton878eaf12010-10-01 03:45:20 +00001365
1366 if (!method_function_prototype)
1367 return NULL;
1368
1369 unsigned int num_params = method_function_prototype->getNumArgs();
1370
1371 if (name[0] == '~')
Greg Claytonf51de672010-10-01 02:31:07 +00001372 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001373 cxx_method_decl = CXXDestructorDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001374 cxx_record_decl,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001375 DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001376 method_qual_type,
Sean Callanan31e851c2010-10-29 18:38:40 +00001377 NULL,
Greg Clayton878eaf12010-10-01 03:45:20 +00001378 is_inline,
1379 is_implicitly_declared);
1380 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001381 else if (decl_name == cxx_record_decl->getDeclName())
Greg Clayton878eaf12010-10-01 03:45:20 +00001382 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001383 cxx_method_decl = CXXConstructorDecl::Create (*ast,
Greg Claytonf51de672010-10-01 02:31:07 +00001384 cxx_record_decl,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001385 DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Claytonf51de672010-10-01 02:31:07 +00001386 method_qual_type,
1387 NULL, // TypeSourceInfo *
1388 is_explicit,
1389 is_inline,
1390 is_implicitly_declared);
1391 }
1392 else
Greg Clayton878eaf12010-10-01 03:45:20 +00001393 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001394
1395 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1396 if (IsOperator (name, op_kind))
Greg Clayton878eaf12010-10-01 03:45:20 +00001397 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001398 if (op_kind != NUM_OVERLOADED_OPERATORS)
1399 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001400 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001401 cxx_record_decl,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001402 DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001403 method_qual_type,
1404 NULL, // TypeSourceInfo *
Greg Claytona3c444a2010-10-01 23:13:49 +00001405 is_static,
1406 SC_None,
1407 is_inline);
1408 }
1409 else if (num_params == 0)
1410 {
1411 // Conversion operators don't take params...
Greg Clayton6beaaa62011-01-17 03:46:26 +00001412 cxx_method_decl = CXXConversionDecl::Create (*ast,
Greg Claytona3c444a2010-10-01 23:13:49 +00001413 cxx_record_decl,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001414 DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytona3c444a2010-10-01 23:13:49 +00001415 method_qual_type,
1416 NULL, // TypeSourceInfo *
1417 is_inline,
1418 is_explicit);
1419 }
Greg Clayton878eaf12010-10-01 03:45:20 +00001420 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001421
1422 if (cxx_method_decl == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001423 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001424 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001425 cxx_record_decl,
Greg Claytona3c444a2010-10-01 23:13:49 +00001426 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001427 method_qual_type,
1428 NULL, // TypeSourceInfo *
1429 is_static,
1430 SC_None,
1431 is_inline);
1432 }
Greg Claytonf51de672010-10-01 02:31:07 +00001433 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001434
Greg Clayton1be10fc2010-09-29 01:12:09 +00001435 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton0fffff52010-09-24 05:15:53 +00001436
1437 cxx_method_decl->setAccess (access_specifier);
1438 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001439
Sean Callananfc55f5d2010-09-21 00:44:12 +00001440 // Populate the method decl with parameter decls
Sean Callananfc55f5d2010-09-21 00:44:12 +00001441
1442 ParmVarDecl *params[num_params];
1443
1444 for (int param_index = 0;
1445 param_index < num_params;
1446 ++param_index)
1447 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001448 params[param_index] = ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001449 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);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001457 }
1458
Greg Clayton0fffff52010-09-24 05:15:53 +00001459 cxx_method_decl->setParams (params, num_params);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001460
Greg Clayton0fffff52010-09-24 05:15:53 +00001461 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan61da09b2010-09-17 02:58:26 +00001462
Greg Claytona51ed9b2010-09-23 01:09:21 +00001463 return cxx_method_decl;
Sean Callanan61da09b2010-09-17 02:58:26 +00001464}
1465
1466bool
Greg Clayton8cf05932010-07-22 18:30:50 +00001467ClangASTContext::AddFieldToRecordType
1468(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001469 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001470 clang_type_t record_clang_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001471 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001472 clang_type_t field_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001473 AccessType access,
1474 uint32_t bitfield_bit_size
1475)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001476{
1477 if (record_clang_type == NULL || field_type == NULL)
1478 return false;
1479
Greg Clayton6beaaa62011-01-17 03:46:26 +00001480 IdentifierTable *identifier_table = &ast->Idents;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001481
Greg Clayton6beaaa62011-01-17 03:46:26 +00001482 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001483 assert (identifier_table != NULL);
1484
1485 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1486
Greg Claytone1a916a2010-07-21 22:12:05 +00001487 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001488 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001496 clang::Expr *bit_width = NULL;
1497 if (bitfield_bit_size != 0)
1498 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001499 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());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001501 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001502 FieldDecl *field = FieldDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001503 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001510
Greg Clayton8cf05932010-07-22 18:30:50 +00001511 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001512
1513 if (field)
1514 {
1515 record_decl->addDecl(field);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001516 }
1517 }
Greg Clayton9e409562010-07-28 02:04:09 +00001518 else
1519 {
1520 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1521 if (objc_class_type)
1522 {
Greg Clayton0fffff52010-09-24 05:15:53 +00001523 bool is_synthesized = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001524 ClangASTContext::AddObjCClassIVar (ast,
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001525 record_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001526 name,
1527 field_type,
1528 access,
1529 bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001530 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001531 }
1532 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001533 }
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(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001546 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001547 FieldDecl* field,
1548 uint32_t& bitfield_bit_size
1549)
1550{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001551 if (ast == NULL || field == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001552 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;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001560 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001561 {
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
Greg Clayton6beaaa62011-01-17 03:46:26 +00001597ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001598{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001599 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001600 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001601 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1602
1603 RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
1604 if (record_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001605 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001606 RecordDecl *record_decl = record_type->getDecl();
1607 if (record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001608 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001609 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)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001614 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001615 // 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);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001618 }
1619 }
1620 }
1621 }
1622}
1623
1624#pragma mark C++ Base Classes
1625
1626CXXBaseSpecifier *
Greg Clayton1be10fc2010-09-29 01:12:09 +00001627ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001628{
1629 if (base_class_type)
Greg Claytone6371122010-07-30 20:30:44 +00001630 return new CXXBaseSpecifier (SourceRange(),
1631 is_virtual,
1632 base_of_class,
1633 ConvertAccessTypeToAccessSpecifier (access),
1634 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001635 return NULL;
1636}
1637
Greg Clayton0b42ac32010-07-02 01:29:13 +00001638void
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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001648bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001649ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001650{
1651 if (class_clang_type)
1652 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001653 CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
1654 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001655 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001656 cxx_record_decl->setBases(base_classes, num_base_classes);
1657 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001658 }
1659 }
1660 return false;
1661}
Greg Clayton8cf05932010-07-22 18:30:50 +00001662#pragma mark Objective C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001663
Greg Clayton1be10fc2010-09-29 01:12:09 +00001664clang_type_t
Greg Clayton8cf05932010-07-22 18:30:50 +00001665ClangASTContext::CreateObjCClass
1666(
1667 const char *name,
1668 DeclContext *decl_ctx,
1669 bool isForwardDecl,
1670 bool isInternal
1671)
1672{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001673 ASTContext *ast = getASTContext();
1674 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001675 assert (name && name[0]);
1676 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001677 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001678
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.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001684 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001685 decl_ctx,
1686 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001687 &ast->Idents.get(name),
Greg Clayton8cf05932010-07-22 18:30:50 +00001688 SourceLocation(),
1689 isForwardDecl,
1690 isInternal);
Greg Clayton9e409562010-07-28 02:04:09 +00001691
Greg Clayton6beaaa62011-01-17 03:46:26 +00001692 return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001693}
1694
1695bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001696ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton8cf05932010-07-22 18:30:50 +00001697{
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(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001727 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001728 clang_type_t class_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001729 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001730 clang_type_t ivar_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001731 AccessType access,
1732 uint32_t bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001733 bool is_synthesized
Greg Clayton8cf05932010-07-22 18:30:50 +00001734)
1735{
1736 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1737 return false;
1738
Greg Clayton6beaaa62011-01-17 03:46:26 +00001739 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton8cf05932010-07-22 18:30:50 +00001740
Greg Clayton6beaaa62011-01-17 03:46:26 +00001741 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001742 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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001760 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());
Greg Clayton8cf05932010-07-22 18:30:50 +00001762 }
1763
Greg Clayton6beaaa62011-01-17 03:46:26 +00001764 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast,
Greg Clayton9e409562010-07-28 02:04:09 +00001765 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,
Greg Clayton0fffff52010-09-24 05:15:53 +00001772 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001773
1774 if (field)
1775 {
1776 class_interface_decl->addDecl(field);
1777 return true;
1778 }
Greg Clayton8cf05932010-07-22 18:30:50 +00001779 }
1780 }
1781 }
1782 return false;
1783}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001784
Greg Clayton9e409562010-07-28 02:04:09 +00001785
1786bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001787ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9e409562010-07-28 02:04:09 +00001788{
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}
Greg Clayton0fffff52010-09-24 05:15:53 +00001817
Greg Clayton1be10fc2010-09-29 01:12:09 +00001818ObjCMethodDecl *
Greg Clayton0fffff52010-09-24 05:15:53 +00001819ClangASTContext::AddMethodToObjCObjectType
1820(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001821 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001822 clang_type_t class_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001823 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton1be10fc2010-09-29 01:12:09 +00001824 clang_type_t method_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001825 lldb::AccessType access
1826)
1827{
1828 if (class_opaque_type == NULL || method_opaque_type == NULL)
1829 return NULL;
1830
Greg Clayton6beaaa62011-01-17 03:46:26 +00001831 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton0fffff52010-09-24 05:15:53 +00001832
Greg Clayton6beaaa62011-01-17 03:46:26 +00001833 assert (ast != NULL);
Greg Clayton0fffff52010-09-24 05:15:53 +00001834 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;
Greg Clayton9e409562010-07-28 02:04:09 +00001851
Greg Clayton0fffff52010-09-24 05:15:53 +00001852 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
Greg Clayton450e3f32010-10-12 02:24:53 +00001861 size_t len = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +00001862 const char *start;
Greg Clayton450e3f32010-10-12 02:24:53 +00001863 //printf ("name = '%s'\n", name);
1864
1865 unsigned num_selectors_with_args = 0;
1866 for (start = selector_start;
Greg Clayton0fffff52010-09-24 05:15:53 +00001867 start && *start != '\0' && *start != ']';
Greg Clayton450e3f32010-10-12 02:24:53 +00001868 start += len)
Greg Clayton0fffff52010-09-24 05:15:53 +00001869 {
Greg Clayton450e3f32010-10-12 02:24:53 +00001870 len = ::strcspn(start, ":]");
Greg Clayton90f90cd2010-10-27 04:01:14 +00001871 bool has_arg = (start[len] == ':');
1872 if (has_arg)
Greg Clayton450e3f32010-10-12 02:24:53 +00001873 ++num_selectors_with_args;
Greg Clayton0fffff52010-09-24 05:15:53 +00001874 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton90f90cd2010-10-27 04:01:14 +00001875 if (has_arg)
1876 len += 1;
Greg Clayton0fffff52010-09-24 05:15:53 +00001877 }
1878
1879
1880 if (selector_idents.size() == 0)
1881 return 0;
1882
Greg Clayton6beaaa62011-01-17 03:46:26 +00001883 clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton0fffff52010-09-24 05:15:53 +00001884 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
Greg Clayton6beaaa62011-01-17 03:46:26 +00001907 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001908 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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001931 params.push_back (ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001932 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
Greg Clayton6beaaa62011-01-17 03:46:26 +00001942 objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args);
Greg Clayton0fffff52010-09-24 05:15:53 +00001943 }
1944
1945 class_interface_decl->addDecl (objc_method_decl);
1946
1947
1948 return objc_method_decl;
1949}
1950
1951
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001952uint32_t
Greg Clayton73b472d2010-10-27 03:32:59 +00001953ClangASTContext::GetTypeInfo
1954(
1955 clang_type_t clang_type,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001956 clang::ASTContext *ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00001957 clang_type_t *pointee_or_element_clang_type
1958)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001959{
1960 if (clang_type == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001961 return 0;
1962
1963 if (pointee_or_element_clang_type)
1964 *pointee_or_element_clang_type = NULL;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001965
1966 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1967
1968 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1969 switch (type_class)
1970 {
Sean Callanana2424172010-10-25 00:29:48 +00001971 case clang::Type::Builtin:
1972 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1973 {
Sean Callanana2424172010-10-25 00:29:48 +00001974 case clang::BuiltinType::ObjCId:
1975 case clang::BuiltinType::ObjCClass:
Greg Clayton6beaaa62011-01-17 03:46:26 +00001976 if (ast && pointee_or_element_clang_type)
1977 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanana2424172010-10-25 00:29:48 +00001978 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00001979
1980 default:
1981 break;
Sean Callanana2424172010-10-25 00:29:48 +00001982 }
1983 return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00001984
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
Greg Clayton49462ea2011-01-15 02:52:14 +00001990 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00001991
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
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002000 case clang::Type::DependentName: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002001 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
2002 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
2003 case clang::Type::Decltype: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002004
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
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002010 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;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002014 case clang::Type::InjectedClassName: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002015
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
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002022 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002023
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
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002029 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2030 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Clayton73b472d2010-10-27 03:32:59 +00002031
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
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002037 case clang::Type::Record:
2038 if (qual_type->getAsCXXRecordDecl())
2039 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
2040 else
2041 return eTypeHasChildren | eTypeIsStructUnion;
2042 break;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002043 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
2044 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
2045 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Clayton73b472d2010-10-27 03:32:59 +00002046
2047 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002048 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00002049 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002050 pointee_or_element_clang_type);
2051
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002052 case clang::Type::TypeOfExpr: return 0;
2053 case clang::Type::TypeOf: return 0;
2054 case clang::Type::UnresolvedUsing: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002055 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
2056 default: return 0;
2057 }
2058 return 0;
2059}
2060
Greg Clayton9e409562010-07-28 02:04:09 +00002061
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002062#pragma mark Aggregate Types
2063
2064bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00002065ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002066{
2067 if (clang_type == NULL)
2068 return false;
2069
2070 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2071
Greg Clayton737b9322010-09-13 03:32:57 +00002072 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2073 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002074 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002075 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:
Greg Clayton9e409562010-07-28 02:04:09 +00002081 case clang::Type::ObjCObject:
2082 case clang::Type::ObjCInterface:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002083 return true;
2084
Greg Claytone1a916a2010-07-21 22:12:05 +00002085 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002086 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002087
2088 default:
2089 break;
2090 }
2091 // The clang type does have a value
2092 return false;
2093}
2094
2095uint32_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00002096ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002097{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002098 if (clang_type == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002099 return 0;
2100
2101 uint32_t num_children = 0;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002102 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00002103 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2104 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002105 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002106 case clang::Type::Builtin:
2107 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2108 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002109 case clang::BuiltinType::ObjCId: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002110 case clang::BuiltinType::ObjCClass: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002111 num_children = 1;
Greg Clayton73b472d2010-10-27 03:32:59 +00002112 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002113
2114 default:
2115 break;
2116 }
2117 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002118
Greg Clayton49462ea2011-01-15 02:52:14 +00002119 case clang::Type::Complex: return 0;
Greg Clayton54979cd2010-12-15 05:08:08 +00002120
Greg Claytone1a916a2010-07-21 22:12:05 +00002121 case clang::Type::Record:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002122 if (ClangASTContext::GetCompleteType (ast, clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002123 {
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
Greg Clayton9e409562010-07-28 02:04:09 +00002163 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:
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002194 {
2195 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
2196 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002197 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2198 pointee_type.getAsOpaquePtr(),
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002199 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;
Greg Clayton9e409562010-07-28 02:04:09 +00002207
Greg Claytone1a916a2010-07-21 22:12:05 +00002208 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002209 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2210 break;
2211
Greg Claytone1a916a2010-07-21 22:12:05 +00002212 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002213 {
2214 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002215 QualType pointee_type (pointer_type->getPointeeType());
Greg Clayton6beaaa62011-01-17 03:46:26 +00002216 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2217 pointee_type.getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00002218 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002219 if (num_pointee_children == 0)
Greg Clayton54979cd2010-12-15 05:08:08 +00002220 {
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 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002225 else
2226 num_children = num_pointee_children;
2227 }
2228 break;
2229
Greg Clayton73b472d2010-10-27 03:32:59 +00002230 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();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002235 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2236 pointee_type.getAsOpaquePtr(),
Greg Clayton73b472d2010-10-27 03:32:59 +00002237 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
Greg Claytone1a916a2010-07-21 22:12:05 +00002247 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002248 num_children = ClangASTContext::GetNumChildren (ast,
2249 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2250 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002251 break;
2252
2253 default:
2254 break;
2255 }
2256 return num_children;
2257}
2258
Greg Clayton54979cd2010-12-15 05:08:08 +00002259// 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 {
Greg Clayton97a43712011-01-08 22:26:47 +00002274 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
Greg Clayton49462ea2011-01-15 02:52:14 +00002311 case clang::Type::Complex: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00002312 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}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002349
Greg Clayton1be10fc2010-09-29 01:12:09 +00002350clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002351ClangASTContext::GetChildClangTypeAtIndex
2352(
2353 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002354 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002355 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,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002362 uint32_t &child_bitfield_bit_offset,
2363 bool &child_is_base_class
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002364)
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,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002378 child_bitfield_bit_offset,
2379 child_is_base_class);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002380 return NULL;
2381}
2382
Greg Clayton1be10fc2010-09-29 01:12:09 +00002383clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002384ClangASTContext::GetChildClangTypeAtIndex
2385(
Greg Clayton6beaaa62011-01-17 03:46:26 +00002386 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002387 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002388 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002389 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,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002396 uint32_t &child_bitfield_bit_offset,
2397 bool &child_is_base_class
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002398)
2399{
2400 if (parent_clang_type == NULL)
2401 return NULL;
2402
Greg Clayton6beaaa62011-01-17 03:46:26 +00002403 if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002404 {
2405 uint32_t bit_offset;
2406 child_bitfield_bit_size = 0;
2407 child_bitfield_bit_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002408 child_is_base_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002409 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00002410 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2411 switch (parent_type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002412 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002413 case clang::Type::Builtin:
2414 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2415 {
2416 case clang::BuiltinType::ObjCId:
2417 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00002418 child_name = "isa";
Greg Clayton6beaaa62011-01-17 03:46:26 +00002419 child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
2420 return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002421
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002422 default:
2423 break;
2424 }
2425 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002426
Greg Claytone1a916a2010-07-21 22:12:05 +00002427 case clang::Type::Record:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002428 if (ClangASTContext::GetCompleteType (ast, parent_clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002429 {
2430 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2431 const RecordDecl *record_decl = record_type->getDecl();
2432 assert(record_decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00002433 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002434 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())
Sean Callanan79439e82010-11-18 02:56:27 +00002462 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002463 else
Sean Callanan79439e82010-11-18 02:56:27 +00002464 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002465
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
Greg Clayton6beaaa62011-01-17 03:46:26 +00002473 uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002474
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;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002478 child_is_base_class = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002479 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 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002486 // 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.
Greg Clayton6beaaa62011-01-17 03:46:26 +00002499 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
Greg Claytonc982c762010-07-09 20:39:50 +00002500 assert(field_idx < record_layout.getFieldCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002501
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;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002507 if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002508 child_bitfield_bit_offset = bit_offset % 8;
2509
2510 return field->getType().getAsOpaquePtr();
2511 }
2512 }
2513 }
2514 break;
2515
Greg Clayton9e409562010-07-28 02:04:09 +00002516 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
Greg Clayton6beaaa62011-01-17 03:46:26 +00002529 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
Greg Clayton9e409562010-07-28 02:04:09 +00002530 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2531 if (superclass_interface_decl)
2532 {
2533 if (omit_empty_base_classes)
2534 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002535 if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9e409562010-07-28 02:04:09 +00002536 {
2537 if (idx == 0)
2538 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002539 QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
Greg Clayton9e409562010-07-28 02:04:09 +00002540
2541
2542 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2543
Greg Clayton6beaaa62011-01-17 03:46:26 +00002544 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002545
2546 child_byte_size = ivar_type_info.first / 8;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002547 child_byte_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002548 child_is_base_class = true;
Greg Clayton9e409562010-07-28 02:04:09 +00002549
2550 return ivar_qual_type.getAsOpaquePtr();
2551 }
2552
2553 ++child_idx;
2554 }
2555 }
2556 else
2557 ++child_idx;
2558 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002559
2560 const uint32_t superclass_idx = child_idx;
Greg Clayton9e409562010-07-28 02:04:09 +00002561
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
Greg Clayton6beaaa62011-01-17 03:46:26 +00002576 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002577
2578 child_byte_size = ivar_type_info.first / 8;
2579
2580 // Figure out the field offset within the current struct/union/class type
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002581 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9e409562010-07-28 02:04:09 +00002582 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 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002596 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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002601 return GetChildClangTypeAtIndex (ast,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002602 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,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002611 child_bitfield_bit_offset,
2612 child_is_base_class);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002613 }
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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002625 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002626 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 }
Greg Clayton9e409562010-07-28 02:04:09 +00002632 }
2633 break;
2634
Greg Claytone1a916a2010-07-21 22:12:05 +00002635 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002636 {
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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002642 if (GetCompleteQualType (ast, array->getElementType()))
2643 {
2644 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002645
Greg Clayton6beaaa62011-01-17 03:46:26 +00002646 char element_name[64];
2647 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002648
Greg Clayton6beaaa62011-01-17 03:46:26 +00002649 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 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002655 }
2656 }
2657 break;
2658
Greg Claytone1a916a2010-07-21 22:12:05 +00002659 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002660 {
2661 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2662 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton97a43712011-01-08 22:26:47 +00002663
2664 // Don't dereference "void *" pointers
2665 if (pointee_type->isVoidType())
2666 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002667
2668 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2669 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002670 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002671 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,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002680 child_bitfield_bit_offset,
2681 child_is_base_class);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002682 }
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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002694 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002695 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
Greg Clayton73b472d2010-10-27 03:32:59 +00002704 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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002712 return GetChildClangTypeAtIndex (ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002713 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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002736 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Clayton73b472d2010-10-27 03:32:59 +00002737 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
Greg Claytone1a916a2010-07-21 22:12:05 +00002746 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002747 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002748 parent_name,
Sean Callanan48114472010-12-13 01:26:27 +00002749 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002750 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,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002757 child_bitfield_bit_offset,
2758 child_is_base_class);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002759 break;
2760
2761 default:
2762 break;
2763 }
2764 }
Greg Clayton19503a22010-07-23 15:37:46 +00002765 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002766}
2767
2768static inline bool
2769BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2770{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002771 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002772}
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(
Greg Clayton6beaaa62011-01-17 03:46:26 +00002945 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002946 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002947 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));
Greg Clayton737b9322010-09-13 03:32:57 +00002955 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2956 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002957 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002958 case clang::Type::Record:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002959 if (ClangASTContext::GetCompleteType (ast, clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002960 {
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...
Greg Clayton6beaaa62011-01-17 03:46:26 +00002992 IdentifierInfo & ident_ref = ast->Idents.get(name, name + strlen (name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002993 DeclarationName decl_name(&ident_ref);
2994
2995 CXXBasePaths paths;
2996 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2997 decl_name.getAsOpaquePtr(),
2998 paths))
2999 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003000 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
Greg Clayton9e409562010-07-28 02:04:09 +00003046 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
Greg Clayton6ba78152010-09-18 02:11:07 +00003062 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9e409562010-07-28 02:04:09 +00003063 {
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
Greg Clayton6beaaa62011-01-17 03:46:26 +00003084 if (GetIndexOfChildMemberWithName (ast,
3085 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00003086 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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003107 return GetIndexOfChildMemberWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003108 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3109 name,
3110 omit_empty_base_classes,
3111 child_indexes);
3112 }
3113 break;
3114
3115
Greg Claytone1a916a2010-07-21 22:12:05 +00003116 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003117 {
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// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003123// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003124//
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
Greg Claytone1a916a2010-07-21 22:12:05 +00003137// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003138// {
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// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003144// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003145// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3146// name);
3147// }
3148// }
3149// break;
3150//
Greg Claytone1a916a2010-07-21 22:12:05 +00003151 case clang::Type::LValueReference:
3152 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003153 {
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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003159 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003160 reference_type->getPointeeType().getAsOpaquePtr(),
3161 name,
3162 omit_empty_base_classes,
3163 child_indexes);
3164 }
3165 }
3166 break;
3167
Greg Claytone1a916a2010-07-21 22:12:05 +00003168 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003169 {
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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003175 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003176 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// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003192// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003193// 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
Greg Claytone1a916a2010-07-21 22:12:05 +00003202 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003203 return GetIndexOfChildMemberWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003204 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003205 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(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003224 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003225 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003226 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));
Greg Clayton9e409562010-07-28 02:04:09 +00003233
Greg Clayton737b9322010-09-13 03:32:57 +00003234 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9e409562010-07-28 02:04:09 +00003235
Greg Clayton737b9322010-09-13 03:32:57 +00003236 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003237 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003238 case clang::Type::Record:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003239 if (ClangASTContext::GetCompleteType (ast, clang_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003240 {
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
Greg Clayton9e409562010-07-28 02:04:09 +00003281 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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003323 return GetIndexOfChildWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003324 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3325 name,
3326 omit_empty_base_classes);
3327 }
3328 break;
3329
Greg Claytone1a916a2010-07-21 22:12:05 +00003330 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003331 {
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// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003337// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003338//
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
Greg Claytone1a916a2010-07-21 22:12:05 +00003351// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003352// {
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// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003358// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003359// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3360// name);
3361// }
3362// }
3363// break;
3364//
Greg Claytone1a916a2010-07-21 22:12:05 +00003365 case clang::Type::LValueReference:
3366 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003367 {
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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003373 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003374 reference_type->getPointeeType().getAsOpaquePtr(),
3375 name,
3376 omit_empty_base_classes);
3377 }
3378 }
3379 break;
3380
Greg Claytone1a916a2010-07-21 22:12:05 +00003381 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003382 {
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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003388 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003389 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// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003404// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003405// 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
Greg Claytone1a916a2010-07-21 22:12:05 +00003414 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003415 return GetIndexOfChildWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003416 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003417 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
Greg Clayton1be10fc2010-09-29 01:12:09 +00003430ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003431{
3432 if (tag_clang_type)
3433 {
3434 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Claytone1a916a2010-07-21 22:12:05 +00003435 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003436 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 *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003457ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003458{
3459 if (clang_type == NULL)
3460 return NULL;
3461
3462 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003463 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3464 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003465 {
Greg Clayton9e409562010-07-28 02:04:09 +00003466 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();
Sean Callanan48114472010-12-13 01:26:27 +00003485 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003486
Greg Clayton9e409562010-07-28 02:04:09 +00003487 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;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003492 }
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 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003506 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003507 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00003508 decl_ctx = ast->getTranslationUnitDecl();
3509 return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), &ast->Idents.get(name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003510 }
3511 return NULL;
3512}
3513
3514
3515#pragma mark Function Types
3516
3517FunctionDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003518ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003519{
3520 if (name)
3521 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003522 ASTContext *ast = getASTContext();
3523 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003524
3525 if (name && name[0])
3526 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003527 return FunctionDecl::Create(*ast,
3528 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003529 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003530 DeclarationName (&ast->Idents.get(name)),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003531 QualType::getFromOpaquePtr(function_clang_type),
3532 NULL,
3533 (FunctionDecl::StorageClass)storage,
3534 (FunctionDecl::StorageClass)storage,
3535 is_inline);
3536 }
3537 else
3538 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003539 return FunctionDecl::Create(*ast,
3540 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003541 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
Greg Clayton1be10fc2010-09-29 01:12:09 +00003553clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00003554ClangASTContext::CreateFunctionType (ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003555 clang_type_t result_type,
3556 clang_type_t *args,
Sean Callananc81256a2010-09-16 20:40:25 +00003557 unsigned num_args,
3558 bool is_variadic,
3559 unsigned type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003560{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003561 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003562 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?
Greg Clayton6beaaa62011-01-17 03:46:26 +00003567 return ast->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton471b31c2010-07-20 22:52:08 +00003568 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003569 qual_type_args.size(),
Sean Callananc81256a2010-09-16 20:40:25 +00003570 is_variadic,
3571 type_quals,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003572 false, // hasExceptionSpec
3573 false, // hasAnyExceptionSpec,
3574 0, // NumExs
3575 0, // const QualType *ExArray
3576 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3577}
3578
3579ParmVarDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003580ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003581{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003582 ASTContext *ast = getASTContext();
3583 assert (ast != NULL);
3584 return ParmVarDecl::Create(*ast,
3585 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003586 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003587 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callananc81256a2010-09-16 20:40:25 +00003588 QualType::getFromOpaquePtr(param_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003589 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
Greg Clayton1be10fc2010-09-29 01:12:09 +00003605clang_type_t
3606ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003607{
3608 if (element_type)
3609 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003610 ASTContext *ast = getASTContext();
3611 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003612 llvm::APInt ap_element_count (64, element_count);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003613 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003614 ap_element_count,
3615 ArrayType::Normal,
3616 0).getAsOpaquePtr(); // ElemQuals
3617 }
3618 return NULL;
3619}
3620
3621
3622#pragma mark TagDecl
3623
3624bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003625ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003626{
3627 if (clang_type)
3628 {
3629 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Claytone1a916a2010-07-21 22:12:05 +00003630 clang::Type *t = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003631 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
Greg Clayton1be10fc2010-09-29 01:12:09 +00003649ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003650{
3651 if (clang_type)
3652 {
3653 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton14372242010-09-29 03:44:17 +00003654
3655 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3656
3657 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003658 {
Greg Clayton14372242010-09-29 03:44:17 +00003659 cxx_record_decl->completeDefinition();
3660
3661 return true;
3662 }
3663
Sean Callanana2424172010-10-25 00:29:48 +00003664 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
Greg Clayton14372242010-09-29 03:44:17 +00003673 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)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003680 {
Greg Clayton14372242010-09-29 03:44:17 +00003681 /// TODO This really needs to be fixed.
3682
3683 unsigned NumPositiveBits = 1;
3684 unsigned NumNegativeBits = 0;
3685
Greg Clayton6beaaa62011-01-17 03:46:26 +00003686 ASTContext *ast = getASTContext();
Greg Claytone02b8502010-10-12 04:29:14 +00003687
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.
Greg Clayton6beaaa62011-01-17 03:46:26 +00003691 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
Greg Claytone02b8502010-10-12 04:29:14 +00003692 {
3693 if (enum_decl->getIntegerType()->isSignedIntegerType())
Greg Clayton6beaaa62011-01-17 03:46:26 +00003694 promotion_qual_type = ast->IntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003695 else
Greg Clayton6beaaa62011-01-17 03:46:26 +00003696 promotion_qual_type = ast->UnsignedIntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003697 }
3698 else
3699 promotion_qual_type = enum_decl->getIntegerType();
3700
3701 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton14372242010-09-29 03:44:17 +00003702 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003703 }
3704 }
3705 }
3706 return false;
3707}
3708
3709
3710#pragma mark Enumeration Types
3711
Greg Clayton1be10fc2010-09-29 01:12:09 +00003712clang_type_t
Greg Claytonca512b32011-01-14 04:54:56 +00003713ClangASTContext::CreateEnumerationType
3714(
3715 const char *name,
3716 DeclContext *decl_ctx,
3717 const Declaration &decl,
3718 clang_type_t integer_qual_type
3719)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003720{
3721 // TODO: Do something intelligent with the Declaration object passed in
3722 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003723 ASTContext *ast = getASTContext();
3724 assert (ast != NULL);
Greg Claytone02b8502010-10-12 04:29:14 +00003725
3726 // TODO: ask about these...
3727// const bool IsScoped = false;
3728// const bool IsFixed = false;
3729
Greg Clayton6beaaa62011-01-17 03:46:26 +00003730 EnumDecl *enum_decl = EnumDecl::Create (*ast,
Greg Claytonca512b32011-01-14 04:54:56 +00003731 decl_ctx,
Greg Claytone02b8502010-10-12 04:29:14 +00003732 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003733 name && name[0] ? &ast->Idents.get(name) : NULL,
Greg Claytone02b8502010-10-12 04:29:14 +00003734 SourceLocation(),
Sean Callanan48114472010-12-13 01:26:27 +00003735 NULL,
3736 false, // IsScoped
3737 false, // IsScopedUsingClassTag
3738 false); // IsFixed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003739 if (enum_decl)
Greg Clayton83ff3892010-09-12 23:17:56 +00003740 {
3741 // TODO: check if we should be setting the promotion type too?
3742 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00003743 return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Clayton83ff3892010-09-12 23:17:56 +00003744 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003745 return NULL;
3746}
3747
Greg Clayton1be10fc2010-09-29 01:12:09 +00003748clang_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}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003766bool
3767ClangASTContext::AddEnumerationValueToEnumerationType
3768(
Greg Clayton1be10fc2010-09-29 01:12:09 +00003769 clang_type_t enum_clang_type,
3770 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003771 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...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003781 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003782 IdentifierTable *identifier_table = getIdentifierTable();
3783
Greg Clayton6beaaa62011-01-17 03:46:26 +00003784 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003785 assert (identifier_table != NULL);
3786 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3787
Greg Claytone1a916a2010-07-21 22:12:05 +00003788 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003789 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 =
Greg Clayton6beaaa62011-01-17 03:46:26 +00003798 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003806 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
Greg Clayton1be10fc2010-09-29 01:12:09 +00003819clang_type_t
3820ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003821{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003822 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)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003829 {
3830 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3831
Greg Clayton737b9322010-09-13 03:32:57 +00003832 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3833 switch (type_class)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003834 {
3835 case clang::Type::ObjCObject:
3836 case clang::Type::ObjCInterface:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003837 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003838
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003839 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003840 return ast->getPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003841 }
3842 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003843 return NULL;
3844}
3845
Greg Clayton1be10fc2010-09-29 01:12:09 +00003846clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003847ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
3848 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003849{
3850 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003851 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003852 return NULL;
3853}
3854
Greg Clayton1be10fc2010-09-29 01:12:09 +00003855clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003856ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
3857 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003858{
3859 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003860 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003861 return NULL;
3862}
3863
Greg Clayton1be10fc2010-09-29 01:12:09 +00003864clang_type_t
3865ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Clayton9b81a312010-06-12 01:20:30 +00003866{
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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003873size_t
3874ClangASTContext::GetPointerBitSize ()
3875{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003876 ASTContext *ast = getASTContext();
3877 return ast->getTypeSize(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003878}
3879
3880bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003881ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003882{
3883 if (clang_type == NULL)
3884 return false;
3885
3886 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003887 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3888 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003889 {
Sean Callanana2424172010-10-25 00:29:48 +00003890 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:
Sean Callanana2424172010-10-25 00:29:48 +00003897 return true;
3898 }
3899 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00003900 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003901 if (target_type)
3902 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3903 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003904 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003905 if (target_type)
3906 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3907 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003908 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003909 if (target_type)
3910 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3911 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003912 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003913 if (target_type)
3914 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3915 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003916 case clang::Type::LValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003917 if (target_type)
3918 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3919 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003920 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003921 if (target_type)
3922 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3923 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003924 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00003925 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003926 default:
3927 break;
3928 }
3929 return false;
3930}
3931
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003932bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003933ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003934{
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
Greg Clayton1be10fc2010-09-29 01:12:09 +00003953ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003954{
3955 if (clang_type)
3956 {
3957 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003958 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3959 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003960 {
Sean Callanana2424172010-10-25 00:29:48 +00003961 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:
Sean Callanana2424172010-10-25 00:29:48 +00003968 return true;
3969 }
3970 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00003971 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003972 if (target_type)
3973 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3974 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003975 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003976 if (target_type)
3977 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3978 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003979 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003980 if (target_type)
3981 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3982 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003983 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003984 if (target_type)
3985 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3986 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003987 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00003988 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003989 default:
3990 break;
3991 }
3992 }
3993 return false;
3994}
3995
3996bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003997ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003998{
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
Greg Clayton8f92f0a2010-10-14 22:52:14 +00004035
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
Greg Clayton0fffff52010-09-24 05:15:53 +00004055bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004056ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004057{
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
Greg Clayton1be10fc2010-09-29 01:12:09 +00004068ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004069{
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
Greg Clayton73b472d2010-10-27 03:32:59 +00004080bool
4081ClangASTContext::IsCharType (clang_type_t clang_type)
4082{
4083 if (clang_type)
4084 return QualType::getFromOpaquePtr(clang_type)->isCharType();
4085 return false;
4086}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004087
4088bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004089ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004090{
Greg Clayton73b472d2010-10-27 03:32:59 +00004091 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))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004098 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004099 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
4100
4101 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004102 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004103 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4104 if (type_flags.Test (eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004105 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004106 // 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;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004110 }
Greg Clayton73b472d2010-10-27 03:32:59 +00004111 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004112 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004113 length = 0;
4114 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004115 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004116
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004117 }
4118 }
4119 return false;
4120}
4121
4122bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004123ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton737b9322010-09-13 03:32:57 +00004124{
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:
Sean Callanan48114472010-12-13 01:26:27 +00004136 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004137
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
Greg Clayton73b472d2010-10-27 03:32:59 +00004151size_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}
Greg Clayton737b9322010-09-13 03:32:57 +00004162
4163bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004164ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004165{
4166 if (!clang_type)
4167 return false;
4168
4169 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4170
Greg Clayton737b9322010-09-13 03:32:57 +00004171 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4172 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004173 {
Greg Claytone1a916a2010-07-21 22:12:05 +00004174 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004175 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;
Greg Claytone1a916a2010-07-21 22:12:05 +00004180 case clang::Type::IncompleteArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004181 if (member_type)
4182 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4183 if (size)
4184 *size = 0;
4185 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004186 case clang::Type::VariableArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004187 if (member_type)
4188 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4189 if (size)
4190 *size = 0;
Greg Claytone1a916a2010-07-21 22:12:05 +00004191 case clang::Type::DependentSizedArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004192 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
Greg Clayton1be10fc2010-09-29 01:12:09 +00004204clang_type_t
4205ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004206{
4207 if (clang_type)
4208 {
4209 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004210 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004211 IdentifierTable *identifier_table = getIdentifierTable();
Greg Clayton6beaaa62011-01-17 03:46:26 +00004212 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004213 assert (identifier_table != NULL);
4214 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00004215 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));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004221
4222 // Get a uniqued QualType for the typedef decl type
Greg Clayton6beaaa62011-01-17 03:46:26 +00004223 return ast->getTypedefType (decl).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004224 }
4225 return NULL;
4226}
4227
4228
4229std::string
Greg Clayton1be10fc2010-09-29 01:12:09 +00004230ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004231{
4232 std::string return_name;
4233
Greg Clayton1be10fc2010-09-29 01:12:09 +00004234 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004235
Greg Clayton1be10fc2010-09-29 01:12:09 +00004236 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004237 if (typedef_type)
4238 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00004239 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004240 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
Greg Clayton6beaaa62011-01-17 03:46:26 +00004257//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)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004258//{
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
Greg Clayton6beaaa62011-01-17 03:46:26 +00004292ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004293{
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);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004306 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004307
Greg Clayton6beaaa62011-01-17 03:46:26 +00004308 const uint64_t bit_size = ast->getTypeSize (qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004309 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}
Sean Callanan6fe64b52010-09-17 02:24:29 +00004329
4330unsigned
Greg Clayton1be10fc2010-09-29 01:12:09 +00004331ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanan6fe64b52010-09-17 02:24:29 +00004332{
4333 assert (clang_type);
4334
4335 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4336
4337 return qual_type.getQualifiers().getCVRQualifiers();
4338}
Greg Clayton6beaaa62011-01-17 03:46:26 +00004339
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