blob: f9d85ac1100c87ca27a0dda8393b7b09ee5f6342 [file] [log] [blame]
Chris Lattner24943d22010-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 Friedmanf05633b2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Sean Callananbc4f0f52010-07-08 18:16:16 +000017#define NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "clang/AST/ASTContext.h"
19#include "clang/AST/ASTImporter.h"
20#include "clang/AST/CXXInheritance.h"
Greg Clayton84f80752010-07-22 18:30:50 +000021#include "clang/AST/DeclObjC.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "clang/AST/RecordLayout.h"
23#include "clang/AST/Type.h"
24#include "clang/Basic/Builtins.h"
25#include "clang/Basic/FileManager.h"
26#include "clang/Basic/SourceManager.h"
27#include "clang/Basic/TargetInfo.h"
28#include "clang/Basic/TargetOptions.h"
29#include "clang/Frontend/FrontendOptions.h"
30#include "clang/Frontend/LangStandard.h"
Sean Callananbc4f0f52010-07-08 18:16:16 +000031#undef NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000032
Chris Lattner24943d22010-06-08 16:52:24 +000033#include "lldb/Core/dwarf.h"
34
Eli Friedmanf05633b2010-06-13 19:06:42 +000035#include <stdio.h>
36
Greg Clayton585660c2010-08-05 01:57:25 +000037using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000038using namespace lldb_private;
39using namespace llvm;
40using namespace clang;
41
Greg Clayton84f80752010-07-22 18:30:50 +000042static AccessSpecifier
Greg Clayton585660c2010-08-05 01:57:25 +000043ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000044{
45 switch (access)
46 {
Greg Clayton585660c2010-08-05 01:57:25 +000047 default: break;
48 case eAccessNone: return AS_none;
49 case eAccessPublic: return AS_public;
50 case eAccessPrivate: return AS_private;
51 case eAccessProtected: return AS_protected;
Greg Clayton84f80752010-07-22 18:30:50 +000052 }
53 return AS_none;
54}
55
56static ObjCIvarDecl::AccessControl
Greg Clayton585660c2010-08-05 01:57:25 +000057ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000058{
59 switch (access)
60 {
Greg Clayton585660c2010-08-05 01:57:25 +000061 default: break;
62 case eAccessNone: return ObjCIvarDecl::None;
63 case eAccessPublic: return ObjCIvarDecl::Public;
64 case eAccessPrivate: return ObjCIvarDecl::Private;
65 case eAccessProtected: return ObjCIvarDecl::Protected;
66 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton84f80752010-07-22 18:30:50 +000067 }
68 return ObjCIvarDecl::None;
69}
70
71
Chris Lattner24943d22010-06-08 16:52:24 +000072static void
73ParseLangArgs
74(
75 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000076 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000077)
78{
79 // FIXME: Cleanup per-file based stuff.
80
81 // Set some properties which depend soley on the input kind; it would be nice
82 // to move these to the language standard, and have the driver resolve the
83 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000084 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000085 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000086 } else if (IK == IK_ObjC ||
87 IK == IK_ObjCXX ||
88 IK == IK_PreprocessedObjC ||
89 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000090 Opts.ObjC1 = Opts.ObjC2 = 1;
91 }
92
93 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
94
95 if (LangStd == LangStandard::lang_unspecified) {
96 // Based on the base language, pick one.
97 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +000098 case IK_None:
99 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +0000100 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +0000101 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +0000102 LangStd = LangStandard::lang_opencl;
103 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000104 case IK_Asm:
105 case IK_C:
106 case IK_PreprocessedC:
107 case IK_ObjC:
108 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +0000109 LangStd = LangStandard::lang_gnu99;
110 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000111 case IK_CXX:
112 case IK_PreprocessedCXX:
113 case IK_ObjCXX:
114 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +0000115 LangStd = LangStandard::lang_gnucxx98;
116 break;
117 }
118 }
119
120 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
121 Opts.BCPLComment = Std.hasBCPLComments();
122 Opts.C99 = Std.isC99();
123 Opts.CPlusPlus = Std.isCPlusPlus();
124 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
125 Opts.Digraphs = Std.hasDigraphs();
126 Opts.GNUMode = Std.isGNUMode();
127 Opts.GNUInline = !Std.isC99();
128 Opts.HexFloats = Std.hasHexFloats();
129 Opts.ImplicitInt = Std.hasImplicitInt();
130
131 // OpenCL has some additional defaults.
132 if (LangStd == LangStandard::lang_opencl) {
133 Opts.OpenCL = 1;
134 Opts.AltiVec = 1;
135 Opts.CXXOperatorNames = 1;
136 Opts.LaxVectorConversions = 1;
137 }
138
139 // OpenCL and C++ both have bool, true, false keywords.
140 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
141
142// if (Opts.CPlusPlus)
143// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
144//
145// if (Args.hasArg(OPT_fobjc_gc_only))
146// Opts.setGCMode(LangOptions::GCOnly);
147// else if (Args.hasArg(OPT_fobjc_gc))
148// Opts.setGCMode(LangOptions::HybridGC);
149//
150// if (Args.hasArg(OPT_print_ivar_layout))
151// Opts.ObjCGCBitmapPrint = 1;
152//
153// if (Args.hasArg(OPT_faltivec))
154// Opts.AltiVec = 1;
155//
156// if (Args.hasArg(OPT_pthread))
157// Opts.POSIXThreads = 1;
158//
159// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
160// "default");
161// if (Vis == "default")
162 Opts.setVisibilityMode(LangOptions::Default);
163// else if (Vis == "hidden")
164// Opts.setVisibilityMode(LangOptions::Hidden);
165// else if (Vis == "protected")
166// Opts.setVisibilityMode(LangOptions::Protected);
167// else
168// Diags.Report(diag::err_drv_invalid_value)
169// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
170
171// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
172
173 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
174 // is specified, or -std is set to a conforming mode.
175 Opts.Trigraphs = !Opts.GNUMode;
176// if (Args.hasArg(OPT_trigraphs))
177// Opts.Trigraphs = 1;
178//
179// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
180// OPT_fno_dollars_in_identifiers,
181// !Opts.AsmPreprocessor);
182// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
183// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
184// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
185// if (Args.hasArg(OPT_fno_lax_vector_conversions))
186// Opts.LaxVectorConversions = 0;
187// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
188// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
189// Opts.Blocks = Args.hasArg(OPT_fblocks);
190// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
191// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
192// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
193// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
194// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
195// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
196// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
197// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
198// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
199// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
200// Diags);
201// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
202// Opts.ObjCConstantStringClass = getLastArgValue(Args,
203// OPT_fconstant_string_class);
204// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
205// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
206// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
207// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
208// Opts.Static = Args.hasArg(OPT_static_define);
209 Opts.OptimizeSize = 0;
210
211 // FIXME: Eliminate this dependency.
212// unsigned Opt =
213// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
214// Opts.Optimize = Opt != 0;
215 unsigned Opt = 0;
216
217 // This is the __NO_INLINE__ define, which just depends on things like the
218 // optimization level and -fno-inline, not actually whether the backend has
219 // inlining enabled.
220 //
221 // FIXME: This is affected by other options (-fno-inline).
222 Opts.NoInline = !Opt;
223
224// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
225// switch (SSP) {
226// default:
227// Diags.Report(diag::err_drv_invalid_value)
228// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
229// break;
230// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
231// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
232// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
233// }
234}
235
Chris Lattner24943d22010-06-08 16:52:24 +0000236
Chris Lattner24943d22010-06-08 16:52:24 +0000237ClangASTContext::ClangASTContext(const char *target_triple) :
238 m_target_triple(),
239 m_ast_context_ap(),
240 m_language_options_ap(),
241 m_source_manager_ap(),
242 m_diagnostic_ap(),
243 m_target_options_ap(),
244 m_target_info_ap(),
245 m_identifier_table_ap(),
246 m_selector_table_ap(),
247 m_builtins_ap()
248{
249 if (target_triple && target_triple[0])
250 m_target_triple.assign (target_triple);
251}
252
253//----------------------------------------------------------------------
254// Destructor
255//----------------------------------------------------------------------
256ClangASTContext::~ClangASTContext()
257{
258 m_builtins_ap.reset();
259 m_selector_table_ap.reset();
260 m_identifier_table_ap.reset();
261 m_target_info_ap.reset();
262 m_target_options_ap.reset();
263 m_diagnostic_ap.reset();
264 m_source_manager_ap.reset();
265 m_language_options_ap.reset();
266 m_ast_context_ap.reset();
267}
268
269
270void
271ClangASTContext::Clear()
272{
273 m_ast_context_ap.reset();
274 m_language_options_ap.reset();
275 m_source_manager_ap.reset();
276 m_diagnostic_ap.reset();
277 m_target_options_ap.reset();
278 m_target_info_ap.reset();
279 m_identifier_table_ap.reset();
280 m_selector_table_ap.reset();
281 m_builtins_ap.reset();
282}
283
284const char *
285ClangASTContext::GetTargetTriple ()
286{
287 return m_target_triple.c_str();
288}
289
290void
291ClangASTContext::SetTargetTriple (const char *target_triple)
292{
293 Clear();
294 m_target_triple.assign(target_triple);
295}
296
297
298ASTContext *
299ClangASTContext::getASTContext()
300{
301 if (m_ast_context_ap.get() == NULL)
302 {
303 m_ast_context_ap.reset(
304 new ASTContext(
305 *getLanguageOptions(),
306 *getSourceManager(),
307 *getTargetInfo(),
308 *getIdentifierTable(),
309 *getSelectorTable(),
Greg Clayton6e713402010-07-30 20:30:44 +0000310 *getBuiltinContext(),
311 0));
Chris Lattner24943d22010-06-08 16:52:24 +0000312 }
313 return m_ast_context_ap.get();
314}
315
316Builtin::Context *
317ClangASTContext::getBuiltinContext()
318{
319 if (m_builtins_ap.get() == NULL)
320 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
321 return m_builtins_ap.get();
322}
323
324IdentifierTable *
325ClangASTContext::getIdentifierTable()
326{
327 if (m_identifier_table_ap.get() == NULL)
328 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
329 return m_identifier_table_ap.get();
330}
331
332LangOptions *
333ClangASTContext::getLanguageOptions()
334{
335 if (m_language_options_ap.get() == NULL)
336 {
337 m_language_options_ap.reset(new LangOptions());
Greg Claytone41c4b22010-06-13 17:34:29 +0000338 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
339// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner24943d22010-06-08 16:52:24 +0000340 }
341 return m_language_options_ap.get();
342}
343
344SelectorTable *
345ClangASTContext::getSelectorTable()
346{
347 if (m_selector_table_ap.get() == NULL)
348 m_selector_table_ap.reset (new SelectorTable());
349 return m_selector_table_ap.get();
350}
351
Greg Clayton1674b122010-07-21 22:12:05 +0000352clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000353ClangASTContext::getSourceManager()
354{
355 if (m_source_manager_ap.get() == NULL)
Greg Clayton1674b122010-07-21 22:12:05 +0000356 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic()));
Chris Lattner24943d22010-06-08 16:52:24 +0000357 return m_source_manager_ap.get();
358}
359
360Diagnostic *
361ClangASTContext::getDiagnostic()
362{
363 if (m_diagnostic_ap.get() == NULL)
364 m_diagnostic_ap.reset(new Diagnostic());
365 return m_diagnostic_ap.get();
366}
367
368TargetOptions *
369ClangASTContext::getTargetOptions()
370{
371 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
372 {
373 m_target_options_ap.reset (new TargetOptions());
374 if (m_target_options_ap.get())
375 m_target_options_ap->Triple = m_target_triple;
376 }
377 return m_target_options_ap.get();
378}
379
380
381TargetInfo *
382ClangASTContext::getTargetInfo()
383{
384 // target_triple should be something like "x86_64-apple-darwin10"
385 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
386 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
387 return m_target_info_ap.get();
388}
389
390#pragma mark Basic Types
391
392static inline bool
393QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
394{
395 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
396 if (qual_type_bit_size == bit_size)
397 return true;
398 return false;
399}
400
401void *
Greg Clayton585660c2010-08-05 01:57:25 +0000402ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000403{
404 ASTContext *ast_context = getASTContext();
405
406 assert (ast_context != NULL);
407
408 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
409}
410
411void *
Greg Clayton585660c2010-08-05 01:57:25 +0000412ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000413{
414 if (!ast_context)
415 return NULL;
416
417 switch (encoding)
418 {
Greg Clayton585660c2010-08-05 01:57:25 +0000419 case eEncodingInvalid:
Chris Lattner24943d22010-06-08 16:52:24 +0000420 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
421 return ast_context->VoidPtrTy.getAsOpaquePtr();
422 break;
423
Greg Clayton585660c2010-08-05 01:57:25 +0000424 case eEncodingUint:
Chris Lattner24943d22010-06-08 16:52:24 +0000425 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
426 return ast_context->UnsignedCharTy.getAsOpaquePtr();
427 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
428 return ast_context->UnsignedShortTy.getAsOpaquePtr();
429 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
430 return ast_context->UnsignedIntTy.getAsOpaquePtr();
431 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
432 return ast_context->UnsignedLongTy.getAsOpaquePtr();
433 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
434 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
435 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
436 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
437 break;
438
Greg Clayton585660c2010-08-05 01:57:25 +0000439 case eEncodingSint:
Chris Lattner24943d22010-06-08 16:52:24 +0000440 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
441 return ast_context->CharTy.getAsOpaquePtr();
442 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
443 return ast_context->ShortTy.getAsOpaquePtr();
444 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
445 return ast_context->IntTy.getAsOpaquePtr();
446 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
447 return ast_context->LongTy.getAsOpaquePtr();
448 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
449 return ast_context->LongLongTy.getAsOpaquePtr();
450 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
451 return ast_context->Int128Ty.getAsOpaquePtr();
452 break;
453
Greg Clayton585660c2010-08-05 01:57:25 +0000454 case eEncodingIEEE754:
Chris Lattner24943d22010-06-08 16:52:24 +0000455 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
456 return ast_context->FloatTy.getAsOpaquePtr();
457 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
458 return ast_context->DoubleTy.getAsOpaquePtr();
459 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
460 return ast_context->LongDoubleTy.getAsOpaquePtr();
461 break;
462
Greg Clayton585660c2010-08-05 01:57:25 +0000463 case eEncodingVector:
Chris Lattner24943d22010-06-08 16:52:24 +0000464 default:
465 break;
466 }
467
468 return NULL;
469}
470
471void *
472ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
473{
474 ASTContext *ast_context = getASTContext();
475
476 #define streq(a,b) strcmp(a,b) == 0
477 assert (ast_context != NULL);
478 if (ast_context)
479 {
480 switch (dw_ate)
481 {
482 default:
483 break;
484
485 case DW_ATE_address:
486 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
487 return ast_context->VoidPtrTy.getAsOpaquePtr();
488 break;
489
490 case DW_ATE_boolean:
491 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
492 return ast_context->BoolTy.getAsOpaquePtr();
493 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
494 return ast_context->UnsignedCharTy.getAsOpaquePtr();
495 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
496 return ast_context->UnsignedShortTy.getAsOpaquePtr();
497 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
498 return ast_context->UnsignedIntTy.getAsOpaquePtr();
499 break;
500
501 case DW_ATE_complex_float:
502 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
503 return ast_context->FloatComplexTy.getAsOpaquePtr();
504 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
505 return ast_context->DoubleComplexTy.getAsOpaquePtr();
506 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
507 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
508 break;
509
510 case DW_ATE_float:
511 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
512 return ast_context->FloatTy.getAsOpaquePtr();
513 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
514 return ast_context->DoubleTy.getAsOpaquePtr();
515 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
516 return ast_context->LongDoubleTy.getAsOpaquePtr();
517 break;
518
519 case DW_ATE_signed:
520 if (type_name)
521 {
522 if (streq(type_name, "int") ||
523 streq(type_name, "signed int"))
524 {
525 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
526 return ast_context->IntTy.getAsOpaquePtr();
527 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
528 return ast_context->Int128Ty.getAsOpaquePtr();
529 }
530
531 if (streq(type_name, "long int") ||
532 streq(type_name, "long long int") ||
533 streq(type_name, "signed long long"))
534 {
535 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
536 return ast_context->LongTy.getAsOpaquePtr();
537 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
538 return ast_context->LongLongTy.getAsOpaquePtr();
539 }
540
541 if (streq(type_name, "short") ||
542 streq(type_name, "short int") ||
543 streq(type_name, "signed short") ||
544 streq(type_name, "short signed int"))
545 {
546 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
547 return ast_context->ShortTy.getAsOpaquePtr();
548 }
549
550 if (streq(type_name, "char") ||
551 streq(type_name, "signed char"))
552 {
553 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
554 return ast_context->CharTy.getAsOpaquePtr();
555 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
556 return ast_context->SignedCharTy.getAsOpaquePtr();
557 }
558
559 if (streq(type_name, "wchar_t"))
560 {
561 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
562 return ast_context->WCharTy.getAsOpaquePtr();
563 }
564
565 }
566 // We weren't able to match up a type name, just search by size
567 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
568 return ast_context->CharTy.getAsOpaquePtr();
569 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
570 return ast_context->ShortTy.getAsOpaquePtr();
571 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
572 return ast_context->IntTy.getAsOpaquePtr();
573 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
574 return ast_context->LongTy.getAsOpaquePtr();
575 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
576 return ast_context->LongLongTy.getAsOpaquePtr();
577 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
578 return ast_context->Int128Ty.getAsOpaquePtr();
579 break;
580
581 case DW_ATE_signed_char:
582 if (type_name)
583 {
584 if (streq(type_name, "signed char"))
585 {
586 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
587 return ast_context->SignedCharTy.getAsOpaquePtr();
588 }
589 }
590 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
591 return ast_context->CharTy.getAsOpaquePtr();
592 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
593 return ast_context->SignedCharTy.getAsOpaquePtr();
594 break;
595
596 case DW_ATE_unsigned:
597 if (type_name)
598 {
599 if (streq(type_name, "unsigned int"))
600 {
601 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
602 return ast_context->UnsignedIntTy.getAsOpaquePtr();
603 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
604 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
605 }
606
607 if (streq(type_name, "unsigned int") ||
608 streq(type_name, "long unsigned int") ||
609 streq(type_name, "unsigned long long"))
610 {
611 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
612 return ast_context->UnsignedLongTy.getAsOpaquePtr();
613 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
614 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
615 }
616
617 if (streq(type_name, "unsigned short") ||
618 streq(type_name, "short unsigned int"))
619 {
620 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
621 return ast_context->UnsignedShortTy.getAsOpaquePtr();
622 }
623 if (streq(type_name, "unsigned char"))
624 {
625 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
626 return ast_context->UnsignedCharTy.getAsOpaquePtr();
627 }
628
629 }
630 // We weren't able to match up a type name, just search by size
631 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
632 return ast_context->UnsignedCharTy.getAsOpaquePtr();
633 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
634 return ast_context->UnsignedShortTy.getAsOpaquePtr();
635 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
636 return ast_context->UnsignedIntTy.getAsOpaquePtr();
637 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
638 return ast_context->UnsignedLongTy.getAsOpaquePtr();
639 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
640 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
641 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
642 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
643 break;
644
645 case DW_ATE_unsigned_char:
646 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
647 return ast_context->UnsignedCharTy.getAsOpaquePtr();
648 break;
649
650 case DW_ATE_imaginary_float:
651 break;
652 }
653 }
654 // This assert should fire for anything that we don't catch above so we know
655 // to fix any issues we run into.
656 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
657 return NULL;
658}
659
660void *
Sean Callanana751f7b2010-09-17 02:24:29 +0000661ClangASTContext::GetBuiltInType_void(clang::ASTContext *ast_context)
Chris Lattner24943d22010-06-08 16:52:24 +0000662{
Sean Callanana751f7b2010-09-17 02:24:29 +0000663 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000664}
665
666void *
Greg Clayton960d6a42010-08-03 00:35:52 +0000667ClangASTContext::GetBuiltInType_objc_id()
668{
669 return getASTContext()->getObjCIdType().getAsOpaquePtr();
670}
671
672void *
673ClangASTContext::GetBuiltInType_objc_Class()
674{
675 return getASTContext()->getObjCClassType().getAsOpaquePtr();
676}
677
678void *
679ClangASTContext::GetBuiltInType_objc_selector()
680{
681 return getASTContext()->getObjCSelType().getAsOpaquePtr();
682}
683
684void *
Chris Lattner24943d22010-06-08 16:52:24 +0000685ClangASTContext::GetCStringType (bool is_const)
686{
687 QualType char_type(getASTContext()->CharTy);
688
689 if (is_const)
690 char_type.addConst();
691
692 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
693}
694
695void *
696ClangASTContext::GetVoidPtrType (bool is_const)
697{
698 return GetVoidPtrType(getASTContext(), is_const);
699}
700
701void *
702ClangASTContext::GetVoidPtrType (clang::ASTContext *ast_context, bool is_const)
703{
704 QualType void_ptr_type(ast_context->VoidPtrTy);
705
706 if (is_const)
707 void_ptr_type.addConst();
708
709 return void_ptr_type.getAsOpaquePtr();
710}
711
712void *
713ClangASTContext::CopyType(clang::ASTContext *dest_context,
714 clang::ASTContext *source_context,
Greg Clayton84f80752010-07-22 18:30:50 +0000715 void *clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000716{
717 Diagnostic diagnostics;
718 FileManager file_manager;
719 ASTImporter importer(diagnostics,
720 *dest_context, file_manager,
721 *source_context, file_manager);
722 QualType ret = importer.Import(QualType::getFromOpaquePtr(clang_type));
723 return ret.getAsOpaquePtr();
724}
725
Sean Callanan8d825062010-07-16 00:00:27 +0000726bool
727ClangASTContext::AreTypesSame(clang::ASTContext *ast_context,
Sean Callanan5510ddd2010-07-15 22:30:52 +0000728 void *type1,
729 void *type2)
730{
731 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
732 QualType::getFromOpaquePtr(type2));
733}
734
Chris Lattner24943d22010-06-08 16:52:24 +0000735#pragma mark CVR modifiers
736
737void *
738ClangASTContext::AddConstModifier (void *clang_type)
739{
740 if (clang_type)
741 {
742 QualType result(QualType::getFromOpaquePtr(clang_type));
743 result.addConst();
744 return result.getAsOpaquePtr();
745 }
746 return NULL;
747}
748
749void *
750ClangASTContext::AddRestrictModifier (void *clang_type)
751{
752 if (clang_type)
753 {
754 QualType result(QualType::getFromOpaquePtr(clang_type));
755 result.getQualifiers().setRestrict (true);
756 return result.getAsOpaquePtr();
757 }
758 return NULL;
759}
760
761void *
762ClangASTContext::AddVolatileModifier (void *clang_type)
763{
764 if (clang_type)
765 {
766 QualType result(QualType::getFromOpaquePtr(clang_type));
767 result.getQualifiers().setVolatile (true);
768 return result.getAsOpaquePtr();
769 }
770 return NULL;
771}
772
773#pragma mark Structure, Unions, Classes
774
775void *
Greg Clayton585660c2010-08-05 01:57:25 +0000776ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000777{
778 ASTContext *ast_context = getASTContext();
779 assert (ast_context != NULL);
780
781 if (decl_ctx == NULL)
782 decl_ctx = ast_context->getTranslationUnitDecl();
783
Greg Clayton9488b742010-07-28 02:04:09 +0000784
Greg Clayton585660c2010-08-05 01:57:25 +0000785 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000786 {
787 bool isForwardDecl = false;
788 bool isInternal = false;
789 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
790 }
791
Chris Lattner24943d22010-06-08 16:52:24 +0000792 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
793 // we will need to update this code. I was told to currently always use
794 // the CXXRecordDecl class since we often don't know from debug information
795 // if something is struct or a class, so we default to always use the more
796 // complete definition just in case.
797 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
798 (TagDecl::TagKind)kind,
799 decl_ctx,
800 SourceLocation(),
801 name && name[0] ? &ast_context->Idents.get(name) : NULL);
802
803 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
804}
805
Greg Clayton412440a2010-09-23 01:09:21 +0000806CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +0000807ClangASTContext::AddMethodToCXXRecordType
808(
Greg Clayton412440a2010-09-23 01:09:21 +0000809 clang::ASTContext *ast_context,
810 void *record_opaque_type,
811 const char *name,
812 void *method_opaque_type,
813 lldb::AccessType access,
814 bool is_virtual
815)
Sean Callanan79523002010-09-17 02:58:26 +0000816{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000817 if (!record_opaque_type || !method_opaque_type || !name)
Sean Callanan79523002010-09-17 02:58:26 +0000818 return false;
819
820 assert(ast_context);
821
822 IdentifierTable *identifier_table = &ast_context->Idents;
823
824 assert(identifier_table);
825
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000826 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Sean Callanan79523002010-09-17 02:58:26 +0000827 clang::Type *record_type(record_qual_type.getTypePtr());
828
829 if (!record_type)
Greg Clayton412440a2010-09-23 01:09:21 +0000830 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +0000831
832 RecordType *record_recty(dyn_cast<RecordType>(record_type));
833
834 if (!record_recty)
Greg Clayton412440a2010-09-23 01:09:21 +0000835 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +0000836
837 RecordDecl *record_decl = record_recty->getDecl();
838
839 if (!record_decl)
Greg Clayton412440a2010-09-23 01:09:21 +0000840 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +0000841
842 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
843
844 if (!cxx_record_decl)
Greg Clayton412440a2010-09-23 01:09:21 +0000845 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +0000846
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000847 QualType method_qual_type(QualType::getFromOpaquePtr(method_opaque_type));
848
Sean Callanan79523002010-09-17 02:58:26 +0000849 CXXMethodDecl *cxx_method_decl = CXXMethodDecl::Create(*ast_context,
850 cxx_record_decl,
851 SourceLocation(),
852 DeclarationName(&identifier_table->get(name)),
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000853 method_qual_type,
Sean Callanan79523002010-09-17 02:58:26 +0000854 NULL);
855
Greg Clayton412440a2010-09-23 01:09:21 +0000856 cxx_method_decl->setAccess (ConvertAccessTypeToAccessSpecifier (access));
857 cxx_method_decl->setVirtualAsWritten (is_virtual);
858
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000859 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000860 clang::Type *method_type(method_qual_type.getTypePtr());
861
862 if (!method_type)
Greg Clayton412440a2010-09-23 01:09:21 +0000863 return NULL;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000864
865 FunctionProtoType *method_funprototy(dyn_cast<FunctionProtoType>(method_type));
866
867 if (!method_funprototy)
Greg Clayton412440a2010-09-23 01:09:21 +0000868 return NULL;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000869
870 unsigned int num_params = method_funprototy->getNumArgs();
871
872 ParmVarDecl *params[num_params];
873
874 for (int param_index = 0;
875 param_index < num_params;
876 ++param_index)
877 {
878 params[param_index] = ParmVarDecl::Create(*ast_context,
879 cxx_method_decl,
880 SourceLocation(),
881 NULL, // anonymous
882 method_funprototy->getArgType(param_index),
883 NULL,
884 VarDecl::Auto,
885 VarDecl::Auto,
886 NULL);
887 }
888
889 cxx_method_decl->setParams(params, num_params);
890
Sean Callanan79523002010-09-17 02:58:26 +0000891 cxx_record_decl->addDecl(cxx_method_decl);
892
Greg Clayton412440a2010-09-23 01:09:21 +0000893 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +0000894}
895
896bool
Greg Clayton84f80752010-07-22 18:30:50 +0000897ClangASTContext::AddFieldToRecordType
898(
Sean Callanan60a0ced2010-09-16 20:01:08 +0000899 clang::ASTContext *ast_context,
Greg Clayton84f80752010-07-22 18:30:50 +0000900 void *record_clang_type,
901 const char *name,
902 void *field_type,
903 AccessType access,
904 uint32_t bitfield_bit_size
905)
Chris Lattner24943d22010-06-08 16:52:24 +0000906{
907 if (record_clang_type == NULL || field_type == NULL)
908 return false;
909
Sean Callanan60a0ced2010-09-16 20:01:08 +0000910 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +0000911
912 assert (ast_context != NULL);
913 assert (identifier_table != NULL);
914
915 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
916
Greg Clayton1674b122010-07-21 22:12:05 +0000917 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000918 if (clang_type)
919 {
920 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
921
922 if (record_type)
923 {
924 RecordDecl *record_decl = record_type->getDecl();
925
926 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
927 if (cxx_record_decl)
Greg Claytona4e27af2010-09-22 00:40:49 +0000928 {
929 // NOTE: we currently have some fixes that should be placed
930 // into clang that will automatically set if a record is empty
931 // when each field is added (during the addDecl() method call
932 // below) so this code should be able to come out when those
933 // changes make it into llvm/clang, then we can remove this
934 // code...
935 // Currently SEMA is using the accessors manually to set
936 // whether a class is empty, is POD, is aggregate, and more.
937 // This code will be moved into CXXRecordDecl so everyone
938 // can benefit.
939 // This will currently work for everything except zero sized
940 // bitfields which we currently aren't detecting anyway from the
941 // DWARF so it should be ok for now.
Chris Lattner24943d22010-06-08 16:52:24 +0000942 cxx_record_decl->setEmpty (false);
Greg Claytona4e27af2010-09-22 00:40:49 +0000943 }
Chris Lattner24943d22010-06-08 16:52:24 +0000944
945 clang::Expr *bit_width = NULL;
946 if (bitfield_bit_size != 0)
947 {
948 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
949 bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
950 }
Greg Clayton84f80752010-07-22 18:30:50 +0000951 FieldDecl *field = FieldDecl::Create (*ast_context,
952 record_decl,
953 SourceLocation(),
954 name ? &identifier_table->get(name) : NULL, // Identifier
955 QualType::getFromOpaquePtr(field_type), // Field type
956 NULL, // DeclaratorInfo *
957 bit_width, // BitWidth
958 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +0000959
Greg Clayton84f80752010-07-22 18:30:50 +0000960 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +0000961
962 if (field)
963 {
964 record_decl->addDecl(field);
Greg Claytona4e27af2010-09-22 00:40:49 +0000965
966 // NOTE: we currently have some fixes that should be placed
967 // into clang that will automatically set if a record is POD
968 // when each field is added (during the addDecl() method call
969 // above) so this code should be able to come out when those
970 // changes make it into llvm/clang, then we can remove this
971 // code...
972 // Currently SEMA is using the accessors manually to set
973 // whether a class is empty, is POD, is aggregate, and more.
974 // This code will be moved into CXXRecordDecl so everyone
975 // can benefit.
976
Greg Clayton22d5fe32010-09-22 00:24:45 +0000977 if (cxx_record_decl->isPOD())
978 {
979 if (!field->getType()->isPODType())
980 cxx_record_decl->setPOD (false);
981 return true;
982 }
Chris Lattner24943d22010-06-08 16:52:24 +0000983 }
984 }
Greg Clayton9488b742010-07-28 02:04:09 +0000985 else
986 {
987 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
988 if (objc_class_type)
989 {
990 bool isSynthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +0000991 ClangASTContext::AddObjCClassIVar (ast_context,
992 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +0000993 name,
994 field_type,
995 access,
996 bitfield_bit_size,
997 isSynthesized);
998 }
999 }
Chris Lattner24943d22010-06-08 16:52:24 +00001000 }
1001 return false;
1002}
1003
1004bool
1005ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1006{
1007 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1008}
1009
1010bool
1011ClangASTContext::FieldIsBitfield
1012(
1013 ASTContext *ast_context,
1014 FieldDecl* field,
1015 uint32_t& bitfield_bit_size
1016)
1017{
1018 if (ast_context == NULL || field == NULL)
1019 return false;
1020
1021 if (field->isBitField())
1022 {
1023 Expr* bit_width_expr = field->getBitWidth();
1024 if (bit_width_expr)
1025 {
1026 llvm::APSInt bit_width_apsint;
1027 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1028 {
1029 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1030 return true;
1031 }
1032 }
1033 }
1034 return false;
1035}
1036
1037bool
1038ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1039{
1040 if (record_decl == NULL)
1041 return false;
1042
1043 if (!record_decl->field_empty())
1044 return true;
1045
1046 // No fields, lets check this is a CXX record and check the base classes
1047 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1048 if (cxx_record_decl)
1049 {
1050 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1051 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1052 base_class != base_class_end;
1053 ++base_class)
1054 {
1055 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1056 if (RecordHasFields(base_class_decl))
1057 return true;
1058 }
1059 }
1060 return false;
1061}
1062
1063void
1064ClangASTContext::SetDefaultAccessForRecordFields (void *clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
1065{
1066 if (clang_qual_type)
1067 {
1068 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001069 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001070 if (clang_type)
1071 {
1072 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1073 if (record_type)
1074 {
1075 RecordDecl *record_decl = record_type->getDecl();
1076 if (record_decl)
1077 {
1078 uint32_t field_idx;
1079 RecordDecl::field_iterator field, field_end;
1080 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1081 field != field_end;
1082 ++field, ++field_idx)
1083 {
1084 // If no accessibility was assigned, assign the correct one
1085 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1086 field->setAccess ((AccessSpecifier)default_accessibility);
1087 }
1088 }
1089 }
1090 }
1091 }
1092}
1093
1094#pragma mark C++ Base Classes
1095
1096CXXBaseSpecifier *
Greg Clayton84f80752010-07-22 18:30:50 +00001097ClangASTContext::CreateBaseClassSpecifier (void *base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001098{
1099 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001100 return new CXXBaseSpecifier (SourceRange(),
1101 is_virtual,
1102 base_of_class,
1103 ConvertAccessTypeToAccessSpecifier (access),
1104 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001105 return NULL;
1106}
1107
Greg Claytone9d0df42010-07-02 01:29:13 +00001108void
1109ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1110{
1111 for (unsigned i=0; i<num_base_classes; ++i)
1112 {
1113 delete base_classes[i];
1114 base_classes[i] = NULL;
1115 }
1116}
1117
Chris Lattner24943d22010-06-08 16:52:24 +00001118bool
1119ClangASTContext::SetBaseClassesForClassType (void *class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
1120{
1121 if (class_clang_type)
1122 {
Greg Clayton1674b122010-07-21 22:12:05 +00001123 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001124 if (clang_type)
1125 {
1126 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1127 if (record_type)
1128 {
1129 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1130 if (cxx_record_decl)
1131 {
Chris Lattner24943d22010-06-08 16:52:24 +00001132 cxx_record_decl->setBases(base_classes, num_base_classes);
Greg Claytonbba60fb2010-09-21 21:22:23 +00001133
Greg Claytona4e27af2010-09-22 00:40:49 +00001134 // NOTE: we currently have some fixes that should be placed
1135 // into clang that will automatically set these things when
1136 // they are added (during the setBases() method call above)
1137 // so this code should be able to come out when those changes
1138 // make it into llvm/clang, then we can remove this code...
1139 // Currently SEMA is using the accessors manually to set
1140 // whether a class is empty, is POD, is aggregate, and more.
1141 // This code will be moved into CXXRecordDecl so everyone
1142 // can benefit.
Greg Clayton22d5fe32010-09-22 00:24:45 +00001143 if (cxx_record_decl->isEmpty() || cxx_record_decl->isPOD())
Greg Claytonbba60fb2010-09-21 21:22:23 +00001144 {
1145 // set empty to false if any bases are virtual, or not empty.
1146
1147 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1148 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1149 base_class != base_class_end;
1150 ++base_class)
1151 {
1152 if (base_class->isVirtual())
1153 {
1154 cxx_record_decl->setEmpty (false);
Greg Clayton22d5fe32010-09-22 00:24:45 +00001155 cxx_record_decl->setPOD (false);
Greg Claytonbba60fb2010-09-21 21:22:23 +00001156 break;
1157 }
1158 else
1159 {
Greg Clayton22d5fe32010-09-22 00:24:45 +00001160 QualType base_type (base_class->getType());
1161
1162 if (!base_type->isPODType())
1163 cxx_record_decl->setPOD (false);
1164
1165 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_type->getAs<RecordType>()->getDecl());
1166 if (!base_class_decl->isEmpty())
1167 {
Greg Claytonbba60fb2010-09-21 21:22:23 +00001168 cxx_record_decl->setEmpty (false);
1169 break;
Greg Clayton22d5fe32010-09-22 00:24:45 +00001170 }
Greg Claytonbba60fb2010-09-21 21:22:23 +00001171 }
1172 }
1173 }
Chris Lattner24943d22010-06-08 16:52:24 +00001174 return true;
1175 }
1176 }
1177 }
1178 }
1179 return false;
1180}
Greg Clayton84f80752010-07-22 18:30:50 +00001181#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001182
Greg Clayton84f80752010-07-22 18:30:50 +00001183void *
1184ClangASTContext::CreateObjCClass
1185(
1186 const char *name,
1187 DeclContext *decl_ctx,
1188 bool isForwardDecl,
1189 bool isInternal
1190)
1191{
1192 ASTContext *ast_context = getASTContext();
1193 assert (ast_context != NULL);
1194 assert (name && name[0]);
1195 if (decl_ctx == NULL)
1196 decl_ctx = ast_context->getTranslationUnitDecl();
1197
1198 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1199 // we will need to update this code. I was told to currently always use
1200 // the CXXRecordDecl class since we often don't know from debug information
1201 // if something is struct or a class, so we default to always use the more
1202 // complete definition just in case.
1203 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1204 decl_ctx,
1205 SourceLocation(),
1206 &ast_context->Idents.get(name),
1207 SourceLocation(),
1208 isForwardDecl,
1209 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001210
1211 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001212}
1213
1214bool
1215ClangASTContext::SetObjCSuperClass (void *class_opaque_type, void *super_opaque_type)
1216{
1217 if (class_opaque_type && super_opaque_type)
1218 {
1219 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1220 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1221 clang::Type *class_type = class_qual_type.getTypePtr();
1222 clang::Type *super_type = super_qual_type.getTypePtr();
1223 if (class_type && super_type)
1224 {
1225 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1226 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1227 if (objc_class_type && objc_super_type)
1228 {
1229 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1230 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1231 if (class_interface_decl && super_interface_decl)
1232 {
1233 class_interface_decl->setSuperClass(super_interface_decl);
1234 return true;
1235 }
1236 }
1237 }
1238 }
1239 return false;
1240}
1241
1242
1243bool
1244ClangASTContext::AddObjCClassIVar
1245(
Sean Callanan60a0ced2010-09-16 20:01:08 +00001246 clang::ASTContext *ast_context,
Greg Clayton84f80752010-07-22 18:30:50 +00001247 void *class_opaque_type,
1248 const char *name,
1249 void *ivar_opaque_type,
1250 AccessType access,
1251 uint32_t bitfield_bit_size,
1252 bool isSynthesized
1253)
1254{
1255 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1256 return false;
1257
Sean Callanan60a0ced2010-09-16 20:01:08 +00001258 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001259
1260 assert (ast_context != NULL);
1261 assert (identifier_table != NULL);
1262
1263 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1264
1265 clang::Type *class_type = class_qual_type.getTypePtr();
1266 if (class_type)
1267 {
1268 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1269
1270 if (objc_class_type)
1271 {
1272 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1273
1274 if (class_interface_decl)
1275 {
1276 clang::Expr *bit_width = NULL;
1277 if (bitfield_bit_size != 0)
1278 {
1279 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
1280 bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
1281 }
1282
Greg Clayton9488b742010-07-28 02:04:09 +00001283 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1284 class_interface_decl,
1285 SourceLocation(),
1286 &identifier_table->get(name), // Identifier
1287 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1288 NULL, // TypeSourceInfo *
1289 ConvertAccessTypeToObjCIvarAccessControl (access),
1290 bit_width,
1291 isSynthesized);
1292
1293 if (field)
1294 {
1295 class_interface_decl->addDecl(field);
1296 return true;
1297 }
Greg Clayton84f80752010-07-22 18:30:50 +00001298 }
1299 }
1300 }
1301 return false;
1302}
Chris Lattner24943d22010-06-08 16:52:24 +00001303
Greg Clayton9488b742010-07-28 02:04:09 +00001304
1305bool
1306ClangASTContext::ObjCTypeHasIVars (void *class_opaque_type, bool check_superclass)
1307{
1308 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1309
1310 clang::Type *class_type = class_qual_type.getTypePtr();
1311 if (class_type)
1312 {
1313 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1314
1315 if (objc_class_type)
1316 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1317 }
1318 return false;
1319}
1320
1321bool
1322ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1323{
1324 while (class_interface_decl)
1325 {
1326 if (class_interface_decl->ivar_size() > 0)
1327 return true;
1328
1329 if (check_superclass)
1330 class_interface_decl = class_interface_decl->getSuperClass();
1331 else
1332 break;
1333 }
1334 return false;
1335}
1336
1337
Chris Lattner24943d22010-06-08 16:52:24 +00001338#pragma mark Aggregate Types
1339
1340bool
1341ClangASTContext::IsAggregateType (void *clang_type)
1342{
1343 if (clang_type == NULL)
1344 return false;
1345
1346 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1347
1348 if (qual_type->isAggregateType ())
1349 return true;
1350
Greg Clayton03e0f972010-09-13 03:32:57 +00001351 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1352 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001353 {
Greg Clayton1674b122010-07-21 22:12:05 +00001354 case clang::Type::IncompleteArray:
1355 case clang::Type::VariableArray:
1356 case clang::Type::ConstantArray:
1357 case clang::Type::ExtVector:
1358 case clang::Type::Vector:
1359 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001360 case clang::Type::ObjCObject:
1361 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001362 return true;
1363
Greg Clayton1674b122010-07-21 22:12:05 +00001364 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001365 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1366
1367 default:
1368 break;
1369 }
1370 // The clang type does have a value
1371 return false;
1372}
1373
1374uint32_t
1375ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_classes)
1376{
1377 if (clang_qual_type == NULL)
1378 return 0;
1379
1380 uint32_t num_children = 0;
1381 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001382 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1383 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001384 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001385 case clang::Type::Builtin:
1386 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1387 {
1388 case clang::BuiltinType::ObjCId: // Child is Class
1389 case clang::BuiltinType::ObjCClass: // child is Class
1390 case clang::BuiltinType::ObjCSel: // child is const char *
1391 num_children = 1;
1392
1393 default:
1394 break;
1395 }
1396 break;
1397
Greg Clayton1674b122010-07-21 22:12:05 +00001398 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001399 {
1400 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1401 const RecordDecl *record_decl = record_type->getDecl();
1402 assert(record_decl);
1403 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1404 if (cxx_record_decl)
1405 {
1406 if (omit_empty_base_classes)
1407 {
1408 // Check each base classes to see if it or any of its
1409 // base classes contain any fields. This can help
1410 // limit the noise in variable views by not having to
1411 // show base classes that contain no members.
1412 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1413 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1414 base_class != base_class_end;
1415 ++base_class)
1416 {
1417 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1418
1419 // Skip empty base classes
1420 if (RecordHasFields(base_class_decl) == false)
1421 continue;
1422
1423 num_children++;
1424 }
1425 }
1426 else
1427 {
1428 // Include all base classes
1429 num_children += cxx_record_decl->getNumBases();
1430 }
1431
1432 }
1433 RecordDecl::field_iterator field, field_end;
1434 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1435 ++num_children;
1436 }
1437 break;
1438
Greg Clayton9488b742010-07-28 02:04:09 +00001439 case clang::Type::ObjCObject:
1440 case clang::Type::ObjCInterface:
1441 {
1442 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1443 assert (objc_class_type);
1444 if (objc_class_type)
1445 {
1446 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1447
1448 if (class_interface_decl)
1449 {
1450
1451 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1452 if (superclass_interface_decl)
1453 {
1454 if (omit_empty_base_classes)
1455 {
1456 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1457 ++num_children;
1458 }
1459 else
1460 ++num_children;
1461 }
1462
1463 num_children += class_interface_decl->ivar_size();
1464 }
1465 }
1466 }
1467 break;
1468
1469 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001470 {
1471 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1472 QualType pointee_type = pointer_type->getPointeeType();
1473 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1474 omit_empty_base_classes);
1475 // If this type points to a simple type, then it has 1 child
1476 if (num_pointee_children == 0)
1477 num_children = 1;
1478 else
1479 num_children = num_pointee_children;
1480 }
1481 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001482
Greg Clayton1674b122010-07-21 22:12:05 +00001483 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001484 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1485 break;
1486
Greg Clayton1674b122010-07-21 22:12:05 +00001487 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001488 {
1489 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1490 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001491 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1492 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001493 // If this type points to a simple type, then it has 1 child
1494 if (num_pointee_children == 0)
1495 num_children = 1;
1496 else
1497 num_children = num_pointee_children;
1498 }
1499 break;
1500
Greg Clayton1674b122010-07-21 22:12:05 +00001501 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001502 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1503 break;
1504
1505 default:
1506 break;
1507 }
1508 return num_children;
1509}
1510
1511
1512void *
1513ClangASTContext::GetChildClangTypeAtIndex
1514(
1515 const char *parent_name,
1516 void *parent_clang_type,
1517 uint32_t idx,
1518 bool transparent_pointers,
1519 bool omit_empty_base_classes,
1520 std::string& child_name,
1521 uint32_t &child_byte_size,
1522 int32_t &child_byte_offset,
1523 uint32_t &child_bitfield_bit_size,
1524 uint32_t &child_bitfield_bit_offset
1525)
1526{
1527 if (parent_clang_type)
1528
1529 return GetChildClangTypeAtIndex (getASTContext(),
1530 parent_name,
1531 parent_clang_type,
1532 idx,
1533 transparent_pointers,
1534 omit_empty_base_classes,
1535 child_name,
1536 child_byte_size,
1537 child_byte_offset,
1538 child_bitfield_bit_size,
1539 child_bitfield_bit_offset);
1540 return NULL;
1541}
1542
1543void *
1544ClangASTContext::GetChildClangTypeAtIndex
1545(
1546 ASTContext *ast_context,
1547 const char *parent_name,
1548 void *parent_clang_type,
1549 uint32_t idx,
1550 bool transparent_pointers,
1551 bool omit_empty_base_classes,
1552 std::string& child_name,
1553 uint32_t &child_byte_size,
1554 int32_t &child_byte_offset,
1555 uint32_t &child_bitfield_bit_size,
1556 uint32_t &child_bitfield_bit_offset
1557)
1558{
1559 if (parent_clang_type == NULL)
1560 return NULL;
1561
1562 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
1563 {
1564 uint32_t bit_offset;
1565 child_bitfield_bit_size = 0;
1566 child_bitfield_bit_offset = 0;
1567 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00001568 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
1569 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001570 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001571 case clang::Type::Builtin:
1572 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
1573 {
1574 case clang::BuiltinType::ObjCId:
1575 case clang::BuiltinType::ObjCClass:
1576 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
1577
1578 case clang::BuiltinType::ObjCSel:
1579 {
1580 QualType char_type(ast_context->CharTy);
1581 char_type.addConst();
1582 return ast_context->getPointerType(char_type).getAsOpaquePtr();
1583 }
1584 break;
1585
1586 default:
1587 break;
1588 }
1589 break;
1590
1591
Greg Clayton1674b122010-07-21 22:12:05 +00001592 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001593 {
1594 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
1595 const RecordDecl *record_decl = record_type->getDecl();
1596 assert(record_decl);
1597 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
1598 uint32_t child_idx = 0;
1599
1600 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1601 if (cxx_record_decl)
1602 {
1603 // We might have base classes to print out first
1604 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1605 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1606 base_class != base_class_end;
1607 ++base_class)
1608 {
1609 const CXXRecordDecl *base_class_decl = NULL;
1610
1611 // Skip empty base classes
1612 if (omit_empty_base_classes)
1613 {
1614 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1615 if (RecordHasFields(base_class_decl) == false)
1616 continue;
1617 }
1618
1619 if (idx == child_idx)
1620 {
1621 if (base_class_decl == NULL)
1622 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1623
1624
1625 if (base_class->isVirtual())
1626 bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
1627 else
1628 bit_offset = record_layout.getBaseClassOffset(base_class_decl);
1629
1630 // Base classes should be a multiple of 8 bits in size
1631 assert (bit_offset % 8 == 0);
1632 child_byte_offset = bit_offset/8;
1633 std::string base_class_type_name(base_class->getType().getAsString());
1634
1635 child_name.assign(base_class_type_name.c_str());
1636
1637 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
1638
1639 // Base classes biut sizes should be a multiple of 8 bits in size
1640 assert (clang_type_info_bit_size % 8 == 0);
1641 child_byte_size = clang_type_info_bit_size / 8;
1642 return base_class->getType().getAsOpaquePtr();
1643 }
1644 // We don't increment the child index in the for loop since we might
1645 // be skipping empty base classes
1646 ++child_idx;
1647 }
1648 }
Chris Lattner24943d22010-06-08 16:52:24 +00001649 // Make sure index is in range...
1650 uint32_t field_idx = 0;
1651 RecordDecl::field_iterator field, field_end;
1652 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
1653 {
1654 if (idx == child_idx)
1655 {
1656 // Print the member type if requested
1657 // Print the member name and equal sign
1658 child_name.assign(field->getNameAsString().c_str());
1659
1660 // Figure out the type byte size (field_type_info.first) and
1661 // alignment (field_type_info.second) from the AST context.
1662 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00001663 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00001664
1665 child_byte_size = field_type_info.first / 8;
1666
1667 // Figure out the field offset within the current struct/union/class type
1668 bit_offset = record_layout.getFieldOffset (field_idx);
1669 child_byte_offset = bit_offset / 8;
1670 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
1671 child_bitfield_bit_offset = bit_offset % 8;
1672
1673 return field->getType().getAsOpaquePtr();
1674 }
1675 }
1676 }
1677 break;
1678
Greg Clayton9488b742010-07-28 02:04:09 +00001679 case clang::Type::ObjCObject:
1680 case clang::Type::ObjCInterface:
1681 {
1682 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
1683 assert (objc_class_type);
1684 if (objc_class_type)
1685 {
1686 uint32_t child_idx = 0;
1687 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1688
1689 if (class_interface_decl)
1690 {
1691
1692 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
1693 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1694 if (superclass_interface_decl)
1695 {
1696 if (omit_empty_base_classes)
1697 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001698 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00001699 {
1700 if (idx == 0)
1701 {
1702 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
1703
1704
1705 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
1706
1707 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
1708
1709 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00001710 child_byte_offset = 0;
Greg Clayton9488b742010-07-28 02:04:09 +00001711
1712 return ivar_qual_type.getAsOpaquePtr();
1713 }
1714
1715 ++child_idx;
1716 }
1717 }
1718 else
1719 ++child_idx;
1720 }
Greg Clayton960d6a42010-08-03 00:35:52 +00001721
1722 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00001723
1724 if (idx < (child_idx + class_interface_decl->ivar_size()))
1725 {
1726 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
1727
1728 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
1729 {
1730 if (child_idx == idx)
1731 {
1732 const ObjCIvarDecl* ivar_decl = *ivar_pos;
1733
1734 QualType ivar_qual_type(ivar_decl->getType());
1735
1736 child_name.assign(ivar_decl->getNameAsString().c_str());
1737
1738 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
1739
1740 child_byte_size = ivar_type_info.first / 8;
1741
1742 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00001743 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00001744 child_byte_offset = bit_offset / 8;
1745
1746 return ivar_qual_type.getAsOpaquePtr();
1747 }
1748 ++child_idx;
1749 }
1750 }
1751 }
1752 }
1753 }
1754 break;
1755
1756 case clang::Type::ObjCObjectPointer:
1757 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001758 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
1759 QualType pointee_type = pointer_type->getPointeeType();
1760
1761 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1762 {
1763 return GetChildClangTypeAtIndex (ast_context,
1764 parent_name,
1765 pointer_type->getPointeeType().getAsOpaquePtr(),
1766 idx,
1767 transparent_pointers,
1768 omit_empty_base_classes,
1769 child_name,
1770 child_byte_size,
1771 child_byte_offset,
1772 child_bitfield_bit_size,
1773 child_bitfield_bit_offset);
1774 }
1775 else
1776 {
1777 if (parent_name)
1778 {
1779 child_name.assign(1, '*');
1780 child_name += parent_name;
1781 }
1782
1783 // We have a pointer to an simple type
1784 if (idx == 0)
1785 {
1786 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1787 assert(clang_type_info.first % 8 == 0);
1788 child_byte_size = clang_type_info.first / 8;
1789 child_byte_offset = 0;
1790 return pointee_type.getAsOpaquePtr();
1791 }
1792 }
Greg Clayton9488b742010-07-28 02:04:09 +00001793 }
1794 break;
1795
Greg Clayton1674b122010-07-21 22:12:05 +00001796 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001797 {
1798 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1799 const uint64_t element_count = array->getSize().getLimitedValue();
1800
1801 if (idx < element_count)
1802 {
1803 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1804
1805 char element_name[32];
1806 ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1807
1808 child_name.assign(element_name);
1809 assert(field_type_info.first % 8 == 0);
1810 child_byte_size = field_type_info.first / 8;
1811 child_byte_offset = idx * child_byte_size;
1812 return array->getElementType().getAsOpaquePtr();
1813 }
1814 }
1815 break;
1816
Greg Clayton1674b122010-07-21 22:12:05 +00001817 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001818 {
1819 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
1820 QualType pointee_type = pointer_type->getPointeeType();
1821
1822 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1823 {
1824 return GetChildClangTypeAtIndex (ast_context,
1825 parent_name,
1826 pointer_type->getPointeeType().getAsOpaquePtr(),
1827 idx,
1828 transparent_pointers,
1829 omit_empty_base_classes,
1830 child_name,
1831 child_byte_size,
1832 child_byte_offset,
1833 child_bitfield_bit_size,
1834 child_bitfield_bit_offset);
1835 }
1836 else
1837 {
1838 if (parent_name)
1839 {
1840 child_name.assign(1, '*');
1841 child_name += parent_name;
1842 }
1843
1844 // We have a pointer to an simple type
1845 if (idx == 0)
1846 {
1847 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1848 assert(clang_type_info.first % 8 == 0);
1849 child_byte_size = clang_type_info.first / 8;
1850 child_byte_offset = 0;
1851 return pointee_type.getAsOpaquePtr();
1852 }
1853 }
1854 }
1855 break;
1856
Greg Clayton1674b122010-07-21 22:12:05 +00001857 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001858 return GetChildClangTypeAtIndex (ast_context,
1859 parent_name,
1860 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1861 idx,
1862 transparent_pointers,
1863 omit_empty_base_classes,
1864 child_name,
1865 child_byte_size,
1866 child_byte_offset,
1867 child_bitfield_bit_size,
1868 child_bitfield_bit_offset);
1869 break;
1870
1871 default:
1872 break;
1873 }
1874 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00001875 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001876}
1877
1878static inline bool
1879BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
1880{
1881 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
1882}
1883
1884static uint32_t
1885GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
1886{
1887 uint32_t num_bases = 0;
1888 if (cxx_record_decl)
1889 {
1890 if (omit_empty_base_classes)
1891 {
1892 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1893 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1894 base_class != base_class_end;
1895 ++base_class)
1896 {
1897 // Skip empty base classes
1898 if (omit_empty_base_classes)
1899 {
1900 if (BaseSpecifierIsEmpty (base_class))
1901 continue;
1902 }
1903 ++num_bases;
1904 }
1905 }
1906 else
1907 num_bases = cxx_record_decl->getNumBases();
1908 }
1909 return num_bases;
1910}
1911
1912
1913static uint32_t
1914GetIndexForRecordBase
1915(
1916 const RecordDecl *record_decl,
1917 const CXXBaseSpecifier *base_spec,
1918 bool omit_empty_base_classes
1919)
1920{
1921 uint32_t child_idx = 0;
1922
1923 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1924
1925// const char *super_name = record_decl->getNameAsCString();
1926// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
1927// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
1928//
1929 if (cxx_record_decl)
1930 {
1931 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1932 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1933 base_class != base_class_end;
1934 ++base_class)
1935 {
1936 if (omit_empty_base_classes)
1937 {
1938 if (BaseSpecifierIsEmpty (base_class))
1939 continue;
1940 }
1941
1942// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
1943// child_idx,
1944// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1945//
1946//
1947 if (base_class == base_spec)
1948 return child_idx;
1949 ++child_idx;
1950 }
1951 }
1952
1953 return UINT32_MAX;
1954}
1955
1956
1957static uint32_t
1958GetIndexForRecordChild
1959(
1960 const RecordDecl *record_decl,
1961 NamedDecl *canonical_decl,
1962 bool omit_empty_base_classes
1963)
1964{
1965 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
1966
1967// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1968//
1969//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
1970// if (cxx_record_decl)
1971// {
1972// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1973// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1974// base_class != base_class_end;
1975// ++base_class)
1976// {
1977// if (omit_empty_base_classes)
1978// {
1979// if (BaseSpecifierIsEmpty (base_class))
1980// continue;
1981// }
1982//
1983//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
1984//// record_decl->getNameAsCString(),
1985//// canonical_decl->getNameAsCString(),
1986//// child_idx,
1987//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1988//
1989//
1990// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1991// if (curr_base_class_decl == canonical_decl)
1992// {
1993// return child_idx;
1994// }
1995// ++child_idx;
1996// }
1997// }
1998//
1999// const uint32_t num_bases = child_idx;
2000 RecordDecl::field_iterator field, field_end;
2001 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2002 field != field_end;
2003 ++field, ++child_idx)
2004 {
2005// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2006// record_decl->getNameAsCString(),
2007// canonical_decl->getNameAsCString(),
2008// child_idx - num_bases,
2009// field->getNameAsCString());
2010
2011 if (field->getCanonicalDecl() == canonical_decl)
2012 return child_idx;
2013 }
2014
2015 return UINT32_MAX;
2016}
2017
2018// Look for a child member (doesn't include base classes, but it does include
2019// their members) in the type hierarchy. Returns an index path into "clang_type"
2020// on how to reach the appropriate member.
2021//
2022// class A
2023// {
2024// public:
2025// int m_a;
2026// int m_b;
2027// };
2028//
2029// class B
2030// {
2031// };
2032//
2033// class C :
2034// public B,
2035// public A
2036// {
2037// };
2038//
2039// If we have a clang type that describes "class C", and we wanted to looked
2040// "m_b" in it:
2041//
2042// With omit_empty_base_classes == false we would get an integer array back with:
2043// { 1, 1 }
2044// The first index 1 is the child index for "class A" within class C
2045// The second index 1 is the child index for "m_b" within class A
2046//
2047// With omit_empty_base_classes == true we would get an integer array back with:
2048// { 0, 1 }
2049// 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)
2050// The second index 1 is the child index for "m_b" within class A
2051
2052size_t
2053ClangASTContext::GetIndexOfChildMemberWithName
2054(
2055 ASTContext *ast_context,
2056 void *clang_type,
2057 const char *name,
2058 bool omit_empty_base_classes,
2059 std::vector<uint32_t>& child_indexes
2060)
2061{
2062 if (clang_type && name && name[0])
2063 {
2064 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002065 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2066 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002067 {
Greg Clayton1674b122010-07-21 22:12:05 +00002068 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002069 {
2070 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2071 const RecordDecl *record_decl = record_type->getDecl();
2072
2073 assert(record_decl);
2074 uint32_t child_idx = 0;
2075
2076 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2077
2078 // Try and find a field that matches NAME
2079 RecordDecl::field_iterator field, field_end;
2080 StringRef name_sref(name);
2081 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2082 field != field_end;
2083 ++field, ++child_idx)
2084 {
2085 if (field->getName().equals (name_sref))
2086 {
2087 // We have to add on the number of base classes to this index!
2088 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2089 return child_indexes.size();
2090 }
2091 }
2092
2093 if (cxx_record_decl)
2094 {
2095 const RecordDecl *parent_record_decl = cxx_record_decl;
2096
2097 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2098
2099 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2100 // Didn't find things easily, lets let clang do its thang...
2101 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2102 DeclarationName decl_name(&ident_ref);
2103
2104 CXXBasePaths paths;
2105 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2106 decl_name.getAsOpaquePtr(),
2107 paths))
2108 {
Chris Lattner24943d22010-06-08 16:52:24 +00002109 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2110 for (path = paths.begin(); path != path_end; ++path)
2111 {
2112 const size_t num_path_elements = path->size();
2113 for (size_t e=0; e<num_path_elements; ++e)
2114 {
2115 CXXBasePathElement elem = (*path)[e];
2116
2117 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2118 if (child_idx == UINT32_MAX)
2119 {
2120 child_indexes.clear();
2121 return 0;
2122 }
2123 else
2124 {
2125 child_indexes.push_back (child_idx);
2126 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2127 }
2128 }
2129 DeclContext::lookup_iterator named_decl_pos;
2130 for (named_decl_pos = path->Decls.first;
2131 named_decl_pos != path->Decls.second && parent_record_decl;
2132 ++named_decl_pos)
2133 {
2134 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2135
2136 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2137 if (child_idx == UINT32_MAX)
2138 {
2139 child_indexes.clear();
2140 return 0;
2141 }
2142 else
2143 {
2144 child_indexes.push_back (child_idx);
2145 }
2146 }
2147 }
2148 return child_indexes.size();
2149 }
2150 }
2151
2152 }
2153 break;
2154
Greg Clayton9488b742010-07-28 02:04:09 +00002155 case clang::Type::ObjCObject:
2156 case clang::Type::ObjCInterface:
2157 {
2158 StringRef name_sref(name);
2159 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2160 assert (objc_class_type);
2161 if (objc_class_type)
2162 {
2163 uint32_t child_idx = 0;
2164 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2165
2166 if (class_interface_decl)
2167 {
2168 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2169 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2170
Greg Clayton823533e2010-09-18 02:11:07 +00002171 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002172 {
2173 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2174
2175 if (ivar_decl->getName().equals (name_sref))
2176 {
2177 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2178 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2179 ++child_idx;
2180
2181 child_indexes.push_back (child_idx);
2182 return child_indexes.size();
2183 }
2184 }
2185
2186 if (superclass_interface_decl)
2187 {
2188 // The super class index is always zero for ObjC classes,
2189 // so we push it onto the child indexes in case we find
2190 // an ivar in our superclass...
2191 child_indexes.push_back (0);
2192
2193 if (GetIndexOfChildMemberWithName (ast_context,
2194 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2195 name,
2196 omit_empty_base_classes,
2197 child_indexes))
2198 {
2199 // We did find an ivar in a superclass so just
2200 // return the results!
2201 return child_indexes.size();
2202 }
2203
2204 // We didn't find an ivar matching "name" in our
2205 // superclass, pop the superclass zero index that
2206 // we pushed on above.
2207 child_indexes.pop_back();
2208 }
2209 }
2210 }
2211 }
2212 break;
2213
2214 case clang::Type::ObjCObjectPointer:
2215 {
2216 return GetIndexOfChildMemberWithName (ast_context,
2217 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2218 name,
2219 omit_empty_base_classes,
2220 child_indexes);
2221 }
2222 break;
2223
2224
Greg Clayton1674b122010-07-21 22:12:05 +00002225 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002226 {
2227// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2228// const uint64_t element_count = array->getSize().getLimitedValue();
2229//
2230// if (idx < element_count)
2231// {
2232// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2233//
2234// char element_name[32];
2235// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2236//
2237// child_name.assign(element_name);
2238// assert(field_type_info.first % 8 == 0);
2239// child_byte_size = field_type_info.first / 8;
2240// child_byte_offset = idx * child_byte_size;
2241// return array->getElementType().getAsOpaquePtr();
2242// }
2243 }
2244 break;
2245
Greg Clayton1674b122010-07-21 22:12:05 +00002246// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002247// {
2248// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2249// QualType pointee_type = mem_ptr_type->getPointeeType();
2250//
2251// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2252// {
2253// return GetIndexOfChildWithName (ast_context,
2254// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2255// name);
2256// }
2257// }
2258// break;
2259//
Greg Clayton1674b122010-07-21 22:12:05 +00002260 case clang::Type::LValueReference:
2261 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002262 {
2263 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2264 QualType pointee_type = reference_type->getPointeeType();
2265
2266 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2267 {
2268 return GetIndexOfChildMemberWithName (ast_context,
2269 reference_type->getPointeeType().getAsOpaquePtr(),
2270 name,
2271 omit_empty_base_classes,
2272 child_indexes);
2273 }
2274 }
2275 break;
2276
Greg Clayton1674b122010-07-21 22:12:05 +00002277 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002278 {
2279 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2280 QualType pointee_type = pointer_type->getPointeeType();
2281
2282 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2283 {
2284 return GetIndexOfChildMemberWithName (ast_context,
2285 pointer_type->getPointeeType().getAsOpaquePtr(),
2286 name,
2287 omit_empty_base_classes,
2288 child_indexes);
2289 }
2290 else
2291 {
2292// if (parent_name)
2293// {
2294// child_name.assign(1, '*');
2295// child_name += parent_name;
2296// }
2297//
2298// // We have a pointer to an simple type
2299// if (idx == 0)
2300// {
2301// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2302// assert(clang_type_info.first % 8 == 0);
2303// child_byte_size = clang_type_info.first / 8;
2304// child_byte_offset = 0;
2305// return pointee_type.getAsOpaquePtr();
2306// }
2307 }
2308 }
2309 break;
2310
Greg Clayton1674b122010-07-21 22:12:05 +00002311 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002312 return GetIndexOfChildMemberWithName (ast_context,
2313 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2314 name,
2315 omit_empty_base_classes,
2316 child_indexes);
2317
2318 default:
2319 break;
2320 }
2321 }
2322 return 0;
2323}
2324
2325
2326// Get the index of the child of "clang_type" whose name matches. This function
2327// doesn't descend into the children, but only looks one level deep and name
2328// matches can include base class names.
2329
2330uint32_t
2331ClangASTContext::GetIndexOfChildWithName
2332(
2333 ASTContext *ast_context,
2334 void *clang_type,
2335 const char *name,
2336 bool omit_empty_base_classes
2337)
2338{
2339 if (clang_type && name && name[0])
2340 {
2341 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002342
Greg Clayton03e0f972010-09-13 03:32:57 +00002343 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002344
Greg Clayton03e0f972010-09-13 03:32:57 +00002345 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002346 {
Greg Clayton1674b122010-07-21 22:12:05 +00002347 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002348 {
2349 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2350 const RecordDecl *record_decl = record_type->getDecl();
2351
2352 assert(record_decl);
2353 uint32_t child_idx = 0;
2354
2355 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2356
2357 if (cxx_record_decl)
2358 {
2359 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2360 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2361 base_class != base_class_end;
2362 ++base_class)
2363 {
2364 // Skip empty base classes
2365 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2366 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2367 continue;
2368
2369 if (base_class->getType().getAsString().compare (name) == 0)
2370 return child_idx;
2371 ++child_idx;
2372 }
2373 }
2374
2375 // Try and find a field that matches NAME
2376 RecordDecl::field_iterator field, field_end;
2377 StringRef name_sref(name);
2378 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2379 field != field_end;
2380 ++field, ++child_idx)
2381 {
2382 if (field->getName().equals (name_sref))
2383 return child_idx;
2384 }
2385
2386 }
2387 break;
2388
Greg Clayton9488b742010-07-28 02:04:09 +00002389 case clang::Type::ObjCObject:
2390 case clang::Type::ObjCInterface:
2391 {
2392 StringRef name_sref(name);
2393 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2394 assert (objc_class_type);
2395 if (objc_class_type)
2396 {
2397 uint32_t child_idx = 0;
2398 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2399
2400 if (class_interface_decl)
2401 {
2402 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2403 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2404
2405 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2406 {
2407 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2408
2409 if (ivar_decl->getName().equals (name_sref))
2410 {
2411 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2412 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2413 ++child_idx;
2414
2415 return child_idx;
2416 }
2417 }
2418
2419 if (superclass_interface_decl)
2420 {
2421 if (superclass_interface_decl->getName().equals (name_sref))
2422 return 0;
2423 }
2424 }
2425 }
2426 }
2427 break;
2428
2429 case clang::Type::ObjCObjectPointer:
2430 {
2431 return GetIndexOfChildWithName (ast_context,
2432 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2433 name,
2434 omit_empty_base_classes);
2435 }
2436 break;
2437
Greg Clayton1674b122010-07-21 22:12:05 +00002438 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002439 {
2440// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2441// const uint64_t element_count = array->getSize().getLimitedValue();
2442//
2443// if (idx < element_count)
2444// {
2445// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2446//
2447// char element_name[32];
2448// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2449//
2450// child_name.assign(element_name);
2451// assert(field_type_info.first % 8 == 0);
2452// child_byte_size = field_type_info.first / 8;
2453// child_byte_offset = idx * child_byte_size;
2454// return array->getElementType().getAsOpaquePtr();
2455// }
2456 }
2457 break;
2458
Greg Clayton1674b122010-07-21 22:12:05 +00002459// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002460// {
2461// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2462// QualType pointee_type = mem_ptr_type->getPointeeType();
2463//
2464// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2465// {
2466// return GetIndexOfChildWithName (ast_context,
2467// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2468// name);
2469// }
2470// }
2471// break;
2472//
Greg Clayton1674b122010-07-21 22:12:05 +00002473 case clang::Type::LValueReference:
2474 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002475 {
2476 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2477 QualType pointee_type = reference_type->getPointeeType();
2478
2479 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2480 {
2481 return GetIndexOfChildWithName (ast_context,
2482 reference_type->getPointeeType().getAsOpaquePtr(),
2483 name,
2484 omit_empty_base_classes);
2485 }
2486 }
2487 break;
2488
Greg Clayton1674b122010-07-21 22:12:05 +00002489 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002490 {
2491 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2492 QualType pointee_type = pointer_type->getPointeeType();
2493
2494 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2495 {
2496 return GetIndexOfChildWithName (ast_context,
2497 pointer_type->getPointeeType().getAsOpaquePtr(),
2498 name,
2499 omit_empty_base_classes);
2500 }
2501 else
2502 {
2503// if (parent_name)
2504// {
2505// child_name.assign(1, '*');
2506// child_name += parent_name;
2507// }
2508//
2509// // We have a pointer to an simple type
2510// if (idx == 0)
2511// {
2512// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2513// assert(clang_type_info.first % 8 == 0);
2514// child_byte_size = clang_type_info.first / 8;
2515// child_byte_offset = 0;
2516// return pointee_type.getAsOpaquePtr();
2517// }
2518 }
2519 }
2520 break;
2521
Greg Clayton1674b122010-07-21 22:12:05 +00002522 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002523 return GetIndexOfChildWithName (ast_context,
2524 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2525 name,
2526 omit_empty_base_classes);
2527
2528 default:
2529 break;
2530 }
2531 }
2532 return UINT32_MAX;
2533}
2534
2535#pragma mark TagType
2536
2537bool
2538ClangASTContext::SetTagTypeKind (void *tag_clang_type, int kind)
2539{
2540 if (tag_clang_type)
2541 {
2542 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00002543 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002544 if (clang_type)
2545 {
2546 TagType *tag_type = dyn_cast<TagType>(clang_type);
2547 if (tag_type)
2548 {
2549 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
2550 if (tag_decl)
2551 {
2552 tag_decl->setTagKind ((TagDecl::TagKind)kind);
2553 return true;
2554 }
2555 }
2556 }
2557 }
2558 return false;
2559}
2560
2561
2562#pragma mark DeclContext Functions
2563
2564DeclContext *
2565ClangASTContext::GetDeclContextForType (void *clang_type)
2566{
2567 if (clang_type == NULL)
2568 return NULL;
2569
2570 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002571 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2572 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002573 {
Greg Clayton9488b742010-07-28 02:04:09 +00002574 case clang::Type::FunctionNoProto: break;
2575 case clang::Type::FunctionProto: break;
2576 case clang::Type::IncompleteArray: break;
2577 case clang::Type::VariableArray: break;
2578 case clang::Type::ConstantArray: break;
2579 case clang::Type::ExtVector: break;
2580 case clang::Type::Vector: break;
2581 case clang::Type::Builtin: break;
2582 case clang::Type::BlockPointer: break;
2583 case clang::Type::Pointer: break;
2584 case clang::Type::LValueReference: break;
2585 case clang::Type::RValueReference: break;
2586 case clang::Type::MemberPointer: break;
2587 case clang::Type::Complex: break;
2588 case clang::Type::ObjCObject: break;
2589 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
2590 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
2591 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
2592 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
2593 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00002594
Greg Clayton9488b742010-07-28 02:04:09 +00002595 case clang::Type::TypeOfExpr: break;
2596 case clang::Type::TypeOf: break;
2597 case clang::Type::Decltype: break;
2598 //case clang::Type::QualifiedName: break;
2599 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00002600 }
2601 // No DeclContext in this type...
2602 return NULL;
2603}
2604
2605#pragma mark Namespace Declarations
2606
2607NamespaceDecl *
2608ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
2609{
2610 // TODO: Do something intelligent with the Declaration object passed in
2611 // like maybe filling in the SourceLocation with it...
2612 if (name)
2613 {
2614 ASTContext *ast_context = getASTContext();
2615 if (decl_ctx == NULL)
2616 decl_ctx = ast_context->getTranslationUnitDecl();
2617 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
2618 }
2619 return NULL;
2620}
2621
2622
2623#pragma mark Function Types
2624
2625FunctionDecl *
2626ClangASTContext::CreateFunctionDeclaration (const char *name, void *function_clang_type, int storage, bool is_inline)
2627{
2628 if (name)
2629 {
2630 ASTContext *ast_context = getASTContext();
2631 assert (ast_context != NULL);
2632
2633 if (name && name[0])
2634 {
2635 return FunctionDecl::Create(*ast_context,
2636 ast_context->getTranslationUnitDecl(),
2637 SourceLocation(),
2638 DeclarationName (&ast_context->Idents.get(name)),
2639 QualType::getFromOpaquePtr(function_clang_type),
2640 NULL,
2641 (FunctionDecl::StorageClass)storage,
2642 (FunctionDecl::StorageClass)storage,
2643 is_inline);
2644 }
2645 else
2646 {
2647 return FunctionDecl::Create(*ast_context,
2648 ast_context->getTranslationUnitDecl(),
2649 SourceLocation(),
2650 DeclarationName (),
2651 QualType::getFromOpaquePtr(function_clang_type),
2652 NULL,
2653 (FunctionDecl::StorageClass)storage,
2654 (FunctionDecl::StorageClass)storage,
2655 is_inline);
2656 }
2657 }
2658 return NULL;
2659}
2660
2661void *
Sean Callanan2ea8f272010-09-16 20:40:25 +00002662ClangASTContext::CreateFunctionType (clang::ASTContext *ast_context,
2663 void *result_type,
2664 void **args,
2665 unsigned num_args,
2666 bool is_variadic,
2667 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00002668{
Chris Lattner24943d22010-06-08 16:52:24 +00002669 assert (ast_context != NULL);
2670 std::vector<QualType> qual_type_args;
2671 for (unsigned i=0; i<num_args; ++i)
2672 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
2673
2674 // TODO: Detect calling convention in DWARF?
2675 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00002676 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00002677 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00002678 is_variadic,
2679 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00002680 false, // hasExceptionSpec
2681 false, // hasAnyExceptionSpec,
2682 0, // NumExs
2683 0, // const QualType *ExArray
2684 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
2685}
2686
2687ParmVarDecl *
Sean Callanan2ea8f272010-09-16 20:40:25 +00002688ClangASTContext::CreateParameterDeclaration (const char *name, void *param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00002689{
2690 ASTContext *ast_context = getASTContext();
2691 assert (ast_context != NULL);
2692 return ParmVarDecl::Create(*ast_context,
2693 ast_context->getTranslationUnitDecl(),
2694 SourceLocation(),
2695 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00002696 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00002697 NULL,
2698 (VarDecl::StorageClass)storage,
2699 (VarDecl::StorageClass)storage,
2700 0);
2701}
2702
2703void
2704ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
2705{
2706 if (function_decl)
2707 function_decl->setParams (params, num_params);
2708}
2709
2710
2711#pragma mark Array Types
2712
2713void *
2714ClangASTContext::CreateArrayType (void *element_type, size_t element_count, uint32_t bit_stride)
2715{
2716 if (element_type)
2717 {
2718 ASTContext *ast_context = getASTContext();
2719 assert (ast_context != NULL);
2720 llvm::APInt ap_element_count (64, element_count);
2721 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
2722 ap_element_count,
2723 ArrayType::Normal,
2724 0).getAsOpaquePtr(); // ElemQuals
2725 }
2726 return NULL;
2727}
2728
2729
2730#pragma mark TagDecl
2731
2732bool
2733ClangASTContext::StartTagDeclarationDefinition (void *clang_type)
2734{
2735 if (clang_type)
2736 {
2737 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00002738 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002739 if (t)
2740 {
2741 TagType *tag_type = dyn_cast<TagType>(t);
2742 if (tag_type)
2743 {
2744 TagDecl *tag_decl = tag_type->getDecl();
2745 if (tag_decl)
2746 {
2747 tag_decl->startDefinition();
2748 return true;
2749 }
2750 }
2751 }
2752 }
2753 return false;
2754}
2755
2756bool
2757ClangASTContext::CompleteTagDeclarationDefinition (void *clang_type)
2758{
2759 if (clang_type)
2760 {
2761 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00002762 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002763 if (t)
2764 {
2765 TagType *tag_type = dyn_cast<TagType>(t);
2766 if (tag_type)
2767 {
2768 TagDecl *tag_decl = tag_type->getDecl();
2769 if (tag_decl)
2770 {
2771 tag_decl->completeDefinition();
2772 return true;
2773 }
2774 }
2775 }
2776 }
2777 return false;
2778}
2779
2780
2781#pragma mark Enumeration Types
2782
2783void *
Greg Claytone37f23c2010-09-12 23:17:56 +00002784ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, void *integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002785{
2786 // TODO: Do something intelligent with the Declaration object passed in
2787 // like maybe filling in the SourceLocation with it...
2788 ASTContext *ast_context = getASTContext();
2789 assert (ast_context != NULL);
2790 EnumDecl *enum_decl = EnumDecl::Create(*ast_context,
2791 ast_context->getTranslationUnitDecl(),
2792 SourceLocation(),
2793 name && name[0] ? &ast_context->Idents.get(name) : NULL,
2794 SourceLocation(),
2795 NULL);
2796 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00002797 {
2798 // TODO: check if we should be setting the promotion type too?
2799 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00002800 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00002801 }
Chris Lattner24943d22010-06-08 16:52:24 +00002802 return NULL;
2803}
2804
2805bool
2806ClangASTContext::AddEnumerationValueToEnumerationType
2807(
2808 void *enum_clang_type,
2809 void *enumerator_clang_type,
2810 const Declaration &decl,
2811 const char *name,
2812 int64_t enum_value,
2813 uint32_t enum_value_bit_size
2814)
2815{
2816 if (enum_clang_type && enumerator_clang_type && name)
2817 {
2818 // TODO: Do something intelligent with the Declaration object passed in
2819 // like maybe filling in the SourceLocation with it...
2820 ASTContext *ast_context = getASTContext();
2821 IdentifierTable *identifier_table = getIdentifierTable();
2822
2823 assert (ast_context != NULL);
2824 assert (identifier_table != NULL);
2825 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
2826
Greg Clayton1674b122010-07-21 22:12:05 +00002827 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002828 if (clang_type)
2829 {
2830 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
2831
2832 if (enum_type)
2833 {
2834 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
2835 enum_llvm_apsint = enum_value;
2836 EnumConstantDecl *enumerator_decl =
2837 EnumConstantDecl::Create(*ast_context,
2838 enum_type->getDecl(),
2839 SourceLocation(),
2840 name ? &identifier_table->get(name) : NULL, // Identifier
2841 QualType::getFromOpaquePtr(enumerator_clang_type),
2842 NULL,
2843 enum_llvm_apsint);
2844
2845 if (enumerator_decl)
2846 {
2847 enum_type->getDecl()->addDecl(enumerator_decl);
2848 return true;
2849 }
2850 }
2851 }
2852 }
2853 return false;
2854}
2855
2856#pragma mark Pointers & References
2857
2858void *
2859ClangASTContext::CreatePointerType (void *clang_type)
2860{
2861 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00002862 {
2863 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2864
Greg Clayton03e0f972010-09-13 03:32:57 +00002865 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2866 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00002867 {
2868 case clang::Type::ObjCObject:
2869 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00002870 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
2871
Greg Clayton7b541032010-07-29 20:06:32 +00002872 default:
2873 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
2874 }
2875 }
Chris Lattner24943d22010-06-08 16:52:24 +00002876 return NULL;
2877}
2878
2879void *
2880ClangASTContext::CreateLValueReferenceType (void *clang_type)
2881{
2882 if (clang_type)
2883 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2884 return NULL;
2885}
2886
2887void *
2888ClangASTContext::CreateRValueReferenceType (void *clang_type)
2889{
2890 if (clang_type)
2891 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2892 return NULL;
2893}
2894
Greg Claytonfa970692010-06-12 01:20:30 +00002895void *
Greg Clayton84f80752010-07-22 18:30:50 +00002896ClangASTContext::CreateMemberPointerType (void *clang_pointee_type, void *clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00002897{
2898 if (clang_pointee_type && clang_pointee_type)
2899 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
2900 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
2901 return NULL;
2902}
2903
Chris Lattner24943d22010-06-08 16:52:24 +00002904size_t
2905ClangASTContext::GetPointerBitSize ()
2906{
2907 ASTContext *ast_context = getASTContext();
2908 return ast_context->getTypeSize(ast_context->VoidPtrTy);
2909}
2910
2911bool
2912ClangASTContext::IsPointerOrReferenceType (void *clang_type, void **target_type)
2913{
2914 if (clang_type == NULL)
2915 return false;
2916
2917 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002918 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2919 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002920 {
Greg Clayton1674b122010-07-21 22:12:05 +00002921 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002922 if (target_type)
2923 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2924 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002925 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002926 if (target_type)
2927 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2928 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002929 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002930 if (target_type)
2931 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2932 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002933 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002934 if (target_type)
2935 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2936 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002937 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002938 if (target_type)
2939 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2940 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002941 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002942 if (target_type)
2943 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2944 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002945 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002946 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
2947 default:
2948 break;
2949 }
2950 return false;
2951}
2952
Chris Lattner24943d22010-06-08 16:52:24 +00002953bool
Greg Clayton84f80752010-07-22 18:30:50 +00002954ClangASTContext::IsIntegerType (void *clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00002955{
2956 if (!clang_type)
2957 return false;
2958
2959 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2960 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
2961
2962 if (builtin_type)
2963 {
2964 if (builtin_type->isInteger())
2965 is_signed = builtin_type->isSignedInteger();
2966
2967 return true;
2968 }
2969
2970 return false;
2971}
2972
2973bool
2974ClangASTContext::IsPointerType (void *clang_type, void **target_type)
2975{
2976 if (clang_type)
2977 {
2978 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002979 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2980 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002981 {
Greg Clayton1674b122010-07-21 22:12:05 +00002982 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002983 if (target_type)
2984 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2985 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002986 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002987 if (target_type)
2988 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2989 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002990 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002991 if (target_type)
2992 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2993 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002994 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002995 if (target_type)
2996 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2997 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002998 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002999 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3000 default:
3001 break;
3002 }
3003 }
3004 return false;
3005}
3006
3007bool
3008ClangASTContext::IsFloatingPointType (void *clang_type, uint32_t &count, bool &is_complex)
3009{
3010 if (clang_type)
3011 {
3012 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3013
3014 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3015 {
3016 clang::BuiltinType::Kind kind = BT->getKind();
3017 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3018 {
3019 count = 1;
3020 is_complex = false;
3021 return true;
3022 }
3023 }
3024 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3025 {
3026 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3027 {
3028 count = 2;
3029 is_complex = true;
3030 return true;
3031 }
3032 }
3033 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3034 {
3035 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3036 {
3037 count = VT->getNumElements();
3038 is_complex = false;
3039 return true;
3040 }
3041 }
3042 }
3043 return false;
3044}
3045
3046
3047bool
3048ClangASTContext::IsCStringType (void *clang_type, uint32_t &length)
3049{
3050 if (clang_type)
3051 {
3052 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003053 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3054 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003055 {
Greg Clayton1674b122010-07-21 22:12:05 +00003056 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003057 {
3058 ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr());
3059 QualType element_qual_type = array->getElementType();
Greg Clayton1674b122010-07-21 22:12:05 +00003060 clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003061 if (canonical_type && canonical_type->isCharType())
3062 {
3063 // We know the size of the array and it could be a C string
3064 // since it is an array of characters
3065 length = array->getSize().getLimitedValue();
3066 return true;
3067 }
3068 }
3069 break;
3070
Greg Clayton1674b122010-07-21 22:12:05 +00003071 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003072 {
3073 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton1674b122010-07-21 22:12:05 +00003074 clang::Type *pointee_type_ptr = pointer_type->getPointeeType().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003075 if (pointee_type_ptr)
3076 {
Greg Clayton1674b122010-07-21 22:12:05 +00003077 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003078 length = 0; // No length info, read until a NULL terminator is received
3079 if (canonical_type_ptr)
3080 return canonical_type_ptr->isCharType();
3081 else
3082 return pointee_type_ptr->isCharType();
3083 }
3084 }
3085 break;
3086
Greg Clayton1674b122010-07-21 22:12:05 +00003087 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003088 return ClangASTContext::IsCStringType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), length);
3089
Greg Clayton1674b122010-07-21 22:12:05 +00003090 case clang::Type::LValueReference:
3091 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003092 {
3093 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton1674b122010-07-21 22:12:05 +00003094 clang::Type *pointee_type_ptr = reference_type->getPointeeType().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003095 if (pointee_type_ptr)
3096 {
Greg Clayton1674b122010-07-21 22:12:05 +00003097 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003098 length = 0; // No length info, read until a NULL terminator is received
3099 if (canonical_type_ptr)
3100 return canonical_type_ptr->isCharType();
3101 else
3102 return pointee_type_ptr->isCharType();
3103 }
3104 }
3105 break;
3106 }
3107 }
3108 return false;
3109}
3110
3111bool
Greg Clayton03e0f972010-09-13 03:32:57 +00003112ClangASTContext::IsFunctionPointerType (void *clang_type)
3113{
3114 if (clang_type)
3115 {
3116 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3117
3118 if (qual_type->isFunctionPointerType())
3119 return true;
3120
3121 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3122 switch (type_class)
3123 {
3124 case clang::Type::Typedef:
3125 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3126
3127 case clang::Type::LValueReference:
3128 case clang::Type::RValueReference:
3129 {
3130 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3131 if (reference_type)
3132 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3133 }
3134 break;
3135 }
3136 }
3137 return false;
3138}
3139
3140
3141
3142
3143bool
Greg Clayton84f80752010-07-22 18:30:50 +00003144ClangASTContext::IsArrayType (void *clang_type, void **member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003145{
3146 if (!clang_type)
3147 return false;
3148
3149 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3150
Greg Clayton03e0f972010-09-13 03:32:57 +00003151 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3152 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003153 {
Greg Clayton1674b122010-07-21 22:12:05 +00003154 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003155 if (member_type)
3156 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3157 if (size)
3158 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3159 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003160 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003161 if (member_type)
3162 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3163 if (size)
3164 *size = 0;
3165 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003166 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003167 if (member_type)
3168 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3169 if (size)
3170 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003171 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003172 if (member_type)
3173 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3174 if (size)
3175 *size = 0;
3176 return true;
3177 }
3178 return false;
3179}
3180
3181
3182#pragma mark Typedefs
3183
3184void *
3185ClangASTContext::CreateTypedefType (const char *name, void *clang_type, DeclContext *decl_ctx)
3186{
3187 if (clang_type)
3188 {
3189 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3190 ASTContext *ast_context = getASTContext();
3191 IdentifierTable *identifier_table = getIdentifierTable();
3192 assert (ast_context != NULL);
3193 assert (identifier_table != NULL);
3194 if (decl_ctx == NULL)
3195 decl_ctx = ast_context->getTranslationUnitDecl();
3196 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3197 decl_ctx,
3198 SourceLocation(),
3199 name ? &identifier_table->get(name) : NULL, // Identifier
3200 ast_context->CreateTypeSourceInfo(qual_type));
3201
3202 // Get a uniqued QualType for the typedef decl type
3203 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3204 }
3205 return NULL;
3206}
3207
3208
3209std::string
3210ClangASTContext::GetTypeName (void *opaque_qual_type)
3211{
3212 std::string return_name;
3213
3214 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_qual_type));
3215
3216 const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
3217 if (typedef_type)
3218 {
3219 const clang::TypedefDecl *typedef_decl = typedef_type->getDecl();
3220 return_name = typedef_decl->getQualifiedNameAsString();
3221 }
3222 else
3223 {
3224 return_name = qual_type.getAsString();
3225 }
3226
3227 return return_name;
3228}
3229
3230// Disable this for now since I can't seem to get a nicely formatted float
3231// out of the APFloat class without just getting the float, double or quad
3232// and then using a formatted print on it which defeats the purpose. We ideally
3233// would like to get perfect string values for any kind of float semantics
3234// so we can support remote targets. The code below also requires a patch to
3235// llvm::APInt.
3236//bool
3237//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, void *clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
3238//{
3239// uint32_t count = 0;
3240// bool is_complex = false;
3241// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3242// {
3243// unsigned num_bytes_per_float = byte_size / count;
3244// unsigned num_bits_per_float = num_bytes_per_float * 8;
3245//
3246// float_str.clear();
3247// uint32_t i;
3248// for (i=0; i<count; i++)
3249// {
3250// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3251// bool is_ieee = false;
3252// APFloat ap_float(ap_int, is_ieee);
3253// char s[1024];
3254// unsigned int hex_digits = 0;
3255// bool upper_case = false;
3256//
3257// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3258// {
3259// if (i > 0)
3260// float_str.append(", ");
3261// float_str.append(s);
3262// if (i == 1 && is_complex)
3263// float_str.append(1, 'i');
3264// }
3265// }
3266// return !float_str.empty();
3267// }
3268// return false;
3269//}
3270
3271size_t
3272ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, void *clang_type, const char *s, uint8_t *dst, size_t dst_size)
3273{
3274 if (clang_type)
3275 {
3276 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3277 uint32_t count = 0;
3278 bool is_complex = false;
3279 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3280 {
3281 // TODO: handle complex and vector types
3282 if (count != 1)
3283 return false;
3284
3285 StringRef s_sref(s);
3286 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3287
3288 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3289 const uint64_t byte_size = bit_size / 8;
3290 if (dst_size >= byte_size)
3291 {
3292 if (bit_size == sizeof(float)*8)
3293 {
3294 float float32 = ap_float.convertToFloat();
3295 ::memcpy (dst, &float32, byte_size);
3296 return byte_size;
3297 }
3298 else if (bit_size >= 64)
3299 {
3300 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3301 ::memcpy (dst, ap_int.getRawData(), byte_size);
3302 return byte_size;
3303 }
3304 }
3305 }
3306 }
3307 return 0;
3308}
Sean Callanana751f7b2010-09-17 02:24:29 +00003309
3310unsigned
3311ClangASTContext::GetTypeQualifiers(void *clang_type)
3312{
3313 assert (clang_type);
3314
3315 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3316
3317 return qual_type.getQualifiers().getCVRQualifiers();
3318}