blob: 5717d331b86348f311ea7030241b82d9bd2c61fe [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)
Greg Clayton22defe82010-12-02 23:20:03 +0000359 {
360 clang::FileSystemOptions file_system_options;
361 m_file_manager_ap.reset(new clang::FileManager(file_system_options));
362 }
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000363 return m_file_manager_ap.get();
364}
365
Greg Clayton1674b122010-07-21 22:12:05 +0000366clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000367ClangASTContext::getSourceManager()
368{
369 if (m_source_manager_ap.get() == NULL)
Greg Clayton22defe82010-12-02 23:20:03 +0000370 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
Chris Lattner24943d22010-06-08 16:52:24 +0000371 return m_source_manager_ap.get();
372}
373
374Diagnostic *
375ClangASTContext::getDiagnostic()
376{
377 if (m_diagnostic_ap.get() == NULL)
Greg Claytoneae91242010-11-19 21:46:54 +0000378 {
379 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
380 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
381 }
Chris Lattner24943d22010-06-08 16:52:24 +0000382 return m_diagnostic_ap.get();
383}
384
385TargetOptions *
386ClangASTContext::getTargetOptions()
387{
388 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
389 {
390 m_target_options_ap.reset (new TargetOptions());
391 if (m_target_options_ap.get())
392 m_target_options_ap->Triple = m_target_triple;
393 }
394 return m_target_options_ap.get();
395}
396
397
398TargetInfo *
399ClangASTContext::getTargetInfo()
400{
401 // target_triple should be something like "x86_64-apple-darwin10"
402 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
403 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
404 return m_target_info_ap.get();
405}
406
407#pragma mark Basic Types
408
409static inline bool
410QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
411{
412 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
413 if (qual_type_bit_size == bit_size)
414 return true;
415 return false;
416}
417
Greg Clayton462d4142010-09-29 01:12:09 +0000418clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000419ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000420{
421 ASTContext *ast_context = getASTContext();
422
423 assert (ast_context != NULL);
424
425 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
426}
427
Greg Clayton462d4142010-09-29 01:12:09 +0000428clang_type_t
429ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000430{
431 if (!ast_context)
432 return NULL;
433
434 switch (encoding)
435 {
Greg Clayton585660c2010-08-05 01:57:25 +0000436 case eEncodingInvalid:
Chris Lattner24943d22010-06-08 16:52:24 +0000437 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
438 return ast_context->VoidPtrTy.getAsOpaquePtr();
439 break;
440
Greg Clayton585660c2010-08-05 01:57:25 +0000441 case eEncodingUint:
Chris Lattner24943d22010-06-08 16:52:24 +0000442 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
443 return ast_context->UnsignedCharTy.getAsOpaquePtr();
444 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
445 return ast_context->UnsignedShortTy.getAsOpaquePtr();
446 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
447 return ast_context->UnsignedIntTy.getAsOpaquePtr();
448 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
449 return ast_context->UnsignedLongTy.getAsOpaquePtr();
450 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
451 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
452 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
453 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
454 break;
455
Greg Clayton585660c2010-08-05 01:57:25 +0000456 case eEncodingSint:
Chris Lattner24943d22010-06-08 16:52:24 +0000457 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
458 return ast_context->CharTy.getAsOpaquePtr();
459 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
460 return ast_context->ShortTy.getAsOpaquePtr();
461 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
462 return ast_context->IntTy.getAsOpaquePtr();
463 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
464 return ast_context->LongTy.getAsOpaquePtr();
465 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
466 return ast_context->LongLongTy.getAsOpaquePtr();
467 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
468 return ast_context->Int128Ty.getAsOpaquePtr();
469 break;
470
Greg Clayton585660c2010-08-05 01:57:25 +0000471 case eEncodingIEEE754:
Chris Lattner24943d22010-06-08 16:52:24 +0000472 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
473 return ast_context->FloatTy.getAsOpaquePtr();
474 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
475 return ast_context->DoubleTy.getAsOpaquePtr();
476 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
477 return ast_context->LongDoubleTy.getAsOpaquePtr();
478 break;
479
Greg Clayton585660c2010-08-05 01:57:25 +0000480 case eEncodingVector:
Chris Lattner24943d22010-06-08 16:52:24 +0000481 default:
482 break;
483 }
484
485 return NULL;
486}
487
Greg Clayton462d4142010-09-29 01:12:09 +0000488clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000489ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
490{
491 ASTContext *ast_context = getASTContext();
492
493 #define streq(a,b) strcmp(a,b) == 0
494 assert (ast_context != NULL);
495 if (ast_context)
496 {
497 switch (dw_ate)
498 {
499 default:
500 break;
501
502 case DW_ATE_address:
503 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
504 return ast_context->VoidPtrTy.getAsOpaquePtr();
505 break;
506
507 case DW_ATE_boolean:
508 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
509 return ast_context->BoolTy.getAsOpaquePtr();
510 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
511 return ast_context->UnsignedCharTy.getAsOpaquePtr();
512 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
513 return ast_context->UnsignedShortTy.getAsOpaquePtr();
514 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
515 return ast_context->UnsignedIntTy.getAsOpaquePtr();
516 break;
517
518 case DW_ATE_complex_float:
519 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
520 return ast_context->FloatComplexTy.getAsOpaquePtr();
521 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
522 return ast_context->DoubleComplexTy.getAsOpaquePtr();
523 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
524 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
525 break;
526
527 case DW_ATE_float:
528 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
529 return ast_context->FloatTy.getAsOpaquePtr();
530 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
531 return ast_context->DoubleTy.getAsOpaquePtr();
532 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
533 return ast_context->LongDoubleTy.getAsOpaquePtr();
534 break;
535
536 case DW_ATE_signed:
537 if (type_name)
538 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000539 if (strstr(type_name, "long long"))
Chris Lattner24943d22010-06-08 16:52:24 +0000540 {
Chris Lattner24943d22010-06-08 16:52:24 +0000541 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
542 return ast_context->LongLongTy.getAsOpaquePtr();
543 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000544 else if (strstr(type_name, "long"))
545 {
546 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
547 return ast_context->LongTy.getAsOpaquePtr();
548 }
549 else if (strstr(type_name, "short"))
Chris Lattner24943d22010-06-08 16:52:24 +0000550 {
551 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
552 return ast_context->ShortTy.getAsOpaquePtr();
553 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000554 else if (strstr(type_name, "char"))
Chris Lattner24943d22010-06-08 16:52:24 +0000555 {
556 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
557 return ast_context->CharTy.getAsOpaquePtr();
558 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
559 return ast_context->SignedCharTy.getAsOpaquePtr();
560 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000561 else if (strstr(type_name, "int"))
562 {
563 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
564 return ast_context->IntTy.getAsOpaquePtr();
565 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
566 return ast_context->Int128Ty.getAsOpaquePtr();
567 }
568 else if (streq(type_name, "wchar_t"))
Chris Lattner24943d22010-06-08 16:52:24 +0000569 {
570 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
571 return ast_context->WCharTy.getAsOpaquePtr();
572 }
Chris Lattner24943d22010-06-08 16:52:24 +0000573 }
574 // We weren't able to match up a type name, just search by size
575 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
576 return ast_context->CharTy.getAsOpaquePtr();
577 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
578 return ast_context->ShortTy.getAsOpaquePtr();
579 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
580 return ast_context->IntTy.getAsOpaquePtr();
581 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
582 return ast_context->LongTy.getAsOpaquePtr();
583 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
584 return ast_context->LongLongTy.getAsOpaquePtr();
585 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
586 return ast_context->Int128Ty.getAsOpaquePtr();
587 break;
588
589 case DW_ATE_signed_char:
590 if (type_name)
591 {
592 if (streq(type_name, "signed char"))
593 {
594 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
595 return ast_context->SignedCharTy.getAsOpaquePtr();
596 }
597 }
598 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
599 return ast_context->CharTy.getAsOpaquePtr();
600 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
601 return ast_context->SignedCharTy.getAsOpaquePtr();
602 break;
603
604 case DW_ATE_unsigned:
605 if (type_name)
606 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000607 if (strstr(type_name, "long long"))
608 {
609 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
610 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
611 }
612 else if (strstr(type_name, "long"))
613 {
614 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
615 return ast_context->UnsignedLongTy.getAsOpaquePtr();
616 }
617 else if (strstr(type_name, "short"))
618 {
619 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
620 return ast_context->UnsignedShortTy.getAsOpaquePtr();
621 }
622 else if (strstr(type_name, "char"))
623 {
624 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
625 return ast_context->UnsignedCharTy.getAsOpaquePtr();
626 }
627 else if (strstr(type_name, "int"))
Chris Lattner24943d22010-06-08 16:52:24 +0000628 {
629 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
630 return ast_context->UnsignedIntTy.getAsOpaquePtr();
631 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
632 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
633 }
Chris Lattner24943d22010-06-08 16:52:24 +0000634 }
635 // We weren't able to match up a type name, just search by size
636 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
637 return ast_context->UnsignedCharTy.getAsOpaquePtr();
638 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
639 return ast_context->UnsignedShortTy.getAsOpaquePtr();
640 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
641 return ast_context->UnsignedIntTy.getAsOpaquePtr();
642 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
643 return ast_context->UnsignedLongTy.getAsOpaquePtr();
644 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
645 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
646 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
647 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
648 break;
649
650 case DW_ATE_unsigned_char:
651 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
652 return ast_context->UnsignedCharTy.getAsOpaquePtr();
653 break;
654
655 case DW_ATE_imaginary_float:
656 break;
657 }
658 }
659 // This assert should fire for anything that we don't catch above so we know
660 // to fix any issues we run into.
661 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
662 return NULL;
663}
664
Greg Clayton462d4142010-09-29 01:12:09 +0000665clang_type_t
666ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
Chris Lattner24943d22010-06-08 16:52:24 +0000667{
Sean Callanana751f7b2010-09-17 02:24:29 +0000668 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000669}
670
Greg Clayton462d4142010-09-29 01:12:09 +0000671clang_type_t
Sean Callanana91dd992010-11-19 02:52:21 +0000672ClangASTContext::GetBuiltInType_bool()
673{
674 return getASTContext()->BoolTy.getAsOpaquePtr();
675}
676
677clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000678ClangASTContext::GetBuiltInType_objc_id()
679{
Sean Callananc4217a62010-12-06 23:53:20 +0000680 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000681}
682
Greg Clayton462d4142010-09-29 01:12:09 +0000683clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000684ClangASTContext::GetBuiltInType_objc_Class()
685{
Sean Callanan04325062010-10-25 00:29:48 +0000686 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000687}
688
Greg Clayton462d4142010-09-29 01:12:09 +0000689clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000690ClangASTContext::GetBuiltInType_objc_selector()
691{
Sean Callananc4217a62010-12-06 23:53:20 +0000692 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000693}
694
Greg Clayton462d4142010-09-29 01:12:09 +0000695clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000696ClangASTContext::GetCStringType (bool is_const)
697{
698 QualType char_type(getASTContext()->CharTy);
699
700 if (is_const)
701 char_type.addConst();
702
703 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
704}
705
Greg Clayton462d4142010-09-29 01:12:09 +0000706clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000707ClangASTContext::GetVoidPtrType (bool is_const)
708{
709 return GetVoidPtrType(getASTContext(), is_const);
710}
711
Greg Clayton462d4142010-09-29 01:12:09 +0000712clang_type_t
713ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
Chris Lattner24943d22010-06-08 16:52:24 +0000714{
715 QualType void_ptr_type(ast_context->VoidPtrTy);
716
717 if (is_const)
718 void_ptr_type.addConst();
719
720 return void_ptr_type.getAsOpaquePtr();
721}
722
Sean Callanan839fde42010-10-28 18:19:36 +0000723class NullDiagnosticClient : public DiagnosticClient
724{
725public:
726 NullDiagnosticClient ()
727 {
728 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
729 }
730
731 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
732 {
733 if (m_log)
734 {
735 llvm::SmallVectorImpl<char> diag_str(10);
736 info.FormatDiagnostic(diag_str);
737 diag_str.push_back('\0');
738 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
739 }
740 }
741private:
Greg Claytone005f2c2010-11-06 01:53:30 +0000742 LogSP m_log;
Sean Callanan839fde42010-10-28 18:19:36 +0000743};
744
Greg Clayton462d4142010-09-29 01:12:09 +0000745clang_type_t
Greg Clayton22defe82010-12-02 23:20:03 +0000746ClangASTContext::CopyType (ASTContext *dst_ast,
747 ASTContext *src_ast,
Greg Clayton462d4142010-09-29 01:12:09 +0000748 clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000749{
Sean Callanan82907582010-12-08 01:51:31 +0000750 // we temporarily install diagnostic clients as needed to ensure that
751 // errors are properly handled
752
753 std::auto_ptr<NullDiagnosticClient> diag_client;
754
755 bool dst_needs_diag = !dst_ast->getDiagnostics().getClient();
756 bool src_needs_diag = !src_ast->getDiagnostics().getClient();
757
758 if (dst_needs_diag || src_needs_diag)
759 {
760 diag_client.reset(new NullDiagnosticClient);
761
762 if (dst_needs_diag)
763 dst_ast->getDiagnostics().setClient(diag_client.get(), false);
764
765 if (src_needs_diag)
766 src_ast->getDiagnostics().setClient(diag_client.get(), false);
767 }
768
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000769 FileSystemOptions file_system_options;
Greg Clayton22defe82010-12-02 23:20:03 +0000770 FileManager file_manager (file_system_options);
771 ASTImporter importer(*dst_ast, file_manager,
772 *src_ast, file_manager);
Sean Callanancf18faa2010-11-09 22:37:10 +0000773
Greg Clayton22defe82010-12-02 23:20:03 +0000774 QualType src (QualType::getFromOpaquePtr(clang_type));
775 QualType dst (importer.Import(src));
Sean Callanancf18faa2010-11-09 22:37:10 +0000776
Sean Callanan82907582010-12-08 01:51:31 +0000777 if (dst_needs_diag)
778 dst_ast->getDiagnostics().setClient(NULL, false);
779
780 if (src_needs_diag)
781 src_ast->getDiagnostics().setClient(NULL, false);
782
Sean Callanancf18faa2010-11-09 22:37:10 +0000783 return dst.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000784}
785
Greg Clayton6916e352010-11-13 03:52:47 +0000786
787clang::Decl *
Greg Clayton22defe82010-12-02 23:20:03 +0000788ClangASTContext::CopyDecl (ASTContext *dst_ast,
789 ASTContext *src_ast,
Greg Clayton6916e352010-11-13 03:52:47 +0000790 clang::Decl *source_decl)
791{
Sean Callanan82907582010-12-08 01:51:31 +0000792 // we temporarily install diagnostic clients as needed to ensure that
793 // errors are properly handled
794
795 std::auto_ptr<NullDiagnosticClient> diag_client;
796
797 bool dst_needs_diag = !dst_ast->getDiagnostics().getClient();
798 bool src_needs_diag = !src_ast->getDiagnostics().getClient();
799
800 if (dst_needs_diag || src_needs_diag)
801 {
802 diag_client.reset(new NullDiagnosticClient);
803
804 if (dst_needs_diag)
805 dst_ast->getDiagnostics().setClient(diag_client.get(), false);
806
807 if (src_needs_diag)
808 src_ast->getDiagnostics().setClient(diag_client.get(), false);
809 }
810
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000811 FileSystemOptions file_system_options;
Greg Clayton22defe82010-12-02 23:20:03 +0000812 FileManager file_manager (file_system_options);
813 ASTImporter importer(*dst_ast, file_manager,
814 *src_ast, file_manager);
Greg Clayton6916e352010-11-13 03:52:47 +0000815
Sean Callanan82907582010-12-08 01:51:31 +0000816 if (dst_needs_diag)
817 dst_ast->getDiagnostics().setClient(NULL, false);
818
819 if (src_needs_diag)
820 src_ast->getDiagnostics().setClient(NULL, false);
821
Greg Clayton6916e352010-11-13 03:52:47 +0000822 return importer.Import(source_decl);
823}
824
Sean Callanan8d825062010-07-16 00:00:27 +0000825bool
Greg Clayton462d4142010-09-29 01:12:09 +0000826ClangASTContext::AreTypesSame(ASTContext *ast_context,
827 clang_type_t type1,
828 clang_type_t type2)
Sean Callanan5510ddd2010-07-15 22:30:52 +0000829{
830 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
831 QualType::getFromOpaquePtr(type2));
832}
833
Chris Lattner24943d22010-06-08 16:52:24 +0000834#pragma mark CVR modifiers
835
Greg Clayton462d4142010-09-29 01:12:09 +0000836clang_type_t
837ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000838{
839 if (clang_type)
840 {
841 QualType result(QualType::getFromOpaquePtr(clang_type));
842 result.addConst();
843 return result.getAsOpaquePtr();
844 }
845 return NULL;
846}
847
Greg Clayton462d4142010-09-29 01:12:09 +0000848clang_type_t
849ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000850{
851 if (clang_type)
852 {
853 QualType result(QualType::getFromOpaquePtr(clang_type));
854 result.getQualifiers().setRestrict (true);
855 return result.getAsOpaquePtr();
856 }
857 return NULL;
858}
859
Greg Clayton462d4142010-09-29 01:12:09 +0000860clang_type_t
861ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000862{
863 if (clang_type)
864 {
865 QualType result(QualType::getFromOpaquePtr(clang_type));
866 result.getQualifiers().setVolatile (true);
867 return result.getAsOpaquePtr();
868 }
869 return NULL;
870}
871
872#pragma mark Structure, Unions, Classes
873
Greg Clayton462d4142010-09-29 01:12:09 +0000874clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000875ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000876{
877 ASTContext *ast_context = getASTContext();
878 assert (ast_context != NULL);
Sean Callanan04325062010-10-25 00:29:48 +0000879
Chris Lattner24943d22010-06-08 16:52:24 +0000880 if (decl_ctx == NULL)
881 decl_ctx = ast_context->getTranslationUnitDecl();
882
Greg Clayton9488b742010-07-28 02:04:09 +0000883
Greg Clayton585660c2010-08-05 01:57:25 +0000884 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000885 {
Greg Clayton306edca2010-10-11 02:25:34 +0000886 bool isForwardDecl = true;
Greg Clayton9488b742010-07-28 02:04:09 +0000887 bool isInternal = false;
888 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
889 }
890
Chris Lattner24943d22010-06-08 16:52:24 +0000891 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
892 // we will need to update this code. I was told to currently always use
893 // the CXXRecordDecl class since we often don't know from debug information
894 // if something is struct or a class, so we default to always use the more
895 // complete definition just in case.
896 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
897 (TagDecl::TagKind)kind,
898 decl_ctx,
899 SourceLocation(),
900 name && name[0] ? &ast_context->Idents.get(name) : NULL);
901
902 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
903}
904
Greg Claytondbf26152010-10-01 23:13:49 +0000905static bool
906IsOperator (const char *name, OverloadedOperatorKind &op_kind)
907{
908 if (name == NULL || name[0] == '\0')
909 return false;
910
Sean Callananc2c9a142010-12-10 02:15:55 +0000911#define OPERATOR_SPACE_PREFIX "operator "
912#define OPERATOR_NOSPACE_PREFIX "operator"
913
914 const char *post_op_name = NULL;
915
916 bool no_space = false;
917
918 if (!::strncmp(name, OPERATOR_SPACE_PREFIX, sizeof(OPERATOR_SPACE_PREFIX) - 1))
919 {
920 post_op_name = name + sizeof(OPERATOR_SPACE_PREFIX) - 1;
921 }
922 else if (!::strncmp(name, OPERATOR_NOSPACE_PREFIX, sizeof(OPERATOR_NOSPACE_PREFIX) - 1))
923 {
924 post_op_name = name + sizeof(OPERATOR_NOSPACE_PREFIX) - 1;
925 no_space = true;
926 }
927
928#undef OPERATOR_SPACE_PREFIX
929#undef OPERATOR_NOSPACE_PREFIX
930
931 if (!post_op_name)
Greg Claytondbf26152010-10-01 23:13:49 +0000932 return false;
933
Greg Claytondbf26152010-10-01 23:13:49 +0000934 // This is an operator, set the overloaded operator kind to invalid
935 // in case this is a conversion operator...
936 op_kind = NUM_OVERLOADED_OPERATORS;
937
938 switch (post_op_name[0])
939 {
Sean Callananc2c9a142010-12-10 02:15:55 +0000940 default:
941 if (no_space)
942 return false;
943 break;
Greg Claytondbf26152010-10-01 23:13:49 +0000944 case 'n':
Sean Callananc2c9a142010-12-10 02:15:55 +0000945 if (no_space)
946 return false;
Greg Claytondbf26152010-10-01 23:13:49 +0000947 if (strcmp (post_op_name, "new") == 0)
948 op_kind = OO_New;
949 else if (strcmp (post_op_name, "new[]") == 0)
950 op_kind = OO_Array_New;
951 break;
952
953 case 'd':
Sean Callananc2c9a142010-12-10 02:15:55 +0000954 if (no_space)
955 return false;
Greg Claytondbf26152010-10-01 23:13:49 +0000956 if (strcmp (post_op_name, "delete") == 0)
957 op_kind = OO_Delete;
958 else if (strcmp (post_op_name, "delete[]") == 0)
959 op_kind = OO_Array_Delete;
960 break;
961
962 case '+':
963 if (post_op_name[1] == '\0')
964 op_kind = OO_Plus;
965 else if (post_op_name[2] == '\0')
966 {
967 if (post_op_name[1] == '=')
968 op_kind = OO_PlusEqual;
969 else if (post_op_name[1] == '+')
970 op_kind = OO_PlusPlus;
971 }
972 break;
973
974 case '-':
975 if (post_op_name[1] == '\0')
976 op_kind = OO_Minus;
977 else if (post_op_name[2] == '\0')
978 {
979 switch (post_op_name[1])
980 {
981 case '=': op_kind = OO_MinusEqual; break;
982 case '-': op_kind = OO_MinusMinus; break;
983 case '>': op_kind = OO_Arrow; break;
984 }
985 }
986 else if (post_op_name[3] == '\0')
987 {
988 if (post_op_name[2] == '*')
989 op_kind = OO_ArrowStar; break;
990 }
991 break;
992
993 case '*':
994 if (post_op_name[1] == '\0')
995 op_kind = OO_Star;
996 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
997 op_kind = OO_StarEqual;
998 break;
999
1000 case '/':
1001 if (post_op_name[1] == '\0')
1002 op_kind = OO_Slash;
1003 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1004 op_kind = OO_SlashEqual;
1005 break;
1006
1007 case '%':
1008 if (post_op_name[1] == '\0')
1009 op_kind = OO_Percent;
1010 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1011 op_kind = OO_PercentEqual;
1012 break;
1013
1014
1015 case '^':
1016 if (post_op_name[1] == '\0')
1017 op_kind = OO_Caret;
1018 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1019 op_kind = OO_CaretEqual;
1020 break;
1021
1022 case '&':
1023 if (post_op_name[1] == '\0')
1024 op_kind = OO_Amp;
1025 else if (post_op_name[2] == '\0')
1026 {
1027 switch (post_op_name[1])
1028 {
1029 case '=': op_kind = OO_AmpEqual; break;
1030 case '&': op_kind = OO_AmpAmp; break;
1031 }
1032 }
1033 break;
1034
1035 case '|':
1036 if (post_op_name[1] == '\0')
1037 op_kind = OO_Pipe;
1038 else if (post_op_name[2] == '\0')
1039 {
1040 switch (post_op_name[1])
1041 {
1042 case '=': op_kind = OO_PipeEqual; break;
1043 case '|': op_kind = OO_PipePipe; break;
1044 }
1045 }
1046 break;
1047
1048 case '~':
1049 if (post_op_name[1] == '\0')
1050 op_kind = OO_Tilde;
1051 break;
1052
1053 case '!':
1054 if (post_op_name[1] == '\0')
1055 op_kind = OO_Exclaim;
1056 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1057 op_kind = OO_ExclaimEqual;
1058 break;
1059
1060 case '=':
1061 if (post_op_name[1] == '\0')
1062 op_kind = OO_Equal;
1063 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1064 op_kind = OO_EqualEqual;
1065 break;
1066
1067 case '<':
1068 if (post_op_name[1] == '\0')
1069 op_kind = OO_Less;
1070 else if (post_op_name[2] == '\0')
1071 {
1072 switch (post_op_name[1])
1073 {
1074 case '<': op_kind = OO_LessLess; break;
1075 case '=': op_kind = OO_LessEqual; break;
1076 }
1077 }
1078 else if (post_op_name[3] == '\0')
1079 {
1080 if (post_op_name[2] == '=')
1081 op_kind = OO_LessLessEqual;
1082 }
1083 break;
1084
1085 case '>':
1086 if (post_op_name[1] == '\0')
1087 op_kind = OO_Greater;
1088 else if (post_op_name[2] == '\0')
1089 {
1090 switch (post_op_name[1])
1091 {
1092 case '>': op_kind = OO_GreaterGreater; break;
1093 case '=': op_kind = OO_GreaterEqual; break;
1094 }
1095 }
1096 else if (post_op_name[1] == '>' &&
1097 post_op_name[2] == '=' &&
1098 post_op_name[3] == '\0')
1099 {
1100 op_kind = OO_GreaterGreaterEqual;
1101 }
1102 break;
1103
1104 case ',':
1105 if (post_op_name[1] == '\0')
1106 op_kind = OO_Comma;
1107 break;
1108
1109 case '(':
1110 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1111 op_kind = OO_Call;
1112 break;
1113
1114 case '[':
1115 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1116 op_kind = OO_Subscript;
1117 break;
1118 }
1119
1120 return true;
1121}
Greg Clayton412440a2010-09-23 01:09:21 +00001122CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +00001123ClangASTContext::AddMethodToCXXRecordType
1124(
Greg Clayton462d4142010-09-29 01:12:09 +00001125 ASTContext *ast_context,
1126 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001127 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001128 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001129 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001130 bool is_virtual,
1131 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001132 bool is_inline,
1133 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +00001134)
Sean Callanan79523002010-09-17 02:58:26 +00001135{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001136 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +00001137 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001138
1139 assert(ast_context);
1140
1141 IdentifierTable *identifier_table = &ast_context->Idents;
1142
1143 assert(identifier_table);
1144
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001145 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +00001146
1147 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +00001148
Greg Clayton1d8173f2010-09-24 05:15:53 +00001149 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001150 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001151
Greg Clayton1d8173f2010-09-24 05:15:53 +00001152 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +00001153
Greg Clayton1d8173f2010-09-24 05:15:53 +00001154 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001155 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001156
Greg Clayton1d8173f2010-09-24 05:15:53 +00001157 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +00001158
Greg Clayton1d8173f2010-09-24 05:15:53 +00001159 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001160 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001161
1162 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1163
Greg Clayton1d8173f2010-09-24 05:15:53 +00001164 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001165 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001166
Greg Clayton1d8173f2010-09-24 05:15:53 +00001167 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001168
Greg Clayton30449d52010-10-01 02:31:07 +00001169 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001170
Greg Clayton30449d52010-10-01 02:31:07 +00001171 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001172
Greg Clayton90e325d2010-10-01 03:45:20 +00001173 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001174
Greg Clayton5325a362010-10-02 01:40:05 +00001175 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001176
Greg Clayton5325a362010-10-02 01:40:05 +00001177 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001178 return NULL;
1179
Greg Clayton5325a362010-10-02 01:40:05 +00001180 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001181
1182 if (!method_function_prototype)
1183 return NULL;
1184
1185 unsigned int num_params = method_function_prototype->getNumArgs();
1186
1187 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001188 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001189 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1190 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001191 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001192 method_qual_type,
Sean Callanan8950c9a2010-10-29 18:38:40 +00001193 NULL,
Greg Clayton90e325d2010-10-01 03:45:20 +00001194 is_inline,
1195 is_implicitly_declared);
1196 }
1197 else if (decl_name == record_decl->getDeclName())
1198 {
Greg Clayton30449d52010-10-01 02:31:07 +00001199 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1200 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001201 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001202 method_qual_type,
1203 NULL, // TypeSourceInfo *
1204 is_explicit,
1205 is_inline,
1206 is_implicitly_declared);
1207 }
1208 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001209 {
Greg Claytondbf26152010-10-01 23:13:49 +00001210
1211 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1212 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001213 {
Greg Claytondbf26152010-10-01 23:13:49 +00001214 if (op_kind != NUM_OVERLOADED_OPERATORS)
1215 {
1216 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001217 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001218 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001219 method_qual_type,
1220 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001221 is_static,
1222 SC_None,
1223 is_inline);
1224 }
1225 else if (num_params == 0)
1226 {
1227 // Conversion operators don't take params...
1228 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1229 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001230 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001231 method_qual_type,
1232 NULL, // TypeSourceInfo *
1233 is_inline,
1234 is_explicit);
1235 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001236 }
Greg Claytondbf26152010-10-01 23:13:49 +00001237
1238 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001239 {
1240 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1241 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001242 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001243 method_qual_type,
1244 NULL, // TypeSourceInfo *
1245 is_static,
1246 SC_None,
1247 is_inline);
1248 }
Greg Clayton30449d52010-10-01 02:31:07 +00001249 }
Greg Claytondbf26152010-10-01 23:13:49 +00001250
Greg Clayton462d4142010-09-29 01:12:09 +00001251 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001252
1253 cxx_method_decl->setAccess (access_specifier);
1254 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001255
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001256 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001257
1258 ParmVarDecl *params[num_params];
1259
1260 for (int param_index = 0;
1261 param_index < num_params;
1262 ++param_index)
1263 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001264 params[param_index] = ParmVarDecl::Create (*ast_context,
1265 cxx_method_decl,
1266 SourceLocation(),
1267 NULL, // anonymous
1268 method_function_prototype->getArgType(param_index),
1269 NULL,
1270 SC_None,
1271 SC_None,
1272 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001273 }
1274
Greg Clayton1d8173f2010-09-24 05:15:53 +00001275 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001276
Greg Clayton1d8173f2010-09-24 05:15:53 +00001277 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001278
Greg Clayton412440a2010-09-23 01:09:21 +00001279 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001280}
1281
1282bool
Greg Clayton84f80752010-07-22 18:30:50 +00001283ClangASTContext::AddFieldToRecordType
1284(
Greg Clayton462d4142010-09-29 01:12:09 +00001285 ASTContext *ast_context,
1286 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001287 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001288 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001289 AccessType access,
1290 uint32_t bitfield_bit_size
1291)
Chris Lattner24943d22010-06-08 16:52:24 +00001292{
1293 if (record_clang_type == NULL || field_type == NULL)
1294 return false;
1295
Sean Callanan60a0ced2010-09-16 20:01:08 +00001296 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001297
1298 assert (ast_context != NULL);
1299 assert (identifier_table != NULL);
1300
1301 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1302
Greg Clayton1674b122010-07-21 22:12:05 +00001303 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001304 if (clang_type)
1305 {
1306 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1307
1308 if (record_type)
1309 {
1310 RecordDecl *record_decl = record_type->getDecl();
1311
Chris Lattner24943d22010-06-08 16:52:24 +00001312 clang::Expr *bit_width = NULL;
1313 if (bitfield_bit_size != 0)
1314 {
1315 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001316 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001317 }
Greg Clayton84f80752010-07-22 18:30:50 +00001318 FieldDecl *field = FieldDecl::Create (*ast_context,
1319 record_decl,
1320 SourceLocation(),
1321 name ? &identifier_table->get(name) : NULL, // Identifier
1322 QualType::getFromOpaquePtr(field_type), // Field type
1323 NULL, // DeclaratorInfo *
1324 bit_width, // BitWidth
1325 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001326
Greg Clayton84f80752010-07-22 18:30:50 +00001327 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001328
1329 if (field)
1330 {
1331 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001332 }
1333 }
Greg Clayton9488b742010-07-28 02:04:09 +00001334 else
1335 {
1336 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1337 if (objc_class_type)
1338 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001339 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001340 ClangASTContext::AddObjCClassIVar (ast_context,
1341 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001342 name,
1343 field_type,
1344 access,
1345 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001346 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001347 }
1348 }
Chris Lattner24943d22010-06-08 16:52:24 +00001349 }
1350 return false;
1351}
1352
1353bool
1354ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1355{
1356 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1357}
1358
1359bool
1360ClangASTContext::FieldIsBitfield
1361(
1362 ASTContext *ast_context,
1363 FieldDecl* field,
1364 uint32_t& bitfield_bit_size
1365)
1366{
1367 if (ast_context == NULL || field == NULL)
1368 return false;
1369
1370 if (field->isBitField())
1371 {
1372 Expr* bit_width_expr = field->getBitWidth();
1373 if (bit_width_expr)
1374 {
1375 llvm::APSInt bit_width_apsint;
1376 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1377 {
1378 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1379 return true;
1380 }
1381 }
1382 }
1383 return false;
1384}
1385
1386bool
1387ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1388{
1389 if (record_decl == NULL)
1390 return false;
1391
1392 if (!record_decl->field_empty())
1393 return true;
1394
1395 // No fields, lets check this is a CXX record and check the base classes
1396 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1397 if (cxx_record_decl)
1398 {
1399 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1400 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1401 base_class != base_class_end;
1402 ++base_class)
1403 {
1404 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1405 if (RecordHasFields(base_class_decl))
1406 return true;
1407 }
1408 }
1409 return false;
1410}
1411
1412void
Greg Clayton462d4142010-09-29 01:12:09 +00001413ClangASTContext::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 +00001414{
1415 if (clang_qual_type)
1416 {
1417 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001418 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001419 if (clang_type)
1420 {
1421 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1422 if (record_type)
1423 {
1424 RecordDecl *record_decl = record_type->getDecl();
1425 if (record_decl)
1426 {
1427 uint32_t field_idx;
1428 RecordDecl::field_iterator field, field_end;
1429 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1430 field != field_end;
1431 ++field, ++field_idx)
1432 {
1433 // If no accessibility was assigned, assign the correct one
1434 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1435 field->setAccess ((AccessSpecifier)default_accessibility);
1436 }
1437 }
1438 }
1439 }
1440 }
1441}
1442
1443#pragma mark C++ Base Classes
1444
1445CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001446ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001447{
1448 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001449 return new CXXBaseSpecifier (SourceRange(),
1450 is_virtual,
1451 base_of_class,
1452 ConvertAccessTypeToAccessSpecifier (access),
1453 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001454 return NULL;
1455}
1456
Greg Claytone9d0df42010-07-02 01:29:13 +00001457void
1458ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1459{
1460 for (unsigned i=0; i<num_base_classes; ++i)
1461 {
1462 delete base_classes[i];
1463 base_classes[i] = NULL;
1464 }
1465}
1466
Chris Lattner24943d22010-06-08 16:52:24 +00001467bool
Greg Clayton462d4142010-09-29 01:12:09 +00001468ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001469{
1470 if (class_clang_type)
1471 {
Greg Clayton1674b122010-07-21 22:12:05 +00001472 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001473 if (clang_type)
1474 {
1475 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1476 if (record_type)
1477 {
1478 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1479 if (cxx_record_decl)
1480 {
Chris Lattner24943d22010-06-08 16:52:24 +00001481 cxx_record_decl->setBases(base_classes, num_base_classes);
1482 return true;
1483 }
1484 }
1485 }
1486 }
1487 return false;
1488}
Greg Clayton84f80752010-07-22 18:30:50 +00001489#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001490
Greg Clayton462d4142010-09-29 01:12:09 +00001491clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001492ClangASTContext::CreateObjCClass
1493(
1494 const char *name,
1495 DeclContext *decl_ctx,
1496 bool isForwardDecl,
1497 bool isInternal
1498)
1499{
1500 ASTContext *ast_context = getASTContext();
1501 assert (ast_context != NULL);
1502 assert (name && name[0]);
1503 if (decl_ctx == NULL)
1504 decl_ctx = ast_context->getTranslationUnitDecl();
1505
1506 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1507 // we will need to update this code. I was told to currently always use
1508 // the CXXRecordDecl class since we often don't know from debug information
1509 // if something is struct or a class, so we default to always use the more
1510 // complete definition just in case.
1511 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1512 decl_ctx,
1513 SourceLocation(),
1514 &ast_context->Idents.get(name),
1515 SourceLocation(),
1516 isForwardDecl,
1517 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001518
1519 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001520}
1521
1522bool
Greg Clayton462d4142010-09-29 01:12:09 +00001523ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001524{
1525 if (class_opaque_type && super_opaque_type)
1526 {
1527 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1528 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1529 clang::Type *class_type = class_qual_type.getTypePtr();
1530 clang::Type *super_type = super_qual_type.getTypePtr();
1531 if (class_type && super_type)
1532 {
1533 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1534 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1535 if (objc_class_type && objc_super_type)
1536 {
1537 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1538 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1539 if (class_interface_decl && super_interface_decl)
1540 {
1541 class_interface_decl->setSuperClass(super_interface_decl);
1542 return true;
1543 }
1544 }
1545 }
1546 }
1547 return false;
1548}
1549
1550
1551bool
1552ClangASTContext::AddObjCClassIVar
1553(
Greg Clayton462d4142010-09-29 01:12:09 +00001554 ASTContext *ast_context,
1555 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001556 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001557 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001558 AccessType access,
1559 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001560 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001561)
1562{
1563 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1564 return false;
1565
Sean Callanan60a0ced2010-09-16 20:01:08 +00001566 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001567
1568 assert (ast_context != NULL);
1569 assert (identifier_table != NULL);
1570
1571 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1572
1573 clang::Type *class_type = class_qual_type.getTypePtr();
1574 if (class_type)
1575 {
1576 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1577
1578 if (objc_class_type)
1579 {
1580 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1581
1582 if (class_interface_decl)
1583 {
1584 clang::Expr *bit_width = NULL;
1585 if (bitfield_bit_size != 0)
1586 {
1587 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001588 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001589 }
1590
Greg Clayton9488b742010-07-28 02:04:09 +00001591 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1592 class_interface_decl,
1593 SourceLocation(),
1594 &identifier_table->get(name), // Identifier
1595 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1596 NULL, // TypeSourceInfo *
1597 ConvertAccessTypeToObjCIvarAccessControl (access),
1598 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001599 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001600
1601 if (field)
1602 {
1603 class_interface_decl->addDecl(field);
1604 return true;
1605 }
Greg Clayton84f80752010-07-22 18:30:50 +00001606 }
1607 }
1608 }
1609 return false;
1610}
Chris Lattner24943d22010-06-08 16:52:24 +00001611
Greg Clayton9488b742010-07-28 02:04:09 +00001612
1613bool
Greg Clayton462d4142010-09-29 01:12:09 +00001614ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001615{
1616 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1617
1618 clang::Type *class_type = class_qual_type.getTypePtr();
1619 if (class_type)
1620 {
1621 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1622
1623 if (objc_class_type)
1624 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1625 }
1626 return false;
1627}
1628
1629bool
1630ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1631{
1632 while (class_interface_decl)
1633 {
1634 if (class_interface_decl->ivar_size() > 0)
1635 return true;
1636
1637 if (check_superclass)
1638 class_interface_decl = class_interface_decl->getSuperClass();
1639 else
1640 break;
1641 }
1642 return false;
1643}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001644
Greg Clayton462d4142010-09-29 01:12:09 +00001645ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001646ClangASTContext::AddMethodToObjCObjectType
1647(
Greg Clayton462d4142010-09-29 01:12:09 +00001648 ASTContext *ast_context,
1649 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001650 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001651 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001652 lldb::AccessType access
1653)
1654{
1655 if (class_opaque_type == NULL || method_opaque_type == NULL)
1656 return NULL;
1657
1658 IdentifierTable *identifier_table = &ast_context->Idents;
1659
1660 assert (ast_context != NULL);
1661 assert (identifier_table != NULL);
1662
1663 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1664
1665 clang::Type *class_type = class_qual_type.getTypePtr();
1666 if (class_type == NULL)
1667 return NULL;
1668
1669 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1670
1671 if (objc_class_type == NULL)
1672 return NULL;
1673
1674 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1675
1676 if (class_interface_decl == NULL)
1677 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001678
Greg Clayton1d8173f2010-09-24 05:15:53 +00001679 const char *selector_start = ::strchr (name, ' ');
1680 if (selector_start == NULL)
1681 return NULL;
1682
1683 selector_start++;
1684 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1685 return NULL;
1686 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1687
Greg Claytonad60bf42010-10-12 02:24:53 +00001688 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001689 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001690 //printf ("name = '%s'\n", name);
1691
1692 unsigned num_selectors_with_args = 0;
1693 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001694 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001695 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001696 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001697 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001698 bool has_arg = (start[len] == ':');
1699 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001700 ++num_selectors_with_args;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001701 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001702 if (has_arg)
1703 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001704 }
1705
1706
1707 if (selector_idents.size() == 0)
1708 return 0;
1709
Greg Claytonad60bf42010-10-12 02:24:53 +00001710 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001711 selector_idents.data());
1712
1713 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1714
1715 // Populate the method decl with parameter decls
1716 clang::Type *method_type(method_qual_type.getTypePtr());
1717
1718 if (method_type == NULL)
1719 return NULL;
1720
1721 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1722
1723 if (!method_function_prototype)
1724 return NULL;
1725
1726
1727 bool is_variadic = false;
1728 bool is_synthesized = false;
1729 bool is_defined = false;
1730 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1731
1732 const unsigned num_args = method_function_prototype->getNumArgs();
1733
1734 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1735 SourceLocation(), // beginLoc,
1736 SourceLocation(), // endLoc,
1737 method_selector,
1738 method_function_prototype->getResultType(),
1739 NULL, // TypeSourceInfo *ResultTInfo,
1740 GetDeclContextForType (class_opaque_type),
1741 name[0] == '-',
1742 is_variadic,
1743 is_synthesized,
1744 is_defined,
1745 imp_control,
1746 num_args);
1747
1748
1749 if (objc_method_decl == NULL)
1750 return NULL;
1751
1752 if (num_args > 0)
1753 {
1754 llvm::SmallVector<ParmVarDecl *, 12> params;
1755
1756 for (int param_index = 0; param_index < num_args; ++param_index)
1757 {
1758 params.push_back (ParmVarDecl::Create (*ast_context,
1759 objc_method_decl,
1760 SourceLocation(),
1761 NULL, // anonymous
1762 method_function_prototype->getArgType(param_index),
1763 NULL,
1764 SC_Auto,
1765 SC_Auto,
1766 NULL));
1767 }
1768
1769 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1770 }
1771
1772 class_interface_decl->addDecl (objc_method_decl);
1773
1774
1775 return objc_method_decl;
1776}
1777
1778
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001779uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001780ClangASTContext::GetTypeInfo
1781(
1782 clang_type_t clang_type,
1783 clang::ASTContext *ast_context,
1784 clang_type_t *pointee_or_element_clang_type
1785)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001786{
1787 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001788 return 0;
1789
1790 if (pointee_or_element_clang_type)
1791 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001792
1793 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1794
1795 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1796 switch (type_class)
1797 {
Sean Callanan04325062010-10-25 00:29:48 +00001798 case clang::Type::Builtin:
1799 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1800 {
Sean Callanan04325062010-10-25 00:29:48 +00001801 case clang::BuiltinType::ObjCId:
1802 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001803 if (ast_context && pointee_or_element_clang_type)
1804 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001805 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001806
1807 default:
1808 break;
Sean Callanan04325062010-10-25 00:29:48 +00001809 }
1810 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001811
1812 case clang::Type::BlockPointer:
1813 if (pointee_or_element_clang_type)
1814 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1815 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1816
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001817 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001818
1819 case clang::Type::ConstantArray:
1820 case clang::Type::DependentSizedArray:
1821 case clang::Type::IncompleteArray:
1822 case clang::Type::VariableArray:
1823 if (pointee_or_element_clang_type)
1824 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1825 return eTypeHasChildren | eTypeIsArray;
1826
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001827 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001828 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1829 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1830 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001831
1832 case clang::Type::Enum:
1833 if (pointee_or_element_clang_type)
1834 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1835 return eTypeIsEnumeration | eTypeHasValue;
1836
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001837 case clang::Type::Elaborated: return 0;
1838 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1839 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1840 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001841 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001842
1843 case clang::Type::LValueReference:
1844 case clang::Type::RValueReference:
1845 if (pointee_or_element_clang_type)
1846 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1847 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1848
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001849 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001850
1851 case clang::Type::ObjCObjectPointer:
1852 if (pointee_or_element_clang_type)
1853 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1854 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1855
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001856 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1857 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001858
1859 case clang::Type::Pointer:
1860 if (pointee_or_element_clang_type)
1861 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1862 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1863
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001864 case clang::Type::Record:
1865 if (qual_type->getAsCXXRecordDecl())
1866 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1867 else
1868 return eTypeHasChildren | eTypeIsStructUnion;
1869 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001870 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1871 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1872 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001873
1874 case clang::Type::Typedef:
1875 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1876 ast_context,
1877 pointee_or_element_clang_type);
1878
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001879 case clang::Type::TypeOfExpr: return 0;
1880 case clang::Type::TypeOf: return 0;
1881 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001882 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1883 default: return 0;
1884 }
1885 return 0;
1886}
1887
Greg Clayton9488b742010-07-28 02:04:09 +00001888
Chris Lattner24943d22010-06-08 16:52:24 +00001889#pragma mark Aggregate Types
1890
1891bool
Greg Clayton462d4142010-09-29 01:12:09 +00001892ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001893{
1894 if (clang_type == NULL)
1895 return false;
1896
1897 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1898
Greg Clayton03e0f972010-09-13 03:32:57 +00001899 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1900 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001901 {
Greg Clayton1674b122010-07-21 22:12:05 +00001902 case clang::Type::IncompleteArray:
1903 case clang::Type::VariableArray:
1904 case clang::Type::ConstantArray:
1905 case clang::Type::ExtVector:
1906 case clang::Type::Vector:
1907 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001908 case clang::Type::ObjCObject:
1909 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001910 return true;
1911
Greg Clayton1674b122010-07-21 22:12:05 +00001912 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001913 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1914
1915 default:
1916 break;
1917 }
1918 // The clang type does have a value
1919 return false;
1920}
1921
1922uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001923ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001924{
1925 if (clang_qual_type == NULL)
1926 return 0;
1927
1928 uint32_t num_children = 0;
1929 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001930 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1931 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001932 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001933 case clang::Type::Builtin:
1934 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1935 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001936 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001937 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001938 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001939 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001940
1941 default:
1942 break;
1943 }
1944 break;
1945
Greg Clayton1674b122010-07-21 22:12:05 +00001946 case clang::Type::Record:
Greg Clayton53d287b2010-11-11 02:14:53 +00001947 if (ClangASTType::IsDefined (clang_qual_type))
Chris Lattner24943d22010-06-08 16:52:24 +00001948 {
1949 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1950 const RecordDecl *record_decl = record_type->getDecl();
1951 assert(record_decl);
1952 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1953 if (cxx_record_decl)
1954 {
1955 if (omit_empty_base_classes)
1956 {
1957 // Check each base classes to see if it or any of its
1958 // base classes contain any fields. This can help
1959 // limit the noise in variable views by not having to
1960 // show base classes that contain no members.
1961 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1962 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1963 base_class != base_class_end;
1964 ++base_class)
1965 {
1966 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1967
1968 // Skip empty base classes
1969 if (RecordHasFields(base_class_decl) == false)
1970 continue;
1971
1972 num_children++;
1973 }
1974 }
1975 else
1976 {
1977 // Include all base classes
1978 num_children += cxx_record_decl->getNumBases();
1979 }
1980
1981 }
1982 RecordDecl::field_iterator field, field_end;
1983 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1984 ++num_children;
1985 }
1986 break;
1987
Greg Clayton9488b742010-07-28 02:04:09 +00001988 case clang::Type::ObjCObject:
1989 case clang::Type::ObjCInterface:
1990 {
1991 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1992 assert (objc_class_type);
1993 if (objc_class_type)
1994 {
1995 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1996
1997 if (class_interface_decl)
1998 {
1999
2000 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2001 if (superclass_interface_decl)
2002 {
2003 if (omit_empty_base_classes)
2004 {
2005 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2006 ++num_children;
2007 }
2008 else
2009 ++num_children;
2010 }
2011
2012 num_children += class_interface_decl->ivar_size();
2013 }
2014 }
2015 }
2016 break;
2017
2018 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00002019 {
2020 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
2021 QualType pointee_type = pointer_type->getPointeeType();
2022 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
2023 omit_empty_base_classes);
2024 // If this type points to a simple type, then it has 1 child
2025 if (num_pointee_children == 0)
2026 num_children = 1;
2027 else
2028 num_children = num_pointee_children;
2029 }
2030 break;
Greg Clayton9488b742010-07-28 02:04:09 +00002031
Greg Clayton1674b122010-07-21 22:12:05 +00002032 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002033 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2034 break;
2035
Greg Clayton1674b122010-07-21 22:12:05 +00002036 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002037 {
2038 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2039 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00002040 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
2041 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00002042 // If this type points to a simple type, then it has 1 child
2043 if (num_pointee_children == 0)
2044 num_children = 1;
2045 else
2046 num_children = num_pointee_children;
2047 }
2048 break;
2049
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002050 case clang::Type::LValueReference:
2051 case clang::Type::RValueReference:
2052 {
2053 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2054 QualType pointee_type = reference_type->getPointeeType();
2055 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
2056 omit_empty_base_classes);
2057 // If this type points to a simple type, then it has 1 child
2058 if (num_pointee_children == 0)
2059 num_children = 1;
2060 else
2061 num_children = num_pointee_children;
2062 }
2063 break;
2064
2065
Greg Clayton1674b122010-07-21 22:12:05 +00002066 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002067 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
2068 break;
2069
2070 default:
2071 break;
2072 }
2073 return num_children;
2074}
2075
2076
Greg Clayton462d4142010-09-29 01:12:09 +00002077clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002078ClangASTContext::GetChildClangTypeAtIndex
2079(
2080 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002081 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002082 uint32_t idx,
2083 bool transparent_pointers,
2084 bool omit_empty_base_classes,
2085 std::string& child_name,
2086 uint32_t &child_byte_size,
2087 int32_t &child_byte_offset,
2088 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002089 uint32_t &child_bitfield_bit_offset,
2090 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002091)
2092{
2093 if (parent_clang_type)
2094
2095 return GetChildClangTypeAtIndex (getASTContext(),
2096 parent_name,
2097 parent_clang_type,
2098 idx,
2099 transparent_pointers,
2100 omit_empty_base_classes,
2101 child_name,
2102 child_byte_size,
2103 child_byte_offset,
2104 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002105 child_bitfield_bit_offset,
2106 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002107 return NULL;
2108}
2109
Greg Clayton462d4142010-09-29 01:12:09 +00002110clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002111ClangASTContext::GetChildClangTypeAtIndex
2112(
2113 ASTContext *ast_context,
2114 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002115 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002116 uint32_t idx,
2117 bool transparent_pointers,
2118 bool omit_empty_base_classes,
2119 std::string& child_name,
2120 uint32_t &child_byte_size,
2121 int32_t &child_byte_offset,
2122 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002123 uint32_t &child_bitfield_bit_offset,
2124 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002125)
2126{
2127 if (parent_clang_type == NULL)
2128 return NULL;
2129
2130 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2131 {
2132 uint32_t bit_offset;
2133 child_bitfield_bit_size = 0;
2134 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002135 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002136 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002137 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2138 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002139 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002140 case clang::Type::Builtin:
2141 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2142 {
2143 case clang::BuiltinType::ObjCId:
2144 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002145 child_name = "isa";
2146 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002147 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2148
Greg Clayton960d6a42010-08-03 00:35:52 +00002149 default:
2150 break;
2151 }
2152 break;
2153
2154
Greg Clayton1674b122010-07-21 22:12:05 +00002155 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002156 {
2157 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2158 const RecordDecl *record_decl = record_type->getDecl();
2159 assert(record_decl);
2160 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2161 uint32_t child_idx = 0;
2162
2163 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2164 if (cxx_record_decl)
2165 {
2166 // We might have base classes to print out first
2167 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2168 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2169 base_class != base_class_end;
2170 ++base_class)
2171 {
2172 const CXXRecordDecl *base_class_decl = NULL;
2173
2174 // Skip empty base classes
2175 if (omit_empty_base_classes)
2176 {
2177 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2178 if (RecordHasFields(base_class_decl) == false)
2179 continue;
2180 }
2181
2182 if (idx == child_idx)
2183 {
2184 if (base_class_decl == NULL)
2185 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2186
2187
2188 if (base_class->isVirtual())
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002189 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002190 else
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002191 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002192
2193 // Base classes should be a multiple of 8 bits in size
2194 assert (bit_offset % 8 == 0);
2195 child_byte_offset = bit_offset/8;
2196 std::string base_class_type_name(base_class->getType().getAsString());
2197
2198 child_name.assign(base_class_type_name.c_str());
2199
2200 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2201
2202 // Base classes biut sizes should be a multiple of 8 bits in size
2203 assert (clang_type_info_bit_size % 8 == 0);
2204 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002205 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002206 return base_class->getType().getAsOpaquePtr();
2207 }
2208 // We don't increment the child index in the for loop since we might
2209 // be skipping empty base classes
2210 ++child_idx;
2211 }
2212 }
Chris Lattner24943d22010-06-08 16:52:24 +00002213 // Make sure index is in range...
2214 uint32_t field_idx = 0;
2215 RecordDecl::field_iterator field, field_end;
2216 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2217 {
2218 if (idx == child_idx)
2219 {
2220 // Print the member type if requested
2221 // Print the member name and equal sign
2222 child_name.assign(field->getNameAsString().c_str());
2223
2224 // Figure out the type byte size (field_type_info.first) and
2225 // alignment (field_type_info.second) from the AST context.
2226 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002227 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002228
2229 child_byte_size = field_type_info.first / 8;
2230
2231 // Figure out the field offset within the current struct/union/class type
2232 bit_offset = record_layout.getFieldOffset (field_idx);
2233 child_byte_offset = bit_offset / 8;
2234 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2235 child_bitfield_bit_offset = bit_offset % 8;
2236
2237 return field->getType().getAsOpaquePtr();
2238 }
2239 }
2240 }
2241 break;
2242
Greg Clayton9488b742010-07-28 02:04:09 +00002243 case clang::Type::ObjCObject:
2244 case clang::Type::ObjCInterface:
2245 {
2246 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2247 assert (objc_class_type);
2248 if (objc_class_type)
2249 {
2250 uint32_t child_idx = 0;
2251 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2252
2253 if (class_interface_decl)
2254 {
2255
2256 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2257 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2258 if (superclass_interface_decl)
2259 {
2260 if (omit_empty_base_classes)
2261 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002262 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002263 {
2264 if (idx == 0)
2265 {
2266 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2267
2268
2269 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2270
2271 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2272
2273 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002274 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002275 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002276
2277 return ivar_qual_type.getAsOpaquePtr();
2278 }
2279
2280 ++child_idx;
2281 }
2282 }
2283 else
2284 ++child_idx;
2285 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002286
2287 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002288
2289 if (idx < (child_idx + class_interface_decl->ivar_size()))
2290 {
2291 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2292
2293 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2294 {
2295 if (child_idx == idx)
2296 {
2297 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2298
2299 QualType ivar_qual_type(ivar_decl->getType());
2300
2301 child_name.assign(ivar_decl->getNameAsString().c_str());
2302
2303 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2304
2305 child_byte_size = ivar_type_info.first / 8;
2306
2307 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002308 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002309 child_byte_offset = bit_offset / 8;
2310
2311 return ivar_qual_type.getAsOpaquePtr();
2312 }
2313 ++child_idx;
2314 }
2315 }
2316 }
2317 }
2318 }
2319 break;
2320
2321 case clang::Type::ObjCObjectPointer:
2322 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002323 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2324 QualType pointee_type = pointer_type->getPointeeType();
2325
2326 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2327 {
2328 return GetChildClangTypeAtIndex (ast_context,
2329 parent_name,
2330 pointer_type->getPointeeType().getAsOpaquePtr(),
2331 idx,
2332 transparent_pointers,
2333 omit_empty_base_classes,
2334 child_name,
2335 child_byte_size,
2336 child_byte_offset,
2337 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002338 child_bitfield_bit_offset,
2339 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002340 }
2341 else
2342 {
2343 if (parent_name)
2344 {
2345 child_name.assign(1, '*');
2346 child_name += parent_name;
2347 }
2348
2349 // We have a pointer to an simple type
2350 if (idx == 0)
2351 {
2352 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2353 assert(clang_type_info.first % 8 == 0);
2354 child_byte_size = clang_type_info.first / 8;
2355 child_byte_offset = 0;
2356 return pointee_type.getAsOpaquePtr();
2357 }
2358 }
Greg Clayton9488b742010-07-28 02:04:09 +00002359 }
2360 break;
2361
Greg Clayton1674b122010-07-21 22:12:05 +00002362 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002363 {
2364 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2365 const uint64_t element_count = array->getSize().getLimitedValue();
2366
2367 if (idx < element_count)
2368 {
2369 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2370
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002371 char element_name[64];
2372 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002373
2374 child_name.assign(element_name);
2375 assert(field_type_info.first % 8 == 0);
2376 child_byte_size = field_type_info.first / 8;
2377 child_byte_offset = idx * child_byte_size;
2378 return array->getElementType().getAsOpaquePtr();
2379 }
2380 }
2381 break;
2382
Greg Clayton1674b122010-07-21 22:12:05 +00002383 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002384 {
2385 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2386 QualType pointee_type = pointer_type->getPointeeType();
2387
2388 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2389 {
2390 return GetChildClangTypeAtIndex (ast_context,
2391 parent_name,
2392 pointer_type->getPointeeType().getAsOpaquePtr(),
2393 idx,
2394 transparent_pointers,
2395 omit_empty_base_classes,
2396 child_name,
2397 child_byte_size,
2398 child_byte_offset,
2399 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002400 child_bitfield_bit_offset,
2401 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002402 }
2403 else
2404 {
2405 if (parent_name)
2406 {
2407 child_name.assign(1, '*');
2408 child_name += parent_name;
2409 }
2410
2411 // We have a pointer to an simple type
2412 if (idx == 0)
2413 {
2414 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2415 assert(clang_type_info.first % 8 == 0);
2416 child_byte_size = clang_type_info.first / 8;
2417 child_byte_offset = 0;
2418 return pointee_type.getAsOpaquePtr();
2419 }
2420 }
2421 }
2422 break;
2423
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002424 case clang::Type::LValueReference:
2425 case clang::Type::RValueReference:
2426 {
2427 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2428 QualType pointee_type(reference_type->getPointeeType());
2429 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2430 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2431 {
2432 return GetChildClangTypeAtIndex (ast_context,
2433 parent_name,
2434 pointee_clang_type,
2435 idx,
2436 transparent_pointers,
2437 omit_empty_base_classes,
2438 child_name,
2439 child_byte_size,
2440 child_byte_offset,
2441 child_bitfield_bit_size,
2442 child_bitfield_bit_offset,
2443 child_is_base_class);
2444 }
2445 else
2446 {
2447 if (parent_name)
2448 {
2449 child_name.assign(1, '&');
2450 child_name += parent_name;
2451 }
2452
2453 // We have a pointer to an simple type
2454 if (idx == 0)
2455 {
2456 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2457 assert(clang_type_info.first % 8 == 0);
2458 child_byte_size = clang_type_info.first / 8;
2459 child_byte_offset = 0;
2460 return pointee_type.getAsOpaquePtr();
2461 }
2462 }
2463 }
2464 break;
2465
Greg Clayton1674b122010-07-21 22:12:05 +00002466 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002467 return GetChildClangTypeAtIndex (ast_context,
2468 parent_name,
2469 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2470 idx,
2471 transparent_pointers,
2472 omit_empty_base_classes,
2473 child_name,
2474 child_byte_size,
2475 child_byte_offset,
2476 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002477 child_bitfield_bit_offset,
2478 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002479 break;
2480
2481 default:
2482 break;
2483 }
2484 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002485 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002486}
2487
2488static inline bool
2489BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2490{
2491 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2492}
2493
2494static uint32_t
2495GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2496{
2497 uint32_t num_bases = 0;
2498 if (cxx_record_decl)
2499 {
2500 if (omit_empty_base_classes)
2501 {
2502 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2503 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2504 base_class != base_class_end;
2505 ++base_class)
2506 {
2507 // Skip empty base classes
2508 if (omit_empty_base_classes)
2509 {
2510 if (BaseSpecifierIsEmpty (base_class))
2511 continue;
2512 }
2513 ++num_bases;
2514 }
2515 }
2516 else
2517 num_bases = cxx_record_decl->getNumBases();
2518 }
2519 return num_bases;
2520}
2521
2522
2523static uint32_t
2524GetIndexForRecordBase
2525(
2526 const RecordDecl *record_decl,
2527 const CXXBaseSpecifier *base_spec,
2528 bool omit_empty_base_classes
2529)
2530{
2531 uint32_t child_idx = 0;
2532
2533 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2534
2535// const char *super_name = record_decl->getNameAsCString();
2536// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2537// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2538//
2539 if (cxx_record_decl)
2540 {
2541 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2542 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2543 base_class != base_class_end;
2544 ++base_class)
2545 {
2546 if (omit_empty_base_classes)
2547 {
2548 if (BaseSpecifierIsEmpty (base_class))
2549 continue;
2550 }
2551
2552// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2553// child_idx,
2554// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2555//
2556//
2557 if (base_class == base_spec)
2558 return child_idx;
2559 ++child_idx;
2560 }
2561 }
2562
2563 return UINT32_MAX;
2564}
2565
2566
2567static uint32_t
2568GetIndexForRecordChild
2569(
2570 const RecordDecl *record_decl,
2571 NamedDecl *canonical_decl,
2572 bool omit_empty_base_classes
2573)
2574{
2575 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2576
2577// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2578//
2579//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2580// if (cxx_record_decl)
2581// {
2582// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2583// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2584// base_class != base_class_end;
2585// ++base_class)
2586// {
2587// if (omit_empty_base_classes)
2588// {
2589// if (BaseSpecifierIsEmpty (base_class))
2590// continue;
2591// }
2592//
2593//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2594//// record_decl->getNameAsCString(),
2595//// canonical_decl->getNameAsCString(),
2596//// child_idx,
2597//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2598//
2599//
2600// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2601// if (curr_base_class_decl == canonical_decl)
2602// {
2603// return child_idx;
2604// }
2605// ++child_idx;
2606// }
2607// }
2608//
2609// const uint32_t num_bases = child_idx;
2610 RecordDecl::field_iterator field, field_end;
2611 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2612 field != field_end;
2613 ++field, ++child_idx)
2614 {
2615// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2616// record_decl->getNameAsCString(),
2617// canonical_decl->getNameAsCString(),
2618// child_idx - num_bases,
2619// field->getNameAsCString());
2620
2621 if (field->getCanonicalDecl() == canonical_decl)
2622 return child_idx;
2623 }
2624
2625 return UINT32_MAX;
2626}
2627
2628// Look for a child member (doesn't include base classes, but it does include
2629// their members) in the type hierarchy. Returns an index path into "clang_type"
2630// on how to reach the appropriate member.
2631//
2632// class A
2633// {
2634// public:
2635// int m_a;
2636// int m_b;
2637// };
2638//
2639// class B
2640// {
2641// };
2642//
2643// class C :
2644// public B,
2645// public A
2646// {
2647// };
2648//
2649// If we have a clang type that describes "class C", and we wanted to looked
2650// "m_b" in it:
2651//
2652// With omit_empty_base_classes == false we would get an integer array back with:
2653// { 1, 1 }
2654// The first index 1 is the child index for "class A" within class C
2655// The second index 1 is the child index for "m_b" within class A
2656//
2657// With omit_empty_base_classes == true we would get an integer array back with:
2658// { 0, 1 }
2659// 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)
2660// The second index 1 is the child index for "m_b" within class A
2661
2662size_t
2663ClangASTContext::GetIndexOfChildMemberWithName
2664(
2665 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002666 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002667 const char *name,
2668 bool omit_empty_base_classes,
2669 std::vector<uint32_t>& child_indexes
2670)
2671{
2672 if (clang_type && name && name[0])
2673 {
2674 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002675 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2676 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002677 {
Greg Clayton1674b122010-07-21 22:12:05 +00002678 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002679 {
2680 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2681 const RecordDecl *record_decl = record_type->getDecl();
2682
2683 assert(record_decl);
2684 uint32_t child_idx = 0;
2685
2686 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2687
2688 // Try and find a field that matches NAME
2689 RecordDecl::field_iterator field, field_end;
2690 StringRef name_sref(name);
2691 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2692 field != field_end;
2693 ++field, ++child_idx)
2694 {
2695 if (field->getName().equals (name_sref))
2696 {
2697 // We have to add on the number of base classes to this index!
2698 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2699 return child_indexes.size();
2700 }
2701 }
2702
2703 if (cxx_record_decl)
2704 {
2705 const RecordDecl *parent_record_decl = cxx_record_decl;
2706
2707 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2708
2709 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2710 // Didn't find things easily, lets let clang do its thang...
2711 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2712 DeclarationName decl_name(&ident_ref);
2713
2714 CXXBasePaths paths;
2715 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2716 decl_name.getAsOpaquePtr(),
2717 paths))
2718 {
Chris Lattner24943d22010-06-08 16:52:24 +00002719 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2720 for (path = paths.begin(); path != path_end; ++path)
2721 {
2722 const size_t num_path_elements = path->size();
2723 for (size_t e=0; e<num_path_elements; ++e)
2724 {
2725 CXXBasePathElement elem = (*path)[e];
2726
2727 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2728 if (child_idx == UINT32_MAX)
2729 {
2730 child_indexes.clear();
2731 return 0;
2732 }
2733 else
2734 {
2735 child_indexes.push_back (child_idx);
2736 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2737 }
2738 }
2739 DeclContext::lookup_iterator named_decl_pos;
2740 for (named_decl_pos = path->Decls.first;
2741 named_decl_pos != path->Decls.second && parent_record_decl;
2742 ++named_decl_pos)
2743 {
2744 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2745
2746 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2747 if (child_idx == UINT32_MAX)
2748 {
2749 child_indexes.clear();
2750 return 0;
2751 }
2752 else
2753 {
2754 child_indexes.push_back (child_idx);
2755 }
2756 }
2757 }
2758 return child_indexes.size();
2759 }
2760 }
2761
2762 }
2763 break;
2764
Greg Clayton9488b742010-07-28 02:04:09 +00002765 case clang::Type::ObjCObject:
2766 case clang::Type::ObjCInterface:
2767 {
2768 StringRef name_sref(name);
2769 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2770 assert (objc_class_type);
2771 if (objc_class_type)
2772 {
2773 uint32_t child_idx = 0;
2774 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2775
2776 if (class_interface_decl)
2777 {
2778 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2779 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2780
Greg Clayton823533e2010-09-18 02:11:07 +00002781 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002782 {
2783 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2784
2785 if (ivar_decl->getName().equals (name_sref))
2786 {
2787 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2788 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2789 ++child_idx;
2790
2791 child_indexes.push_back (child_idx);
2792 return child_indexes.size();
2793 }
2794 }
2795
2796 if (superclass_interface_decl)
2797 {
2798 // The super class index is always zero for ObjC classes,
2799 // so we push it onto the child indexes in case we find
2800 // an ivar in our superclass...
2801 child_indexes.push_back (0);
2802
2803 if (GetIndexOfChildMemberWithName (ast_context,
2804 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2805 name,
2806 omit_empty_base_classes,
2807 child_indexes))
2808 {
2809 // We did find an ivar in a superclass so just
2810 // return the results!
2811 return child_indexes.size();
2812 }
2813
2814 // We didn't find an ivar matching "name" in our
2815 // superclass, pop the superclass zero index that
2816 // we pushed on above.
2817 child_indexes.pop_back();
2818 }
2819 }
2820 }
2821 }
2822 break;
2823
2824 case clang::Type::ObjCObjectPointer:
2825 {
2826 return GetIndexOfChildMemberWithName (ast_context,
2827 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2828 name,
2829 omit_empty_base_classes,
2830 child_indexes);
2831 }
2832 break;
2833
2834
Greg Clayton1674b122010-07-21 22:12:05 +00002835 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002836 {
2837// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2838// const uint64_t element_count = array->getSize().getLimitedValue();
2839//
2840// if (idx < element_count)
2841// {
2842// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2843//
2844// char element_name[32];
2845// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2846//
2847// child_name.assign(element_name);
2848// assert(field_type_info.first % 8 == 0);
2849// child_byte_size = field_type_info.first / 8;
2850// child_byte_offset = idx * child_byte_size;
2851// return array->getElementType().getAsOpaquePtr();
2852// }
2853 }
2854 break;
2855
Greg Clayton1674b122010-07-21 22:12:05 +00002856// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002857// {
2858// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2859// QualType pointee_type = mem_ptr_type->getPointeeType();
2860//
2861// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2862// {
2863// return GetIndexOfChildWithName (ast_context,
2864// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2865// name);
2866// }
2867// }
2868// break;
2869//
Greg Clayton1674b122010-07-21 22:12:05 +00002870 case clang::Type::LValueReference:
2871 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002872 {
2873 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2874 QualType pointee_type = reference_type->getPointeeType();
2875
2876 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2877 {
2878 return GetIndexOfChildMemberWithName (ast_context,
2879 reference_type->getPointeeType().getAsOpaquePtr(),
2880 name,
2881 omit_empty_base_classes,
2882 child_indexes);
2883 }
2884 }
2885 break;
2886
Greg Clayton1674b122010-07-21 22:12:05 +00002887 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002888 {
2889 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2890 QualType pointee_type = pointer_type->getPointeeType();
2891
2892 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2893 {
2894 return GetIndexOfChildMemberWithName (ast_context,
2895 pointer_type->getPointeeType().getAsOpaquePtr(),
2896 name,
2897 omit_empty_base_classes,
2898 child_indexes);
2899 }
2900 else
2901 {
2902// if (parent_name)
2903// {
2904// child_name.assign(1, '*');
2905// child_name += parent_name;
2906// }
2907//
2908// // We have a pointer to an simple type
2909// if (idx == 0)
2910// {
2911// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2912// assert(clang_type_info.first % 8 == 0);
2913// child_byte_size = clang_type_info.first / 8;
2914// child_byte_offset = 0;
2915// return pointee_type.getAsOpaquePtr();
2916// }
2917 }
2918 }
2919 break;
2920
Greg Clayton1674b122010-07-21 22:12:05 +00002921 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002922 return GetIndexOfChildMemberWithName (ast_context,
2923 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2924 name,
2925 omit_empty_base_classes,
2926 child_indexes);
2927
2928 default:
2929 break;
2930 }
2931 }
2932 return 0;
2933}
2934
2935
2936// Get the index of the child of "clang_type" whose name matches. This function
2937// doesn't descend into the children, but only looks one level deep and name
2938// matches can include base class names.
2939
2940uint32_t
2941ClangASTContext::GetIndexOfChildWithName
2942(
2943 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002944 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002945 const char *name,
2946 bool omit_empty_base_classes
2947)
2948{
2949 if (clang_type && name && name[0])
2950 {
2951 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002952
Greg Clayton03e0f972010-09-13 03:32:57 +00002953 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002954
Greg Clayton03e0f972010-09-13 03:32:57 +00002955 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002956 {
Greg Clayton1674b122010-07-21 22:12:05 +00002957 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002958 {
2959 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2960 const RecordDecl *record_decl = record_type->getDecl();
2961
2962 assert(record_decl);
2963 uint32_t child_idx = 0;
2964
2965 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2966
2967 if (cxx_record_decl)
2968 {
2969 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2970 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2971 base_class != base_class_end;
2972 ++base_class)
2973 {
2974 // Skip empty base classes
2975 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2976 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2977 continue;
2978
2979 if (base_class->getType().getAsString().compare (name) == 0)
2980 return child_idx;
2981 ++child_idx;
2982 }
2983 }
2984
2985 // Try and find a field that matches NAME
2986 RecordDecl::field_iterator field, field_end;
2987 StringRef name_sref(name);
2988 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2989 field != field_end;
2990 ++field, ++child_idx)
2991 {
2992 if (field->getName().equals (name_sref))
2993 return child_idx;
2994 }
2995
2996 }
2997 break;
2998
Greg Clayton9488b742010-07-28 02:04:09 +00002999 case clang::Type::ObjCObject:
3000 case clang::Type::ObjCInterface:
3001 {
3002 StringRef name_sref(name);
3003 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
3004 assert (objc_class_type);
3005 if (objc_class_type)
3006 {
3007 uint32_t child_idx = 0;
3008 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3009
3010 if (class_interface_decl)
3011 {
3012 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3013 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3014
3015 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3016 {
3017 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3018
3019 if (ivar_decl->getName().equals (name_sref))
3020 {
3021 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3022 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3023 ++child_idx;
3024
3025 return child_idx;
3026 }
3027 }
3028
3029 if (superclass_interface_decl)
3030 {
3031 if (superclass_interface_decl->getName().equals (name_sref))
3032 return 0;
3033 }
3034 }
3035 }
3036 }
3037 break;
3038
3039 case clang::Type::ObjCObjectPointer:
3040 {
3041 return GetIndexOfChildWithName (ast_context,
3042 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3043 name,
3044 omit_empty_base_classes);
3045 }
3046 break;
3047
Greg Clayton1674b122010-07-21 22:12:05 +00003048 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003049 {
3050// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3051// const uint64_t element_count = array->getSize().getLimitedValue();
3052//
3053// if (idx < element_count)
3054// {
3055// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
3056//
3057// char element_name[32];
3058// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3059//
3060// child_name.assign(element_name);
3061// assert(field_type_info.first % 8 == 0);
3062// child_byte_size = field_type_info.first / 8;
3063// child_byte_offset = idx * child_byte_size;
3064// return array->getElementType().getAsOpaquePtr();
3065// }
3066 }
3067 break;
3068
Greg Clayton1674b122010-07-21 22:12:05 +00003069// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00003070// {
3071// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3072// QualType pointee_type = mem_ptr_type->getPointeeType();
3073//
3074// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3075// {
3076// return GetIndexOfChildWithName (ast_context,
3077// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3078// name);
3079// }
3080// }
3081// break;
3082//
Greg Clayton1674b122010-07-21 22:12:05 +00003083 case clang::Type::LValueReference:
3084 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003085 {
3086 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3087 QualType pointee_type = reference_type->getPointeeType();
3088
3089 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3090 {
3091 return GetIndexOfChildWithName (ast_context,
3092 reference_type->getPointeeType().getAsOpaquePtr(),
3093 name,
3094 omit_empty_base_classes);
3095 }
3096 }
3097 break;
3098
Greg Clayton1674b122010-07-21 22:12:05 +00003099 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003100 {
3101 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3102 QualType pointee_type = pointer_type->getPointeeType();
3103
3104 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3105 {
3106 return GetIndexOfChildWithName (ast_context,
3107 pointer_type->getPointeeType().getAsOpaquePtr(),
3108 name,
3109 omit_empty_base_classes);
3110 }
3111 else
3112 {
3113// if (parent_name)
3114// {
3115// child_name.assign(1, '*');
3116// child_name += parent_name;
3117// }
3118//
3119// // We have a pointer to an simple type
3120// if (idx == 0)
3121// {
3122// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3123// assert(clang_type_info.first % 8 == 0);
3124// child_byte_size = clang_type_info.first / 8;
3125// child_byte_offset = 0;
3126// return pointee_type.getAsOpaquePtr();
3127// }
3128 }
3129 }
3130 break;
3131
Greg Clayton1674b122010-07-21 22:12:05 +00003132 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003133 return GetIndexOfChildWithName (ast_context,
3134 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3135 name,
3136 omit_empty_base_classes);
3137
3138 default:
3139 break;
3140 }
3141 }
3142 return UINT32_MAX;
3143}
3144
3145#pragma mark TagType
3146
3147bool
Greg Clayton462d4142010-09-29 01:12:09 +00003148ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003149{
3150 if (tag_clang_type)
3151 {
3152 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003153 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003154 if (clang_type)
3155 {
3156 TagType *tag_type = dyn_cast<TagType>(clang_type);
3157 if (tag_type)
3158 {
3159 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3160 if (tag_decl)
3161 {
3162 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3163 return true;
3164 }
3165 }
3166 }
3167 }
3168 return false;
3169}
3170
3171
3172#pragma mark DeclContext Functions
3173
3174DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003175ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003176{
3177 if (clang_type == NULL)
3178 return NULL;
3179
3180 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003181 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3182 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003183 {
Greg Clayton9488b742010-07-28 02:04:09 +00003184 case clang::Type::FunctionNoProto: break;
3185 case clang::Type::FunctionProto: break;
3186 case clang::Type::IncompleteArray: break;
3187 case clang::Type::VariableArray: break;
3188 case clang::Type::ConstantArray: break;
3189 case clang::Type::ExtVector: break;
3190 case clang::Type::Vector: break;
3191 case clang::Type::Builtin: break;
3192 case clang::Type::BlockPointer: break;
3193 case clang::Type::Pointer: break;
3194 case clang::Type::LValueReference: break;
3195 case clang::Type::RValueReference: break;
3196 case clang::Type::MemberPointer: break;
3197 case clang::Type::Complex: break;
3198 case clang::Type::ObjCObject: break;
3199 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3200 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3201 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3202 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
3203 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003204
Greg Clayton9488b742010-07-28 02:04:09 +00003205 case clang::Type::TypeOfExpr: break;
3206 case clang::Type::TypeOf: break;
3207 case clang::Type::Decltype: break;
3208 //case clang::Type::QualifiedName: break;
3209 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003210 }
3211 // No DeclContext in this type...
3212 return NULL;
3213}
3214
3215#pragma mark Namespace Declarations
3216
3217NamespaceDecl *
3218ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3219{
3220 // TODO: Do something intelligent with the Declaration object passed in
3221 // like maybe filling in the SourceLocation with it...
3222 if (name)
3223 {
3224 ASTContext *ast_context = getASTContext();
3225 if (decl_ctx == NULL)
3226 decl_ctx = ast_context->getTranslationUnitDecl();
3227 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3228 }
3229 return NULL;
3230}
3231
3232
3233#pragma mark Function Types
3234
3235FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003236ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003237{
3238 if (name)
3239 {
3240 ASTContext *ast_context = getASTContext();
3241 assert (ast_context != NULL);
3242
3243 if (name && name[0])
3244 {
3245 return FunctionDecl::Create(*ast_context,
3246 ast_context->getTranslationUnitDecl(),
3247 SourceLocation(),
3248 DeclarationName (&ast_context->Idents.get(name)),
3249 QualType::getFromOpaquePtr(function_clang_type),
3250 NULL,
3251 (FunctionDecl::StorageClass)storage,
3252 (FunctionDecl::StorageClass)storage,
3253 is_inline);
3254 }
3255 else
3256 {
3257 return FunctionDecl::Create(*ast_context,
3258 ast_context->getTranslationUnitDecl(),
3259 SourceLocation(),
3260 DeclarationName (),
3261 QualType::getFromOpaquePtr(function_clang_type),
3262 NULL,
3263 (FunctionDecl::StorageClass)storage,
3264 (FunctionDecl::StorageClass)storage,
3265 is_inline);
3266 }
3267 }
3268 return NULL;
3269}
3270
Greg Clayton462d4142010-09-29 01:12:09 +00003271clang_type_t
3272ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3273 clang_type_t result_type,
3274 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003275 unsigned num_args,
3276 bool is_variadic,
3277 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003278{
Chris Lattner24943d22010-06-08 16:52:24 +00003279 assert (ast_context != NULL);
3280 std::vector<QualType> qual_type_args;
3281 for (unsigned i=0; i<num_args; ++i)
3282 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3283
3284 // TODO: Detect calling convention in DWARF?
3285 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003286 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003287 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003288 is_variadic,
3289 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003290 false, // hasExceptionSpec
3291 false, // hasAnyExceptionSpec,
3292 0, // NumExs
3293 0, // const QualType *ExArray
3294 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3295}
3296
3297ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003298ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003299{
3300 ASTContext *ast_context = getASTContext();
3301 assert (ast_context != NULL);
3302 return ParmVarDecl::Create(*ast_context,
3303 ast_context->getTranslationUnitDecl(),
3304 SourceLocation(),
3305 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003306 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003307 NULL,
3308 (VarDecl::StorageClass)storage,
3309 (VarDecl::StorageClass)storage,
3310 0);
3311}
3312
3313void
3314ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3315{
3316 if (function_decl)
3317 function_decl->setParams (params, num_params);
3318}
3319
3320
3321#pragma mark Array Types
3322
Greg Clayton462d4142010-09-29 01:12:09 +00003323clang_type_t
3324ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003325{
3326 if (element_type)
3327 {
3328 ASTContext *ast_context = getASTContext();
3329 assert (ast_context != NULL);
3330 llvm::APInt ap_element_count (64, element_count);
3331 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3332 ap_element_count,
3333 ArrayType::Normal,
3334 0).getAsOpaquePtr(); // ElemQuals
3335 }
3336 return NULL;
3337}
3338
3339
3340#pragma mark TagDecl
3341
3342bool
Greg Clayton462d4142010-09-29 01:12:09 +00003343ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003344{
3345 if (clang_type)
3346 {
3347 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003348 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003349 if (t)
3350 {
3351 TagType *tag_type = dyn_cast<TagType>(t);
3352 if (tag_type)
3353 {
3354 TagDecl *tag_decl = tag_type->getDecl();
3355 if (tag_decl)
3356 {
3357 tag_decl->startDefinition();
3358 return true;
3359 }
3360 }
3361 }
3362 }
3363 return false;
3364}
3365
3366bool
Greg Clayton462d4142010-09-29 01:12:09 +00003367ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003368{
3369 if (clang_type)
3370 {
3371 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00003372
3373 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3374
3375 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003376 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003377 cxx_record_decl->completeDefinition();
3378
3379 return true;
3380 }
3381
Sean Callanan04325062010-10-25 00:29:48 +00003382 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3383
3384 if (objc_class_type)
3385 {
3386 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3387
3388 class_interface_decl->setForwardDecl(false);
3389 }
3390
Greg Clayton55b6c532010-09-29 03:44:17 +00003391 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3392
3393 if (enum_type)
3394 {
3395 EnumDecl *enum_decl = enum_type->getDecl();
3396
3397 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003398 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003399 /// TODO This really needs to be fixed.
3400
3401 unsigned NumPositiveBits = 1;
3402 unsigned NumNegativeBits = 0;
3403
Greg Clayton48fbdf72010-10-12 04:29:14 +00003404 ASTContext *ast_context = getASTContext();
3405
3406 QualType promotion_qual_type;
3407 // If the enum integer type is less than an integer in bit width,
3408 // then we must promote it to an integer size.
3409 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3410 {
3411 if (enum_decl->getIntegerType()->isSignedIntegerType())
3412 promotion_qual_type = ast_context->IntTy;
3413 else
3414 promotion_qual_type = ast_context->UnsignedIntTy;
3415 }
3416 else
3417 promotion_qual_type = enum_decl->getIntegerType();
3418
3419 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003420 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003421 }
3422 }
3423 }
3424 return false;
3425}
3426
3427
3428#pragma mark Enumeration Types
3429
Greg Clayton462d4142010-09-29 01:12:09 +00003430clang_type_t
3431ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003432{
3433 // TODO: Do something intelligent with the Declaration object passed in
3434 // like maybe filling in the SourceLocation with it...
3435 ASTContext *ast_context = getASTContext();
3436 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003437
3438 // TODO: ask about these...
3439// const bool IsScoped = false;
3440// const bool IsFixed = false;
3441
3442 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3443 ast_context->getTranslationUnitDecl(),
3444 SourceLocation(),
3445 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3446 SourceLocation(),
Sean Callanan8950c9a2010-10-29 18:38:40 +00003447 NULL, false, false); //IsScoped, IsFixed);
Chris Lattner24943d22010-06-08 16:52:24 +00003448 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003449 {
3450 // TODO: check if we should be setting the promotion type too?
3451 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003452 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003453 }
Chris Lattner24943d22010-06-08 16:52:24 +00003454 return NULL;
3455}
3456
Greg Clayton462d4142010-09-29 01:12:09 +00003457clang_type_t
3458ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3459{
3460 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3461
3462 clang::Type *clang_type = enum_qual_type.getTypePtr();
3463 if (clang_type)
3464 {
3465 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3466 if (enum_type)
3467 {
3468 EnumDecl *enum_decl = enum_type->getDecl();
3469 if (enum_decl)
3470 return enum_decl->getIntegerType().getAsOpaquePtr();
3471 }
3472 }
3473 return NULL;
3474}
Chris Lattner24943d22010-06-08 16:52:24 +00003475bool
3476ClangASTContext::AddEnumerationValueToEnumerationType
3477(
Greg Clayton462d4142010-09-29 01:12:09 +00003478 clang_type_t enum_clang_type,
3479 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003480 const Declaration &decl,
3481 const char *name,
3482 int64_t enum_value,
3483 uint32_t enum_value_bit_size
3484)
3485{
3486 if (enum_clang_type && enumerator_clang_type && name)
3487 {
3488 // TODO: Do something intelligent with the Declaration object passed in
3489 // like maybe filling in the SourceLocation with it...
3490 ASTContext *ast_context = getASTContext();
3491 IdentifierTable *identifier_table = getIdentifierTable();
3492
3493 assert (ast_context != NULL);
3494 assert (identifier_table != NULL);
3495 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3496
Greg Clayton1674b122010-07-21 22:12:05 +00003497 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003498 if (clang_type)
3499 {
3500 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3501
3502 if (enum_type)
3503 {
3504 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3505 enum_llvm_apsint = enum_value;
3506 EnumConstantDecl *enumerator_decl =
3507 EnumConstantDecl::Create(*ast_context,
3508 enum_type->getDecl(),
3509 SourceLocation(),
3510 name ? &identifier_table->get(name) : NULL, // Identifier
3511 QualType::getFromOpaquePtr(enumerator_clang_type),
3512 NULL,
3513 enum_llvm_apsint);
3514
3515 if (enumerator_decl)
3516 {
3517 enum_type->getDecl()->addDecl(enumerator_decl);
3518 return true;
3519 }
3520 }
3521 }
3522 }
3523 return false;
3524}
3525
3526#pragma mark Pointers & References
3527
Greg Clayton462d4142010-09-29 01:12:09 +00003528clang_type_t
3529ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003530{
3531 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003532 {
3533 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3534
Greg Clayton03e0f972010-09-13 03:32:57 +00003535 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3536 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003537 {
3538 case clang::Type::ObjCObject:
3539 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003540 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3541
Greg Clayton7b541032010-07-29 20:06:32 +00003542 default:
3543 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3544 }
3545 }
Chris Lattner24943d22010-06-08 16:52:24 +00003546 return NULL;
3547}
3548
Greg Clayton462d4142010-09-29 01:12:09 +00003549clang_type_t
3550ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003551{
3552 if (clang_type)
3553 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3554 return NULL;
3555}
3556
Greg Clayton462d4142010-09-29 01:12:09 +00003557clang_type_t
3558ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003559{
3560 if (clang_type)
3561 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3562 return NULL;
3563}
3564
Greg Clayton462d4142010-09-29 01:12:09 +00003565clang_type_t
3566ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003567{
3568 if (clang_pointee_type && clang_pointee_type)
3569 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3570 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3571 return NULL;
3572}
3573
Chris Lattner24943d22010-06-08 16:52:24 +00003574size_t
3575ClangASTContext::GetPointerBitSize ()
3576{
3577 ASTContext *ast_context = getASTContext();
3578 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3579}
3580
3581bool
Greg Clayton462d4142010-09-29 01:12:09 +00003582ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003583{
3584 if (clang_type == NULL)
3585 return false;
3586
3587 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003588 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3589 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003590 {
Sean Callanan04325062010-10-25 00:29:48 +00003591 case clang::Type::Builtin:
3592 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3593 {
3594 default:
3595 break;
3596 case clang::BuiltinType::ObjCId:
3597 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003598 return true;
3599 }
3600 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003601 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003602 if (target_type)
3603 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3604 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003605 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003606 if (target_type)
3607 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3608 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003609 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003610 if (target_type)
3611 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3612 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003613 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003614 if (target_type)
3615 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3616 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003617 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003618 if (target_type)
3619 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3620 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003621 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003622 if (target_type)
3623 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3624 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003625 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003626 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3627 default:
3628 break;
3629 }
3630 return false;
3631}
3632
Chris Lattner24943d22010-06-08 16:52:24 +00003633bool
Greg Clayton462d4142010-09-29 01:12:09 +00003634ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003635{
3636 if (!clang_type)
3637 return false;
3638
3639 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3640 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3641
3642 if (builtin_type)
3643 {
3644 if (builtin_type->isInteger())
3645 is_signed = builtin_type->isSignedInteger();
3646
3647 return true;
3648 }
3649
3650 return false;
3651}
3652
3653bool
Greg Clayton462d4142010-09-29 01:12:09 +00003654ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003655{
3656 if (clang_type)
3657 {
3658 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003659 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3660 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003661 {
Sean Callanan04325062010-10-25 00:29:48 +00003662 case clang::Type::Builtin:
3663 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3664 {
3665 default:
3666 break;
3667 case clang::BuiltinType::ObjCId:
3668 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003669 return true;
3670 }
3671 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003672 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003673 if (target_type)
3674 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3675 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003676 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003677 if (target_type)
3678 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3679 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003680 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003681 if (target_type)
3682 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3683 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003684 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003685 if (target_type)
3686 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3687 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003688 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003689 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3690 default:
3691 break;
3692 }
3693 }
3694 return false;
3695}
3696
3697bool
Greg Clayton462d4142010-09-29 01:12:09 +00003698ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003699{
3700 if (clang_type)
3701 {
3702 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3703
3704 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3705 {
3706 clang::BuiltinType::Kind kind = BT->getKind();
3707 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3708 {
3709 count = 1;
3710 is_complex = false;
3711 return true;
3712 }
3713 }
3714 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3715 {
3716 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3717 {
3718 count = 2;
3719 is_complex = true;
3720 return true;
3721 }
3722 }
3723 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3724 {
3725 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3726 {
3727 count = VT->getNumElements();
3728 is_complex = false;
3729 return true;
3730 }
3731 }
3732 }
3733 return false;
3734}
3735
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003736
3737bool
3738ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3739{
3740 if (clang_type)
3741 {
3742 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3743
3744 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3745 if (cxx_record_decl)
3746 {
3747 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3748 return true;
3749 }
3750 }
3751 class_name.clear();
3752 return false;
3753}
3754
3755
Greg Clayton1d8173f2010-09-24 05:15:53 +00003756bool
Greg Clayton462d4142010-09-29 01:12:09 +00003757ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003758{
3759 if (clang_type)
3760 {
3761 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3762 if (qual_type->getAsCXXRecordDecl() != NULL)
3763 return true;
3764 }
3765 return false;
3766}
3767
3768bool
Greg Clayton462d4142010-09-29 01:12:09 +00003769ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003770{
3771 if (clang_type)
3772 {
3773 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3774 if (qual_type->isObjCObjectOrInterfaceType())
3775 return true;
3776 }
3777 return false;
3778}
3779
3780
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003781bool
3782ClangASTContext::IsCharType (clang_type_t clang_type)
3783{
3784 if (clang_type)
3785 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3786 return false;
3787}
Chris Lattner24943d22010-06-08 16:52:24 +00003788
3789bool
Greg Clayton462d4142010-09-29 01:12:09 +00003790ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003791{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003792 clang_type_t pointee_or_element_clang_type = NULL;
3793 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3794
3795 if (pointee_or_element_clang_type == NULL)
3796 return false;
3797
3798 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003799 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003800 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3801
3802 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003803 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003804 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3805 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003806 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003807 // We know the size of the array and it could be a C string
3808 // since it is an array of characters
3809 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3810 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003811 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003812 else
Chris Lattner24943d22010-06-08 16:52:24 +00003813 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003814 length = 0;
3815 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003816 }
Chris Lattner24943d22010-06-08 16:52:24 +00003817
Chris Lattner24943d22010-06-08 16:52:24 +00003818 }
3819 }
3820 return false;
3821}
3822
3823bool
Greg Clayton462d4142010-09-29 01:12:09 +00003824ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003825{
3826 if (clang_type)
3827 {
3828 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3829
3830 if (qual_type->isFunctionPointerType())
3831 return true;
3832
3833 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3834 switch (type_class)
3835 {
3836 case clang::Type::Typedef:
3837 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3838
3839 case clang::Type::LValueReference:
3840 case clang::Type::RValueReference:
3841 {
3842 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3843 if (reference_type)
3844 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3845 }
3846 break;
3847 }
3848 }
3849 return false;
3850}
3851
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003852size_t
3853ClangASTContext::GetArraySize (clang_type_t clang_type)
3854{
3855 if (clang_type)
3856 {
3857 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3858 if (array)
3859 return array->getSize().getLimitedValue();
3860 }
3861 return 0;
3862}
Greg Clayton03e0f972010-09-13 03:32:57 +00003863
3864bool
Greg Clayton462d4142010-09-29 01:12:09 +00003865ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003866{
3867 if (!clang_type)
3868 return false;
3869
3870 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3871
Greg Clayton03e0f972010-09-13 03:32:57 +00003872 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3873 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003874 {
Greg Clayton1674b122010-07-21 22:12:05 +00003875 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003876 if (member_type)
3877 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3878 if (size)
3879 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3880 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003881 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003882 if (member_type)
3883 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3884 if (size)
3885 *size = 0;
3886 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003887 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003888 if (member_type)
3889 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3890 if (size)
3891 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003892 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003893 if (member_type)
3894 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3895 if (size)
3896 *size = 0;
3897 return true;
3898 }
3899 return false;
3900}
3901
3902
3903#pragma mark Typedefs
3904
Greg Clayton462d4142010-09-29 01:12:09 +00003905clang_type_t
3906ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003907{
3908 if (clang_type)
3909 {
3910 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3911 ASTContext *ast_context = getASTContext();
3912 IdentifierTable *identifier_table = getIdentifierTable();
3913 assert (ast_context != NULL);
3914 assert (identifier_table != NULL);
3915 if (decl_ctx == NULL)
3916 decl_ctx = ast_context->getTranslationUnitDecl();
3917 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3918 decl_ctx,
3919 SourceLocation(),
3920 name ? &identifier_table->get(name) : NULL, // Identifier
3921 ast_context->CreateTypeSourceInfo(qual_type));
3922
3923 // Get a uniqued QualType for the typedef decl type
3924 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3925 }
3926 return NULL;
3927}
3928
3929
3930std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003931ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003932{
3933 std::string return_name;
3934
Greg Clayton462d4142010-09-29 01:12:09 +00003935 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003936
Greg Clayton462d4142010-09-29 01:12:09 +00003937 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003938 if (typedef_type)
3939 {
Greg Clayton462d4142010-09-29 01:12:09 +00003940 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003941 return_name = typedef_decl->getQualifiedNameAsString();
3942 }
3943 else
3944 {
3945 return_name = qual_type.getAsString();
3946 }
3947
3948 return return_name;
3949}
3950
3951// Disable this for now since I can't seem to get a nicely formatted float
3952// out of the APFloat class without just getting the float, double or quad
3953// and then using a formatted print on it which defeats the purpose. We ideally
3954// would like to get perfect string values for any kind of float semantics
3955// so we can support remote targets. The code below also requires a patch to
3956// llvm::APInt.
3957//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003958//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 +00003959//{
3960// uint32_t count = 0;
3961// bool is_complex = false;
3962// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3963// {
3964// unsigned num_bytes_per_float = byte_size / count;
3965// unsigned num_bits_per_float = num_bytes_per_float * 8;
3966//
3967// float_str.clear();
3968// uint32_t i;
3969// for (i=0; i<count; i++)
3970// {
3971// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3972// bool is_ieee = false;
3973// APFloat ap_float(ap_int, is_ieee);
3974// char s[1024];
3975// unsigned int hex_digits = 0;
3976// bool upper_case = false;
3977//
3978// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3979// {
3980// if (i > 0)
3981// float_str.append(", ");
3982// float_str.append(s);
3983// if (i == 1 && is_complex)
3984// float_str.append(1, 'i');
3985// }
3986// }
3987// return !float_str.empty();
3988// }
3989// return false;
3990//}
3991
3992size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003993ClangASTContext::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 +00003994{
3995 if (clang_type)
3996 {
3997 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3998 uint32_t count = 0;
3999 bool is_complex = false;
4000 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4001 {
4002 // TODO: handle complex and vector types
4003 if (count != 1)
4004 return false;
4005
4006 StringRef s_sref(s);
4007 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
4008
4009 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
4010 const uint64_t byte_size = bit_size / 8;
4011 if (dst_size >= byte_size)
4012 {
4013 if (bit_size == sizeof(float)*8)
4014 {
4015 float float32 = ap_float.convertToFloat();
4016 ::memcpy (dst, &float32, byte_size);
4017 return byte_size;
4018 }
4019 else if (bit_size >= 64)
4020 {
4021 llvm::APInt ap_int(ap_float.bitcastToAPInt());
4022 ::memcpy (dst, ap_int.getRawData(), byte_size);
4023 return byte_size;
4024 }
4025 }
4026 }
4027 }
4028 return 0;
4029}
Sean Callanana751f7b2010-09-17 02:24:29 +00004030
4031unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00004032ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00004033{
4034 assert (clang_type);
4035
4036 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4037
4038 return qual_type.getQualifiers().getCVRQualifiers();
4039}