blob: 52235dab2409770db748c0b22f3343cb4e40ec13 [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 *
Greg Clayton9488b742010-07-28 02:04:09 +0000756ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, lldb::LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000757{
758 ASTContext *ast_context = getASTContext();
759 assert (ast_context != NULL);
760
761 if (decl_ctx == NULL)
762 decl_ctx = ast_context->getTranslationUnitDecl();
763
Greg Clayton9488b742010-07-28 02:04:09 +0000764
765 if (language == lldb::eLanguageTypeObjC)
766 {
767 bool isForwardDecl = false;
768 bool isInternal = false;
769 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
770 }
771
Chris Lattner24943d22010-06-08 16:52:24 +0000772 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
773 // we will need to update this code. I was told to currently always use
774 // the CXXRecordDecl class since we often don't know from debug information
775 // if something is struct or a class, so we default to always use the more
776 // complete definition just in case.
777 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
778 (TagDecl::TagKind)kind,
779 decl_ctx,
780 SourceLocation(),
781 name && name[0] ? &ast_context->Idents.get(name) : NULL);
782
783 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
784}
785
786bool
Greg Clayton84f80752010-07-22 18:30:50 +0000787ClangASTContext::AddFieldToRecordType
788(
789 void *record_clang_type,
790 const char *name,
791 void *field_type,
792 AccessType access,
793 uint32_t bitfield_bit_size
794)
Chris Lattner24943d22010-06-08 16:52:24 +0000795{
796 if (record_clang_type == NULL || field_type == NULL)
797 return false;
798
799 ASTContext *ast_context = getASTContext();
800 IdentifierTable *identifier_table = getIdentifierTable();
801
802 assert (ast_context != NULL);
803 assert (identifier_table != NULL);
804
805 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
806
Greg Clayton1674b122010-07-21 22:12:05 +0000807 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000808 if (clang_type)
809 {
810 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
811
812 if (record_type)
813 {
814 RecordDecl *record_decl = record_type->getDecl();
815
816 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
817 if (cxx_record_decl)
818 cxx_record_decl->setEmpty (false);
819
820 clang::Expr *bit_width = NULL;
821 if (bitfield_bit_size != 0)
822 {
823 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
824 bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
825 }
Greg Clayton84f80752010-07-22 18:30:50 +0000826 FieldDecl *field = FieldDecl::Create (*ast_context,
827 record_decl,
828 SourceLocation(),
829 name ? &identifier_table->get(name) : NULL, // Identifier
830 QualType::getFromOpaquePtr(field_type), // Field type
831 NULL, // DeclaratorInfo *
832 bit_width, // BitWidth
833 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +0000834
Greg Clayton84f80752010-07-22 18:30:50 +0000835 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +0000836
837 if (field)
838 {
839 record_decl->addDecl(field);
840 return true;
841 }
842 }
Greg Clayton9488b742010-07-28 02:04:09 +0000843 else
844 {
845 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
846 if (objc_class_type)
847 {
848 bool isSynthesized = false;
849 ClangASTContext::AddObjCClassIVar (record_clang_type,
850 name,
851 field_type,
852 access,
853 bitfield_bit_size,
854 isSynthesized);
855 }
856 }
Chris Lattner24943d22010-06-08 16:52:24 +0000857 }
858 return false;
859}
860
861bool
862ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
863{
864 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
865}
866
867bool
868ClangASTContext::FieldIsBitfield
869(
870 ASTContext *ast_context,
871 FieldDecl* field,
872 uint32_t& bitfield_bit_size
873)
874{
875 if (ast_context == NULL || field == NULL)
876 return false;
877
878 if (field->isBitField())
879 {
880 Expr* bit_width_expr = field->getBitWidth();
881 if (bit_width_expr)
882 {
883 llvm::APSInt bit_width_apsint;
884 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
885 {
886 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
887 return true;
888 }
889 }
890 }
891 return false;
892}
893
894bool
895ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
896{
897 if (record_decl == NULL)
898 return false;
899
900 if (!record_decl->field_empty())
901 return true;
902
903 // No fields, lets check this is a CXX record and check the base classes
904 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
905 if (cxx_record_decl)
906 {
907 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
908 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
909 base_class != base_class_end;
910 ++base_class)
911 {
912 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
913 if (RecordHasFields(base_class_decl))
914 return true;
915 }
916 }
917 return false;
918}
919
920void
921ClangASTContext::SetDefaultAccessForRecordFields (void *clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
922{
923 if (clang_qual_type)
924 {
925 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +0000926 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000927 if (clang_type)
928 {
929 RecordType *record_type = dyn_cast<RecordType>(clang_type);
930 if (record_type)
931 {
932 RecordDecl *record_decl = record_type->getDecl();
933 if (record_decl)
934 {
935 uint32_t field_idx;
936 RecordDecl::field_iterator field, field_end;
937 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
938 field != field_end;
939 ++field, ++field_idx)
940 {
941 // If no accessibility was assigned, assign the correct one
942 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
943 field->setAccess ((AccessSpecifier)default_accessibility);
944 }
945 }
946 }
947 }
948 }
949}
950
951#pragma mark C++ Base Classes
952
953CXXBaseSpecifier *
Greg Clayton84f80752010-07-22 18:30:50 +0000954ClangASTContext::CreateBaseClassSpecifier (void *base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +0000955{
956 if (base_class_type)
957 return new CXXBaseSpecifier(SourceRange(), is_virtual, base_of_class, (AccessSpecifier)access, QualType::getFromOpaquePtr(base_class_type));
958 return NULL;
959}
960
Greg Claytone9d0df42010-07-02 01:29:13 +0000961void
962ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
963{
964 for (unsigned i=0; i<num_base_classes; ++i)
965 {
966 delete base_classes[i];
967 base_classes[i] = NULL;
968 }
969}
970
Chris Lattner24943d22010-06-08 16:52:24 +0000971bool
972ClangASTContext::SetBaseClassesForClassType (void *class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
973{
974 if (class_clang_type)
975 {
Greg Clayton1674b122010-07-21 22:12:05 +0000976 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000977 if (clang_type)
978 {
979 RecordType *record_type = dyn_cast<RecordType>(clang_type);
980 if (record_type)
981 {
982 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
983 if (cxx_record_decl)
984 {
985 //cxx_record_decl->setEmpty (false);
986 cxx_record_decl->setBases(base_classes, num_base_classes);
987 return true;
988 }
989 }
990 }
991 }
992 return false;
993}
Greg Clayton84f80752010-07-22 18:30:50 +0000994#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +0000995
Greg Clayton84f80752010-07-22 18:30:50 +0000996void *
997ClangASTContext::CreateObjCClass
998(
999 const char *name,
1000 DeclContext *decl_ctx,
1001 bool isForwardDecl,
1002 bool isInternal
1003)
1004{
1005 ASTContext *ast_context = getASTContext();
1006 assert (ast_context != NULL);
1007 assert (name && name[0]);
1008 if (decl_ctx == NULL)
1009 decl_ctx = ast_context->getTranslationUnitDecl();
1010
1011 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1012 // we will need to update this code. I was told to currently always use
1013 // the CXXRecordDecl class since we often don't know from debug information
1014 // if something is struct or a class, so we default to always use the more
1015 // complete definition just in case.
1016 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1017 decl_ctx,
1018 SourceLocation(),
1019 &ast_context->Idents.get(name),
1020 SourceLocation(),
1021 isForwardDecl,
1022 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001023
1024 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001025}
1026
1027bool
1028ClangASTContext::SetObjCSuperClass (void *class_opaque_type, void *super_opaque_type)
1029{
1030 if (class_opaque_type && super_opaque_type)
1031 {
1032 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1033 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1034 clang::Type *class_type = class_qual_type.getTypePtr();
1035 clang::Type *super_type = super_qual_type.getTypePtr();
1036 if (class_type && super_type)
1037 {
1038 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1039 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1040 if (objc_class_type && objc_super_type)
1041 {
1042 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1043 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1044 if (class_interface_decl && super_interface_decl)
1045 {
1046 class_interface_decl->setSuperClass(super_interface_decl);
1047 return true;
1048 }
1049 }
1050 }
1051 }
1052 return false;
1053}
1054
1055
1056bool
1057ClangASTContext::AddObjCClassIVar
1058(
1059 void *class_opaque_type,
1060 const char *name,
1061 void *ivar_opaque_type,
1062 AccessType access,
1063 uint32_t bitfield_bit_size,
1064 bool isSynthesized
1065)
1066{
1067 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1068 return false;
1069
1070 ASTContext *ast_context = getASTContext();
1071 IdentifierTable *identifier_table = getIdentifierTable();
1072
1073 assert (ast_context != NULL);
1074 assert (identifier_table != NULL);
1075
1076 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1077
1078 clang::Type *class_type = class_qual_type.getTypePtr();
1079 if (class_type)
1080 {
1081 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1082
1083 if (objc_class_type)
1084 {
1085 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1086
1087 if (class_interface_decl)
1088 {
1089 clang::Expr *bit_width = NULL;
1090 if (bitfield_bit_size != 0)
1091 {
1092 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
1093 bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
1094 }
1095
Greg Clayton9488b742010-07-28 02:04:09 +00001096 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1097 class_interface_decl,
1098 SourceLocation(),
1099 &identifier_table->get(name), // Identifier
1100 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1101 NULL, // TypeSourceInfo *
1102 ConvertAccessTypeToObjCIvarAccessControl (access),
1103 bit_width,
1104 isSynthesized);
1105
1106 if (field)
1107 {
1108 class_interface_decl->addDecl(field);
1109 return true;
1110 }
Greg Clayton84f80752010-07-22 18:30:50 +00001111 }
1112 }
1113 }
1114 return false;
1115}
Chris Lattner24943d22010-06-08 16:52:24 +00001116
Greg Clayton9488b742010-07-28 02:04:09 +00001117
1118bool
1119ClangASTContext::ObjCTypeHasIVars (void *class_opaque_type, bool check_superclass)
1120{
1121 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1122
1123 clang::Type *class_type = class_qual_type.getTypePtr();
1124 if (class_type)
1125 {
1126 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1127
1128 if (objc_class_type)
1129 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1130 }
1131 return false;
1132}
1133
1134bool
1135ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1136{
1137 while (class_interface_decl)
1138 {
1139 if (class_interface_decl->ivar_size() > 0)
1140 return true;
1141
1142 if (check_superclass)
1143 class_interface_decl = class_interface_decl->getSuperClass();
1144 else
1145 break;
1146 }
1147 return false;
1148}
1149
1150
Chris Lattner24943d22010-06-08 16:52:24 +00001151#pragma mark Aggregate Types
1152
1153bool
1154ClangASTContext::IsAggregateType (void *clang_type)
1155{
1156 if (clang_type == NULL)
1157 return false;
1158
1159 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1160
1161 if (qual_type->isAggregateType ())
1162 return true;
1163
1164 switch (qual_type->getTypeClass())
1165 {
Greg Clayton1674b122010-07-21 22:12:05 +00001166 case clang::Type::IncompleteArray:
1167 case clang::Type::VariableArray:
1168 case clang::Type::ConstantArray:
1169 case clang::Type::ExtVector:
1170 case clang::Type::Vector:
1171 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001172 case clang::Type::ObjCObject:
1173 case clang::Type::ObjCInterface:
1174 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001175 return true;
1176
Greg Clayton1674b122010-07-21 22:12:05 +00001177 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001178 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1179
1180 default:
1181 break;
1182 }
1183 // The clang type does have a value
1184 return false;
1185}
1186
1187uint32_t
1188ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_classes)
1189{
1190 if (clang_qual_type == NULL)
1191 return 0;
1192
1193 uint32_t num_children = 0;
1194 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001195 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1196 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001197 {
Greg Clayton1674b122010-07-21 22:12:05 +00001198 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001199 {
1200 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1201 const RecordDecl *record_decl = record_type->getDecl();
1202 assert(record_decl);
1203 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1204 if (cxx_record_decl)
1205 {
1206 if (omit_empty_base_classes)
1207 {
1208 // Check each base classes to see if it or any of its
1209 // base classes contain any fields. This can help
1210 // limit the noise in variable views by not having to
1211 // show base classes that contain no members.
1212 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1213 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1214 base_class != base_class_end;
1215 ++base_class)
1216 {
1217 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1218
1219 // Skip empty base classes
1220 if (RecordHasFields(base_class_decl) == false)
1221 continue;
1222
1223 num_children++;
1224 }
1225 }
1226 else
1227 {
1228 // Include all base classes
1229 num_children += cxx_record_decl->getNumBases();
1230 }
1231
1232 }
1233 RecordDecl::field_iterator field, field_end;
1234 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1235 ++num_children;
1236 }
1237 break;
1238
Greg Clayton9488b742010-07-28 02:04:09 +00001239 case clang::Type::ObjCObject:
1240 case clang::Type::ObjCInterface:
1241 {
1242 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1243 assert (objc_class_type);
1244 if (objc_class_type)
1245 {
1246 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1247
1248 if (class_interface_decl)
1249 {
1250
1251 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1252 if (superclass_interface_decl)
1253 {
1254 if (omit_empty_base_classes)
1255 {
1256 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1257 ++num_children;
1258 }
1259 else
1260 ++num_children;
1261 }
1262
1263 num_children += class_interface_decl->ivar_size();
1264 }
1265 }
1266 }
1267 break;
1268
1269 case clang::Type::ObjCObjectPointer:
1270 return ClangASTContext::GetNumChildren (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
1271 omit_empty_base_classes);
1272
Greg Clayton1674b122010-07-21 22:12:05 +00001273 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001274 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1275 break;
1276
Greg Clayton1674b122010-07-21 22:12:05 +00001277 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001278 {
1279 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1280 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001281 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1282 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001283 // If this type points to a simple type, then it has 1 child
1284 if (num_pointee_children == 0)
1285 num_children = 1;
1286 else
1287 num_children = num_pointee_children;
1288 }
1289 break;
1290
Greg Clayton1674b122010-07-21 22:12:05 +00001291 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001292 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1293 break;
1294
1295 default:
1296 break;
1297 }
1298 return num_children;
1299}
1300
1301
1302void *
1303ClangASTContext::GetChildClangTypeAtIndex
1304(
1305 const char *parent_name,
1306 void *parent_clang_type,
1307 uint32_t idx,
1308 bool transparent_pointers,
1309 bool omit_empty_base_classes,
1310 std::string& child_name,
1311 uint32_t &child_byte_size,
1312 int32_t &child_byte_offset,
1313 uint32_t &child_bitfield_bit_size,
1314 uint32_t &child_bitfield_bit_offset
1315)
1316{
1317 if (parent_clang_type)
1318
1319 return GetChildClangTypeAtIndex (getASTContext(),
1320 parent_name,
1321 parent_clang_type,
1322 idx,
1323 transparent_pointers,
1324 omit_empty_base_classes,
1325 child_name,
1326 child_byte_size,
1327 child_byte_offset,
1328 child_bitfield_bit_size,
1329 child_bitfield_bit_offset);
1330 return NULL;
1331}
1332
1333void *
1334ClangASTContext::GetChildClangTypeAtIndex
1335(
1336 ASTContext *ast_context,
1337 const char *parent_name,
1338 void *parent_clang_type,
1339 uint32_t idx,
1340 bool transparent_pointers,
1341 bool omit_empty_base_classes,
1342 std::string& child_name,
1343 uint32_t &child_byte_size,
1344 int32_t &child_byte_offset,
1345 uint32_t &child_bitfield_bit_size,
1346 uint32_t &child_bitfield_bit_offset
1347)
1348{
1349 if (parent_clang_type == NULL)
1350 return NULL;
1351
1352 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
1353 {
1354 uint32_t bit_offset;
1355 child_bitfield_bit_size = 0;
1356 child_bitfield_bit_offset = 0;
1357 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
1358 switch (parent_qual_type->getTypeClass())
1359 {
Greg Clayton1674b122010-07-21 22:12:05 +00001360 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001361 {
1362 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
1363 const RecordDecl *record_decl = record_type->getDecl();
1364 assert(record_decl);
1365 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
1366 uint32_t child_idx = 0;
1367
1368 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1369 if (cxx_record_decl)
1370 {
1371 // We might have base classes to print out first
1372 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1373 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1374 base_class != base_class_end;
1375 ++base_class)
1376 {
1377 const CXXRecordDecl *base_class_decl = NULL;
1378
1379 // Skip empty base classes
1380 if (omit_empty_base_classes)
1381 {
1382 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1383 if (RecordHasFields(base_class_decl) == false)
1384 continue;
1385 }
1386
1387 if (idx == child_idx)
1388 {
1389 if (base_class_decl == NULL)
1390 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1391
1392
1393 if (base_class->isVirtual())
1394 bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
1395 else
1396 bit_offset = record_layout.getBaseClassOffset(base_class_decl);
1397
1398 // Base classes should be a multiple of 8 bits in size
1399 assert (bit_offset % 8 == 0);
1400 child_byte_offset = bit_offset/8;
1401 std::string base_class_type_name(base_class->getType().getAsString());
1402
1403 child_name.assign(base_class_type_name.c_str());
1404
1405 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
1406
1407 // Base classes biut sizes should be a multiple of 8 bits in size
1408 assert (clang_type_info_bit_size % 8 == 0);
1409 child_byte_size = clang_type_info_bit_size / 8;
1410 return base_class->getType().getAsOpaquePtr();
1411 }
1412 // We don't increment the child index in the for loop since we might
1413 // be skipping empty base classes
1414 ++child_idx;
1415 }
1416 }
Chris Lattner24943d22010-06-08 16:52:24 +00001417 // Make sure index is in range...
1418 uint32_t field_idx = 0;
1419 RecordDecl::field_iterator field, field_end;
1420 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
1421 {
1422 if (idx == child_idx)
1423 {
1424 // Print the member type if requested
1425 // Print the member name and equal sign
1426 child_name.assign(field->getNameAsString().c_str());
1427
1428 // Figure out the type byte size (field_type_info.first) and
1429 // alignment (field_type_info.second) from the AST context.
1430 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00001431 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00001432
1433 child_byte_size = field_type_info.first / 8;
1434
1435 // Figure out the field offset within the current struct/union/class type
1436 bit_offset = record_layout.getFieldOffset (field_idx);
1437 child_byte_offset = bit_offset / 8;
1438 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
1439 child_bitfield_bit_offset = bit_offset % 8;
1440
1441 return field->getType().getAsOpaquePtr();
1442 }
1443 }
1444 }
1445 break;
1446
Greg Clayton9488b742010-07-28 02:04:09 +00001447 case clang::Type::ObjCObject:
1448 case clang::Type::ObjCInterface:
1449 {
1450 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
1451 assert (objc_class_type);
1452 if (objc_class_type)
1453 {
1454 uint32_t child_idx = 0;
1455 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1456
1457 if (class_interface_decl)
1458 {
1459
1460 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
1461 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1462 if (superclass_interface_decl)
1463 {
1464 if (omit_empty_base_classes)
1465 {
1466 if (ClangASTContext::GetNumChildren(superclass_interface_decl, omit_empty_base_classes) > 0)
1467 {
1468 if (idx == 0)
1469 {
1470 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
1471
1472
1473 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
1474
1475 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
1476
1477 child_byte_size = ivar_type_info.first / 8;
1478
1479 // Figure out the field offset within the current struct/union/class type
1480 bit_offset = interface_layout.getFieldOffset (child_idx);
1481 child_byte_offset = bit_offset / 8;
1482
1483 return ivar_qual_type.getAsOpaquePtr();
1484 }
1485
1486 ++child_idx;
1487 }
1488 }
1489 else
1490 ++child_idx;
1491 }
1492
1493 if (idx < (child_idx + class_interface_decl->ivar_size()))
1494 {
1495 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
1496
1497 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
1498 {
1499 if (child_idx == idx)
1500 {
1501 const ObjCIvarDecl* ivar_decl = *ivar_pos;
1502
1503 QualType ivar_qual_type(ivar_decl->getType());
1504
1505 child_name.assign(ivar_decl->getNameAsString().c_str());
1506
1507 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
1508
1509 child_byte_size = ivar_type_info.first / 8;
1510
1511 // Figure out the field offset within the current struct/union/class type
1512 bit_offset = interface_layout.getFieldOffset (child_idx);
1513 child_byte_offset = bit_offset / 8;
1514
1515 return ivar_qual_type.getAsOpaquePtr();
1516 }
1517 ++child_idx;
1518 }
1519 }
1520 }
1521 }
1522 }
1523 break;
1524
1525 case clang::Type::ObjCObjectPointer:
1526 {
1527 return GetChildClangTypeAtIndex (ast_context,
1528 parent_name,
1529 cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
1530 idx,
1531 transparent_pointers,
1532 omit_empty_base_classes,
1533 child_name,
1534 child_byte_size,
1535 child_byte_offset,
1536 child_bitfield_bit_size,
1537 child_bitfield_bit_offset);
1538 }
1539 break;
1540
Greg Clayton1674b122010-07-21 22:12:05 +00001541 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001542 {
1543 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1544 const uint64_t element_count = array->getSize().getLimitedValue();
1545
1546 if (idx < element_count)
1547 {
1548 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1549
1550 char element_name[32];
1551 ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1552
1553 child_name.assign(element_name);
1554 assert(field_type_info.first % 8 == 0);
1555 child_byte_size = field_type_info.first / 8;
1556 child_byte_offset = idx * child_byte_size;
1557 return array->getElementType().getAsOpaquePtr();
1558 }
1559 }
1560 break;
1561
Greg Clayton1674b122010-07-21 22:12:05 +00001562 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001563 {
1564 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
1565 QualType pointee_type = pointer_type->getPointeeType();
1566
1567 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1568 {
1569 return GetChildClangTypeAtIndex (ast_context,
1570 parent_name,
1571 pointer_type->getPointeeType().getAsOpaquePtr(),
1572 idx,
1573 transparent_pointers,
1574 omit_empty_base_classes,
1575 child_name,
1576 child_byte_size,
1577 child_byte_offset,
1578 child_bitfield_bit_size,
1579 child_bitfield_bit_offset);
1580 }
1581 else
1582 {
1583 if (parent_name)
1584 {
1585 child_name.assign(1, '*');
1586 child_name += parent_name;
1587 }
1588
1589 // We have a pointer to an simple type
1590 if (idx == 0)
1591 {
1592 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1593 assert(clang_type_info.first % 8 == 0);
1594 child_byte_size = clang_type_info.first / 8;
1595 child_byte_offset = 0;
1596 return pointee_type.getAsOpaquePtr();
1597 }
1598 }
1599 }
1600 break;
1601
Greg Clayton1674b122010-07-21 22:12:05 +00001602 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001603 return GetChildClangTypeAtIndex (ast_context,
1604 parent_name,
1605 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1606 idx,
1607 transparent_pointers,
1608 omit_empty_base_classes,
1609 child_name,
1610 child_byte_size,
1611 child_byte_offset,
1612 child_bitfield_bit_size,
1613 child_bitfield_bit_offset);
1614 break;
1615
1616 default:
1617 break;
1618 }
1619 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00001620 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001621}
1622
1623static inline bool
1624BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
1625{
1626 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
1627}
1628
1629static uint32_t
1630GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
1631{
1632 uint32_t num_bases = 0;
1633 if (cxx_record_decl)
1634 {
1635 if (omit_empty_base_classes)
1636 {
1637 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1638 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1639 base_class != base_class_end;
1640 ++base_class)
1641 {
1642 // Skip empty base classes
1643 if (omit_empty_base_classes)
1644 {
1645 if (BaseSpecifierIsEmpty (base_class))
1646 continue;
1647 }
1648 ++num_bases;
1649 }
1650 }
1651 else
1652 num_bases = cxx_record_decl->getNumBases();
1653 }
1654 return num_bases;
1655}
1656
1657
1658static uint32_t
1659GetIndexForRecordBase
1660(
1661 const RecordDecl *record_decl,
1662 const CXXBaseSpecifier *base_spec,
1663 bool omit_empty_base_classes
1664)
1665{
1666 uint32_t child_idx = 0;
1667
1668 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1669
1670// const char *super_name = record_decl->getNameAsCString();
1671// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
1672// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
1673//
1674 if (cxx_record_decl)
1675 {
1676 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1677 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1678 base_class != base_class_end;
1679 ++base_class)
1680 {
1681 if (omit_empty_base_classes)
1682 {
1683 if (BaseSpecifierIsEmpty (base_class))
1684 continue;
1685 }
1686
1687// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
1688// child_idx,
1689// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1690//
1691//
1692 if (base_class == base_spec)
1693 return child_idx;
1694 ++child_idx;
1695 }
1696 }
1697
1698 return UINT32_MAX;
1699}
1700
1701
1702static uint32_t
1703GetIndexForRecordChild
1704(
1705 const RecordDecl *record_decl,
1706 NamedDecl *canonical_decl,
1707 bool omit_empty_base_classes
1708)
1709{
1710 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
1711
1712// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1713//
1714//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
1715// if (cxx_record_decl)
1716// {
1717// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1718// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1719// base_class != base_class_end;
1720// ++base_class)
1721// {
1722// if (omit_empty_base_classes)
1723// {
1724// if (BaseSpecifierIsEmpty (base_class))
1725// continue;
1726// }
1727//
1728//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
1729//// record_decl->getNameAsCString(),
1730//// canonical_decl->getNameAsCString(),
1731//// child_idx,
1732//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1733//
1734//
1735// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1736// if (curr_base_class_decl == canonical_decl)
1737// {
1738// return child_idx;
1739// }
1740// ++child_idx;
1741// }
1742// }
1743//
1744// const uint32_t num_bases = child_idx;
1745 RecordDecl::field_iterator field, field_end;
1746 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1747 field != field_end;
1748 ++field, ++child_idx)
1749 {
1750// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
1751// record_decl->getNameAsCString(),
1752// canonical_decl->getNameAsCString(),
1753// child_idx - num_bases,
1754// field->getNameAsCString());
1755
1756 if (field->getCanonicalDecl() == canonical_decl)
1757 return child_idx;
1758 }
1759
1760 return UINT32_MAX;
1761}
1762
1763// Look for a child member (doesn't include base classes, but it does include
1764// their members) in the type hierarchy. Returns an index path into "clang_type"
1765// on how to reach the appropriate member.
1766//
1767// class A
1768// {
1769// public:
1770// int m_a;
1771// int m_b;
1772// };
1773//
1774// class B
1775// {
1776// };
1777//
1778// class C :
1779// public B,
1780// public A
1781// {
1782// };
1783//
1784// If we have a clang type that describes "class C", and we wanted to looked
1785// "m_b" in it:
1786//
1787// With omit_empty_base_classes == false we would get an integer array back with:
1788// { 1, 1 }
1789// The first index 1 is the child index for "class A" within class C
1790// The second index 1 is the child index for "m_b" within class A
1791//
1792// With omit_empty_base_classes == true we would get an integer array back with:
1793// { 0, 1 }
1794// 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)
1795// The second index 1 is the child index for "m_b" within class A
1796
1797size_t
1798ClangASTContext::GetIndexOfChildMemberWithName
1799(
1800 ASTContext *ast_context,
1801 void *clang_type,
1802 const char *name,
1803 bool omit_empty_base_classes,
1804 std::vector<uint32_t>& child_indexes
1805)
1806{
1807 if (clang_type && name && name[0])
1808 {
1809 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1810 switch (qual_type->getTypeClass())
1811 {
Greg Clayton1674b122010-07-21 22:12:05 +00001812 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001813 {
1814 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1815 const RecordDecl *record_decl = record_type->getDecl();
1816
1817 assert(record_decl);
1818 uint32_t child_idx = 0;
1819
1820 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1821
1822 // Try and find a field that matches NAME
1823 RecordDecl::field_iterator field, field_end;
1824 StringRef name_sref(name);
1825 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1826 field != field_end;
1827 ++field, ++child_idx)
1828 {
1829 if (field->getName().equals (name_sref))
1830 {
1831 // We have to add on the number of base classes to this index!
1832 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
1833 return child_indexes.size();
1834 }
1835 }
1836
1837 if (cxx_record_decl)
1838 {
1839 const RecordDecl *parent_record_decl = cxx_record_decl;
1840
1841 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
1842
1843 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
1844 // Didn't find things easily, lets let clang do its thang...
1845 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
1846 DeclarationName decl_name(&ident_ref);
1847
1848 CXXBasePaths paths;
1849 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
1850 decl_name.getAsOpaquePtr(),
1851 paths))
1852 {
Chris Lattner24943d22010-06-08 16:52:24 +00001853 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
1854 for (path = paths.begin(); path != path_end; ++path)
1855 {
1856 const size_t num_path_elements = path->size();
1857 for (size_t e=0; e<num_path_elements; ++e)
1858 {
1859 CXXBasePathElement elem = (*path)[e];
1860
1861 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
1862 if (child_idx == UINT32_MAX)
1863 {
1864 child_indexes.clear();
1865 return 0;
1866 }
1867 else
1868 {
1869 child_indexes.push_back (child_idx);
1870 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
1871 }
1872 }
1873 DeclContext::lookup_iterator named_decl_pos;
1874 for (named_decl_pos = path->Decls.first;
1875 named_decl_pos != path->Decls.second && parent_record_decl;
1876 ++named_decl_pos)
1877 {
1878 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
1879
1880 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
1881 if (child_idx == UINT32_MAX)
1882 {
1883 child_indexes.clear();
1884 return 0;
1885 }
1886 else
1887 {
1888 child_indexes.push_back (child_idx);
1889 }
1890 }
1891 }
1892 return child_indexes.size();
1893 }
1894 }
1895
1896 }
1897 break;
1898
Greg Clayton9488b742010-07-28 02:04:09 +00001899 case clang::Type::ObjCObject:
1900 case clang::Type::ObjCInterface:
1901 {
1902 StringRef name_sref(name);
1903 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1904 assert (objc_class_type);
1905 if (objc_class_type)
1906 {
1907 uint32_t child_idx = 0;
1908 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1909
1910 if (class_interface_decl)
1911 {
1912 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
1913 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1914
1915 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
1916 {
1917 const ObjCIvarDecl* ivar_decl = *ivar_pos;
1918
1919 if (ivar_decl->getName().equals (name_sref))
1920 {
1921 if ((!omit_empty_base_classes && superclass_interface_decl) ||
1922 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
1923 ++child_idx;
1924
1925 child_indexes.push_back (child_idx);
1926 return child_indexes.size();
1927 }
1928 }
1929
1930 if (superclass_interface_decl)
1931 {
1932 // The super class index is always zero for ObjC classes,
1933 // so we push it onto the child indexes in case we find
1934 // an ivar in our superclass...
1935 child_indexes.push_back (0);
1936
1937 if (GetIndexOfChildMemberWithName (ast_context,
1938 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
1939 name,
1940 omit_empty_base_classes,
1941 child_indexes))
1942 {
1943 // We did find an ivar in a superclass so just
1944 // return the results!
1945 return child_indexes.size();
1946 }
1947
1948 // We didn't find an ivar matching "name" in our
1949 // superclass, pop the superclass zero index that
1950 // we pushed on above.
1951 child_indexes.pop_back();
1952 }
1953 }
1954 }
1955 }
1956 break;
1957
1958 case clang::Type::ObjCObjectPointer:
1959 {
1960 return GetIndexOfChildMemberWithName (ast_context,
1961 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
1962 name,
1963 omit_empty_base_classes,
1964 child_indexes);
1965 }
1966 break;
1967
1968
Greg Clayton1674b122010-07-21 22:12:05 +00001969 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001970 {
1971// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1972// const uint64_t element_count = array->getSize().getLimitedValue();
1973//
1974// if (idx < element_count)
1975// {
1976// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1977//
1978// char element_name[32];
1979// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1980//
1981// child_name.assign(element_name);
1982// assert(field_type_info.first % 8 == 0);
1983// child_byte_size = field_type_info.first / 8;
1984// child_byte_offset = idx * child_byte_size;
1985// return array->getElementType().getAsOpaquePtr();
1986// }
1987 }
1988 break;
1989
Greg Clayton1674b122010-07-21 22:12:05 +00001990// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00001991// {
1992// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
1993// QualType pointee_type = mem_ptr_type->getPointeeType();
1994//
1995// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1996// {
1997// return GetIndexOfChildWithName (ast_context,
1998// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
1999// name);
2000// }
2001// }
2002// break;
2003//
Greg Clayton1674b122010-07-21 22:12:05 +00002004 case clang::Type::LValueReference:
2005 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002006 {
2007 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2008 QualType pointee_type = reference_type->getPointeeType();
2009
2010 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2011 {
2012 return GetIndexOfChildMemberWithName (ast_context,
2013 reference_type->getPointeeType().getAsOpaquePtr(),
2014 name,
2015 omit_empty_base_classes,
2016 child_indexes);
2017 }
2018 }
2019 break;
2020
Greg Clayton1674b122010-07-21 22:12:05 +00002021 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002022 {
2023 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2024 QualType pointee_type = pointer_type->getPointeeType();
2025
2026 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2027 {
2028 return GetIndexOfChildMemberWithName (ast_context,
2029 pointer_type->getPointeeType().getAsOpaquePtr(),
2030 name,
2031 omit_empty_base_classes,
2032 child_indexes);
2033 }
2034 else
2035 {
2036// if (parent_name)
2037// {
2038// child_name.assign(1, '*');
2039// child_name += parent_name;
2040// }
2041//
2042// // We have a pointer to an simple type
2043// if (idx == 0)
2044// {
2045// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2046// assert(clang_type_info.first % 8 == 0);
2047// child_byte_size = clang_type_info.first / 8;
2048// child_byte_offset = 0;
2049// return pointee_type.getAsOpaquePtr();
2050// }
2051 }
2052 }
2053 break;
2054
Greg Clayton1674b122010-07-21 22:12:05 +00002055 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002056 return GetIndexOfChildMemberWithName (ast_context,
2057 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2058 name,
2059 omit_empty_base_classes,
2060 child_indexes);
2061
2062 default:
2063 break;
2064 }
2065 }
2066 return 0;
2067}
2068
2069
2070// Get the index of the child of "clang_type" whose name matches. This function
2071// doesn't descend into the children, but only looks one level deep and name
2072// matches can include base class names.
2073
2074uint32_t
2075ClangASTContext::GetIndexOfChildWithName
2076(
2077 ASTContext *ast_context,
2078 void *clang_type,
2079 const char *name,
2080 bool omit_empty_base_classes
2081)
2082{
2083 if (clang_type && name && name[0])
2084 {
2085 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002086
2087 clang::Type::TypeClass qual_type_class = qual_type->getTypeClass();
2088
2089 switch (qual_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002090 {
Greg Clayton1674b122010-07-21 22:12:05 +00002091 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002092 {
2093 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2094 const RecordDecl *record_decl = record_type->getDecl();
2095
2096 assert(record_decl);
2097 uint32_t child_idx = 0;
2098
2099 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2100
2101 if (cxx_record_decl)
2102 {
2103 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2104 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2105 base_class != base_class_end;
2106 ++base_class)
2107 {
2108 // Skip empty base classes
2109 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2110 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2111 continue;
2112
2113 if (base_class->getType().getAsString().compare (name) == 0)
2114 return child_idx;
2115 ++child_idx;
2116 }
2117 }
2118
2119 // Try and find a field that matches NAME
2120 RecordDecl::field_iterator field, field_end;
2121 StringRef name_sref(name);
2122 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2123 field != field_end;
2124 ++field, ++child_idx)
2125 {
2126 if (field->getName().equals (name_sref))
2127 return child_idx;
2128 }
2129
2130 }
2131 break;
2132
Greg Clayton9488b742010-07-28 02:04:09 +00002133 case clang::Type::ObjCObject:
2134 case clang::Type::ObjCInterface:
2135 {
2136 StringRef name_sref(name);
2137 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2138 assert (objc_class_type);
2139 if (objc_class_type)
2140 {
2141 uint32_t child_idx = 0;
2142 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2143
2144 if (class_interface_decl)
2145 {
2146 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2147 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2148
2149 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2150 {
2151 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2152
2153 if (ivar_decl->getName().equals (name_sref))
2154 {
2155 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2156 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2157 ++child_idx;
2158
2159 return child_idx;
2160 }
2161 }
2162
2163 if (superclass_interface_decl)
2164 {
2165 if (superclass_interface_decl->getName().equals (name_sref))
2166 return 0;
2167 }
2168 }
2169 }
2170 }
2171 break;
2172
2173 case clang::Type::ObjCObjectPointer:
2174 {
2175 return GetIndexOfChildWithName (ast_context,
2176 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2177 name,
2178 omit_empty_base_classes);
2179 }
2180 break;
2181
Greg Clayton1674b122010-07-21 22:12:05 +00002182 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002183 {
2184// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2185// const uint64_t element_count = array->getSize().getLimitedValue();
2186//
2187// if (idx < element_count)
2188// {
2189// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2190//
2191// char element_name[32];
2192// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2193//
2194// child_name.assign(element_name);
2195// assert(field_type_info.first % 8 == 0);
2196// child_byte_size = field_type_info.first / 8;
2197// child_byte_offset = idx * child_byte_size;
2198// return array->getElementType().getAsOpaquePtr();
2199// }
2200 }
2201 break;
2202
Greg Clayton1674b122010-07-21 22:12:05 +00002203// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002204// {
2205// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2206// QualType pointee_type = mem_ptr_type->getPointeeType();
2207//
2208// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2209// {
2210// return GetIndexOfChildWithName (ast_context,
2211// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2212// name);
2213// }
2214// }
2215// break;
2216//
Greg Clayton1674b122010-07-21 22:12:05 +00002217 case clang::Type::LValueReference:
2218 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002219 {
2220 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2221 QualType pointee_type = reference_type->getPointeeType();
2222
2223 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2224 {
2225 return GetIndexOfChildWithName (ast_context,
2226 reference_type->getPointeeType().getAsOpaquePtr(),
2227 name,
2228 omit_empty_base_classes);
2229 }
2230 }
2231 break;
2232
Greg Clayton1674b122010-07-21 22:12:05 +00002233 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002234 {
2235 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2236 QualType pointee_type = pointer_type->getPointeeType();
2237
2238 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2239 {
2240 return GetIndexOfChildWithName (ast_context,
2241 pointer_type->getPointeeType().getAsOpaquePtr(),
2242 name,
2243 omit_empty_base_classes);
2244 }
2245 else
2246 {
2247// if (parent_name)
2248// {
2249// child_name.assign(1, '*');
2250// child_name += parent_name;
2251// }
2252//
2253// // We have a pointer to an simple type
2254// if (idx == 0)
2255// {
2256// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2257// assert(clang_type_info.first % 8 == 0);
2258// child_byte_size = clang_type_info.first / 8;
2259// child_byte_offset = 0;
2260// return pointee_type.getAsOpaquePtr();
2261// }
2262 }
2263 }
2264 break;
2265
Greg Clayton1674b122010-07-21 22:12:05 +00002266 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002267 return GetIndexOfChildWithName (ast_context,
2268 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2269 name,
2270 omit_empty_base_classes);
2271
2272 default:
2273 break;
2274 }
2275 }
2276 return UINT32_MAX;
2277}
2278
2279#pragma mark TagType
2280
2281bool
2282ClangASTContext::SetTagTypeKind (void *tag_clang_type, int kind)
2283{
2284 if (tag_clang_type)
2285 {
2286 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00002287 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002288 if (clang_type)
2289 {
2290 TagType *tag_type = dyn_cast<TagType>(clang_type);
2291 if (tag_type)
2292 {
2293 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
2294 if (tag_decl)
2295 {
2296 tag_decl->setTagKind ((TagDecl::TagKind)kind);
2297 return true;
2298 }
2299 }
2300 }
2301 }
2302 return false;
2303}
2304
2305
2306#pragma mark DeclContext Functions
2307
2308DeclContext *
2309ClangASTContext::GetDeclContextForType (void *clang_type)
2310{
2311 if (clang_type == NULL)
2312 return NULL;
2313
2314 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2315 switch (qual_type->getTypeClass())
2316 {
Greg Clayton9488b742010-07-28 02:04:09 +00002317 case clang::Type::FunctionNoProto: break;
2318 case clang::Type::FunctionProto: break;
2319 case clang::Type::IncompleteArray: break;
2320 case clang::Type::VariableArray: break;
2321 case clang::Type::ConstantArray: break;
2322 case clang::Type::ExtVector: break;
2323 case clang::Type::Vector: break;
2324 case clang::Type::Builtin: break;
2325 case clang::Type::BlockPointer: break;
2326 case clang::Type::Pointer: break;
2327 case clang::Type::LValueReference: break;
2328 case clang::Type::RValueReference: break;
2329 case clang::Type::MemberPointer: break;
2330 case clang::Type::Complex: break;
2331 case clang::Type::ObjCObject: break;
2332 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
2333 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
2334 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
2335 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
2336 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00002337
Greg Clayton9488b742010-07-28 02:04:09 +00002338 case clang::Type::TypeOfExpr: break;
2339 case clang::Type::TypeOf: break;
2340 case clang::Type::Decltype: break;
2341 //case clang::Type::QualifiedName: break;
2342 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00002343 }
2344 // No DeclContext in this type...
2345 return NULL;
2346}
2347
2348#pragma mark Namespace Declarations
2349
2350NamespaceDecl *
2351ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
2352{
2353 // TODO: Do something intelligent with the Declaration object passed in
2354 // like maybe filling in the SourceLocation with it...
2355 if (name)
2356 {
2357 ASTContext *ast_context = getASTContext();
2358 if (decl_ctx == NULL)
2359 decl_ctx = ast_context->getTranslationUnitDecl();
2360 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
2361 }
2362 return NULL;
2363}
2364
2365
2366#pragma mark Function Types
2367
2368FunctionDecl *
2369ClangASTContext::CreateFunctionDeclaration (const char *name, void *function_clang_type, int storage, bool is_inline)
2370{
2371 if (name)
2372 {
2373 ASTContext *ast_context = getASTContext();
2374 assert (ast_context != NULL);
2375
2376 if (name && name[0])
2377 {
2378 return FunctionDecl::Create(*ast_context,
2379 ast_context->getTranslationUnitDecl(),
2380 SourceLocation(),
2381 DeclarationName (&ast_context->Idents.get(name)),
2382 QualType::getFromOpaquePtr(function_clang_type),
2383 NULL,
2384 (FunctionDecl::StorageClass)storage,
2385 (FunctionDecl::StorageClass)storage,
2386 is_inline);
2387 }
2388 else
2389 {
2390 return FunctionDecl::Create(*ast_context,
2391 ast_context->getTranslationUnitDecl(),
2392 SourceLocation(),
2393 DeclarationName (),
2394 QualType::getFromOpaquePtr(function_clang_type),
2395 NULL,
2396 (FunctionDecl::StorageClass)storage,
2397 (FunctionDecl::StorageClass)storage,
2398 is_inline);
2399 }
2400 }
2401 return NULL;
2402}
2403
2404void *
2405ClangASTContext::CreateFunctionType (void *result_type, void **args, unsigned num_args, bool isVariadic, unsigned TypeQuals)
2406{
2407 ASTContext *ast_context = getASTContext();
2408 assert (ast_context != NULL);
2409 std::vector<QualType> qual_type_args;
2410 for (unsigned i=0; i<num_args; ++i)
2411 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
2412
2413 // TODO: Detect calling convention in DWARF?
2414 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00002415 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00002416 qual_type_args.size(),
2417 isVariadic,
2418 TypeQuals,
2419 false, // hasExceptionSpec
2420 false, // hasAnyExceptionSpec,
2421 0, // NumExs
2422 0, // const QualType *ExArray
2423 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
2424}
2425
2426ParmVarDecl *
Greg Clayton84f80752010-07-22 18:30:50 +00002427ClangASTContext::CreateParmeterDeclaration (const char *name, void *return_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00002428{
2429 ASTContext *ast_context = getASTContext();
2430 assert (ast_context != NULL);
2431 return ParmVarDecl::Create(*ast_context,
2432 ast_context->getTranslationUnitDecl(),
2433 SourceLocation(),
2434 name && name[0] ? &ast_context->Idents.get(name) : NULL,
2435 QualType::getFromOpaquePtr(return_type),
2436 NULL,
2437 (VarDecl::StorageClass)storage,
2438 (VarDecl::StorageClass)storage,
2439 0);
2440}
2441
2442void
2443ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
2444{
2445 if (function_decl)
2446 function_decl->setParams (params, num_params);
2447}
2448
2449
2450#pragma mark Array Types
2451
2452void *
2453ClangASTContext::CreateArrayType (void *element_type, size_t element_count, uint32_t bit_stride)
2454{
2455 if (element_type)
2456 {
2457 ASTContext *ast_context = getASTContext();
2458 assert (ast_context != NULL);
2459 llvm::APInt ap_element_count (64, element_count);
2460 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
2461 ap_element_count,
2462 ArrayType::Normal,
2463 0).getAsOpaquePtr(); // ElemQuals
2464 }
2465 return NULL;
2466}
2467
2468
2469#pragma mark TagDecl
2470
2471bool
2472ClangASTContext::StartTagDeclarationDefinition (void *clang_type)
2473{
2474 if (clang_type)
2475 {
2476 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00002477 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002478 if (t)
2479 {
2480 TagType *tag_type = dyn_cast<TagType>(t);
2481 if (tag_type)
2482 {
2483 TagDecl *tag_decl = tag_type->getDecl();
2484 if (tag_decl)
2485 {
2486 tag_decl->startDefinition();
2487 return true;
2488 }
2489 }
2490 }
2491 }
2492 return false;
2493}
2494
2495bool
2496ClangASTContext::CompleteTagDeclarationDefinition (void *clang_type)
2497{
2498 if (clang_type)
2499 {
2500 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00002501 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002502 if (t)
2503 {
2504 TagType *tag_type = dyn_cast<TagType>(t);
2505 if (tag_type)
2506 {
2507 TagDecl *tag_decl = tag_type->getDecl();
2508 if (tag_decl)
2509 {
2510 tag_decl->completeDefinition();
2511 return true;
2512 }
2513 }
2514 }
2515 }
2516 return false;
2517}
2518
2519
2520#pragma mark Enumeration Types
2521
2522void *
2523ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name)
2524{
2525 // TODO: Do something intelligent with the Declaration object passed in
2526 // like maybe filling in the SourceLocation with it...
2527 ASTContext *ast_context = getASTContext();
2528 assert (ast_context != NULL);
2529 EnumDecl *enum_decl = EnumDecl::Create(*ast_context,
2530 ast_context->getTranslationUnitDecl(),
2531 SourceLocation(),
2532 name && name[0] ? &ast_context->Idents.get(name) : NULL,
2533 SourceLocation(),
2534 NULL);
2535 if (enum_decl)
2536 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
2537 return NULL;
2538}
2539
2540bool
2541ClangASTContext::AddEnumerationValueToEnumerationType
2542(
2543 void *enum_clang_type,
2544 void *enumerator_clang_type,
2545 const Declaration &decl,
2546 const char *name,
2547 int64_t enum_value,
2548 uint32_t enum_value_bit_size
2549)
2550{
2551 if (enum_clang_type && enumerator_clang_type && name)
2552 {
2553 // TODO: Do something intelligent with the Declaration object passed in
2554 // like maybe filling in the SourceLocation with it...
2555 ASTContext *ast_context = getASTContext();
2556 IdentifierTable *identifier_table = getIdentifierTable();
2557
2558 assert (ast_context != NULL);
2559 assert (identifier_table != NULL);
2560 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
2561
Greg Clayton1674b122010-07-21 22:12:05 +00002562 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002563 if (clang_type)
2564 {
2565 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
2566
2567 if (enum_type)
2568 {
2569 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
2570 enum_llvm_apsint = enum_value;
2571 EnumConstantDecl *enumerator_decl =
2572 EnumConstantDecl::Create(*ast_context,
2573 enum_type->getDecl(),
2574 SourceLocation(),
2575 name ? &identifier_table->get(name) : NULL, // Identifier
2576 QualType::getFromOpaquePtr(enumerator_clang_type),
2577 NULL,
2578 enum_llvm_apsint);
2579
2580 if (enumerator_decl)
2581 {
2582 enum_type->getDecl()->addDecl(enumerator_decl);
2583 return true;
2584 }
2585 }
2586 }
2587 }
2588 return false;
2589}
2590
2591#pragma mark Pointers & References
2592
2593void *
2594ClangASTContext::CreatePointerType (void *clang_type)
2595{
2596 if (clang_type)
2597 return getASTContext()->getPointerType(QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2598 return NULL;
2599}
2600
2601void *
2602ClangASTContext::CreateLValueReferenceType (void *clang_type)
2603{
2604 if (clang_type)
2605 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2606 return NULL;
2607}
2608
2609void *
2610ClangASTContext::CreateRValueReferenceType (void *clang_type)
2611{
2612 if (clang_type)
2613 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2614 return NULL;
2615}
2616
Greg Claytonfa970692010-06-12 01:20:30 +00002617void *
Greg Clayton84f80752010-07-22 18:30:50 +00002618ClangASTContext::CreateMemberPointerType (void *clang_pointee_type, void *clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00002619{
2620 if (clang_pointee_type && clang_pointee_type)
2621 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
2622 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
2623 return NULL;
2624}
2625
Chris Lattner24943d22010-06-08 16:52:24 +00002626size_t
2627ClangASTContext::GetPointerBitSize ()
2628{
2629 ASTContext *ast_context = getASTContext();
2630 return ast_context->getTypeSize(ast_context->VoidPtrTy);
2631}
2632
2633bool
2634ClangASTContext::IsPointerOrReferenceType (void *clang_type, void **target_type)
2635{
2636 if (clang_type == NULL)
2637 return false;
2638
2639 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2640 switch (qual_type->getTypeClass())
2641 {
Greg Clayton1674b122010-07-21 22:12:05 +00002642 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002643 if (target_type)
2644 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2645 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002646 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002647 if (target_type)
2648 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2649 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002650 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002651 if (target_type)
2652 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2653 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002654 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002655 if (target_type)
2656 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2657 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002658 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002659 if (target_type)
2660 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2661 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002662 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002663 if (target_type)
2664 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2665 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002666 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002667 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
2668 default:
2669 break;
2670 }
2671 return false;
2672}
2673
2674size_t
2675ClangASTContext::GetTypeBitSize (clang::ASTContext *ast_context, void *clang_type)
2676{
2677 if (clang_type)
2678 return ast_context->getTypeSize(QualType::getFromOpaquePtr(clang_type));
2679 return 0;
2680}
2681
2682size_t
2683ClangASTContext::GetTypeBitAlign (clang::ASTContext *ast_context, void *clang_type)
2684{
2685 if (clang_type)
2686 return ast_context->getTypeAlign(QualType::getFromOpaquePtr(clang_type));
2687 return 0;
2688}
2689
2690bool
Greg Clayton84f80752010-07-22 18:30:50 +00002691ClangASTContext::IsIntegerType (void *clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00002692{
2693 if (!clang_type)
2694 return false;
2695
2696 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2697 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
2698
2699 if (builtin_type)
2700 {
2701 if (builtin_type->isInteger())
2702 is_signed = builtin_type->isSignedInteger();
2703
2704 return true;
2705 }
2706
2707 return false;
2708}
2709
2710bool
2711ClangASTContext::IsPointerType (void *clang_type, void **target_type)
2712{
2713 if (clang_type)
2714 {
2715 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2716 switch (qual_type->getTypeClass())
2717 {
Greg Clayton1674b122010-07-21 22:12:05 +00002718 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002719 if (target_type)
2720 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2721 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002722 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002723 if (target_type)
2724 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2725 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002726 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002727 if (target_type)
2728 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2729 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002730 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002731 if (target_type)
2732 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2733 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002734 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002735 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
2736 default:
2737 break;
2738 }
2739 }
2740 return false;
2741}
2742
2743bool
2744ClangASTContext::IsFloatingPointType (void *clang_type, uint32_t &count, bool &is_complex)
2745{
2746 if (clang_type)
2747 {
2748 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2749
2750 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
2751 {
2752 clang::BuiltinType::Kind kind = BT->getKind();
2753 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
2754 {
2755 count = 1;
2756 is_complex = false;
2757 return true;
2758 }
2759 }
2760 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
2761 {
2762 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
2763 {
2764 count = 2;
2765 is_complex = true;
2766 return true;
2767 }
2768 }
2769 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
2770 {
2771 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
2772 {
2773 count = VT->getNumElements();
2774 is_complex = false;
2775 return true;
2776 }
2777 }
2778 }
2779 return false;
2780}
2781
2782
2783bool
2784ClangASTContext::IsCStringType (void *clang_type, uint32_t &length)
2785{
2786 if (clang_type)
2787 {
2788 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2789 switch (qual_type->getTypeClass())
2790 {
Greg Clayton1674b122010-07-21 22:12:05 +00002791 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002792 {
2793 ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr());
2794 QualType element_qual_type = array->getElementType();
Greg Clayton1674b122010-07-21 22:12:05 +00002795 clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002796 if (canonical_type && canonical_type->isCharType())
2797 {
2798 // We know the size of the array and it could be a C string
2799 // since it is an array of characters
2800 length = array->getSize().getLimitedValue();
2801 return true;
2802 }
2803 }
2804 break;
2805
Greg Clayton1674b122010-07-21 22:12:05 +00002806 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002807 {
2808 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton1674b122010-07-21 22:12:05 +00002809 clang::Type *pointee_type_ptr = pointer_type->getPointeeType().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002810 if (pointee_type_ptr)
2811 {
Greg Clayton1674b122010-07-21 22:12:05 +00002812 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002813 length = 0; // No length info, read until a NULL terminator is received
2814 if (canonical_type_ptr)
2815 return canonical_type_ptr->isCharType();
2816 else
2817 return pointee_type_ptr->isCharType();
2818 }
2819 }
2820 break;
2821
Greg Clayton1674b122010-07-21 22:12:05 +00002822 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002823 return ClangASTContext::IsCStringType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), length);
2824
Greg Clayton1674b122010-07-21 22:12:05 +00002825 case clang::Type::LValueReference:
2826 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002827 {
2828 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton1674b122010-07-21 22:12:05 +00002829 clang::Type *pointee_type_ptr = reference_type->getPointeeType().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002830 if (pointee_type_ptr)
2831 {
Greg Clayton1674b122010-07-21 22:12:05 +00002832 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002833 length = 0; // No length info, read until a NULL terminator is received
2834 if (canonical_type_ptr)
2835 return canonical_type_ptr->isCharType();
2836 else
2837 return pointee_type_ptr->isCharType();
2838 }
2839 }
2840 break;
2841 }
2842 }
2843 return false;
2844}
2845
2846bool
Greg Clayton84f80752010-07-22 18:30:50 +00002847ClangASTContext::IsArrayType (void *clang_type, void **member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00002848{
2849 if (!clang_type)
2850 return false;
2851
2852 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2853
2854 switch (qual_type->getTypeClass())
2855 {
Greg Clayton1674b122010-07-21 22:12:05 +00002856 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002857 if (member_type)
2858 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2859 if (size)
2860 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
2861 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002862 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002863 if (member_type)
2864 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2865 if (size)
2866 *size = 0;
2867 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00002868 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002869 if (member_type)
2870 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2871 if (size)
2872 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00002873 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002874 if (member_type)
2875 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2876 if (size)
2877 *size = 0;
2878 return true;
2879 }
2880 return false;
2881}
2882
2883
2884#pragma mark Typedefs
2885
2886void *
2887ClangASTContext::CreateTypedefType (const char *name, void *clang_type, DeclContext *decl_ctx)
2888{
2889 if (clang_type)
2890 {
2891 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2892 ASTContext *ast_context = getASTContext();
2893 IdentifierTable *identifier_table = getIdentifierTable();
2894 assert (ast_context != NULL);
2895 assert (identifier_table != NULL);
2896 if (decl_ctx == NULL)
2897 decl_ctx = ast_context->getTranslationUnitDecl();
2898 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
2899 decl_ctx,
2900 SourceLocation(),
2901 name ? &identifier_table->get(name) : NULL, // Identifier
2902 ast_context->CreateTypeSourceInfo(qual_type));
2903
2904 // Get a uniqued QualType for the typedef decl type
2905 return ast_context->getTypedefType (decl).getAsOpaquePtr();
2906 }
2907 return NULL;
2908}
2909
2910
2911std::string
2912ClangASTContext::GetTypeName (void *opaque_qual_type)
2913{
2914 std::string return_name;
2915
2916 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_qual_type));
2917
2918 const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
2919 if (typedef_type)
2920 {
2921 const clang::TypedefDecl *typedef_decl = typedef_type->getDecl();
2922 return_name = typedef_decl->getQualifiedNameAsString();
2923 }
2924 else
2925 {
2926 return_name = qual_type.getAsString();
2927 }
2928
2929 return return_name;
2930}
2931
2932// Disable this for now since I can't seem to get a nicely formatted float
2933// out of the APFloat class without just getting the float, double or quad
2934// and then using a formatted print on it which defeats the purpose. We ideally
2935// would like to get perfect string values for any kind of float semantics
2936// so we can support remote targets. The code below also requires a patch to
2937// llvm::APInt.
2938//bool
2939//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, void *clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
2940//{
2941// uint32_t count = 0;
2942// bool is_complex = false;
2943// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
2944// {
2945// unsigned num_bytes_per_float = byte_size / count;
2946// unsigned num_bits_per_float = num_bytes_per_float * 8;
2947//
2948// float_str.clear();
2949// uint32_t i;
2950// for (i=0; i<count; i++)
2951// {
2952// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
2953// bool is_ieee = false;
2954// APFloat ap_float(ap_int, is_ieee);
2955// char s[1024];
2956// unsigned int hex_digits = 0;
2957// bool upper_case = false;
2958//
2959// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
2960// {
2961// if (i > 0)
2962// float_str.append(", ");
2963// float_str.append(s);
2964// if (i == 1 && is_complex)
2965// float_str.append(1, 'i');
2966// }
2967// }
2968// return !float_str.empty();
2969// }
2970// return false;
2971//}
2972
2973size_t
2974ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, void *clang_type, const char *s, uint8_t *dst, size_t dst_size)
2975{
2976 if (clang_type)
2977 {
2978 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2979 uint32_t count = 0;
2980 bool is_complex = false;
2981 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
2982 {
2983 // TODO: handle complex and vector types
2984 if (count != 1)
2985 return false;
2986
2987 StringRef s_sref(s);
2988 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
2989
2990 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
2991 const uint64_t byte_size = bit_size / 8;
2992 if (dst_size >= byte_size)
2993 {
2994 if (bit_size == sizeof(float)*8)
2995 {
2996 float float32 = ap_float.convertToFloat();
2997 ::memcpy (dst, &float32, byte_size);
2998 return byte_size;
2999 }
3000 else if (bit_size >= 64)
3001 {
3002 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3003 ::memcpy (dst, ap_int.getRawData(), byte_size);
3004 return byte_size;
3005 }
3006 }
3007 }
3008 }
3009 return 0;
3010}