blob: 6a03514b9626ef69c29d474456330b38506fcd0a [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedmanf05633b2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Sean Callananbc4f0f52010-07-08 18:16:16 +000017#define NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "clang/AST/ASTContext.h"
19#include "clang/AST/ASTImporter.h"
20#include "clang/AST/CXXInheritance.h"
Greg Clayton84f80752010-07-22 18:30:50 +000021#include "clang/AST/DeclObjC.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "clang/AST/RecordLayout.h"
23#include "clang/AST/Type.h"
24#include "clang/Basic/Builtins.h"
25#include "clang/Basic/FileManager.h"
26#include "clang/Basic/SourceManager.h"
27#include "clang/Basic/TargetInfo.h"
28#include "clang/Basic/TargetOptions.h"
29#include "clang/Frontend/FrontendOptions.h"
30#include "clang/Frontend/LangStandard.h"
Sean Callananbc4f0f52010-07-08 18:16:16 +000031#undef NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000032
Chris Lattner24943d22010-06-08 16:52:24 +000033#include "lldb/Core/dwarf.h"
34
Eli Friedmanf05633b2010-06-13 19:06:42 +000035#include <stdio.h>
36
Greg Clayton585660c2010-08-05 01:57:25 +000037using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000038using namespace lldb_private;
39using namespace llvm;
40using namespace clang;
41
Greg Clayton84f80752010-07-22 18:30:50 +000042static AccessSpecifier
Greg Clayton585660c2010-08-05 01:57:25 +000043ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000044{
45 switch (access)
46 {
Greg Clayton585660c2010-08-05 01:57:25 +000047 default: break;
48 case eAccessNone: return AS_none;
49 case eAccessPublic: return AS_public;
50 case eAccessPrivate: return AS_private;
51 case eAccessProtected: return AS_protected;
Greg Clayton84f80752010-07-22 18:30:50 +000052 }
53 return AS_none;
54}
55
56static ObjCIvarDecl::AccessControl
Greg Clayton585660c2010-08-05 01:57:25 +000057ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000058{
59 switch (access)
60 {
Greg Clayton585660c2010-08-05 01:57:25 +000061 default: break;
62 case eAccessNone: return ObjCIvarDecl::None;
63 case eAccessPublic: return ObjCIvarDecl::Public;
64 case eAccessPrivate: return ObjCIvarDecl::Private;
65 case eAccessProtected: return ObjCIvarDecl::Protected;
66 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton84f80752010-07-22 18:30:50 +000067 }
68 return ObjCIvarDecl::None;
69}
70
71
Chris Lattner24943d22010-06-08 16:52:24 +000072static void
73ParseLangArgs
74(
75 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000076 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000077)
78{
79 // FIXME: Cleanup per-file based stuff.
80
81 // Set some properties which depend soley on the input kind; it would be nice
82 // to move these to the language standard, and have the driver resolve the
83 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000084 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000085 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000086 } else if (IK == IK_ObjC ||
87 IK == IK_ObjCXX ||
88 IK == IK_PreprocessedObjC ||
89 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000090 Opts.ObjC1 = Opts.ObjC2 = 1;
91 }
92
93 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
94
95 if (LangStd == LangStandard::lang_unspecified) {
96 // Based on the base language, pick one.
97 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +000098 case IK_None:
99 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +0000100 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +0000101 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +0000102 LangStd = LangStandard::lang_opencl;
103 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000104 case IK_Asm:
105 case IK_C:
106 case IK_PreprocessedC:
107 case IK_ObjC:
108 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +0000109 LangStd = LangStandard::lang_gnu99;
110 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000111 case IK_CXX:
112 case IK_PreprocessedCXX:
113 case IK_ObjCXX:
114 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +0000115 LangStd = LangStandard::lang_gnucxx98;
116 break;
117 }
118 }
119
120 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
121 Opts.BCPLComment = Std.hasBCPLComments();
122 Opts.C99 = Std.isC99();
123 Opts.CPlusPlus = Std.isCPlusPlus();
124 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
125 Opts.Digraphs = Std.hasDigraphs();
126 Opts.GNUMode = Std.isGNUMode();
127 Opts.GNUInline = !Std.isC99();
128 Opts.HexFloats = Std.hasHexFloats();
129 Opts.ImplicitInt = Std.hasImplicitInt();
130
131 // OpenCL has some additional defaults.
132 if (LangStd == LangStandard::lang_opencl) {
133 Opts.OpenCL = 1;
134 Opts.AltiVec = 1;
135 Opts.CXXOperatorNames = 1;
136 Opts.LaxVectorConversions = 1;
137 }
138
139 // OpenCL and C++ both have bool, true, false keywords.
140 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
141
142// if (Opts.CPlusPlus)
143// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
144//
145// if (Args.hasArg(OPT_fobjc_gc_only))
146// Opts.setGCMode(LangOptions::GCOnly);
147// else if (Args.hasArg(OPT_fobjc_gc))
148// Opts.setGCMode(LangOptions::HybridGC);
149//
150// if (Args.hasArg(OPT_print_ivar_layout))
151// Opts.ObjCGCBitmapPrint = 1;
152//
153// if (Args.hasArg(OPT_faltivec))
154// Opts.AltiVec = 1;
155//
156// if (Args.hasArg(OPT_pthread))
157// Opts.POSIXThreads = 1;
158//
159// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
160// "default");
161// if (Vis == "default")
162 Opts.setVisibilityMode(LangOptions::Default);
163// else if (Vis == "hidden")
164// Opts.setVisibilityMode(LangOptions::Hidden);
165// else if (Vis == "protected")
166// Opts.setVisibilityMode(LangOptions::Protected);
167// else
168// Diags.Report(diag::err_drv_invalid_value)
169// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
170
171// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
172
173 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
174 // is specified, or -std is set to a conforming mode.
175 Opts.Trigraphs = !Opts.GNUMode;
176// if (Args.hasArg(OPT_trigraphs))
177// Opts.Trigraphs = 1;
178//
179// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
180// OPT_fno_dollars_in_identifiers,
181// !Opts.AsmPreprocessor);
182// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
183// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
184// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
185// if (Args.hasArg(OPT_fno_lax_vector_conversions))
186// Opts.LaxVectorConversions = 0;
187// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
188// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
189// Opts.Blocks = Args.hasArg(OPT_fblocks);
190// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
191// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
192// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
193// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
194// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
195// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
196// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
197// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
198// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
199// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
200// Diags);
201// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
202// Opts.ObjCConstantStringClass = getLastArgValue(Args,
203// OPT_fconstant_string_class);
204// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
205// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
206// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
207// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
208// Opts.Static = Args.hasArg(OPT_static_define);
209 Opts.OptimizeSize = 0;
210
211 // FIXME: Eliminate this dependency.
212// unsigned Opt =
213// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
214// Opts.Optimize = Opt != 0;
215 unsigned Opt = 0;
216
217 // This is the __NO_INLINE__ define, which just depends on things like the
218 // optimization level and -fno-inline, not actually whether the backend has
219 // inlining enabled.
220 //
221 // FIXME: This is affected by other options (-fno-inline).
222 Opts.NoInline = !Opt;
223
224// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
225// switch (SSP) {
226// default:
227// Diags.Report(diag::err_drv_invalid_value)
228// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
229// break;
230// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
231// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
232// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
233// }
234}
235
Chris Lattner24943d22010-06-08 16:52:24 +0000236
Chris Lattner24943d22010-06-08 16:52:24 +0000237ClangASTContext::ClangASTContext(const char *target_triple) :
238 m_target_triple(),
239 m_ast_context_ap(),
240 m_language_options_ap(),
241 m_source_manager_ap(),
242 m_diagnostic_ap(),
243 m_target_options_ap(),
244 m_target_info_ap(),
245 m_identifier_table_ap(),
246 m_selector_table_ap(),
247 m_builtins_ap()
248{
249 if (target_triple && target_triple[0])
250 m_target_triple.assign (target_triple);
251}
252
253//----------------------------------------------------------------------
254// Destructor
255//----------------------------------------------------------------------
256ClangASTContext::~ClangASTContext()
257{
258 m_builtins_ap.reset();
259 m_selector_table_ap.reset();
260 m_identifier_table_ap.reset();
261 m_target_info_ap.reset();
262 m_target_options_ap.reset();
263 m_diagnostic_ap.reset();
264 m_source_manager_ap.reset();
265 m_language_options_ap.reset();
266 m_ast_context_ap.reset();
267}
268
269
270void
271ClangASTContext::Clear()
272{
273 m_ast_context_ap.reset();
274 m_language_options_ap.reset();
275 m_source_manager_ap.reset();
276 m_diagnostic_ap.reset();
277 m_target_options_ap.reset();
278 m_target_info_ap.reset();
279 m_identifier_table_ap.reset();
280 m_selector_table_ap.reset();
281 m_builtins_ap.reset();
282}
283
284const char *
285ClangASTContext::GetTargetTriple ()
286{
287 return m_target_triple.c_str();
288}
289
290void
291ClangASTContext::SetTargetTriple (const char *target_triple)
292{
293 Clear();
294 m_target_triple.assign(target_triple);
295}
296
297
298ASTContext *
299ClangASTContext::getASTContext()
300{
301 if (m_ast_context_ap.get() == NULL)
302 {
303 m_ast_context_ap.reset(
304 new ASTContext(
305 *getLanguageOptions(),
306 *getSourceManager(),
307 *getTargetInfo(),
308 *getIdentifierTable(),
309 *getSelectorTable(),
Greg Clayton6e713402010-07-30 20:30:44 +0000310 *getBuiltinContext(),
311 0));
Chris Lattner24943d22010-06-08 16:52:24 +0000312 }
313 return m_ast_context_ap.get();
314}
315
316Builtin::Context *
317ClangASTContext::getBuiltinContext()
318{
319 if (m_builtins_ap.get() == NULL)
320 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
321 return m_builtins_ap.get();
322}
323
324IdentifierTable *
325ClangASTContext::getIdentifierTable()
326{
327 if (m_identifier_table_ap.get() == NULL)
328 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
329 return m_identifier_table_ap.get();
330}
331
332LangOptions *
333ClangASTContext::getLanguageOptions()
334{
335 if (m_language_options_ap.get() == NULL)
336 {
337 m_language_options_ap.reset(new LangOptions());
Greg Claytone41c4b22010-06-13 17:34:29 +0000338 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
339// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner24943d22010-06-08 16:52:24 +0000340 }
341 return m_language_options_ap.get();
342}
343
344SelectorTable *
345ClangASTContext::getSelectorTable()
346{
347 if (m_selector_table_ap.get() == NULL)
348 m_selector_table_ap.reset (new SelectorTable());
349 return m_selector_table_ap.get();
350}
351
Greg Clayton1674b122010-07-21 22:12:05 +0000352clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000353ClangASTContext::getSourceManager()
354{
355 if (m_source_manager_ap.get() == NULL)
Greg Clayton1674b122010-07-21 22:12:05 +0000356 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic()));
Chris Lattner24943d22010-06-08 16:52:24 +0000357 return m_source_manager_ap.get();
358}
359
360Diagnostic *
361ClangASTContext::getDiagnostic()
362{
363 if (m_diagnostic_ap.get() == NULL)
364 m_diagnostic_ap.reset(new Diagnostic());
365 return m_diagnostic_ap.get();
366}
367
368TargetOptions *
369ClangASTContext::getTargetOptions()
370{
371 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
372 {
373 m_target_options_ap.reset (new TargetOptions());
374 if (m_target_options_ap.get())
375 m_target_options_ap->Triple = m_target_triple;
376 }
377 return m_target_options_ap.get();
378}
379
380
381TargetInfo *
382ClangASTContext::getTargetInfo()
383{
384 // target_triple should be something like "x86_64-apple-darwin10"
385 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
386 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
387 return m_target_info_ap.get();
388}
389
390#pragma mark Basic Types
391
392static inline bool
393QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
394{
395 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
396 if (qual_type_bit_size == bit_size)
397 return true;
398 return false;
399}
400
Greg Clayton462d4142010-09-29 01:12:09 +0000401clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000402ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000403{
404 ASTContext *ast_context = getASTContext();
405
406 assert (ast_context != NULL);
407
408 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
409}
410
Greg Clayton462d4142010-09-29 01:12:09 +0000411clang_type_t
412ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000413{
414 if (!ast_context)
415 return NULL;
416
417 switch (encoding)
418 {
Greg Clayton585660c2010-08-05 01:57:25 +0000419 case eEncodingInvalid:
Chris Lattner24943d22010-06-08 16:52:24 +0000420 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
421 return ast_context->VoidPtrTy.getAsOpaquePtr();
422 break;
423
Greg Clayton585660c2010-08-05 01:57:25 +0000424 case eEncodingUint:
Chris Lattner24943d22010-06-08 16:52:24 +0000425 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
426 return ast_context->UnsignedCharTy.getAsOpaquePtr();
427 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
428 return ast_context->UnsignedShortTy.getAsOpaquePtr();
429 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
430 return ast_context->UnsignedIntTy.getAsOpaquePtr();
431 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
432 return ast_context->UnsignedLongTy.getAsOpaquePtr();
433 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
434 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
435 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
436 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
437 break;
438
Greg Clayton585660c2010-08-05 01:57:25 +0000439 case eEncodingSint:
Chris Lattner24943d22010-06-08 16:52:24 +0000440 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
441 return ast_context->CharTy.getAsOpaquePtr();
442 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
443 return ast_context->ShortTy.getAsOpaquePtr();
444 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
445 return ast_context->IntTy.getAsOpaquePtr();
446 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
447 return ast_context->LongTy.getAsOpaquePtr();
448 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
449 return ast_context->LongLongTy.getAsOpaquePtr();
450 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
451 return ast_context->Int128Ty.getAsOpaquePtr();
452 break;
453
Greg Clayton585660c2010-08-05 01:57:25 +0000454 case eEncodingIEEE754:
Chris Lattner24943d22010-06-08 16:52:24 +0000455 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
456 return ast_context->FloatTy.getAsOpaquePtr();
457 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
458 return ast_context->DoubleTy.getAsOpaquePtr();
459 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
460 return ast_context->LongDoubleTy.getAsOpaquePtr();
461 break;
462
Greg Clayton585660c2010-08-05 01:57:25 +0000463 case eEncodingVector:
Chris Lattner24943d22010-06-08 16:52:24 +0000464 default:
465 break;
466 }
467
468 return NULL;
469}
470
Greg Clayton462d4142010-09-29 01:12:09 +0000471clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000472ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
473{
474 ASTContext *ast_context = getASTContext();
475
476 #define streq(a,b) strcmp(a,b) == 0
477 assert (ast_context != NULL);
478 if (ast_context)
479 {
480 switch (dw_ate)
481 {
482 default:
483 break;
484
485 case DW_ATE_address:
486 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
487 return ast_context->VoidPtrTy.getAsOpaquePtr();
488 break;
489
490 case DW_ATE_boolean:
491 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
492 return ast_context->BoolTy.getAsOpaquePtr();
493 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
494 return ast_context->UnsignedCharTy.getAsOpaquePtr();
495 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
496 return ast_context->UnsignedShortTy.getAsOpaquePtr();
497 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
498 return ast_context->UnsignedIntTy.getAsOpaquePtr();
499 break;
500
501 case DW_ATE_complex_float:
502 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
503 return ast_context->FloatComplexTy.getAsOpaquePtr();
504 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
505 return ast_context->DoubleComplexTy.getAsOpaquePtr();
506 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
507 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
508 break;
509
510 case DW_ATE_float:
511 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
512 return ast_context->FloatTy.getAsOpaquePtr();
513 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
514 return ast_context->DoubleTy.getAsOpaquePtr();
515 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
516 return ast_context->LongDoubleTy.getAsOpaquePtr();
517 break;
518
519 case DW_ATE_signed:
520 if (type_name)
521 {
522 if (streq(type_name, "int") ||
523 streq(type_name, "signed int"))
524 {
525 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
526 return ast_context->IntTy.getAsOpaquePtr();
527 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
528 return ast_context->Int128Ty.getAsOpaquePtr();
529 }
530
531 if (streq(type_name, "long int") ||
532 streq(type_name, "long long int") ||
533 streq(type_name, "signed long long"))
534 {
535 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
536 return ast_context->LongTy.getAsOpaquePtr();
537 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
538 return ast_context->LongLongTy.getAsOpaquePtr();
539 }
540
541 if (streq(type_name, "short") ||
542 streq(type_name, "short int") ||
543 streq(type_name, "signed short") ||
544 streq(type_name, "short signed int"))
545 {
546 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
547 return ast_context->ShortTy.getAsOpaquePtr();
548 }
549
550 if (streq(type_name, "char") ||
551 streq(type_name, "signed char"))
552 {
553 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
554 return ast_context->CharTy.getAsOpaquePtr();
555 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
556 return ast_context->SignedCharTy.getAsOpaquePtr();
557 }
558
559 if (streq(type_name, "wchar_t"))
560 {
561 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
562 return ast_context->WCharTy.getAsOpaquePtr();
563 }
564
565 }
566 // We weren't able to match up a type name, just search by size
567 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
568 return ast_context->CharTy.getAsOpaquePtr();
569 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
570 return ast_context->ShortTy.getAsOpaquePtr();
571 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
572 return ast_context->IntTy.getAsOpaquePtr();
573 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
574 return ast_context->LongTy.getAsOpaquePtr();
575 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
576 return ast_context->LongLongTy.getAsOpaquePtr();
577 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
578 return ast_context->Int128Ty.getAsOpaquePtr();
579 break;
580
581 case DW_ATE_signed_char:
582 if (type_name)
583 {
584 if (streq(type_name, "signed char"))
585 {
586 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
587 return ast_context->SignedCharTy.getAsOpaquePtr();
588 }
589 }
590 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
591 return ast_context->CharTy.getAsOpaquePtr();
592 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
593 return ast_context->SignedCharTy.getAsOpaquePtr();
594 break;
595
596 case DW_ATE_unsigned:
597 if (type_name)
598 {
599 if (streq(type_name, "unsigned int"))
600 {
601 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
602 return ast_context->UnsignedIntTy.getAsOpaquePtr();
603 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
604 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
605 }
606
607 if (streq(type_name, "unsigned int") ||
608 streq(type_name, "long unsigned int") ||
609 streq(type_name, "unsigned long long"))
610 {
611 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
612 return ast_context->UnsignedLongTy.getAsOpaquePtr();
613 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
614 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
615 }
616
617 if (streq(type_name, "unsigned short") ||
618 streq(type_name, "short unsigned int"))
619 {
620 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
621 return ast_context->UnsignedShortTy.getAsOpaquePtr();
622 }
623 if (streq(type_name, "unsigned char"))
624 {
625 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
626 return ast_context->UnsignedCharTy.getAsOpaquePtr();
627 }
628
629 }
630 // We weren't able to match up a type name, just search by size
631 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
632 return ast_context->UnsignedCharTy.getAsOpaquePtr();
633 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
634 return ast_context->UnsignedShortTy.getAsOpaquePtr();
635 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
636 return ast_context->UnsignedIntTy.getAsOpaquePtr();
637 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
638 return ast_context->UnsignedLongTy.getAsOpaquePtr();
639 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
640 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
641 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
642 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
643 break;
644
645 case DW_ATE_unsigned_char:
646 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
647 return ast_context->UnsignedCharTy.getAsOpaquePtr();
648 break;
649
650 case DW_ATE_imaginary_float:
651 break;
652 }
653 }
654 // This assert should fire for anything that we don't catch above so we know
655 // to fix any issues we run into.
656 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
657 return NULL;
658}
659
Greg Clayton462d4142010-09-29 01:12:09 +0000660clang_type_t
661ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
Chris Lattner24943d22010-06-08 16:52:24 +0000662{
Sean Callanana751f7b2010-09-17 02:24:29 +0000663 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000664}
665
Greg Clayton462d4142010-09-29 01:12:09 +0000666clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000667ClangASTContext::GetBuiltInType_objc_id()
668{
669 return getASTContext()->getObjCIdType().getAsOpaquePtr();
670}
671
Greg Clayton462d4142010-09-29 01:12:09 +0000672clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000673ClangASTContext::GetBuiltInType_objc_Class()
674{
675 return getASTContext()->getObjCClassType().getAsOpaquePtr();
676}
677
Greg Clayton462d4142010-09-29 01:12:09 +0000678clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000679ClangASTContext::GetBuiltInType_objc_selector()
680{
681 return getASTContext()->getObjCSelType().getAsOpaquePtr();
682}
683
Greg Clayton462d4142010-09-29 01:12:09 +0000684clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000685ClangASTContext::GetCStringType (bool is_const)
686{
687 QualType char_type(getASTContext()->CharTy);
688
689 if (is_const)
690 char_type.addConst();
691
692 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
693}
694
Greg Clayton462d4142010-09-29 01:12:09 +0000695clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000696ClangASTContext::GetVoidPtrType (bool is_const)
697{
698 return GetVoidPtrType(getASTContext(), is_const);
699}
700
Greg Clayton462d4142010-09-29 01:12:09 +0000701clang_type_t
702ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
Chris Lattner24943d22010-06-08 16:52:24 +0000703{
704 QualType void_ptr_type(ast_context->VoidPtrTy);
705
706 if (is_const)
707 void_ptr_type.addConst();
708
709 return void_ptr_type.getAsOpaquePtr();
710}
711
Greg Clayton462d4142010-09-29 01:12:09 +0000712clang_type_t
713ClangASTContext::CopyType (ASTContext *dest_context,
714 ASTContext *source_context,
715 clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000716{
717 Diagnostic diagnostics;
718 FileManager file_manager;
719 ASTImporter importer(diagnostics,
720 *dest_context, file_manager,
721 *source_context, file_manager);
722 QualType ret = importer.Import(QualType::getFromOpaquePtr(clang_type));
723 return ret.getAsOpaquePtr();
724}
725
Sean Callanan8d825062010-07-16 00:00:27 +0000726bool
Greg Clayton462d4142010-09-29 01:12:09 +0000727ClangASTContext::AreTypesSame(ASTContext *ast_context,
728 clang_type_t type1,
729 clang_type_t type2)
Sean Callanan5510ddd2010-07-15 22:30:52 +0000730{
731 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
732 QualType::getFromOpaquePtr(type2));
733}
734
Chris Lattner24943d22010-06-08 16:52:24 +0000735#pragma mark CVR modifiers
736
Greg Clayton462d4142010-09-29 01:12:09 +0000737clang_type_t
738ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000739{
740 if (clang_type)
741 {
742 QualType result(QualType::getFromOpaquePtr(clang_type));
743 result.addConst();
744 return result.getAsOpaquePtr();
745 }
746 return NULL;
747}
748
Greg Clayton462d4142010-09-29 01:12:09 +0000749clang_type_t
750ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000751{
752 if (clang_type)
753 {
754 QualType result(QualType::getFromOpaquePtr(clang_type));
755 result.getQualifiers().setRestrict (true);
756 return result.getAsOpaquePtr();
757 }
758 return NULL;
759}
760
Greg Clayton462d4142010-09-29 01:12:09 +0000761clang_type_t
762ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000763{
764 if (clang_type)
765 {
766 QualType result(QualType::getFromOpaquePtr(clang_type));
767 result.getQualifiers().setVolatile (true);
768 return result.getAsOpaquePtr();
769 }
770 return NULL;
771}
772
773#pragma mark Structure, Unions, Classes
774
Greg Clayton462d4142010-09-29 01:12:09 +0000775clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000776ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000777{
778 ASTContext *ast_context = getASTContext();
779 assert (ast_context != NULL);
780
781 if (decl_ctx == NULL)
782 decl_ctx = ast_context->getTranslationUnitDecl();
783
Greg Clayton9488b742010-07-28 02:04:09 +0000784
Greg Clayton585660c2010-08-05 01:57:25 +0000785 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000786 {
787 bool isForwardDecl = false;
788 bool isInternal = false;
789 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
790 }
791
Chris Lattner24943d22010-06-08 16:52:24 +0000792 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
793 // we will need to update this code. I was told to currently always use
794 // the CXXRecordDecl class since we often don't know from debug information
795 // if something is struct or a class, so we default to always use the more
796 // complete definition just in case.
797 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
798 (TagDecl::TagKind)kind,
799 decl_ctx,
800 SourceLocation(),
801 name && name[0] ? &ast_context->Idents.get(name) : NULL);
802
803 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
804}
805
Greg Clayton412440a2010-09-23 01:09:21 +0000806CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +0000807ClangASTContext::AddMethodToCXXRecordType
808(
Greg Clayton462d4142010-09-29 01:12:09 +0000809 ASTContext *ast_context,
810 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +0000811 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +0000812 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +0000813 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +0000814 bool is_virtual,
815 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +0000816 bool is_inline,
817 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +0000818)
Sean Callanan79523002010-09-17 02:58:26 +0000819{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000820 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +0000821 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +0000822
823 assert(ast_context);
824
825 IdentifierTable *identifier_table = &ast_context->Idents;
826
827 assert(identifier_table);
828
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000829 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +0000830
831 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +0000832
Greg Clayton1d8173f2010-09-24 05:15:53 +0000833 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +0000834 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +0000835
Greg Clayton1d8173f2010-09-24 05:15:53 +0000836 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +0000837
Greg Clayton1d8173f2010-09-24 05:15:53 +0000838 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +0000839 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +0000840
Greg Clayton1d8173f2010-09-24 05:15:53 +0000841 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +0000842
Greg Clayton1d8173f2010-09-24 05:15:53 +0000843 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +0000844 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +0000845
846 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
847
Greg Clayton1d8173f2010-09-24 05:15:53 +0000848 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +0000849 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +0000850
Greg Clayton1d8173f2010-09-24 05:15:53 +0000851 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000852
Greg Clayton30449d52010-10-01 02:31:07 +0000853 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +0000854
Greg Clayton30449d52010-10-01 02:31:07 +0000855 DeclarationName decl_name (&identifier_table->get(name));
856
857 if (name[0] == '~' || decl_name == record_decl->getDeclName())
858 {
859 bool is_implicitly_declared = false;
860 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
861 cxx_record_decl,
862 DeclarationNameInfo (decl_name, SourceLocation()),
863 method_qual_type,
864 NULL, // TypeSourceInfo *
865 is_explicit,
866 is_inline,
867 is_implicitly_declared);
868 }
869 else
870 {
871 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
872 cxx_record_decl,
873 DeclarationNameInfo (decl_name, SourceLocation()),
874 method_qual_type,
875 NULL, // TypeSourceInfo *
876 is_static,
877 SC_None,
878 is_inline);
879 }
880
Sean Callanan47a5c4c2010-09-23 03:01:22 +0000881
Greg Clayton462d4142010-09-29 01:12:09 +0000882 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +0000883
884 cxx_method_decl->setAccess (access_specifier);
885 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +0000886
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000887 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000888 clang::Type *method_type(method_qual_type.getTypePtr());
889
Greg Clayton1d8173f2010-09-24 05:15:53 +0000890 if (method_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +0000891 return NULL;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000892
Greg Clayton1d8173f2010-09-24 05:15:53 +0000893 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000894
Greg Clayton1d8173f2010-09-24 05:15:53 +0000895 if (!method_function_prototype)
Greg Clayton412440a2010-09-23 01:09:21 +0000896 return NULL;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000897
Greg Clayton1d8173f2010-09-24 05:15:53 +0000898 unsigned int num_params = method_function_prototype->getNumArgs();
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000899
900 ParmVarDecl *params[num_params];
901
902 for (int param_index = 0;
903 param_index < num_params;
904 ++param_index)
905 {
Greg Clayton1d8173f2010-09-24 05:15:53 +0000906 params[param_index] = ParmVarDecl::Create (*ast_context,
907 cxx_method_decl,
908 SourceLocation(),
909 NULL, // anonymous
910 method_function_prototype->getArgType(param_index),
911 NULL,
912 SC_None,
913 SC_None,
914 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000915 }
916
Greg Clayton1d8173f2010-09-24 05:15:53 +0000917 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000918
Greg Clayton1d8173f2010-09-24 05:15:53 +0000919 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +0000920
Greg Clayton412440a2010-09-23 01:09:21 +0000921 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +0000922}
923
924bool
Greg Clayton84f80752010-07-22 18:30:50 +0000925ClangASTContext::AddFieldToRecordType
926(
Greg Clayton462d4142010-09-29 01:12:09 +0000927 ASTContext *ast_context,
928 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +0000929 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +0000930 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +0000931 AccessType access,
932 uint32_t bitfield_bit_size
933)
Chris Lattner24943d22010-06-08 16:52:24 +0000934{
935 if (record_clang_type == NULL || field_type == NULL)
936 return false;
937
Sean Callanan60a0ced2010-09-16 20:01:08 +0000938 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +0000939
940 assert (ast_context != NULL);
941 assert (identifier_table != NULL);
942
943 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
944
Greg Clayton1674b122010-07-21 22:12:05 +0000945 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000946 if (clang_type)
947 {
948 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
949
950 if (record_type)
951 {
952 RecordDecl *record_decl = record_type->getDecl();
953
Chris Lattner24943d22010-06-08 16:52:24 +0000954 clang::Expr *bit_width = NULL;
955 if (bitfield_bit_size != 0)
956 {
957 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +0000958 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +0000959 }
Greg Clayton84f80752010-07-22 18:30:50 +0000960 FieldDecl *field = FieldDecl::Create (*ast_context,
961 record_decl,
962 SourceLocation(),
963 name ? &identifier_table->get(name) : NULL, // Identifier
964 QualType::getFromOpaquePtr(field_type), // Field type
965 NULL, // DeclaratorInfo *
966 bit_width, // BitWidth
967 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +0000968
Greg Clayton84f80752010-07-22 18:30:50 +0000969 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +0000970
971 if (field)
972 {
973 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +0000974 }
975 }
Greg Clayton9488b742010-07-28 02:04:09 +0000976 else
977 {
978 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
979 if (objc_class_type)
980 {
Greg Clayton1d8173f2010-09-24 05:15:53 +0000981 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +0000982 ClangASTContext::AddObjCClassIVar (ast_context,
983 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +0000984 name,
985 field_type,
986 access,
987 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +0000988 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +0000989 }
990 }
Chris Lattner24943d22010-06-08 16:52:24 +0000991 }
992 return false;
993}
994
995bool
996ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
997{
998 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
999}
1000
1001bool
1002ClangASTContext::FieldIsBitfield
1003(
1004 ASTContext *ast_context,
1005 FieldDecl* field,
1006 uint32_t& bitfield_bit_size
1007)
1008{
1009 if (ast_context == NULL || field == NULL)
1010 return false;
1011
1012 if (field->isBitField())
1013 {
1014 Expr* bit_width_expr = field->getBitWidth();
1015 if (bit_width_expr)
1016 {
1017 llvm::APSInt bit_width_apsint;
1018 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1019 {
1020 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1021 return true;
1022 }
1023 }
1024 }
1025 return false;
1026}
1027
1028bool
1029ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1030{
1031 if (record_decl == NULL)
1032 return false;
1033
1034 if (!record_decl->field_empty())
1035 return true;
1036
1037 // No fields, lets check this is a CXX record and check the base classes
1038 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1039 if (cxx_record_decl)
1040 {
1041 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1042 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1043 base_class != base_class_end;
1044 ++base_class)
1045 {
1046 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1047 if (RecordHasFields(base_class_decl))
1048 return true;
1049 }
1050 }
1051 return false;
1052}
1053
1054void
Greg Clayton462d4142010-09-29 01:12:09 +00001055ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner24943d22010-06-08 16:52:24 +00001056{
1057 if (clang_qual_type)
1058 {
1059 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001060 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001061 if (clang_type)
1062 {
1063 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1064 if (record_type)
1065 {
1066 RecordDecl *record_decl = record_type->getDecl();
1067 if (record_decl)
1068 {
1069 uint32_t field_idx;
1070 RecordDecl::field_iterator field, field_end;
1071 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1072 field != field_end;
1073 ++field, ++field_idx)
1074 {
1075 // If no accessibility was assigned, assign the correct one
1076 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1077 field->setAccess ((AccessSpecifier)default_accessibility);
1078 }
1079 }
1080 }
1081 }
1082 }
1083}
1084
1085#pragma mark C++ Base Classes
1086
1087CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001088ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001089{
1090 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001091 return new CXXBaseSpecifier (SourceRange(),
1092 is_virtual,
1093 base_of_class,
1094 ConvertAccessTypeToAccessSpecifier (access),
1095 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001096 return NULL;
1097}
1098
Greg Claytone9d0df42010-07-02 01:29:13 +00001099void
1100ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1101{
1102 for (unsigned i=0; i<num_base_classes; ++i)
1103 {
1104 delete base_classes[i];
1105 base_classes[i] = NULL;
1106 }
1107}
1108
Chris Lattner24943d22010-06-08 16:52:24 +00001109bool
Greg Clayton462d4142010-09-29 01:12:09 +00001110ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001111{
1112 if (class_clang_type)
1113 {
Greg Clayton1674b122010-07-21 22:12:05 +00001114 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001115 if (clang_type)
1116 {
1117 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1118 if (record_type)
1119 {
1120 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1121 if (cxx_record_decl)
1122 {
Chris Lattner24943d22010-06-08 16:52:24 +00001123 cxx_record_decl->setBases(base_classes, num_base_classes);
1124 return true;
1125 }
1126 }
1127 }
1128 }
1129 return false;
1130}
Greg Clayton84f80752010-07-22 18:30:50 +00001131#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001132
Greg Clayton462d4142010-09-29 01:12:09 +00001133clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001134ClangASTContext::CreateObjCClass
1135(
1136 const char *name,
1137 DeclContext *decl_ctx,
1138 bool isForwardDecl,
1139 bool isInternal
1140)
1141{
1142 ASTContext *ast_context = getASTContext();
1143 assert (ast_context != NULL);
1144 assert (name && name[0]);
1145 if (decl_ctx == NULL)
1146 decl_ctx = ast_context->getTranslationUnitDecl();
1147
1148 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1149 // we will need to update this code. I was told to currently always use
1150 // the CXXRecordDecl class since we often don't know from debug information
1151 // if something is struct or a class, so we default to always use the more
1152 // complete definition just in case.
1153 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1154 decl_ctx,
1155 SourceLocation(),
1156 &ast_context->Idents.get(name),
1157 SourceLocation(),
1158 isForwardDecl,
1159 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001160
1161 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001162}
1163
1164bool
Greg Clayton462d4142010-09-29 01:12:09 +00001165ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001166{
1167 if (class_opaque_type && super_opaque_type)
1168 {
1169 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1170 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1171 clang::Type *class_type = class_qual_type.getTypePtr();
1172 clang::Type *super_type = super_qual_type.getTypePtr();
1173 if (class_type && super_type)
1174 {
1175 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1176 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1177 if (objc_class_type && objc_super_type)
1178 {
1179 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1180 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1181 if (class_interface_decl && super_interface_decl)
1182 {
1183 class_interface_decl->setSuperClass(super_interface_decl);
1184 return true;
1185 }
1186 }
1187 }
1188 }
1189 return false;
1190}
1191
1192
1193bool
1194ClangASTContext::AddObjCClassIVar
1195(
Greg Clayton462d4142010-09-29 01:12:09 +00001196 ASTContext *ast_context,
1197 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001198 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001199 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001200 AccessType access,
1201 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001202 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001203)
1204{
1205 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1206 return false;
1207
Sean Callanan60a0ced2010-09-16 20:01:08 +00001208 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001209
1210 assert (ast_context != NULL);
1211 assert (identifier_table != NULL);
1212
1213 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1214
1215 clang::Type *class_type = class_qual_type.getTypePtr();
1216 if (class_type)
1217 {
1218 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1219
1220 if (objc_class_type)
1221 {
1222 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1223
1224 if (class_interface_decl)
1225 {
1226 clang::Expr *bit_width = NULL;
1227 if (bitfield_bit_size != 0)
1228 {
1229 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001230 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001231 }
1232
Greg Clayton9488b742010-07-28 02:04:09 +00001233 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1234 class_interface_decl,
1235 SourceLocation(),
1236 &identifier_table->get(name), // Identifier
1237 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1238 NULL, // TypeSourceInfo *
1239 ConvertAccessTypeToObjCIvarAccessControl (access),
1240 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001241 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001242
1243 if (field)
1244 {
1245 class_interface_decl->addDecl(field);
1246 return true;
1247 }
Greg Clayton84f80752010-07-22 18:30:50 +00001248 }
1249 }
1250 }
1251 return false;
1252}
Chris Lattner24943d22010-06-08 16:52:24 +00001253
Greg Clayton9488b742010-07-28 02:04:09 +00001254
1255bool
Greg Clayton462d4142010-09-29 01:12:09 +00001256ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001257{
1258 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1259
1260 clang::Type *class_type = class_qual_type.getTypePtr();
1261 if (class_type)
1262 {
1263 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1264
1265 if (objc_class_type)
1266 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1267 }
1268 return false;
1269}
1270
1271bool
1272ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1273{
1274 while (class_interface_decl)
1275 {
1276 if (class_interface_decl->ivar_size() > 0)
1277 return true;
1278
1279 if (check_superclass)
1280 class_interface_decl = class_interface_decl->getSuperClass();
1281 else
1282 break;
1283 }
1284 return false;
1285}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001286
Greg Clayton462d4142010-09-29 01:12:09 +00001287ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001288ClangASTContext::AddMethodToObjCObjectType
1289(
Greg Clayton462d4142010-09-29 01:12:09 +00001290 ASTContext *ast_context,
1291 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001292 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001293 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001294 lldb::AccessType access
1295)
1296{
1297 if (class_opaque_type == NULL || method_opaque_type == NULL)
1298 return NULL;
1299
1300 IdentifierTable *identifier_table = &ast_context->Idents;
1301
1302 assert (ast_context != NULL);
1303 assert (identifier_table != NULL);
1304
1305 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1306
1307 clang::Type *class_type = class_qual_type.getTypePtr();
1308 if (class_type == NULL)
1309 return NULL;
1310
1311 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1312
1313 if (objc_class_type == NULL)
1314 return NULL;
1315
1316 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1317
1318 if (class_interface_decl == NULL)
1319 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001320
Greg Clayton1d8173f2010-09-24 05:15:53 +00001321 const char *selector_start = ::strchr (name, ' ');
1322 if (selector_start == NULL)
1323 return NULL;
1324
1325 selector_start++;
1326 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1327 return NULL;
1328 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1329
1330 size_t len;
1331 const char *start;
1332 for (start = selector_start, len = ::strcspn(start, ":]");
1333 start && *start != '\0' && *start != ']';
1334 start += len + 1)
1335 {
1336 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
1337 }
1338
1339
1340 if (selector_idents.size() == 0)
1341 return 0;
1342
1343 clang::Selector method_selector = ast_context->Selectors.getSelector (selector_idents.size(),
1344 selector_idents.data());
1345
1346 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1347
1348 // Populate the method decl with parameter decls
1349 clang::Type *method_type(method_qual_type.getTypePtr());
1350
1351 if (method_type == NULL)
1352 return NULL;
1353
1354 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1355
1356 if (!method_function_prototype)
1357 return NULL;
1358
1359
1360 bool is_variadic = false;
1361 bool is_synthesized = false;
1362 bool is_defined = false;
1363 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1364
1365 const unsigned num_args = method_function_prototype->getNumArgs();
1366
1367 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1368 SourceLocation(), // beginLoc,
1369 SourceLocation(), // endLoc,
1370 method_selector,
1371 method_function_prototype->getResultType(),
1372 NULL, // TypeSourceInfo *ResultTInfo,
1373 GetDeclContextForType (class_opaque_type),
1374 name[0] == '-',
1375 is_variadic,
1376 is_synthesized,
1377 is_defined,
1378 imp_control,
1379 num_args);
1380
1381
1382 if (objc_method_decl == NULL)
1383 return NULL;
1384
1385 if (num_args > 0)
1386 {
1387 llvm::SmallVector<ParmVarDecl *, 12> params;
1388
1389 for (int param_index = 0; param_index < num_args; ++param_index)
1390 {
1391 params.push_back (ParmVarDecl::Create (*ast_context,
1392 objc_method_decl,
1393 SourceLocation(),
1394 NULL, // anonymous
1395 method_function_prototype->getArgType(param_index),
1396 NULL,
1397 SC_Auto,
1398 SC_Auto,
1399 NULL));
1400 }
1401
1402 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1403 }
1404
1405 class_interface_decl->addDecl (objc_method_decl);
1406
1407
1408 return objc_method_decl;
1409}
1410
1411
Greg Clayton9488b742010-07-28 02:04:09 +00001412
Chris Lattner24943d22010-06-08 16:52:24 +00001413#pragma mark Aggregate Types
1414
1415bool
Greg Clayton462d4142010-09-29 01:12:09 +00001416ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001417{
1418 if (clang_type == NULL)
1419 return false;
1420
1421 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1422
1423 if (qual_type->isAggregateType ())
1424 return true;
1425
Greg Clayton03e0f972010-09-13 03:32:57 +00001426 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1427 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001428 {
Greg Clayton1674b122010-07-21 22:12:05 +00001429 case clang::Type::IncompleteArray:
1430 case clang::Type::VariableArray:
1431 case clang::Type::ConstantArray:
1432 case clang::Type::ExtVector:
1433 case clang::Type::Vector:
1434 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001435 case clang::Type::ObjCObject:
1436 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001437 return true;
1438
Greg Clayton1674b122010-07-21 22:12:05 +00001439 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001440 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1441
1442 default:
1443 break;
1444 }
1445 // The clang type does have a value
1446 return false;
1447}
1448
1449uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001450ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001451{
1452 if (clang_qual_type == NULL)
1453 return 0;
1454
1455 uint32_t num_children = 0;
1456 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001457 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1458 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001459 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001460 case clang::Type::Builtin:
1461 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1462 {
1463 case clang::BuiltinType::ObjCId: // Child is Class
1464 case clang::BuiltinType::ObjCClass: // child is Class
1465 case clang::BuiltinType::ObjCSel: // child is const char *
1466 num_children = 1;
1467
1468 default:
1469 break;
1470 }
1471 break;
1472
Greg Clayton1674b122010-07-21 22:12:05 +00001473 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001474 {
1475 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1476 const RecordDecl *record_decl = record_type->getDecl();
1477 assert(record_decl);
1478 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1479 if (cxx_record_decl)
1480 {
1481 if (omit_empty_base_classes)
1482 {
1483 // Check each base classes to see if it or any of its
1484 // base classes contain any fields. This can help
1485 // limit the noise in variable views by not having to
1486 // show base classes that contain no members.
1487 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1488 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1489 base_class != base_class_end;
1490 ++base_class)
1491 {
1492 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1493
1494 // Skip empty base classes
1495 if (RecordHasFields(base_class_decl) == false)
1496 continue;
1497
1498 num_children++;
1499 }
1500 }
1501 else
1502 {
1503 // Include all base classes
1504 num_children += cxx_record_decl->getNumBases();
1505 }
1506
1507 }
1508 RecordDecl::field_iterator field, field_end;
1509 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1510 ++num_children;
1511 }
1512 break;
1513
Greg Clayton9488b742010-07-28 02:04:09 +00001514 case clang::Type::ObjCObject:
1515 case clang::Type::ObjCInterface:
1516 {
1517 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1518 assert (objc_class_type);
1519 if (objc_class_type)
1520 {
1521 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1522
1523 if (class_interface_decl)
1524 {
1525
1526 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1527 if (superclass_interface_decl)
1528 {
1529 if (omit_empty_base_classes)
1530 {
1531 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1532 ++num_children;
1533 }
1534 else
1535 ++num_children;
1536 }
1537
1538 num_children += class_interface_decl->ivar_size();
1539 }
1540 }
1541 }
1542 break;
1543
1544 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001545 {
1546 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1547 QualType pointee_type = pointer_type->getPointeeType();
1548 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1549 omit_empty_base_classes);
1550 // If this type points to a simple type, then it has 1 child
1551 if (num_pointee_children == 0)
1552 num_children = 1;
1553 else
1554 num_children = num_pointee_children;
1555 }
1556 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001557
Greg Clayton1674b122010-07-21 22:12:05 +00001558 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001559 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
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>(qual_type.getTypePtr());
1565 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001566 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1567 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001568 // If this type points to a simple type, then it has 1 child
1569 if (num_pointee_children == 0)
1570 num_children = 1;
1571 else
1572 num_children = num_pointee_children;
1573 }
1574 break;
1575
Greg Clayton1674b122010-07-21 22:12:05 +00001576 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001577 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1578 break;
1579
1580 default:
1581 break;
1582 }
1583 return num_children;
1584}
1585
1586
Greg Clayton462d4142010-09-29 01:12:09 +00001587clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00001588ClangASTContext::GetChildClangTypeAtIndex
1589(
1590 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00001591 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00001592 uint32_t idx,
1593 bool transparent_pointers,
1594 bool omit_empty_base_classes,
1595 std::string& child_name,
1596 uint32_t &child_byte_size,
1597 int32_t &child_byte_offset,
1598 uint32_t &child_bitfield_bit_size,
1599 uint32_t &child_bitfield_bit_offset
1600)
1601{
1602 if (parent_clang_type)
1603
1604 return GetChildClangTypeAtIndex (getASTContext(),
1605 parent_name,
1606 parent_clang_type,
1607 idx,
1608 transparent_pointers,
1609 omit_empty_base_classes,
1610 child_name,
1611 child_byte_size,
1612 child_byte_offset,
1613 child_bitfield_bit_size,
1614 child_bitfield_bit_offset);
1615 return NULL;
1616}
1617
Greg Clayton462d4142010-09-29 01:12:09 +00001618clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00001619ClangASTContext::GetChildClangTypeAtIndex
1620(
1621 ASTContext *ast_context,
1622 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00001623 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00001624 uint32_t idx,
1625 bool transparent_pointers,
1626 bool omit_empty_base_classes,
1627 std::string& child_name,
1628 uint32_t &child_byte_size,
1629 int32_t &child_byte_offset,
1630 uint32_t &child_bitfield_bit_size,
1631 uint32_t &child_bitfield_bit_offset
1632)
1633{
1634 if (parent_clang_type == NULL)
1635 return NULL;
1636
1637 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
1638 {
1639 uint32_t bit_offset;
1640 child_bitfield_bit_size = 0;
1641 child_bitfield_bit_offset = 0;
1642 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00001643 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
1644 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001645 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001646 case clang::Type::Builtin:
1647 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
1648 {
1649 case clang::BuiltinType::ObjCId:
1650 case clang::BuiltinType::ObjCClass:
1651 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
1652
1653 case clang::BuiltinType::ObjCSel:
1654 {
1655 QualType char_type(ast_context->CharTy);
1656 char_type.addConst();
1657 return ast_context->getPointerType(char_type).getAsOpaquePtr();
1658 }
1659 break;
1660
1661 default:
1662 break;
1663 }
1664 break;
1665
1666
Greg Clayton1674b122010-07-21 22:12:05 +00001667 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001668 {
1669 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
1670 const RecordDecl *record_decl = record_type->getDecl();
1671 assert(record_decl);
1672 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
1673 uint32_t child_idx = 0;
1674
1675 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1676 if (cxx_record_decl)
1677 {
1678 // We might have base classes to print out first
1679 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1680 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1681 base_class != base_class_end;
1682 ++base_class)
1683 {
1684 const CXXRecordDecl *base_class_decl = NULL;
1685
1686 // Skip empty base classes
1687 if (omit_empty_base_classes)
1688 {
1689 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1690 if (RecordHasFields(base_class_decl) == false)
1691 continue;
1692 }
1693
1694 if (idx == child_idx)
1695 {
1696 if (base_class_decl == NULL)
1697 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1698
1699
1700 if (base_class->isVirtual())
1701 bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
1702 else
1703 bit_offset = record_layout.getBaseClassOffset(base_class_decl);
1704
1705 // Base classes should be a multiple of 8 bits in size
1706 assert (bit_offset % 8 == 0);
1707 child_byte_offset = bit_offset/8;
1708 std::string base_class_type_name(base_class->getType().getAsString());
1709
1710 child_name.assign(base_class_type_name.c_str());
1711
1712 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
1713
1714 // Base classes biut sizes should be a multiple of 8 bits in size
1715 assert (clang_type_info_bit_size % 8 == 0);
1716 child_byte_size = clang_type_info_bit_size / 8;
1717 return base_class->getType().getAsOpaquePtr();
1718 }
1719 // We don't increment the child index in the for loop since we might
1720 // be skipping empty base classes
1721 ++child_idx;
1722 }
1723 }
Chris Lattner24943d22010-06-08 16:52:24 +00001724 // Make sure index is in range...
1725 uint32_t field_idx = 0;
1726 RecordDecl::field_iterator field, field_end;
1727 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
1728 {
1729 if (idx == child_idx)
1730 {
1731 // Print the member type if requested
1732 // Print the member name and equal sign
1733 child_name.assign(field->getNameAsString().c_str());
1734
1735 // Figure out the type byte size (field_type_info.first) and
1736 // alignment (field_type_info.second) from the AST context.
1737 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00001738 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00001739
1740 child_byte_size = field_type_info.first / 8;
1741
1742 // Figure out the field offset within the current struct/union/class type
1743 bit_offset = record_layout.getFieldOffset (field_idx);
1744 child_byte_offset = bit_offset / 8;
1745 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
1746 child_bitfield_bit_offset = bit_offset % 8;
1747
1748 return field->getType().getAsOpaquePtr();
1749 }
1750 }
1751 }
1752 break;
1753
Greg Clayton9488b742010-07-28 02:04:09 +00001754 case clang::Type::ObjCObject:
1755 case clang::Type::ObjCInterface:
1756 {
1757 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
1758 assert (objc_class_type);
1759 if (objc_class_type)
1760 {
1761 uint32_t child_idx = 0;
1762 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1763
1764 if (class_interface_decl)
1765 {
1766
1767 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
1768 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1769 if (superclass_interface_decl)
1770 {
1771 if (omit_empty_base_classes)
1772 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001773 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00001774 {
1775 if (idx == 0)
1776 {
1777 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
1778
1779
1780 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
1781
1782 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
1783
1784 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00001785 child_byte_offset = 0;
Greg Clayton9488b742010-07-28 02:04:09 +00001786
1787 return ivar_qual_type.getAsOpaquePtr();
1788 }
1789
1790 ++child_idx;
1791 }
1792 }
1793 else
1794 ++child_idx;
1795 }
Greg Clayton960d6a42010-08-03 00:35:52 +00001796
1797 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00001798
1799 if (idx < (child_idx + class_interface_decl->ivar_size()))
1800 {
1801 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
1802
1803 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
1804 {
1805 if (child_idx == idx)
1806 {
1807 const ObjCIvarDecl* ivar_decl = *ivar_pos;
1808
1809 QualType ivar_qual_type(ivar_decl->getType());
1810
1811 child_name.assign(ivar_decl->getNameAsString().c_str());
1812
1813 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
1814
1815 child_byte_size = ivar_type_info.first / 8;
1816
1817 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00001818 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00001819 child_byte_offset = bit_offset / 8;
1820
1821 return ivar_qual_type.getAsOpaquePtr();
1822 }
1823 ++child_idx;
1824 }
1825 }
1826 }
1827 }
1828 }
1829 break;
1830
1831 case clang::Type::ObjCObjectPointer:
1832 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001833 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
1834 QualType pointee_type = pointer_type->getPointeeType();
1835
1836 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1837 {
1838 return GetChildClangTypeAtIndex (ast_context,
1839 parent_name,
1840 pointer_type->getPointeeType().getAsOpaquePtr(),
1841 idx,
1842 transparent_pointers,
1843 omit_empty_base_classes,
1844 child_name,
1845 child_byte_size,
1846 child_byte_offset,
1847 child_bitfield_bit_size,
1848 child_bitfield_bit_offset);
1849 }
1850 else
1851 {
1852 if (parent_name)
1853 {
1854 child_name.assign(1, '*');
1855 child_name += parent_name;
1856 }
1857
1858 // We have a pointer to an simple type
1859 if (idx == 0)
1860 {
1861 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1862 assert(clang_type_info.first % 8 == 0);
1863 child_byte_size = clang_type_info.first / 8;
1864 child_byte_offset = 0;
1865 return pointee_type.getAsOpaquePtr();
1866 }
1867 }
Greg Clayton9488b742010-07-28 02:04:09 +00001868 }
1869 break;
1870
Greg Clayton1674b122010-07-21 22:12:05 +00001871 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001872 {
1873 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
1874 const uint64_t element_count = array->getSize().getLimitedValue();
1875
1876 if (idx < element_count)
1877 {
1878 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
1879
1880 char element_name[32];
1881 ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
1882
1883 child_name.assign(element_name);
1884 assert(field_type_info.first % 8 == 0);
1885 child_byte_size = field_type_info.first / 8;
1886 child_byte_offset = idx * child_byte_size;
1887 return array->getElementType().getAsOpaquePtr();
1888 }
1889 }
1890 break;
1891
Greg Clayton1674b122010-07-21 22:12:05 +00001892 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001893 {
1894 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
1895 QualType pointee_type = pointer_type->getPointeeType();
1896
1897 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
1898 {
1899 return GetChildClangTypeAtIndex (ast_context,
1900 parent_name,
1901 pointer_type->getPointeeType().getAsOpaquePtr(),
1902 idx,
1903 transparent_pointers,
1904 omit_empty_base_classes,
1905 child_name,
1906 child_byte_size,
1907 child_byte_offset,
1908 child_bitfield_bit_size,
1909 child_bitfield_bit_offset);
1910 }
1911 else
1912 {
1913 if (parent_name)
1914 {
1915 child_name.assign(1, '*');
1916 child_name += parent_name;
1917 }
1918
1919 // We have a pointer to an simple type
1920 if (idx == 0)
1921 {
1922 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
1923 assert(clang_type_info.first % 8 == 0);
1924 child_byte_size = clang_type_info.first / 8;
1925 child_byte_offset = 0;
1926 return pointee_type.getAsOpaquePtr();
1927 }
1928 }
1929 }
1930 break;
1931
Greg Clayton1674b122010-07-21 22:12:05 +00001932 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001933 return GetChildClangTypeAtIndex (ast_context,
1934 parent_name,
1935 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1936 idx,
1937 transparent_pointers,
1938 omit_empty_base_classes,
1939 child_name,
1940 child_byte_size,
1941 child_byte_offset,
1942 child_bitfield_bit_size,
1943 child_bitfield_bit_offset);
1944 break;
1945
1946 default:
1947 break;
1948 }
1949 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00001950 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001951}
1952
1953static inline bool
1954BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
1955{
1956 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
1957}
1958
1959static uint32_t
1960GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
1961{
1962 uint32_t num_bases = 0;
1963 if (cxx_record_decl)
1964 {
1965 if (omit_empty_base_classes)
1966 {
1967 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1968 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1969 base_class != base_class_end;
1970 ++base_class)
1971 {
1972 // Skip empty base classes
1973 if (omit_empty_base_classes)
1974 {
1975 if (BaseSpecifierIsEmpty (base_class))
1976 continue;
1977 }
1978 ++num_bases;
1979 }
1980 }
1981 else
1982 num_bases = cxx_record_decl->getNumBases();
1983 }
1984 return num_bases;
1985}
1986
1987
1988static uint32_t
1989GetIndexForRecordBase
1990(
1991 const RecordDecl *record_decl,
1992 const CXXBaseSpecifier *base_spec,
1993 bool omit_empty_base_classes
1994)
1995{
1996 uint32_t child_idx = 0;
1997
1998 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1999
2000// const char *super_name = record_decl->getNameAsCString();
2001// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2002// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2003//
2004 if (cxx_record_decl)
2005 {
2006 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2007 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2008 base_class != base_class_end;
2009 ++base_class)
2010 {
2011 if (omit_empty_base_classes)
2012 {
2013 if (BaseSpecifierIsEmpty (base_class))
2014 continue;
2015 }
2016
2017// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2018// child_idx,
2019// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2020//
2021//
2022 if (base_class == base_spec)
2023 return child_idx;
2024 ++child_idx;
2025 }
2026 }
2027
2028 return UINT32_MAX;
2029}
2030
2031
2032static uint32_t
2033GetIndexForRecordChild
2034(
2035 const RecordDecl *record_decl,
2036 NamedDecl *canonical_decl,
2037 bool omit_empty_base_classes
2038)
2039{
2040 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2041
2042// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2043//
2044//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2045// if (cxx_record_decl)
2046// {
2047// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2048// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2049// base_class != base_class_end;
2050// ++base_class)
2051// {
2052// if (omit_empty_base_classes)
2053// {
2054// if (BaseSpecifierIsEmpty (base_class))
2055// continue;
2056// }
2057//
2058//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2059//// record_decl->getNameAsCString(),
2060//// canonical_decl->getNameAsCString(),
2061//// child_idx,
2062//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2063//
2064//
2065// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2066// if (curr_base_class_decl == canonical_decl)
2067// {
2068// return child_idx;
2069// }
2070// ++child_idx;
2071// }
2072// }
2073//
2074// const uint32_t num_bases = child_idx;
2075 RecordDecl::field_iterator field, field_end;
2076 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2077 field != field_end;
2078 ++field, ++child_idx)
2079 {
2080// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2081// record_decl->getNameAsCString(),
2082// canonical_decl->getNameAsCString(),
2083// child_idx - num_bases,
2084// field->getNameAsCString());
2085
2086 if (field->getCanonicalDecl() == canonical_decl)
2087 return child_idx;
2088 }
2089
2090 return UINT32_MAX;
2091}
2092
2093// Look for a child member (doesn't include base classes, but it does include
2094// their members) in the type hierarchy. Returns an index path into "clang_type"
2095// on how to reach the appropriate member.
2096//
2097// class A
2098// {
2099// public:
2100// int m_a;
2101// int m_b;
2102// };
2103//
2104// class B
2105// {
2106// };
2107//
2108// class C :
2109// public B,
2110// public A
2111// {
2112// };
2113//
2114// If we have a clang type that describes "class C", and we wanted to looked
2115// "m_b" in it:
2116//
2117// With omit_empty_base_classes == false we would get an integer array back with:
2118// { 1, 1 }
2119// The first index 1 is the child index for "class A" within class C
2120// The second index 1 is the child index for "m_b" within class A
2121//
2122// With omit_empty_base_classes == true we would get an integer array back with:
2123// { 0, 1 }
2124// 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)
2125// The second index 1 is the child index for "m_b" within class A
2126
2127size_t
2128ClangASTContext::GetIndexOfChildMemberWithName
2129(
2130 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002131 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002132 const char *name,
2133 bool omit_empty_base_classes,
2134 std::vector<uint32_t>& child_indexes
2135)
2136{
2137 if (clang_type && name && name[0])
2138 {
2139 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002140 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2141 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002142 {
Greg Clayton1674b122010-07-21 22:12:05 +00002143 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002144 {
2145 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2146 const RecordDecl *record_decl = record_type->getDecl();
2147
2148 assert(record_decl);
2149 uint32_t child_idx = 0;
2150
2151 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2152
2153 // Try and find a field that matches NAME
2154 RecordDecl::field_iterator field, field_end;
2155 StringRef name_sref(name);
2156 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2157 field != field_end;
2158 ++field, ++child_idx)
2159 {
2160 if (field->getName().equals (name_sref))
2161 {
2162 // We have to add on the number of base classes to this index!
2163 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2164 return child_indexes.size();
2165 }
2166 }
2167
2168 if (cxx_record_decl)
2169 {
2170 const RecordDecl *parent_record_decl = cxx_record_decl;
2171
2172 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2173
2174 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2175 // Didn't find things easily, lets let clang do its thang...
2176 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2177 DeclarationName decl_name(&ident_ref);
2178
2179 CXXBasePaths paths;
2180 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2181 decl_name.getAsOpaquePtr(),
2182 paths))
2183 {
Chris Lattner24943d22010-06-08 16:52:24 +00002184 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2185 for (path = paths.begin(); path != path_end; ++path)
2186 {
2187 const size_t num_path_elements = path->size();
2188 for (size_t e=0; e<num_path_elements; ++e)
2189 {
2190 CXXBasePathElement elem = (*path)[e];
2191
2192 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2193 if (child_idx == UINT32_MAX)
2194 {
2195 child_indexes.clear();
2196 return 0;
2197 }
2198 else
2199 {
2200 child_indexes.push_back (child_idx);
2201 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2202 }
2203 }
2204 DeclContext::lookup_iterator named_decl_pos;
2205 for (named_decl_pos = path->Decls.first;
2206 named_decl_pos != path->Decls.second && parent_record_decl;
2207 ++named_decl_pos)
2208 {
2209 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2210
2211 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2212 if (child_idx == UINT32_MAX)
2213 {
2214 child_indexes.clear();
2215 return 0;
2216 }
2217 else
2218 {
2219 child_indexes.push_back (child_idx);
2220 }
2221 }
2222 }
2223 return child_indexes.size();
2224 }
2225 }
2226
2227 }
2228 break;
2229
Greg Clayton9488b742010-07-28 02:04:09 +00002230 case clang::Type::ObjCObject:
2231 case clang::Type::ObjCInterface:
2232 {
2233 StringRef name_sref(name);
2234 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2235 assert (objc_class_type);
2236 if (objc_class_type)
2237 {
2238 uint32_t child_idx = 0;
2239 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2240
2241 if (class_interface_decl)
2242 {
2243 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2244 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2245
Greg Clayton823533e2010-09-18 02:11:07 +00002246 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002247 {
2248 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2249
2250 if (ivar_decl->getName().equals (name_sref))
2251 {
2252 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2253 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2254 ++child_idx;
2255
2256 child_indexes.push_back (child_idx);
2257 return child_indexes.size();
2258 }
2259 }
2260
2261 if (superclass_interface_decl)
2262 {
2263 // The super class index is always zero for ObjC classes,
2264 // so we push it onto the child indexes in case we find
2265 // an ivar in our superclass...
2266 child_indexes.push_back (0);
2267
2268 if (GetIndexOfChildMemberWithName (ast_context,
2269 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2270 name,
2271 omit_empty_base_classes,
2272 child_indexes))
2273 {
2274 // We did find an ivar in a superclass so just
2275 // return the results!
2276 return child_indexes.size();
2277 }
2278
2279 // We didn't find an ivar matching "name" in our
2280 // superclass, pop the superclass zero index that
2281 // we pushed on above.
2282 child_indexes.pop_back();
2283 }
2284 }
2285 }
2286 }
2287 break;
2288
2289 case clang::Type::ObjCObjectPointer:
2290 {
2291 return GetIndexOfChildMemberWithName (ast_context,
2292 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2293 name,
2294 omit_empty_base_classes,
2295 child_indexes);
2296 }
2297 break;
2298
2299
Greg Clayton1674b122010-07-21 22:12:05 +00002300 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002301 {
2302// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2303// const uint64_t element_count = array->getSize().getLimitedValue();
2304//
2305// if (idx < element_count)
2306// {
2307// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2308//
2309// char element_name[32];
2310// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2311//
2312// child_name.assign(element_name);
2313// assert(field_type_info.first % 8 == 0);
2314// child_byte_size = field_type_info.first / 8;
2315// child_byte_offset = idx * child_byte_size;
2316// return array->getElementType().getAsOpaquePtr();
2317// }
2318 }
2319 break;
2320
Greg Clayton1674b122010-07-21 22:12:05 +00002321// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002322// {
2323// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2324// QualType pointee_type = mem_ptr_type->getPointeeType();
2325//
2326// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2327// {
2328// return GetIndexOfChildWithName (ast_context,
2329// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2330// name);
2331// }
2332// }
2333// break;
2334//
Greg Clayton1674b122010-07-21 22:12:05 +00002335 case clang::Type::LValueReference:
2336 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002337 {
2338 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2339 QualType pointee_type = reference_type->getPointeeType();
2340
2341 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2342 {
2343 return GetIndexOfChildMemberWithName (ast_context,
2344 reference_type->getPointeeType().getAsOpaquePtr(),
2345 name,
2346 omit_empty_base_classes,
2347 child_indexes);
2348 }
2349 }
2350 break;
2351
Greg Clayton1674b122010-07-21 22:12:05 +00002352 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002353 {
2354 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2355 QualType pointee_type = pointer_type->getPointeeType();
2356
2357 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2358 {
2359 return GetIndexOfChildMemberWithName (ast_context,
2360 pointer_type->getPointeeType().getAsOpaquePtr(),
2361 name,
2362 omit_empty_base_classes,
2363 child_indexes);
2364 }
2365 else
2366 {
2367// if (parent_name)
2368// {
2369// child_name.assign(1, '*');
2370// child_name += parent_name;
2371// }
2372//
2373// // We have a pointer to an simple type
2374// if (idx == 0)
2375// {
2376// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2377// assert(clang_type_info.first % 8 == 0);
2378// child_byte_size = clang_type_info.first / 8;
2379// child_byte_offset = 0;
2380// return pointee_type.getAsOpaquePtr();
2381// }
2382 }
2383 }
2384 break;
2385
Greg Clayton1674b122010-07-21 22:12:05 +00002386 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002387 return GetIndexOfChildMemberWithName (ast_context,
2388 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2389 name,
2390 omit_empty_base_classes,
2391 child_indexes);
2392
2393 default:
2394 break;
2395 }
2396 }
2397 return 0;
2398}
2399
2400
2401// Get the index of the child of "clang_type" whose name matches. This function
2402// doesn't descend into the children, but only looks one level deep and name
2403// matches can include base class names.
2404
2405uint32_t
2406ClangASTContext::GetIndexOfChildWithName
2407(
2408 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002409 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002410 const char *name,
2411 bool omit_empty_base_classes
2412)
2413{
2414 if (clang_type && name && name[0])
2415 {
2416 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002417
Greg Clayton03e0f972010-09-13 03:32:57 +00002418 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002419
Greg Clayton03e0f972010-09-13 03:32:57 +00002420 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002421 {
Greg Clayton1674b122010-07-21 22:12:05 +00002422 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002423 {
2424 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2425 const RecordDecl *record_decl = record_type->getDecl();
2426
2427 assert(record_decl);
2428 uint32_t child_idx = 0;
2429
2430 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2431
2432 if (cxx_record_decl)
2433 {
2434 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2435 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2436 base_class != base_class_end;
2437 ++base_class)
2438 {
2439 // Skip empty base classes
2440 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2441 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2442 continue;
2443
2444 if (base_class->getType().getAsString().compare (name) == 0)
2445 return child_idx;
2446 ++child_idx;
2447 }
2448 }
2449
2450 // Try and find a field that matches NAME
2451 RecordDecl::field_iterator field, field_end;
2452 StringRef name_sref(name);
2453 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2454 field != field_end;
2455 ++field, ++child_idx)
2456 {
2457 if (field->getName().equals (name_sref))
2458 return child_idx;
2459 }
2460
2461 }
2462 break;
2463
Greg Clayton9488b742010-07-28 02:04:09 +00002464 case clang::Type::ObjCObject:
2465 case clang::Type::ObjCInterface:
2466 {
2467 StringRef name_sref(name);
2468 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2469 assert (objc_class_type);
2470 if (objc_class_type)
2471 {
2472 uint32_t child_idx = 0;
2473 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2474
2475 if (class_interface_decl)
2476 {
2477 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2478 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2479
2480 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2481 {
2482 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2483
2484 if (ivar_decl->getName().equals (name_sref))
2485 {
2486 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2487 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2488 ++child_idx;
2489
2490 return child_idx;
2491 }
2492 }
2493
2494 if (superclass_interface_decl)
2495 {
2496 if (superclass_interface_decl->getName().equals (name_sref))
2497 return 0;
2498 }
2499 }
2500 }
2501 }
2502 break;
2503
2504 case clang::Type::ObjCObjectPointer:
2505 {
2506 return GetIndexOfChildWithName (ast_context,
2507 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2508 name,
2509 omit_empty_base_classes);
2510 }
2511 break;
2512
Greg Clayton1674b122010-07-21 22:12:05 +00002513 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002514 {
2515// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2516// const uint64_t element_count = array->getSize().getLimitedValue();
2517//
2518// if (idx < element_count)
2519// {
2520// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2521//
2522// char element_name[32];
2523// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2524//
2525// child_name.assign(element_name);
2526// assert(field_type_info.first % 8 == 0);
2527// child_byte_size = field_type_info.first / 8;
2528// child_byte_offset = idx * child_byte_size;
2529// return array->getElementType().getAsOpaquePtr();
2530// }
2531 }
2532 break;
2533
Greg Clayton1674b122010-07-21 22:12:05 +00002534// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002535// {
2536// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2537// QualType pointee_type = mem_ptr_type->getPointeeType();
2538//
2539// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2540// {
2541// return GetIndexOfChildWithName (ast_context,
2542// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2543// name);
2544// }
2545// }
2546// break;
2547//
Greg Clayton1674b122010-07-21 22:12:05 +00002548 case clang::Type::LValueReference:
2549 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002550 {
2551 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2552 QualType pointee_type = reference_type->getPointeeType();
2553
2554 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2555 {
2556 return GetIndexOfChildWithName (ast_context,
2557 reference_type->getPointeeType().getAsOpaquePtr(),
2558 name,
2559 omit_empty_base_classes);
2560 }
2561 }
2562 break;
2563
Greg Clayton1674b122010-07-21 22:12:05 +00002564 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002565 {
2566 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2567 QualType pointee_type = pointer_type->getPointeeType();
2568
2569 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2570 {
2571 return GetIndexOfChildWithName (ast_context,
2572 pointer_type->getPointeeType().getAsOpaquePtr(),
2573 name,
2574 omit_empty_base_classes);
2575 }
2576 else
2577 {
2578// if (parent_name)
2579// {
2580// child_name.assign(1, '*');
2581// child_name += parent_name;
2582// }
2583//
2584// // We have a pointer to an simple type
2585// if (idx == 0)
2586// {
2587// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2588// assert(clang_type_info.first % 8 == 0);
2589// child_byte_size = clang_type_info.first / 8;
2590// child_byte_offset = 0;
2591// return pointee_type.getAsOpaquePtr();
2592// }
2593 }
2594 }
2595 break;
2596
Greg Clayton1674b122010-07-21 22:12:05 +00002597 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002598 return GetIndexOfChildWithName (ast_context,
2599 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2600 name,
2601 omit_empty_base_classes);
2602
2603 default:
2604 break;
2605 }
2606 }
2607 return UINT32_MAX;
2608}
2609
2610#pragma mark TagType
2611
2612bool
Greg Clayton462d4142010-09-29 01:12:09 +00002613ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00002614{
2615 if (tag_clang_type)
2616 {
2617 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00002618 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002619 if (clang_type)
2620 {
2621 TagType *tag_type = dyn_cast<TagType>(clang_type);
2622 if (tag_type)
2623 {
2624 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
2625 if (tag_decl)
2626 {
2627 tag_decl->setTagKind ((TagDecl::TagKind)kind);
2628 return true;
2629 }
2630 }
2631 }
2632 }
2633 return false;
2634}
2635
2636
2637#pragma mark DeclContext Functions
2638
2639DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00002640ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002641{
2642 if (clang_type == NULL)
2643 return NULL;
2644
2645 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002646 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2647 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002648 {
Greg Clayton9488b742010-07-28 02:04:09 +00002649 case clang::Type::FunctionNoProto: break;
2650 case clang::Type::FunctionProto: break;
2651 case clang::Type::IncompleteArray: break;
2652 case clang::Type::VariableArray: break;
2653 case clang::Type::ConstantArray: break;
2654 case clang::Type::ExtVector: break;
2655 case clang::Type::Vector: break;
2656 case clang::Type::Builtin: break;
2657 case clang::Type::BlockPointer: break;
2658 case clang::Type::Pointer: break;
2659 case clang::Type::LValueReference: break;
2660 case clang::Type::RValueReference: break;
2661 case clang::Type::MemberPointer: break;
2662 case clang::Type::Complex: break;
2663 case clang::Type::ObjCObject: break;
2664 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
2665 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
2666 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
2667 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
2668 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00002669
Greg Clayton9488b742010-07-28 02:04:09 +00002670 case clang::Type::TypeOfExpr: break;
2671 case clang::Type::TypeOf: break;
2672 case clang::Type::Decltype: break;
2673 //case clang::Type::QualifiedName: break;
2674 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00002675 }
2676 // No DeclContext in this type...
2677 return NULL;
2678}
2679
2680#pragma mark Namespace Declarations
2681
2682NamespaceDecl *
2683ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
2684{
2685 // TODO: Do something intelligent with the Declaration object passed in
2686 // like maybe filling in the SourceLocation with it...
2687 if (name)
2688 {
2689 ASTContext *ast_context = getASTContext();
2690 if (decl_ctx == NULL)
2691 decl_ctx = ast_context->getTranslationUnitDecl();
2692 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
2693 }
2694 return NULL;
2695}
2696
2697
2698#pragma mark Function Types
2699
2700FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00002701ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00002702{
2703 if (name)
2704 {
2705 ASTContext *ast_context = getASTContext();
2706 assert (ast_context != NULL);
2707
2708 if (name && name[0])
2709 {
2710 return FunctionDecl::Create(*ast_context,
2711 ast_context->getTranslationUnitDecl(),
2712 SourceLocation(),
2713 DeclarationName (&ast_context->Idents.get(name)),
2714 QualType::getFromOpaquePtr(function_clang_type),
2715 NULL,
2716 (FunctionDecl::StorageClass)storage,
2717 (FunctionDecl::StorageClass)storage,
2718 is_inline);
2719 }
2720 else
2721 {
2722 return FunctionDecl::Create(*ast_context,
2723 ast_context->getTranslationUnitDecl(),
2724 SourceLocation(),
2725 DeclarationName (),
2726 QualType::getFromOpaquePtr(function_clang_type),
2727 NULL,
2728 (FunctionDecl::StorageClass)storage,
2729 (FunctionDecl::StorageClass)storage,
2730 is_inline);
2731 }
2732 }
2733 return NULL;
2734}
2735
Greg Clayton462d4142010-09-29 01:12:09 +00002736clang_type_t
2737ClangASTContext::CreateFunctionType (ASTContext *ast_context,
2738 clang_type_t result_type,
2739 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00002740 unsigned num_args,
2741 bool is_variadic,
2742 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00002743{
Chris Lattner24943d22010-06-08 16:52:24 +00002744 assert (ast_context != NULL);
2745 std::vector<QualType> qual_type_args;
2746 for (unsigned i=0; i<num_args; ++i)
2747 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
2748
2749 // TODO: Detect calling convention in DWARF?
2750 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00002751 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00002752 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00002753 is_variadic,
2754 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00002755 false, // hasExceptionSpec
2756 false, // hasAnyExceptionSpec,
2757 0, // NumExs
2758 0, // const QualType *ExArray
2759 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
2760}
2761
2762ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00002763ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00002764{
2765 ASTContext *ast_context = getASTContext();
2766 assert (ast_context != NULL);
2767 return ParmVarDecl::Create(*ast_context,
2768 ast_context->getTranslationUnitDecl(),
2769 SourceLocation(),
2770 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00002771 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00002772 NULL,
2773 (VarDecl::StorageClass)storage,
2774 (VarDecl::StorageClass)storage,
2775 0);
2776}
2777
2778void
2779ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
2780{
2781 if (function_decl)
2782 function_decl->setParams (params, num_params);
2783}
2784
2785
2786#pragma mark Array Types
2787
Greg Clayton462d4142010-09-29 01:12:09 +00002788clang_type_t
2789ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00002790{
2791 if (element_type)
2792 {
2793 ASTContext *ast_context = getASTContext();
2794 assert (ast_context != NULL);
2795 llvm::APInt ap_element_count (64, element_count);
2796 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
2797 ap_element_count,
2798 ArrayType::Normal,
2799 0).getAsOpaquePtr(); // ElemQuals
2800 }
2801 return NULL;
2802}
2803
2804
2805#pragma mark TagDecl
2806
2807bool
Greg Clayton462d4142010-09-29 01:12:09 +00002808ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002809{
2810 if (clang_type)
2811 {
2812 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00002813 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002814 if (t)
2815 {
2816 TagType *tag_type = dyn_cast<TagType>(t);
2817 if (tag_type)
2818 {
2819 TagDecl *tag_decl = tag_type->getDecl();
2820 if (tag_decl)
2821 {
2822 tag_decl->startDefinition();
2823 return true;
2824 }
2825 }
2826 }
2827 }
2828 return false;
2829}
2830
2831bool
Greg Clayton462d4142010-09-29 01:12:09 +00002832ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002833{
2834 if (clang_type)
2835 {
2836 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00002837
2838 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2839
2840 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00002841 {
Greg Clayton55b6c532010-09-29 03:44:17 +00002842 cxx_record_decl->completeDefinition();
2843
2844 return true;
2845 }
2846
2847 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
2848
2849 if (enum_type)
2850 {
2851 EnumDecl *enum_decl = enum_type->getDecl();
2852
2853 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00002854 {
Greg Clayton55b6c532010-09-29 03:44:17 +00002855 /// TODO This really needs to be fixed.
2856
2857 unsigned NumPositiveBits = 1;
2858 unsigned NumNegativeBits = 0;
2859
2860 enum_decl->completeDefinition(enum_decl->getIntegerType(), enum_decl->getIntegerType(), NumPositiveBits, NumNegativeBits);
2861 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00002862 }
2863 }
2864 }
2865 return false;
2866}
2867
2868
2869#pragma mark Enumeration Types
2870
Greg Clayton462d4142010-09-29 01:12:09 +00002871clang_type_t
2872ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002873{
2874 // TODO: Do something intelligent with the Declaration object passed in
2875 // like maybe filling in the SourceLocation with it...
2876 ASTContext *ast_context = getASTContext();
2877 assert (ast_context != NULL);
2878 EnumDecl *enum_decl = EnumDecl::Create(*ast_context,
2879 ast_context->getTranslationUnitDecl(),
2880 SourceLocation(),
2881 name && name[0] ? &ast_context->Idents.get(name) : NULL,
2882 SourceLocation(),
2883 NULL);
2884 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00002885 {
2886 // TODO: check if we should be setting the promotion type too?
2887 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00002888 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00002889 }
Chris Lattner24943d22010-06-08 16:52:24 +00002890 return NULL;
2891}
2892
Greg Clayton462d4142010-09-29 01:12:09 +00002893clang_type_t
2894ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
2895{
2896 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
2897
2898 clang::Type *clang_type = enum_qual_type.getTypePtr();
2899 if (clang_type)
2900 {
2901 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
2902 if (enum_type)
2903 {
2904 EnumDecl *enum_decl = enum_type->getDecl();
2905 if (enum_decl)
2906 return enum_decl->getIntegerType().getAsOpaquePtr();
2907 }
2908 }
2909 return NULL;
2910}
Chris Lattner24943d22010-06-08 16:52:24 +00002911bool
2912ClangASTContext::AddEnumerationValueToEnumerationType
2913(
Greg Clayton462d4142010-09-29 01:12:09 +00002914 clang_type_t enum_clang_type,
2915 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002916 const Declaration &decl,
2917 const char *name,
2918 int64_t enum_value,
2919 uint32_t enum_value_bit_size
2920)
2921{
2922 if (enum_clang_type && enumerator_clang_type && name)
2923 {
2924 // TODO: Do something intelligent with the Declaration object passed in
2925 // like maybe filling in the SourceLocation with it...
2926 ASTContext *ast_context = getASTContext();
2927 IdentifierTable *identifier_table = getIdentifierTable();
2928
2929 assert (ast_context != NULL);
2930 assert (identifier_table != NULL);
2931 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
2932
Greg Clayton1674b122010-07-21 22:12:05 +00002933 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00002934 if (clang_type)
2935 {
2936 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
2937
2938 if (enum_type)
2939 {
2940 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
2941 enum_llvm_apsint = enum_value;
2942 EnumConstantDecl *enumerator_decl =
2943 EnumConstantDecl::Create(*ast_context,
2944 enum_type->getDecl(),
2945 SourceLocation(),
2946 name ? &identifier_table->get(name) : NULL, // Identifier
2947 QualType::getFromOpaquePtr(enumerator_clang_type),
2948 NULL,
2949 enum_llvm_apsint);
2950
2951 if (enumerator_decl)
2952 {
2953 enum_type->getDecl()->addDecl(enumerator_decl);
2954 return true;
2955 }
2956 }
2957 }
2958 }
2959 return false;
2960}
2961
2962#pragma mark Pointers & References
2963
Greg Clayton462d4142010-09-29 01:12:09 +00002964clang_type_t
2965ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002966{
2967 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00002968 {
2969 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2970
Greg Clayton03e0f972010-09-13 03:32:57 +00002971 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2972 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00002973 {
2974 case clang::Type::ObjCObject:
2975 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00002976 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
2977
Greg Clayton7b541032010-07-29 20:06:32 +00002978 default:
2979 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
2980 }
2981 }
Chris Lattner24943d22010-06-08 16:52:24 +00002982 return NULL;
2983}
2984
Greg Clayton462d4142010-09-29 01:12:09 +00002985clang_type_t
2986ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002987{
2988 if (clang_type)
2989 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2990 return NULL;
2991}
2992
Greg Clayton462d4142010-09-29 01:12:09 +00002993clang_type_t
2994ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002995{
2996 if (clang_type)
2997 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
2998 return NULL;
2999}
3000
Greg Clayton462d4142010-09-29 01:12:09 +00003001clang_type_t
3002ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003003{
3004 if (clang_pointee_type && clang_pointee_type)
3005 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3006 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3007 return NULL;
3008}
3009
Chris Lattner24943d22010-06-08 16:52:24 +00003010size_t
3011ClangASTContext::GetPointerBitSize ()
3012{
3013 ASTContext *ast_context = getASTContext();
3014 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3015}
3016
3017bool
Greg Clayton462d4142010-09-29 01:12:09 +00003018ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003019{
3020 if (clang_type == NULL)
3021 return false;
3022
3023 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003024 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3025 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003026 {
Greg Clayton1674b122010-07-21 22:12:05 +00003027 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003028 if (target_type)
3029 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3030 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003031 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003032 if (target_type)
3033 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3034 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003035 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003036 if (target_type)
3037 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3038 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003039 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003040 if (target_type)
3041 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3042 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003043 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003044 if (target_type)
3045 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3046 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003047 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003048 if (target_type)
3049 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3050 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003051 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003052 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3053 default:
3054 break;
3055 }
3056 return false;
3057}
3058
Chris Lattner24943d22010-06-08 16:52:24 +00003059bool
Greg Clayton462d4142010-09-29 01:12:09 +00003060ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003061{
3062 if (!clang_type)
3063 return false;
3064
3065 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3066 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3067
3068 if (builtin_type)
3069 {
3070 if (builtin_type->isInteger())
3071 is_signed = builtin_type->isSignedInteger();
3072
3073 return true;
3074 }
3075
3076 return false;
3077}
3078
3079bool
Greg Clayton462d4142010-09-29 01:12:09 +00003080ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003081{
3082 if (clang_type)
3083 {
3084 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003085 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3086 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003087 {
Greg Clayton1674b122010-07-21 22:12:05 +00003088 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003089 if (target_type)
3090 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3091 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003092 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003093 if (target_type)
3094 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3095 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003096 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003097 if (target_type)
3098 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3099 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003100 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003101 if (target_type)
3102 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3103 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003104 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003105 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3106 default:
3107 break;
3108 }
3109 }
3110 return false;
3111}
3112
3113bool
Greg Clayton462d4142010-09-29 01:12:09 +00003114ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003115{
3116 if (clang_type)
3117 {
3118 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3119
3120 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3121 {
3122 clang::BuiltinType::Kind kind = BT->getKind();
3123 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3124 {
3125 count = 1;
3126 is_complex = false;
3127 return true;
3128 }
3129 }
3130 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3131 {
3132 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3133 {
3134 count = 2;
3135 is_complex = true;
3136 return true;
3137 }
3138 }
3139 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3140 {
3141 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3142 {
3143 count = VT->getNumElements();
3144 is_complex = false;
3145 return true;
3146 }
3147 }
3148 }
3149 return false;
3150}
3151
Greg Clayton1d8173f2010-09-24 05:15:53 +00003152bool
Greg Clayton462d4142010-09-29 01:12:09 +00003153ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003154{
3155 if (clang_type)
3156 {
3157 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3158 if (qual_type->getAsCXXRecordDecl() != NULL)
3159 return true;
3160 }
3161 return false;
3162}
3163
3164bool
Greg Clayton462d4142010-09-29 01:12:09 +00003165ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003166{
3167 if (clang_type)
3168 {
3169 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3170 if (qual_type->isObjCObjectOrInterfaceType())
3171 return true;
3172 }
3173 return false;
3174}
3175
3176
3177
Chris Lattner24943d22010-06-08 16:52:24 +00003178
3179bool
Greg Clayton462d4142010-09-29 01:12:09 +00003180ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003181{
3182 if (clang_type)
3183 {
3184 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003185 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3186 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003187 {
Greg Clayton1674b122010-07-21 22:12:05 +00003188 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003189 {
3190 ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr());
3191 QualType element_qual_type = array->getElementType();
Greg Clayton1674b122010-07-21 22:12:05 +00003192 clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003193 if (canonical_type && canonical_type->isCharType())
3194 {
3195 // We know the size of the array and it could be a C string
3196 // since it is an array of characters
3197 length = array->getSize().getLimitedValue();
3198 return true;
3199 }
3200 }
3201 break;
3202
Greg Clayton1674b122010-07-21 22:12:05 +00003203 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003204 {
3205 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton1674b122010-07-21 22:12:05 +00003206 clang::Type *pointee_type_ptr = pointer_type->getPointeeType().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003207 if (pointee_type_ptr)
3208 {
Greg Clayton1674b122010-07-21 22:12:05 +00003209 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003210 length = 0; // No length info, read until a NULL terminator is received
3211 if (canonical_type_ptr)
3212 return canonical_type_ptr->isCharType();
3213 else
3214 return pointee_type_ptr->isCharType();
3215 }
3216 }
3217 break;
3218
Greg Clayton1674b122010-07-21 22:12:05 +00003219 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003220 return ClangASTContext::IsCStringType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), length);
3221
Greg Clayton1674b122010-07-21 22:12:05 +00003222 case clang::Type::LValueReference:
3223 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003224 {
3225 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton1674b122010-07-21 22:12:05 +00003226 clang::Type *pointee_type_ptr = reference_type->getPointeeType().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003227 if (pointee_type_ptr)
3228 {
Greg Clayton1674b122010-07-21 22:12:05 +00003229 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003230 length = 0; // No length info, read until a NULL terminator is received
3231 if (canonical_type_ptr)
3232 return canonical_type_ptr->isCharType();
3233 else
3234 return pointee_type_ptr->isCharType();
3235 }
3236 }
3237 break;
3238 }
3239 }
3240 return false;
3241}
3242
3243bool
Greg Clayton462d4142010-09-29 01:12:09 +00003244ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003245{
3246 if (clang_type)
3247 {
3248 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3249
3250 if (qual_type->isFunctionPointerType())
3251 return true;
3252
3253 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3254 switch (type_class)
3255 {
3256 case clang::Type::Typedef:
3257 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3258
3259 case clang::Type::LValueReference:
3260 case clang::Type::RValueReference:
3261 {
3262 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3263 if (reference_type)
3264 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3265 }
3266 break;
3267 }
3268 }
3269 return false;
3270}
3271
3272
3273
3274
3275bool
Greg Clayton462d4142010-09-29 01:12:09 +00003276ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003277{
3278 if (!clang_type)
3279 return false;
3280
3281 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3282
Greg Clayton03e0f972010-09-13 03:32:57 +00003283 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3284 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003285 {
Greg Clayton1674b122010-07-21 22:12:05 +00003286 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003287 if (member_type)
3288 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3289 if (size)
3290 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3291 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003292 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003293 if (member_type)
3294 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3295 if (size)
3296 *size = 0;
3297 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003298 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003299 if (member_type)
3300 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3301 if (size)
3302 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003303 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003304 if (member_type)
3305 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3306 if (size)
3307 *size = 0;
3308 return true;
3309 }
3310 return false;
3311}
3312
3313
3314#pragma mark Typedefs
3315
Greg Clayton462d4142010-09-29 01:12:09 +00003316clang_type_t
3317ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003318{
3319 if (clang_type)
3320 {
3321 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3322 ASTContext *ast_context = getASTContext();
3323 IdentifierTable *identifier_table = getIdentifierTable();
3324 assert (ast_context != NULL);
3325 assert (identifier_table != NULL);
3326 if (decl_ctx == NULL)
3327 decl_ctx = ast_context->getTranslationUnitDecl();
3328 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3329 decl_ctx,
3330 SourceLocation(),
3331 name ? &identifier_table->get(name) : NULL, // Identifier
3332 ast_context->CreateTypeSourceInfo(qual_type));
3333
3334 // Get a uniqued QualType for the typedef decl type
3335 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3336 }
3337 return NULL;
3338}
3339
3340
3341std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003342ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003343{
3344 std::string return_name;
3345
Greg Clayton462d4142010-09-29 01:12:09 +00003346 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003347
Greg Clayton462d4142010-09-29 01:12:09 +00003348 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003349 if (typedef_type)
3350 {
Greg Clayton462d4142010-09-29 01:12:09 +00003351 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003352 return_name = typedef_decl->getQualifiedNameAsString();
3353 }
3354 else
3355 {
3356 return_name = qual_type.getAsString();
3357 }
3358
3359 return return_name;
3360}
3361
3362// Disable this for now since I can't seem to get a nicely formatted float
3363// out of the APFloat class without just getting the float, double or quad
3364// and then using a formatted print on it which defeats the purpose. We ideally
3365// would like to get perfect string values for any kind of float semantics
3366// so we can support remote targets. The code below also requires a patch to
3367// llvm::APInt.
3368//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003369//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, clang_type_t clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
Chris Lattner24943d22010-06-08 16:52:24 +00003370//{
3371// uint32_t count = 0;
3372// bool is_complex = false;
3373// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3374// {
3375// unsigned num_bytes_per_float = byte_size / count;
3376// unsigned num_bits_per_float = num_bytes_per_float * 8;
3377//
3378// float_str.clear();
3379// uint32_t i;
3380// for (i=0; i<count; i++)
3381// {
3382// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3383// bool is_ieee = false;
3384// APFloat ap_float(ap_int, is_ieee);
3385// char s[1024];
3386// unsigned int hex_digits = 0;
3387// bool upper_case = false;
3388//
3389// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3390// {
3391// if (i > 0)
3392// float_str.append(", ");
3393// float_str.append(s);
3394// if (i == 1 && is_complex)
3395// float_str.append(1, 'i');
3396// }
3397// }
3398// return !float_str.empty();
3399// }
3400// return false;
3401//}
3402
3403size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003404ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
Chris Lattner24943d22010-06-08 16:52:24 +00003405{
3406 if (clang_type)
3407 {
3408 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3409 uint32_t count = 0;
3410 bool is_complex = false;
3411 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3412 {
3413 // TODO: handle complex and vector types
3414 if (count != 1)
3415 return false;
3416
3417 StringRef s_sref(s);
3418 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3419
3420 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3421 const uint64_t byte_size = bit_size / 8;
3422 if (dst_size >= byte_size)
3423 {
3424 if (bit_size == sizeof(float)*8)
3425 {
3426 float float32 = ap_float.convertToFloat();
3427 ::memcpy (dst, &float32, byte_size);
3428 return byte_size;
3429 }
3430 else if (bit_size >= 64)
3431 {
3432 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3433 ::memcpy (dst, ap_int.getRawData(), byte_size);
3434 return byte_size;
3435 }
3436 }
3437 }
3438 }
3439 return 0;
3440}
Sean Callanana751f7b2010-09-17 02:24:29 +00003441
3442unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00003443ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00003444{
3445 assert (clang_type);
3446
3447 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3448
3449 return qual_type.getQualifiers().getCVRQualifiers();
3450}