blob: 3d6d61e4395e78c57d9a4783cbbc34a55901fbad [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
Chris Lattner24943d22010-06-08 16:52:24 +000037using namespace lldb_private;
38using namespace llvm;
39using namespace clang;
40
Greg Clayton84f80752010-07-22 18:30:50 +000041static AccessSpecifier
42ConvertAccessTypeToAccessSpecifier (ClangASTContext::AccessType access)
43{
44 switch (access)
45 {
46 default: break;
47 case ClangASTContext::eAccessNone: return AS_none;
48 case ClangASTContext::eAccessPublic: return AS_public;
49 case ClangASTContext::eAccessPrivate: return AS_private;
50 case ClangASTContext::eAccessProtected: return AS_protected;
51 }
52 return AS_none;
53}
54
55static ObjCIvarDecl::AccessControl
56ConvertAccessTypeToObjCIvarAccessControl (ClangASTContext::AccessType access)
57{
58 switch (access)
59 {
60 default: break;
61 case ClangASTContext::eAccessNone: return ObjCIvarDecl::None;
62 case ClangASTContext::eAccessPublic: return ObjCIvarDecl::Public;
63 case ClangASTContext::eAccessPrivate: return ObjCIvarDecl::Private;
64 case ClangASTContext::eAccessProtected: return ObjCIvarDecl::Protected;
65 case ClangASTContext::eAccessPackage: return ObjCIvarDecl::Package;
66 }
67 return ObjCIvarDecl::None;
68}
69
70
Chris Lattner24943d22010-06-08 16:52:24 +000071static void
72ParseLangArgs
73(
74 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000075 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000076)
77{
78 // FIXME: Cleanup per-file based stuff.
79
80 // Set some properties which depend soley on the input kind; it would be nice
81 // to move these to the language standard, and have the driver resolve the
82 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000083 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000084 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000085 } else if (IK == IK_ObjC ||
86 IK == IK_ObjCXX ||
87 IK == IK_PreprocessedObjC ||
88 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000089 Opts.ObjC1 = Opts.ObjC2 = 1;
90 }
91
92 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
93
94 if (LangStd == LangStandard::lang_unspecified) {
95 // Based on the base language, pick one.
96 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +000097 case IK_None:
98 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +000099 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +0000100 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +0000101 LangStd = LangStandard::lang_opencl;
102 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000103 case IK_Asm:
104 case IK_C:
105 case IK_PreprocessedC:
106 case IK_ObjC:
107 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +0000108 LangStd = LangStandard::lang_gnu99;
109 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000110 case IK_CXX:
111 case IK_PreprocessedCXX:
112 case IK_ObjCXX:
113 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +0000114 LangStd = LangStandard::lang_gnucxx98;
115 break;
116 }
117 }
118
119 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
120 Opts.BCPLComment = Std.hasBCPLComments();
121 Opts.C99 = Std.isC99();
122 Opts.CPlusPlus = Std.isCPlusPlus();
123 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
124 Opts.Digraphs = Std.hasDigraphs();
125 Opts.GNUMode = Std.isGNUMode();
126 Opts.GNUInline = !Std.isC99();
127 Opts.HexFloats = Std.hasHexFloats();
128 Opts.ImplicitInt = Std.hasImplicitInt();
129
130 // OpenCL has some additional defaults.
131 if (LangStd == LangStandard::lang_opencl) {
132 Opts.OpenCL = 1;
133 Opts.AltiVec = 1;
134 Opts.CXXOperatorNames = 1;
135 Opts.LaxVectorConversions = 1;
136 }
137
138 // OpenCL and C++ both have bool, true, false keywords.
139 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
140
141// if (Opts.CPlusPlus)
142// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
143//
144// if (Args.hasArg(OPT_fobjc_gc_only))
145// Opts.setGCMode(LangOptions::GCOnly);
146// else if (Args.hasArg(OPT_fobjc_gc))
147// Opts.setGCMode(LangOptions::HybridGC);
148//
149// if (Args.hasArg(OPT_print_ivar_layout))
150// Opts.ObjCGCBitmapPrint = 1;
151//
152// if (Args.hasArg(OPT_faltivec))
153// Opts.AltiVec = 1;
154//
155// if (Args.hasArg(OPT_pthread))
156// Opts.POSIXThreads = 1;
157//
158// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
159// "default");
160// if (Vis == "default")
161 Opts.setVisibilityMode(LangOptions::Default);
162// else if (Vis == "hidden")
163// Opts.setVisibilityMode(LangOptions::Hidden);
164// else if (Vis == "protected")
165// Opts.setVisibilityMode(LangOptions::Protected);
166// else
167// Diags.Report(diag::err_drv_invalid_value)
168// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
169
170// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
171
172 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
173 // is specified, or -std is set to a conforming mode.
174 Opts.Trigraphs = !Opts.GNUMode;
175// if (Args.hasArg(OPT_trigraphs))
176// Opts.Trigraphs = 1;
177//
178// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
179// OPT_fno_dollars_in_identifiers,
180// !Opts.AsmPreprocessor);
181// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
182// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
183// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
184// if (Args.hasArg(OPT_fno_lax_vector_conversions))
185// Opts.LaxVectorConversions = 0;
186// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
187// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
188// Opts.Blocks = Args.hasArg(OPT_fblocks);
189// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
190// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
191// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
192// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
193// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
194// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
195// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
196// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
197// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
198// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
199// Diags);
200// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
201// Opts.ObjCConstantStringClass = getLastArgValue(Args,
202// OPT_fconstant_string_class);
203// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
204// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
205// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
206// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
207// Opts.Static = Args.hasArg(OPT_static_define);
208 Opts.OptimizeSize = 0;
209
210 // FIXME: Eliminate this dependency.
211// unsigned Opt =
212// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
213// Opts.Optimize = Opt != 0;
214 unsigned Opt = 0;
215
216 // This is the __NO_INLINE__ define, which just depends on things like the
217 // optimization level and -fno-inline, not actually whether the backend has
218 // inlining enabled.
219 //
220 // FIXME: This is affected by other options (-fno-inline).
221 Opts.NoInline = !Opt;
222
223// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
224// switch (SSP) {
225// default:
226// Diags.Report(diag::err_drv_invalid_value)
227// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
228// break;
229// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
230// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
231// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
232// }
233}
234
Chris Lattner24943d22010-06-08 16:52:24 +0000235
Chris Lattner24943d22010-06-08 16:52:24 +0000236ClangASTContext::ClangASTContext(const char *target_triple) :
237 m_target_triple(),
238 m_ast_context_ap(),
239 m_language_options_ap(),
240 m_source_manager_ap(),
241 m_diagnostic_ap(),
242 m_target_options_ap(),
243 m_target_info_ap(),
244 m_identifier_table_ap(),
245 m_selector_table_ap(),
246 m_builtins_ap()
247{
248 if (target_triple && target_triple[0])
249 m_target_triple.assign (target_triple);
250}
251
252//----------------------------------------------------------------------
253// Destructor
254//----------------------------------------------------------------------
255ClangASTContext::~ClangASTContext()
256{
257 m_builtins_ap.reset();
258 m_selector_table_ap.reset();
259 m_identifier_table_ap.reset();
260 m_target_info_ap.reset();
261 m_target_options_ap.reset();
262 m_diagnostic_ap.reset();
263 m_source_manager_ap.reset();
264 m_language_options_ap.reset();
265 m_ast_context_ap.reset();
266}
267
268
269void
270ClangASTContext::Clear()
271{
272 m_ast_context_ap.reset();
273 m_language_options_ap.reset();
274 m_source_manager_ap.reset();
275 m_diagnostic_ap.reset();
276 m_target_options_ap.reset();
277 m_target_info_ap.reset();
278 m_identifier_table_ap.reset();
279 m_selector_table_ap.reset();
280 m_builtins_ap.reset();
281}
282
283const char *
284ClangASTContext::GetTargetTriple ()
285{
286 return m_target_triple.c_str();
287}
288
289void
290ClangASTContext::SetTargetTriple (const char *target_triple)
291{
292 Clear();
293 m_target_triple.assign(target_triple);
294}
295
296
297ASTContext *
298ClangASTContext::getASTContext()
299{
300 if (m_ast_context_ap.get() == NULL)
301 {
302 m_ast_context_ap.reset(
303 new ASTContext(
304 *getLanguageOptions(),
305 *getSourceManager(),
306 *getTargetInfo(),
307 *getIdentifierTable(),
308 *getSelectorTable(),
309 *getBuiltinContext()));
310 }
311 return m_ast_context_ap.get();
312}
313
314Builtin::Context *
315ClangASTContext::getBuiltinContext()
316{
317 if (m_builtins_ap.get() == NULL)
318 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
319 return m_builtins_ap.get();
320}
321
322IdentifierTable *
323ClangASTContext::getIdentifierTable()
324{
325 if (m_identifier_table_ap.get() == NULL)
326 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
327 return m_identifier_table_ap.get();
328}
329
330LangOptions *
331ClangASTContext::getLanguageOptions()
332{
333 if (m_language_options_ap.get() == NULL)
334 {
335 m_language_options_ap.reset(new LangOptions());
Greg Claytone41c4b22010-06-13 17:34:29 +0000336 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
337// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner24943d22010-06-08 16:52:24 +0000338 }
339 return m_language_options_ap.get();
340}
341
342SelectorTable *
343ClangASTContext::getSelectorTable()
344{
345 if (m_selector_table_ap.get() == NULL)
346 m_selector_table_ap.reset (new SelectorTable());
347 return m_selector_table_ap.get();
348}
349
Greg Clayton1674b122010-07-21 22:12:05 +0000350clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000351ClangASTContext::getSourceManager()
352{
353 if (m_source_manager_ap.get() == NULL)
Greg Clayton1674b122010-07-21 22:12:05 +0000354 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic()));
Chris Lattner24943d22010-06-08 16:52:24 +0000355 return m_source_manager_ap.get();
356}
357
358Diagnostic *
359ClangASTContext::getDiagnostic()
360{
361 if (m_diagnostic_ap.get() == NULL)
362 m_diagnostic_ap.reset(new Diagnostic());
363 return m_diagnostic_ap.get();
364}
365
366TargetOptions *
367ClangASTContext::getTargetOptions()
368{
369 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
370 {
371 m_target_options_ap.reset (new TargetOptions());
372 if (m_target_options_ap.get())
373 m_target_options_ap->Triple = m_target_triple;
374 }
375 return m_target_options_ap.get();
376}
377
378
379TargetInfo *
380ClangASTContext::getTargetInfo()
381{
382 // target_triple should be something like "x86_64-apple-darwin10"
383 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
384 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
385 return m_target_info_ap.get();
386}
387
388#pragma mark Basic Types
389
390static inline bool
391QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
392{
393 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
394 if (qual_type_bit_size == bit_size)
395 return true;
396 return false;
397}
398
399void *
400ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding, uint32_t bit_size)
401{
402 ASTContext *ast_context = getASTContext();
403
404 assert (ast_context != NULL);
405
406 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
407}
408
409void *
410ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast_context, lldb::Encoding encoding, uint32_t bit_size)
411{
412 if (!ast_context)
413 return NULL;
414
415 switch (encoding)
416 {
417 case lldb::eEncodingInvalid:
418 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
419 return ast_context->VoidPtrTy.getAsOpaquePtr();
420 break;
421
422 case lldb::eEncodingUint:
423 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
424 return ast_context->UnsignedCharTy.getAsOpaquePtr();
425 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
426 return ast_context->UnsignedShortTy.getAsOpaquePtr();
427 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
428 return ast_context->UnsignedIntTy.getAsOpaquePtr();
429 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
430 return ast_context->UnsignedLongTy.getAsOpaquePtr();
431 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
432 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
433 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
434 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
435 break;
436
437 case lldb::eEncodingSint:
438 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
439 return ast_context->CharTy.getAsOpaquePtr();
440 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
441 return ast_context->ShortTy.getAsOpaquePtr();
442 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
443 return ast_context->IntTy.getAsOpaquePtr();
444 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
445 return ast_context->LongTy.getAsOpaquePtr();
446 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
447 return ast_context->LongLongTy.getAsOpaquePtr();
448 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
449 return ast_context->Int128Ty.getAsOpaquePtr();
450 break;
451
452 case lldb::eEncodingIEEE754:
453 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
454 return ast_context->FloatTy.getAsOpaquePtr();
455 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
456 return ast_context->DoubleTy.getAsOpaquePtr();
457 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
458 return ast_context->LongDoubleTy.getAsOpaquePtr();
459 break;
460
461 case lldb::eEncodingVector:
462 default:
463 break;
464 }
465
466 return NULL;
467}
468
469void *
470ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
471{
472 ASTContext *ast_context = getASTContext();
473
474 #define streq(a,b) strcmp(a,b) == 0
475 assert (ast_context != NULL);
476 if (ast_context)
477 {
478 switch (dw_ate)
479 {
480 default:
481 break;
482
483 case DW_ATE_address:
484 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
485 return ast_context->VoidPtrTy.getAsOpaquePtr();
486 break;
487
488 case DW_ATE_boolean:
489 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
490 return ast_context->BoolTy.getAsOpaquePtr();
491 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
492 return ast_context->UnsignedCharTy.getAsOpaquePtr();
493 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
494 return ast_context->UnsignedShortTy.getAsOpaquePtr();
495 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
496 return ast_context->UnsignedIntTy.getAsOpaquePtr();
497 break;
498
499 case DW_ATE_complex_float:
500 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
501 return ast_context->FloatComplexTy.getAsOpaquePtr();
502 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
503 return ast_context->DoubleComplexTy.getAsOpaquePtr();
504 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
505 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
506 break;
507
508 case DW_ATE_float:
509 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
510 return ast_context->FloatTy.getAsOpaquePtr();
511 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
512 return ast_context->DoubleTy.getAsOpaquePtr();
513 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
514 return ast_context->LongDoubleTy.getAsOpaquePtr();
515 break;
516
517 case DW_ATE_signed:
518 if (type_name)
519 {
520 if (streq(type_name, "int") ||
521 streq(type_name, "signed int"))
522 {
523 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
524 return ast_context->IntTy.getAsOpaquePtr();
525 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
526 return ast_context->Int128Ty.getAsOpaquePtr();
527 }
528
529 if (streq(type_name, "long int") ||
530 streq(type_name, "long long int") ||
531 streq(type_name, "signed long long"))
532 {
533 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
534 return ast_context->LongTy.getAsOpaquePtr();
535 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
536 return ast_context->LongLongTy.getAsOpaquePtr();
537 }
538
539 if (streq(type_name, "short") ||
540 streq(type_name, "short int") ||
541 streq(type_name, "signed short") ||
542 streq(type_name, "short signed int"))
543 {
544 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
545 return ast_context->ShortTy.getAsOpaquePtr();
546 }
547
548 if (streq(type_name, "char") ||
549 streq(type_name, "signed char"))
550 {
551 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
552 return ast_context->CharTy.getAsOpaquePtr();
553 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
554 return ast_context->SignedCharTy.getAsOpaquePtr();
555 }
556
557 if (streq(type_name, "wchar_t"))
558 {
559 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
560 return ast_context->WCharTy.getAsOpaquePtr();
561 }
562
563 }
564 // We weren't able to match up a type name, just search by size
565 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
566 return ast_context->CharTy.getAsOpaquePtr();
567 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
568 return ast_context->ShortTy.getAsOpaquePtr();
569 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
570 return ast_context->IntTy.getAsOpaquePtr();
571 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
572 return ast_context->LongTy.getAsOpaquePtr();
573 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
574 return ast_context->LongLongTy.getAsOpaquePtr();
575 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
576 return ast_context->Int128Ty.getAsOpaquePtr();
577 break;
578
579 case DW_ATE_signed_char:
580 if (type_name)
581 {
582 if (streq(type_name, "signed char"))
583 {
584 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
585 return ast_context->SignedCharTy.getAsOpaquePtr();
586 }
587 }
588 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
589 return ast_context->CharTy.getAsOpaquePtr();
590 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
591 return ast_context->SignedCharTy.getAsOpaquePtr();
592 break;
593
594 case DW_ATE_unsigned:
595 if (type_name)
596 {
597 if (streq(type_name, "unsigned int"))
598 {
599 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
600 return ast_context->UnsignedIntTy.getAsOpaquePtr();
601 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
602 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
603 }
604
605 if (streq(type_name, "unsigned int") ||
606 streq(type_name, "long unsigned int") ||
607 streq(type_name, "unsigned long long"))
608 {
609 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
610 return ast_context->UnsignedLongTy.getAsOpaquePtr();
611 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
612 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
613 }
614
615 if (streq(type_name, "unsigned short") ||
616 streq(type_name, "short unsigned int"))
617 {
618 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
619 return ast_context->UnsignedShortTy.getAsOpaquePtr();
620 }
621 if (streq(type_name, "unsigned char"))
622 {
623 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
624 return ast_context->UnsignedCharTy.getAsOpaquePtr();
625 }
626
627 }
628 // We weren't able to match up a type name, just search by size
629 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
630 return ast_context->UnsignedCharTy.getAsOpaquePtr();
631 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
632 return ast_context->UnsignedShortTy.getAsOpaquePtr();
633 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
634 return ast_context->UnsignedIntTy.getAsOpaquePtr();
635 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
636 return ast_context->UnsignedLongTy.getAsOpaquePtr();
637 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
638 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
639 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
640 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
641 break;
642
643 case DW_ATE_unsigned_char:
644 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
645 return ast_context->UnsignedCharTy.getAsOpaquePtr();
646 break;
647
648 case DW_ATE_imaginary_float:
649 break;
650 }
651 }
652 // This assert should fire for anything that we don't catch above so we know
653 // to fix any issues we run into.
654 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
655 return NULL;
656}
657
658void *
659ClangASTContext::GetVoidBuiltInType()
660{
661 return getASTContext()->VoidTy.getAsOpaquePtr();
662}
663
664void *
665ClangASTContext::GetCStringType (bool is_const)
666{
667 QualType char_type(getASTContext()->CharTy);
668
669 if (is_const)
670 char_type.addConst();
671
672 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
673}
674
675void *
676ClangASTContext::GetVoidPtrType (bool is_const)
677{
678 return GetVoidPtrType(getASTContext(), is_const);
679}
680
681void *
682ClangASTContext::GetVoidPtrType (clang::ASTContext *ast_context, bool is_const)
683{
684 QualType void_ptr_type(ast_context->VoidPtrTy);
685
686 if (is_const)
687 void_ptr_type.addConst();
688
689 return void_ptr_type.getAsOpaquePtr();
690}
691
692void *
693ClangASTContext::CopyType(clang::ASTContext *dest_context,
694 clang::ASTContext *source_context,
Greg Clayton84f80752010-07-22 18:30:50 +0000695 void *clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000696{
697 Diagnostic diagnostics;
698 FileManager file_manager;
699 ASTImporter importer(diagnostics,
700 *dest_context, file_manager,
701 *source_context, file_manager);
702 QualType ret = importer.Import(QualType::getFromOpaquePtr(clang_type));
703 return ret.getAsOpaquePtr();
704}
705
Sean Callanan8d825062010-07-16 00:00:27 +0000706bool
707ClangASTContext::AreTypesSame(clang::ASTContext *ast_context,
Sean Callanan5510ddd2010-07-15 22:30:52 +0000708 void *type1,
709 void *type2)
710{
711 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
712 QualType::getFromOpaquePtr(type2));
713}
714
Chris Lattner24943d22010-06-08 16:52:24 +0000715#pragma mark CVR modifiers
716
717void *
718ClangASTContext::AddConstModifier (void *clang_type)
719{
720 if (clang_type)
721 {
722 QualType result(QualType::getFromOpaquePtr(clang_type));
723 result.addConst();
724 return result.getAsOpaquePtr();
725 }
726 return NULL;
727}
728
729void *
730ClangASTContext::AddRestrictModifier (void *clang_type)
731{
732 if (clang_type)
733 {
734 QualType result(QualType::getFromOpaquePtr(clang_type));
735 result.getQualifiers().setRestrict (true);
736 return result.getAsOpaquePtr();
737 }
738 return NULL;
739}
740
741void *
742ClangASTContext::AddVolatileModifier (void *clang_type)
743{
744 if (clang_type)
745 {
746 QualType result(QualType::getFromOpaquePtr(clang_type));
747 result.getQualifiers().setVolatile (true);
748 return result.getAsOpaquePtr();
749 }
750 return NULL;
751}
752
753#pragma mark Structure, Unions, Classes
754
755void *
756ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx)
757{
758 ASTContext *ast_context = getASTContext();
759 assert (ast_context != NULL);
760
761 if (decl_ctx == NULL)
762 decl_ctx = ast_context->getTranslationUnitDecl();
763
764 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
765 // we will need to update this code. I was told to currently always use
766 // the CXXRecordDecl class since we often don't know from debug information
767 // if something is struct or a class, so we default to always use the more
768 // complete definition just in case.
769 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
770 (TagDecl::TagKind)kind,
771 decl_ctx,
772 SourceLocation(),
773 name && name[0] ? &ast_context->Idents.get(name) : NULL);
774
775 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
776}
777
778bool
Greg Clayton84f80752010-07-22 18:30:50 +0000779ClangASTContext::AddFieldToRecordType
780(
781 void *record_clang_type,
782 const char *name,
783 void *field_type,
784 AccessType access,
785 uint32_t bitfield_bit_size
786)
Chris Lattner24943d22010-06-08 16:52:24 +0000787{
788 if (record_clang_type == NULL || field_type == NULL)
789 return false;
790
791 ASTContext *ast_context = getASTContext();
792 IdentifierTable *identifier_table = getIdentifierTable();
793
794 assert (ast_context != NULL);
795 assert (identifier_table != NULL);
796
797 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
798
Greg Clayton1674b122010-07-21 22:12:05 +0000799 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000800 if (clang_type)
801 {
802 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
803
804 if (record_type)
805 {
806 RecordDecl *record_decl = record_type->getDecl();
807
808 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
809 if (cxx_record_decl)
810 cxx_record_decl->setEmpty (false);
811
812 clang::Expr *bit_width = NULL;
813 if (bitfield_bit_size != 0)
814 {
815 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
816 bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
817 }
Greg Clayton84f80752010-07-22 18:30:50 +0000818 FieldDecl *field = FieldDecl::Create (*ast_context,
819 record_decl,
820 SourceLocation(),
821 name ? &identifier_table->get(name) : NULL, // Identifier
822 QualType::getFromOpaquePtr(field_type), // Field type
823 NULL, // DeclaratorInfo *
824 bit_width, // BitWidth
825 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +0000826
Greg Clayton84f80752010-07-22 18:30:50 +0000827 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +0000828
829 if (field)
830 {
831 record_decl->addDecl(field);
832 return true;
833 }
834 }
835 }
836 return false;
837}
838
839bool
840ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
841{
842 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
843}
844
845bool
846ClangASTContext::FieldIsBitfield
847(
848 ASTContext *ast_context,
849 FieldDecl* field,
850 uint32_t& bitfield_bit_size
851)
852{
853 if (ast_context == NULL || field == NULL)
854 return false;
855
856 if (field->isBitField())
857 {
858 Expr* bit_width_expr = field->getBitWidth();
859 if (bit_width_expr)
860 {
861 llvm::APSInt bit_width_apsint;
862 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
863 {
864 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
865 return true;
866 }
867 }
868 }
869 return false;
870}
871
872bool
873ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
874{
875 if (record_decl == NULL)
876 return false;
877
878 if (!record_decl->field_empty())
879 return true;
880
881 // No fields, lets check this is a CXX record and check the base classes
882 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
883 if (cxx_record_decl)
884 {
885 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
886 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
887 base_class != base_class_end;
888 ++base_class)
889 {
890 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
891 if (RecordHasFields(base_class_decl))
892 return true;
893 }
894 }
895 return false;
896}
897
898void
899ClangASTContext::SetDefaultAccessForRecordFields (void *clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
900{
901 if (clang_qual_type)
902 {
903 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +0000904 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000905 if (clang_type)
906 {
907 RecordType *record_type = dyn_cast<RecordType>(clang_type);
908 if (record_type)
909 {
910 RecordDecl *record_decl = record_type->getDecl();
911 if (record_decl)
912 {
913 uint32_t field_idx;
914 RecordDecl::field_iterator field, field_end;
915 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
916 field != field_end;
917 ++field, ++field_idx)
918 {
919 // If no accessibility was assigned, assign the correct one
920 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
921 field->setAccess ((AccessSpecifier)default_accessibility);
922 }
923 }
924 }
925 }
926 }
927}
928
929#pragma mark C++ Base Classes
930
931CXXBaseSpecifier *
Greg Clayton84f80752010-07-22 18:30:50 +0000932ClangASTContext::CreateBaseClassSpecifier (void *base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +0000933{
934 if (base_class_type)
935 return new CXXBaseSpecifier(SourceRange(), is_virtual, base_of_class, (AccessSpecifier)access, QualType::getFromOpaquePtr(base_class_type));
936 return NULL;
937}
938
Greg Claytone9d0df42010-07-02 01:29:13 +0000939void
940ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
941{
942 for (unsigned i=0; i<num_base_classes; ++i)
943 {
944 delete base_classes[i];
945 base_classes[i] = NULL;
946 }
947}
948
Chris Lattner24943d22010-06-08 16:52:24 +0000949bool
950ClangASTContext::SetBaseClassesForClassType (void *class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
951{
952 if (class_clang_type)
953 {
Greg Clayton1674b122010-07-21 22:12:05 +0000954 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000955 if (clang_type)
956 {
957 RecordType *record_type = dyn_cast<RecordType>(clang_type);
958 if (record_type)
959 {
960 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
961 if (cxx_record_decl)
962 {
963 //cxx_record_decl->setEmpty (false);
964 cxx_record_decl->setBases(base_classes, num_base_classes);
965 return true;
966 }
967 }
968 }
969 }
970 return false;
971}
Greg Clayton84f80752010-07-22 18:30:50 +0000972#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +0000973
Greg Clayton84f80752010-07-22 18:30:50 +0000974void *
975ClangASTContext::CreateObjCClass
976(
977 const char *name,
978 DeclContext *decl_ctx,
979 bool isForwardDecl,
980 bool isInternal
981)
982{
983 ASTContext *ast_context = getASTContext();
984 assert (ast_context != NULL);
985 assert (name && name[0]);
986 if (decl_ctx == NULL)
987 decl_ctx = ast_context->getTranslationUnitDecl();
988
989 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
990 // we will need to update this code. I was told to currently always use
991 // the CXXRecordDecl class since we often don't know from debug information
992 // if something is struct or a class, so we default to always use the more
993 // complete definition just in case.
994 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
995 decl_ctx,
996 SourceLocation(),
997 &ast_context->Idents.get(name),
998 SourceLocation(),
999 isForwardDecl,
1000 isInternal);
1001
1002 return QualType (decl->getTypeForDecl(), 0).getAsOpaquePtr();
1003}
1004
1005bool
1006ClangASTContext::SetObjCSuperClass (void *class_opaque_type, void *super_opaque_type)
1007{
1008 if (class_opaque_type && super_opaque_type)
1009 {
1010 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1011 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1012 clang::Type *class_type = class_qual_type.getTypePtr();
1013 clang::Type *super_type = super_qual_type.getTypePtr();
1014 if (class_type && super_type)
1015 {
1016 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1017 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1018 if (objc_class_type && objc_super_type)
1019 {
1020 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1021 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1022 if (class_interface_decl && super_interface_decl)
1023 {
1024 class_interface_decl->setSuperClass(super_interface_decl);
1025 return true;
1026 }
1027 }
1028 }
1029 }
1030 return false;
1031}
1032
1033
1034bool
1035ClangASTContext::AddObjCClassIVar
1036(
1037 void *class_opaque_type,
1038 const char *name,
1039 void *ivar_opaque_type,
1040 AccessType access,
1041 uint32_t bitfield_bit_size,
1042 bool isSynthesized
1043)
1044{
1045 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1046 return false;
1047
1048 ASTContext *ast_context = getASTContext();
1049 IdentifierTable *identifier_table = getIdentifierTable();
1050
1051 assert (ast_context != NULL);
1052 assert (identifier_table != NULL);
1053
1054 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1055
1056 clang::Type *class_type = class_qual_type.getTypePtr();
1057 if (class_type)
1058 {
1059 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1060
1061 if (objc_class_type)
1062 {
1063 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1064
1065 if (class_interface_decl)
1066 {
1067 clang::Expr *bit_width = NULL;
1068 if (bitfield_bit_size != 0)
1069 {
1070 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
1071 bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
1072 }
1073
1074 //ObjCIvarDecl *field =
1075 ObjCIvarDecl::Create (*ast_context,
1076 class_interface_decl,
1077 SourceLocation(),
1078 &identifier_table->get(name), // Identifier
1079 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1080 NULL, // TypeSourceInfo *
1081 ConvertAccessTypeToObjCIvarAccessControl (access),
1082 bit_width,
1083 isSynthesized);
1084 // TODO: Do I need to do an addDecl? I am thinking I don't since
1085 // I passed the "class_interface_decl" into "ObjCIvarDecl::Create"
1086 // above. Verify this. Also verify it is ok to pass NULL TypeSourceInfo
1087 // above.
1088 return true;
1089 }
1090 }
1091 }
1092 return false;
1093}
Chris Lattner24943d22010-06-08 16:52:24 +00001094
1095#pragma mark Aggregate Types
1096
1097bool
1098ClangASTContext::IsAggregateType (void *clang_type)
1099{
1100 if (clang_type == NULL)
1101 return false;
1102
1103 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1104
1105 if (qual_type->isAggregateType ())
1106 return true;
1107
1108 switch (qual_type->getTypeClass())
1109 {
Greg Clayton1674b122010-07-21 22:12:05 +00001110 case clang::Type::IncompleteArray:
1111 case clang::Type::VariableArray:
1112 case clang::Type::ConstantArray:
1113 case clang::Type::ExtVector:
1114 case clang::Type::Vector:
1115 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001116 return true;
1117
Greg Clayton1674b122010-07-21 22:12:05 +00001118 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001119 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1120
1121 default:
1122 break;
1123 }
1124 // The clang type does have a value
1125 return false;
1126}
1127
1128uint32_t
1129ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_classes)
1130{
1131 if (clang_qual_type == NULL)
1132 return 0;
1133
1134 uint32_t num_children = 0;
1135 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
1136 switch (qual_type->getTypeClass())
1137 {
Greg Clayton1674b122010-07-21 22:12:05 +00001138 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001139 {
1140 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1141 const RecordDecl *record_decl = record_type->getDecl();
1142 assert(record_decl);
1143 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1144 if (cxx_record_decl)
1145 {
1146 if (omit_empty_base_classes)
1147 {
1148 // Check each base classes to see if it or any of its
1149 // base classes contain any fields. This can help
1150 // limit the noise in variable views by not having to
1151 // show base classes that contain no members.
1152 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1153 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1154 base_class != base_class_end;
1155 ++base_class)
1156 {
1157 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1158
1159 // Skip empty base classes
1160 if (RecordHasFields(base_class_decl) == false)
1161 continue;
1162
1163 num_children++;
1164 }
1165 }
1166 else
1167 {
1168 // Include all base classes
1169 num_children += cxx_record_decl->getNumBases();
1170 }
1171
1172 }
1173 RecordDecl::field_iterator field, field_end;
1174 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1175 ++num_children;
1176 }
1177 break;
1178
Greg Clayton1674b122010-07-21 22:12:05 +00001179 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001180 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1181 break;
1182
Greg Clayton1674b122010-07-21 22:12:05 +00001183 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001184 {
1185 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1186 QualType pointee_type = pointer_type->getPointeeType();
1187 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), omit_empty_base_classes);
1188 // If this type points to a simple type, then it has 1 child
1189 if (num_pointee_children == 0)
1190 num_children = 1;
1191 else
1192 num_children = num_pointee_children;
1193 }
1194 break;
1195
Greg Clayton1674b122010-07-21 22:12:05 +00001196 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001197 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1198 break;
1199
1200 default:
1201 break;
1202 }
1203 return num_children;
1204}
1205
1206
1207void *
1208ClangASTContext::GetChildClangTypeAtIndex
1209(
1210 const char *parent_name,
1211 void *parent_clang_type,
1212 uint32_t idx,
1213 bool transparent_pointers,
1214 bool omit_empty_base_classes,
1215 std::string& child_name,
1216 uint32_t &child_byte_size,
1217 int32_t &child_byte_offset,
1218 uint32_t &child_bitfield_bit_size,
1219 uint32_t &child_bitfield_bit_offset
1220)
1221{
1222 if (parent_clang_type)
1223
1224 return GetChildClangTypeAtIndex (getASTContext(),
1225 parent_name,
1226 parent_clang_type,
1227 idx,
1228 transparent_pointers,
1229 omit_empty_base_classes,
1230 child_name,
1231 child_byte_size,
1232 child_byte_offset,
1233 child_bitfield_bit_size,
1234 child_bitfield_bit_offset);
1235 return NULL;
1236}
1237
1238void *
1239ClangASTContext::GetChildClangTypeAtIndex
1240(
1241 ASTContext *ast_context,
1242 const char *parent_name,
1243 void *parent_clang_type,
1244 uint32_t idx,
1245 bool transparent_pointers,
1246 bool omit_empty_base_classes,
1247 std::string& child_name,
1248 uint32_t &child_byte_size,
1249 int32_t &child_byte_offset,
1250 uint32_t &child_bitfield_bit_size,
1251 uint32_t &child_bitfield_bit_offset
1252)
1253{
1254 if (parent_clang_type == NULL)
1255 return NULL;
1256
1257 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
1258 {
1259 uint32_t bit_offset;
1260 child_bitfield_bit_size = 0;
1261 child_bitfield_bit_offset = 0;
1262 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
1263 switch (parent_qual_type->getTypeClass())
1264 {
Greg Clayton1674b122010-07-21 22:12:05 +00001265 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001266 {
1267 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
1268 const RecordDecl *record_decl = record_type->getDecl();
1269 assert(record_decl);
1270 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
1271 uint32_t child_idx = 0;
1272
1273 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1274 if (cxx_record_decl)
1275 {
1276 // We might have base classes to print out first
1277 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1278 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1279 base_class != base_class_end;
1280 ++base_class)
1281 {
1282 const CXXRecordDecl *base_class_decl = NULL;
1283
1284 // Skip empty base classes
1285 if (omit_empty_base_classes)
1286 {
1287 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1288 if (RecordHasFields(base_class_decl) == false)
1289 continue;
1290 }
1291
1292 if (idx == child_idx)
1293 {
1294 if (base_class_decl == NULL)
1295 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1296
1297
1298 if (base_class->isVirtual())
1299 bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
1300 else
1301 bit_offset = record_layout.getBaseClassOffset(base_class_decl);
1302
1303 // Base classes should be a multiple of 8 bits in size
1304 assert (bit_offset % 8 == 0);
1305 child_byte_offset = bit_offset/8;
1306 std::string base_class_type_name(base_class->getType().getAsString());
1307
1308 child_name.assign(base_class_type_name.c_str());
1309
1310 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
1311
1312 // Base classes biut sizes should be a multiple of 8 bits in size
1313 assert (clang_type_info_bit_size % 8 == 0);
1314 child_byte_size = clang_type_info_bit_size / 8;
1315 return base_class->getType().getAsOpaquePtr();
1316 }
1317 // We don't increment the child index in the for loop since we might
1318 // be skipping empty base classes
1319 ++child_idx;
1320 }
1321 }
Chris Lattner24943d22010-06-08 16:52:24 +00001322 // Make sure index is in range...
1323 uint32_t field_idx = 0;
1324 RecordDecl::field_iterator field, field_end;
1325 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
1326 {
1327 if (idx == child_idx)
1328 {
1329 // Print the member type if requested
1330 // Print the member name and equal sign
1331 child_name.assign(field->getNameAsString().c_str());
1332
1333 // Figure out the type byte size (field_type_info.first) and
1334 // alignment (field_type_info.second) from the AST context.
1335 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00001336 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00001337
1338 child_byte_size = field_type_info.first / 8;
1339
1340 // Figure out the field offset within the current struct/union/class type
1341 bit_offset = record_layout.getFieldOffset (field_idx);
1342 child_byte_offset = bit_offset / 8;
1343 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
1344 child_bitfield_bit_offset = bit_offset % 8;
1345
1346 return field->getType().getAsOpaquePtr();
1347 }
1348 }
1349 }
1350 break;
1351
Greg Clayton1674b122010-07-21 22:12:05 +00001352 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001353 {
1354 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1355 const uint64_t element_count = array->getSize().getLimitedValue();
1356
1357 if (idx < element_count)
1358 {
1359 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1360
1361 char element_name[32];
1362 ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1363
1364 child_name.assign(element_name);
1365 assert(field_type_info.first % 8 == 0);
1366 child_byte_size = field_type_info.first / 8;
1367 child_byte_offset = idx * child_byte_size;
1368 return array->getElementType().getAsOpaquePtr();
1369 }
1370 }
1371 break;
1372
Greg Clayton1674b122010-07-21 22:12:05 +00001373 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001374 {
1375 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
1376 QualType pointee_type = pointer_type->getPointeeType();
1377
1378 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1379 {
1380 return GetChildClangTypeAtIndex (ast_context,
1381 parent_name,
1382 pointer_type->getPointeeType().getAsOpaquePtr(),
1383 idx,
1384 transparent_pointers,
1385 omit_empty_base_classes,
1386 child_name,
1387 child_byte_size,
1388 child_byte_offset,
1389 child_bitfield_bit_size,
1390 child_bitfield_bit_offset);
1391 }
1392 else
1393 {
1394 if (parent_name)
1395 {
1396 child_name.assign(1, '*');
1397 child_name += parent_name;
1398 }
1399
1400 // We have a pointer to an simple type
1401 if (idx == 0)
1402 {
1403 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1404 assert(clang_type_info.first % 8 == 0);
1405 child_byte_size = clang_type_info.first / 8;
1406 child_byte_offset = 0;
1407 return pointee_type.getAsOpaquePtr();
1408 }
1409 }
1410 }
1411 break;
1412
Greg Clayton1674b122010-07-21 22:12:05 +00001413 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001414 return GetChildClangTypeAtIndex (ast_context,
1415 parent_name,
1416 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1417 idx,
1418 transparent_pointers,
1419 omit_empty_base_classes,
1420 child_name,
1421 child_byte_size,
1422 child_byte_offset,
1423 child_bitfield_bit_size,
1424 child_bitfield_bit_offset);
1425 break;
1426
1427 default:
1428 break;
1429 }
1430 }
1431 return false;
1432}
1433
1434static inline bool
1435BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
1436{
1437 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
1438}
1439
1440static uint32_t
1441GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
1442{
1443 uint32_t num_bases = 0;
1444 if (cxx_record_decl)
1445 {
1446 if (omit_empty_base_classes)
1447 {
1448 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1449 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1450 base_class != base_class_end;
1451 ++base_class)
1452 {
1453 // Skip empty base classes
1454 if (omit_empty_base_classes)
1455 {
1456 if (BaseSpecifierIsEmpty (base_class))
1457 continue;
1458 }
1459 ++num_bases;
1460 }
1461 }
1462 else
1463 num_bases = cxx_record_decl->getNumBases();
1464 }
1465 return num_bases;
1466}
1467
1468
1469static uint32_t
1470GetIndexForRecordBase
1471(
1472 const RecordDecl *record_decl,
1473 const CXXBaseSpecifier *base_spec,
1474 bool omit_empty_base_classes
1475)
1476{
1477 uint32_t child_idx = 0;
1478
1479 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1480
1481// const char *super_name = record_decl->getNameAsCString();
1482// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
1483// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
1484//
1485 if (cxx_record_decl)
1486 {
1487 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1488 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1489 base_class != base_class_end;
1490 ++base_class)
1491 {
1492 if (omit_empty_base_classes)
1493 {
1494 if (BaseSpecifierIsEmpty (base_class))
1495 continue;
1496 }
1497
1498// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
1499// child_idx,
1500// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1501//
1502//
1503 if (base_class == base_spec)
1504 return child_idx;
1505 ++child_idx;
1506 }
1507 }
1508
1509 return UINT32_MAX;
1510}
1511
1512
1513static uint32_t
1514GetIndexForRecordChild
1515(
1516 const RecordDecl *record_decl,
1517 NamedDecl *canonical_decl,
1518 bool omit_empty_base_classes
1519)
1520{
1521 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
1522
1523// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1524//
1525//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
1526// if (cxx_record_decl)
1527// {
1528// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1529// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1530// base_class != base_class_end;
1531// ++base_class)
1532// {
1533// if (omit_empty_base_classes)
1534// {
1535// if (BaseSpecifierIsEmpty (base_class))
1536// continue;
1537// }
1538//
1539//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
1540//// record_decl->getNameAsCString(),
1541//// canonical_decl->getNameAsCString(),
1542//// child_idx,
1543//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1544//
1545//
1546// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1547// if (curr_base_class_decl == canonical_decl)
1548// {
1549// return child_idx;
1550// }
1551// ++child_idx;
1552// }
1553// }
1554//
1555// const uint32_t num_bases = child_idx;
1556 RecordDecl::field_iterator field, field_end;
1557 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1558 field != field_end;
1559 ++field, ++child_idx)
1560 {
1561// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
1562// record_decl->getNameAsCString(),
1563// canonical_decl->getNameAsCString(),
1564// child_idx - num_bases,
1565// field->getNameAsCString());
1566
1567 if (field->getCanonicalDecl() == canonical_decl)
1568 return child_idx;
1569 }
1570
1571 return UINT32_MAX;
1572}
1573
1574// Look for a child member (doesn't include base classes, but it does include
1575// their members) in the type hierarchy. Returns an index path into "clang_type"
1576// on how to reach the appropriate member.
1577//
1578// class A
1579// {
1580// public:
1581// int m_a;
1582// int m_b;
1583// };
1584//
1585// class B
1586// {
1587// };
1588//
1589// class C :
1590// public B,
1591// public A
1592// {
1593// };
1594//
1595// If we have a clang type that describes "class C", and we wanted to looked
1596// "m_b" in it:
1597//
1598// With omit_empty_base_classes == false we would get an integer array back with:
1599// { 1, 1 }
1600// The first index 1 is the child index for "class A" within class C
1601// The second index 1 is the child index for "m_b" within class A
1602//
1603// With omit_empty_base_classes == true we would get an integer array back with:
1604// { 0, 1 }
1605// 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)
1606// The second index 1 is the child index for "m_b" within class A
1607
1608size_t
1609ClangASTContext::GetIndexOfChildMemberWithName
1610(
1611 ASTContext *ast_context,
1612 void *clang_type,
1613 const char *name,
1614 bool omit_empty_base_classes,
1615 std::vector<uint32_t>& child_indexes
1616)
1617{
1618 if (clang_type && name && name[0])
1619 {
1620 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1621 switch (qual_type->getTypeClass())
1622 {
Greg Clayton1674b122010-07-21 22:12:05 +00001623 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001624 {
1625 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1626 const RecordDecl *record_decl = record_type->getDecl();
1627
1628 assert(record_decl);
1629 uint32_t child_idx = 0;
1630
1631 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1632
1633 // Try and find a field that matches NAME
1634 RecordDecl::field_iterator field, field_end;
1635 StringRef name_sref(name);
1636 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1637 field != field_end;
1638 ++field, ++child_idx)
1639 {
1640 if (field->getName().equals (name_sref))
1641 {
1642 // We have to add on the number of base classes to this index!
1643 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
1644 return child_indexes.size();
1645 }
1646 }
1647
1648 if (cxx_record_decl)
1649 {
1650 const RecordDecl *parent_record_decl = cxx_record_decl;
1651
1652 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
1653
1654 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
1655 // Didn't find things easily, lets let clang do its thang...
1656 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
1657 DeclarationName decl_name(&ident_ref);
1658
1659 CXXBasePaths paths;
1660 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
1661 decl_name.getAsOpaquePtr(),
1662 paths))
1663 {
Chris Lattner24943d22010-06-08 16:52:24 +00001664 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
1665 for (path = paths.begin(); path != path_end; ++path)
1666 {
1667 const size_t num_path_elements = path->size();
1668 for (size_t e=0; e<num_path_elements; ++e)
1669 {
1670 CXXBasePathElement elem = (*path)[e];
1671
1672 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
1673 if (child_idx == UINT32_MAX)
1674 {
1675 child_indexes.clear();
1676 return 0;
1677 }
1678 else
1679 {
1680 child_indexes.push_back (child_idx);
1681 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
1682 }
1683 }
1684 DeclContext::lookup_iterator named_decl_pos;
1685 for (named_decl_pos = path->Decls.first;
1686 named_decl_pos != path->Decls.second && parent_record_decl;
1687 ++named_decl_pos)
1688 {
1689 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
1690
1691 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
1692 if (child_idx == UINT32_MAX)
1693 {
1694 child_indexes.clear();
1695 return 0;
1696 }
1697 else
1698 {
1699 child_indexes.push_back (child_idx);
1700 }
1701 }
1702 }
1703 return child_indexes.size();
1704 }
1705 }
1706
1707 }
1708 break;
1709
Greg Clayton1674b122010-07-21 22:12:05 +00001710 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001711 {
1712// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1713// const uint64_t element_count = array->getSize().getLimitedValue();
1714//
1715// if (idx < element_count)
1716// {
1717// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1718//
1719// char element_name[32];
1720// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1721//
1722// child_name.assign(element_name);
1723// assert(field_type_info.first % 8 == 0);
1724// child_byte_size = field_type_info.first / 8;
1725// child_byte_offset = idx * child_byte_size;
1726// return array->getElementType().getAsOpaquePtr();
1727// }
1728 }
1729 break;
1730
Greg Clayton1674b122010-07-21 22:12:05 +00001731// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00001732// {
1733// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
1734// QualType pointee_type = mem_ptr_type->getPointeeType();
1735//
1736// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1737// {
1738// return GetIndexOfChildWithName (ast_context,
1739// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
1740// name);
1741// }
1742// }
1743// break;
1744//
Greg Clayton1674b122010-07-21 22:12:05 +00001745 case clang::Type::LValueReference:
1746 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00001747 {
1748 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1749 QualType pointee_type = reference_type->getPointeeType();
1750
1751 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1752 {
1753 return GetIndexOfChildMemberWithName (ast_context,
1754 reference_type->getPointeeType().getAsOpaquePtr(),
1755 name,
1756 omit_empty_base_classes,
1757 child_indexes);
1758 }
1759 }
1760 break;
1761
Greg Clayton1674b122010-07-21 22:12:05 +00001762 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001763 {
1764 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1765 QualType pointee_type = pointer_type->getPointeeType();
1766
1767 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1768 {
1769 return GetIndexOfChildMemberWithName (ast_context,
1770 pointer_type->getPointeeType().getAsOpaquePtr(),
1771 name,
1772 omit_empty_base_classes,
1773 child_indexes);
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 }
1793 }
1794 break;
1795
Greg Clayton1674b122010-07-21 22:12:05 +00001796 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001797 return GetIndexOfChildMemberWithName (ast_context,
1798 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1799 name,
1800 omit_empty_base_classes,
1801 child_indexes);
1802
1803 default:
1804 break;
1805 }
1806 }
1807 return 0;
1808}
1809
1810
1811// Get the index of the child of "clang_type" whose name matches. This function
1812// doesn't descend into the children, but only looks one level deep and name
1813// matches can include base class names.
1814
1815uint32_t
1816ClangASTContext::GetIndexOfChildWithName
1817(
1818 ASTContext *ast_context,
1819 void *clang_type,
1820 const char *name,
1821 bool omit_empty_base_classes
1822)
1823{
1824 if (clang_type && name && name[0])
1825 {
1826 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1827 switch (qual_type->getTypeClass())
1828 {
Greg Clayton1674b122010-07-21 22:12:05 +00001829 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001830 {
1831 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1832 const RecordDecl *record_decl = record_type->getDecl();
1833
1834 assert(record_decl);
1835 uint32_t child_idx = 0;
1836
1837 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1838
1839 if (cxx_record_decl)
1840 {
1841 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1842 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1843 base_class != base_class_end;
1844 ++base_class)
1845 {
1846 // Skip empty base classes
1847 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1848 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
1849 continue;
1850
1851 if (base_class->getType().getAsString().compare (name) == 0)
1852 return child_idx;
1853 ++child_idx;
1854 }
1855 }
1856
1857 // Try and find a field that matches NAME
1858 RecordDecl::field_iterator field, field_end;
1859 StringRef name_sref(name);
1860 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1861 field != field_end;
1862 ++field, ++child_idx)
1863 {
1864 if (field->getName().equals (name_sref))
1865 return child_idx;
1866 }
1867
1868 }
1869 break;
1870
Greg Clayton1674b122010-07-21 22:12:05 +00001871 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001872 {
1873// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1874// const uint64_t element_count = array->getSize().getLimitedValue();
1875//
1876// if (idx < element_count)
1877// {
1878// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1879//
1880// char element_name[32];
1881// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1882//
1883// child_name.assign(element_name);
1884// assert(field_type_info.first % 8 == 0);
1885// child_byte_size = field_type_info.first / 8;
1886// child_byte_offset = idx * child_byte_size;
1887// return array->getElementType().getAsOpaquePtr();
1888// }
1889 }
1890 break;
1891
Greg Clayton1674b122010-07-21 22:12:05 +00001892// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00001893// {
1894// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
1895// QualType pointee_type = mem_ptr_type->getPointeeType();
1896//
1897// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1898// {
1899// return GetIndexOfChildWithName (ast_context,
1900// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
1901// name);
1902// }
1903// }
1904// break;
1905//
Greg Clayton1674b122010-07-21 22:12:05 +00001906 case clang::Type::LValueReference:
1907 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00001908 {
1909 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1910 QualType pointee_type = reference_type->getPointeeType();
1911
1912 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1913 {
1914 return GetIndexOfChildWithName (ast_context,
1915 reference_type->getPointeeType().getAsOpaquePtr(),
1916 name,
1917 omit_empty_base_classes);
1918 }
1919 }
1920 break;
1921
Greg Clayton1674b122010-07-21 22:12:05 +00001922 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001923 {
1924 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1925 QualType pointee_type = pointer_type->getPointeeType();
1926
1927 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1928 {
1929 return GetIndexOfChildWithName (ast_context,
1930 pointer_type->getPointeeType().getAsOpaquePtr(),
1931 name,
1932 omit_empty_base_classes);
1933 }
1934 else
1935 {
1936// if (parent_name)
1937// {
1938// child_name.assign(1, '*');
1939// child_name += parent_name;
1940// }
1941//
1942// // We have a pointer to an simple type
1943// if (idx == 0)
1944// {
1945// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1946// assert(clang_type_info.first % 8 == 0);
1947// child_byte_size = clang_type_info.first / 8;
1948// child_byte_offset = 0;
1949// return pointee_type.getAsOpaquePtr();
1950// }
1951 }
1952 }
1953 break;
1954
Greg Clayton1674b122010-07-21 22:12:05 +00001955 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001956 return GetIndexOfChildWithName (ast_context,
1957 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1958 name,
1959 omit_empty_base_classes);
1960
1961 default:
1962 break;
1963 }
1964 }
1965 return UINT32_MAX;
1966}
1967
1968#pragma mark TagType
1969
1970bool
1971ClangASTContext::SetTagTypeKind (void *tag_clang_type, int kind)
1972{
1973 if (tag_clang_type)
1974 {
1975 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001976 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001977 if (clang_type)
1978 {
1979 TagType *tag_type = dyn_cast<TagType>(clang_type);
1980 if (tag_type)
1981 {
1982 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
1983 if (tag_decl)
1984 {
1985 tag_decl->setTagKind ((TagDecl::TagKind)kind);
1986 return true;
1987 }
1988 }
1989 }
1990 }
1991 return false;
1992}
1993
1994
1995#pragma mark DeclContext Functions
1996
1997DeclContext *
1998ClangASTContext::GetDeclContextForType (void *clang_type)
1999{
2000 if (clang_type == NULL)
2001 return NULL;
2002
2003 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2004 switch (qual_type->getTypeClass())
2005 {
Greg Clayton1674b122010-07-21 22:12:05 +00002006 case clang::Type::FunctionNoProto: break;
2007 case clang::Type::FunctionProto: break;
2008 case clang::Type::IncompleteArray: break;
2009 case clang::Type::VariableArray: break;
2010 case clang::Type::ConstantArray: break;
2011 case clang::Type::ExtVector: break;
2012 case clang::Type::Vector: break;
2013 case clang::Type::Builtin: break;
2014 case clang::Type::ObjCObjectPointer: break;
2015 case clang::Type::BlockPointer: break;
2016 case clang::Type::Pointer: break;
2017 case clang::Type::LValueReference: break;
2018 case clang::Type::RValueReference: break;
2019 case clang::Type::MemberPointer: break;
2020 case clang::Type::Complex: break;
2021 case clang::Type::ObjCInterface: break;
2022 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002023 return cast<RecordType>(qual_type)->getDecl();
Greg Clayton1674b122010-07-21 22:12:05 +00002024 case clang::Type::Enum:
Chris Lattner24943d22010-06-08 16:52:24 +00002025 return cast<EnumType>(qual_type)->getDecl();
Greg Clayton1674b122010-07-21 22:12:05 +00002026 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002027 return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
2028
Greg Clayton1674b122010-07-21 22:12:05 +00002029 case clang::Type::TypeOfExpr: break;
2030 case clang::Type::TypeOf: break;
2031 case clang::Type::Decltype: break;
2032 //case clang::Type::QualifiedName: break;
2033 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00002034 }
2035 // No DeclContext in this type...
2036 return NULL;
2037}
2038
2039#pragma mark Namespace Declarations
2040
2041NamespaceDecl *
2042ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
2043{
2044 // TODO: Do something intelligent with the Declaration object passed in
2045 // like maybe filling in the SourceLocation with it...
2046 if (name)
2047 {
2048 ASTContext *ast_context = getASTContext();
2049 if (decl_ctx == NULL)
2050 decl_ctx = ast_context->getTranslationUnitDecl();
2051 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
2052 }
2053 return NULL;
2054}
2055
2056
2057#pragma mark Function Types
2058
2059FunctionDecl *
2060ClangASTContext::CreateFunctionDeclaration (const char *name, void *function_clang_type, int storage, bool is_inline)
2061{
2062 if (name)
2063 {
2064 ASTContext *ast_context = getASTContext();
2065 assert (ast_context != NULL);
2066
2067 if (name && name[0])
2068 {
2069 return FunctionDecl::Create(*ast_context,
2070 ast_context->getTranslationUnitDecl(),
2071 SourceLocation(),
2072 DeclarationName (&ast_context->Idents.get(name)),
2073 QualType::getFromOpaquePtr(function_clang_type),
2074 NULL,
2075 (FunctionDecl::StorageClass)storage,
2076 (FunctionDecl::StorageClass)storage,
2077 is_inline);
2078 }
2079 else
2080 {
2081 return FunctionDecl::Create(*ast_context,
2082 ast_context->getTranslationUnitDecl(),
2083 SourceLocation(),
2084 DeclarationName (),
2085 QualType::getFromOpaquePtr(function_clang_type),
2086 NULL,
2087 (FunctionDecl::StorageClass)storage,
2088 (FunctionDecl::StorageClass)storage,
2089 is_inline);
2090 }
2091 }
2092 return NULL;
2093}
2094
2095void *
2096ClangASTContext::CreateFunctionType (void *result_type, void **args, unsigned num_args, bool isVariadic, unsigned TypeQuals)
2097{
2098 ASTContext *ast_context = getASTContext();
2099 assert (ast_context != NULL);
2100 std::vector<QualType> qual_type_args;
2101 for (unsigned i=0; i<num_args; ++i)
2102 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
2103
2104 // TODO: Detect calling convention in DWARF?
2105 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00002106 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00002107 qual_type_args.size(),
2108 isVariadic,
2109 TypeQuals,
2110 false, // hasExceptionSpec
2111 false, // hasAnyExceptionSpec,
2112 0, // NumExs
2113 0, // const QualType *ExArray
2114 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
2115}
2116
2117ParmVarDecl *
Greg Clayton84f80752010-07-22 18:30:50 +00002118ClangASTContext::CreateParmeterDeclaration (const char *name, void *return_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00002119{
2120 ASTContext *ast_context = getASTContext();
2121 assert (ast_context != NULL);
2122 return ParmVarDecl::Create(*ast_context,
2123 ast_context->getTranslationUnitDecl(),
2124 SourceLocation(),
2125 name && name[0] ? &ast_context->Idents.get(name) : NULL,
2126 QualType::getFromOpaquePtr(return_type),
2127 NULL,
2128 (VarDecl::StorageClass)storage,
2129 (VarDecl::StorageClass)storage,
2130 0);
2131}
2132
2133void
2134ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
2135{
2136 if (function_decl)
2137 function_decl->setParams (params, num_params);
2138}
2139
2140
2141#pragma mark Array Types
2142
2143void *
2144ClangASTContext::CreateArrayType (void *element_type, size_t element_count, uint32_t bit_stride)
2145{
2146 if (element_type)
2147 {
2148 ASTContext *ast_context = getASTContext();
2149 assert (ast_context != NULL);
2150 llvm::APInt ap_element_count (64, element_count);
2151 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
2152 ap_element_count,
2153 ArrayType::Normal,
2154 0).getAsOpaquePtr(); // ElemQuals
2155 }
2156 return NULL;
2157}
2158
2159
2160#pragma mark TagDecl
2161
2162bool
2163ClangASTContext::StartTagDeclarationDefinition (void *clang_type)
2164{
2165 if (clang_type)
2166 {
2167 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00002168 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002169 if (t)
2170 {
2171 TagType *tag_type = dyn_cast<TagType>(t);
2172 if (tag_type)
2173 {
2174 TagDecl *tag_decl = tag_type->getDecl();
2175 if (tag_decl)
2176 {
2177 tag_decl->startDefinition();
2178 return true;
2179 }
2180 }
2181 }
2182 }
2183 return false;
2184}
2185
2186bool
2187ClangASTContext::CompleteTagDeclarationDefinition (void *clang_type)
2188{
2189 if (clang_type)
2190 {
2191 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00002192 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002193 if (t)
2194 {
2195 TagType *tag_type = dyn_cast<TagType>(t);
2196 if (tag_type)
2197 {
2198 TagDecl *tag_decl = tag_type->getDecl();
2199 if (tag_decl)
2200 {
2201 tag_decl->completeDefinition();
2202 return true;
2203 }
2204 }
2205 }
2206 }
2207 return false;
2208}
2209
2210
2211#pragma mark Enumeration Types
2212
2213void *
2214ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name)
2215{
2216 // TODO: Do something intelligent with the Declaration object passed in
2217 // like maybe filling in the SourceLocation with it...
2218 ASTContext *ast_context = getASTContext();
2219 assert (ast_context != NULL);
2220 EnumDecl *enum_decl = EnumDecl::Create(*ast_context,
2221 ast_context->getTranslationUnitDecl(),
2222 SourceLocation(),
2223 name && name[0] ? &ast_context->Idents.get(name) : NULL,
2224 SourceLocation(),
2225 NULL);
2226 if (enum_decl)
2227 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
2228 return NULL;
2229}
2230
2231bool
2232ClangASTContext::AddEnumerationValueToEnumerationType
2233(
2234 void *enum_clang_type,
2235 void *enumerator_clang_type,
2236 const Declaration &decl,
2237 const char *name,
2238 int64_t enum_value,
2239 uint32_t enum_value_bit_size
2240)
2241{
2242 if (enum_clang_type && enumerator_clang_type && name)
2243 {
2244 // TODO: Do something intelligent with the Declaration object passed in
2245 // like maybe filling in the SourceLocation with it...
2246 ASTContext *ast_context = getASTContext();
2247 IdentifierTable *identifier_table = getIdentifierTable();
2248
2249 assert (ast_context != NULL);
2250 assert (identifier_table != NULL);
2251 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
2252
Greg Clayton1674b122010-07-21 22:12:05 +00002253 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002254 if (clang_type)
2255 {
2256 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
2257
2258 if (enum_type)
2259 {
2260 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
2261 enum_llvm_apsint = enum_value;
2262 EnumConstantDecl *enumerator_decl =
2263 EnumConstantDecl::Create(*ast_context,
2264 enum_type->getDecl(),
2265 SourceLocation(),
2266 name ? &identifier_table->get(name) : NULL, // Identifier
2267 QualType::getFromOpaquePtr(enumerator_clang_type),
2268 NULL,
2269 enum_llvm_apsint);
2270
2271 if (enumerator_decl)
2272 {
2273 enum_type->getDecl()->addDecl(enumerator_decl);
2274 return true;
2275 }
2276 }
2277 }
2278 }
2279 return false;
2280}
2281
2282#pragma mark Pointers & References
2283
2284void *
2285ClangASTContext::CreatePointerType (void *clang_type)
2286{
2287 if (clang_type)
2288 return getASTContext()->getPointerType(QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2289 return NULL;
2290}
2291
2292void *
2293ClangASTContext::CreateLValueReferenceType (void *clang_type)
2294{
2295 if (clang_type)
2296 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2297 return NULL;
2298}
2299
2300void *
2301ClangASTContext::CreateRValueReferenceType (void *clang_type)
2302{
2303 if (clang_type)
2304 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2305 return NULL;
2306}
2307
Greg Claytonfa970692010-06-12 01:20:30 +00002308void *
Greg Clayton84f80752010-07-22 18:30:50 +00002309ClangASTContext::CreateMemberPointerType (void *clang_pointee_type, void *clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00002310{
2311 if (clang_pointee_type && clang_pointee_type)
2312 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
2313 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
2314 return NULL;
2315}
2316
Chris Lattner24943d22010-06-08 16:52:24 +00002317size_t
2318ClangASTContext::GetPointerBitSize ()
2319{
2320 ASTContext *ast_context = getASTContext();
2321 return ast_context->getTypeSize(ast_context->VoidPtrTy);
2322}
2323
2324bool
2325ClangASTContext::IsPointerOrReferenceType (void *clang_type, void **target_type)
2326{
2327 if (clang_type == NULL)
2328 return false;
2329
2330 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2331 switch (qual_type->getTypeClass())
2332 {
Greg Clayton1674b122010-07-21 22:12:05 +00002333 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002334 if (target_type)
2335 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2336 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002337 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002338 if (target_type)
2339 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2340 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002341 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002342 if (target_type)
2343 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2344 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002345 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002346 if (target_type)
2347 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2348 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002349 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002350 if (target_type)
2351 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2352 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002353 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002354 if (target_type)
2355 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2356 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002357 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002358 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
2359 default:
2360 break;
2361 }
2362 return false;
2363}
2364
2365size_t
2366ClangASTContext::GetTypeBitSize (clang::ASTContext *ast_context, void *clang_type)
2367{
2368 if (clang_type)
2369 return ast_context->getTypeSize(QualType::getFromOpaquePtr(clang_type));
2370 return 0;
2371}
2372
2373size_t
2374ClangASTContext::GetTypeBitAlign (clang::ASTContext *ast_context, void *clang_type)
2375{
2376 if (clang_type)
2377 return ast_context->getTypeAlign(QualType::getFromOpaquePtr(clang_type));
2378 return 0;
2379}
2380
2381bool
Greg Clayton84f80752010-07-22 18:30:50 +00002382ClangASTContext::IsIntegerType (void *clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00002383{
2384 if (!clang_type)
2385 return false;
2386
2387 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2388 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
2389
2390 if (builtin_type)
2391 {
2392 if (builtin_type->isInteger())
2393 is_signed = builtin_type->isSignedInteger();
2394
2395 return true;
2396 }
2397
2398 return false;
2399}
2400
2401bool
2402ClangASTContext::IsPointerType (void *clang_type, void **target_type)
2403{
2404 if (clang_type)
2405 {
2406 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2407 switch (qual_type->getTypeClass())
2408 {
Greg Clayton1674b122010-07-21 22:12:05 +00002409 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002410 if (target_type)
2411 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2412 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002413 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002414 if (target_type)
2415 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2416 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002417 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002418 if (target_type)
2419 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2420 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002421 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002422 if (target_type)
2423 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2424 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002425 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002426 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
2427 default:
2428 break;
2429 }
2430 }
2431 return false;
2432}
2433
2434bool
2435ClangASTContext::IsFloatingPointType (void *clang_type, uint32_t &count, bool &is_complex)
2436{
2437 if (clang_type)
2438 {
2439 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2440
2441 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
2442 {
2443 clang::BuiltinType::Kind kind = BT->getKind();
2444 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
2445 {
2446 count = 1;
2447 is_complex = false;
2448 return true;
2449 }
2450 }
2451 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
2452 {
2453 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
2454 {
2455 count = 2;
2456 is_complex = true;
2457 return true;
2458 }
2459 }
2460 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
2461 {
2462 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
2463 {
2464 count = VT->getNumElements();
2465 is_complex = false;
2466 return true;
2467 }
2468 }
2469 }
2470 return false;
2471}
2472
2473
2474bool
2475ClangASTContext::IsCStringType (void *clang_type, uint32_t &length)
2476{
2477 if (clang_type)
2478 {
2479 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2480 switch (qual_type->getTypeClass())
2481 {
Greg Clayton1674b122010-07-21 22:12:05 +00002482 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002483 {
2484 ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr());
2485 QualType element_qual_type = array->getElementType();
Greg Clayton1674b122010-07-21 22:12:05 +00002486 clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002487 if (canonical_type && canonical_type->isCharType())
2488 {
2489 // We know the size of the array and it could be a C string
2490 // since it is an array of characters
2491 length = array->getSize().getLimitedValue();
2492 return true;
2493 }
2494 }
2495 break;
2496
Greg Clayton1674b122010-07-21 22:12:05 +00002497 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002498 {
2499 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton1674b122010-07-21 22:12:05 +00002500 clang::Type *pointee_type_ptr = pointer_type->getPointeeType().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002501 if (pointee_type_ptr)
2502 {
Greg Clayton1674b122010-07-21 22:12:05 +00002503 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002504 length = 0; // No length info, read until a NULL terminator is received
2505 if (canonical_type_ptr)
2506 return canonical_type_ptr->isCharType();
2507 else
2508 return pointee_type_ptr->isCharType();
2509 }
2510 }
2511 break;
2512
Greg Clayton1674b122010-07-21 22:12:05 +00002513 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002514 return ClangASTContext::IsCStringType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), length);
2515
Greg Clayton1674b122010-07-21 22:12:05 +00002516 case clang::Type::LValueReference:
2517 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002518 {
2519 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton1674b122010-07-21 22:12:05 +00002520 clang::Type *pointee_type_ptr = reference_type->getPointeeType().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002521 if (pointee_type_ptr)
2522 {
Greg Clayton1674b122010-07-21 22:12:05 +00002523 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002524 length = 0; // No length info, read until a NULL terminator is received
2525 if (canonical_type_ptr)
2526 return canonical_type_ptr->isCharType();
2527 else
2528 return pointee_type_ptr->isCharType();
2529 }
2530 }
2531 break;
2532 }
2533 }
2534 return false;
2535}
2536
2537bool
Greg Clayton84f80752010-07-22 18:30:50 +00002538ClangASTContext::IsArrayType (void *clang_type, void **member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00002539{
2540 if (!clang_type)
2541 return false;
2542
2543 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2544
2545 switch (qual_type->getTypeClass())
2546 {
Greg Clayton1674b122010-07-21 22:12:05 +00002547 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002548 if (member_type)
2549 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2550 if (size)
2551 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
2552 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002553 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002554 if (member_type)
2555 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2556 if (size)
2557 *size = 0;
2558 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002559 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002560 if (member_type)
2561 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2562 if (size)
2563 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00002564 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002565 if (member_type)
2566 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2567 if (size)
2568 *size = 0;
2569 return true;
2570 }
2571 return false;
2572}
2573
2574
2575#pragma mark Typedefs
2576
2577void *
2578ClangASTContext::CreateTypedefType (const char *name, void *clang_type, DeclContext *decl_ctx)
2579{
2580 if (clang_type)
2581 {
2582 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2583 ASTContext *ast_context = getASTContext();
2584 IdentifierTable *identifier_table = getIdentifierTable();
2585 assert (ast_context != NULL);
2586 assert (identifier_table != NULL);
2587 if (decl_ctx == NULL)
2588 decl_ctx = ast_context->getTranslationUnitDecl();
2589 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
2590 decl_ctx,
2591 SourceLocation(),
2592 name ? &identifier_table->get(name) : NULL, // Identifier
2593 ast_context->CreateTypeSourceInfo(qual_type));
2594
2595 // Get a uniqued QualType for the typedef decl type
2596 return ast_context->getTypedefType (decl).getAsOpaquePtr();
2597 }
2598 return NULL;
2599}
2600
2601
2602std::string
2603ClangASTContext::GetTypeName (void *opaque_qual_type)
2604{
2605 std::string return_name;
2606
2607 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_qual_type));
2608
2609 const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
2610 if (typedef_type)
2611 {
2612 const clang::TypedefDecl *typedef_decl = typedef_type->getDecl();
2613 return_name = typedef_decl->getQualifiedNameAsString();
2614 }
2615 else
2616 {
2617 return_name = qual_type.getAsString();
2618 }
2619
2620 return return_name;
2621}
2622
2623// Disable this for now since I can't seem to get a nicely formatted float
2624// out of the APFloat class without just getting the float, double or quad
2625// and then using a formatted print on it which defeats the purpose. We ideally
2626// would like to get perfect string values for any kind of float semantics
2627// so we can support remote targets. The code below also requires a patch to
2628// llvm::APInt.
2629//bool
2630//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, void *clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
2631//{
2632// uint32_t count = 0;
2633// bool is_complex = false;
2634// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
2635// {
2636// unsigned num_bytes_per_float = byte_size / count;
2637// unsigned num_bits_per_float = num_bytes_per_float * 8;
2638//
2639// float_str.clear();
2640// uint32_t i;
2641// for (i=0; i<count; i++)
2642// {
2643// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
2644// bool is_ieee = false;
2645// APFloat ap_float(ap_int, is_ieee);
2646// char s[1024];
2647// unsigned int hex_digits = 0;
2648// bool upper_case = false;
2649//
2650// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
2651// {
2652// if (i > 0)
2653// float_str.append(", ");
2654// float_str.append(s);
2655// if (i == 1 && is_complex)
2656// float_str.append(1, 'i');
2657// }
2658// }
2659// return !float_str.empty();
2660// }
2661// return false;
2662//}
2663
2664size_t
2665ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, void *clang_type, const char *s, uint8_t *dst, size_t dst_size)
2666{
2667 if (clang_type)
2668 {
2669 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2670 uint32_t count = 0;
2671 bool is_complex = false;
2672 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
2673 {
2674 // TODO: handle complex and vector types
2675 if (count != 1)
2676 return false;
2677
2678 StringRef s_sref(s);
2679 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
2680
2681 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
2682 const uint64_t byte_size = bit_size / 8;
2683 if (dst_size >= byte_size)
2684 {
2685 if (bit_size == sizeof(float)*8)
2686 {
2687 float float32 = ap_float.convertToFloat();
2688 ::memcpy (dst, &float32, byte_size);
2689 return byte_size;
2690 }
2691 else if (bit_size >= 64)
2692 {
2693 llvm::APInt ap_int(ap_float.bitcastToAPInt());
2694 ::memcpy (dst, ap_int.getRawData(), byte_size);
2695 return byte_size;
2696 }
2697 }
2698 }
2699 }
2700 return 0;
2701}