blob: c4cd159195e55ba89a12b065fbaf8e5ad4d105ba [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 Callanan494735d2010-12-10 19:51:54 +0000911#define OPERATOR_PREFIX "operator"
Sean Callananc2c9a142010-12-10 02:15:55 +0000912
913 const char *post_op_name = NULL;
914
Sean Callanan494735d2010-12-10 19:51:54 +0000915 bool no_space = true;
Sean Callananc2c9a142010-12-10 02:15:55 +0000916
Sean Callanan494735d2010-12-10 19:51:54 +0000917 if (!::strncmp(name, OPERATOR_PREFIX, sizeof(OPERATOR_PREFIX) - 1))
918 post_op_name = name + sizeof(OPERATOR_PREFIX) - 1;
919 else
Greg Claytondbf26152010-10-01 23:13:49 +0000920 return false;
921
Sean Callanan494735d2010-12-10 19:51:54 +0000922 if (post_op_name[0] == ' ')
923 {
924 post_op_name++;
925 no_space = false;
926 }
927
928#undef OPERATOR_PREFIX
929
Greg Claytondbf26152010-10-01 23:13:49 +0000930 // This is an operator, set the overloaded operator kind to invalid
931 // in case this is a conversion operator...
932 op_kind = NUM_OVERLOADED_OPERATORS;
933
934 switch (post_op_name[0])
935 {
Sean Callananc2c9a142010-12-10 02:15:55 +0000936 default:
937 if (no_space)
938 return false;
939 break;
Greg Claytondbf26152010-10-01 23:13:49 +0000940 case 'n':
Sean Callananc2c9a142010-12-10 02:15:55 +0000941 if (no_space)
942 return false;
Greg Claytondbf26152010-10-01 23:13:49 +0000943 if (strcmp (post_op_name, "new") == 0)
944 op_kind = OO_New;
945 else if (strcmp (post_op_name, "new[]") == 0)
946 op_kind = OO_Array_New;
947 break;
948
949 case 'd':
Sean Callananc2c9a142010-12-10 02:15:55 +0000950 if (no_space)
951 return false;
Greg Claytondbf26152010-10-01 23:13:49 +0000952 if (strcmp (post_op_name, "delete") == 0)
953 op_kind = OO_Delete;
954 else if (strcmp (post_op_name, "delete[]") == 0)
955 op_kind = OO_Array_Delete;
956 break;
957
958 case '+':
959 if (post_op_name[1] == '\0')
960 op_kind = OO_Plus;
961 else if (post_op_name[2] == '\0')
962 {
963 if (post_op_name[1] == '=')
964 op_kind = OO_PlusEqual;
965 else if (post_op_name[1] == '+')
966 op_kind = OO_PlusPlus;
967 }
968 break;
969
970 case '-':
971 if (post_op_name[1] == '\0')
972 op_kind = OO_Minus;
973 else if (post_op_name[2] == '\0')
974 {
975 switch (post_op_name[1])
976 {
977 case '=': op_kind = OO_MinusEqual; break;
978 case '-': op_kind = OO_MinusMinus; break;
979 case '>': op_kind = OO_Arrow; break;
980 }
981 }
982 else if (post_op_name[3] == '\0')
983 {
984 if (post_op_name[2] == '*')
985 op_kind = OO_ArrowStar; break;
986 }
987 break;
988
989 case '*':
990 if (post_op_name[1] == '\0')
991 op_kind = OO_Star;
992 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
993 op_kind = OO_StarEqual;
994 break;
995
996 case '/':
997 if (post_op_name[1] == '\0')
998 op_kind = OO_Slash;
999 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1000 op_kind = OO_SlashEqual;
1001 break;
1002
1003 case '%':
1004 if (post_op_name[1] == '\0')
1005 op_kind = OO_Percent;
1006 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1007 op_kind = OO_PercentEqual;
1008 break;
1009
1010
1011 case '^':
1012 if (post_op_name[1] == '\0')
1013 op_kind = OO_Caret;
1014 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1015 op_kind = OO_CaretEqual;
1016 break;
1017
1018 case '&':
1019 if (post_op_name[1] == '\0')
1020 op_kind = OO_Amp;
1021 else if (post_op_name[2] == '\0')
1022 {
1023 switch (post_op_name[1])
1024 {
1025 case '=': op_kind = OO_AmpEqual; break;
1026 case '&': op_kind = OO_AmpAmp; break;
1027 }
1028 }
1029 break;
1030
1031 case '|':
1032 if (post_op_name[1] == '\0')
1033 op_kind = OO_Pipe;
1034 else if (post_op_name[2] == '\0')
1035 {
1036 switch (post_op_name[1])
1037 {
1038 case '=': op_kind = OO_PipeEqual; break;
1039 case '|': op_kind = OO_PipePipe; break;
1040 }
1041 }
1042 break;
1043
1044 case '~':
1045 if (post_op_name[1] == '\0')
1046 op_kind = OO_Tilde;
1047 break;
1048
1049 case '!':
1050 if (post_op_name[1] == '\0')
1051 op_kind = OO_Exclaim;
1052 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1053 op_kind = OO_ExclaimEqual;
1054 break;
1055
1056 case '=':
1057 if (post_op_name[1] == '\0')
1058 op_kind = OO_Equal;
1059 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1060 op_kind = OO_EqualEqual;
1061 break;
1062
1063 case '<':
1064 if (post_op_name[1] == '\0')
1065 op_kind = OO_Less;
1066 else if (post_op_name[2] == '\0')
1067 {
1068 switch (post_op_name[1])
1069 {
1070 case '<': op_kind = OO_LessLess; break;
1071 case '=': op_kind = OO_LessEqual; break;
1072 }
1073 }
1074 else if (post_op_name[3] == '\0')
1075 {
1076 if (post_op_name[2] == '=')
1077 op_kind = OO_LessLessEqual;
1078 }
1079 break;
1080
1081 case '>':
1082 if (post_op_name[1] == '\0')
1083 op_kind = OO_Greater;
1084 else if (post_op_name[2] == '\0')
1085 {
1086 switch (post_op_name[1])
1087 {
1088 case '>': op_kind = OO_GreaterGreater; break;
1089 case '=': op_kind = OO_GreaterEqual; break;
1090 }
1091 }
1092 else if (post_op_name[1] == '>' &&
1093 post_op_name[2] == '=' &&
1094 post_op_name[3] == '\0')
1095 {
1096 op_kind = OO_GreaterGreaterEqual;
1097 }
1098 break;
1099
1100 case ',':
1101 if (post_op_name[1] == '\0')
1102 op_kind = OO_Comma;
1103 break;
1104
1105 case '(':
1106 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1107 op_kind = OO_Call;
1108 break;
1109
1110 case '[':
1111 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1112 op_kind = OO_Subscript;
1113 break;
1114 }
1115
1116 return true;
1117}
Greg Clayton412440a2010-09-23 01:09:21 +00001118CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +00001119ClangASTContext::AddMethodToCXXRecordType
1120(
Greg Clayton462d4142010-09-29 01:12:09 +00001121 ASTContext *ast_context,
1122 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001123 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001124 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001125 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001126 bool is_virtual,
1127 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001128 bool is_inline,
1129 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +00001130)
Sean Callanan79523002010-09-17 02:58:26 +00001131{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001132 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +00001133 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001134
1135 assert(ast_context);
1136
1137 IdentifierTable *identifier_table = &ast_context->Idents;
1138
1139 assert(identifier_table);
1140
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001141 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +00001142
1143 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +00001144
Greg Clayton1d8173f2010-09-24 05:15:53 +00001145 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001146 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001147
Greg Clayton1d8173f2010-09-24 05:15:53 +00001148 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +00001149
Greg Clayton1d8173f2010-09-24 05:15:53 +00001150 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001151 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001152
Greg Clayton1d8173f2010-09-24 05:15:53 +00001153 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +00001154
Greg Clayton1d8173f2010-09-24 05:15:53 +00001155 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001156 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001157
1158 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1159
Greg Clayton1d8173f2010-09-24 05:15:53 +00001160 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001161 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001162
Greg Clayton1d8173f2010-09-24 05:15:53 +00001163 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001164
Greg Clayton30449d52010-10-01 02:31:07 +00001165 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001166
Greg Clayton30449d52010-10-01 02:31:07 +00001167 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001168
Greg Clayton90e325d2010-10-01 03:45:20 +00001169 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001170
Greg Clayton5325a362010-10-02 01:40:05 +00001171 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001172
Greg Clayton5325a362010-10-02 01:40:05 +00001173 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001174 return NULL;
1175
Greg Clayton5325a362010-10-02 01:40:05 +00001176 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001177
1178 if (!method_function_prototype)
1179 return NULL;
1180
1181 unsigned int num_params = method_function_prototype->getNumArgs();
1182
1183 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001184 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001185 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1186 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001187 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001188 method_qual_type,
Sean Callanan8950c9a2010-10-29 18:38:40 +00001189 NULL,
Greg Clayton90e325d2010-10-01 03:45:20 +00001190 is_inline,
1191 is_implicitly_declared);
1192 }
1193 else if (decl_name == record_decl->getDeclName())
1194 {
Greg Clayton30449d52010-10-01 02:31:07 +00001195 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1196 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001197 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001198 method_qual_type,
1199 NULL, // TypeSourceInfo *
1200 is_explicit,
1201 is_inline,
1202 is_implicitly_declared);
1203 }
1204 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001205 {
Greg Claytondbf26152010-10-01 23:13:49 +00001206
1207 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1208 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001209 {
Greg Claytondbf26152010-10-01 23:13:49 +00001210 if (op_kind != NUM_OVERLOADED_OPERATORS)
1211 {
1212 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001213 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001214 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001215 method_qual_type,
1216 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001217 is_static,
1218 SC_None,
1219 is_inline);
1220 }
1221 else if (num_params == 0)
1222 {
1223 // Conversion operators don't take params...
1224 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1225 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001226 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001227 method_qual_type,
1228 NULL, // TypeSourceInfo *
1229 is_inline,
1230 is_explicit);
1231 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001232 }
Greg Claytondbf26152010-10-01 23:13:49 +00001233
1234 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001235 {
1236 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1237 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001238 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001239 method_qual_type,
1240 NULL, // TypeSourceInfo *
1241 is_static,
1242 SC_None,
1243 is_inline);
1244 }
Greg Clayton30449d52010-10-01 02:31:07 +00001245 }
Greg Claytondbf26152010-10-01 23:13:49 +00001246
Greg Clayton462d4142010-09-29 01:12:09 +00001247 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001248
1249 cxx_method_decl->setAccess (access_specifier);
1250 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001251
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001252 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001253
1254 ParmVarDecl *params[num_params];
1255
1256 for (int param_index = 0;
1257 param_index < num_params;
1258 ++param_index)
1259 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001260 params[param_index] = ParmVarDecl::Create (*ast_context,
1261 cxx_method_decl,
1262 SourceLocation(),
1263 NULL, // anonymous
1264 method_function_prototype->getArgType(param_index),
1265 NULL,
1266 SC_None,
1267 SC_None,
1268 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001269 }
1270
Greg Clayton1d8173f2010-09-24 05:15:53 +00001271 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001272
Greg Clayton1d8173f2010-09-24 05:15:53 +00001273 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001274
Greg Clayton412440a2010-09-23 01:09:21 +00001275 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001276}
1277
1278bool
Greg Clayton84f80752010-07-22 18:30:50 +00001279ClangASTContext::AddFieldToRecordType
1280(
Greg Clayton462d4142010-09-29 01:12:09 +00001281 ASTContext *ast_context,
1282 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001283 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001284 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001285 AccessType access,
1286 uint32_t bitfield_bit_size
1287)
Chris Lattner24943d22010-06-08 16:52:24 +00001288{
1289 if (record_clang_type == NULL || field_type == NULL)
1290 return false;
1291
Sean Callanan60a0ced2010-09-16 20:01:08 +00001292 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001293
1294 assert (ast_context != NULL);
1295 assert (identifier_table != NULL);
1296
1297 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1298
Greg Clayton1674b122010-07-21 22:12:05 +00001299 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001300 if (clang_type)
1301 {
1302 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1303
1304 if (record_type)
1305 {
1306 RecordDecl *record_decl = record_type->getDecl();
1307
Chris Lattner24943d22010-06-08 16:52:24 +00001308 clang::Expr *bit_width = NULL;
1309 if (bitfield_bit_size != 0)
1310 {
1311 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001312 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001313 }
Greg Clayton84f80752010-07-22 18:30:50 +00001314 FieldDecl *field = FieldDecl::Create (*ast_context,
1315 record_decl,
1316 SourceLocation(),
1317 name ? &identifier_table->get(name) : NULL, // Identifier
1318 QualType::getFromOpaquePtr(field_type), // Field type
1319 NULL, // DeclaratorInfo *
1320 bit_width, // BitWidth
1321 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001322
Greg Clayton84f80752010-07-22 18:30:50 +00001323 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001324
1325 if (field)
1326 {
1327 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001328 }
1329 }
Greg Clayton9488b742010-07-28 02:04:09 +00001330 else
1331 {
1332 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1333 if (objc_class_type)
1334 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001335 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001336 ClangASTContext::AddObjCClassIVar (ast_context,
1337 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001338 name,
1339 field_type,
1340 access,
1341 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001342 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001343 }
1344 }
Chris Lattner24943d22010-06-08 16:52:24 +00001345 }
1346 return false;
1347}
1348
1349bool
1350ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1351{
1352 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1353}
1354
1355bool
1356ClangASTContext::FieldIsBitfield
1357(
1358 ASTContext *ast_context,
1359 FieldDecl* field,
1360 uint32_t& bitfield_bit_size
1361)
1362{
1363 if (ast_context == NULL || field == NULL)
1364 return false;
1365
1366 if (field->isBitField())
1367 {
1368 Expr* bit_width_expr = field->getBitWidth();
1369 if (bit_width_expr)
1370 {
1371 llvm::APSInt bit_width_apsint;
1372 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1373 {
1374 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1375 return true;
1376 }
1377 }
1378 }
1379 return false;
1380}
1381
1382bool
1383ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1384{
1385 if (record_decl == NULL)
1386 return false;
1387
1388 if (!record_decl->field_empty())
1389 return true;
1390
1391 // No fields, lets check this is a CXX record and check the base classes
1392 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1393 if (cxx_record_decl)
1394 {
1395 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1396 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1397 base_class != base_class_end;
1398 ++base_class)
1399 {
1400 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1401 if (RecordHasFields(base_class_decl))
1402 return true;
1403 }
1404 }
1405 return false;
1406}
1407
1408void
Greg Clayton462d4142010-09-29 01:12:09 +00001409ClangASTContext::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 +00001410{
1411 if (clang_qual_type)
1412 {
1413 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001414 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001415 if (clang_type)
1416 {
1417 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1418 if (record_type)
1419 {
1420 RecordDecl *record_decl = record_type->getDecl();
1421 if (record_decl)
1422 {
1423 uint32_t field_idx;
1424 RecordDecl::field_iterator field, field_end;
1425 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1426 field != field_end;
1427 ++field, ++field_idx)
1428 {
1429 // If no accessibility was assigned, assign the correct one
1430 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1431 field->setAccess ((AccessSpecifier)default_accessibility);
1432 }
1433 }
1434 }
1435 }
1436 }
1437}
1438
1439#pragma mark C++ Base Classes
1440
1441CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001442ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001443{
1444 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001445 return new CXXBaseSpecifier (SourceRange(),
1446 is_virtual,
1447 base_of_class,
1448 ConvertAccessTypeToAccessSpecifier (access),
1449 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001450 return NULL;
1451}
1452
Greg Claytone9d0df42010-07-02 01:29:13 +00001453void
1454ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1455{
1456 for (unsigned i=0; i<num_base_classes; ++i)
1457 {
1458 delete base_classes[i];
1459 base_classes[i] = NULL;
1460 }
1461}
1462
Chris Lattner24943d22010-06-08 16:52:24 +00001463bool
Greg Clayton462d4142010-09-29 01:12:09 +00001464ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001465{
1466 if (class_clang_type)
1467 {
Greg Clayton1674b122010-07-21 22:12:05 +00001468 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001469 if (clang_type)
1470 {
1471 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1472 if (record_type)
1473 {
1474 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1475 if (cxx_record_decl)
1476 {
Chris Lattner24943d22010-06-08 16:52:24 +00001477 cxx_record_decl->setBases(base_classes, num_base_classes);
1478 return true;
1479 }
1480 }
1481 }
1482 }
1483 return false;
1484}
Greg Clayton84f80752010-07-22 18:30:50 +00001485#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001486
Greg Clayton462d4142010-09-29 01:12:09 +00001487clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001488ClangASTContext::CreateObjCClass
1489(
1490 const char *name,
1491 DeclContext *decl_ctx,
1492 bool isForwardDecl,
1493 bool isInternal
1494)
1495{
1496 ASTContext *ast_context = getASTContext();
1497 assert (ast_context != NULL);
1498 assert (name && name[0]);
1499 if (decl_ctx == NULL)
1500 decl_ctx = ast_context->getTranslationUnitDecl();
1501
1502 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1503 // we will need to update this code. I was told to currently always use
1504 // the CXXRecordDecl class since we often don't know from debug information
1505 // if something is struct or a class, so we default to always use the more
1506 // complete definition just in case.
1507 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1508 decl_ctx,
1509 SourceLocation(),
1510 &ast_context->Idents.get(name),
1511 SourceLocation(),
1512 isForwardDecl,
1513 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001514
1515 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001516}
1517
1518bool
Greg Clayton462d4142010-09-29 01:12:09 +00001519ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001520{
1521 if (class_opaque_type && super_opaque_type)
1522 {
1523 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1524 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1525 clang::Type *class_type = class_qual_type.getTypePtr();
1526 clang::Type *super_type = super_qual_type.getTypePtr();
1527 if (class_type && super_type)
1528 {
1529 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1530 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1531 if (objc_class_type && objc_super_type)
1532 {
1533 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1534 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1535 if (class_interface_decl && super_interface_decl)
1536 {
1537 class_interface_decl->setSuperClass(super_interface_decl);
1538 return true;
1539 }
1540 }
1541 }
1542 }
1543 return false;
1544}
1545
1546
1547bool
1548ClangASTContext::AddObjCClassIVar
1549(
Greg Clayton462d4142010-09-29 01:12:09 +00001550 ASTContext *ast_context,
1551 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001552 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001553 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001554 AccessType access,
1555 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001556 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001557)
1558{
1559 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1560 return false;
1561
Sean Callanan60a0ced2010-09-16 20:01:08 +00001562 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001563
1564 assert (ast_context != NULL);
1565 assert (identifier_table != NULL);
1566
1567 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1568
1569 clang::Type *class_type = class_qual_type.getTypePtr();
1570 if (class_type)
1571 {
1572 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1573
1574 if (objc_class_type)
1575 {
1576 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1577
1578 if (class_interface_decl)
1579 {
1580 clang::Expr *bit_width = NULL;
1581 if (bitfield_bit_size != 0)
1582 {
1583 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001584 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001585 }
1586
Greg Clayton9488b742010-07-28 02:04:09 +00001587 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1588 class_interface_decl,
1589 SourceLocation(),
1590 &identifier_table->get(name), // Identifier
1591 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1592 NULL, // TypeSourceInfo *
1593 ConvertAccessTypeToObjCIvarAccessControl (access),
1594 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001595 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001596
1597 if (field)
1598 {
1599 class_interface_decl->addDecl(field);
1600 return true;
1601 }
Greg Clayton84f80752010-07-22 18:30:50 +00001602 }
1603 }
1604 }
1605 return false;
1606}
Chris Lattner24943d22010-06-08 16:52:24 +00001607
Greg Clayton9488b742010-07-28 02:04:09 +00001608
1609bool
Greg Clayton462d4142010-09-29 01:12:09 +00001610ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001611{
1612 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1613
1614 clang::Type *class_type = class_qual_type.getTypePtr();
1615 if (class_type)
1616 {
1617 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1618
1619 if (objc_class_type)
1620 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1621 }
1622 return false;
1623}
1624
1625bool
1626ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1627{
1628 while (class_interface_decl)
1629 {
1630 if (class_interface_decl->ivar_size() > 0)
1631 return true;
1632
1633 if (check_superclass)
1634 class_interface_decl = class_interface_decl->getSuperClass();
1635 else
1636 break;
1637 }
1638 return false;
1639}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001640
Greg Clayton462d4142010-09-29 01:12:09 +00001641ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001642ClangASTContext::AddMethodToObjCObjectType
1643(
Greg Clayton462d4142010-09-29 01:12:09 +00001644 ASTContext *ast_context,
1645 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001646 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001647 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001648 lldb::AccessType access
1649)
1650{
1651 if (class_opaque_type == NULL || method_opaque_type == NULL)
1652 return NULL;
1653
1654 IdentifierTable *identifier_table = &ast_context->Idents;
1655
1656 assert (ast_context != NULL);
1657 assert (identifier_table != NULL);
1658
1659 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1660
1661 clang::Type *class_type = class_qual_type.getTypePtr();
1662 if (class_type == NULL)
1663 return NULL;
1664
1665 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1666
1667 if (objc_class_type == NULL)
1668 return NULL;
1669
1670 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1671
1672 if (class_interface_decl == NULL)
1673 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001674
Greg Clayton1d8173f2010-09-24 05:15:53 +00001675 const char *selector_start = ::strchr (name, ' ');
1676 if (selector_start == NULL)
1677 return NULL;
1678
1679 selector_start++;
1680 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1681 return NULL;
1682 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1683
Greg Claytonad60bf42010-10-12 02:24:53 +00001684 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001685 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001686 //printf ("name = '%s'\n", name);
1687
1688 unsigned num_selectors_with_args = 0;
1689 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001690 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001691 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001692 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001693 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001694 bool has_arg = (start[len] == ':');
1695 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001696 ++num_selectors_with_args;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001697 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001698 if (has_arg)
1699 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001700 }
1701
1702
1703 if (selector_idents.size() == 0)
1704 return 0;
1705
Greg Claytonad60bf42010-10-12 02:24:53 +00001706 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001707 selector_idents.data());
1708
1709 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1710
1711 // Populate the method decl with parameter decls
1712 clang::Type *method_type(method_qual_type.getTypePtr());
1713
1714 if (method_type == NULL)
1715 return NULL;
1716
1717 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1718
1719 if (!method_function_prototype)
1720 return NULL;
1721
1722
1723 bool is_variadic = false;
1724 bool is_synthesized = false;
1725 bool is_defined = false;
1726 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1727
1728 const unsigned num_args = method_function_prototype->getNumArgs();
1729
1730 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1731 SourceLocation(), // beginLoc,
1732 SourceLocation(), // endLoc,
1733 method_selector,
1734 method_function_prototype->getResultType(),
1735 NULL, // TypeSourceInfo *ResultTInfo,
1736 GetDeclContextForType (class_opaque_type),
1737 name[0] == '-',
1738 is_variadic,
1739 is_synthesized,
1740 is_defined,
1741 imp_control,
1742 num_args);
1743
1744
1745 if (objc_method_decl == NULL)
1746 return NULL;
1747
1748 if (num_args > 0)
1749 {
1750 llvm::SmallVector<ParmVarDecl *, 12> params;
1751
1752 for (int param_index = 0; param_index < num_args; ++param_index)
1753 {
1754 params.push_back (ParmVarDecl::Create (*ast_context,
1755 objc_method_decl,
1756 SourceLocation(),
1757 NULL, // anonymous
1758 method_function_prototype->getArgType(param_index),
1759 NULL,
1760 SC_Auto,
1761 SC_Auto,
1762 NULL));
1763 }
1764
1765 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1766 }
1767
1768 class_interface_decl->addDecl (objc_method_decl);
1769
1770
1771 return objc_method_decl;
1772}
1773
1774
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001775uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001776ClangASTContext::GetTypeInfo
1777(
1778 clang_type_t clang_type,
1779 clang::ASTContext *ast_context,
1780 clang_type_t *pointee_or_element_clang_type
1781)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001782{
1783 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001784 return 0;
1785
1786 if (pointee_or_element_clang_type)
1787 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001788
1789 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1790
1791 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1792 switch (type_class)
1793 {
Sean Callanan04325062010-10-25 00:29:48 +00001794 case clang::Type::Builtin:
1795 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1796 {
Sean Callanan04325062010-10-25 00:29:48 +00001797 case clang::BuiltinType::ObjCId:
1798 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001799 if (ast_context && pointee_or_element_clang_type)
1800 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001801 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001802
1803 default:
1804 break;
Sean Callanan04325062010-10-25 00:29:48 +00001805 }
1806 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001807
1808 case clang::Type::BlockPointer:
1809 if (pointee_or_element_clang_type)
1810 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1811 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1812
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001813 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001814
1815 case clang::Type::ConstantArray:
1816 case clang::Type::DependentSizedArray:
1817 case clang::Type::IncompleteArray:
1818 case clang::Type::VariableArray:
1819 if (pointee_or_element_clang_type)
1820 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1821 return eTypeHasChildren | eTypeIsArray;
1822
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001823 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001824 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1825 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1826 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001827
1828 case clang::Type::Enum:
1829 if (pointee_or_element_clang_type)
1830 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1831 return eTypeIsEnumeration | eTypeHasValue;
1832
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001833 case clang::Type::Elaborated: return 0;
1834 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1835 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1836 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001837 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001838
1839 case clang::Type::LValueReference:
1840 case clang::Type::RValueReference:
1841 if (pointee_or_element_clang_type)
1842 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1843 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1844
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001845 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001846
1847 case clang::Type::ObjCObjectPointer:
1848 if (pointee_or_element_clang_type)
1849 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1850 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1851
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001852 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1853 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001854
1855 case clang::Type::Pointer:
1856 if (pointee_or_element_clang_type)
1857 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1858 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1859
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001860 case clang::Type::Record:
1861 if (qual_type->getAsCXXRecordDecl())
1862 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1863 else
1864 return eTypeHasChildren | eTypeIsStructUnion;
1865 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001866 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1867 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1868 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001869
1870 case clang::Type::Typedef:
1871 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1872 ast_context,
1873 pointee_or_element_clang_type);
1874
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001875 case clang::Type::TypeOfExpr: return 0;
1876 case clang::Type::TypeOf: return 0;
1877 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001878 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1879 default: return 0;
1880 }
1881 return 0;
1882}
1883
Greg Clayton9488b742010-07-28 02:04:09 +00001884
Chris Lattner24943d22010-06-08 16:52:24 +00001885#pragma mark Aggregate Types
1886
1887bool
Greg Clayton462d4142010-09-29 01:12:09 +00001888ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001889{
1890 if (clang_type == NULL)
1891 return false;
1892
1893 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1894
Greg Clayton03e0f972010-09-13 03:32:57 +00001895 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1896 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001897 {
Greg Clayton1674b122010-07-21 22:12:05 +00001898 case clang::Type::IncompleteArray:
1899 case clang::Type::VariableArray:
1900 case clang::Type::ConstantArray:
1901 case clang::Type::ExtVector:
1902 case clang::Type::Vector:
1903 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001904 case clang::Type::ObjCObject:
1905 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001906 return true;
1907
Greg Clayton1674b122010-07-21 22:12:05 +00001908 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001909 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1910
1911 default:
1912 break;
1913 }
1914 // The clang type does have a value
1915 return false;
1916}
1917
1918uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001919ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001920{
1921 if (clang_qual_type == NULL)
1922 return 0;
1923
1924 uint32_t num_children = 0;
1925 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001926 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1927 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001928 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001929 case clang::Type::Builtin:
1930 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1931 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001932 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001933 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001934 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001935 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001936
1937 default:
1938 break;
1939 }
1940 break;
1941
Greg Clayton1674b122010-07-21 22:12:05 +00001942 case clang::Type::Record:
Greg Clayton53d287b2010-11-11 02:14:53 +00001943 if (ClangASTType::IsDefined (clang_qual_type))
Chris Lattner24943d22010-06-08 16:52:24 +00001944 {
1945 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1946 const RecordDecl *record_decl = record_type->getDecl();
1947 assert(record_decl);
1948 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1949 if (cxx_record_decl)
1950 {
1951 if (omit_empty_base_classes)
1952 {
1953 // Check each base classes to see if it or any of its
1954 // base classes contain any fields. This can help
1955 // limit the noise in variable views by not having to
1956 // show base classes that contain no members.
1957 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1958 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1959 base_class != base_class_end;
1960 ++base_class)
1961 {
1962 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1963
1964 // Skip empty base classes
1965 if (RecordHasFields(base_class_decl) == false)
1966 continue;
1967
1968 num_children++;
1969 }
1970 }
1971 else
1972 {
1973 // Include all base classes
1974 num_children += cxx_record_decl->getNumBases();
1975 }
1976
1977 }
1978 RecordDecl::field_iterator field, field_end;
1979 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1980 ++num_children;
1981 }
1982 break;
1983
Greg Clayton9488b742010-07-28 02:04:09 +00001984 case clang::Type::ObjCObject:
1985 case clang::Type::ObjCInterface:
1986 {
1987 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1988 assert (objc_class_type);
1989 if (objc_class_type)
1990 {
1991 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1992
1993 if (class_interface_decl)
1994 {
1995
1996 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1997 if (superclass_interface_decl)
1998 {
1999 if (omit_empty_base_classes)
2000 {
2001 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2002 ++num_children;
2003 }
2004 else
2005 ++num_children;
2006 }
2007
2008 num_children += class_interface_decl->ivar_size();
2009 }
2010 }
2011 }
2012 break;
2013
2014 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00002015 {
2016 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
2017 QualType pointee_type = pointer_type->getPointeeType();
2018 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
2019 omit_empty_base_classes);
2020 // If this type points to a simple type, then it has 1 child
2021 if (num_pointee_children == 0)
2022 num_children = 1;
2023 else
2024 num_children = num_pointee_children;
2025 }
2026 break;
Greg Clayton9488b742010-07-28 02:04:09 +00002027
Greg Clayton1674b122010-07-21 22:12:05 +00002028 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002029 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2030 break;
2031
Greg Clayton1674b122010-07-21 22:12:05 +00002032 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002033 {
2034 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2035 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00002036 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
2037 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00002038 // If this type points to a simple type, then it has 1 child
2039 if (num_pointee_children == 0)
2040 num_children = 1;
2041 else
2042 num_children = num_pointee_children;
2043 }
2044 break;
2045
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002046 case clang::Type::LValueReference:
2047 case clang::Type::RValueReference:
2048 {
2049 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2050 QualType pointee_type = reference_type->getPointeeType();
2051 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
2052 omit_empty_base_classes);
2053 // If this type points to a simple type, then it has 1 child
2054 if (num_pointee_children == 0)
2055 num_children = 1;
2056 else
2057 num_children = num_pointee_children;
2058 }
2059 break;
2060
2061
Greg Clayton1674b122010-07-21 22:12:05 +00002062 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002063 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
2064 break;
2065
2066 default:
2067 break;
2068 }
2069 return num_children;
2070}
2071
2072
Greg Clayton462d4142010-09-29 01:12:09 +00002073clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002074ClangASTContext::GetChildClangTypeAtIndex
2075(
2076 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002077 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002078 uint32_t idx,
2079 bool transparent_pointers,
2080 bool omit_empty_base_classes,
2081 std::string& child_name,
2082 uint32_t &child_byte_size,
2083 int32_t &child_byte_offset,
2084 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002085 uint32_t &child_bitfield_bit_offset,
2086 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002087)
2088{
2089 if (parent_clang_type)
2090
2091 return GetChildClangTypeAtIndex (getASTContext(),
2092 parent_name,
2093 parent_clang_type,
2094 idx,
2095 transparent_pointers,
2096 omit_empty_base_classes,
2097 child_name,
2098 child_byte_size,
2099 child_byte_offset,
2100 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002101 child_bitfield_bit_offset,
2102 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002103 return NULL;
2104}
2105
Greg Clayton462d4142010-09-29 01:12:09 +00002106clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002107ClangASTContext::GetChildClangTypeAtIndex
2108(
2109 ASTContext *ast_context,
2110 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002111 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002112 uint32_t idx,
2113 bool transparent_pointers,
2114 bool omit_empty_base_classes,
2115 std::string& child_name,
2116 uint32_t &child_byte_size,
2117 int32_t &child_byte_offset,
2118 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002119 uint32_t &child_bitfield_bit_offset,
2120 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002121)
2122{
2123 if (parent_clang_type == NULL)
2124 return NULL;
2125
2126 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2127 {
2128 uint32_t bit_offset;
2129 child_bitfield_bit_size = 0;
2130 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002131 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002132 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002133 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2134 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002135 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002136 case clang::Type::Builtin:
2137 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2138 {
2139 case clang::BuiltinType::ObjCId:
2140 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002141 child_name = "isa";
2142 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002143 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2144
Greg Clayton960d6a42010-08-03 00:35:52 +00002145 default:
2146 break;
2147 }
2148 break;
2149
2150
Greg Clayton1674b122010-07-21 22:12:05 +00002151 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002152 {
2153 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2154 const RecordDecl *record_decl = record_type->getDecl();
2155 assert(record_decl);
2156 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2157 uint32_t child_idx = 0;
2158
2159 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2160 if (cxx_record_decl)
2161 {
2162 // We might have base classes to print out first
2163 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2164 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2165 base_class != base_class_end;
2166 ++base_class)
2167 {
2168 const CXXRecordDecl *base_class_decl = NULL;
2169
2170 // Skip empty base classes
2171 if (omit_empty_base_classes)
2172 {
2173 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2174 if (RecordHasFields(base_class_decl) == false)
2175 continue;
2176 }
2177
2178 if (idx == child_idx)
2179 {
2180 if (base_class_decl == NULL)
2181 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2182
2183
2184 if (base_class->isVirtual())
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002185 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002186 else
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002187 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002188
2189 // Base classes should be a multiple of 8 bits in size
2190 assert (bit_offset % 8 == 0);
2191 child_byte_offset = bit_offset/8;
2192 std::string base_class_type_name(base_class->getType().getAsString());
2193
2194 child_name.assign(base_class_type_name.c_str());
2195
2196 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2197
2198 // Base classes biut sizes should be a multiple of 8 bits in size
2199 assert (clang_type_info_bit_size % 8 == 0);
2200 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002201 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002202 return base_class->getType().getAsOpaquePtr();
2203 }
2204 // We don't increment the child index in the for loop since we might
2205 // be skipping empty base classes
2206 ++child_idx;
2207 }
2208 }
Chris Lattner24943d22010-06-08 16:52:24 +00002209 // Make sure index is in range...
2210 uint32_t field_idx = 0;
2211 RecordDecl::field_iterator field, field_end;
2212 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2213 {
2214 if (idx == child_idx)
2215 {
2216 // Print the member type if requested
2217 // Print the member name and equal sign
2218 child_name.assign(field->getNameAsString().c_str());
2219
2220 // Figure out the type byte size (field_type_info.first) and
2221 // alignment (field_type_info.second) from the AST context.
2222 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002223 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002224
2225 child_byte_size = field_type_info.first / 8;
2226
2227 // Figure out the field offset within the current struct/union/class type
2228 bit_offset = record_layout.getFieldOffset (field_idx);
2229 child_byte_offset = bit_offset / 8;
2230 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2231 child_bitfield_bit_offset = bit_offset % 8;
2232
2233 return field->getType().getAsOpaquePtr();
2234 }
2235 }
2236 }
2237 break;
2238
Greg Clayton9488b742010-07-28 02:04:09 +00002239 case clang::Type::ObjCObject:
2240 case clang::Type::ObjCInterface:
2241 {
2242 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2243 assert (objc_class_type);
2244 if (objc_class_type)
2245 {
2246 uint32_t child_idx = 0;
2247 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2248
2249 if (class_interface_decl)
2250 {
2251
2252 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2253 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2254 if (superclass_interface_decl)
2255 {
2256 if (omit_empty_base_classes)
2257 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002258 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002259 {
2260 if (idx == 0)
2261 {
2262 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2263
2264
2265 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2266
2267 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2268
2269 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002270 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002271 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002272
2273 return ivar_qual_type.getAsOpaquePtr();
2274 }
2275
2276 ++child_idx;
2277 }
2278 }
2279 else
2280 ++child_idx;
2281 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002282
2283 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002284
2285 if (idx < (child_idx + class_interface_decl->ivar_size()))
2286 {
2287 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2288
2289 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2290 {
2291 if (child_idx == idx)
2292 {
2293 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2294
2295 QualType ivar_qual_type(ivar_decl->getType());
2296
2297 child_name.assign(ivar_decl->getNameAsString().c_str());
2298
2299 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2300
2301 child_byte_size = ivar_type_info.first / 8;
2302
2303 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002304 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002305 child_byte_offset = bit_offset / 8;
2306
2307 return ivar_qual_type.getAsOpaquePtr();
2308 }
2309 ++child_idx;
2310 }
2311 }
2312 }
2313 }
2314 }
2315 break;
2316
2317 case clang::Type::ObjCObjectPointer:
2318 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002319 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2320 QualType pointee_type = pointer_type->getPointeeType();
2321
2322 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2323 {
2324 return GetChildClangTypeAtIndex (ast_context,
2325 parent_name,
2326 pointer_type->getPointeeType().getAsOpaquePtr(),
2327 idx,
2328 transparent_pointers,
2329 omit_empty_base_classes,
2330 child_name,
2331 child_byte_size,
2332 child_byte_offset,
2333 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002334 child_bitfield_bit_offset,
2335 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002336 }
2337 else
2338 {
2339 if (parent_name)
2340 {
2341 child_name.assign(1, '*');
2342 child_name += parent_name;
2343 }
2344
2345 // We have a pointer to an simple type
2346 if (idx == 0)
2347 {
2348 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2349 assert(clang_type_info.first % 8 == 0);
2350 child_byte_size = clang_type_info.first / 8;
2351 child_byte_offset = 0;
2352 return pointee_type.getAsOpaquePtr();
2353 }
2354 }
Greg Clayton9488b742010-07-28 02:04:09 +00002355 }
2356 break;
2357
Greg Clayton1674b122010-07-21 22:12:05 +00002358 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002359 {
2360 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2361 const uint64_t element_count = array->getSize().getLimitedValue();
2362
2363 if (idx < element_count)
2364 {
2365 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2366
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002367 char element_name[64];
2368 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002369
2370 child_name.assign(element_name);
2371 assert(field_type_info.first % 8 == 0);
2372 child_byte_size = field_type_info.first / 8;
2373 child_byte_offset = idx * child_byte_size;
2374 return array->getElementType().getAsOpaquePtr();
2375 }
2376 }
2377 break;
2378
Greg Clayton1674b122010-07-21 22:12:05 +00002379 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002380 {
2381 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2382 QualType pointee_type = pointer_type->getPointeeType();
2383
2384 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2385 {
2386 return GetChildClangTypeAtIndex (ast_context,
2387 parent_name,
2388 pointer_type->getPointeeType().getAsOpaquePtr(),
2389 idx,
2390 transparent_pointers,
2391 omit_empty_base_classes,
2392 child_name,
2393 child_byte_size,
2394 child_byte_offset,
2395 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002396 child_bitfield_bit_offset,
2397 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002398 }
2399 else
2400 {
2401 if (parent_name)
2402 {
2403 child_name.assign(1, '*');
2404 child_name += parent_name;
2405 }
2406
2407 // We have a pointer to an simple type
2408 if (idx == 0)
2409 {
2410 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2411 assert(clang_type_info.first % 8 == 0);
2412 child_byte_size = clang_type_info.first / 8;
2413 child_byte_offset = 0;
2414 return pointee_type.getAsOpaquePtr();
2415 }
2416 }
2417 }
2418 break;
2419
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002420 case clang::Type::LValueReference:
2421 case clang::Type::RValueReference:
2422 {
2423 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2424 QualType pointee_type(reference_type->getPointeeType());
2425 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2426 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2427 {
2428 return GetChildClangTypeAtIndex (ast_context,
2429 parent_name,
2430 pointee_clang_type,
2431 idx,
2432 transparent_pointers,
2433 omit_empty_base_classes,
2434 child_name,
2435 child_byte_size,
2436 child_byte_offset,
2437 child_bitfield_bit_size,
2438 child_bitfield_bit_offset,
2439 child_is_base_class);
2440 }
2441 else
2442 {
2443 if (parent_name)
2444 {
2445 child_name.assign(1, '&');
2446 child_name += parent_name;
2447 }
2448
2449 // We have a pointer to an simple type
2450 if (idx == 0)
2451 {
2452 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2453 assert(clang_type_info.first % 8 == 0);
2454 child_byte_size = clang_type_info.first / 8;
2455 child_byte_offset = 0;
2456 return pointee_type.getAsOpaquePtr();
2457 }
2458 }
2459 }
2460 break;
2461
Greg Clayton1674b122010-07-21 22:12:05 +00002462 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002463 return GetChildClangTypeAtIndex (ast_context,
2464 parent_name,
2465 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2466 idx,
2467 transparent_pointers,
2468 omit_empty_base_classes,
2469 child_name,
2470 child_byte_size,
2471 child_byte_offset,
2472 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002473 child_bitfield_bit_offset,
2474 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002475 break;
2476
2477 default:
2478 break;
2479 }
2480 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002481 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002482}
2483
2484static inline bool
2485BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2486{
2487 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2488}
2489
2490static uint32_t
2491GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2492{
2493 uint32_t num_bases = 0;
2494 if (cxx_record_decl)
2495 {
2496 if (omit_empty_base_classes)
2497 {
2498 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2499 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2500 base_class != base_class_end;
2501 ++base_class)
2502 {
2503 // Skip empty base classes
2504 if (omit_empty_base_classes)
2505 {
2506 if (BaseSpecifierIsEmpty (base_class))
2507 continue;
2508 }
2509 ++num_bases;
2510 }
2511 }
2512 else
2513 num_bases = cxx_record_decl->getNumBases();
2514 }
2515 return num_bases;
2516}
2517
2518
2519static uint32_t
2520GetIndexForRecordBase
2521(
2522 const RecordDecl *record_decl,
2523 const CXXBaseSpecifier *base_spec,
2524 bool omit_empty_base_classes
2525)
2526{
2527 uint32_t child_idx = 0;
2528
2529 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2530
2531// const char *super_name = record_decl->getNameAsCString();
2532// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2533// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2534//
2535 if (cxx_record_decl)
2536 {
2537 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2538 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2539 base_class != base_class_end;
2540 ++base_class)
2541 {
2542 if (omit_empty_base_classes)
2543 {
2544 if (BaseSpecifierIsEmpty (base_class))
2545 continue;
2546 }
2547
2548// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2549// child_idx,
2550// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2551//
2552//
2553 if (base_class == base_spec)
2554 return child_idx;
2555 ++child_idx;
2556 }
2557 }
2558
2559 return UINT32_MAX;
2560}
2561
2562
2563static uint32_t
2564GetIndexForRecordChild
2565(
2566 const RecordDecl *record_decl,
2567 NamedDecl *canonical_decl,
2568 bool omit_empty_base_classes
2569)
2570{
2571 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2572
2573// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2574//
2575//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2576// if (cxx_record_decl)
2577// {
2578// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2579// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2580// base_class != base_class_end;
2581// ++base_class)
2582// {
2583// if (omit_empty_base_classes)
2584// {
2585// if (BaseSpecifierIsEmpty (base_class))
2586// continue;
2587// }
2588//
2589//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2590//// record_decl->getNameAsCString(),
2591//// canonical_decl->getNameAsCString(),
2592//// child_idx,
2593//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2594//
2595//
2596// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2597// if (curr_base_class_decl == canonical_decl)
2598// {
2599// return child_idx;
2600// }
2601// ++child_idx;
2602// }
2603// }
2604//
2605// const uint32_t num_bases = child_idx;
2606 RecordDecl::field_iterator field, field_end;
2607 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2608 field != field_end;
2609 ++field, ++child_idx)
2610 {
2611// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2612// record_decl->getNameAsCString(),
2613// canonical_decl->getNameAsCString(),
2614// child_idx - num_bases,
2615// field->getNameAsCString());
2616
2617 if (field->getCanonicalDecl() == canonical_decl)
2618 return child_idx;
2619 }
2620
2621 return UINT32_MAX;
2622}
2623
2624// Look for a child member (doesn't include base classes, but it does include
2625// their members) in the type hierarchy. Returns an index path into "clang_type"
2626// on how to reach the appropriate member.
2627//
2628// class A
2629// {
2630// public:
2631// int m_a;
2632// int m_b;
2633// };
2634//
2635// class B
2636// {
2637// };
2638//
2639// class C :
2640// public B,
2641// public A
2642// {
2643// };
2644//
2645// If we have a clang type that describes "class C", and we wanted to looked
2646// "m_b" in it:
2647//
2648// With omit_empty_base_classes == false we would get an integer array back with:
2649// { 1, 1 }
2650// The first index 1 is the child index for "class A" within class C
2651// The second index 1 is the child index for "m_b" within class A
2652//
2653// With omit_empty_base_classes == true we would get an integer array back with:
2654// { 0, 1 }
2655// 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)
2656// The second index 1 is the child index for "m_b" within class A
2657
2658size_t
2659ClangASTContext::GetIndexOfChildMemberWithName
2660(
2661 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002662 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002663 const char *name,
2664 bool omit_empty_base_classes,
2665 std::vector<uint32_t>& child_indexes
2666)
2667{
2668 if (clang_type && name && name[0])
2669 {
2670 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002671 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2672 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002673 {
Greg Clayton1674b122010-07-21 22:12:05 +00002674 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002675 {
2676 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2677 const RecordDecl *record_decl = record_type->getDecl();
2678
2679 assert(record_decl);
2680 uint32_t child_idx = 0;
2681
2682 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2683
2684 // Try and find a field that matches NAME
2685 RecordDecl::field_iterator field, field_end;
2686 StringRef name_sref(name);
2687 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2688 field != field_end;
2689 ++field, ++child_idx)
2690 {
2691 if (field->getName().equals (name_sref))
2692 {
2693 // We have to add on the number of base classes to this index!
2694 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2695 return child_indexes.size();
2696 }
2697 }
2698
2699 if (cxx_record_decl)
2700 {
2701 const RecordDecl *parent_record_decl = cxx_record_decl;
2702
2703 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2704
2705 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2706 // Didn't find things easily, lets let clang do its thang...
2707 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2708 DeclarationName decl_name(&ident_ref);
2709
2710 CXXBasePaths paths;
2711 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2712 decl_name.getAsOpaquePtr(),
2713 paths))
2714 {
Chris Lattner24943d22010-06-08 16:52:24 +00002715 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2716 for (path = paths.begin(); path != path_end; ++path)
2717 {
2718 const size_t num_path_elements = path->size();
2719 for (size_t e=0; e<num_path_elements; ++e)
2720 {
2721 CXXBasePathElement elem = (*path)[e];
2722
2723 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2724 if (child_idx == UINT32_MAX)
2725 {
2726 child_indexes.clear();
2727 return 0;
2728 }
2729 else
2730 {
2731 child_indexes.push_back (child_idx);
2732 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2733 }
2734 }
2735 DeclContext::lookup_iterator named_decl_pos;
2736 for (named_decl_pos = path->Decls.first;
2737 named_decl_pos != path->Decls.second && parent_record_decl;
2738 ++named_decl_pos)
2739 {
2740 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2741
2742 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2743 if (child_idx == UINT32_MAX)
2744 {
2745 child_indexes.clear();
2746 return 0;
2747 }
2748 else
2749 {
2750 child_indexes.push_back (child_idx);
2751 }
2752 }
2753 }
2754 return child_indexes.size();
2755 }
2756 }
2757
2758 }
2759 break;
2760
Greg Clayton9488b742010-07-28 02:04:09 +00002761 case clang::Type::ObjCObject:
2762 case clang::Type::ObjCInterface:
2763 {
2764 StringRef name_sref(name);
2765 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2766 assert (objc_class_type);
2767 if (objc_class_type)
2768 {
2769 uint32_t child_idx = 0;
2770 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2771
2772 if (class_interface_decl)
2773 {
2774 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2775 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2776
Greg Clayton823533e2010-09-18 02:11:07 +00002777 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002778 {
2779 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2780
2781 if (ivar_decl->getName().equals (name_sref))
2782 {
2783 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2784 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2785 ++child_idx;
2786
2787 child_indexes.push_back (child_idx);
2788 return child_indexes.size();
2789 }
2790 }
2791
2792 if (superclass_interface_decl)
2793 {
2794 // The super class index is always zero for ObjC classes,
2795 // so we push it onto the child indexes in case we find
2796 // an ivar in our superclass...
2797 child_indexes.push_back (0);
2798
2799 if (GetIndexOfChildMemberWithName (ast_context,
2800 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2801 name,
2802 omit_empty_base_classes,
2803 child_indexes))
2804 {
2805 // We did find an ivar in a superclass so just
2806 // return the results!
2807 return child_indexes.size();
2808 }
2809
2810 // We didn't find an ivar matching "name" in our
2811 // superclass, pop the superclass zero index that
2812 // we pushed on above.
2813 child_indexes.pop_back();
2814 }
2815 }
2816 }
2817 }
2818 break;
2819
2820 case clang::Type::ObjCObjectPointer:
2821 {
2822 return GetIndexOfChildMemberWithName (ast_context,
2823 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2824 name,
2825 omit_empty_base_classes,
2826 child_indexes);
2827 }
2828 break;
2829
2830
Greg Clayton1674b122010-07-21 22:12:05 +00002831 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002832 {
2833// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2834// const uint64_t element_count = array->getSize().getLimitedValue();
2835//
2836// if (idx < element_count)
2837// {
2838// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2839//
2840// char element_name[32];
2841// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2842//
2843// child_name.assign(element_name);
2844// assert(field_type_info.first % 8 == 0);
2845// child_byte_size = field_type_info.first / 8;
2846// child_byte_offset = idx * child_byte_size;
2847// return array->getElementType().getAsOpaquePtr();
2848// }
2849 }
2850 break;
2851
Greg Clayton1674b122010-07-21 22:12:05 +00002852// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002853// {
2854// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2855// QualType pointee_type = mem_ptr_type->getPointeeType();
2856//
2857// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2858// {
2859// return GetIndexOfChildWithName (ast_context,
2860// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2861// name);
2862// }
2863// }
2864// break;
2865//
Greg Clayton1674b122010-07-21 22:12:05 +00002866 case clang::Type::LValueReference:
2867 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002868 {
2869 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2870 QualType pointee_type = reference_type->getPointeeType();
2871
2872 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2873 {
2874 return GetIndexOfChildMemberWithName (ast_context,
2875 reference_type->getPointeeType().getAsOpaquePtr(),
2876 name,
2877 omit_empty_base_classes,
2878 child_indexes);
2879 }
2880 }
2881 break;
2882
Greg Clayton1674b122010-07-21 22:12:05 +00002883 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002884 {
2885 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2886 QualType pointee_type = pointer_type->getPointeeType();
2887
2888 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2889 {
2890 return GetIndexOfChildMemberWithName (ast_context,
2891 pointer_type->getPointeeType().getAsOpaquePtr(),
2892 name,
2893 omit_empty_base_classes,
2894 child_indexes);
2895 }
2896 else
2897 {
2898// if (parent_name)
2899// {
2900// child_name.assign(1, '*');
2901// child_name += parent_name;
2902// }
2903//
2904// // We have a pointer to an simple type
2905// if (idx == 0)
2906// {
2907// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2908// assert(clang_type_info.first % 8 == 0);
2909// child_byte_size = clang_type_info.first / 8;
2910// child_byte_offset = 0;
2911// return pointee_type.getAsOpaquePtr();
2912// }
2913 }
2914 }
2915 break;
2916
Greg Clayton1674b122010-07-21 22:12:05 +00002917 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002918 return GetIndexOfChildMemberWithName (ast_context,
2919 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2920 name,
2921 omit_empty_base_classes,
2922 child_indexes);
2923
2924 default:
2925 break;
2926 }
2927 }
2928 return 0;
2929}
2930
2931
2932// Get the index of the child of "clang_type" whose name matches. This function
2933// doesn't descend into the children, but only looks one level deep and name
2934// matches can include base class names.
2935
2936uint32_t
2937ClangASTContext::GetIndexOfChildWithName
2938(
2939 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002940 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002941 const char *name,
2942 bool omit_empty_base_classes
2943)
2944{
2945 if (clang_type && name && name[0])
2946 {
2947 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002948
Greg Clayton03e0f972010-09-13 03:32:57 +00002949 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002950
Greg Clayton03e0f972010-09-13 03:32:57 +00002951 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002952 {
Greg Clayton1674b122010-07-21 22:12:05 +00002953 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002954 {
2955 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2956 const RecordDecl *record_decl = record_type->getDecl();
2957
2958 assert(record_decl);
2959 uint32_t child_idx = 0;
2960
2961 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2962
2963 if (cxx_record_decl)
2964 {
2965 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2966 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2967 base_class != base_class_end;
2968 ++base_class)
2969 {
2970 // Skip empty base classes
2971 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2972 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2973 continue;
2974
2975 if (base_class->getType().getAsString().compare (name) == 0)
2976 return child_idx;
2977 ++child_idx;
2978 }
2979 }
2980
2981 // Try and find a field that matches NAME
2982 RecordDecl::field_iterator field, field_end;
2983 StringRef name_sref(name);
2984 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2985 field != field_end;
2986 ++field, ++child_idx)
2987 {
2988 if (field->getName().equals (name_sref))
2989 return child_idx;
2990 }
2991
2992 }
2993 break;
2994
Greg Clayton9488b742010-07-28 02:04:09 +00002995 case clang::Type::ObjCObject:
2996 case clang::Type::ObjCInterface:
2997 {
2998 StringRef name_sref(name);
2999 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
3000 assert (objc_class_type);
3001 if (objc_class_type)
3002 {
3003 uint32_t child_idx = 0;
3004 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3005
3006 if (class_interface_decl)
3007 {
3008 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3009 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3010
3011 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3012 {
3013 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3014
3015 if (ivar_decl->getName().equals (name_sref))
3016 {
3017 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3018 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3019 ++child_idx;
3020
3021 return child_idx;
3022 }
3023 }
3024
3025 if (superclass_interface_decl)
3026 {
3027 if (superclass_interface_decl->getName().equals (name_sref))
3028 return 0;
3029 }
3030 }
3031 }
3032 }
3033 break;
3034
3035 case clang::Type::ObjCObjectPointer:
3036 {
3037 return GetIndexOfChildWithName (ast_context,
3038 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3039 name,
3040 omit_empty_base_classes);
3041 }
3042 break;
3043
Greg Clayton1674b122010-07-21 22:12:05 +00003044 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003045 {
3046// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3047// const uint64_t element_count = array->getSize().getLimitedValue();
3048//
3049// if (idx < element_count)
3050// {
3051// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
3052//
3053// char element_name[32];
3054// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3055//
3056// child_name.assign(element_name);
3057// assert(field_type_info.first % 8 == 0);
3058// child_byte_size = field_type_info.first / 8;
3059// child_byte_offset = idx * child_byte_size;
3060// return array->getElementType().getAsOpaquePtr();
3061// }
3062 }
3063 break;
3064
Greg Clayton1674b122010-07-21 22:12:05 +00003065// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00003066// {
3067// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3068// QualType pointee_type = mem_ptr_type->getPointeeType();
3069//
3070// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3071// {
3072// return GetIndexOfChildWithName (ast_context,
3073// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3074// name);
3075// }
3076// }
3077// break;
3078//
Greg Clayton1674b122010-07-21 22:12:05 +00003079 case clang::Type::LValueReference:
3080 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003081 {
3082 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3083 QualType pointee_type = reference_type->getPointeeType();
3084
3085 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3086 {
3087 return GetIndexOfChildWithName (ast_context,
3088 reference_type->getPointeeType().getAsOpaquePtr(),
3089 name,
3090 omit_empty_base_classes);
3091 }
3092 }
3093 break;
3094
Greg Clayton1674b122010-07-21 22:12:05 +00003095 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003096 {
3097 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3098 QualType pointee_type = pointer_type->getPointeeType();
3099
3100 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3101 {
3102 return GetIndexOfChildWithName (ast_context,
3103 pointer_type->getPointeeType().getAsOpaquePtr(),
3104 name,
3105 omit_empty_base_classes);
3106 }
3107 else
3108 {
3109// if (parent_name)
3110// {
3111// child_name.assign(1, '*');
3112// child_name += parent_name;
3113// }
3114//
3115// // We have a pointer to an simple type
3116// if (idx == 0)
3117// {
3118// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3119// assert(clang_type_info.first % 8 == 0);
3120// child_byte_size = clang_type_info.first / 8;
3121// child_byte_offset = 0;
3122// return pointee_type.getAsOpaquePtr();
3123// }
3124 }
3125 }
3126 break;
3127
Greg Clayton1674b122010-07-21 22:12:05 +00003128 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003129 return GetIndexOfChildWithName (ast_context,
3130 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3131 name,
3132 omit_empty_base_classes);
3133
3134 default:
3135 break;
3136 }
3137 }
3138 return UINT32_MAX;
3139}
3140
3141#pragma mark TagType
3142
3143bool
Greg Clayton462d4142010-09-29 01:12:09 +00003144ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003145{
3146 if (tag_clang_type)
3147 {
3148 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003149 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003150 if (clang_type)
3151 {
3152 TagType *tag_type = dyn_cast<TagType>(clang_type);
3153 if (tag_type)
3154 {
3155 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3156 if (tag_decl)
3157 {
3158 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3159 return true;
3160 }
3161 }
3162 }
3163 }
3164 return false;
3165}
3166
3167
3168#pragma mark DeclContext Functions
3169
3170DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003171ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003172{
3173 if (clang_type == NULL)
3174 return NULL;
3175
3176 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003177 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3178 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003179 {
Greg Clayton9488b742010-07-28 02:04:09 +00003180 case clang::Type::FunctionNoProto: break;
3181 case clang::Type::FunctionProto: break;
3182 case clang::Type::IncompleteArray: break;
3183 case clang::Type::VariableArray: break;
3184 case clang::Type::ConstantArray: break;
3185 case clang::Type::ExtVector: break;
3186 case clang::Type::Vector: break;
3187 case clang::Type::Builtin: break;
3188 case clang::Type::BlockPointer: break;
3189 case clang::Type::Pointer: break;
3190 case clang::Type::LValueReference: break;
3191 case clang::Type::RValueReference: break;
3192 case clang::Type::MemberPointer: break;
3193 case clang::Type::Complex: break;
3194 case clang::Type::ObjCObject: break;
3195 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3196 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3197 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3198 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
3199 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003200
Greg Clayton9488b742010-07-28 02:04:09 +00003201 case clang::Type::TypeOfExpr: break;
3202 case clang::Type::TypeOf: break;
3203 case clang::Type::Decltype: break;
3204 //case clang::Type::QualifiedName: break;
3205 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003206 }
3207 // No DeclContext in this type...
3208 return NULL;
3209}
3210
3211#pragma mark Namespace Declarations
3212
3213NamespaceDecl *
3214ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3215{
3216 // TODO: Do something intelligent with the Declaration object passed in
3217 // like maybe filling in the SourceLocation with it...
3218 if (name)
3219 {
3220 ASTContext *ast_context = getASTContext();
3221 if (decl_ctx == NULL)
3222 decl_ctx = ast_context->getTranslationUnitDecl();
3223 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3224 }
3225 return NULL;
3226}
3227
3228
3229#pragma mark Function Types
3230
3231FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003232ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003233{
3234 if (name)
3235 {
3236 ASTContext *ast_context = getASTContext();
3237 assert (ast_context != NULL);
3238
3239 if (name && name[0])
3240 {
3241 return FunctionDecl::Create(*ast_context,
3242 ast_context->getTranslationUnitDecl(),
3243 SourceLocation(),
3244 DeclarationName (&ast_context->Idents.get(name)),
3245 QualType::getFromOpaquePtr(function_clang_type),
3246 NULL,
3247 (FunctionDecl::StorageClass)storage,
3248 (FunctionDecl::StorageClass)storage,
3249 is_inline);
3250 }
3251 else
3252 {
3253 return FunctionDecl::Create(*ast_context,
3254 ast_context->getTranslationUnitDecl(),
3255 SourceLocation(),
3256 DeclarationName (),
3257 QualType::getFromOpaquePtr(function_clang_type),
3258 NULL,
3259 (FunctionDecl::StorageClass)storage,
3260 (FunctionDecl::StorageClass)storage,
3261 is_inline);
3262 }
3263 }
3264 return NULL;
3265}
3266
Greg Clayton462d4142010-09-29 01:12:09 +00003267clang_type_t
3268ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3269 clang_type_t result_type,
3270 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003271 unsigned num_args,
3272 bool is_variadic,
3273 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003274{
Chris Lattner24943d22010-06-08 16:52:24 +00003275 assert (ast_context != NULL);
3276 std::vector<QualType> qual_type_args;
3277 for (unsigned i=0; i<num_args; ++i)
3278 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3279
3280 // TODO: Detect calling convention in DWARF?
3281 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003282 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003283 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003284 is_variadic,
3285 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003286 false, // hasExceptionSpec
3287 false, // hasAnyExceptionSpec,
3288 0, // NumExs
3289 0, // const QualType *ExArray
3290 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3291}
3292
3293ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003294ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003295{
3296 ASTContext *ast_context = getASTContext();
3297 assert (ast_context != NULL);
3298 return ParmVarDecl::Create(*ast_context,
3299 ast_context->getTranslationUnitDecl(),
3300 SourceLocation(),
3301 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003302 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003303 NULL,
3304 (VarDecl::StorageClass)storage,
3305 (VarDecl::StorageClass)storage,
3306 0);
3307}
3308
3309void
3310ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3311{
3312 if (function_decl)
3313 function_decl->setParams (params, num_params);
3314}
3315
3316
3317#pragma mark Array Types
3318
Greg Clayton462d4142010-09-29 01:12:09 +00003319clang_type_t
3320ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003321{
3322 if (element_type)
3323 {
3324 ASTContext *ast_context = getASTContext();
3325 assert (ast_context != NULL);
3326 llvm::APInt ap_element_count (64, element_count);
3327 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3328 ap_element_count,
3329 ArrayType::Normal,
3330 0).getAsOpaquePtr(); // ElemQuals
3331 }
3332 return NULL;
3333}
3334
3335
3336#pragma mark TagDecl
3337
3338bool
Greg Clayton462d4142010-09-29 01:12:09 +00003339ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003340{
3341 if (clang_type)
3342 {
3343 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003344 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003345 if (t)
3346 {
3347 TagType *tag_type = dyn_cast<TagType>(t);
3348 if (tag_type)
3349 {
3350 TagDecl *tag_decl = tag_type->getDecl();
3351 if (tag_decl)
3352 {
3353 tag_decl->startDefinition();
3354 return true;
3355 }
3356 }
3357 }
3358 }
3359 return false;
3360}
3361
3362bool
Greg Clayton462d4142010-09-29 01:12:09 +00003363ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003364{
3365 if (clang_type)
3366 {
3367 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00003368
3369 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3370
3371 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003372 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003373 cxx_record_decl->completeDefinition();
3374
3375 return true;
3376 }
3377
Sean Callanan04325062010-10-25 00:29:48 +00003378 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3379
3380 if (objc_class_type)
3381 {
3382 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3383
3384 class_interface_decl->setForwardDecl(false);
3385 }
3386
Greg Clayton55b6c532010-09-29 03:44:17 +00003387 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3388
3389 if (enum_type)
3390 {
3391 EnumDecl *enum_decl = enum_type->getDecl();
3392
3393 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003394 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003395 /// TODO This really needs to be fixed.
3396
3397 unsigned NumPositiveBits = 1;
3398 unsigned NumNegativeBits = 0;
3399
Greg Clayton48fbdf72010-10-12 04:29:14 +00003400 ASTContext *ast_context = getASTContext();
3401
3402 QualType promotion_qual_type;
3403 // If the enum integer type is less than an integer in bit width,
3404 // then we must promote it to an integer size.
3405 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3406 {
3407 if (enum_decl->getIntegerType()->isSignedIntegerType())
3408 promotion_qual_type = ast_context->IntTy;
3409 else
3410 promotion_qual_type = ast_context->UnsignedIntTy;
3411 }
3412 else
3413 promotion_qual_type = enum_decl->getIntegerType();
3414
3415 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003416 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003417 }
3418 }
3419 }
3420 return false;
3421}
3422
3423
3424#pragma mark Enumeration Types
3425
Greg Clayton462d4142010-09-29 01:12:09 +00003426clang_type_t
3427ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003428{
3429 // TODO: Do something intelligent with the Declaration object passed in
3430 // like maybe filling in the SourceLocation with it...
3431 ASTContext *ast_context = getASTContext();
3432 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003433
3434 // TODO: ask about these...
3435// const bool IsScoped = false;
3436// const bool IsFixed = false;
3437
3438 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3439 ast_context->getTranslationUnitDecl(),
3440 SourceLocation(),
3441 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3442 SourceLocation(),
Sean Callanan8950c9a2010-10-29 18:38:40 +00003443 NULL, false, false); //IsScoped, IsFixed);
Chris Lattner24943d22010-06-08 16:52:24 +00003444 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003445 {
3446 // TODO: check if we should be setting the promotion type too?
3447 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003448 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003449 }
Chris Lattner24943d22010-06-08 16:52:24 +00003450 return NULL;
3451}
3452
Greg Clayton462d4142010-09-29 01:12:09 +00003453clang_type_t
3454ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3455{
3456 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3457
3458 clang::Type *clang_type = enum_qual_type.getTypePtr();
3459 if (clang_type)
3460 {
3461 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3462 if (enum_type)
3463 {
3464 EnumDecl *enum_decl = enum_type->getDecl();
3465 if (enum_decl)
3466 return enum_decl->getIntegerType().getAsOpaquePtr();
3467 }
3468 }
3469 return NULL;
3470}
Chris Lattner24943d22010-06-08 16:52:24 +00003471bool
3472ClangASTContext::AddEnumerationValueToEnumerationType
3473(
Greg Clayton462d4142010-09-29 01:12:09 +00003474 clang_type_t enum_clang_type,
3475 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003476 const Declaration &decl,
3477 const char *name,
3478 int64_t enum_value,
3479 uint32_t enum_value_bit_size
3480)
3481{
3482 if (enum_clang_type && enumerator_clang_type && name)
3483 {
3484 // TODO: Do something intelligent with the Declaration object passed in
3485 // like maybe filling in the SourceLocation with it...
3486 ASTContext *ast_context = getASTContext();
3487 IdentifierTable *identifier_table = getIdentifierTable();
3488
3489 assert (ast_context != NULL);
3490 assert (identifier_table != NULL);
3491 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3492
Greg Clayton1674b122010-07-21 22:12:05 +00003493 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003494 if (clang_type)
3495 {
3496 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3497
3498 if (enum_type)
3499 {
3500 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3501 enum_llvm_apsint = enum_value;
3502 EnumConstantDecl *enumerator_decl =
3503 EnumConstantDecl::Create(*ast_context,
3504 enum_type->getDecl(),
3505 SourceLocation(),
3506 name ? &identifier_table->get(name) : NULL, // Identifier
3507 QualType::getFromOpaquePtr(enumerator_clang_type),
3508 NULL,
3509 enum_llvm_apsint);
3510
3511 if (enumerator_decl)
3512 {
3513 enum_type->getDecl()->addDecl(enumerator_decl);
3514 return true;
3515 }
3516 }
3517 }
3518 }
3519 return false;
3520}
3521
3522#pragma mark Pointers & References
3523
Greg Clayton462d4142010-09-29 01:12:09 +00003524clang_type_t
3525ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003526{
3527 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003528 {
3529 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3530
Greg Clayton03e0f972010-09-13 03:32:57 +00003531 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3532 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003533 {
3534 case clang::Type::ObjCObject:
3535 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003536 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3537
Greg Clayton7b541032010-07-29 20:06:32 +00003538 default:
3539 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3540 }
3541 }
Chris Lattner24943d22010-06-08 16:52:24 +00003542 return NULL;
3543}
3544
Greg Clayton462d4142010-09-29 01:12:09 +00003545clang_type_t
3546ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003547{
3548 if (clang_type)
3549 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3550 return NULL;
3551}
3552
Greg Clayton462d4142010-09-29 01:12:09 +00003553clang_type_t
3554ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003555{
3556 if (clang_type)
3557 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3558 return NULL;
3559}
3560
Greg Clayton462d4142010-09-29 01:12:09 +00003561clang_type_t
3562ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003563{
3564 if (clang_pointee_type && clang_pointee_type)
3565 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3566 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3567 return NULL;
3568}
3569
Chris Lattner24943d22010-06-08 16:52:24 +00003570size_t
3571ClangASTContext::GetPointerBitSize ()
3572{
3573 ASTContext *ast_context = getASTContext();
3574 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3575}
3576
3577bool
Greg Clayton462d4142010-09-29 01:12:09 +00003578ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003579{
3580 if (clang_type == NULL)
3581 return false;
3582
3583 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003584 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3585 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003586 {
Sean Callanan04325062010-10-25 00:29:48 +00003587 case clang::Type::Builtin:
3588 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3589 {
3590 default:
3591 break;
3592 case clang::BuiltinType::ObjCId:
3593 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003594 return true;
3595 }
3596 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003597 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003598 if (target_type)
3599 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3600 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003601 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003602 if (target_type)
3603 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3604 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003605 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003606 if (target_type)
3607 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3608 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003609 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003610 if (target_type)
3611 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3612 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003613 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003614 if (target_type)
3615 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3616 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003617 case clang::Type::RValueReference:
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::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003622 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3623 default:
3624 break;
3625 }
3626 return false;
3627}
3628
Chris Lattner24943d22010-06-08 16:52:24 +00003629bool
Greg Clayton462d4142010-09-29 01:12:09 +00003630ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003631{
3632 if (!clang_type)
3633 return false;
3634
3635 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3636 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3637
3638 if (builtin_type)
3639 {
3640 if (builtin_type->isInteger())
3641 is_signed = builtin_type->isSignedInteger();
3642
3643 return true;
3644 }
3645
3646 return false;
3647}
3648
3649bool
Greg Clayton462d4142010-09-29 01:12:09 +00003650ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003651{
3652 if (clang_type)
3653 {
3654 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003655 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3656 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003657 {
Sean Callanan04325062010-10-25 00:29:48 +00003658 case clang::Type::Builtin:
3659 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3660 {
3661 default:
3662 break;
3663 case clang::BuiltinType::ObjCId:
3664 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003665 return true;
3666 }
3667 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003668 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003669 if (target_type)
3670 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3671 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003672 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003673 if (target_type)
3674 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3675 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003676 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003677 if (target_type)
3678 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3679 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003680 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003681 if (target_type)
3682 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3683 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003684 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003685 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3686 default:
3687 break;
3688 }
3689 }
3690 return false;
3691}
3692
3693bool
Greg Clayton462d4142010-09-29 01:12:09 +00003694ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003695{
3696 if (clang_type)
3697 {
3698 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3699
3700 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3701 {
3702 clang::BuiltinType::Kind kind = BT->getKind();
3703 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3704 {
3705 count = 1;
3706 is_complex = false;
3707 return true;
3708 }
3709 }
3710 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3711 {
3712 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3713 {
3714 count = 2;
3715 is_complex = true;
3716 return true;
3717 }
3718 }
3719 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3720 {
3721 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3722 {
3723 count = VT->getNumElements();
3724 is_complex = false;
3725 return true;
3726 }
3727 }
3728 }
3729 return false;
3730}
3731
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003732
3733bool
3734ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3735{
3736 if (clang_type)
3737 {
3738 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3739
3740 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3741 if (cxx_record_decl)
3742 {
3743 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3744 return true;
3745 }
3746 }
3747 class_name.clear();
3748 return false;
3749}
3750
3751
Greg Clayton1d8173f2010-09-24 05:15:53 +00003752bool
Greg Clayton462d4142010-09-29 01:12:09 +00003753ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003754{
3755 if (clang_type)
3756 {
3757 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3758 if (qual_type->getAsCXXRecordDecl() != NULL)
3759 return true;
3760 }
3761 return false;
3762}
3763
3764bool
Greg Clayton462d4142010-09-29 01:12:09 +00003765ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003766{
3767 if (clang_type)
3768 {
3769 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3770 if (qual_type->isObjCObjectOrInterfaceType())
3771 return true;
3772 }
3773 return false;
3774}
3775
3776
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003777bool
3778ClangASTContext::IsCharType (clang_type_t clang_type)
3779{
3780 if (clang_type)
3781 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3782 return false;
3783}
Chris Lattner24943d22010-06-08 16:52:24 +00003784
3785bool
Greg Clayton462d4142010-09-29 01:12:09 +00003786ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003787{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003788 clang_type_t pointee_or_element_clang_type = NULL;
3789 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3790
3791 if (pointee_or_element_clang_type == NULL)
3792 return false;
3793
3794 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003795 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003796 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3797
3798 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003799 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003800 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3801 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003802 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003803 // We know the size of the array and it could be a C string
3804 // since it is an array of characters
3805 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3806 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003807 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003808 else
Chris Lattner24943d22010-06-08 16:52:24 +00003809 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003810 length = 0;
3811 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003812 }
Chris Lattner24943d22010-06-08 16:52:24 +00003813
Chris Lattner24943d22010-06-08 16:52:24 +00003814 }
3815 }
3816 return false;
3817}
3818
3819bool
Greg Clayton462d4142010-09-29 01:12:09 +00003820ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003821{
3822 if (clang_type)
3823 {
3824 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3825
3826 if (qual_type->isFunctionPointerType())
3827 return true;
3828
3829 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3830 switch (type_class)
3831 {
3832 case clang::Type::Typedef:
3833 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3834
3835 case clang::Type::LValueReference:
3836 case clang::Type::RValueReference:
3837 {
3838 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3839 if (reference_type)
3840 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3841 }
3842 break;
3843 }
3844 }
3845 return false;
3846}
3847
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003848size_t
3849ClangASTContext::GetArraySize (clang_type_t clang_type)
3850{
3851 if (clang_type)
3852 {
3853 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3854 if (array)
3855 return array->getSize().getLimitedValue();
3856 }
3857 return 0;
3858}
Greg Clayton03e0f972010-09-13 03:32:57 +00003859
3860bool
Greg Clayton462d4142010-09-29 01:12:09 +00003861ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003862{
3863 if (!clang_type)
3864 return false;
3865
3866 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3867
Greg Clayton03e0f972010-09-13 03:32:57 +00003868 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3869 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003870 {
Greg Clayton1674b122010-07-21 22:12:05 +00003871 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003872 if (member_type)
3873 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3874 if (size)
3875 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3876 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003877 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003878 if (member_type)
3879 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3880 if (size)
3881 *size = 0;
3882 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003883 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003884 if (member_type)
3885 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3886 if (size)
3887 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003888 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003889 if (member_type)
3890 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3891 if (size)
3892 *size = 0;
3893 return true;
3894 }
3895 return false;
3896}
3897
3898
3899#pragma mark Typedefs
3900
Greg Clayton462d4142010-09-29 01:12:09 +00003901clang_type_t
3902ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003903{
3904 if (clang_type)
3905 {
3906 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3907 ASTContext *ast_context = getASTContext();
3908 IdentifierTable *identifier_table = getIdentifierTable();
3909 assert (ast_context != NULL);
3910 assert (identifier_table != NULL);
3911 if (decl_ctx == NULL)
3912 decl_ctx = ast_context->getTranslationUnitDecl();
3913 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3914 decl_ctx,
3915 SourceLocation(),
3916 name ? &identifier_table->get(name) : NULL, // Identifier
3917 ast_context->CreateTypeSourceInfo(qual_type));
3918
3919 // Get a uniqued QualType for the typedef decl type
3920 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3921 }
3922 return NULL;
3923}
3924
3925
3926std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003927ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003928{
3929 std::string return_name;
3930
Greg Clayton462d4142010-09-29 01:12:09 +00003931 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003932
Greg Clayton462d4142010-09-29 01:12:09 +00003933 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003934 if (typedef_type)
3935 {
Greg Clayton462d4142010-09-29 01:12:09 +00003936 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003937 return_name = typedef_decl->getQualifiedNameAsString();
3938 }
3939 else
3940 {
3941 return_name = qual_type.getAsString();
3942 }
3943
3944 return return_name;
3945}
3946
3947// Disable this for now since I can't seem to get a nicely formatted float
3948// out of the APFloat class without just getting the float, double or quad
3949// and then using a formatted print on it which defeats the purpose. We ideally
3950// would like to get perfect string values for any kind of float semantics
3951// so we can support remote targets. The code below also requires a patch to
3952// llvm::APInt.
3953//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003954//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 +00003955//{
3956// uint32_t count = 0;
3957// bool is_complex = false;
3958// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3959// {
3960// unsigned num_bytes_per_float = byte_size / count;
3961// unsigned num_bits_per_float = num_bytes_per_float * 8;
3962//
3963// float_str.clear();
3964// uint32_t i;
3965// for (i=0; i<count; i++)
3966// {
3967// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3968// bool is_ieee = false;
3969// APFloat ap_float(ap_int, is_ieee);
3970// char s[1024];
3971// unsigned int hex_digits = 0;
3972// bool upper_case = false;
3973//
3974// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3975// {
3976// if (i > 0)
3977// float_str.append(", ");
3978// float_str.append(s);
3979// if (i == 1 && is_complex)
3980// float_str.append(1, 'i');
3981// }
3982// }
3983// return !float_str.empty();
3984// }
3985// return false;
3986//}
3987
3988size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003989ClangASTContext::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 +00003990{
3991 if (clang_type)
3992 {
3993 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3994 uint32_t count = 0;
3995 bool is_complex = false;
3996 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3997 {
3998 // TODO: handle complex and vector types
3999 if (count != 1)
4000 return false;
4001
4002 StringRef s_sref(s);
4003 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
4004
4005 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
4006 const uint64_t byte_size = bit_size / 8;
4007 if (dst_size >= byte_size)
4008 {
4009 if (bit_size == sizeof(float)*8)
4010 {
4011 float float32 = ap_float.convertToFloat();
4012 ::memcpy (dst, &float32, byte_size);
4013 return byte_size;
4014 }
4015 else if (bit_size >= 64)
4016 {
4017 llvm::APInt ap_int(ap_float.bitcastToAPInt());
4018 ::memcpy (dst, ap_int.getRawData(), byte_size);
4019 return byte_size;
4020 }
4021 }
4022 }
4023 }
4024 return 0;
4025}
Sean Callanana751f7b2010-09-17 02:24:29 +00004026
4027unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00004028ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00004029{
4030 assert (clang_type);
4031
4032 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4033
4034 return qual_type.getQualifiers().getCVRQualifiers();
4035}