blob: b8a36fbfb55a8a5278ca00d21a2b62304151523f [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
17#include "clang/AST/ASTContext.h"
18#include "clang/AST/ASTImporter.h"
19#include "clang/AST/CXXInheritance.h"
20#include "clang/AST/RecordLayout.h"
21#include "clang/AST/Type.h"
22#include "clang/Basic/Builtins.h"
23#include "clang/Basic/FileManager.h"
24#include "clang/Basic/SourceManager.h"
25#include "clang/Basic/TargetInfo.h"
26#include "clang/Basic/TargetOptions.h"
27#include "clang/Frontend/FrontendOptions.h"
28#include "clang/Frontend/LangStandard.h"
29
30// Project includes
31#include "lldb/Core/dwarf.h"
32
Eli Friedmanf05633b2010-06-13 19:06:42 +000033#include <stdio.h>
34
Chris Lattner24943d22010-06-08 16:52:24 +000035using namespace lldb_private;
36using namespace llvm;
37using namespace clang;
38
39
40static void
41ParseLangArgs
42(
43 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000044 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000045)
46{
47 // FIXME: Cleanup per-file based stuff.
48
49 // Set some properties which depend soley on the input kind; it would be nice
50 // to move these to the language standard, and have the driver resolve the
51 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000052 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000053 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000054 } else if (IK == IK_ObjC ||
55 IK == IK_ObjCXX ||
56 IK == IK_PreprocessedObjC ||
57 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000058 Opts.ObjC1 = Opts.ObjC2 = 1;
59 }
60
61 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
62
63 if (LangStd == LangStandard::lang_unspecified) {
64 // Based on the base language, pick one.
65 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +000066 case IK_None:
67 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +000068 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +000069 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +000070 LangStd = LangStandard::lang_opencl;
71 break;
Greg Claytone41c4b22010-06-13 17:34:29 +000072 case IK_Asm:
73 case IK_C:
74 case IK_PreprocessedC:
75 case IK_ObjC:
76 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +000077 LangStd = LangStandard::lang_gnu99;
78 break;
Greg Claytone41c4b22010-06-13 17:34:29 +000079 case IK_CXX:
80 case IK_PreprocessedCXX:
81 case IK_ObjCXX:
82 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +000083 LangStd = LangStandard::lang_gnucxx98;
84 break;
85 }
86 }
87
88 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
89 Opts.BCPLComment = Std.hasBCPLComments();
90 Opts.C99 = Std.isC99();
91 Opts.CPlusPlus = Std.isCPlusPlus();
92 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
93 Opts.Digraphs = Std.hasDigraphs();
94 Opts.GNUMode = Std.isGNUMode();
95 Opts.GNUInline = !Std.isC99();
96 Opts.HexFloats = Std.hasHexFloats();
97 Opts.ImplicitInt = Std.hasImplicitInt();
98
99 // OpenCL has some additional defaults.
100 if (LangStd == LangStandard::lang_opencl) {
101 Opts.OpenCL = 1;
102 Opts.AltiVec = 1;
103 Opts.CXXOperatorNames = 1;
104 Opts.LaxVectorConversions = 1;
105 }
106
107 // OpenCL and C++ both have bool, true, false keywords.
108 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
109
110// if (Opts.CPlusPlus)
111// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
112//
113// if (Args.hasArg(OPT_fobjc_gc_only))
114// Opts.setGCMode(LangOptions::GCOnly);
115// else if (Args.hasArg(OPT_fobjc_gc))
116// Opts.setGCMode(LangOptions::HybridGC);
117//
118// if (Args.hasArg(OPT_print_ivar_layout))
119// Opts.ObjCGCBitmapPrint = 1;
120//
121// if (Args.hasArg(OPT_faltivec))
122// Opts.AltiVec = 1;
123//
124// if (Args.hasArg(OPT_pthread))
125// Opts.POSIXThreads = 1;
126//
127// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
128// "default");
129// if (Vis == "default")
130 Opts.setVisibilityMode(LangOptions::Default);
131// else if (Vis == "hidden")
132// Opts.setVisibilityMode(LangOptions::Hidden);
133// else if (Vis == "protected")
134// Opts.setVisibilityMode(LangOptions::Protected);
135// else
136// Diags.Report(diag::err_drv_invalid_value)
137// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
138
139// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
140
141 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
142 // is specified, or -std is set to a conforming mode.
143 Opts.Trigraphs = !Opts.GNUMode;
144// if (Args.hasArg(OPT_trigraphs))
145// Opts.Trigraphs = 1;
146//
147// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
148// OPT_fno_dollars_in_identifiers,
149// !Opts.AsmPreprocessor);
150// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
151// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
152// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
153// if (Args.hasArg(OPT_fno_lax_vector_conversions))
154// Opts.LaxVectorConversions = 0;
155// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
156// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
157// Opts.Blocks = Args.hasArg(OPT_fblocks);
158// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
159// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
160// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
161// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
162// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
163// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
164// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
165// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
166// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
167// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
168// Diags);
169// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
170// Opts.ObjCConstantStringClass = getLastArgValue(Args,
171// OPT_fconstant_string_class);
172// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
173// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
174// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
175// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
176// Opts.Static = Args.hasArg(OPT_static_define);
177 Opts.OptimizeSize = 0;
178
179 // FIXME: Eliminate this dependency.
180// unsigned Opt =
181// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
182// Opts.Optimize = Opt != 0;
183 unsigned Opt = 0;
184
185 // This is the __NO_INLINE__ define, which just depends on things like the
186 // optimization level and -fno-inline, not actually whether the backend has
187 // inlining enabled.
188 //
189 // FIXME: This is affected by other options (-fno-inline).
190 Opts.NoInline = !Opt;
191
192// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
193// switch (SSP) {
194// default:
195// Diags.Report(diag::err_drv_invalid_value)
196// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
197// break;
198// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
199// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
200// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
201// }
202}
203
204//----------------------------------------------------------------------
205// ClangASTContext constructor
206//----------------------------------------------------------------------
207//ClangASTContext::ClangASTContext(Module *module) :
208// m_target_triple(),
209// m_ast_context_ap(),
210// m_language_options_ap(),
211// m_source_manager_ap(),
212// m_target_info_ap(),
213// m_identifier_table_ap(),
214// m_selector_table_ap(),
215// m_builtins_ap()
216//{
217// if (module)
218// {
219// ObjectFile * objfile = module->GetObjectFile();
220// if (objfile)
221// objfile->GetTargetTriple(m_target_triple);
222// }
223//}
224
225//ClangASTContext::ClangASTContext(const ConstString& target_triple) :
226// m_target_triple(target_triple),
227// m_ast_context_ap(),
228// m_language_options_ap(),
229// m_source_manager_ap(),
230// m_target_info_ap(),
231// m_identifier_table_ap(),
232// m_selector_table_ap(),
233// m_builtins_ap()
234//{
235//}
236ClangASTContext::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
350SourceManager *
351ClangASTContext::getSourceManager()
352{
353 if (m_source_manager_ap.get() == NULL)
354 m_source_manager_ap.reset(new SourceManager(*getDiagnostic()));
355 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,
695 void * clang_type)
696{
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
706#pragma mark CVR modifiers
707
708void *
709ClangASTContext::AddConstModifier (void *clang_type)
710{
711 if (clang_type)
712 {
713 QualType result(QualType::getFromOpaquePtr(clang_type));
714 result.addConst();
715 return result.getAsOpaquePtr();
716 }
717 return NULL;
718}
719
720void *
721ClangASTContext::AddRestrictModifier (void *clang_type)
722{
723 if (clang_type)
724 {
725 QualType result(QualType::getFromOpaquePtr(clang_type));
726 result.getQualifiers().setRestrict (true);
727 return result.getAsOpaquePtr();
728 }
729 return NULL;
730}
731
732void *
733ClangASTContext::AddVolatileModifier (void *clang_type)
734{
735 if (clang_type)
736 {
737 QualType result(QualType::getFromOpaquePtr(clang_type));
738 result.getQualifiers().setVolatile (true);
739 return result.getAsOpaquePtr();
740 }
741 return NULL;
742}
743
744#pragma mark Structure, Unions, Classes
745
746void *
747ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx)
748{
749 ASTContext *ast_context = getASTContext();
750 assert (ast_context != NULL);
751
752 if (decl_ctx == NULL)
753 decl_ctx = ast_context->getTranslationUnitDecl();
754
755 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
756 // we will need to update this code. I was told to currently always use
757 // the CXXRecordDecl class since we often don't know from debug information
758 // if something is struct or a class, so we default to always use the more
759 // complete definition just in case.
760 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
761 (TagDecl::TagKind)kind,
762 decl_ctx,
763 SourceLocation(),
764 name && name[0] ? &ast_context->Idents.get(name) : NULL);
765
766 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
767}
768
769bool
770ClangASTContext::AddFieldToRecordType (void * record_clang_type, const char *name, void * field_type, int access, uint32_t bitfield_bit_size)
771{
772 if (record_clang_type == NULL || field_type == NULL)
773 return false;
774
775 ASTContext *ast_context = getASTContext();
776 IdentifierTable *identifier_table = getIdentifierTable();
777
778 assert (ast_context != NULL);
779 assert (identifier_table != NULL);
780
781 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
782
783 Type *clang_type = record_qual_type.getTypePtr();
784 if (clang_type)
785 {
786 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
787
788 if (record_type)
789 {
790 RecordDecl *record_decl = record_type->getDecl();
791
792 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
793 if (cxx_record_decl)
794 cxx_record_decl->setEmpty (false);
795
796 clang::Expr *bit_width = NULL;
797 if (bitfield_bit_size != 0)
798 {
799 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
800 bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
801 }
802 FieldDecl *field = FieldDecl::Create(*ast_context,
803 record_decl,
804 SourceLocation(),
805 name ? &identifier_table->get(name) : NULL, // Identifier
806 QualType::getFromOpaquePtr(field_type), // Field type
807 NULL, // DeclaratorInfo *
808 bit_width, // BitWidth
809 false); // Mutable
810
811 field->setAccess((AccessSpecifier)access);
812
813 if (field)
814 {
815 record_decl->addDecl(field);
816 return true;
817 }
818 }
819 }
820 return false;
821}
822
823bool
824ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
825{
826 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
827}
828
829bool
830ClangASTContext::FieldIsBitfield
831(
832 ASTContext *ast_context,
833 FieldDecl* field,
834 uint32_t& bitfield_bit_size
835)
836{
837 if (ast_context == NULL || field == NULL)
838 return false;
839
840 if (field->isBitField())
841 {
842 Expr* bit_width_expr = field->getBitWidth();
843 if (bit_width_expr)
844 {
845 llvm::APSInt bit_width_apsint;
846 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
847 {
848 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
849 return true;
850 }
851 }
852 }
853 return false;
854}
855
856bool
857ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
858{
859 if (record_decl == NULL)
860 return false;
861
862 if (!record_decl->field_empty())
863 return true;
864
865 // No fields, lets check this is a CXX record and check the base classes
866 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
867 if (cxx_record_decl)
868 {
869 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
870 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
871 base_class != base_class_end;
872 ++base_class)
873 {
874 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
875 if (RecordHasFields(base_class_decl))
876 return true;
877 }
878 }
879 return false;
880}
881
882void
883ClangASTContext::SetDefaultAccessForRecordFields (void *clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
884{
885 if (clang_qual_type)
886 {
887 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
888 Type *clang_type = qual_type.getTypePtr();
889 if (clang_type)
890 {
891 RecordType *record_type = dyn_cast<RecordType>(clang_type);
892 if (record_type)
893 {
894 RecordDecl *record_decl = record_type->getDecl();
895 if (record_decl)
896 {
897 uint32_t field_idx;
898 RecordDecl::field_iterator field, field_end;
899 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
900 field != field_end;
901 ++field, ++field_idx)
902 {
903 // If no accessibility was assigned, assign the correct one
904 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
905 field->setAccess ((AccessSpecifier)default_accessibility);
906 }
907 }
908 }
909 }
910 }
911}
912
913#pragma mark C++ Base Classes
914
915CXXBaseSpecifier *
916ClangASTContext::CreateBaseClassSpecifier (void *base_class_type, int access, bool is_virtual, bool base_of_class)
917{
918 if (base_class_type)
919 return new CXXBaseSpecifier(SourceRange(), is_virtual, base_of_class, (AccessSpecifier)access, QualType::getFromOpaquePtr(base_class_type));
920 return NULL;
921}
922
923bool
924ClangASTContext::SetBaseClassesForClassType (void *class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
925{
926 if (class_clang_type)
927 {
928 ASTContext *ast_context = getASTContext();
929 IdentifierTable *identifier_table = getIdentifierTable();
930
931 assert (ast_context != NULL);
932 assert (identifier_table != NULL);
933
934 Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
935 if (clang_type)
936 {
937 RecordType *record_type = dyn_cast<RecordType>(clang_type);
938 if (record_type)
939 {
940 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
941 if (cxx_record_decl)
942 {
943 //cxx_record_decl->setEmpty (false);
944 cxx_record_decl->setBases(base_classes, num_base_classes);
945 return true;
946 }
947 }
948 }
949 }
950 return false;
951}
952
953
954#pragma mark Aggregate Types
955
956bool
957ClangASTContext::IsAggregateType (void *clang_type)
958{
959 if (clang_type == NULL)
960 return false;
961
962 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
963
964 if (qual_type->isAggregateType ())
965 return true;
966
967 switch (qual_type->getTypeClass())
968 {
969 case Type::IncompleteArray:
970 case Type::VariableArray:
971 case Type::ConstantArray:
972 case Type::ExtVector:
973 case Type::Vector:
974 case Type::Record:
975 return true;
976
977 case Type::Typedef:
978 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
979
980 default:
981 break;
982 }
983 // The clang type does have a value
984 return false;
985}
986
987uint32_t
988ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_classes)
989{
990 if (clang_qual_type == NULL)
991 return 0;
992
993 uint32_t num_children = 0;
994 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
995 switch (qual_type->getTypeClass())
996 {
997 case Type::Record:
998 {
999 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1000 const RecordDecl *record_decl = record_type->getDecl();
1001 assert(record_decl);
1002 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1003 if (cxx_record_decl)
1004 {
1005 if (omit_empty_base_classes)
1006 {
1007 // Check each base classes to see if it or any of its
1008 // base classes contain any fields. This can help
1009 // limit the noise in variable views by not having to
1010 // show base classes that contain no members.
1011 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1012 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1013 base_class != base_class_end;
1014 ++base_class)
1015 {
1016 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1017
1018 // Skip empty base classes
1019 if (RecordHasFields(base_class_decl) == false)
1020 continue;
1021
1022 num_children++;
1023 }
1024 }
1025 else
1026 {
1027 // Include all base classes
1028 num_children += cxx_record_decl->getNumBases();
1029 }
1030
1031 }
1032 RecordDecl::field_iterator field, field_end;
1033 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1034 ++num_children;
1035 }
1036 break;
1037
1038 case Type::ConstantArray:
1039 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1040 break;
1041
1042 case Type::Pointer:
1043 {
1044 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1045 QualType pointee_type = pointer_type->getPointeeType();
1046 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), omit_empty_base_classes);
1047 // If this type points to a simple type, then it has 1 child
1048 if (num_pointee_children == 0)
1049 num_children = 1;
1050 else
1051 num_children = num_pointee_children;
1052 }
1053 break;
1054
1055 case Type::Typedef:
1056 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1057 break;
1058
1059 default:
1060 break;
1061 }
1062 return num_children;
1063}
1064
1065
1066void *
1067ClangASTContext::GetChildClangTypeAtIndex
1068(
1069 const char *parent_name,
1070 void *parent_clang_type,
1071 uint32_t idx,
1072 bool transparent_pointers,
1073 bool omit_empty_base_classes,
1074 std::string& child_name,
1075 uint32_t &child_byte_size,
1076 int32_t &child_byte_offset,
1077 uint32_t &child_bitfield_bit_size,
1078 uint32_t &child_bitfield_bit_offset
1079)
1080{
1081 if (parent_clang_type)
1082
1083 return GetChildClangTypeAtIndex (getASTContext(),
1084 parent_name,
1085 parent_clang_type,
1086 idx,
1087 transparent_pointers,
1088 omit_empty_base_classes,
1089 child_name,
1090 child_byte_size,
1091 child_byte_offset,
1092 child_bitfield_bit_size,
1093 child_bitfield_bit_offset);
1094 return NULL;
1095}
1096
1097void *
1098ClangASTContext::GetChildClangTypeAtIndex
1099(
1100 ASTContext *ast_context,
1101 const char *parent_name,
1102 void *parent_clang_type,
1103 uint32_t idx,
1104 bool transparent_pointers,
1105 bool omit_empty_base_classes,
1106 std::string& child_name,
1107 uint32_t &child_byte_size,
1108 int32_t &child_byte_offset,
1109 uint32_t &child_bitfield_bit_size,
1110 uint32_t &child_bitfield_bit_offset
1111)
1112{
1113 if (parent_clang_type == NULL)
1114 return NULL;
1115
1116 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
1117 {
1118 uint32_t bit_offset;
1119 child_bitfield_bit_size = 0;
1120 child_bitfield_bit_offset = 0;
1121 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
1122 switch (parent_qual_type->getTypeClass())
1123 {
1124 case Type::Record:
1125 {
1126 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
1127 const RecordDecl *record_decl = record_type->getDecl();
1128 assert(record_decl);
1129 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
1130 uint32_t child_idx = 0;
1131
1132 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1133 if (cxx_record_decl)
1134 {
1135 // We might have base classes to print out first
1136 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1137 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1138 base_class != base_class_end;
1139 ++base_class)
1140 {
1141 const CXXRecordDecl *base_class_decl = NULL;
1142
1143 // Skip empty base classes
1144 if (omit_empty_base_classes)
1145 {
1146 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1147 if (RecordHasFields(base_class_decl) == false)
1148 continue;
1149 }
1150
1151 if (idx == child_idx)
1152 {
1153 if (base_class_decl == NULL)
1154 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1155
1156
1157 if (base_class->isVirtual())
1158 bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
1159 else
1160 bit_offset = record_layout.getBaseClassOffset(base_class_decl);
1161
1162 // Base classes should be a multiple of 8 bits in size
1163 assert (bit_offset % 8 == 0);
1164 child_byte_offset = bit_offset/8;
1165 std::string base_class_type_name(base_class->getType().getAsString());
1166
1167 child_name.assign(base_class_type_name.c_str());
1168
1169 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
1170
1171 // Base classes biut sizes should be a multiple of 8 bits in size
1172 assert (clang_type_info_bit_size % 8 == 0);
1173 child_byte_size = clang_type_info_bit_size / 8;
1174 return base_class->getType().getAsOpaquePtr();
1175 }
1176 // We don't increment the child index in the for loop since we might
1177 // be skipping empty base classes
1178 ++child_idx;
1179 }
1180 }
1181 const unsigned num_fields = record_layout.getFieldCount();
1182
1183 // Make sure index is in range...
1184 uint32_t field_idx = 0;
1185 RecordDecl::field_iterator field, field_end;
1186 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
1187 {
1188 if (idx == child_idx)
1189 {
1190 // Print the member type if requested
1191 // Print the member name and equal sign
1192 child_name.assign(field->getNameAsString().c_str());
1193
1194 // Figure out the type byte size (field_type_info.first) and
1195 // alignment (field_type_info.second) from the AST context.
1196 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
1197 assert(field_idx < num_fields);
1198
1199 child_byte_size = field_type_info.first / 8;
1200
1201 // Figure out the field offset within the current struct/union/class type
1202 bit_offset = record_layout.getFieldOffset (field_idx);
1203 child_byte_offset = bit_offset / 8;
1204 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
1205 child_bitfield_bit_offset = bit_offset % 8;
1206
1207 return field->getType().getAsOpaquePtr();
1208 }
1209 }
1210 }
1211 break;
1212
1213 case Type::ConstantArray:
1214 {
1215 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1216 const uint64_t element_count = array->getSize().getLimitedValue();
1217
1218 if (idx < element_count)
1219 {
1220 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1221
1222 char element_name[32];
1223 ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1224
1225 child_name.assign(element_name);
1226 assert(field_type_info.first % 8 == 0);
1227 child_byte_size = field_type_info.first / 8;
1228 child_byte_offset = idx * child_byte_size;
1229 return array->getElementType().getAsOpaquePtr();
1230 }
1231 }
1232 break;
1233
1234 case Type::Pointer:
1235 {
1236 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
1237 QualType pointee_type = pointer_type->getPointeeType();
1238
1239 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1240 {
1241 return GetChildClangTypeAtIndex (ast_context,
1242 parent_name,
1243 pointer_type->getPointeeType().getAsOpaquePtr(),
1244 idx,
1245 transparent_pointers,
1246 omit_empty_base_classes,
1247 child_name,
1248 child_byte_size,
1249 child_byte_offset,
1250 child_bitfield_bit_size,
1251 child_bitfield_bit_offset);
1252 }
1253 else
1254 {
1255 if (parent_name)
1256 {
1257 child_name.assign(1, '*');
1258 child_name += parent_name;
1259 }
1260
1261 // We have a pointer to an simple type
1262 if (idx == 0)
1263 {
1264 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1265 assert(clang_type_info.first % 8 == 0);
1266 child_byte_size = clang_type_info.first / 8;
1267 child_byte_offset = 0;
1268 return pointee_type.getAsOpaquePtr();
1269 }
1270 }
1271 }
1272 break;
1273
1274 case Type::Typedef:
1275 return GetChildClangTypeAtIndex (ast_context,
1276 parent_name,
1277 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1278 idx,
1279 transparent_pointers,
1280 omit_empty_base_classes,
1281 child_name,
1282 child_byte_size,
1283 child_byte_offset,
1284 child_bitfield_bit_size,
1285 child_bitfield_bit_offset);
1286 break;
1287
1288 default:
1289 break;
1290 }
1291 }
1292 return false;
1293}
1294
1295static inline bool
1296BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
1297{
1298 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
1299}
1300
1301static uint32_t
1302GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
1303{
1304 uint32_t num_bases = 0;
1305 if (cxx_record_decl)
1306 {
1307 if (omit_empty_base_classes)
1308 {
1309 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1310 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1311 base_class != base_class_end;
1312 ++base_class)
1313 {
1314 // Skip empty base classes
1315 if (omit_empty_base_classes)
1316 {
1317 if (BaseSpecifierIsEmpty (base_class))
1318 continue;
1319 }
1320 ++num_bases;
1321 }
1322 }
1323 else
1324 num_bases = cxx_record_decl->getNumBases();
1325 }
1326 return num_bases;
1327}
1328
1329
1330static uint32_t
1331GetIndexForRecordBase
1332(
1333 const RecordDecl *record_decl,
1334 const CXXBaseSpecifier *base_spec,
1335 bool omit_empty_base_classes
1336)
1337{
1338 uint32_t child_idx = 0;
1339
1340 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1341
1342// const char *super_name = record_decl->getNameAsCString();
1343// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
1344// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
1345//
1346 if (cxx_record_decl)
1347 {
1348 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1349 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1350 base_class != base_class_end;
1351 ++base_class)
1352 {
1353 if (omit_empty_base_classes)
1354 {
1355 if (BaseSpecifierIsEmpty (base_class))
1356 continue;
1357 }
1358
1359// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
1360// child_idx,
1361// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1362//
1363//
1364 if (base_class == base_spec)
1365 return child_idx;
1366 ++child_idx;
1367 }
1368 }
1369
1370 return UINT32_MAX;
1371}
1372
1373
1374static uint32_t
1375GetIndexForRecordChild
1376(
1377 const RecordDecl *record_decl,
1378 NamedDecl *canonical_decl,
1379 bool omit_empty_base_classes
1380)
1381{
1382 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
1383
1384// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1385//
1386//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
1387// if (cxx_record_decl)
1388// {
1389// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1390// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1391// base_class != base_class_end;
1392// ++base_class)
1393// {
1394// if (omit_empty_base_classes)
1395// {
1396// if (BaseSpecifierIsEmpty (base_class))
1397// continue;
1398// }
1399//
1400//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
1401//// record_decl->getNameAsCString(),
1402//// canonical_decl->getNameAsCString(),
1403//// child_idx,
1404//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
1405//
1406//
1407// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1408// if (curr_base_class_decl == canonical_decl)
1409// {
1410// return child_idx;
1411// }
1412// ++child_idx;
1413// }
1414// }
1415//
1416// const uint32_t num_bases = child_idx;
1417 RecordDecl::field_iterator field, field_end;
1418 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1419 field != field_end;
1420 ++field, ++child_idx)
1421 {
1422// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
1423// record_decl->getNameAsCString(),
1424// canonical_decl->getNameAsCString(),
1425// child_idx - num_bases,
1426// field->getNameAsCString());
1427
1428 if (field->getCanonicalDecl() == canonical_decl)
1429 return child_idx;
1430 }
1431
1432 return UINT32_MAX;
1433}
1434
1435// Look for a child member (doesn't include base classes, but it does include
1436// their members) in the type hierarchy. Returns an index path into "clang_type"
1437// on how to reach the appropriate member.
1438//
1439// class A
1440// {
1441// public:
1442// int m_a;
1443// int m_b;
1444// };
1445//
1446// class B
1447// {
1448// };
1449//
1450// class C :
1451// public B,
1452// public A
1453// {
1454// };
1455//
1456// If we have a clang type that describes "class C", and we wanted to looked
1457// "m_b" in it:
1458//
1459// With omit_empty_base_classes == false we would get an integer array back with:
1460// { 1, 1 }
1461// The first index 1 is the child index for "class A" within class C
1462// The second index 1 is the child index for "m_b" within class A
1463//
1464// With omit_empty_base_classes == true we would get an integer array back with:
1465// { 0, 1 }
1466// 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)
1467// The second index 1 is the child index for "m_b" within class A
1468
1469size_t
1470ClangASTContext::GetIndexOfChildMemberWithName
1471(
1472 ASTContext *ast_context,
1473 void *clang_type,
1474 const char *name,
1475 bool omit_empty_base_classes,
1476 std::vector<uint32_t>& child_indexes
1477)
1478{
1479 if (clang_type && name && name[0])
1480 {
1481 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1482 switch (qual_type->getTypeClass())
1483 {
1484 case Type::Record:
1485 {
1486 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1487 const RecordDecl *record_decl = record_type->getDecl();
1488
1489 assert(record_decl);
1490 uint32_t child_idx = 0;
1491
1492 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1493
1494 // Try and find a field that matches NAME
1495 RecordDecl::field_iterator field, field_end;
1496 StringRef name_sref(name);
1497 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1498 field != field_end;
1499 ++field, ++child_idx)
1500 {
1501 if (field->getName().equals (name_sref))
1502 {
1503 // We have to add on the number of base classes to this index!
1504 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
1505 return child_indexes.size();
1506 }
1507 }
1508
1509 if (cxx_record_decl)
1510 {
1511 const RecordDecl *parent_record_decl = cxx_record_decl;
1512
1513 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
1514
1515 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
1516 // Didn't find things easily, lets let clang do its thang...
1517 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
1518 DeclarationName decl_name(&ident_ref);
1519
1520 CXXBasePaths paths;
1521 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
1522 decl_name.getAsOpaquePtr(),
1523 paths))
1524 {
1525 uint32_t child_idx;
1526 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
1527 for (path = paths.begin(); path != path_end; ++path)
1528 {
1529 const size_t num_path_elements = path->size();
1530 for (size_t e=0; e<num_path_elements; ++e)
1531 {
1532 CXXBasePathElement elem = (*path)[e];
1533
1534 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
1535 if (child_idx == UINT32_MAX)
1536 {
1537 child_indexes.clear();
1538 return 0;
1539 }
1540 else
1541 {
1542 child_indexes.push_back (child_idx);
1543 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
1544 }
1545 }
1546 DeclContext::lookup_iterator named_decl_pos;
1547 for (named_decl_pos = path->Decls.first;
1548 named_decl_pos != path->Decls.second && parent_record_decl;
1549 ++named_decl_pos)
1550 {
1551 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
1552
1553 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
1554 if (child_idx == UINT32_MAX)
1555 {
1556 child_indexes.clear();
1557 return 0;
1558 }
1559 else
1560 {
1561 child_indexes.push_back (child_idx);
1562 }
1563 }
1564 }
1565 return child_indexes.size();
1566 }
1567 }
1568
1569 }
1570 break;
1571
1572 case Type::ConstantArray:
1573 {
1574// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1575// const uint64_t element_count = array->getSize().getLimitedValue();
1576//
1577// if (idx < element_count)
1578// {
1579// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1580//
1581// char element_name[32];
1582// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1583//
1584// child_name.assign(element_name);
1585// assert(field_type_info.first % 8 == 0);
1586// child_byte_size = field_type_info.first / 8;
1587// child_byte_offset = idx * child_byte_size;
1588// return array->getElementType().getAsOpaquePtr();
1589// }
1590 }
1591 break;
1592
1593// case Type::MemberPointerType:
1594// {
1595// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
1596// QualType pointee_type = mem_ptr_type->getPointeeType();
1597//
1598// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1599// {
1600// return GetIndexOfChildWithName (ast_context,
1601// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
1602// name);
1603// }
1604// }
1605// break;
1606//
1607 case Type::LValueReference:
1608 case Type::RValueReference:
1609 {
1610 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1611 QualType pointee_type = reference_type->getPointeeType();
1612
1613 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1614 {
1615 return GetIndexOfChildMemberWithName (ast_context,
1616 reference_type->getPointeeType().getAsOpaquePtr(),
1617 name,
1618 omit_empty_base_classes,
1619 child_indexes);
1620 }
1621 }
1622 break;
1623
1624 case Type::Pointer:
1625 {
1626 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1627 QualType pointee_type = pointer_type->getPointeeType();
1628
1629 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1630 {
1631 return GetIndexOfChildMemberWithName (ast_context,
1632 pointer_type->getPointeeType().getAsOpaquePtr(),
1633 name,
1634 omit_empty_base_classes,
1635 child_indexes);
1636 }
1637 else
1638 {
1639// if (parent_name)
1640// {
1641// child_name.assign(1, '*');
1642// child_name += parent_name;
1643// }
1644//
1645// // We have a pointer to an simple type
1646// if (idx == 0)
1647// {
1648// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1649// assert(clang_type_info.first % 8 == 0);
1650// child_byte_size = clang_type_info.first / 8;
1651// child_byte_offset = 0;
1652// return pointee_type.getAsOpaquePtr();
1653// }
1654 }
1655 }
1656 break;
1657
1658 case Type::Typedef:
1659 return GetIndexOfChildMemberWithName (ast_context,
1660 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1661 name,
1662 omit_empty_base_classes,
1663 child_indexes);
1664
1665 default:
1666 break;
1667 }
1668 }
1669 return 0;
1670}
1671
1672
1673// Get the index of the child of "clang_type" whose name matches. This function
1674// doesn't descend into the children, but only looks one level deep and name
1675// matches can include base class names.
1676
1677uint32_t
1678ClangASTContext::GetIndexOfChildWithName
1679(
1680 ASTContext *ast_context,
1681 void *clang_type,
1682 const char *name,
1683 bool omit_empty_base_classes
1684)
1685{
1686 if (clang_type && name && name[0])
1687 {
1688 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1689 switch (qual_type->getTypeClass())
1690 {
1691 case Type::Record:
1692 {
1693 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1694 const RecordDecl *record_decl = record_type->getDecl();
1695
1696 assert(record_decl);
1697 uint32_t child_idx = 0;
1698
1699 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1700
1701 if (cxx_record_decl)
1702 {
1703 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1704 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1705 base_class != base_class_end;
1706 ++base_class)
1707 {
1708 // Skip empty base classes
1709 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1710 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
1711 continue;
1712
1713 if (base_class->getType().getAsString().compare (name) == 0)
1714 return child_idx;
1715 ++child_idx;
1716 }
1717 }
1718
1719 // Try and find a field that matches NAME
1720 RecordDecl::field_iterator field, field_end;
1721 StringRef name_sref(name);
1722 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
1723 field != field_end;
1724 ++field, ++child_idx)
1725 {
1726 if (field->getName().equals (name_sref))
1727 return child_idx;
1728 }
1729
1730 }
1731 break;
1732
1733 case Type::ConstantArray:
1734 {
1735// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1736// const uint64_t element_count = array->getSize().getLimitedValue();
1737//
1738// if (idx < element_count)
1739// {
1740// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1741//
1742// char element_name[32];
1743// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1744//
1745// child_name.assign(element_name);
1746// assert(field_type_info.first % 8 == 0);
1747// child_byte_size = field_type_info.first / 8;
1748// child_byte_offset = idx * child_byte_size;
1749// return array->getElementType().getAsOpaquePtr();
1750// }
1751 }
1752 break;
1753
1754// case Type::MemberPointerType:
1755// {
1756// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
1757// QualType pointee_type = mem_ptr_type->getPointeeType();
1758//
1759// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1760// {
1761// return GetIndexOfChildWithName (ast_context,
1762// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
1763// name);
1764// }
1765// }
1766// break;
1767//
1768 case Type::LValueReference:
1769 case Type::RValueReference:
1770 {
1771 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1772 QualType pointee_type = reference_type->getPointeeType();
1773
1774 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1775 {
1776 return GetIndexOfChildWithName (ast_context,
1777 reference_type->getPointeeType().getAsOpaquePtr(),
1778 name,
1779 omit_empty_base_classes);
1780 }
1781 }
1782 break;
1783
1784 case Type::Pointer:
1785 {
1786 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1787 QualType pointee_type = pointer_type->getPointeeType();
1788
1789 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1790 {
1791 return GetIndexOfChildWithName (ast_context,
1792 pointer_type->getPointeeType().getAsOpaquePtr(),
1793 name,
1794 omit_empty_base_classes);
1795 }
1796 else
1797 {
1798// if (parent_name)
1799// {
1800// child_name.assign(1, '*');
1801// child_name += parent_name;
1802// }
1803//
1804// // We have a pointer to an simple type
1805// if (idx == 0)
1806// {
1807// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1808// assert(clang_type_info.first % 8 == 0);
1809// child_byte_size = clang_type_info.first / 8;
1810// child_byte_offset = 0;
1811// return pointee_type.getAsOpaquePtr();
1812// }
1813 }
1814 }
1815 break;
1816
1817 case Type::Typedef:
1818 return GetIndexOfChildWithName (ast_context,
1819 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1820 name,
1821 omit_empty_base_classes);
1822
1823 default:
1824 break;
1825 }
1826 }
1827 return UINT32_MAX;
1828}
1829
1830#pragma mark TagType
1831
1832bool
1833ClangASTContext::SetTagTypeKind (void *tag_clang_type, int kind)
1834{
1835 if (tag_clang_type)
1836 {
1837 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
1838 Type *clang_type = tag_qual_type.getTypePtr();
1839 if (clang_type)
1840 {
1841 TagType *tag_type = dyn_cast<TagType>(clang_type);
1842 if (tag_type)
1843 {
1844 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
1845 if (tag_decl)
1846 {
1847 tag_decl->setTagKind ((TagDecl::TagKind)kind);
1848 return true;
1849 }
1850 }
1851 }
1852 }
1853 return false;
1854}
1855
1856
1857#pragma mark DeclContext Functions
1858
1859DeclContext *
1860ClangASTContext::GetDeclContextForType (void *clang_type)
1861{
1862 if (clang_type == NULL)
1863 return NULL;
1864
1865 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1866 switch (qual_type->getTypeClass())
1867 {
1868 case Type::FunctionNoProto: break;
1869 case Type::FunctionProto: break;
1870 case Type::IncompleteArray: break;
1871 case Type::VariableArray: break;
1872 case Type::ConstantArray: break;
1873 case Type::ExtVector: break;
1874 case Type::Vector: break;
1875 case Type::Builtin: break;
1876 case Type::ObjCObjectPointer: break;
1877 case Type::BlockPointer: break;
1878 case Type::Pointer: break;
1879 case Type::LValueReference: break;
1880 case Type::RValueReference: break;
1881 case Type::MemberPointer: break;
1882 case Type::Complex: break;
1883 case Type::ObjCInterface: break;
1884 case Type::Record:
1885 return cast<RecordType>(qual_type)->getDecl();
1886 case Type::Enum:
1887 return cast<EnumType>(qual_type)->getDecl();
1888 case Type::Typedef:
1889 return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1890
1891 case Type::TypeOfExpr: break;
1892 case Type::TypeOf: break;
1893 case Type::Decltype: break;
1894 //case Type::QualifiedName: break;
1895 case Type::TemplateSpecialization: break;
1896 }
1897 // No DeclContext in this type...
1898 return NULL;
1899}
1900
1901#pragma mark Namespace Declarations
1902
1903NamespaceDecl *
1904ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
1905{
1906 // TODO: Do something intelligent with the Declaration object passed in
1907 // like maybe filling in the SourceLocation with it...
1908 if (name)
1909 {
1910 ASTContext *ast_context = getASTContext();
1911 if (decl_ctx == NULL)
1912 decl_ctx = ast_context->getTranslationUnitDecl();
1913 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
1914 }
1915 return NULL;
1916}
1917
1918
1919#pragma mark Function Types
1920
1921FunctionDecl *
1922ClangASTContext::CreateFunctionDeclaration (const char *name, void *function_clang_type, int storage, bool is_inline)
1923{
1924 if (name)
1925 {
1926 ASTContext *ast_context = getASTContext();
1927 assert (ast_context != NULL);
1928
1929 if (name && name[0])
1930 {
1931 return FunctionDecl::Create(*ast_context,
1932 ast_context->getTranslationUnitDecl(),
1933 SourceLocation(),
1934 DeclarationName (&ast_context->Idents.get(name)),
1935 QualType::getFromOpaquePtr(function_clang_type),
1936 NULL,
1937 (FunctionDecl::StorageClass)storage,
1938 (FunctionDecl::StorageClass)storage,
1939 is_inline);
1940 }
1941 else
1942 {
1943 return FunctionDecl::Create(*ast_context,
1944 ast_context->getTranslationUnitDecl(),
1945 SourceLocation(),
1946 DeclarationName (),
1947 QualType::getFromOpaquePtr(function_clang_type),
1948 NULL,
1949 (FunctionDecl::StorageClass)storage,
1950 (FunctionDecl::StorageClass)storage,
1951 is_inline);
1952 }
1953 }
1954 return NULL;
1955}
1956
1957void *
1958ClangASTContext::CreateFunctionType (void *result_type, void **args, unsigned num_args, bool isVariadic, unsigned TypeQuals)
1959{
1960 ASTContext *ast_context = getASTContext();
1961 assert (ast_context != NULL);
1962 std::vector<QualType> qual_type_args;
1963 for (unsigned i=0; i<num_args; ++i)
1964 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
1965
1966 // TODO: Detect calling convention in DWARF?
1967 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
1968 qual_type_args.data(),
1969 qual_type_args.size(),
1970 isVariadic,
1971 TypeQuals,
1972 false, // hasExceptionSpec
1973 false, // hasAnyExceptionSpec,
1974 0, // NumExs
1975 0, // const QualType *ExArray
1976 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
1977}
1978
1979ParmVarDecl *
1980ClangASTContext::CreateParmeterDeclaration (const char *name, void * return_type, int storage)
1981{
1982 ASTContext *ast_context = getASTContext();
1983 assert (ast_context != NULL);
1984 return ParmVarDecl::Create(*ast_context,
1985 ast_context->getTranslationUnitDecl(),
1986 SourceLocation(),
1987 name && name[0] ? &ast_context->Idents.get(name) : NULL,
1988 QualType::getFromOpaquePtr(return_type),
1989 NULL,
1990 (VarDecl::StorageClass)storage,
1991 (VarDecl::StorageClass)storage,
1992 0);
1993}
1994
1995void
1996ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
1997{
1998 if (function_decl)
1999 function_decl->setParams (params, num_params);
2000}
2001
2002
2003#pragma mark Array Types
2004
2005void *
2006ClangASTContext::CreateArrayType (void *element_type, size_t element_count, uint32_t bit_stride)
2007{
2008 if (element_type)
2009 {
2010 ASTContext *ast_context = getASTContext();
2011 assert (ast_context != NULL);
2012 llvm::APInt ap_element_count (64, element_count);
2013 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
2014 ap_element_count,
2015 ArrayType::Normal,
2016 0).getAsOpaquePtr(); // ElemQuals
2017 }
2018 return NULL;
2019}
2020
2021
2022#pragma mark TagDecl
2023
2024bool
2025ClangASTContext::StartTagDeclarationDefinition (void *clang_type)
2026{
2027 if (clang_type)
2028 {
2029 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2030 Type *t = qual_type.getTypePtr();
2031 if (t)
2032 {
2033 TagType *tag_type = dyn_cast<TagType>(t);
2034 if (tag_type)
2035 {
2036 TagDecl *tag_decl = tag_type->getDecl();
2037 if (tag_decl)
2038 {
2039 tag_decl->startDefinition();
2040 return true;
2041 }
2042 }
2043 }
2044 }
2045 return false;
2046}
2047
2048bool
2049ClangASTContext::CompleteTagDeclarationDefinition (void *clang_type)
2050{
2051 if (clang_type)
2052 {
2053 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2054 Type *t = qual_type.getTypePtr();
2055 if (t)
2056 {
2057 TagType *tag_type = dyn_cast<TagType>(t);
2058 if (tag_type)
2059 {
2060 TagDecl *tag_decl = tag_type->getDecl();
2061 if (tag_decl)
2062 {
2063 tag_decl->completeDefinition();
2064 return true;
2065 }
2066 }
2067 }
2068 }
2069 return false;
2070}
2071
2072
2073#pragma mark Enumeration Types
2074
2075void *
2076ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name)
2077{
2078 // TODO: Do something intelligent with the Declaration object passed in
2079 // like maybe filling in the SourceLocation with it...
2080 ASTContext *ast_context = getASTContext();
2081 assert (ast_context != NULL);
2082 EnumDecl *enum_decl = EnumDecl::Create(*ast_context,
2083 ast_context->getTranslationUnitDecl(),
2084 SourceLocation(),
2085 name && name[0] ? &ast_context->Idents.get(name) : NULL,
2086 SourceLocation(),
2087 NULL);
2088 if (enum_decl)
2089 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
2090 return NULL;
2091}
2092
2093bool
2094ClangASTContext::AddEnumerationValueToEnumerationType
2095(
2096 void *enum_clang_type,
2097 void *enumerator_clang_type,
2098 const Declaration &decl,
2099 const char *name,
2100 int64_t enum_value,
2101 uint32_t enum_value_bit_size
2102)
2103{
2104 if (enum_clang_type && enumerator_clang_type && name)
2105 {
2106 // TODO: Do something intelligent with the Declaration object passed in
2107 // like maybe filling in the SourceLocation with it...
2108 ASTContext *ast_context = getASTContext();
2109 IdentifierTable *identifier_table = getIdentifierTable();
2110
2111 assert (ast_context != NULL);
2112 assert (identifier_table != NULL);
2113 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
2114
2115 Type *clang_type = enum_qual_type.getTypePtr();
2116 if (clang_type)
2117 {
2118 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
2119
2120 if (enum_type)
2121 {
2122 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
2123 enum_llvm_apsint = enum_value;
2124 EnumConstantDecl *enumerator_decl =
2125 EnumConstantDecl::Create(*ast_context,
2126 enum_type->getDecl(),
2127 SourceLocation(),
2128 name ? &identifier_table->get(name) : NULL, // Identifier
2129 QualType::getFromOpaquePtr(enumerator_clang_type),
2130 NULL,
2131 enum_llvm_apsint);
2132
2133 if (enumerator_decl)
2134 {
2135 enum_type->getDecl()->addDecl(enumerator_decl);
2136 return true;
2137 }
2138 }
2139 }
2140 }
2141 return false;
2142}
2143
2144#pragma mark Pointers & References
2145
2146void *
2147ClangASTContext::CreatePointerType (void *clang_type)
2148{
2149 if (clang_type)
2150 return getASTContext()->getPointerType(QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2151 return NULL;
2152}
2153
2154void *
2155ClangASTContext::CreateLValueReferenceType (void *clang_type)
2156{
2157 if (clang_type)
2158 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2159 return NULL;
2160}
2161
2162void *
2163ClangASTContext::CreateRValueReferenceType (void *clang_type)
2164{
2165 if (clang_type)
2166 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2167 return NULL;
2168}
2169
Greg Claytonfa970692010-06-12 01:20:30 +00002170void *
2171ClangASTContext::CreateMemberPointerType (void * clang_pointee_type, void * clang_class_type)
2172{
2173 if (clang_pointee_type && clang_pointee_type)
2174 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
2175 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
2176 return NULL;
2177}
2178
Chris Lattner24943d22010-06-08 16:52:24 +00002179size_t
2180ClangASTContext::GetPointerBitSize ()
2181{
2182 ASTContext *ast_context = getASTContext();
2183 return ast_context->getTypeSize(ast_context->VoidPtrTy);
2184}
2185
2186bool
2187ClangASTContext::IsPointerOrReferenceType (void *clang_type, void **target_type)
2188{
2189 if (clang_type == NULL)
2190 return false;
2191
2192 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2193 switch (qual_type->getTypeClass())
2194 {
2195 case Type::ObjCObjectPointer:
2196 if (target_type)
2197 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2198 return true;
2199 case Type::BlockPointer:
2200 if (target_type)
2201 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2202 return true;
2203 case Type::Pointer:
2204 if (target_type)
2205 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2206 return true;
2207 case Type::MemberPointer:
2208 if (target_type)
2209 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2210 return true;
2211 case Type::LValueReference:
2212 if (target_type)
2213 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2214 return true;
2215 case Type::RValueReference:
2216 if (target_type)
2217 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
2218 return true;
2219 case Type::Typedef:
2220 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
2221 default:
2222 break;
2223 }
2224 return false;
2225}
2226
2227size_t
2228ClangASTContext::GetTypeBitSize (clang::ASTContext *ast_context, void *clang_type)
2229{
2230 if (clang_type)
2231 return ast_context->getTypeSize(QualType::getFromOpaquePtr(clang_type));
2232 return 0;
2233}
2234
2235size_t
2236ClangASTContext::GetTypeBitAlign (clang::ASTContext *ast_context, void *clang_type)
2237{
2238 if (clang_type)
2239 return ast_context->getTypeAlign(QualType::getFromOpaquePtr(clang_type));
2240 return 0;
2241}
2242
2243bool
2244ClangASTContext::IsIntegerType (void * clang_type, bool &is_signed)
2245{
2246 if (!clang_type)
2247 return false;
2248
2249 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2250 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
2251
2252 if (builtin_type)
2253 {
2254 if (builtin_type->isInteger())
2255 is_signed = builtin_type->isSignedInteger();
2256
2257 return true;
2258 }
2259
2260 return false;
2261}
2262
2263bool
2264ClangASTContext::IsPointerType (void *clang_type, void **target_type)
2265{
2266 if (clang_type)
2267 {
2268 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2269 switch (qual_type->getTypeClass())
2270 {
2271 case Type::ObjCObjectPointer:
2272 if (target_type)
2273 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2274 return true;
2275 case Type::BlockPointer:
2276 if (target_type)
2277 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2278 return true;
2279 case Type::Pointer:
2280 if (target_type)
2281 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2282 return true;
2283 case Type::MemberPointer:
2284 if (target_type)
2285 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
2286 return true;
2287 case Type::Typedef:
2288 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
2289 default:
2290 break;
2291 }
2292 }
2293 return false;
2294}
2295
2296bool
2297ClangASTContext::IsFloatingPointType (void *clang_type, uint32_t &count, bool &is_complex)
2298{
2299 if (clang_type)
2300 {
2301 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2302
2303 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
2304 {
2305 clang::BuiltinType::Kind kind = BT->getKind();
2306 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
2307 {
2308 count = 1;
2309 is_complex = false;
2310 return true;
2311 }
2312 }
2313 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
2314 {
2315 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
2316 {
2317 count = 2;
2318 is_complex = true;
2319 return true;
2320 }
2321 }
2322 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
2323 {
2324 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
2325 {
2326 count = VT->getNumElements();
2327 is_complex = false;
2328 return true;
2329 }
2330 }
2331 }
2332 return false;
2333}
2334
2335
2336bool
2337ClangASTContext::IsCStringType (void *clang_type, uint32_t &length)
2338{
2339 if (clang_type)
2340 {
2341 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2342 switch (qual_type->getTypeClass())
2343 {
2344 case Type::ConstantArray:
2345 {
2346 ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr());
2347 QualType element_qual_type = array->getElementType();
2348 Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
2349 if (canonical_type && canonical_type->isCharType())
2350 {
2351 // We know the size of the array and it could be a C string
2352 // since it is an array of characters
2353 length = array->getSize().getLimitedValue();
2354 return true;
2355 }
2356 }
2357 break;
2358
2359 case Type::Pointer:
2360 {
2361 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2362 Type *pointee_type_ptr = pointer_type->getPointeeType().getTypePtr();
2363 if (pointee_type_ptr)
2364 {
2365 Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
2366 length = 0; // No length info, read until a NULL terminator is received
2367 if (canonical_type_ptr)
2368 return canonical_type_ptr->isCharType();
2369 else
2370 return pointee_type_ptr->isCharType();
2371 }
2372 }
2373 break;
2374
2375 case Type::Typedef:
2376 return ClangASTContext::IsCStringType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), length);
2377
2378 case Type::LValueReference:
2379 case Type::RValueReference:
2380 {
2381 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2382 Type *pointee_type_ptr = reference_type->getPointeeType().getTypePtr();
2383 if (pointee_type_ptr)
2384 {
2385 Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
2386 length = 0; // No length info, read until a NULL terminator is received
2387 if (canonical_type_ptr)
2388 return canonical_type_ptr->isCharType();
2389 else
2390 return pointee_type_ptr->isCharType();
2391 }
2392 }
2393 break;
2394 }
2395 }
2396 return false;
2397}
2398
2399bool
2400ClangASTContext::IsArrayType (void * clang_type, void **member_type, uint64_t *size)
2401{
2402 if (!clang_type)
2403 return false;
2404
2405 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2406
2407 switch (qual_type->getTypeClass())
2408 {
2409 case Type::ConstantArray:
2410 if (member_type)
2411 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2412 if (size)
2413 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
2414 return true;
2415 case Type::IncompleteArray:
2416 if (member_type)
2417 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2418 if (size)
2419 *size = 0;
2420 return true;
2421 case Type::VariableArray:
2422 if (member_type)
2423 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2424 if (size)
2425 *size = 0;
2426 case Type::DependentSizedArray:
2427 if (member_type)
2428 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
2429 if (size)
2430 *size = 0;
2431 return true;
2432 }
2433 return false;
2434}
2435
2436
2437#pragma mark Typedefs
2438
2439void *
2440ClangASTContext::CreateTypedefType (const char *name, void *clang_type, DeclContext *decl_ctx)
2441{
2442 if (clang_type)
2443 {
2444 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2445 ASTContext *ast_context = getASTContext();
2446 IdentifierTable *identifier_table = getIdentifierTable();
2447 assert (ast_context != NULL);
2448 assert (identifier_table != NULL);
2449 if (decl_ctx == NULL)
2450 decl_ctx = ast_context->getTranslationUnitDecl();
2451 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
2452 decl_ctx,
2453 SourceLocation(),
2454 name ? &identifier_table->get(name) : NULL, // Identifier
2455 ast_context->CreateTypeSourceInfo(qual_type));
2456
2457 // Get a uniqued QualType for the typedef decl type
2458 return ast_context->getTypedefType (decl).getAsOpaquePtr();
2459 }
2460 return NULL;
2461}
2462
2463
2464std::string
2465ClangASTContext::GetTypeName (void *opaque_qual_type)
2466{
2467 std::string return_name;
2468
2469 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_qual_type));
2470
2471 const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
2472 if (typedef_type)
2473 {
2474 const clang::TypedefDecl *typedef_decl = typedef_type->getDecl();
2475 return_name = typedef_decl->getQualifiedNameAsString();
2476 }
2477 else
2478 {
2479 return_name = qual_type.getAsString();
2480 }
2481
2482 return return_name;
2483}
2484
2485// Disable this for now since I can't seem to get a nicely formatted float
2486// out of the APFloat class without just getting the float, double or quad
2487// and then using a formatted print on it which defeats the purpose. We ideally
2488// would like to get perfect string values for any kind of float semantics
2489// so we can support remote targets. The code below also requires a patch to
2490// llvm::APInt.
2491//bool
2492//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, void *clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
2493//{
2494// uint32_t count = 0;
2495// bool is_complex = false;
2496// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
2497// {
2498// unsigned num_bytes_per_float = byte_size / count;
2499// unsigned num_bits_per_float = num_bytes_per_float * 8;
2500//
2501// float_str.clear();
2502// uint32_t i;
2503// for (i=0; i<count; i++)
2504// {
2505// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
2506// bool is_ieee = false;
2507// APFloat ap_float(ap_int, is_ieee);
2508// char s[1024];
2509// unsigned int hex_digits = 0;
2510// bool upper_case = false;
2511//
2512// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
2513// {
2514// if (i > 0)
2515// float_str.append(", ");
2516// float_str.append(s);
2517// if (i == 1 && is_complex)
2518// float_str.append(1, 'i');
2519// }
2520// }
2521// return !float_str.empty();
2522// }
2523// return false;
2524//}
2525
2526size_t
2527ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, void *clang_type, const char *s, uint8_t *dst, size_t dst_size)
2528{
2529 if (clang_type)
2530 {
2531 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2532 uint32_t count = 0;
2533 bool is_complex = false;
2534 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
2535 {
2536 // TODO: handle complex and vector types
2537 if (count != 1)
2538 return false;
2539
2540 StringRef s_sref(s);
2541 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
2542
2543 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
2544 const uint64_t byte_size = bit_size / 8;
2545 if (dst_size >= byte_size)
2546 {
2547 if (bit_size == sizeof(float)*8)
2548 {
2549 float float32 = ap_float.convertToFloat();
2550 ::memcpy (dst, &float32, byte_size);
2551 return byte_size;
2552 }
2553 else if (bit_size >= 64)
2554 {
2555 llvm::APInt ap_int(ap_float.bitcastToAPInt());
2556 ::memcpy (dst, ap_int.getRawData(), byte_size);
2557 return byte_size;
2558 }
2559 }
2560 }
2561 }
2562 return 0;
2563}