blob: 1ab02b989f9872260f111e4ce5f5707f0538d196 [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"
Sean Callanan8a3b0a82010-11-18 02:56:27 +000026#include "clang/Basic/FileSystemOptions.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "clang/Basic/SourceManager.h"
28#include "clang/Basic/TargetInfo.h"
29#include "clang/Basic/TargetOptions.h"
30#include "clang/Frontend/FrontendOptions.h"
31#include "clang/Frontend/LangStandard.h"
Sean Callananbc4f0f52010-07-08 18:16:16 +000032#undef NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000033
Chris Lattner24943d22010-06-08 16:52:24 +000034#include "lldb/Core/dwarf.h"
Greg Claytonf3d0b0c2010-10-27 03:32:59 +000035#include "lldb/Core/Flags.h"
Sean Callanan839fde42010-10-28 18:19:36 +000036#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037
Eli Friedmanf05633b2010-06-13 19:06:42 +000038#include <stdio.h>
39
Greg Clayton585660c2010-08-05 01:57:25 +000040using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000041using namespace lldb_private;
42using namespace llvm;
43using namespace clang;
44
Greg Clayton84f80752010-07-22 18:30:50 +000045static AccessSpecifier
Greg Clayton585660c2010-08-05 01:57:25 +000046ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000047{
48 switch (access)
49 {
Greg Clayton585660c2010-08-05 01:57:25 +000050 default: break;
51 case eAccessNone: return AS_none;
52 case eAccessPublic: return AS_public;
53 case eAccessPrivate: return AS_private;
54 case eAccessProtected: return AS_protected;
Greg Clayton84f80752010-07-22 18:30:50 +000055 }
56 return AS_none;
57}
58
59static ObjCIvarDecl::AccessControl
Greg Clayton585660c2010-08-05 01:57:25 +000060ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000061{
62 switch (access)
63 {
Greg Clayton585660c2010-08-05 01:57:25 +000064 default: break;
65 case eAccessNone: return ObjCIvarDecl::None;
66 case eAccessPublic: return ObjCIvarDecl::Public;
67 case eAccessPrivate: return ObjCIvarDecl::Private;
68 case eAccessProtected: return ObjCIvarDecl::Protected;
69 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton84f80752010-07-22 18:30:50 +000070 }
71 return ObjCIvarDecl::None;
72}
73
74
Chris Lattner24943d22010-06-08 16:52:24 +000075static void
76ParseLangArgs
77(
78 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000079 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000080)
81{
82 // FIXME: Cleanup per-file based stuff.
83
84 // Set some properties which depend soley on the input kind; it would be nice
85 // to move these to the language standard, and have the driver resolve the
86 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000087 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000088 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000089 } else if (IK == IK_ObjC ||
90 IK == IK_ObjCXX ||
91 IK == IK_PreprocessedObjC ||
92 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000093 Opts.ObjC1 = Opts.ObjC2 = 1;
94 }
95
96 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
97
98 if (LangStd == LangStandard::lang_unspecified) {
99 // Based on the base language, pick one.
100 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +0000101 case IK_None:
102 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +0000103 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +0000104 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +0000105 LangStd = LangStandard::lang_opencl;
106 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000107 case IK_Asm:
108 case IK_C:
109 case IK_PreprocessedC:
110 case IK_ObjC:
111 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +0000112 LangStd = LangStandard::lang_gnu99;
113 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000114 case IK_CXX:
115 case IK_PreprocessedCXX:
116 case IK_ObjCXX:
117 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +0000118 LangStd = LangStandard::lang_gnucxx98;
119 break;
120 }
121 }
122
123 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
124 Opts.BCPLComment = Std.hasBCPLComments();
125 Opts.C99 = Std.isC99();
126 Opts.CPlusPlus = Std.isCPlusPlus();
127 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
128 Opts.Digraphs = Std.hasDigraphs();
129 Opts.GNUMode = Std.isGNUMode();
130 Opts.GNUInline = !Std.isC99();
131 Opts.HexFloats = Std.hasHexFloats();
132 Opts.ImplicitInt = Std.hasImplicitInt();
133
134 // OpenCL has some additional defaults.
135 if (LangStd == LangStandard::lang_opencl) {
136 Opts.OpenCL = 1;
137 Opts.AltiVec = 1;
138 Opts.CXXOperatorNames = 1;
139 Opts.LaxVectorConversions = 1;
140 }
141
142 // OpenCL and C++ both have bool, true, false keywords.
143 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
144
145// if (Opts.CPlusPlus)
146// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
147//
148// if (Args.hasArg(OPT_fobjc_gc_only))
149// Opts.setGCMode(LangOptions::GCOnly);
150// else if (Args.hasArg(OPT_fobjc_gc))
151// Opts.setGCMode(LangOptions::HybridGC);
152//
153// if (Args.hasArg(OPT_print_ivar_layout))
154// Opts.ObjCGCBitmapPrint = 1;
155//
156// if (Args.hasArg(OPT_faltivec))
157// Opts.AltiVec = 1;
158//
159// if (Args.hasArg(OPT_pthread))
160// Opts.POSIXThreads = 1;
161//
162// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
163// "default");
164// if (Vis == "default")
Sean Callanan8950c9a2010-10-29 18:38:40 +0000165 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner24943d22010-06-08 16:52:24 +0000166// else if (Vis == "hidden")
167// Opts.setVisibilityMode(LangOptions::Hidden);
168// else if (Vis == "protected")
169// Opts.setVisibilityMode(LangOptions::Protected);
170// else
171// Diags.Report(diag::err_drv_invalid_value)
172// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
173
174// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
175
176 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
177 // is specified, or -std is set to a conforming mode.
178 Opts.Trigraphs = !Opts.GNUMode;
179// if (Args.hasArg(OPT_trigraphs))
180// Opts.Trigraphs = 1;
181//
182// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
183// OPT_fno_dollars_in_identifiers,
184// !Opts.AsmPreprocessor);
185// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
186// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
187// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
188// if (Args.hasArg(OPT_fno_lax_vector_conversions))
189// Opts.LaxVectorConversions = 0;
190// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
191// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
192// Opts.Blocks = Args.hasArg(OPT_fblocks);
193// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
194// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
195// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
196// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
197// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
198// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
199// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
200// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
201// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
202// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
203// Diags);
204// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
205// Opts.ObjCConstantStringClass = getLastArgValue(Args,
206// OPT_fconstant_string_class);
207// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
208// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
209// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
210// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
211// Opts.Static = Args.hasArg(OPT_static_define);
212 Opts.OptimizeSize = 0;
213
214 // FIXME: Eliminate this dependency.
215// unsigned Opt =
216// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
217// Opts.Optimize = Opt != 0;
218 unsigned Opt = 0;
219
220 // This is the __NO_INLINE__ define, which just depends on things like the
221 // optimization level and -fno-inline, not actually whether the backend has
222 // inlining enabled.
223 //
224 // FIXME: This is affected by other options (-fno-inline).
225 Opts.NoInline = !Opt;
226
227// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
228// switch (SSP) {
229// default:
230// Diags.Report(diag::err_drv_invalid_value)
231// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
232// break;
233// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
234// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
235// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
236// }
237}
238
Chris Lattner24943d22010-06-08 16:52:24 +0000239
Chris Lattner24943d22010-06-08 16:52:24 +0000240ClangASTContext::ClangASTContext(const char *target_triple) :
241 m_target_triple(),
242 m_ast_context_ap(),
243 m_language_options_ap(),
244 m_source_manager_ap(),
245 m_diagnostic_ap(),
246 m_target_options_ap(),
247 m_target_info_ap(),
248 m_identifier_table_ap(),
249 m_selector_table_ap(),
250 m_builtins_ap()
251{
252 if (target_triple && target_triple[0])
253 m_target_triple.assign (target_triple);
254}
255
256//----------------------------------------------------------------------
257// Destructor
258//----------------------------------------------------------------------
259ClangASTContext::~ClangASTContext()
260{
261 m_builtins_ap.reset();
262 m_selector_table_ap.reset();
263 m_identifier_table_ap.reset();
264 m_target_info_ap.reset();
265 m_target_options_ap.reset();
266 m_diagnostic_ap.reset();
267 m_source_manager_ap.reset();
268 m_language_options_ap.reset();
269 m_ast_context_ap.reset();
270}
271
272
273void
274ClangASTContext::Clear()
275{
276 m_ast_context_ap.reset();
277 m_language_options_ap.reset();
278 m_source_manager_ap.reset();
279 m_diagnostic_ap.reset();
280 m_target_options_ap.reset();
281 m_target_info_ap.reset();
282 m_identifier_table_ap.reset();
283 m_selector_table_ap.reset();
284 m_builtins_ap.reset();
285}
286
287const char *
288ClangASTContext::GetTargetTriple ()
289{
290 return m_target_triple.c_str();
291}
292
293void
294ClangASTContext::SetTargetTriple (const char *target_triple)
295{
296 Clear();
297 m_target_triple.assign(target_triple);
298}
299
300
301ASTContext *
302ClangASTContext::getASTContext()
303{
304 if (m_ast_context_ap.get() == NULL)
305 {
306 m_ast_context_ap.reset(
307 new ASTContext(
308 *getLanguageOptions(),
309 *getSourceManager(),
310 *getTargetInfo(),
311 *getIdentifierTable(),
312 *getSelectorTable(),
Greg Clayton6e713402010-07-30 20:30:44 +0000313 *getBuiltinContext(),
314 0));
Chris Lattner24943d22010-06-08 16:52:24 +0000315 }
316 return m_ast_context_ap.get();
317}
318
319Builtin::Context *
320ClangASTContext::getBuiltinContext()
321{
322 if (m_builtins_ap.get() == NULL)
323 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
324 return m_builtins_ap.get();
325}
326
327IdentifierTable *
328ClangASTContext::getIdentifierTable()
329{
330 if (m_identifier_table_ap.get() == NULL)
331 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
332 return m_identifier_table_ap.get();
333}
334
335LangOptions *
336ClangASTContext::getLanguageOptions()
337{
338 if (m_language_options_ap.get() == NULL)
339 {
340 m_language_options_ap.reset(new LangOptions());
Greg Claytone41c4b22010-06-13 17:34:29 +0000341 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
342// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner24943d22010-06-08 16:52:24 +0000343 }
344 return m_language_options_ap.get();
345}
346
347SelectorTable *
348ClangASTContext::getSelectorTable()
349{
350 if (m_selector_table_ap.get() == NULL)
351 m_selector_table_ap.reset (new SelectorTable());
352 return m_selector_table_ap.get();
353}
354
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000355clang::FileManager *
356ClangASTContext::getFileManager()
357{
358 if (m_file_manager_ap.get() == NULL)
359 m_file_manager_ap.reset(new clang::FileManager());
360 return m_file_manager_ap.get();
361}
362
363clang::FileSystemOptions *
364ClangASTContext::getFileSystemOptions()
365{
366 if (m_file_system_options_ap.get() == NULL)
367 m_file_system_options_ap.reset(new clang::FileSystemOptions());
368 return m_file_system_options_ap.get();
369}
370
Greg Clayton1674b122010-07-21 22:12:05 +0000371clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000372ClangASTContext::getSourceManager()
373{
374 if (m_source_manager_ap.get() == NULL)
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000375 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager(), *getFileSystemOptions()));
Chris Lattner24943d22010-06-08 16:52:24 +0000376 return m_source_manager_ap.get();
377}
378
379Diagnostic *
380ClangASTContext::getDiagnostic()
381{
382 if (m_diagnostic_ap.get() == NULL)
383 m_diagnostic_ap.reset(new Diagnostic());
384 return m_diagnostic_ap.get();
385}
386
387TargetOptions *
388ClangASTContext::getTargetOptions()
389{
390 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
391 {
392 m_target_options_ap.reset (new TargetOptions());
393 if (m_target_options_ap.get())
394 m_target_options_ap->Triple = m_target_triple;
395 }
396 return m_target_options_ap.get();
397}
398
399
400TargetInfo *
401ClangASTContext::getTargetInfo()
402{
403 // target_triple should be something like "x86_64-apple-darwin10"
404 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
405 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
406 return m_target_info_ap.get();
407}
408
409#pragma mark Basic Types
410
411static inline bool
412QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
413{
414 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
415 if (qual_type_bit_size == bit_size)
416 return true;
417 return false;
418}
419
Greg Clayton462d4142010-09-29 01:12:09 +0000420clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000421ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000422{
423 ASTContext *ast_context = getASTContext();
424
425 assert (ast_context != NULL);
426
427 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
428}
429
Greg Clayton462d4142010-09-29 01:12:09 +0000430clang_type_t
431ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000432{
433 if (!ast_context)
434 return NULL;
435
436 switch (encoding)
437 {
Greg Clayton585660c2010-08-05 01:57:25 +0000438 case eEncodingInvalid:
Chris Lattner24943d22010-06-08 16:52:24 +0000439 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
440 return ast_context->VoidPtrTy.getAsOpaquePtr();
441 break;
442
Greg Clayton585660c2010-08-05 01:57:25 +0000443 case eEncodingUint:
Chris Lattner24943d22010-06-08 16:52:24 +0000444 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
445 return ast_context->UnsignedCharTy.getAsOpaquePtr();
446 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
447 return ast_context->UnsignedShortTy.getAsOpaquePtr();
448 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
449 return ast_context->UnsignedIntTy.getAsOpaquePtr();
450 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
451 return ast_context->UnsignedLongTy.getAsOpaquePtr();
452 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
453 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
454 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
455 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
456 break;
457
Greg Clayton585660c2010-08-05 01:57:25 +0000458 case eEncodingSint:
Chris Lattner24943d22010-06-08 16:52:24 +0000459 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
460 return ast_context->CharTy.getAsOpaquePtr();
461 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
462 return ast_context->ShortTy.getAsOpaquePtr();
463 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
464 return ast_context->IntTy.getAsOpaquePtr();
465 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
466 return ast_context->LongTy.getAsOpaquePtr();
467 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
468 return ast_context->LongLongTy.getAsOpaquePtr();
469 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
470 return ast_context->Int128Ty.getAsOpaquePtr();
471 break;
472
Greg Clayton585660c2010-08-05 01:57:25 +0000473 case eEncodingIEEE754:
Chris Lattner24943d22010-06-08 16:52:24 +0000474 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
475 return ast_context->FloatTy.getAsOpaquePtr();
476 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
477 return ast_context->DoubleTy.getAsOpaquePtr();
478 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
479 return ast_context->LongDoubleTy.getAsOpaquePtr();
480 break;
481
Greg Clayton585660c2010-08-05 01:57:25 +0000482 case eEncodingVector:
Chris Lattner24943d22010-06-08 16:52:24 +0000483 default:
484 break;
485 }
486
487 return NULL;
488}
489
Greg Clayton462d4142010-09-29 01:12:09 +0000490clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000491ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
492{
493 ASTContext *ast_context = getASTContext();
494
495 #define streq(a,b) strcmp(a,b) == 0
496 assert (ast_context != NULL);
497 if (ast_context)
498 {
499 switch (dw_ate)
500 {
501 default:
502 break;
503
504 case DW_ATE_address:
505 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
506 return ast_context->VoidPtrTy.getAsOpaquePtr();
507 break;
508
509 case DW_ATE_boolean:
510 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
511 return ast_context->BoolTy.getAsOpaquePtr();
512 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
513 return ast_context->UnsignedCharTy.getAsOpaquePtr();
514 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
515 return ast_context->UnsignedShortTy.getAsOpaquePtr();
516 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
517 return ast_context->UnsignedIntTy.getAsOpaquePtr();
518 break;
519
520 case DW_ATE_complex_float:
521 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
522 return ast_context->FloatComplexTy.getAsOpaquePtr();
523 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
524 return ast_context->DoubleComplexTy.getAsOpaquePtr();
525 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
526 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
527 break;
528
529 case DW_ATE_float:
530 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
531 return ast_context->FloatTy.getAsOpaquePtr();
532 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
533 return ast_context->DoubleTy.getAsOpaquePtr();
534 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
535 return ast_context->LongDoubleTy.getAsOpaquePtr();
536 break;
537
538 case DW_ATE_signed:
539 if (type_name)
540 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000541 if (strstr(type_name, "long long"))
Chris Lattner24943d22010-06-08 16:52:24 +0000542 {
Chris Lattner24943d22010-06-08 16:52:24 +0000543 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
544 return ast_context->LongLongTy.getAsOpaquePtr();
545 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000546 else if (strstr(type_name, "long"))
547 {
548 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
549 return ast_context->LongTy.getAsOpaquePtr();
550 }
551 else if (strstr(type_name, "short"))
Chris Lattner24943d22010-06-08 16:52:24 +0000552 {
553 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
554 return ast_context->ShortTy.getAsOpaquePtr();
555 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000556 else if (strstr(type_name, "char"))
Chris Lattner24943d22010-06-08 16:52:24 +0000557 {
558 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
559 return ast_context->CharTy.getAsOpaquePtr();
560 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
561 return ast_context->SignedCharTy.getAsOpaquePtr();
562 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000563 else if (strstr(type_name, "int"))
564 {
565 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
566 return ast_context->IntTy.getAsOpaquePtr();
567 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
568 return ast_context->Int128Ty.getAsOpaquePtr();
569 }
570 else if (streq(type_name, "wchar_t"))
Chris Lattner24943d22010-06-08 16:52:24 +0000571 {
572 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
573 return ast_context->WCharTy.getAsOpaquePtr();
574 }
Chris Lattner24943d22010-06-08 16:52:24 +0000575 }
576 // We weren't able to match up a type name, just search by size
577 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
578 return ast_context->CharTy.getAsOpaquePtr();
579 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
580 return ast_context->ShortTy.getAsOpaquePtr();
581 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
582 return ast_context->IntTy.getAsOpaquePtr();
583 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
584 return ast_context->LongTy.getAsOpaquePtr();
585 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
586 return ast_context->LongLongTy.getAsOpaquePtr();
587 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
588 return ast_context->Int128Ty.getAsOpaquePtr();
589 break;
590
591 case DW_ATE_signed_char:
592 if (type_name)
593 {
594 if (streq(type_name, "signed char"))
595 {
596 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
597 return ast_context->SignedCharTy.getAsOpaquePtr();
598 }
599 }
600 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
601 return ast_context->CharTy.getAsOpaquePtr();
602 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
603 return ast_context->SignedCharTy.getAsOpaquePtr();
604 break;
605
606 case DW_ATE_unsigned:
607 if (type_name)
608 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000609 if (strstr(type_name, "long long"))
610 {
611 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
612 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
613 }
614 else if (strstr(type_name, "long"))
615 {
616 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
617 return ast_context->UnsignedLongTy.getAsOpaquePtr();
618 }
619 else if (strstr(type_name, "short"))
620 {
621 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
622 return ast_context->UnsignedShortTy.getAsOpaquePtr();
623 }
624 else if (strstr(type_name, "char"))
625 {
626 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
627 return ast_context->UnsignedCharTy.getAsOpaquePtr();
628 }
629 else if (strstr(type_name, "int"))
Chris Lattner24943d22010-06-08 16:52:24 +0000630 {
631 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
632 return ast_context->UnsignedIntTy.getAsOpaquePtr();
633 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
634 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
635 }
Chris Lattner24943d22010-06-08 16:52:24 +0000636 }
637 // We weren't able to match up a type name, just search by size
638 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
639 return ast_context->UnsignedCharTy.getAsOpaquePtr();
640 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
641 return ast_context->UnsignedShortTy.getAsOpaquePtr();
642 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
643 return ast_context->UnsignedIntTy.getAsOpaquePtr();
644 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
645 return ast_context->UnsignedLongTy.getAsOpaquePtr();
646 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
647 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
648 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
649 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
650 break;
651
652 case DW_ATE_unsigned_char:
653 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
654 return ast_context->UnsignedCharTy.getAsOpaquePtr();
655 break;
656
657 case DW_ATE_imaginary_float:
658 break;
659 }
660 }
661 // This assert should fire for anything that we don't catch above so we know
662 // to fix any issues we run into.
663 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
664 return NULL;
665}
666
Greg Clayton462d4142010-09-29 01:12:09 +0000667clang_type_t
668ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
Chris Lattner24943d22010-06-08 16:52:24 +0000669{
Sean Callanana751f7b2010-09-17 02:24:29 +0000670 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000671}
672
Greg Clayton462d4142010-09-29 01:12:09 +0000673clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000674ClangASTContext::GetBuiltInType_objc_id()
675{
Sean Callanan04325062010-10-25 00:29:48 +0000676 return getASTContext()->ObjCBuiltinIdTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000677}
678
Greg Clayton462d4142010-09-29 01:12:09 +0000679clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000680ClangASTContext::GetBuiltInType_objc_Class()
681{
Sean Callanan04325062010-10-25 00:29:48 +0000682 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000683}
684
Greg Clayton462d4142010-09-29 01:12:09 +0000685clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000686ClangASTContext::GetBuiltInType_objc_selector()
687{
Sean Callanan04325062010-10-25 00:29:48 +0000688 return getASTContext()->ObjCBuiltinSelTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000689}
690
Greg Clayton462d4142010-09-29 01:12:09 +0000691clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000692ClangASTContext::GetCStringType (bool is_const)
693{
694 QualType char_type(getASTContext()->CharTy);
695
696 if (is_const)
697 char_type.addConst();
698
699 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
700}
701
Greg Clayton462d4142010-09-29 01:12:09 +0000702clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000703ClangASTContext::GetVoidPtrType (bool is_const)
704{
705 return GetVoidPtrType(getASTContext(), is_const);
706}
707
Greg Clayton462d4142010-09-29 01:12:09 +0000708clang_type_t
709ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
Chris Lattner24943d22010-06-08 16:52:24 +0000710{
711 QualType void_ptr_type(ast_context->VoidPtrTy);
712
713 if (is_const)
714 void_ptr_type.addConst();
715
716 return void_ptr_type.getAsOpaquePtr();
717}
718
Sean Callanan839fde42010-10-28 18:19:36 +0000719class NullDiagnosticClient : public DiagnosticClient
720{
721public:
722 NullDiagnosticClient ()
723 {
724 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
725 }
726
727 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
728 {
729 if (m_log)
730 {
731 llvm::SmallVectorImpl<char> diag_str(10);
732 info.FormatDiagnostic(diag_str);
733 diag_str.push_back('\0');
734 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
735 }
736 }
737private:
Greg Claytone005f2c2010-11-06 01:53:30 +0000738 LogSP m_log;
Sean Callanan839fde42010-10-28 18:19:36 +0000739};
740
Greg Clayton462d4142010-09-29 01:12:09 +0000741clang_type_t
742ClangASTContext::CopyType (ASTContext *dest_context,
743 ASTContext *source_context,
744 clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000745{
Sean Callananad5b61b2010-10-28 18:43:33 +0000746 // null_client's ownership is transferred to diagnostics
Sean Callanan839fde42010-10-28 18:19:36 +0000747 NullDiagnosticClient *null_client = new NullDiagnosticClient;
748 Diagnostic diagnostics(null_client);
Chris Lattner24943d22010-06-08 16:52:24 +0000749 FileManager file_manager;
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000750 FileSystemOptions file_system_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000751 ASTImporter importer(diagnostics,
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000752 *dest_context, file_manager, file_system_options,
753 *source_context, file_manager, file_system_options);
Sean Callanancf18faa2010-11-09 22:37:10 +0000754
755 QualType src = QualType::getFromOpaquePtr(clang_type);
756 QualType dst = importer.Import(src);
757
758 return dst.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000759}
760
Greg Clayton6916e352010-11-13 03:52:47 +0000761
762clang::Decl *
763ClangASTContext::CopyDecl (ASTContext *dest_context,
764 ASTContext *source_context,
765 clang::Decl *source_decl)
766{
767 // null_client's ownership is transferred to diagnostics
768 NullDiagnosticClient *null_client = new NullDiagnosticClient;
769 Diagnostic diagnostics(null_client);
770 FileManager file_manager;
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000771 FileSystemOptions file_system_options;
Greg Clayton6916e352010-11-13 03:52:47 +0000772 ASTImporter importer(diagnostics,
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000773 *dest_context, file_manager, file_system_options,
774 *source_context, file_manager, file_system_options);
Greg Clayton6916e352010-11-13 03:52:47 +0000775
776 return importer.Import(source_decl);
777}
778
Sean Callanan8d825062010-07-16 00:00:27 +0000779bool
Greg Clayton462d4142010-09-29 01:12:09 +0000780ClangASTContext::AreTypesSame(ASTContext *ast_context,
781 clang_type_t type1,
782 clang_type_t type2)
Sean Callanan5510ddd2010-07-15 22:30:52 +0000783{
784 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
785 QualType::getFromOpaquePtr(type2));
786}
787
Chris Lattner24943d22010-06-08 16:52:24 +0000788#pragma mark CVR modifiers
789
Greg Clayton462d4142010-09-29 01:12:09 +0000790clang_type_t
791ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000792{
793 if (clang_type)
794 {
795 QualType result(QualType::getFromOpaquePtr(clang_type));
796 result.addConst();
797 return result.getAsOpaquePtr();
798 }
799 return NULL;
800}
801
Greg Clayton462d4142010-09-29 01:12:09 +0000802clang_type_t
803ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000804{
805 if (clang_type)
806 {
807 QualType result(QualType::getFromOpaquePtr(clang_type));
808 result.getQualifiers().setRestrict (true);
809 return result.getAsOpaquePtr();
810 }
811 return NULL;
812}
813
Greg Clayton462d4142010-09-29 01:12:09 +0000814clang_type_t
815ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000816{
817 if (clang_type)
818 {
819 QualType result(QualType::getFromOpaquePtr(clang_type));
820 result.getQualifiers().setVolatile (true);
821 return result.getAsOpaquePtr();
822 }
823 return NULL;
824}
825
826#pragma mark Structure, Unions, Classes
827
Greg Clayton462d4142010-09-29 01:12:09 +0000828clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000829ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000830{
831 ASTContext *ast_context = getASTContext();
832 assert (ast_context != NULL);
Sean Callanan04325062010-10-25 00:29:48 +0000833
Chris Lattner24943d22010-06-08 16:52:24 +0000834 if (decl_ctx == NULL)
835 decl_ctx = ast_context->getTranslationUnitDecl();
836
Greg Clayton9488b742010-07-28 02:04:09 +0000837
Greg Clayton585660c2010-08-05 01:57:25 +0000838 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000839 {
Greg Clayton306edca2010-10-11 02:25:34 +0000840 bool isForwardDecl = true;
Greg Clayton9488b742010-07-28 02:04:09 +0000841 bool isInternal = false;
842 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
843 }
844
Chris Lattner24943d22010-06-08 16:52:24 +0000845 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
846 // we will need to update this code. I was told to currently always use
847 // the CXXRecordDecl class since we often don't know from debug information
848 // if something is struct or a class, so we default to always use the more
849 // complete definition just in case.
850 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
851 (TagDecl::TagKind)kind,
852 decl_ctx,
853 SourceLocation(),
854 name && name[0] ? &ast_context->Idents.get(name) : NULL);
855
856 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
857}
858
Greg Claytondbf26152010-10-01 23:13:49 +0000859static bool
860IsOperator (const char *name, OverloadedOperatorKind &op_kind)
861{
862 if (name == NULL || name[0] == '\0')
863 return false;
864
865 if (::strstr(name, "operator ") != name)
866 return false;
867
868 const char *post_op_name = name + 9;
869
870 // This is an operator, set the overloaded operator kind to invalid
871 // in case this is a conversion operator...
872 op_kind = NUM_OVERLOADED_OPERATORS;
873
874 switch (post_op_name[0])
875 {
876 case 'n':
877 if (strcmp (post_op_name, "new") == 0)
878 op_kind = OO_New;
879 else if (strcmp (post_op_name, "new[]") == 0)
880 op_kind = OO_Array_New;
881 break;
882
883 case 'd':
884 if (strcmp (post_op_name, "delete") == 0)
885 op_kind = OO_Delete;
886 else if (strcmp (post_op_name, "delete[]") == 0)
887 op_kind = OO_Array_Delete;
888 break;
889
890 case '+':
891 if (post_op_name[1] == '\0')
892 op_kind = OO_Plus;
893 else if (post_op_name[2] == '\0')
894 {
895 if (post_op_name[1] == '=')
896 op_kind = OO_PlusEqual;
897 else if (post_op_name[1] == '+')
898 op_kind = OO_PlusPlus;
899 }
900 break;
901
902 case '-':
903 if (post_op_name[1] == '\0')
904 op_kind = OO_Minus;
905 else if (post_op_name[2] == '\0')
906 {
907 switch (post_op_name[1])
908 {
909 case '=': op_kind = OO_MinusEqual; break;
910 case '-': op_kind = OO_MinusMinus; break;
911 case '>': op_kind = OO_Arrow; break;
912 }
913 }
914 else if (post_op_name[3] == '\0')
915 {
916 if (post_op_name[2] == '*')
917 op_kind = OO_ArrowStar; break;
918 }
919 break;
920
921 case '*':
922 if (post_op_name[1] == '\0')
923 op_kind = OO_Star;
924 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
925 op_kind = OO_StarEqual;
926 break;
927
928 case '/':
929 if (post_op_name[1] == '\0')
930 op_kind = OO_Slash;
931 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
932 op_kind = OO_SlashEqual;
933 break;
934
935 case '%':
936 if (post_op_name[1] == '\0')
937 op_kind = OO_Percent;
938 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
939 op_kind = OO_PercentEqual;
940 break;
941
942
943 case '^':
944 if (post_op_name[1] == '\0')
945 op_kind = OO_Caret;
946 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
947 op_kind = OO_CaretEqual;
948 break;
949
950 case '&':
951 if (post_op_name[1] == '\0')
952 op_kind = OO_Amp;
953 else if (post_op_name[2] == '\0')
954 {
955 switch (post_op_name[1])
956 {
957 case '=': op_kind = OO_AmpEqual; break;
958 case '&': op_kind = OO_AmpAmp; break;
959 }
960 }
961 break;
962
963 case '|':
964 if (post_op_name[1] == '\0')
965 op_kind = OO_Pipe;
966 else if (post_op_name[2] == '\0')
967 {
968 switch (post_op_name[1])
969 {
970 case '=': op_kind = OO_PipeEqual; break;
971 case '|': op_kind = OO_PipePipe; break;
972 }
973 }
974 break;
975
976 case '~':
977 if (post_op_name[1] == '\0')
978 op_kind = OO_Tilde;
979 break;
980
981 case '!':
982 if (post_op_name[1] == '\0')
983 op_kind = OO_Exclaim;
984 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
985 op_kind = OO_ExclaimEqual;
986 break;
987
988 case '=':
989 if (post_op_name[1] == '\0')
990 op_kind = OO_Equal;
991 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
992 op_kind = OO_EqualEqual;
993 break;
994
995 case '<':
996 if (post_op_name[1] == '\0')
997 op_kind = OO_Less;
998 else if (post_op_name[2] == '\0')
999 {
1000 switch (post_op_name[1])
1001 {
1002 case '<': op_kind = OO_LessLess; break;
1003 case '=': op_kind = OO_LessEqual; break;
1004 }
1005 }
1006 else if (post_op_name[3] == '\0')
1007 {
1008 if (post_op_name[2] == '=')
1009 op_kind = OO_LessLessEqual;
1010 }
1011 break;
1012
1013 case '>':
1014 if (post_op_name[1] == '\0')
1015 op_kind = OO_Greater;
1016 else if (post_op_name[2] == '\0')
1017 {
1018 switch (post_op_name[1])
1019 {
1020 case '>': op_kind = OO_GreaterGreater; break;
1021 case '=': op_kind = OO_GreaterEqual; break;
1022 }
1023 }
1024 else if (post_op_name[1] == '>' &&
1025 post_op_name[2] == '=' &&
1026 post_op_name[3] == '\0')
1027 {
1028 op_kind = OO_GreaterGreaterEqual;
1029 }
1030 break;
1031
1032 case ',':
1033 if (post_op_name[1] == '\0')
1034 op_kind = OO_Comma;
1035 break;
1036
1037 case '(':
1038 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1039 op_kind = OO_Call;
1040 break;
1041
1042 case '[':
1043 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1044 op_kind = OO_Subscript;
1045 break;
1046 }
1047
1048 return true;
1049}
Greg Clayton412440a2010-09-23 01:09:21 +00001050CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +00001051ClangASTContext::AddMethodToCXXRecordType
1052(
Greg Clayton462d4142010-09-29 01:12:09 +00001053 ASTContext *ast_context,
1054 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001055 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001056 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001057 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001058 bool is_virtual,
1059 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001060 bool is_inline,
1061 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +00001062)
Sean Callanan79523002010-09-17 02:58:26 +00001063{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001064 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +00001065 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001066
1067 assert(ast_context);
1068
1069 IdentifierTable *identifier_table = &ast_context->Idents;
1070
1071 assert(identifier_table);
1072
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001073 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +00001074
1075 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +00001076
Greg Clayton1d8173f2010-09-24 05:15:53 +00001077 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001078 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001079
Greg Clayton1d8173f2010-09-24 05:15:53 +00001080 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +00001081
Greg Clayton1d8173f2010-09-24 05:15:53 +00001082 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001083 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001084
Greg Clayton1d8173f2010-09-24 05:15:53 +00001085 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +00001086
Greg Clayton1d8173f2010-09-24 05:15:53 +00001087 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001088 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001089
1090 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1091
Greg Clayton1d8173f2010-09-24 05:15:53 +00001092 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001093 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001094
Greg Clayton1d8173f2010-09-24 05:15:53 +00001095 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001096
Greg Clayton30449d52010-10-01 02:31:07 +00001097 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001098
Greg Clayton30449d52010-10-01 02:31:07 +00001099 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001100
Greg Clayton90e325d2010-10-01 03:45:20 +00001101 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001102
Greg Clayton5325a362010-10-02 01:40:05 +00001103 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001104
Greg Clayton5325a362010-10-02 01:40:05 +00001105 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001106 return NULL;
1107
Greg Clayton5325a362010-10-02 01:40:05 +00001108 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001109
1110 if (!method_function_prototype)
1111 return NULL;
1112
1113 unsigned int num_params = method_function_prototype->getNumArgs();
1114
1115 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001116 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001117 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1118 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001119 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001120 method_qual_type,
Sean Callanan8950c9a2010-10-29 18:38:40 +00001121 NULL,
Greg Clayton90e325d2010-10-01 03:45:20 +00001122 is_inline,
1123 is_implicitly_declared);
1124 }
1125 else if (decl_name == record_decl->getDeclName())
1126 {
Greg Clayton30449d52010-10-01 02:31:07 +00001127 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1128 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001129 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001130 method_qual_type,
1131 NULL, // TypeSourceInfo *
1132 is_explicit,
1133 is_inline,
1134 is_implicitly_declared);
1135 }
1136 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001137 {
Greg Claytondbf26152010-10-01 23:13:49 +00001138
1139 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1140 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001141 {
Greg Claytondbf26152010-10-01 23:13:49 +00001142 if (op_kind != NUM_OVERLOADED_OPERATORS)
1143 {
1144 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001145 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001146 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001147 method_qual_type,
1148 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001149 is_static,
1150 SC_None,
1151 is_inline);
1152 }
1153 else if (num_params == 0)
1154 {
1155 // Conversion operators don't take params...
1156 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1157 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001158 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001159 method_qual_type,
1160 NULL, // TypeSourceInfo *
1161 is_inline,
1162 is_explicit);
1163 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001164 }
Greg Claytondbf26152010-10-01 23:13:49 +00001165
1166 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001167 {
1168 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1169 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001170 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001171 method_qual_type,
1172 NULL, // TypeSourceInfo *
1173 is_static,
1174 SC_None,
1175 is_inline);
1176 }
Greg Clayton30449d52010-10-01 02:31:07 +00001177 }
Greg Claytondbf26152010-10-01 23:13:49 +00001178
Greg Clayton462d4142010-09-29 01:12:09 +00001179 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001180
1181 cxx_method_decl->setAccess (access_specifier);
1182 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001183
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001184 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001185
1186 ParmVarDecl *params[num_params];
1187
1188 for (int param_index = 0;
1189 param_index < num_params;
1190 ++param_index)
1191 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001192 params[param_index] = ParmVarDecl::Create (*ast_context,
1193 cxx_method_decl,
1194 SourceLocation(),
1195 NULL, // anonymous
1196 method_function_prototype->getArgType(param_index),
1197 NULL,
1198 SC_None,
1199 SC_None,
1200 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001201 }
1202
Greg Clayton1d8173f2010-09-24 05:15:53 +00001203 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001204
Greg Clayton1d8173f2010-09-24 05:15:53 +00001205 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001206
Greg Clayton412440a2010-09-23 01:09:21 +00001207 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001208}
1209
1210bool
Greg Clayton84f80752010-07-22 18:30:50 +00001211ClangASTContext::AddFieldToRecordType
1212(
Greg Clayton462d4142010-09-29 01:12:09 +00001213 ASTContext *ast_context,
1214 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001215 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001216 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001217 AccessType access,
1218 uint32_t bitfield_bit_size
1219)
Chris Lattner24943d22010-06-08 16:52:24 +00001220{
1221 if (record_clang_type == NULL || field_type == NULL)
1222 return false;
1223
Sean Callanan60a0ced2010-09-16 20:01:08 +00001224 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001225
1226 assert (ast_context != NULL);
1227 assert (identifier_table != NULL);
1228
1229 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1230
Greg Clayton1674b122010-07-21 22:12:05 +00001231 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001232 if (clang_type)
1233 {
1234 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1235
1236 if (record_type)
1237 {
1238 RecordDecl *record_decl = record_type->getDecl();
1239
Chris Lattner24943d22010-06-08 16:52:24 +00001240 clang::Expr *bit_width = NULL;
1241 if (bitfield_bit_size != 0)
1242 {
1243 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001244 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001245 }
Greg Clayton84f80752010-07-22 18:30:50 +00001246 FieldDecl *field = FieldDecl::Create (*ast_context,
1247 record_decl,
1248 SourceLocation(),
1249 name ? &identifier_table->get(name) : NULL, // Identifier
1250 QualType::getFromOpaquePtr(field_type), // Field type
1251 NULL, // DeclaratorInfo *
1252 bit_width, // BitWidth
1253 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001254
Greg Clayton84f80752010-07-22 18:30:50 +00001255 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001256
1257 if (field)
1258 {
1259 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001260 }
1261 }
Greg Clayton9488b742010-07-28 02:04:09 +00001262 else
1263 {
1264 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1265 if (objc_class_type)
1266 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001267 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001268 ClangASTContext::AddObjCClassIVar (ast_context,
1269 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001270 name,
1271 field_type,
1272 access,
1273 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001274 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001275 }
1276 }
Chris Lattner24943d22010-06-08 16:52:24 +00001277 }
1278 return false;
1279}
1280
1281bool
1282ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1283{
1284 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1285}
1286
1287bool
1288ClangASTContext::FieldIsBitfield
1289(
1290 ASTContext *ast_context,
1291 FieldDecl* field,
1292 uint32_t& bitfield_bit_size
1293)
1294{
1295 if (ast_context == NULL || field == NULL)
1296 return false;
1297
1298 if (field->isBitField())
1299 {
1300 Expr* bit_width_expr = field->getBitWidth();
1301 if (bit_width_expr)
1302 {
1303 llvm::APSInt bit_width_apsint;
1304 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1305 {
1306 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1307 return true;
1308 }
1309 }
1310 }
1311 return false;
1312}
1313
1314bool
1315ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1316{
1317 if (record_decl == NULL)
1318 return false;
1319
1320 if (!record_decl->field_empty())
1321 return true;
1322
1323 // No fields, lets check this is a CXX record and check the base classes
1324 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1325 if (cxx_record_decl)
1326 {
1327 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1328 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1329 base_class != base_class_end;
1330 ++base_class)
1331 {
1332 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1333 if (RecordHasFields(base_class_decl))
1334 return true;
1335 }
1336 }
1337 return false;
1338}
1339
1340void
Greg Clayton462d4142010-09-29 01:12:09 +00001341ClangASTContext::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 +00001342{
1343 if (clang_qual_type)
1344 {
1345 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001346 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001347 if (clang_type)
1348 {
1349 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1350 if (record_type)
1351 {
1352 RecordDecl *record_decl = record_type->getDecl();
1353 if (record_decl)
1354 {
1355 uint32_t field_idx;
1356 RecordDecl::field_iterator field, field_end;
1357 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1358 field != field_end;
1359 ++field, ++field_idx)
1360 {
1361 // If no accessibility was assigned, assign the correct one
1362 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1363 field->setAccess ((AccessSpecifier)default_accessibility);
1364 }
1365 }
1366 }
1367 }
1368 }
1369}
1370
1371#pragma mark C++ Base Classes
1372
1373CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001374ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001375{
1376 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001377 return new CXXBaseSpecifier (SourceRange(),
1378 is_virtual,
1379 base_of_class,
1380 ConvertAccessTypeToAccessSpecifier (access),
1381 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001382 return NULL;
1383}
1384
Greg Claytone9d0df42010-07-02 01:29:13 +00001385void
1386ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1387{
1388 for (unsigned i=0; i<num_base_classes; ++i)
1389 {
1390 delete base_classes[i];
1391 base_classes[i] = NULL;
1392 }
1393}
1394
Chris Lattner24943d22010-06-08 16:52:24 +00001395bool
Greg Clayton462d4142010-09-29 01:12:09 +00001396ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001397{
1398 if (class_clang_type)
1399 {
Greg Clayton1674b122010-07-21 22:12:05 +00001400 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001401 if (clang_type)
1402 {
1403 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1404 if (record_type)
1405 {
1406 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1407 if (cxx_record_decl)
1408 {
Chris Lattner24943d22010-06-08 16:52:24 +00001409 cxx_record_decl->setBases(base_classes, num_base_classes);
1410 return true;
1411 }
1412 }
1413 }
1414 }
1415 return false;
1416}
Greg Clayton84f80752010-07-22 18:30:50 +00001417#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001418
Greg Clayton462d4142010-09-29 01:12:09 +00001419clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001420ClangASTContext::CreateObjCClass
1421(
1422 const char *name,
1423 DeclContext *decl_ctx,
1424 bool isForwardDecl,
1425 bool isInternal
1426)
1427{
1428 ASTContext *ast_context = getASTContext();
1429 assert (ast_context != NULL);
1430 assert (name && name[0]);
1431 if (decl_ctx == NULL)
1432 decl_ctx = ast_context->getTranslationUnitDecl();
1433
1434 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1435 // we will need to update this code. I was told to currently always use
1436 // the CXXRecordDecl class since we often don't know from debug information
1437 // if something is struct or a class, so we default to always use the more
1438 // complete definition just in case.
1439 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1440 decl_ctx,
1441 SourceLocation(),
1442 &ast_context->Idents.get(name),
1443 SourceLocation(),
1444 isForwardDecl,
1445 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001446
1447 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001448}
1449
1450bool
Greg Clayton462d4142010-09-29 01:12:09 +00001451ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001452{
1453 if (class_opaque_type && super_opaque_type)
1454 {
1455 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1456 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1457 clang::Type *class_type = class_qual_type.getTypePtr();
1458 clang::Type *super_type = super_qual_type.getTypePtr();
1459 if (class_type && super_type)
1460 {
1461 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1462 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1463 if (objc_class_type && objc_super_type)
1464 {
1465 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1466 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1467 if (class_interface_decl && super_interface_decl)
1468 {
1469 class_interface_decl->setSuperClass(super_interface_decl);
1470 return true;
1471 }
1472 }
1473 }
1474 }
1475 return false;
1476}
1477
1478
1479bool
1480ClangASTContext::AddObjCClassIVar
1481(
Greg Clayton462d4142010-09-29 01:12:09 +00001482 ASTContext *ast_context,
1483 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001484 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001485 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001486 AccessType access,
1487 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001488 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001489)
1490{
1491 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1492 return false;
1493
Sean Callanan60a0ced2010-09-16 20:01:08 +00001494 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001495
1496 assert (ast_context != NULL);
1497 assert (identifier_table != NULL);
1498
1499 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1500
1501 clang::Type *class_type = class_qual_type.getTypePtr();
1502 if (class_type)
1503 {
1504 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1505
1506 if (objc_class_type)
1507 {
1508 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1509
1510 if (class_interface_decl)
1511 {
1512 clang::Expr *bit_width = NULL;
1513 if (bitfield_bit_size != 0)
1514 {
1515 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001516 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001517 }
1518
Greg Clayton9488b742010-07-28 02:04:09 +00001519 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1520 class_interface_decl,
1521 SourceLocation(),
1522 &identifier_table->get(name), // Identifier
1523 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1524 NULL, // TypeSourceInfo *
1525 ConvertAccessTypeToObjCIvarAccessControl (access),
1526 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001527 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001528
1529 if (field)
1530 {
1531 class_interface_decl->addDecl(field);
1532 return true;
1533 }
Greg Clayton84f80752010-07-22 18:30:50 +00001534 }
1535 }
1536 }
1537 return false;
1538}
Chris Lattner24943d22010-06-08 16:52:24 +00001539
Greg Clayton9488b742010-07-28 02:04:09 +00001540
1541bool
Greg Clayton462d4142010-09-29 01:12:09 +00001542ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001543{
1544 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1545
1546 clang::Type *class_type = class_qual_type.getTypePtr();
1547 if (class_type)
1548 {
1549 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1550
1551 if (objc_class_type)
1552 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1553 }
1554 return false;
1555}
1556
1557bool
1558ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1559{
1560 while (class_interface_decl)
1561 {
1562 if (class_interface_decl->ivar_size() > 0)
1563 return true;
1564
1565 if (check_superclass)
1566 class_interface_decl = class_interface_decl->getSuperClass();
1567 else
1568 break;
1569 }
1570 return false;
1571}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001572
Greg Clayton462d4142010-09-29 01:12:09 +00001573ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001574ClangASTContext::AddMethodToObjCObjectType
1575(
Greg Clayton462d4142010-09-29 01:12:09 +00001576 ASTContext *ast_context,
1577 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001578 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001579 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001580 lldb::AccessType access
1581)
1582{
1583 if (class_opaque_type == NULL || method_opaque_type == NULL)
1584 return NULL;
1585
1586 IdentifierTable *identifier_table = &ast_context->Idents;
1587
1588 assert (ast_context != NULL);
1589 assert (identifier_table != NULL);
1590
1591 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1592
1593 clang::Type *class_type = class_qual_type.getTypePtr();
1594 if (class_type == NULL)
1595 return NULL;
1596
1597 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1598
1599 if (objc_class_type == NULL)
1600 return NULL;
1601
1602 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1603
1604 if (class_interface_decl == NULL)
1605 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001606
Greg Clayton1d8173f2010-09-24 05:15:53 +00001607 const char *selector_start = ::strchr (name, ' ');
1608 if (selector_start == NULL)
1609 return NULL;
1610
1611 selector_start++;
1612 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1613 return NULL;
1614 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1615
Greg Claytonad60bf42010-10-12 02:24:53 +00001616 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001617 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001618 //printf ("name = '%s'\n", name);
1619
1620 unsigned num_selectors_with_args = 0;
1621 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001622 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001623 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001624 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001625 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001626 bool has_arg = (start[len] == ':');
1627 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001628 ++num_selectors_with_args;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001629 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001630 if (has_arg)
1631 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001632 }
1633
1634
1635 if (selector_idents.size() == 0)
1636 return 0;
1637
Greg Claytonad60bf42010-10-12 02:24:53 +00001638 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001639 selector_idents.data());
1640
1641 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1642
1643 // Populate the method decl with parameter decls
1644 clang::Type *method_type(method_qual_type.getTypePtr());
1645
1646 if (method_type == NULL)
1647 return NULL;
1648
1649 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1650
1651 if (!method_function_prototype)
1652 return NULL;
1653
1654
1655 bool is_variadic = false;
1656 bool is_synthesized = false;
1657 bool is_defined = false;
1658 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1659
1660 const unsigned num_args = method_function_prototype->getNumArgs();
1661
1662 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1663 SourceLocation(), // beginLoc,
1664 SourceLocation(), // endLoc,
1665 method_selector,
1666 method_function_prototype->getResultType(),
1667 NULL, // TypeSourceInfo *ResultTInfo,
1668 GetDeclContextForType (class_opaque_type),
1669 name[0] == '-',
1670 is_variadic,
1671 is_synthesized,
1672 is_defined,
1673 imp_control,
1674 num_args);
1675
1676
1677 if (objc_method_decl == NULL)
1678 return NULL;
1679
1680 if (num_args > 0)
1681 {
1682 llvm::SmallVector<ParmVarDecl *, 12> params;
1683
1684 for (int param_index = 0; param_index < num_args; ++param_index)
1685 {
1686 params.push_back (ParmVarDecl::Create (*ast_context,
1687 objc_method_decl,
1688 SourceLocation(),
1689 NULL, // anonymous
1690 method_function_prototype->getArgType(param_index),
1691 NULL,
1692 SC_Auto,
1693 SC_Auto,
1694 NULL));
1695 }
1696
1697 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1698 }
1699
1700 class_interface_decl->addDecl (objc_method_decl);
1701
1702
1703 return objc_method_decl;
1704}
1705
1706
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001707uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001708ClangASTContext::GetTypeInfo
1709(
1710 clang_type_t clang_type,
1711 clang::ASTContext *ast_context,
1712 clang_type_t *pointee_or_element_clang_type
1713)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001714{
1715 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001716 return 0;
1717
1718 if (pointee_or_element_clang_type)
1719 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001720
1721 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1722
1723 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1724 switch (type_class)
1725 {
Sean Callanan04325062010-10-25 00:29:48 +00001726 case clang::Type::Builtin:
1727 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1728 {
Sean Callanan04325062010-10-25 00:29:48 +00001729 case clang::BuiltinType::ObjCId:
1730 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001731 if (ast_context && pointee_or_element_clang_type)
1732 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001733 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001734
1735 default:
1736 break;
Sean Callanan04325062010-10-25 00:29:48 +00001737 }
1738 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001739
1740 case clang::Type::BlockPointer:
1741 if (pointee_or_element_clang_type)
1742 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1743 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1744
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001745 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001746
1747 case clang::Type::ConstantArray:
1748 case clang::Type::DependentSizedArray:
1749 case clang::Type::IncompleteArray:
1750 case clang::Type::VariableArray:
1751 if (pointee_or_element_clang_type)
1752 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1753 return eTypeHasChildren | eTypeIsArray;
1754
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001755 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001756 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1757 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1758 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001759
1760 case clang::Type::Enum:
1761 if (pointee_or_element_clang_type)
1762 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1763 return eTypeIsEnumeration | eTypeHasValue;
1764
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001765 case clang::Type::Elaborated: return 0;
1766 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1767 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1768 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001769 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001770
1771 case clang::Type::LValueReference:
1772 case clang::Type::RValueReference:
1773 if (pointee_or_element_clang_type)
1774 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1775 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1776
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001777 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001778
1779 case clang::Type::ObjCObjectPointer:
1780 if (pointee_or_element_clang_type)
1781 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1782 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1783
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001784 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1785 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001786
1787 case clang::Type::Pointer:
1788 if (pointee_or_element_clang_type)
1789 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1790 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1791
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001792 case clang::Type::Record:
1793 if (qual_type->getAsCXXRecordDecl())
1794 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1795 else
1796 return eTypeHasChildren | eTypeIsStructUnion;
1797 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001798 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1799 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1800 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001801
1802 case clang::Type::Typedef:
1803 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1804 ast_context,
1805 pointee_or_element_clang_type);
1806
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001807 case clang::Type::TypeOfExpr: return 0;
1808 case clang::Type::TypeOf: return 0;
1809 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001810 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1811 default: return 0;
1812 }
1813 return 0;
1814}
1815
Greg Clayton9488b742010-07-28 02:04:09 +00001816
Chris Lattner24943d22010-06-08 16:52:24 +00001817#pragma mark Aggregate Types
1818
1819bool
Greg Clayton462d4142010-09-29 01:12:09 +00001820ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001821{
1822 if (clang_type == NULL)
1823 return false;
1824
1825 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1826
Greg Clayton03e0f972010-09-13 03:32:57 +00001827 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1828 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001829 {
Greg Clayton1674b122010-07-21 22:12:05 +00001830 case clang::Type::IncompleteArray:
1831 case clang::Type::VariableArray:
1832 case clang::Type::ConstantArray:
1833 case clang::Type::ExtVector:
1834 case clang::Type::Vector:
1835 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001836 case clang::Type::ObjCObject:
1837 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001838 return true;
1839
Greg Clayton1674b122010-07-21 22:12:05 +00001840 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001841 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1842
1843 default:
1844 break;
1845 }
1846 // The clang type does have a value
1847 return false;
1848}
1849
1850uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001851ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001852{
1853 if (clang_qual_type == NULL)
1854 return 0;
1855
1856 uint32_t num_children = 0;
1857 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001858 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1859 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001860 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001861 case clang::Type::Builtin:
1862 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1863 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001864 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001865 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001866 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001867 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001868
1869 default:
1870 break;
1871 }
1872 break;
1873
Greg Clayton1674b122010-07-21 22:12:05 +00001874 case clang::Type::Record:
Greg Clayton53d287b2010-11-11 02:14:53 +00001875 if (ClangASTType::IsDefined (clang_qual_type))
Chris Lattner24943d22010-06-08 16:52:24 +00001876 {
1877 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1878 const RecordDecl *record_decl = record_type->getDecl();
1879 assert(record_decl);
1880 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1881 if (cxx_record_decl)
1882 {
1883 if (omit_empty_base_classes)
1884 {
1885 // Check each base classes to see if it or any of its
1886 // base classes contain any fields. This can help
1887 // limit the noise in variable views by not having to
1888 // show base classes that contain no members.
1889 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1890 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1891 base_class != base_class_end;
1892 ++base_class)
1893 {
1894 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1895
1896 // Skip empty base classes
1897 if (RecordHasFields(base_class_decl) == false)
1898 continue;
1899
1900 num_children++;
1901 }
1902 }
1903 else
1904 {
1905 // Include all base classes
1906 num_children += cxx_record_decl->getNumBases();
1907 }
1908
1909 }
1910 RecordDecl::field_iterator field, field_end;
1911 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1912 ++num_children;
1913 }
1914 break;
1915
Greg Clayton9488b742010-07-28 02:04:09 +00001916 case clang::Type::ObjCObject:
1917 case clang::Type::ObjCInterface:
1918 {
1919 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1920 assert (objc_class_type);
1921 if (objc_class_type)
1922 {
1923 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1924
1925 if (class_interface_decl)
1926 {
1927
1928 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1929 if (superclass_interface_decl)
1930 {
1931 if (omit_empty_base_classes)
1932 {
1933 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1934 ++num_children;
1935 }
1936 else
1937 ++num_children;
1938 }
1939
1940 num_children += class_interface_decl->ivar_size();
1941 }
1942 }
1943 }
1944 break;
1945
1946 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001947 {
1948 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1949 QualType pointee_type = pointer_type->getPointeeType();
1950 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1951 omit_empty_base_classes);
1952 // If this type points to a simple type, then it has 1 child
1953 if (num_pointee_children == 0)
1954 num_children = 1;
1955 else
1956 num_children = num_pointee_children;
1957 }
1958 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001959
Greg Clayton1674b122010-07-21 22:12:05 +00001960 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001961 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1962 break;
1963
Greg Clayton1674b122010-07-21 22:12:05 +00001964 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001965 {
1966 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1967 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001968 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1969 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001970 // If this type points to a simple type, then it has 1 child
1971 if (num_pointee_children == 0)
1972 num_children = 1;
1973 else
1974 num_children = num_pointee_children;
1975 }
1976 break;
1977
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001978 case clang::Type::LValueReference:
1979 case clang::Type::RValueReference:
1980 {
1981 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1982 QualType pointee_type = reference_type->getPointeeType();
1983 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1984 omit_empty_base_classes);
1985 // If this type points to a simple type, then it has 1 child
1986 if (num_pointee_children == 0)
1987 num_children = 1;
1988 else
1989 num_children = num_pointee_children;
1990 }
1991 break;
1992
1993
Greg Clayton1674b122010-07-21 22:12:05 +00001994 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001995 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1996 break;
1997
1998 default:
1999 break;
2000 }
2001 return num_children;
2002}
2003
2004
Greg Clayton462d4142010-09-29 01:12:09 +00002005clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002006ClangASTContext::GetChildClangTypeAtIndex
2007(
2008 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002009 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002010 uint32_t idx,
2011 bool transparent_pointers,
2012 bool omit_empty_base_classes,
2013 std::string& child_name,
2014 uint32_t &child_byte_size,
2015 int32_t &child_byte_offset,
2016 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002017 uint32_t &child_bitfield_bit_offset,
2018 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002019)
2020{
2021 if (parent_clang_type)
2022
2023 return GetChildClangTypeAtIndex (getASTContext(),
2024 parent_name,
2025 parent_clang_type,
2026 idx,
2027 transparent_pointers,
2028 omit_empty_base_classes,
2029 child_name,
2030 child_byte_size,
2031 child_byte_offset,
2032 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002033 child_bitfield_bit_offset,
2034 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002035 return NULL;
2036}
2037
Greg Clayton462d4142010-09-29 01:12:09 +00002038clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002039ClangASTContext::GetChildClangTypeAtIndex
2040(
2041 ASTContext *ast_context,
2042 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002043 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002044 uint32_t idx,
2045 bool transparent_pointers,
2046 bool omit_empty_base_classes,
2047 std::string& child_name,
2048 uint32_t &child_byte_size,
2049 int32_t &child_byte_offset,
2050 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002051 uint32_t &child_bitfield_bit_offset,
2052 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002053)
2054{
2055 if (parent_clang_type == NULL)
2056 return NULL;
2057
2058 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2059 {
2060 uint32_t bit_offset;
2061 child_bitfield_bit_size = 0;
2062 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002063 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002064 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002065 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2066 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002067 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002068 case clang::Type::Builtin:
2069 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2070 {
2071 case clang::BuiltinType::ObjCId:
2072 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002073 child_name = "isa";
2074 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002075 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2076
Greg Clayton960d6a42010-08-03 00:35:52 +00002077 default:
2078 break;
2079 }
2080 break;
2081
2082
Greg Clayton1674b122010-07-21 22:12:05 +00002083 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002084 {
2085 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2086 const RecordDecl *record_decl = record_type->getDecl();
2087 assert(record_decl);
2088 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2089 uint32_t child_idx = 0;
2090
2091 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2092 if (cxx_record_decl)
2093 {
2094 // We might have base classes to print out first
2095 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2096 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2097 base_class != base_class_end;
2098 ++base_class)
2099 {
2100 const CXXRecordDecl *base_class_decl = NULL;
2101
2102 // Skip empty base classes
2103 if (omit_empty_base_classes)
2104 {
2105 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2106 if (RecordHasFields(base_class_decl) == false)
2107 continue;
2108 }
2109
2110 if (idx == child_idx)
2111 {
2112 if (base_class_decl == NULL)
2113 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2114
2115
2116 if (base_class->isVirtual())
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002117 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002118 else
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002119 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002120
2121 // Base classes should be a multiple of 8 bits in size
2122 assert (bit_offset % 8 == 0);
2123 child_byte_offset = bit_offset/8;
2124 std::string base_class_type_name(base_class->getType().getAsString());
2125
2126 child_name.assign(base_class_type_name.c_str());
2127
2128 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2129
2130 // Base classes biut sizes should be a multiple of 8 bits in size
2131 assert (clang_type_info_bit_size % 8 == 0);
2132 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002133 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002134 return base_class->getType().getAsOpaquePtr();
2135 }
2136 // We don't increment the child index in the for loop since we might
2137 // be skipping empty base classes
2138 ++child_idx;
2139 }
2140 }
Chris Lattner24943d22010-06-08 16:52:24 +00002141 // Make sure index is in range...
2142 uint32_t field_idx = 0;
2143 RecordDecl::field_iterator field, field_end;
2144 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2145 {
2146 if (idx == child_idx)
2147 {
2148 // Print the member type if requested
2149 // Print the member name and equal sign
2150 child_name.assign(field->getNameAsString().c_str());
2151
2152 // Figure out the type byte size (field_type_info.first) and
2153 // alignment (field_type_info.second) from the AST context.
2154 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002155 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002156
2157 child_byte_size = field_type_info.first / 8;
2158
2159 // Figure out the field offset within the current struct/union/class type
2160 bit_offset = record_layout.getFieldOffset (field_idx);
2161 child_byte_offset = bit_offset / 8;
2162 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2163 child_bitfield_bit_offset = bit_offset % 8;
2164
2165 return field->getType().getAsOpaquePtr();
2166 }
2167 }
2168 }
2169 break;
2170
Greg Clayton9488b742010-07-28 02:04:09 +00002171 case clang::Type::ObjCObject:
2172 case clang::Type::ObjCInterface:
2173 {
2174 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2175 assert (objc_class_type);
2176 if (objc_class_type)
2177 {
2178 uint32_t child_idx = 0;
2179 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2180
2181 if (class_interface_decl)
2182 {
2183
2184 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2185 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2186 if (superclass_interface_decl)
2187 {
2188 if (omit_empty_base_classes)
2189 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002190 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002191 {
2192 if (idx == 0)
2193 {
2194 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2195
2196
2197 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2198
2199 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2200
2201 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002202 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002203 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002204
2205 return ivar_qual_type.getAsOpaquePtr();
2206 }
2207
2208 ++child_idx;
2209 }
2210 }
2211 else
2212 ++child_idx;
2213 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002214
2215 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002216
2217 if (idx < (child_idx + class_interface_decl->ivar_size()))
2218 {
2219 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2220
2221 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2222 {
2223 if (child_idx == idx)
2224 {
2225 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2226
2227 QualType ivar_qual_type(ivar_decl->getType());
2228
2229 child_name.assign(ivar_decl->getNameAsString().c_str());
2230
2231 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2232
2233 child_byte_size = ivar_type_info.first / 8;
2234
2235 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002236 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002237 child_byte_offset = bit_offset / 8;
2238
2239 return ivar_qual_type.getAsOpaquePtr();
2240 }
2241 ++child_idx;
2242 }
2243 }
2244 }
2245 }
2246 }
2247 break;
2248
2249 case clang::Type::ObjCObjectPointer:
2250 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002251 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2252 QualType pointee_type = pointer_type->getPointeeType();
2253
2254 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2255 {
2256 return GetChildClangTypeAtIndex (ast_context,
2257 parent_name,
2258 pointer_type->getPointeeType().getAsOpaquePtr(),
2259 idx,
2260 transparent_pointers,
2261 omit_empty_base_classes,
2262 child_name,
2263 child_byte_size,
2264 child_byte_offset,
2265 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002266 child_bitfield_bit_offset,
2267 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002268 }
2269 else
2270 {
2271 if (parent_name)
2272 {
2273 child_name.assign(1, '*');
2274 child_name += parent_name;
2275 }
2276
2277 // We have a pointer to an simple type
2278 if (idx == 0)
2279 {
2280 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2281 assert(clang_type_info.first % 8 == 0);
2282 child_byte_size = clang_type_info.first / 8;
2283 child_byte_offset = 0;
2284 return pointee_type.getAsOpaquePtr();
2285 }
2286 }
Greg Clayton9488b742010-07-28 02:04:09 +00002287 }
2288 break;
2289
Greg Clayton1674b122010-07-21 22:12:05 +00002290 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002291 {
2292 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2293 const uint64_t element_count = array->getSize().getLimitedValue();
2294
2295 if (idx < element_count)
2296 {
2297 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2298
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002299 char element_name[64];
2300 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002301
2302 child_name.assign(element_name);
2303 assert(field_type_info.first % 8 == 0);
2304 child_byte_size = field_type_info.first / 8;
2305 child_byte_offset = idx * child_byte_size;
2306 return array->getElementType().getAsOpaquePtr();
2307 }
2308 }
2309 break;
2310
Greg Clayton1674b122010-07-21 22:12:05 +00002311 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002312 {
2313 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2314 QualType pointee_type = pointer_type->getPointeeType();
2315
2316 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2317 {
2318 return GetChildClangTypeAtIndex (ast_context,
2319 parent_name,
2320 pointer_type->getPointeeType().getAsOpaquePtr(),
2321 idx,
2322 transparent_pointers,
2323 omit_empty_base_classes,
2324 child_name,
2325 child_byte_size,
2326 child_byte_offset,
2327 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002328 child_bitfield_bit_offset,
2329 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002330 }
2331 else
2332 {
2333 if (parent_name)
2334 {
2335 child_name.assign(1, '*');
2336 child_name += parent_name;
2337 }
2338
2339 // We have a pointer to an simple type
2340 if (idx == 0)
2341 {
2342 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2343 assert(clang_type_info.first % 8 == 0);
2344 child_byte_size = clang_type_info.first / 8;
2345 child_byte_offset = 0;
2346 return pointee_type.getAsOpaquePtr();
2347 }
2348 }
2349 }
2350 break;
2351
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002352 case clang::Type::LValueReference:
2353 case clang::Type::RValueReference:
2354 {
2355 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2356 QualType pointee_type(reference_type->getPointeeType());
2357 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2358 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2359 {
2360 return GetChildClangTypeAtIndex (ast_context,
2361 parent_name,
2362 pointee_clang_type,
2363 idx,
2364 transparent_pointers,
2365 omit_empty_base_classes,
2366 child_name,
2367 child_byte_size,
2368 child_byte_offset,
2369 child_bitfield_bit_size,
2370 child_bitfield_bit_offset,
2371 child_is_base_class);
2372 }
2373 else
2374 {
2375 if (parent_name)
2376 {
2377 child_name.assign(1, '&');
2378 child_name += parent_name;
2379 }
2380
2381 // We have a pointer to an simple type
2382 if (idx == 0)
2383 {
2384 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2385 assert(clang_type_info.first % 8 == 0);
2386 child_byte_size = clang_type_info.first / 8;
2387 child_byte_offset = 0;
2388 return pointee_type.getAsOpaquePtr();
2389 }
2390 }
2391 }
2392 break;
2393
Greg Clayton1674b122010-07-21 22:12:05 +00002394 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002395 return GetChildClangTypeAtIndex (ast_context,
2396 parent_name,
2397 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2398 idx,
2399 transparent_pointers,
2400 omit_empty_base_classes,
2401 child_name,
2402 child_byte_size,
2403 child_byte_offset,
2404 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002405 child_bitfield_bit_offset,
2406 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002407 break;
2408
2409 default:
2410 break;
2411 }
2412 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002413 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002414}
2415
2416static inline bool
2417BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2418{
2419 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2420}
2421
2422static uint32_t
2423GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2424{
2425 uint32_t num_bases = 0;
2426 if (cxx_record_decl)
2427 {
2428 if (omit_empty_base_classes)
2429 {
2430 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2431 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2432 base_class != base_class_end;
2433 ++base_class)
2434 {
2435 // Skip empty base classes
2436 if (omit_empty_base_classes)
2437 {
2438 if (BaseSpecifierIsEmpty (base_class))
2439 continue;
2440 }
2441 ++num_bases;
2442 }
2443 }
2444 else
2445 num_bases = cxx_record_decl->getNumBases();
2446 }
2447 return num_bases;
2448}
2449
2450
2451static uint32_t
2452GetIndexForRecordBase
2453(
2454 const RecordDecl *record_decl,
2455 const CXXBaseSpecifier *base_spec,
2456 bool omit_empty_base_classes
2457)
2458{
2459 uint32_t child_idx = 0;
2460
2461 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2462
2463// const char *super_name = record_decl->getNameAsCString();
2464// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2465// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2466//
2467 if (cxx_record_decl)
2468 {
2469 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2470 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2471 base_class != base_class_end;
2472 ++base_class)
2473 {
2474 if (omit_empty_base_classes)
2475 {
2476 if (BaseSpecifierIsEmpty (base_class))
2477 continue;
2478 }
2479
2480// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2481// child_idx,
2482// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2483//
2484//
2485 if (base_class == base_spec)
2486 return child_idx;
2487 ++child_idx;
2488 }
2489 }
2490
2491 return UINT32_MAX;
2492}
2493
2494
2495static uint32_t
2496GetIndexForRecordChild
2497(
2498 const RecordDecl *record_decl,
2499 NamedDecl *canonical_decl,
2500 bool omit_empty_base_classes
2501)
2502{
2503 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2504
2505// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2506//
2507//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2508// if (cxx_record_decl)
2509// {
2510// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2511// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2512// base_class != base_class_end;
2513// ++base_class)
2514// {
2515// if (omit_empty_base_classes)
2516// {
2517// if (BaseSpecifierIsEmpty (base_class))
2518// continue;
2519// }
2520//
2521//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2522//// record_decl->getNameAsCString(),
2523//// canonical_decl->getNameAsCString(),
2524//// child_idx,
2525//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2526//
2527//
2528// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2529// if (curr_base_class_decl == canonical_decl)
2530// {
2531// return child_idx;
2532// }
2533// ++child_idx;
2534// }
2535// }
2536//
2537// const uint32_t num_bases = child_idx;
2538 RecordDecl::field_iterator field, field_end;
2539 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2540 field != field_end;
2541 ++field, ++child_idx)
2542 {
2543// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2544// record_decl->getNameAsCString(),
2545// canonical_decl->getNameAsCString(),
2546// child_idx - num_bases,
2547// field->getNameAsCString());
2548
2549 if (field->getCanonicalDecl() == canonical_decl)
2550 return child_idx;
2551 }
2552
2553 return UINT32_MAX;
2554}
2555
2556// Look for a child member (doesn't include base classes, but it does include
2557// their members) in the type hierarchy. Returns an index path into "clang_type"
2558// on how to reach the appropriate member.
2559//
2560// class A
2561// {
2562// public:
2563// int m_a;
2564// int m_b;
2565// };
2566//
2567// class B
2568// {
2569// };
2570//
2571// class C :
2572// public B,
2573// public A
2574// {
2575// };
2576//
2577// If we have a clang type that describes "class C", and we wanted to looked
2578// "m_b" in it:
2579//
2580// With omit_empty_base_classes == false we would get an integer array back with:
2581// { 1, 1 }
2582// The first index 1 is the child index for "class A" within class C
2583// The second index 1 is the child index for "m_b" within class A
2584//
2585// With omit_empty_base_classes == true we would get an integer array back with:
2586// { 0, 1 }
2587// 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)
2588// The second index 1 is the child index for "m_b" within class A
2589
2590size_t
2591ClangASTContext::GetIndexOfChildMemberWithName
2592(
2593 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002594 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002595 const char *name,
2596 bool omit_empty_base_classes,
2597 std::vector<uint32_t>& child_indexes
2598)
2599{
2600 if (clang_type && name && name[0])
2601 {
2602 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002603 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2604 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002605 {
Greg Clayton1674b122010-07-21 22:12:05 +00002606 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002607 {
2608 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2609 const RecordDecl *record_decl = record_type->getDecl();
2610
2611 assert(record_decl);
2612 uint32_t child_idx = 0;
2613
2614 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2615
2616 // Try and find a field that matches NAME
2617 RecordDecl::field_iterator field, field_end;
2618 StringRef name_sref(name);
2619 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2620 field != field_end;
2621 ++field, ++child_idx)
2622 {
2623 if (field->getName().equals (name_sref))
2624 {
2625 // We have to add on the number of base classes to this index!
2626 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2627 return child_indexes.size();
2628 }
2629 }
2630
2631 if (cxx_record_decl)
2632 {
2633 const RecordDecl *parent_record_decl = cxx_record_decl;
2634
2635 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2636
2637 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2638 // Didn't find things easily, lets let clang do its thang...
2639 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2640 DeclarationName decl_name(&ident_ref);
2641
2642 CXXBasePaths paths;
2643 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2644 decl_name.getAsOpaquePtr(),
2645 paths))
2646 {
Chris Lattner24943d22010-06-08 16:52:24 +00002647 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2648 for (path = paths.begin(); path != path_end; ++path)
2649 {
2650 const size_t num_path_elements = path->size();
2651 for (size_t e=0; e<num_path_elements; ++e)
2652 {
2653 CXXBasePathElement elem = (*path)[e];
2654
2655 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2656 if (child_idx == UINT32_MAX)
2657 {
2658 child_indexes.clear();
2659 return 0;
2660 }
2661 else
2662 {
2663 child_indexes.push_back (child_idx);
2664 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2665 }
2666 }
2667 DeclContext::lookup_iterator named_decl_pos;
2668 for (named_decl_pos = path->Decls.first;
2669 named_decl_pos != path->Decls.second && parent_record_decl;
2670 ++named_decl_pos)
2671 {
2672 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2673
2674 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2675 if (child_idx == UINT32_MAX)
2676 {
2677 child_indexes.clear();
2678 return 0;
2679 }
2680 else
2681 {
2682 child_indexes.push_back (child_idx);
2683 }
2684 }
2685 }
2686 return child_indexes.size();
2687 }
2688 }
2689
2690 }
2691 break;
2692
Greg Clayton9488b742010-07-28 02:04:09 +00002693 case clang::Type::ObjCObject:
2694 case clang::Type::ObjCInterface:
2695 {
2696 StringRef name_sref(name);
2697 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2698 assert (objc_class_type);
2699 if (objc_class_type)
2700 {
2701 uint32_t child_idx = 0;
2702 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2703
2704 if (class_interface_decl)
2705 {
2706 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2707 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2708
Greg Clayton823533e2010-09-18 02:11:07 +00002709 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002710 {
2711 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2712
2713 if (ivar_decl->getName().equals (name_sref))
2714 {
2715 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2716 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2717 ++child_idx;
2718
2719 child_indexes.push_back (child_idx);
2720 return child_indexes.size();
2721 }
2722 }
2723
2724 if (superclass_interface_decl)
2725 {
2726 // The super class index is always zero for ObjC classes,
2727 // so we push it onto the child indexes in case we find
2728 // an ivar in our superclass...
2729 child_indexes.push_back (0);
2730
2731 if (GetIndexOfChildMemberWithName (ast_context,
2732 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2733 name,
2734 omit_empty_base_classes,
2735 child_indexes))
2736 {
2737 // We did find an ivar in a superclass so just
2738 // return the results!
2739 return child_indexes.size();
2740 }
2741
2742 // We didn't find an ivar matching "name" in our
2743 // superclass, pop the superclass zero index that
2744 // we pushed on above.
2745 child_indexes.pop_back();
2746 }
2747 }
2748 }
2749 }
2750 break;
2751
2752 case clang::Type::ObjCObjectPointer:
2753 {
2754 return GetIndexOfChildMemberWithName (ast_context,
2755 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2756 name,
2757 omit_empty_base_classes,
2758 child_indexes);
2759 }
2760 break;
2761
2762
Greg Clayton1674b122010-07-21 22:12:05 +00002763 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002764 {
2765// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2766// const uint64_t element_count = array->getSize().getLimitedValue();
2767//
2768// if (idx < element_count)
2769// {
2770// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2771//
2772// char element_name[32];
2773// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2774//
2775// child_name.assign(element_name);
2776// assert(field_type_info.first % 8 == 0);
2777// child_byte_size = field_type_info.first / 8;
2778// child_byte_offset = idx * child_byte_size;
2779// return array->getElementType().getAsOpaquePtr();
2780// }
2781 }
2782 break;
2783
Greg Clayton1674b122010-07-21 22:12:05 +00002784// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002785// {
2786// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2787// QualType pointee_type = mem_ptr_type->getPointeeType();
2788//
2789// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2790// {
2791// return GetIndexOfChildWithName (ast_context,
2792// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2793// name);
2794// }
2795// }
2796// break;
2797//
Greg Clayton1674b122010-07-21 22:12:05 +00002798 case clang::Type::LValueReference:
2799 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002800 {
2801 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2802 QualType pointee_type = reference_type->getPointeeType();
2803
2804 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2805 {
2806 return GetIndexOfChildMemberWithName (ast_context,
2807 reference_type->getPointeeType().getAsOpaquePtr(),
2808 name,
2809 omit_empty_base_classes,
2810 child_indexes);
2811 }
2812 }
2813 break;
2814
Greg Clayton1674b122010-07-21 22:12:05 +00002815 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002816 {
2817 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2818 QualType pointee_type = pointer_type->getPointeeType();
2819
2820 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2821 {
2822 return GetIndexOfChildMemberWithName (ast_context,
2823 pointer_type->getPointeeType().getAsOpaquePtr(),
2824 name,
2825 omit_empty_base_classes,
2826 child_indexes);
2827 }
2828 else
2829 {
2830// if (parent_name)
2831// {
2832// child_name.assign(1, '*');
2833// child_name += parent_name;
2834// }
2835//
2836// // We have a pointer to an simple type
2837// if (idx == 0)
2838// {
2839// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2840// assert(clang_type_info.first % 8 == 0);
2841// child_byte_size = clang_type_info.first / 8;
2842// child_byte_offset = 0;
2843// return pointee_type.getAsOpaquePtr();
2844// }
2845 }
2846 }
2847 break;
2848
Greg Clayton1674b122010-07-21 22:12:05 +00002849 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002850 return GetIndexOfChildMemberWithName (ast_context,
2851 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2852 name,
2853 omit_empty_base_classes,
2854 child_indexes);
2855
2856 default:
2857 break;
2858 }
2859 }
2860 return 0;
2861}
2862
2863
2864// Get the index of the child of "clang_type" whose name matches. This function
2865// doesn't descend into the children, but only looks one level deep and name
2866// matches can include base class names.
2867
2868uint32_t
2869ClangASTContext::GetIndexOfChildWithName
2870(
2871 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002872 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002873 const char *name,
2874 bool omit_empty_base_classes
2875)
2876{
2877 if (clang_type && name && name[0])
2878 {
2879 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002880
Greg Clayton03e0f972010-09-13 03:32:57 +00002881 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002882
Greg Clayton03e0f972010-09-13 03:32:57 +00002883 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002884 {
Greg Clayton1674b122010-07-21 22:12:05 +00002885 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002886 {
2887 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2888 const RecordDecl *record_decl = record_type->getDecl();
2889
2890 assert(record_decl);
2891 uint32_t child_idx = 0;
2892
2893 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2894
2895 if (cxx_record_decl)
2896 {
2897 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2898 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2899 base_class != base_class_end;
2900 ++base_class)
2901 {
2902 // Skip empty base classes
2903 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2904 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2905 continue;
2906
2907 if (base_class->getType().getAsString().compare (name) == 0)
2908 return child_idx;
2909 ++child_idx;
2910 }
2911 }
2912
2913 // Try and find a field that matches NAME
2914 RecordDecl::field_iterator field, field_end;
2915 StringRef name_sref(name);
2916 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2917 field != field_end;
2918 ++field, ++child_idx)
2919 {
2920 if (field->getName().equals (name_sref))
2921 return child_idx;
2922 }
2923
2924 }
2925 break;
2926
Greg Clayton9488b742010-07-28 02:04:09 +00002927 case clang::Type::ObjCObject:
2928 case clang::Type::ObjCInterface:
2929 {
2930 StringRef name_sref(name);
2931 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2932 assert (objc_class_type);
2933 if (objc_class_type)
2934 {
2935 uint32_t child_idx = 0;
2936 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2937
2938 if (class_interface_decl)
2939 {
2940 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2941 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2942
2943 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2944 {
2945 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2946
2947 if (ivar_decl->getName().equals (name_sref))
2948 {
2949 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2950 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2951 ++child_idx;
2952
2953 return child_idx;
2954 }
2955 }
2956
2957 if (superclass_interface_decl)
2958 {
2959 if (superclass_interface_decl->getName().equals (name_sref))
2960 return 0;
2961 }
2962 }
2963 }
2964 }
2965 break;
2966
2967 case clang::Type::ObjCObjectPointer:
2968 {
2969 return GetIndexOfChildWithName (ast_context,
2970 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2971 name,
2972 omit_empty_base_classes);
2973 }
2974 break;
2975
Greg Clayton1674b122010-07-21 22:12:05 +00002976 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002977 {
2978// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2979// const uint64_t element_count = array->getSize().getLimitedValue();
2980//
2981// if (idx < element_count)
2982// {
2983// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2984//
2985// char element_name[32];
2986// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2987//
2988// child_name.assign(element_name);
2989// assert(field_type_info.first % 8 == 0);
2990// child_byte_size = field_type_info.first / 8;
2991// child_byte_offset = idx * child_byte_size;
2992// return array->getElementType().getAsOpaquePtr();
2993// }
2994 }
2995 break;
2996
Greg Clayton1674b122010-07-21 22:12:05 +00002997// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002998// {
2999// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3000// QualType pointee_type = mem_ptr_type->getPointeeType();
3001//
3002// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3003// {
3004// return GetIndexOfChildWithName (ast_context,
3005// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3006// name);
3007// }
3008// }
3009// break;
3010//
Greg Clayton1674b122010-07-21 22:12:05 +00003011 case clang::Type::LValueReference:
3012 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003013 {
3014 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3015 QualType pointee_type = reference_type->getPointeeType();
3016
3017 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3018 {
3019 return GetIndexOfChildWithName (ast_context,
3020 reference_type->getPointeeType().getAsOpaquePtr(),
3021 name,
3022 omit_empty_base_classes);
3023 }
3024 }
3025 break;
3026
Greg Clayton1674b122010-07-21 22:12:05 +00003027 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003028 {
3029 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3030 QualType pointee_type = pointer_type->getPointeeType();
3031
3032 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3033 {
3034 return GetIndexOfChildWithName (ast_context,
3035 pointer_type->getPointeeType().getAsOpaquePtr(),
3036 name,
3037 omit_empty_base_classes);
3038 }
3039 else
3040 {
3041// if (parent_name)
3042// {
3043// child_name.assign(1, '*');
3044// child_name += parent_name;
3045// }
3046//
3047// // We have a pointer to an simple type
3048// if (idx == 0)
3049// {
3050// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3051// assert(clang_type_info.first % 8 == 0);
3052// child_byte_size = clang_type_info.first / 8;
3053// child_byte_offset = 0;
3054// return pointee_type.getAsOpaquePtr();
3055// }
3056 }
3057 }
3058 break;
3059
Greg Clayton1674b122010-07-21 22:12:05 +00003060 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003061 return GetIndexOfChildWithName (ast_context,
3062 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3063 name,
3064 omit_empty_base_classes);
3065
3066 default:
3067 break;
3068 }
3069 }
3070 return UINT32_MAX;
3071}
3072
3073#pragma mark TagType
3074
3075bool
Greg Clayton462d4142010-09-29 01:12:09 +00003076ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003077{
3078 if (tag_clang_type)
3079 {
3080 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003081 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003082 if (clang_type)
3083 {
3084 TagType *tag_type = dyn_cast<TagType>(clang_type);
3085 if (tag_type)
3086 {
3087 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3088 if (tag_decl)
3089 {
3090 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3091 return true;
3092 }
3093 }
3094 }
3095 }
3096 return false;
3097}
3098
3099
3100#pragma mark DeclContext Functions
3101
3102DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003103ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003104{
3105 if (clang_type == NULL)
3106 return NULL;
3107
3108 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003109 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3110 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003111 {
Greg Clayton9488b742010-07-28 02:04:09 +00003112 case clang::Type::FunctionNoProto: break;
3113 case clang::Type::FunctionProto: break;
3114 case clang::Type::IncompleteArray: break;
3115 case clang::Type::VariableArray: break;
3116 case clang::Type::ConstantArray: break;
3117 case clang::Type::ExtVector: break;
3118 case clang::Type::Vector: break;
3119 case clang::Type::Builtin: break;
3120 case clang::Type::BlockPointer: break;
3121 case clang::Type::Pointer: break;
3122 case clang::Type::LValueReference: break;
3123 case clang::Type::RValueReference: break;
3124 case clang::Type::MemberPointer: break;
3125 case clang::Type::Complex: break;
3126 case clang::Type::ObjCObject: break;
3127 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3128 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3129 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3130 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
3131 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003132
Greg Clayton9488b742010-07-28 02:04:09 +00003133 case clang::Type::TypeOfExpr: break;
3134 case clang::Type::TypeOf: break;
3135 case clang::Type::Decltype: break;
3136 //case clang::Type::QualifiedName: break;
3137 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003138 }
3139 // No DeclContext in this type...
3140 return NULL;
3141}
3142
3143#pragma mark Namespace Declarations
3144
3145NamespaceDecl *
3146ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3147{
3148 // TODO: Do something intelligent with the Declaration object passed in
3149 // like maybe filling in the SourceLocation with it...
3150 if (name)
3151 {
3152 ASTContext *ast_context = getASTContext();
3153 if (decl_ctx == NULL)
3154 decl_ctx = ast_context->getTranslationUnitDecl();
3155 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3156 }
3157 return NULL;
3158}
3159
3160
3161#pragma mark Function Types
3162
3163FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003164ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003165{
3166 if (name)
3167 {
3168 ASTContext *ast_context = getASTContext();
3169 assert (ast_context != NULL);
3170
3171 if (name && name[0])
3172 {
3173 return FunctionDecl::Create(*ast_context,
3174 ast_context->getTranslationUnitDecl(),
3175 SourceLocation(),
3176 DeclarationName (&ast_context->Idents.get(name)),
3177 QualType::getFromOpaquePtr(function_clang_type),
3178 NULL,
3179 (FunctionDecl::StorageClass)storage,
3180 (FunctionDecl::StorageClass)storage,
3181 is_inline);
3182 }
3183 else
3184 {
3185 return FunctionDecl::Create(*ast_context,
3186 ast_context->getTranslationUnitDecl(),
3187 SourceLocation(),
3188 DeclarationName (),
3189 QualType::getFromOpaquePtr(function_clang_type),
3190 NULL,
3191 (FunctionDecl::StorageClass)storage,
3192 (FunctionDecl::StorageClass)storage,
3193 is_inline);
3194 }
3195 }
3196 return NULL;
3197}
3198
Greg Clayton462d4142010-09-29 01:12:09 +00003199clang_type_t
3200ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3201 clang_type_t result_type,
3202 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003203 unsigned num_args,
3204 bool is_variadic,
3205 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003206{
Chris Lattner24943d22010-06-08 16:52:24 +00003207 assert (ast_context != NULL);
3208 std::vector<QualType> qual_type_args;
3209 for (unsigned i=0; i<num_args; ++i)
3210 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3211
3212 // TODO: Detect calling convention in DWARF?
3213 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003214 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003215 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003216 is_variadic,
3217 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003218 false, // hasExceptionSpec
3219 false, // hasAnyExceptionSpec,
3220 0, // NumExs
3221 0, // const QualType *ExArray
3222 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3223}
3224
3225ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003226ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003227{
3228 ASTContext *ast_context = getASTContext();
3229 assert (ast_context != NULL);
3230 return ParmVarDecl::Create(*ast_context,
3231 ast_context->getTranslationUnitDecl(),
3232 SourceLocation(),
3233 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003234 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003235 NULL,
3236 (VarDecl::StorageClass)storage,
3237 (VarDecl::StorageClass)storage,
3238 0);
3239}
3240
3241void
3242ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3243{
3244 if (function_decl)
3245 function_decl->setParams (params, num_params);
3246}
3247
3248
3249#pragma mark Array Types
3250
Greg Clayton462d4142010-09-29 01:12:09 +00003251clang_type_t
3252ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003253{
3254 if (element_type)
3255 {
3256 ASTContext *ast_context = getASTContext();
3257 assert (ast_context != NULL);
3258 llvm::APInt ap_element_count (64, element_count);
3259 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3260 ap_element_count,
3261 ArrayType::Normal,
3262 0).getAsOpaquePtr(); // ElemQuals
3263 }
3264 return NULL;
3265}
3266
3267
3268#pragma mark TagDecl
3269
3270bool
Greg Clayton462d4142010-09-29 01:12:09 +00003271ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003272{
3273 if (clang_type)
3274 {
3275 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003276 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003277 if (t)
3278 {
3279 TagType *tag_type = dyn_cast<TagType>(t);
3280 if (tag_type)
3281 {
3282 TagDecl *tag_decl = tag_type->getDecl();
3283 if (tag_decl)
3284 {
3285 tag_decl->startDefinition();
3286 return true;
3287 }
3288 }
3289 }
3290 }
3291 return false;
3292}
3293
3294bool
Greg Clayton462d4142010-09-29 01:12:09 +00003295ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003296{
3297 if (clang_type)
3298 {
3299 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00003300
3301 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3302
3303 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003304 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003305 cxx_record_decl->completeDefinition();
3306
3307 return true;
3308 }
3309
Sean Callanan04325062010-10-25 00:29:48 +00003310 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3311
3312 if (objc_class_type)
3313 {
3314 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3315
3316 class_interface_decl->setForwardDecl(false);
3317 }
3318
Greg Clayton55b6c532010-09-29 03:44:17 +00003319 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3320
3321 if (enum_type)
3322 {
3323 EnumDecl *enum_decl = enum_type->getDecl();
3324
3325 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003326 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003327 /// TODO This really needs to be fixed.
3328
3329 unsigned NumPositiveBits = 1;
3330 unsigned NumNegativeBits = 0;
3331
Greg Clayton48fbdf72010-10-12 04:29:14 +00003332 ASTContext *ast_context = getASTContext();
3333
3334 QualType promotion_qual_type;
3335 // If the enum integer type is less than an integer in bit width,
3336 // then we must promote it to an integer size.
3337 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3338 {
3339 if (enum_decl->getIntegerType()->isSignedIntegerType())
3340 promotion_qual_type = ast_context->IntTy;
3341 else
3342 promotion_qual_type = ast_context->UnsignedIntTy;
3343 }
3344 else
3345 promotion_qual_type = enum_decl->getIntegerType();
3346
3347 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003348 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003349 }
3350 }
3351 }
3352 return false;
3353}
3354
3355
3356#pragma mark Enumeration Types
3357
Greg Clayton462d4142010-09-29 01:12:09 +00003358clang_type_t
3359ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003360{
3361 // TODO: Do something intelligent with the Declaration object passed in
3362 // like maybe filling in the SourceLocation with it...
3363 ASTContext *ast_context = getASTContext();
3364 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003365
3366 // TODO: ask about these...
3367// const bool IsScoped = false;
3368// const bool IsFixed = false;
3369
3370 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3371 ast_context->getTranslationUnitDecl(),
3372 SourceLocation(),
3373 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3374 SourceLocation(),
Sean Callanan8950c9a2010-10-29 18:38:40 +00003375 NULL, false, false); //IsScoped, IsFixed);
Chris Lattner24943d22010-06-08 16:52:24 +00003376 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003377 {
3378 // TODO: check if we should be setting the promotion type too?
3379 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003380 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003381 }
Chris Lattner24943d22010-06-08 16:52:24 +00003382 return NULL;
3383}
3384
Greg Clayton462d4142010-09-29 01:12:09 +00003385clang_type_t
3386ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3387{
3388 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3389
3390 clang::Type *clang_type = enum_qual_type.getTypePtr();
3391 if (clang_type)
3392 {
3393 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3394 if (enum_type)
3395 {
3396 EnumDecl *enum_decl = enum_type->getDecl();
3397 if (enum_decl)
3398 return enum_decl->getIntegerType().getAsOpaquePtr();
3399 }
3400 }
3401 return NULL;
3402}
Chris Lattner24943d22010-06-08 16:52:24 +00003403bool
3404ClangASTContext::AddEnumerationValueToEnumerationType
3405(
Greg Clayton462d4142010-09-29 01:12:09 +00003406 clang_type_t enum_clang_type,
3407 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003408 const Declaration &decl,
3409 const char *name,
3410 int64_t enum_value,
3411 uint32_t enum_value_bit_size
3412)
3413{
3414 if (enum_clang_type && enumerator_clang_type && name)
3415 {
3416 // TODO: Do something intelligent with the Declaration object passed in
3417 // like maybe filling in the SourceLocation with it...
3418 ASTContext *ast_context = getASTContext();
3419 IdentifierTable *identifier_table = getIdentifierTable();
3420
3421 assert (ast_context != NULL);
3422 assert (identifier_table != NULL);
3423 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3424
Greg Clayton1674b122010-07-21 22:12:05 +00003425 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003426 if (clang_type)
3427 {
3428 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3429
3430 if (enum_type)
3431 {
3432 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3433 enum_llvm_apsint = enum_value;
3434 EnumConstantDecl *enumerator_decl =
3435 EnumConstantDecl::Create(*ast_context,
3436 enum_type->getDecl(),
3437 SourceLocation(),
3438 name ? &identifier_table->get(name) : NULL, // Identifier
3439 QualType::getFromOpaquePtr(enumerator_clang_type),
3440 NULL,
3441 enum_llvm_apsint);
3442
3443 if (enumerator_decl)
3444 {
3445 enum_type->getDecl()->addDecl(enumerator_decl);
3446 return true;
3447 }
3448 }
3449 }
3450 }
3451 return false;
3452}
3453
3454#pragma mark Pointers & References
3455
Greg Clayton462d4142010-09-29 01:12:09 +00003456clang_type_t
3457ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003458{
3459 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003460 {
3461 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3462
Greg Clayton03e0f972010-09-13 03:32:57 +00003463 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3464 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003465 {
3466 case clang::Type::ObjCObject:
3467 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003468 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3469
Greg Clayton7b541032010-07-29 20:06:32 +00003470 default:
3471 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3472 }
3473 }
Chris Lattner24943d22010-06-08 16:52:24 +00003474 return NULL;
3475}
3476
Greg Clayton462d4142010-09-29 01:12:09 +00003477clang_type_t
3478ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003479{
3480 if (clang_type)
3481 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3482 return NULL;
3483}
3484
Greg Clayton462d4142010-09-29 01:12:09 +00003485clang_type_t
3486ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003487{
3488 if (clang_type)
3489 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3490 return NULL;
3491}
3492
Greg Clayton462d4142010-09-29 01:12:09 +00003493clang_type_t
3494ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003495{
3496 if (clang_pointee_type && clang_pointee_type)
3497 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3498 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3499 return NULL;
3500}
3501
Chris Lattner24943d22010-06-08 16:52:24 +00003502size_t
3503ClangASTContext::GetPointerBitSize ()
3504{
3505 ASTContext *ast_context = getASTContext();
3506 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3507}
3508
3509bool
Greg Clayton462d4142010-09-29 01:12:09 +00003510ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003511{
3512 if (clang_type == NULL)
3513 return false;
3514
3515 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003516 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3517 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003518 {
Sean Callanan04325062010-10-25 00:29:48 +00003519 case clang::Type::Builtin:
3520 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3521 {
3522 default:
3523 break;
3524 case clang::BuiltinType::ObjCId:
3525 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003526 return true;
3527 }
3528 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003529 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003530 if (target_type)
3531 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3532 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003533 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003534 if (target_type)
3535 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3536 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003537 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003538 if (target_type)
3539 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3540 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003541 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003542 if (target_type)
3543 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3544 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003545 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003546 if (target_type)
3547 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3548 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003549 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003550 if (target_type)
3551 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3552 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003553 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003554 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3555 default:
3556 break;
3557 }
3558 return false;
3559}
3560
Chris Lattner24943d22010-06-08 16:52:24 +00003561bool
Greg Clayton462d4142010-09-29 01:12:09 +00003562ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003563{
3564 if (!clang_type)
3565 return false;
3566
3567 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3568 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3569
3570 if (builtin_type)
3571 {
3572 if (builtin_type->isInteger())
3573 is_signed = builtin_type->isSignedInteger();
3574
3575 return true;
3576 }
3577
3578 return false;
3579}
3580
3581bool
Greg Clayton462d4142010-09-29 01:12:09 +00003582ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003583{
3584 if (clang_type)
3585 {
3586 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003587 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3588 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003589 {
Sean Callanan04325062010-10-25 00:29:48 +00003590 case clang::Type::Builtin:
3591 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3592 {
3593 default:
3594 break;
3595 case clang::BuiltinType::ObjCId:
3596 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003597 return true;
3598 }
3599 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003600 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003601 if (target_type)
3602 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3603 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003604 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003605 if (target_type)
3606 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3607 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003608 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003609 if (target_type)
3610 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3611 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003612 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003613 if (target_type)
3614 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3615 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003616 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003617 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3618 default:
3619 break;
3620 }
3621 }
3622 return false;
3623}
3624
3625bool
Greg Clayton462d4142010-09-29 01:12:09 +00003626ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003627{
3628 if (clang_type)
3629 {
3630 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3631
3632 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3633 {
3634 clang::BuiltinType::Kind kind = BT->getKind();
3635 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3636 {
3637 count = 1;
3638 is_complex = false;
3639 return true;
3640 }
3641 }
3642 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3643 {
3644 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3645 {
3646 count = 2;
3647 is_complex = true;
3648 return true;
3649 }
3650 }
3651 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3652 {
3653 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3654 {
3655 count = VT->getNumElements();
3656 is_complex = false;
3657 return true;
3658 }
3659 }
3660 }
3661 return false;
3662}
3663
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003664
3665bool
3666ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3667{
3668 if (clang_type)
3669 {
3670 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3671
3672 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3673 if (cxx_record_decl)
3674 {
3675 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3676 return true;
3677 }
3678 }
3679 class_name.clear();
3680 return false;
3681}
3682
3683
Greg Clayton1d8173f2010-09-24 05:15:53 +00003684bool
Greg Clayton462d4142010-09-29 01:12:09 +00003685ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003686{
3687 if (clang_type)
3688 {
3689 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3690 if (qual_type->getAsCXXRecordDecl() != NULL)
3691 return true;
3692 }
3693 return false;
3694}
3695
3696bool
Greg Clayton462d4142010-09-29 01:12:09 +00003697ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003698{
3699 if (clang_type)
3700 {
3701 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3702 if (qual_type->isObjCObjectOrInterfaceType())
3703 return true;
3704 }
3705 return false;
3706}
3707
3708
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003709bool
3710ClangASTContext::IsCharType (clang_type_t clang_type)
3711{
3712 if (clang_type)
3713 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3714 return false;
3715}
Chris Lattner24943d22010-06-08 16:52:24 +00003716
3717bool
Greg Clayton462d4142010-09-29 01:12:09 +00003718ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003719{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003720 clang_type_t pointee_or_element_clang_type = NULL;
3721 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3722
3723 if (pointee_or_element_clang_type == NULL)
3724 return false;
3725
3726 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003727 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003728 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3729
3730 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003731 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003732 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3733 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003734 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003735 // We know the size of the array and it could be a C string
3736 // since it is an array of characters
3737 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3738 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003739 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003740 else
Chris Lattner24943d22010-06-08 16:52:24 +00003741 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003742 length = 0;
3743 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003744 }
Chris Lattner24943d22010-06-08 16:52:24 +00003745
Chris Lattner24943d22010-06-08 16:52:24 +00003746 }
3747 }
3748 return false;
3749}
3750
3751bool
Greg Clayton462d4142010-09-29 01:12:09 +00003752ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003753{
3754 if (clang_type)
3755 {
3756 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3757
3758 if (qual_type->isFunctionPointerType())
3759 return true;
3760
3761 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3762 switch (type_class)
3763 {
3764 case clang::Type::Typedef:
3765 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3766
3767 case clang::Type::LValueReference:
3768 case clang::Type::RValueReference:
3769 {
3770 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3771 if (reference_type)
3772 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3773 }
3774 break;
3775 }
3776 }
3777 return false;
3778}
3779
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003780size_t
3781ClangASTContext::GetArraySize (clang_type_t clang_type)
3782{
3783 if (clang_type)
3784 {
3785 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3786 if (array)
3787 return array->getSize().getLimitedValue();
3788 }
3789 return 0;
3790}
Greg Clayton03e0f972010-09-13 03:32:57 +00003791
3792bool
Greg Clayton462d4142010-09-29 01:12:09 +00003793ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003794{
3795 if (!clang_type)
3796 return false;
3797
3798 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3799
Greg Clayton03e0f972010-09-13 03:32:57 +00003800 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3801 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003802 {
Greg Clayton1674b122010-07-21 22:12:05 +00003803 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003804 if (member_type)
3805 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3806 if (size)
3807 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3808 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003809 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003810 if (member_type)
3811 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3812 if (size)
3813 *size = 0;
3814 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003815 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003816 if (member_type)
3817 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3818 if (size)
3819 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003820 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003821 if (member_type)
3822 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3823 if (size)
3824 *size = 0;
3825 return true;
3826 }
3827 return false;
3828}
3829
3830
3831#pragma mark Typedefs
3832
Greg Clayton462d4142010-09-29 01:12:09 +00003833clang_type_t
3834ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003835{
3836 if (clang_type)
3837 {
3838 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3839 ASTContext *ast_context = getASTContext();
3840 IdentifierTable *identifier_table = getIdentifierTable();
3841 assert (ast_context != NULL);
3842 assert (identifier_table != NULL);
3843 if (decl_ctx == NULL)
3844 decl_ctx = ast_context->getTranslationUnitDecl();
3845 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3846 decl_ctx,
3847 SourceLocation(),
3848 name ? &identifier_table->get(name) : NULL, // Identifier
3849 ast_context->CreateTypeSourceInfo(qual_type));
3850
3851 // Get a uniqued QualType for the typedef decl type
3852 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3853 }
3854 return NULL;
3855}
3856
3857
3858std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003859ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003860{
3861 std::string return_name;
3862
Greg Clayton462d4142010-09-29 01:12:09 +00003863 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003864
Greg Clayton462d4142010-09-29 01:12:09 +00003865 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003866 if (typedef_type)
3867 {
Greg Clayton462d4142010-09-29 01:12:09 +00003868 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003869 return_name = typedef_decl->getQualifiedNameAsString();
3870 }
3871 else
3872 {
3873 return_name = qual_type.getAsString();
3874 }
3875
3876 return return_name;
3877}
3878
3879// Disable this for now since I can't seem to get a nicely formatted float
3880// out of the APFloat class without just getting the float, double or quad
3881// and then using a formatted print on it which defeats the purpose. We ideally
3882// would like to get perfect string values for any kind of float semantics
3883// so we can support remote targets. The code below also requires a patch to
3884// llvm::APInt.
3885//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003886//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 +00003887//{
3888// uint32_t count = 0;
3889// bool is_complex = false;
3890// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3891// {
3892// unsigned num_bytes_per_float = byte_size / count;
3893// unsigned num_bits_per_float = num_bytes_per_float * 8;
3894//
3895// float_str.clear();
3896// uint32_t i;
3897// for (i=0; i<count; i++)
3898// {
3899// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3900// bool is_ieee = false;
3901// APFloat ap_float(ap_int, is_ieee);
3902// char s[1024];
3903// unsigned int hex_digits = 0;
3904// bool upper_case = false;
3905//
3906// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3907// {
3908// if (i > 0)
3909// float_str.append(", ");
3910// float_str.append(s);
3911// if (i == 1 && is_complex)
3912// float_str.append(1, 'i');
3913// }
3914// }
3915// return !float_str.empty();
3916// }
3917// return false;
3918//}
3919
3920size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003921ClangASTContext::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 +00003922{
3923 if (clang_type)
3924 {
3925 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3926 uint32_t count = 0;
3927 bool is_complex = false;
3928 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3929 {
3930 // TODO: handle complex and vector types
3931 if (count != 1)
3932 return false;
3933
3934 StringRef s_sref(s);
3935 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3936
3937 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3938 const uint64_t byte_size = bit_size / 8;
3939 if (dst_size >= byte_size)
3940 {
3941 if (bit_size == sizeof(float)*8)
3942 {
3943 float float32 = ap_float.convertToFloat();
3944 ::memcpy (dst, &float32, byte_size);
3945 return byte_size;
3946 }
3947 else if (bit_size >= 64)
3948 {
3949 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3950 ::memcpy (dst, ap_int.getRawData(), byte_size);
3951 return byte_size;
3952 }
3953 }
3954 }
3955 }
3956 return 0;
3957}
Sean Callanana751f7b2010-09-17 02:24:29 +00003958
3959unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00003960ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00003961{
3962 assert (clang_type);
3963
3964 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3965
3966 return qual_type.getQualifiers().getCVRQualifiers();
3967}