blob: c2d73d5cfb2f7c832d68f76d3bf154027cc400e3 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedmanf05633b2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Sean Callananbc4f0f52010-07-08 18:16:16 +000017#define NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "clang/AST/ASTContext.h"
19#include "clang/AST/ASTImporter.h"
20#include "clang/AST/CXXInheritance.h"
Greg Clayton84f80752010-07-22 18:30:50 +000021#include "clang/AST/DeclObjC.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "clang/AST/RecordLayout.h"
23#include "clang/AST/Type.h"
24#include "clang/Basic/Builtins.h"
25#include "clang/Basic/FileManager.h"
Sean Callanan8a3b0a82010-11-18 02:56:27 +000026#include "clang/Basic/FileSystemOptions.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "clang/Basic/SourceManager.h"
28#include "clang/Basic/TargetInfo.h"
29#include "clang/Basic/TargetOptions.h"
30#include "clang/Frontend/FrontendOptions.h"
31#include "clang/Frontend/LangStandard.h"
Sean Callananbc4f0f52010-07-08 18:16:16 +000032#undef NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000033
Chris Lattner24943d22010-06-08 16:52:24 +000034#include "lldb/Core/dwarf.h"
Greg Claytonf3d0b0c2010-10-27 03:32:59 +000035#include "lldb/Core/Flags.h"
Sean Callanan839fde42010-10-28 18:19:36 +000036#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037
Eli Friedmanf05633b2010-06-13 19:06:42 +000038#include <stdio.h>
39
Greg Clayton585660c2010-08-05 01:57:25 +000040using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000041using namespace lldb_private;
42using namespace llvm;
43using namespace clang;
44
Greg Clayton84f80752010-07-22 18:30:50 +000045static AccessSpecifier
Greg Clayton585660c2010-08-05 01:57:25 +000046ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000047{
48 switch (access)
49 {
Greg Clayton585660c2010-08-05 01:57:25 +000050 default: break;
51 case eAccessNone: return AS_none;
52 case eAccessPublic: return AS_public;
53 case eAccessPrivate: return AS_private;
54 case eAccessProtected: return AS_protected;
Greg Clayton84f80752010-07-22 18:30:50 +000055 }
56 return AS_none;
57}
58
59static ObjCIvarDecl::AccessControl
Greg Clayton585660c2010-08-05 01:57:25 +000060ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000061{
62 switch (access)
63 {
Greg Clayton585660c2010-08-05 01:57:25 +000064 default: break;
65 case eAccessNone: return ObjCIvarDecl::None;
66 case eAccessPublic: return ObjCIvarDecl::Public;
67 case eAccessPrivate: return ObjCIvarDecl::Private;
68 case eAccessProtected: return ObjCIvarDecl::Protected;
69 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton84f80752010-07-22 18:30:50 +000070 }
71 return ObjCIvarDecl::None;
72}
73
74
Chris Lattner24943d22010-06-08 16:52:24 +000075static void
76ParseLangArgs
77(
78 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000079 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000080)
81{
82 // FIXME: Cleanup per-file based stuff.
83
84 // Set some properties which depend soley on the input kind; it would be nice
85 // to move these to the language standard, and have the driver resolve the
86 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000087 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000088 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000089 } else if (IK == IK_ObjC ||
90 IK == IK_ObjCXX ||
91 IK == IK_PreprocessedObjC ||
92 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000093 Opts.ObjC1 = Opts.ObjC2 = 1;
94 }
95
96 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
97
98 if (LangStd == LangStandard::lang_unspecified) {
99 // Based on the base language, pick one.
100 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +0000101 case IK_None:
102 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +0000103 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +0000104 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +0000105 LangStd = LangStandard::lang_opencl;
106 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000107 case IK_Asm:
108 case IK_C:
109 case IK_PreprocessedC:
110 case IK_ObjC:
111 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +0000112 LangStd = LangStandard::lang_gnu99;
113 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000114 case IK_CXX:
115 case IK_PreprocessedCXX:
116 case IK_ObjCXX:
117 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +0000118 LangStd = LangStandard::lang_gnucxx98;
119 break;
120 }
121 }
122
123 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
124 Opts.BCPLComment = Std.hasBCPLComments();
125 Opts.C99 = Std.isC99();
126 Opts.CPlusPlus = Std.isCPlusPlus();
127 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
128 Opts.Digraphs = Std.hasDigraphs();
129 Opts.GNUMode = Std.isGNUMode();
130 Opts.GNUInline = !Std.isC99();
131 Opts.HexFloats = Std.hasHexFloats();
132 Opts.ImplicitInt = Std.hasImplicitInt();
133
134 // OpenCL has some additional defaults.
135 if (LangStd == LangStandard::lang_opencl) {
136 Opts.OpenCL = 1;
137 Opts.AltiVec = 1;
138 Opts.CXXOperatorNames = 1;
139 Opts.LaxVectorConversions = 1;
140 }
141
142 // OpenCL and C++ both have bool, true, false keywords.
143 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
144
145// if (Opts.CPlusPlus)
146// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
147//
148// if (Args.hasArg(OPT_fobjc_gc_only))
149// Opts.setGCMode(LangOptions::GCOnly);
150// else if (Args.hasArg(OPT_fobjc_gc))
151// Opts.setGCMode(LangOptions::HybridGC);
152//
153// if (Args.hasArg(OPT_print_ivar_layout))
154// Opts.ObjCGCBitmapPrint = 1;
155//
156// if (Args.hasArg(OPT_faltivec))
157// Opts.AltiVec = 1;
158//
159// if (Args.hasArg(OPT_pthread))
160// Opts.POSIXThreads = 1;
161//
162// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
163// "default");
164// if (Vis == "default")
Sean Callanan8950c9a2010-10-29 18:38:40 +0000165 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner24943d22010-06-08 16:52:24 +0000166// else if (Vis == "hidden")
167// Opts.setVisibilityMode(LangOptions::Hidden);
168// else if (Vis == "protected")
169// Opts.setVisibilityMode(LangOptions::Protected);
170// else
171// Diags.Report(diag::err_drv_invalid_value)
172// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
173
174// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
175
176 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
177 // is specified, or -std is set to a conforming mode.
178 Opts.Trigraphs = !Opts.GNUMode;
179// if (Args.hasArg(OPT_trigraphs))
180// Opts.Trigraphs = 1;
181//
182// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
183// OPT_fno_dollars_in_identifiers,
184// !Opts.AsmPreprocessor);
185// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
186// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
187// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
188// if (Args.hasArg(OPT_fno_lax_vector_conversions))
189// Opts.LaxVectorConversions = 0;
190// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
191// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
192// Opts.Blocks = Args.hasArg(OPT_fblocks);
193// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
194// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
195// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
196// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
197// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
198// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
199// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
200// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
201// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
202// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
203// Diags);
204// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
205// Opts.ObjCConstantStringClass = getLastArgValue(Args,
206// OPT_fconstant_string_class);
207// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
208// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
209// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
210// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
211// Opts.Static = Args.hasArg(OPT_static_define);
212 Opts.OptimizeSize = 0;
213
214 // FIXME: Eliminate this dependency.
215// unsigned Opt =
216// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
217// Opts.Optimize = Opt != 0;
218 unsigned Opt = 0;
219
220 // This is the __NO_INLINE__ define, which just depends on things like the
221 // optimization level and -fno-inline, not actually whether the backend has
222 // inlining enabled.
223 //
224 // FIXME: This is affected by other options (-fno-inline).
225 Opts.NoInline = !Opt;
226
227// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
228// switch (SSP) {
229// default:
230// Diags.Report(diag::err_drv_invalid_value)
231// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
232// break;
233// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
234// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
235// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
236// }
237}
238
Chris Lattner24943d22010-06-08 16:52:24 +0000239
Chris Lattner24943d22010-06-08 16:52:24 +0000240ClangASTContext::ClangASTContext(const char *target_triple) :
241 m_target_triple(),
242 m_ast_context_ap(),
243 m_language_options_ap(),
244 m_source_manager_ap(),
245 m_diagnostic_ap(),
246 m_target_options_ap(),
247 m_target_info_ap(),
248 m_identifier_table_ap(),
249 m_selector_table_ap(),
250 m_builtins_ap()
251{
252 if (target_triple && target_triple[0])
253 m_target_triple.assign (target_triple);
254}
255
256//----------------------------------------------------------------------
257// Destructor
258//----------------------------------------------------------------------
259ClangASTContext::~ClangASTContext()
260{
261 m_builtins_ap.reset();
262 m_selector_table_ap.reset();
263 m_identifier_table_ap.reset();
264 m_target_info_ap.reset();
265 m_target_options_ap.reset();
266 m_diagnostic_ap.reset();
267 m_source_manager_ap.reset();
268 m_language_options_ap.reset();
269 m_ast_context_ap.reset();
270}
271
272
273void
274ClangASTContext::Clear()
275{
276 m_ast_context_ap.reset();
277 m_language_options_ap.reset();
278 m_source_manager_ap.reset();
279 m_diagnostic_ap.reset();
280 m_target_options_ap.reset();
281 m_target_info_ap.reset();
282 m_identifier_table_ap.reset();
283 m_selector_table_ap.reset();
284 m_builtins_ap.reset();
285}
286
287const char *
288ClangASTContext::GetTargetTriple ()
289{
290 return m_target_triple.c_str();
291}
292
293void
294ClangASTContext::SetTargetTriple (const char *target_triple)
295{
296 Clear();
297 m_target_triple.assign(target_triple);
298}
299
300
301ASTContext *
302ClangASTContext::getASTContext()
303{
304 if (m_ast_context_ap.get() == NULL)
305 {
306 m_ast_context_ap.reset(
307 new ASTContext(
308 *getLanguageOptions(),
309 *getSourceManager(),
310 *getTargetInfo(),
311 *getIdentifierTable(),
312 *getSelectorTable(),
Greg Clayton6e713402010-07-30 20:30:44 +0000313 *getBuiltinContext(),
314 0));
Chris Lattner24943d22010-06-08 16:52:24 +0000315 }
316 return m_ast_context_ap.get();
317}
318
319Builtin::Context *
320ClangASTContext::getBuiltinContext()
321{
322 if (m_builtins_ap.get() == NULL)
323 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
324 return m_builtins_ap.get();
325}
326
327IdentifierTable *
328ClangASTContext::getIdentifierTable()
329{
330 if (m_identifier_table_ap.get() == NULL)
331 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
332 return m_identifier_table_ap.get();
333}
334
335LangOptions *
336ClangASTContext::getLanguageOptions()
337{
338 if (m_language_options_ap.get() == NULL)
339 {
340 m_language_options_ap.reset(new LangOptions());
Greg Claytone41c4b22010-06-13 17:34:29 +0000341 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
342// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner24943d22010-06-08 16:52:24 +0000343 }
344 return m_language_options_ap.get();
345}
346
347SelectorTable *
348ClangASTContext::getSelectorTable()
349{
350 if (m_selector_table_ap.get() == NULL)
351 m_selector_table_ap.reset (new SelectorTable());
352 return m_selector_table_ap.get();
353}
354
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000355clang::FileManager *
356ClangASTContext::getFileManager()
357{
358 if (m_file_manager_ap.get() == NULL)
359 m_file_manager_ap.reset(new clang::FileManager());
360 return m_file_manager_ap.get();
361}
362
363clang::FileSystemOptions *
364ClangASTContext::getFileSystemOptions()
365{
366 if (m_file_system_options_ap.get() == NULL)
367 m_file_system_options_ap.reset(new clang::FileSystemOptions());
368 return m_file_system_options_ap.get();
369}
370
Greg Clayton1674b122010-07-21 22:12:05 +0000371clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000372ClangASTContext::getSourceManager()
373{
374 if (m_source_manager_ap.get() == NULL)
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000375 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager(), *getFileSystemOptions()));
Chris Lattner24943d22010-06-08 16:52:24 +0000376 return m_source_manager_ap.get();
377}
378
379Diagnostic *
380ClangASTContext::getDiagnostic()
381{
382 if (m_diagnostic_ap.get() == NULL)
Greg Claytoneae91242010-11-19 21:46:54 +0000383 {
384 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
385 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
386 }
Chris Lattner24943d22010-06-08 16:52:24 +0000387 return m_diagnostic_ap.get();
388}
389
390TargetOptions *
391ClangASTContext::getTargetOptions()
392{
393 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
394 {
395 m_target_options_ap.reset (new TargetOptions());
396 if (m_target_options_ap.get())
397 m_target_options_ap->Triple = m_target_triple;
398 }
399 return m_target_options_ap.get();
400}
401
402
403TargetInfo *
404ClangASTContext::getTargetInfo()
405{
406 // target_triple should be something like "x86_64-apple-darwin10"
407 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
408 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
409 return m_target_info_ap.get();
410}
411
412#pragma mark Basic Types
413
414static inline bool
415QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
416{
417 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
418 if (qual_type_bit_size == bit_size)
419 return true;
420 return false;
421}
422
Greg Clayton462d4142010-09-29 01:12:09 +0000423clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000424ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000425{
426 ASTContext *ast_context = getASTContext();
427
428 assert (ast_context != NULL);
429
430 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
431}
432
Greg Clayton462d4142010-09-29 01:12:09 +0000433clang_type_t
434ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000435{
436 if (!ast_context)
437 return NULL;
438
439 switch (encoding)
440 {
Greg Clayton585660c2010-08-05 01:57:25 +0000441 case eEncodingInvalid:
Chris Lattner24943d22010-06-08 16:52:24 +0000442 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
443 return ast_context->VoidPtrTy.getAsOpaquePtr();
444 break;
445
Greg Clayton585660c2010-08-05 01:57:25 +0000446 case eEncodingUint:
Chris Lattner24943d22010-06-08 16:52:24 +0000447 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
448 return ast_context->UnsignedCharTy.getAsOpaquePtr();
449 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
450 return ast_context->UnsignedShortTy.getAsOpaquePtr();
451 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
452 return ast_context->UnsignedIntTy.getAsOpaquePtr();
453 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
454 return ast_context->UnsignedLongTy.getAsOpaquePtr();
455 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
456 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
457 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
458 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
459 break;
460
Greg Clayton585660c2010-08-05 01:57:25 +0000461 case eEncodingSint:
Chris Lattner24943d22010-06-08 16:52:24 +0000462 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
463 return ast_context->CharTy.getAsOpaquePtr();
464 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
465 return ast_context->ShortTy.getAsOpaquePtr();
466 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
467 return ast_context->IntTy.getAsOpaquePtr();
468 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
469 return ast_context->LongTy.getAsOpaquePtr();
470 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
471 return ast_context->LongLongTy.getAsOpaquePtr();
472 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
473 return ast_context->Int128Ty.getAsOpaquePtr();
474 break;
475
Greg Clayton585660c2010-08-05 01:57:25 +0000476 case eEncodingIEEE754:
Chris Lattner24943d22010-06-08 16:52:24 +0000477 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
478 return ast_context->FloatTy.getAsOpaquePtr();
479 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
480 return ast_context->DoubleTy.getAsOpaquePtr();
481 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
482 return ast_context->LongDoubleTy.getAsOpaquePtr();
483 break;
484
Greg Clayton585660c2010-08-05 01:57:25 +0000485 case eEncodingVector:
Chris Lattner24943d22010-06-08 16:52:24 +0000486 default:
487 break;
488 }
489
490 return NULL;
491}
492
Greg Clayton462d4142010-09-29 01:12:09 +0000493clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000494ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
495{
496 ASTContext *ast_context = getASTContext();
497
498 #define streq(a,b) strcmp(a,b) == 0
499 assert (ast_context != NULL);
500 if (ast_context)
501 {
502 switch (dw_ate)
503 {
504 default:
505 break;
506
507 case DW_ATE_address:
508 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
509 return ast_context->VoidPtrTy.getAsOpaquePtr();
510 break;
511
512 case DW_ATE_boolean:
513 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
514 return ast_context->BoolTy.getAsOpaquePtr();
515 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
516 return ast_context->UnsignedCharTy.getAsOpaquePtr();
517 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
518 return ast_context->UnsignedShortTy.getAsOpaquePtr();
519 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
520 return ast_context->UnsignedIntTy.getAsOpaquePtr();
521 break;
522
523 case DW_ATE_complex_float:
524 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
525 return ast_context->FloatComplexTy.getAsOpaquePtr();
526 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
527 return ast_context->DoubleComplexTy.getAsOpaquePtr();
528 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
529 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
530 break;
531
532 case DW_ATE_float:
533 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
534 return ast_context->FloatTy.getAsOpaquePtr();
535 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
536 return ast_context->DoubleTy.getAsOpaquePtr();
537 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
538 return ast_context->LongDoubleTy.getAsOpaquePtr();
539 break;
540
541 case DW_ATE_signed:
542 if (type_name)
543 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000544 if (strstr(type_name, "long long"))
Chris Lattner24943d22010-06-08 16:52:24 +0000545 {
Chris Lattner24943d22010-06-08 16:52:24 +0000546 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
547 return ast_context->LongLongTy.getAsOpaquePtr();
548 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000549 else if (strstr(type_name, "long"))
550 {
551 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
552 return ast_context->LongTy.getAsOpaquePtr();
553 }
554 else if (strstr(type_name, "short"))
Chris Lattner24943d22010-06-08 16:52:24 +0000555 {
556 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
557 return ast_context->ShortTy.getAsOpaquePtr();
558 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000559 else if (strstr(type_name, "char"))
Chris Lattner24943d22010-06-08 16:52:24 +0000560 {
561 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
562 return ast_context->CharTy.getAsOpaquePtr();
563 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
564 return ast_context->SignedCharTy.getAsOpaquePtr();
565 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000566 else if (strstr(type_name, "int"))
567 {
568 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
569 return ast_context->IntTy.getAsOpaquePtr();
570 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
571 return ast_context->Int128Ty.getAsOpaquePtr();
572 }
573 else if (streq(type_name, "wchar_t"))
Chris Lattner24943d22010-06-08 16:52:24 +0000574 {
575 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
576 return ast_context->WCharTy.getAsOpaquePtr();
577 }
Chris Lattner24943d22010-06-08 16:52:24 +0000578 }
579 // We weren't able to match up a type name, just search by size
580 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
581 return ast_context->CharTy.getAsOpaquePtr();
582 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
583 return ast_context->ShortTy.getAsOpaquePtr();
584 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
585 return ast_context->IntTy.getAsOpaquePtr();
586 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
587 return ast_context->LongTy.getAsOpaquePtr();
588 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
589 return ast_context->LongLongTy.getAsOpaquePtr();
590 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
591 return ast_context->Int128Ty.getAsOpaquePtr();
592 break;
593
594 case DW_ATE_signed_char:
595 if (type_name)
596 {
597 if (streq(type_name, "signed char"))
598 {
599 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
600 return ast_context->SignedCharTy.getAsOpaquePtr();
601 }
602 }
603 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
604 return ast_context->CharTy.getAsOpaquePtr();
605 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
606 return ast_context->SignedCharTy.getAsOpaquePtr();
607 break;
608
609 case DW_ATE_unsigned:
610 if (type_name)
611 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000612 if (strstr(type_name, "long long"))
613 {
614 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
615 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
616 }
617 else if (strstr(type_name, "long"))
618 {
619 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
620 return ast_context->UnsignedLongTy.getAsOpaquePtr();
621 }
622 else if (strstr(type_name, "short"))
623 {
624 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
625 return ast_context->UnsignedShortTy.getAsOpaquePtr();
626 }
627 else if (strstr(type_name, "char"))
628 {
629 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
630 return ast_context->UnsignedCharTy.getAsOpaquePtr();
631 }
632 else if (strstr(type_name, "int"))
Chris Lattner24943d22010-06-08 16:52:24 +0000633 {
634 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
635 return ast_context->UnsignedIntTy.getAsOpaquePtr();
636 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
637 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
638 }
Chris Lattner24943d22010-06-08 16:52:24 +0000639 }
640 // We weren't able to match up a type name, just search by size
641 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
642 return ast_context->UnsignedCharTy.getAsOpaquePtr();
643 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
644 return ast_context->UnsignedShortTy.getAsOpaquePtr();
645 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
646 return ast_context->UnsignedIntTy.getAsOpaquePtr();
647 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
648 return ast_context->UnsignedLongTy.getAsOpaquePtr();
649 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
650 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
651 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
652 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
653 break;
654
655 case DW_ATE_unsigned_char:
656 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
657 return ast_context->UnsignedCharTy.getAsOpaquePtr();
658 break;
659
660 case DW_ATE_imaginary_float:
661 break;
662 }
663 }
664 // This assert should fire for anything that we don't catch above so we know
665 // to fix any issues we run into.
666 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
667 return NULL;
668}
669
Greg Clayton462d4142010-09-29 01:12:09 +0000670clang_type_t
671ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
Chris Lattner24943d22010-06-08 16:52:24 +0000672{
Sean Callanana751f7b2010-09-17 02:24:29 +0000673 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000674}
675
Greg Clayton462d4142010-09-29 01:12:09 +0000676clang_type_t
Sean Callanana91dd992010-11-19 02:52:21 +0000677ClangASTContext::GetBuiltInType_bool()
678{
679 return getASTContext()->BoolTy.getAsOpaquePtr();
680}
681
682clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000683ClangASTContext::GetBuiltInType_objc_id()
684{
Sean Callanan04325062010-10-25 00:29:48 +0000685 return getASTContext()->ObjCBuiltinIdTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000686}
687
Greg Clayton462d4142010-09-29 01:12:09 +0000688clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000689ClangASTContext::GetBuiltInType_objc_Class()
690{
Sean Callanan04325062010-10-25 00:29:48 +0000691 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000692}
693
Greg Clayton462d4142010-09-29 01:12:09 +0000694clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000695ClangASTContext::GetBuiltInType_objc_selector()
696{
Sean Callanan04325062010-10-25 00:29:48 +0000697 return getASTContext()->ObjCBuiltinSelTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000698}
699
Greg Clayton462d4142010-09-29 01:12:09 +0000700clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000701ClangASTContext::GetCStringType (bool is_const)
702{
703 QualType char_type(getASTContext()->CharTy);
704
705 if (is_const)
706 char_type.addConst();
707
708 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
709}
710
Greg Clayton462d4142010-09-29 01:12:09 +0000711clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000712ClangASTContext::GetVoidPtrType (bool is_const)
713{
714 return GetVoidPtrType(getASTContext(), is_const);
715}
716
Greg Clayton462d4142010-09-29 01:12:09 +0000717clang_type_t
718ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
Chris Lattner24943d22010-06-08 16:52:24 +0000719{
720 QualType void_ptr_type(ast_context->VoidPtrTy);
721
722 if (is_const)
723 void_ptr_type.addConst();
724
725 return void_ptr_type.getAsOpaquePtr();
726}
727
Sean Callanan839fde42010-10-28 18:19:36 +0000728class NullDiagnosticClient : public DiagnosticClient
729{
730public:
731 NullDiagnosticClient ()
732 {
733 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
734 }
735
736 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
737 {
738 if (m_log)
739 {
740 llvm::SmallVectorImpl<char> diag_str(10);
741 info.FormatDiagnostic(diag_str);
742 diag_str.push_back('\0');
743 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
744 }
745 }
746private:
Greg Claytone005f2c2010-11-06 01:53:30 +0000747 LogSP m_log;
Sean Callanan839fde42010-10-28 18:19:36 +0000748};
749
Greg Clayton462d4142010-09-29 01:12:09 +0000750clang_type_t
751ClangASTContext::CopyType (ASTContext *dest_context,
752 ASTContext *source_context,
753 clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000754{
Sean Callananad5b61b2010-10-28 18:43:33 +0000755 // null_client's ownership is transferred to diagnostics
Chris Lattner24943d22010-06-08 16:52:24 +0000756 FileManager file_manager;
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000757 FileSystemOptions file_system_options;
Greg Claytoneae91242010-11-19 21:46:54 +0000758 ASTImporter importer(*dest_context, file_manager, file_system_options,
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000759 *source_context, file_manager, file_system_options);
Sean Callanancf18faa2010-11-09 22:37:10 +0000760
761 QualType src = QualType::getFromOpaquePtr(clang_type);
762 QualType dst = importer.Import(src);
763
764 return dst.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000765}
766
Greg Clayton6916e352010-11-13 03:52:47 +0000767
768clang::Decl *
769ClangASTContext::CopyDecl (ASTContext *dest_context,
770 ASTContext *source_context,
771 clang::Decl *source_decl)
772{
773 // null_client's ownership is transferred to diagnostics
Greg Clayton6916e352010-11-13 03:52:47 +0000774 FileManager file_manager;
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000775 FileSystemOptions file_system_options;
Greg Claytoneae91242010-11-19 21:46:54 +0000776 ASTImporter importer(*dest_context, file_manager, file_system_options,
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000777 *source_context, file_manager, file_system_options);
Greg Clayton6916e352010-11-13 03:52:47 +0000778
779 return importer.Import(source_decl);
780}
781
Sean Callanan8d825062010-07-16 00:00:27 +0000782bool
Greg Clayton462d4142010-09-29 01:12:09 +0000783ClangASTContext::AreTypesSame(ASTContext *ast_context,
784 clang_type_t type1,
785 clang_type_t type2)
Sean Callanan5510ddd2010-07-15 22:30:52 +0000786{
787 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
788 QualType::getFromOpaquePtr(type2));
789}
790
Chris Lattner24943d22010-06-08 16:52:24 +0000791#pragma mark CVR modifiers
792
Greg Clayton462d4142010-09-29 01:12:09 +0000793clang_type_t
794ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000795{
796 if (clang_type)
797 {
798 QualType result(QualType::getFromOpaquePtr(clang_type));
799 result.addConst();
800 return result.getAsOpaquePtr();
801 }
802 return NULL;
803}
804
Greg Clayton462d4142010-09-29 01:12:09 +0000805clang_type_t
806ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000807{
808 if (clang_type)
809 {
810 QualType result(QualType::getFromOpaquePtr(clang_type));
811 result.getQualifiers().setRestrict (true);
812 return result.getAsOpaquePtr();
813 }
814 return NULL;
815}
816
Greg Clayton462d4142010-09-29 01:12:09 +0000817clang_type_t
818ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000819{
820 if (clang_type)
821 {
822 QualType result(QualType::getFromOpaquePtr(clang_type));
823 result.getQualifiers().setVolatile (true);
824 return result.getAsOpaquePtr();
825 }
826 return NULL;
827}
828
829#pragma mark Structure, Unions, Classes
830
Greg Clayton462d4142010-09-29 01:12:09 +0000831clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000832ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000833{
834 ASTContext *ast_context = getASTContext();
835 assert (ast_context != NULL);
Sean Callanan04325062010-10-25 00:29:48 +0000836
Chris Lattner24943d22010-06-08 16:52:24 +0000837 if (decl_ctx == NULL)
838 decl_ctx = ast_context->getTranslationUnitDecl();
839
Greg Clayton9488b742010-07-28 02:04:09 +0000840
Greg Clayton585660c2010-08-05 01:57:25 +0000841 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000842 {
Greg Clayton306edca2010-10-11 02:25:34 +0000843 bool isForwardDecl = true;
Greg Clayton9488b742010-07-28 02:04:09 +0000844 bool isInternal = false;
845 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
846 }
847
Chris Lattner24943d22010-06-08 16:52:24 +0000848 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
849 // we will need to update this code. I was told to currently always use
850 // the CXXRecordDecl class since we often don't know from debug information
851 // if something is struct or a class, so we default to always use the more
852 // complete definition just in case.
853 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
854 (TagDecl::TagKind)kind,
855 decl_ctx,
856 SourceLocation(),
857 name && name[0] ? &ast_context->Idents.get(name) : NULL);
858
859 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
860}
861
Greg Claytondbf26152010-10-01 23:13:49 +0000862static bool
863IsOperator (const char *name, OverloadedOperatorKind &op_kind)
864{
865 if (name == NULL || name[0] == '\0')
866 return false;
867
868 if (::strstr(name, "operator ") != name)
869 return false;
870
871 const char *post_op_name = name + 9;
872
873 // This is an operator, set the overloaded operator kind to invalid
874 // in case this is a conversion operator...
875 op_kind = NUM_OVERLOADED_OPERATORS;
876
877 switch (post_op_name[0])
878 {
879 case 'n':
880 if (strcmp (post_op_name, "new") == 0)
881 op_kind = OO_New;
882 else if (strcmp (post_op_name, "new[]") == 0)
883 op_kind = OO_Array_New;
884 break;
885
886 case 'd':
887 if (strcmp (post_op_name, "delete") == 0)
888 op_kind = OO_Delete;
889 else if (strcmp (post_op_name, "delete[]") == 0)
890 op_kind = OO_Array_Delete;
891 break;
892
893 case '+':
894 if (post_op_name[1] == '\0')
895 op_kind = OO_Plus;
896 else if (post_op_name[2] == '\0')
897 {
898 if (post_op_name[1] == '=')
899 op_kind = OO_PlusEqual;
900 else if (post_op_name[1] == '+')
901 op_kind = OO_PlusPlus;
902 }
903 break;
904
905 case '-':
906 if (post_op_name[1] == '\0')
907 op_kind = OO_Minus;
908 else if (post_op_name[2] == '\0')
909 {
910 switch (post_op_name[1])
911 {
912 case '=': op_kind = OO_MinusEqual; break;
913 case '-': op_kind = OO_MinusMinus; break;
914 case '>': op_kind = OO_Arrow; break;
915 }
916 }
917 else if (post_op_name[3] == '\0')
918 {
919 if (post_op_name[2] == '*')
920 op_kind = OO_ArrowStar; break;
921 }
922 break;
923
924 case '*':
925 if (post_op_name[1] == '\0')
926 op_kind = OO_Star;
927 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
928 op_kind = OO_StarEqual;
929 break;
930
931 case '/':
932 if (post_op_name[1] == '\0')
933 op_kind = OO_Slash;
934 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
935 op_kind = OO_SlashEqual;
936 break;
937
938 case '%':
939 if (post_op_name[1] == '\0')
940 op_kind = OO_Percent;
941 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
942 op_kind = OO_PercentEqual;
943 break;
944
945
946 case '^':
947 if (post_op_name[1] == '\0')
948 op_kind = OO_Caret;
949 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
950 op_kind = OO_CaretEqual;
951 break;
952
953 case '&':
954 if (post_op_name[1] == '\0')
955 op_kind = OO_Amp;
956 else if (post_op_name[2] == '\0')
957 {
958 switch (post_op_name[1])
959 {
960 case '=': op_kind = OO_AmpEqual; break;
961 case '&': op_kind = OO_AmpAmp; break;
962 }
963 }
964 break;
965
966 case '|':
967 if (post_op_name[1] == '\0')
968 op_kind = OO_Pipe;
969 else if (post_op_name[2] == '\0')
970 {
971 switch (post_op_name[1])
972 {
973 case '=': op_kind = OO_PipeEqual; break;
974 case '|': op_kind = OO_PipePipe; break;
975 }
976 }
977 break;
978
979 case '~':
980 if (post_op_name[1] == '\0')
981 op_kind = OO_Tilde;
982 break;
983
984 case '!':
985 if (post_op_name[1] == '\0')
986 op_kind = OO_Exclaim;
987 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
988 op_kind = OO_ExclaimEqual;
989 break;
990
991 case '=':
992 if (post_op_name[1] == '\0')
993 op_kind = OO_Equal;
994 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
995 op_kind = OO_EqualEqual;
996 break;
997
998 case '<':
999 if (post_op_name[1] == '\0')
1000 op_kind = OO_Less;
1001 else if (post_op_name[2] == '\0')
1002 {
1003 switch (post_op_name[1])
1004 {
1005 case '<': op_kind = OO_LessLess; break;
1006 case '=': op_kind = OO_LessEqual; break;
1007 }
1008 }
1009 else if (post_op_name[3] == '\0')
1010 {
1011 if (post_op_name[2] == '=')
1012 op_kind = OO_LessLessEqual;
1013 }
1014 break;
1015
1016 case '>':
1017 if (post_op_name[1] == '\0')
1018 op_kind = OO_Greater;
1019 else if (post_op_name[2] == '\0')
1020 {
1021 switch (post_op_name[1])
1022 {
1023 case '>': op_kind = OO_GreaterGreater; break;
1024 case '=': op_kind = OO_GreaterEqual; break;
1025 }
1026 }
1027 else if (post_op_name[1] == '>' &&
1028 post_op_name[2] == '=' &&
1029 post_op_name[3] == '\0')
1030 {
1031 op_kind = OO_GreaterGreaterEqual;
1032 }
1033 break;
1034
1035 case ',':
1036 if (post_op_name[1] == '\0')
1037 op_kind = OO_Comma;
1038 break;
1039
1040 case '(':
1041 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1042 op_kind = OO_Call;
1043 break;
1044
1045 case '[':
1046 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1047 op_kind = OO_Subscript;
1048 break;
1049 }
1050
1051 return true;
1052}
Greg Clayton412440a2010-09-23 01:09:21 +00001053CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +00001054ClangASTContext::AddMethodToCXXRecordType
1055(
Greg Clayton462d4142010-09-29 01:12:09 +00001056 ASTContext *ast_context,
1057 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001058 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001059 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001060 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001061 bool is_virtual,
1062 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001063 bool is_inline,
1064 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +00001065)
Sean Callanan79523002010-09-17 02:58:26 +00001066{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001067 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +00001068 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001069
1070 assert(ast_context);
1071
1072 IdentifierTable *identifier_table = &ast_context->Idents;
1073
1074 assert(identifier_table);
1075
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001076 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +00001077
1078 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +00001079
Greg Clayton1d8173f2010-09-24 05:15:53 +00001080 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001081 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001082
Greg Clayton1d8173f2010-09-24 05:15:53 +00001083 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +00001084
Greg Clayton1d8173f2010-09-24 05:15:53 +00001085 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001086 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001087
Greg Clayton1d8173f2010-09-24 05:15:53 +00001088 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +00001089
Greg Clayton1d8173f2010-09-24 05:15:53 +00001090 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001091 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001092
1093 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1094
Greg Clayton1d8173f2010-09-24 05:15:53 +00001095 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001096 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001097
Greg Clayton1d8173f2010-09-24 05:15:53 +00001098 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001099
Greg Claytoneae91242010-11-19 21:46:54 +00001100 method_qual_type.dump();
1101
Greg Clayton30449d52010-10-01 02:31:07 +00001102 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001103
Greg Clayton30449d52010-10-01 02:31:07 +00001104 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001105
Greg Clayton90e325d2010-10-01 03:45:20 +00001106 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001107
Greg Clayton5325a362010-10-02 01:40:05 +00001108 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001109
Greg Clayton5325a362010-10-02 01:40:05 +00001110 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001111 return NULL;
1112
Greg Clayton5325a362010-10-02 01:40:05 +00001113 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001114
1115 if (!method_function_prototype)
1116 return NULL;
1117
1118 unsigned int num_params = method_function_prototype->getNumArgs();
1119
1120 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001121 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001122 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1123 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001124 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001125 method_qual_type,
Sean Callanan8950c9a2010-10-29 18:38:40 +00001126 NULL,
Greg Clayton90e325d2010-10-01 03:45:20 +00001127 is_inline,
1128 is_implicitly_declared);
1129 }
1130 else if (decl_name == record_decl->getDeclName())
1131 {
Greg Clayton30449d52010-10-01 02:31:07 +00001132 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1133 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001134 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001135 method_qual_type,
1136 NULL, // TypeSourceInfo *
1137 is_explicit,
1138 is_inline,
1139 is_implicitly_declared);
1140 }
1141 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001142 {
Greg Claytondbf26152010-10-01 23:13:49 +00001143
1144 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1145 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001146 {
Greg Claytondbf26152010-10-01 23:13:49 +00001147 if (op_kind != NUM_OVERLOADED_OPERATORS)
1148 {
1149 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001150 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001151 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001152 method_qual_type,
1153 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001154 is_static,
1155 SC_None,
1156 is_inline);
1157 }
1158 else if (num_params == 0)
1159 {
1160 // Conversion operators don't take params...
1161 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1162 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001163 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001164 method_qual_type,
1165 NULL, // TypeSourceInfo *
1166 is_inline,
1167 is_explicit);
1168 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001169 }
Greg Claytondbf26152010-10-01 23:13:49 +00001170
1171 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001172 {
1173 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1174 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001175 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001176 method_qual_type,
1177 NULL, // TypeSourceInfo *
1178 is_static,
1179 SC_None,
1180 is_inline);
1181 }
Greg Clayton30449d52010-10-01 02:31:07 +00001182 }
Greg Claytondbf26152010-10-01 23:13:49 +00001183
Greg Clayton462d4142010-09-29 01:12:09 +00001184 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001185
1186 cxx_method_decl->setAccess (access_specifier);
1187 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001188
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001189 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001190
1191 ParmVarDecl *params[num_params];
1192
1193 for (int param_index = 0;
1194 param_index < num_params;
1195 ++param_index)
1196 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001197 params[param_index] = ParmVarDecl::Create (*ast_context,
1198 cxx_method_decl,
1199 SourceLocation(),
1200 NULL, // anonymous
1201 method_function_prototype->getArgType(param_index),
1202 NULL,
1203 SC_None,
1204 SC_None,
1205 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001206 }
1207
Greg Clayton1d8173f2010-09-24 05:15:53 +00001208 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001209
Greg Clayton1d8173f2010-09-24 05:15:53 +00001210 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001211
Greg Clayton412440a2010-09-23 01:09:21 +00001212 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001213}
1214
1215bool
Greg Clayton84f80752010-07-22 18:30:50 +00001216ClangASTContext::AddFieldToRecordType
1217(
Greg Clayton462d4142010-09-29 01:12:09 +00001218 ASTContext *ast_context,
1219 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001220 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001221 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001222 AccessType access,
1223 uint32_t bitfield_bit_size
1224)
Chris Lattner24943d22010-06-08 16:52:24 +00001225{
1226 if (record_clang_type == NULL || field_type == NULL)
1227 return false;
1228
Sean Callanan60a0ced2010-09-16 20:01:08 +00001229 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001230
1231 assert (ast_context != NULL);
1232 assert (identifier_table != NULL);
1233
1234 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1235
Greg Clayton1674b122010-07-21 22:12:05 +00001236 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001237 if (clang_type)
1238 {
1239 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1240
1241 if (record_type)
1242 {
1243 RecordDecl *record_decl = record_type->getDecl();
1244
Chris Lattner24943d22010-06-08 16:52:24 +00001245 clang::Expr *bit_width = NULL;
1246 if (bitfield_bit_size != 0)
1247 {
1248 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001249 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001250 }
Greg Clayton84f80752010-07-22 18:30:50 +00001251 FieldDecl *field = FieldDecl::Create (*ast_context,
1252 record_decl,
1253 SourceLocation(),
1254 name ? &identifier_table->get(name) : NULL, // Identifier
1255 QualType::getFromOpaquePtr(field_type), // Field type
1256 NULL, // DeclaratorInfo *
1257 bit_width, // BitWidth
1258 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001259
Greg Clayton84f80752010-07-22 18:30:50 +00001260 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001261
1262 if (field)
1263 {
1264 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001265 }
1266 }
Greg Clayton9488b742010-07-28 02:04:09 +00001267 else
1268 {
1269 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1270 if (objc_class_type)
1271 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001272 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001273 ClangASTContext::AddObjCClassIVar (ast_context,
1274 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001275 name,
1276 field_type,
1277 access,
1278 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001279 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001280 }
1281 }
Chris Lattner24943d22010-06-08 16:52:24 +00001282 }
1283 return false;
1284}
1285
1286bool
1287ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1288{
1289 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1290}
1291
1292bool
1293ClangASTContext::FieldIsBitfield
1294(
1295 ASTContext *ast_context,
1296 FieldDecl* field,
1297 uint32_t& bitfield_bit_size
1298)
1299{
1300 if (ast_context == NULL || field == NULL)
1301 return false;
1302
1303 if (field->isBitField())
1304 {
1305 Expr* bit_width_expr = field->getBitWidth();
1306 if (bit_width_expr)
1307 {
1308 llvm::APSInt bit_width_apsint;
1309 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1310 {
1311 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1312 return true;
1313 }
1314 }
1315 }
1316 return false;
1317}
1318
1319bool
1320ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1321{
1322 if (record_decl == NULL)
1323 return false;
1324
1325 if (!record_decl->field_empty())
1326 return true;
1327
1328 // No fields, lets check this is a CXX record and check the base classes
1329 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1330 if (cxx_record_decl)
1331 {
1332 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1333 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1334 base_class != base_class_end;
1335 ++base_class)
1336 {
1337 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1338 if (RecordHasFields(base_class_decl))
1339 return true;
1340 }
1341 }
1342 return false;
1343}
1344
1345void
Greg Clayton462d4142010-09-29 01:12:09 +00001346ClangASTContext::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 +00001347{
1348 if (clang_qual_type)
1349 {
1350 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001351 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001352 if (clang_type)
1353 {
1354 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1355 if (record_type)
1356 {
1357 RecordDecl *record_decl = record_type->getDecl();
1358 if (record_decl)
1359 {
1360 uint32_t field_idx;
1361 RecordDecl::field_iterator field, field_end;
1362 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1363 field != field_end;
1364 ++field, ++field_idx)
1365 {
1366 // If no accessibility was assigned, assign the correct one
1367 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1368 field->setAccess ((AccessSpecifier)default_accessibility);
1369 }
1370 }
1371 }
1372 }
1373 }
1374}
1375
1376#pragma mark C++ Base Classes
1377
1378CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001379ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001380{
1381 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001382 return new CXXBaseSpecifier (SourceRange(),
1383 is_virtual,
1384 base_of_class,
1385 ConvertAccessTypeToAccessSpecifier (access),
1386 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001387 return NULL;
1388}
1389
Greg Claytone9d0df42010-07-02 01:29:13 +00001390void
1391ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1392{
1393 for (unsigned i=0; i<num_base_classes; ++i)
1394 {
1395 delete base_classes[i];
1396 base_classes[i] = NULL;
1397 }
1398}
1399
Chris Lattner24943d22010-06-08 16:52:24 +00001400bool
Greg Clayton462d4142010-09-29 01:12:09 +00001401ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001402{
1403 if (class_clang_type)
1404 {
Greg Clayton1674b122010-07-21 22:12:05 +00001405 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001406 if (clang_type)
1407 {
1408 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1409 if (record_type)
1410 {
1411 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1412 if (cxx_record_decl)
1413 {
Chris Lattner24943d22010-06-08 16:52:24 +00001414 cxx_record_decl->setBases(base_classes, num_base_classes);
1415 return true;
1416 }
1417 }
1418 }
1419 }
1420 return false;
1421}
Greg Clayton84f80752010-07-22 18:30:50 +00001422#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001423
Greg Clayton462d4142010-09-29 01:12:09 +00001424clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001425ClangASTContext::CreateObjCClass
1426(
1427 const char *name,
1428 DeclContext *decl_ctx,
1429 bool isForwardDecl,
1430 bool isInternal
1431)
1432{
1433 ASTContext *ast_context = getASTContext();
1434 assert (ast_context != NULL);
1435 assert (name && name[0]);
1436 if (decl_ctx == NULL)
1437 decl_ctx = ast_context->getTranslationUnitDecl();
1438
1439 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1440 // we will need to update this code. I was told to currently always use
1441 // the CXXRecordDecl class since we often don't know from debug information
1442 // if something is struct or a class, so we default to always use the more
1443 // complete definition just in case.
1444 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1445 decl_ctx,
1446 SourceLocation(),
1447 &ast_context->Idents.get(name),
1448 SourceLocation(),
1449 isForwardDecl,
1450 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001451
1452 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001453}
1454
1455bool
Greg Clayton462d4142010-09-29 01:12:09 +00001456ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001457{
1458 if (class_opaque_type && super_opaque_type)
1459 {
1460 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1461 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1462 clang::Type *class_type = class_qual_type.getTypePtr();
1463 clang::Type *super_type = super_qual_type.getTypePtr();
1464 if (class_type && super_type)
1465 {
1466 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1467 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1468 if (objc_class_type && objc_super_type)
1469 {
1470 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1471 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1472 if (class_interface_decl && super_interface_decl)
1473 {
1474 class_interface_decl->setSuperClass(super_interface_decl);
1475 return true;
1476 }
1477 }
1478 }
1479 }
1480 return false;
1481}
1482
1483
1484bool
1485ClangASTContext::AddObjCClassIVar
1486(
Greg Clayton462d4142010-09-29 01:12:09 +00001487 ASTContext *ast_context,
1488 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001489 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001490 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001491 AccessType access,
1492 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001493 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001494)
1495{
1496 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1497 return false;
1498
Sean Callanan60a0ced2010-09-16 20:01:08 +00001499 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001500
1501 assert (ast_context != NULL);
1502 assert (identifier_table != NULL);
1503
1504 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1505
1506 clang::Type *class_type = class_qual_type.getTypePtr();
1507 if (class_type)
1508 {
1509 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1510
1511 if (objc_class_type)
1512 {
1513 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1514
1515 if (class_interface_decl)
1516 {
1517 clang::Expr *bit_width = NULL;
1518 if (bitfield_bit_size != 0)
1519 {
1520 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001521 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001522 }
1523
Greg Clayton9488b742010-07-28 02:04:09 +00001524 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1525 class_interface_decl,
1526 SourceLocation(),
1527 &identifier_table->get(name), // Identifier
1528 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1529 NULL, // TypeSourceInfo *
1530 ConvertAccessTypeToObjCIvarAccessControl (access),
1531 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001532 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001533
1534 if (field)
1535 {
1536 class_interface_decl->addDecl(field);
1537 return true;
1538 }
Greg Clayton84f80752010-07-22 18:30:50 +00001539 }
1540 }
1541 }
1542 return false;
1543}
Chris Lattner24943d22010-06-08 16:52:24 +00001544
Greg Clayton9488b742010-07-28 02:04:09 +00001545
1546bool
Greg Clayton462d4142010-09-29 01:12:09 +00001547ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001548{
1549 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1550
1551 clang::Type *class_type = class_qual_type.getTypePtr();
1552 if (class_type)
1553 {
1554 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1555
1556 if (objc_class_type)
1557 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1558 }
1559 return false;
1560}
1561
1562bool
1563ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1564{
1565 while (class_interface_decl)
1566 {
1567 if (class_interface_decl->ivar_size() > 0)
1568 return true;
1569
1570 if (check_superclass)
1571 class_interface_decl = class_interface_decl->getSuperClass();
1572 else
1573 break;
1574 }
1575 return false;
1576}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001577
Greg Clayton462d4142010-09-29 01:12:09 +00001578ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001579ClangASTContext::AddMethodToObjCObjectType
1580(
Greg Clayton462d4142010-09-29 01:12:09 +00001581 ASTContext *ast_context,
1582 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001583 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001584 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001585 lldb::AccessType access
1586)
1587{
1588 if (class_opaque_type == NULL || method_opaque_type == NULL)
1589 return NULL;
1590
1591 IdentifierTable *identifier_table = &ast_context->Idents;
1592
1593 assert (ast_context != NULL);
1594 assert (identifier_table != NULL);
1595
1596 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1597
1598 clang::Type *class_type = class_qual_type.getTypePtr();
1599 if (class_type == NULL)
1600 return NULL;
1601
1602 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1603
1604 if (objc_class_type == NULL)
1605 return NULL;
1606
1607 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1608
1609 if (class_interface_decl == NULL)
1610 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001611
Greg Clayton1d8173f2010-09-24 05:15:53 +00001612 const char *selector_start = ::strchr (name, ' ');
1613 if (selector_start == NULL)
1614 return NULL;
1615
1616 selector_start++;
1617 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1618 return NULL;
1619 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1620
Greg Claytonad60bf42010-10-12 02:24:53 +00001621 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001622 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001623 //printf ("name = '%s'\n", name);
1624
1625 unsigned num_selectors_with_args = 0;
1626 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001627 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001628 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001629 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001630 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001631 bool has_arg = (start[len] == ':');
1632 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001633 ++num_selectors_with_args;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001634 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001635 if (has_arg)
1636 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001637 }
1638
1639
1640 if (selector_idents.size() == 0)
1641 return 0;
1642
Greg Claytonad60bf42010-10-12 02:24:53 +00001643 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001644 selector_idents.data());
1645
1646 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1647
1648 // Populate the method decl with parameter decls
1649 clang::Type *method_type(method_qual_type.getTypePtr());
1650
1651 if (method_type == NULL)
1652 return NULL;
1653
1654 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1655
1656 if (!method_function_prototype)
1657 return NULL;
1658
1659
1660 bool is_variadic = false;
1661 bool is_synthesized = false;
1662 bool is_defined = false;
1663 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1664
1665 const unsigned num_args = method_function_prototype->getNumArgs();
1666
1667 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1668 SourceLocation(), // beginLoc,
1669 SourceLocation(), // endLoc,
1670 method_selector,
1671 method_function_prototype->getResultType(),
1672 NULL, // TypeSourceInfo *ResultTInfo,
1673 GetDeclContextForType (class_opaque_type),
1674 name[0] == '-',
1675 is_variadic,
1676 is_synthesized,
1677 is_defined,
1678 imp_control,
1679 num_args);
1680
1681
1682 if (objc_method_decl == NULL)
1683 return NULL;
1684
1685 if (num_args > 0)
1686 {
1687 llvm::SmallVector<ParmVarDecl *, 12> params;
1688
1689 for (int param_index = 0; param_index < num_args; ++param_index)
1690 {
1691 params.push_back (ParmVarDecl::Create (*ast_context,
1692 objc_method_decl,
1693 SourceLocation(),
1694 NULL, // anonymous
1695 method_function_prototype->getArgType(param_index),
1696 NULL,
1697 SC_Auto,
1698 SC_Auto,
1699 NULL));
1700 }
1701
1702 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1703 }
1704
1705 class_interface_decl->addDecl (objc_method_decl);
1706
1707
1708 return objc_method_decl;
1709}
1710
1711
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001712uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001713ClangASTContext::GetTypeInfo
1714(
1715 clang_type_t clang_type,
1716 clang::ASTContext *ast_context,
1717 clang_type_t *pointee_or_element_clang_type
1718)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001719{
1720 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001721 return 0;
1722
1723 if (pointee_or_element_clang_type)
1724 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001725
1726 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1727
1728 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1729 switch (type_class)
1730 {
Sean Callanan04325062010-10-25 00:29:48 +00001731 case clang::Type::Builtin:
1732 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1733 {
Sean Callanan04325062010-10-25 00:29:48 +00001734 case clang::BuiltinType::ObjCId:
1735 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001736 if (ast_context && pointee_or_element_clang_type)
1737 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001738 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001739
1740 default:
1741 break;
Sean Callanan04325062010-10-25 00:29:48 +00001742 }
1743 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001744
1745 case clang::Type::BlockPointer:
1746 if (pointee_or_element_clang_type)
1747 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1748 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1749
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001750 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001751
1752 case clang::Type::ConstantArray:
1753 case clang::Type::DependentSizedArray:
1754 case clang::Type::IncompleteArray:
1755 case clang::Type::VariableArray:
1756 if (pointee_or_element_clang_type)
1757 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1758 return eTypeHasChildren | eTypeIsArray;
1759
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001760 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001761 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1762 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1763 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001764
1765 case clang::Type::Enum:
1766 if (pointee_or_element_clang_type)
1767 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1768 return eTypeIsEnumeration | eTypeHasValue;
1769
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001770 case clang::Type::Elaborated: return 0;
1771 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1772 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1773 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001774 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001775
1776 case clang::Type::LValueReference:
1777 case clang::Type::RValueReference:
1778 if (pointee_or_element_clang_type)
1779 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1780 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1781
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001782 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001783
1784 case clang::Type::ObjCObjectPointer:
1785 if (pointee_or_element_clang_type)
1786 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1787 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1788
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001789 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1790 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001791
1792 case clang::Type::Pointer:
1793 if (pointee_or_element_clang_type)
1794 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1795 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1796
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001797 case clang::Type::Record:
1798 if (qual_type->getAsCXXRecordDecl())
1799 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1800 else
1801 return eTypeHasChildren | eTypeIsStructUnion;
1802 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001803 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1804 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1805 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001806
1807 case clang::Type::Typedef:
1808 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1809 ast_context,
1810 pointee_or_element_clang_type);
1811
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001812 case clang::Type::TypeOfExpr: return 0;
1813 case clang::Type::TypeOf: return 0;
1814 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001815 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1816 default: return 0;
1817 }
1818 return 0;
1819}
1820
Greg Clayton9488b742010-07-28 02:04:09 +00001821
Chris Lattner24943d22010-06-08 16:52:24 +00001822#pragma mark Aggregate Types
1823
1824bool
Greg Clayton462d4142010-09-29 01:12:09 +00001825ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001826{
1827 if (clang_type == NULL)
1828 return false;
1829
1830 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1831
Greg Clayton03e0f972010-09-13 03:32:57 +00001832 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1833 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001834 {
Greg Clayton1674b122010-07-21 22:12:05 +00001835 case clang::Type::IncompleteArray:
1836 case clang::Type::VariableArray:
1837 case clang::Type::ConstantArray:
1838 case clang::Type::ExtVector:
1839 case clang::Type::Vector:
1840 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001841 case clang::Type::ObjCObject:
1842 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001843 return true;
1844
Greg Clayton1674b122010-07-21 22:12:05 +00001845 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001846 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1847
1848 default:
1849 break;
1850 }
1851 // The clang type does have a value
1852 return false;
1853}
1854
1855uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001856ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001857{
1858 if (clang_qual_type == NULL)
1859 return 0;
1860
1861 uint32_t num_children = 0;
1862 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001863 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1864 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001865 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001866 case clang::Type::Builtin:
1867 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1868 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001869 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001870 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001871 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001872 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001873
1874 default:
1875 break;
1876 }
1877 break;
1878
Greg Clayton1674b122010-07-21 22:12:05 +00001879 case clang::Type::Record:
Greg Clayton53d287b2010-11-11 02:14:53 +00001880 if (ClangASTType::IsDefined (clang_qual_type))
Chris Lattner24943d22010-06-08 16:52:24 +00001881 {
1882 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1883 const RecordDecl *record_decl = record_type->getDecl();
1884 assert(record_decl);
1885 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1886 if (cxx_record_decl)
1887 {
1888 if (omit_empty_base_classes)
1889 {
1890 // Check each base classes to see if it or any of its
1891 // base classes contain any fields. This can help
1892 // limit the noise in variable views by not having to
1893 // show base classes that contain no members.
1894 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1895 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1896 base_class != base_class_end;
1897 ++base_class)
1898 {
1899 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1900
1901 // Skip empty base classes
1902 if (RecordHasFields(base_class_decl) == false)
1903 continue;
1904
1905 num_children++;
1906 }
1907 }
1908 else
1909 {
1910 // Include all base classes
1911 num_children += cxx_record_decl->getNumBases();
1912 }
1913
1914 }
1915 RecordDecl::field_iterator field, field_end;
1916 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1917 ++num_children;
1918 }
1919 break;
1920
Greg Clayton9488b742010-07-28 02:04:09 +00001921 case clang::Type::ObjCObject:
1922 case clang::Type::ObjCInterface:
1923 {
1924 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1925 assert (objc_class_type);
1926 if (objc_class_type)
1927 {
1928 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1929
1930 if (class_interface_decl)
1931 {
1932
1933 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1934 if (superclass_interface_decl)
1935 {
1936 if (omit_empty_base_classes)
1937 {
1938 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1939 ++num_children;
1940 }
1941 else
1942 ++num_children;
1943 }
1944
1945 num_children += class_interface_decl->ivar_size();
1946 }
1947 }
1948 }
1949 break;
1950
1951 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001952 {
1953 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1954 QualType pointee_type = pointer_type->getPointeeType();
1955 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1956 omit_empty_base_classes);
1957 // If this type points to a simple type, then it has 1 child
1958 if (num_pointee_children == 0)
1959 num_children = 1;
1960 else
1961 num_children = num_pointee_children;
1962 }
1963 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001964
Greg Clayton1674b122010-07-21 22:12:05 +00001965 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001966 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1967 break;
1968
Greg Clayton1674b122010-07-21 22:12:05 +00001969 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001970 {
1971 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1972 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001973 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1974 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001975 // If this type points to a simple type, then it has 1 child
1976 if (num_pointee_children == 0)
1977 num_children = 1;
1978 else
1979 num_children = num_pointee_children;
1980 }
1981 break;
1982
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001983 case clang::Type::LValueReference:
1984 case clang::Type::RValueReference:
1985 {
1986 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1987 QualType pointee_type = reference_type->getPointeeType();
1988 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1989 omit_empty_base_classes);
1990 // If this type points to a simple type, then it has 1 child
1991 if (num_pointee_children == 0)
1992 num_children = 1;
1993 else
1994 num_children = num_pointee_children;
1995 }
1996 break;
1997
1998
Greg Clayton1674b122010-07-21 22:12:05 +00001999 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002000 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
2001 break;
2002
2003 default:
2004 break;
2005 }
2006 return num_children;
2007}
2008
2009
Greg Clayton462d4142010-09-29 01:12:09 +00002010clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002011ClangASTContext::GetChildClangTypeAtIndex
2012(
2013 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002014 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002015 uint32_t idx,
2016 bool transparent_pointers,
2017 bool omit_empty_base_classes,
2018 std::string& child_name,
2019 uint32_t &child_byte_size,
2020 int32_t &child_byte_offset,
2021 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002022 uint32_t &child_bitfield_bit_offset,
2023 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002024)
2025{
2026 if (parent_clang_type)
2027
2028 return GetChildClangTypeAtIndex (getASTContext(),
2029 parent_name,
2030 parent_clang_type,
2031 idx,
2032 transparent_pointers,
2033 omit_empty_base_classes,
2034 child_name,
2035 child_byte_size,
2036 child_byte_offset,
2037 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002038 child_bitfield_bit_offset,
2039 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002040 return NULL;
2041}
2042
Greg Clayton462d4142010-09-29 01:12:09 +00002043clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002044ClangASTContext::GetChildClangTypeAtIndex
2045(
2046 ASTContext *ast_context,
2047 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002048 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002049 uint32_t idx,
2050 bool transparent_pointers,
2051 bool omit_empty_base_classes,
2052 std::string& child_name,
2053 uint32_t &child_byte_size,
2054 int32_t &child_byte_offset,
2055 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002056 uint32_t &child_bitfield_bit_offset,
2057 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002058)
2059{
2060 if (parent_clang_type == NULL)
2061 return NULL;
2062
2063 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2064 {
2065 uint32_t bit_offset;
2066 child_bitfield_bit_size = 0;
2067 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002068 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002069 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002070 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2071 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002072 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002073 case clang::Type::Builtin:
2074 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2075 {
2076 case clang::BuiltinType::ObjCId:
2077 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002078 child_name = "isa";
2079 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002080 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2081
Greg Clayton960d6a42010-08-03 00:35:52 +00002082 default:
2083 break;
2084 }
2085 break;
2086
2087
Greg Clayton1674b122010-07-21 22:12:05 +00002088 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002089 {
2090 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2091 const RecordDecl *record_decl = record_type->getDecl();
2092 assert(record_decl);
2093 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2094 uint32_t child_idx = 0;
2095
2096 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2097 if (cxx_record_decl)
2098 {
2099 // We might have base classes to print out first
2100 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2101 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2102 base_class != base_class_end;
2103 ++base_class)
2104 {
2105 const CXXRecordDecl *base_class_decl = NULL;
2106
2107 // Skip empty base classes
2108 if (omit_empty_base_classes)
2109 {
2110 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2111 if (RecordHasFields(base_class_decl) == false)
2112 continue;
2113 }
2114
2115 if (idx == child_idx)
2116 {
2117 if (base_class_decl == NULL)
2118 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2119
2120
2121 if (base_class->isVirtual())
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002122 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002123 else
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002124 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002125
2126 // Base classes should be a multiple of 8 bits in size
2127 assert (bit_offset % 8 == 0);
2128 child_byte_offset = bit_offset/8;
2129 std::string base_class_type_name(base_class->getType().getAsString());
2130
2131 child_name.assign(base_class_type_name.c_str());
2132
2133 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2134
2135 // Base classes biut sizes should be a multiple of 8 bits in size
2136 assert (clang_type_info_bit_size % 8 == 0);
2137 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002138 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002139 return base_class->getType().getAsOpaquePtr();
2140 }
2141 // We don't increment the child index in the for loop since we might
2142 // be skipping empty base classes
2143 ++child_idx;
2144 }
2145 }
Chris Lattner24943d22010-06-08 16:52:24 +00002146 // Make sure index is in range...
2147 uint32_t field_idx = 0;
2148 RecordDecl::field_iterator field, field_end;
2149 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2150 {
2151 if (idx == child_idx)
2152 {
2153 // Print the member type if requested
2154 // Print the member name and equal sign
2155 child_name.assign(field->getNameAsString().c_str());
2156
2157 // Figure out the type byte size (field_type_info.first) and
2158 // alignment (field_type_info.second) from the AST context.
2159 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002160 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002161
2162 child_byte_size = field_type_info.first / 8;
2163
2164 // Figure out the field offset within the current struct/union/class type
2165 bit_offset = record_layout.getFieldOffset (field_idx);
2166 child_byte_offset = bit_offset / 8;
2167 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2168 child_bitfield_bit_offset = bit_offset % 8;
2169
2170 return field->getType().getAsOpaquePtr();
2171 }
2172 }
2173 }
2174 break;
2175
Greg Clayton9488b742010-07-28 02:04:09 +00002176 case clang::Type::ObjCObject:
2177 case clang::Type::ObjCInterface:
2178 {
2179 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2180 assert (objc_class_type);
2181 if (objc_class_type)
2182 {
2183 uint32_t child_idx = 0;
2184 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2185
2186 if (class_interface_decl)
2187 {
2188
2189 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2190 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2191 if (superclass_interface_decl)
2192 {
2193 if (omit_empty_base_classes)
2194 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002195 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002196 {
2197 if (idx == 0)
2198 {
2199 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2200
2201
2202 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2203
2204 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2205
2206 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002207 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002208 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002209
2210 return ivar_qual_type.getAsOpaquePtr();
2211 }
2212
2213 ++child_idx;
2214 }
2215 }
2216 else
2217 ++child_idx;
2218 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002219
2220 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002221
2222 if (idx < (child_idx + class_interface_decl->ivar_size()))
2223 {
2224 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2225
2226 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2227 {
2228 if (child_idx == idx)
2229 {
2230 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2231
2232 QualType ivar_qual_type(ivar_decl->getType());
2233
2234 child_name.assign(ivar_decl->getNameAsString().c_str());
2235
2236 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2237
2238 child_byte_size = ivar_type_info.first / 8;
2239
2240 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002241 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002242 child_byte_offset = bit_offset / 8;
2243
2244 return ivar_qual_type.getAsOpaquePtr();
2245 }
2246 ++child_idx;
2247 }
2248 }
2249 }
2250 }
2251 }
2252 break;
2253
2254 case clang::Type::ObjCObjectPointer:
2255 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002256 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2257 QualType pointee_type = pointer_type->getPointeeType();
2258
2259 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2260 {
2261 return GetChildClangTypeAtIndex (ast_context,
2262 parent_name,
2263 pointer_type->getPointeeType().getAsOpaquePtr(),
2264 idx,
2265 transparent_pointers,
2266 omit_empty_base_classes,
2267 child_name,
2268 child_byte_size,
2269 child_byte_offset,
2270 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002271 child_bitfield_bit_offset,
2272 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002273 }
2274 else
2275 {
2276 if (parent_name)
2277 {
2278 child_name.assign(1, '*');
2279 child_name += parent_name;
2280 }
2281
2282 // We have a pointer to an simple type
2283 if (idx == 0)
2284 {
2285 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2286 assert(clang_type_info.first % 8 == 0);
2287 child_byte_size = clang_type_info.first / 8;
2288 child_byte_offset = 0;
2289 return pointee_type.getAsOpaquePtr();
2290 }
2291 }
Greg Clayton9488b742010-07-28 02:04:09 +00002292 }
2293 break;
2294
Greg Clayton1674b122010-07-21 22:12:05 +00002295 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002296 {
2297 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2298 const uint64_t element_count = array->getSize().getLimitedValue();
2299
2300 if (idx < element_count)
2301 {
2302 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2303
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002304 char element_name[64];
2305 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002306
2307 child_name.assign(element_name);
2308 assert(field_type_info.first % 8 == 0);
2309 child_byte_size = field_type_info.first / 8;
2310 child_byte_offset = idx * child_byte_size;
2311 return array->getElementType().getAsOpaquePtr();
2312 }
2313 }
2314 break;
2315
Greg Clayton1674b122010-07-21 22:12:05 +00002316 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002317 {
2318 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2319 QualType pointee_type = pointer_type->getPointeeType();
2320
2321 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2322 {
2323 return GetChildClangTypeAtIndex (ast_context,
2324 parent_name,
2325 pointer_type->getPointeeType().getAsOpaquePtr(),
2326 idx,
2327 transparent_pointers,
2328 omit_empty_base_classes,
2329 child_name,
2330 child_byte_size,
2331 child_byte_offset,
2332 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002333 child_bitfield_bit_offset,
2334 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002335 }
2336 else
2337 {
2338 if (parent_name)
2339 {
2340 child_name.assign(1, '*');
2341 child_name += parent_name;
2342 }
2343
2344 // We have a pointer to an simple type
2345 if (idx == 0)
2346 {
2347 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2348 assert(clang_type_info.first % 8 == 0);
2349 child_byte_size = clang_type_info.first / 8;
2350 child_byte_offset = 0;
2351 return pointee_type.getAsOpaquePtr();
2352 }
2353 }
2354 }
2355 break;
2356
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002357 case clang::Type::LValueReference:
2358 case clang::Type::RValueReference:
2359 {
2360 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2361 QualType pointee_type(reference_type->getPointeeType());
2362 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2363 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2364 {
2365 return GetChildClangTypeAtIndex (ast_context,
2366 parent_name,
2367 pointee_clang_type,
2368 idx,
2369 transparent_pointers,
2370 omit_empty_base_classes,
2371 child_name,
2372 child_byte_size,
2373 child_byte_offset,
2374 child_bitfield_bit_size,
2375 child_bitfield_bit_offset,
2376 child_is_base_class);
2377 }
2378 else
2379 {
2380 if (parent_name)
2381 {
2382 child_name.assign(1, '&');
2383 child_name += parent_name;
2384 }
2385
2386 // We have a pointer to an simple type
2387 if (idx == 0)
2388 {
2389 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2390 assert(clang_type_info.first % 8 == 0);
2391 child_byte_size = clang_type_info.first / 8;
2392 child_byte_offset = 0;
2393 return pointee_type.getAsOpaquePtr();
2394 }
2395 }
2396 }
2397 break;
2398
Greg Clayton1674b122010-07-21 22:12:05 +00002399 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002400 return GetChildClangTypeAtIndex (ast_context,
2401 parent_name,
2402 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2403 idx,
2404 transparent_pointers,
2405 omit_empty_base_classes,
2406 child_name,
2407 child_byte_size,
2408 child_byte_offset,
2409 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002410 child_bitfield_bit_offset,
2411 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002412 break;
2413
2414 default:
2415 break;
2416 }
2417 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002418 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002419}
2420
2421static inline bool
2422BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2423{
2424 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2425}
2426
2427static uint32_t
2428GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2429{
2430 uint32_t num_bases = 0;
2431 if (cxx_record_decl)
2432 {
2433 if (omit_empty_base_classes)
2434 {
2435 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2436 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2437 base_class != base_class_end;
2438 ++base_class)
2439 {
2440 // Skip empty base classes
2441 if (omit_empty_base_classes)
2442 {
2443 if (BaseSpecifierIsEmpty (base_class))
2444 continue;
2445 }
2446 ++num_bases;
2447 }
2448 }
2449 else
2450 num_bases = cxx_record_decl->getNumBases();
2451 }
2452 return num_bases;
2453}
2454
2455
2456static uint32_t
2457GetIndexForRecordBase
2458(
2459 const RecordDecl *record_decl,
2460 const CXXBaseSpecifier *base_spec,
2461 bool omit_empty_base_classes
2462)
2463{
2464 uint32_t child_idx = 0;
2465
2466 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2467
2468// const char *super_name = record_decl->getNameAsCString();
2469// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2470// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2471//
2472 if (cxx_record_decl)
2473 {
2474 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2475 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2476 base_class != base_class_end;
2477 ++base_class)
2478 {
2479 if (omit_empty_base_classes)
2480 {
2481 if (BaseSpecifierIsEmpty (base_class))
2482 continue;
2483 }
2484
2485// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2486// child_idx,
2487// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2488//
2489//
2490 if (base_class == base_spec)
2491 return child_idx;
2492 ++child_idx;
2493 }
2494 }
2495
2496 return UINT32_MAX;
2497}
2498
2499
2500static uint32_t
2501GetIndexForRecordChild
2502(
2503 const RecordDecl *record_decl,
2504 NamedDecl *canonical_decl,
2505 bool omit_empty_base_classes
2506)
2507{
2508 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2509
2510// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2511//
2512//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2513// if (cxx_record_decl)
2514// {
2515// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2516// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2517// base_class != base_class_end;
2518// ++base_class)
2519// {
2520// if (omit_empty_base_classes)
2521// {
2522// if (BaseSpecifierIsEmpty (base_class))
2523// continue;
2524// }
2525//
2526//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2527//// record_decl->getNameAsCString(),
2528//// canonical_decl->getNameAsCString(),
2529//// child_idx,
2530//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2531//
2532//
2533// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2534// if (curr_base_class_decl == canonical_decl)
2535// {
2536// return child_idx;
2537// }
2538// ++child_idx;
2539// }
2540// }
2541//
2542// const uint32_t num_bases = child_idx;
2543 RecordDecl::field_iterator field, field_end;
2544 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2545 field != field_end;
2546 ++field, ++child_idx)
2547 {
2548// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2549// record_decl->getNameAsCString(),
2550// canonical_decl->getNameAsCString(),
2551// child_idx - num_bases,
2552// field->getNameAsCString());
2553
2554 if (field->getCanonicalDecl() == canonical_decl)
2555 return child_idx;
2556 }
2557
2558 return UINT32_MAX;
2559}
2560
2561// Look for a child member (doesn't include base classes, but it does include
2562// their members) in the type hierarchy. Returns an index path into "clang_type"
2563// on how to reach the appropriate member.
2564//
2565// class A
2566// {
2567// public:
2568// int m_a;
2569// int m_b;
2570// };
2571//
2572// class B
2573// {
2574// };
2575//
2576// class C :
2577// public B,
2578// public A
2579// {
2580// };
2581//
2582// If we have a clang type that describes "class C", and we wanted to looked
2583// "m_b" in it:
2584//
2585// With omit_empty_base_classes == false we would get an integer array back with:
2586// { 1, 1 }
2587// The first index 1 is the child index for "class A" within class C
2588// The second index 1 is the child index for "m_b" within class A
2589//
2590// With omit_empty_base_classes == true we would get an integer array back with:
2591// { 0, 1 }
2592// 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)
2593// The second index 1 is the child index for "m_b" within class A
2594
2595size_t
2596ClangASTContext::GetIndexOfChildMemberWithName
2597(
2598 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002599 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002600 const char *name,
2601 bool omit_empty_base_classes,
2602 std::vector<uint32_t>& child_indexes
2603)
2604{
2605 if (clang_type && name && name[0])
2606 {
2607 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002608 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2609 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002610 {
Greg Clayton1674b122010-07-21 22:12:05 +00002611 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002612 {
2613 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2614 const RecordDecl *record_decl = record_type->getDecl();
2615
2616 assert(record_decl);
2617 uint32_t child_idx = 0;
2618
2619 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2620
2621 // Try and find a field that matches NAME
2622 RecordDecl::field_iterator field, field_end;
2623 StringRef name_sref(name);
2624 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2625 field != field_end;
2626 ++field, ++child_idx)
2627 {
2628 if (field->getName().equals (name_sref))
2629 {
2630 // We have to add on the number of base classes to this index!
2631 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2632 return child_indexes.size();
2633 }
2634 }
2635
2636 if (cxx_record_decl)
2637 {
2638 const RecordDecl *parent_record_decl = cxx_record_decl;
2639
2640 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2641
2642 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2643 // Didn't find things easily, lets let clang do its thang...
2644 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2645 DeclarationName decl_name(&ident_ref);
2646
2647 CXXBasePaths paths;
2648 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2649 decl_name.getAsOpaquePtr(),
2650 paths))
2651 {
Chris Lattner24943d22010-06-08 16:52:24 +00002652 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2653 for (path = paths.begin(); path != path_end; ++path)
2654 {
2655 const size_t num_path_elements = path->size();
2656 for (size_t e=0; e<num_path_elements; ++e)
2657 {
2658 CXXBasePathElement elem = (*path)[e];
2659
2660 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2661 if (child_idx == UINT32_MAX)
2662 {
2663 child_indexes.clear();
2664 return 0;
2665 }
2666 else
2667 {
2668 child_indexes.push_back (child_idx);
2669 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2670 }
2671 }
2672 DeclContext::lookup_iterator named_decl_pos;
2673 for (named_decl_pos = path->Decls.first;
2674 named_decl_pos != path->Decls.second && parent_record_decl;
2675 ++named_decl_pos)
2676 {
2677 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2678
2679 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2680 if (child_idx == UINT32_MAX)
2681 {
2682 child_indexes.clear();
2683 return 0;
2684 }
2685 else
2686 {
2687 child_indexes.push_back (child_idx);
2688 }
2689 }
2690 }
2691 return child_indexes.size();
2692 }
2693 }
2694
2695 }
2696 break;
2697
Greg Clayton9488b742010-07-28 02:04:09 +00002698 case clang::Type::ObjCObject:
2699 case clang::Type::ObjCInterface:
2700 {
2701 StringRef name_sref(name);
2702 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2703 assert (objc_class_type);
2704 if (objc_class_type)
2705 {
2706 uint32_t child_idx = 0;
2707 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2708
2709 if (class_interface_decl)
2710 {
2711 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2712 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2713
Greg Clayton823533e2010-09-18 02:11:07 +00002714 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002715 {
2716 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2717
2718 if (ivar_decl->getName().equals (name_sref))
2719 {
2720 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2721 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2722 ++child_idx;
2723
2724 child_indexes.push_back (child_idx);
2725 return child_indexes.size();
2726 }
2727 }
2728
2729 if (superclass_interface_decl)
2730 {
2731 // The super class index is always zero for ObjC classes,
2732 // so we push it onto the child indexes in case we find
2733 // an ivar in our superclass...
2734 child_indexes.push_back (0);
2735
2736 if (GetIndexOfChildMemberWithName (ast_context,
2737 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2738 name,
2739 omit_empty_base_classes,
2740 child_indexes))
2741 {
2742 // We did find an ivar in a superclass so just
2743 // return the results!
2744 return child_indexes.size();
2745 }
2746
2747 // We didn't find an ivar matching "name" in our
2748 // superclass, pop the superclass zero index that
2749 // we pushed on above.
2750 child_indexes.pop_back();
2751 }
2752 }
2753 }
2754 }
2755 break;
2756
2757 case clang::Type::ObjCObjectPointer:
2758 {
2759 return GetIndexOfChildMemberWithName (ast_context,
2760 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2761 name,
2762 omit_empty_base_classes,
2763 child_indexes);
2764 }
2765 break;
2766
2767
Greg Clayton1674b122010-07-21 22:12:05 +00002768 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002769 {
2770// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2771// const uint64_t element_count = array->getSize().getLimitedValue();
2772//
2773// if (idx < element_count)
2774// {
2775// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2776//
2777// char element_name[32];
2778// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2779//
2780// child_name.assign(element_name);
2781// assert(field_type_info.first % 8 == 0);
2782// child_byte_size = field_type_info.first / 8;
2783// child_byte_offset = idx * child_byte_size;
2784// return array->getElementType().getAsOpaquePtr();
2785// }
2786 }
2787 break;
2788
Greg Clayton1674b122010-07-21 22:12:05 +00002789// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002790// {
2791// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2792// QualType pointee_type = mem_ptr_type->getPointeeType();
2793//
2794// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2795// {
2796// return GetIndexOfChildWithName (ast_context,
2797// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2798// name);
2799// }
2800// }
2801// break;
2802//
Greg Clayton1674b122010-07-21 22:12:05 +00002803 case clang::Type::LValueReference:
2804 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002805 {
2806 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2807 QualType pointee_type = reference_type->getPointeeType();
2808
2809 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2810 {
2811 return GetIndexOfChildMemberWithName (ast_context,
2812 reference_type->getPointeeType().getAsOpaquePtr(),
2813 name,
2814 omit_empty_base_classes,
2815 child_indexes);
2816 }
2817 }
2818 break;
2819
Greg Clayton1674b122010-07-21 22:12:05 +00002820 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002821 {
2822 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2823 QualType pointee_type = pointer_type->getPointeeType();
2824
2825 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2826 {
2827 return GetIndexOfChildMemberWithName (ast_context,
2828 pointer_type->getPointeeType().getAsOpaquePtr(),
2829 name,
2830 omit_empty_base_classes,
2831 child_indexes);
2832 }
2833 else
2834 {
2835// if (parent_name)
2836// {
2837// child_name.assign(1, '*');
2838// child_name += parent_name;
2839// }
2840//
2841// // We have a pointer to an simple type
2842// if (idx == 0)
2843// {
2844// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2845// assert(clang_type_info.first % 8 == 0);
2846// child_byte_size = clang_type_info.first / 8;
2847// child_byte_offset = 0;
2848// return pointee_type.getAsOpaquePtr();
2849// }
2850 }
2851 }
2852 break;
2853
Greg Clayton1674b122010-07-21 22:12:05 +00002854 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002855 return GetIndexOfChildMemberWithName (ast_context,
2856 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2857 name,
2858 omit_empty_base_classes,
2859 child_indexes);
2860
2861 default:
2862 break;
2863 }
2864 }
2865 return 0;
2866}
2867
2868
2869// Get the index of the child of "clang_type" whose name matches. This function
2870// doesn't descend into the children, but only looks one level deep and name
2871// matches can include base class names.
2872
2873uint32_t
2874ClangASTContext::GetIndexOfChildWithName
2875(
2876 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002877 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002878 const char *name,
2879 bool omit_empty_base_classes
2880)
2881{
2882 if (clang_type && name && name[0])
2883 {
2884 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002885
Greg Clayton03e0f972010-09-13 03:32:57 +00002886 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002887
Greg Clayton03e0f972010-09-13 03:32:57 +00002888 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002889 {
Greg Clayton1674b122010-07-21 22:12:05 +00002890 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002891 {
2892 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2893 const RecordDecl *record_decl = record_type->getDecl();
2894
2895 assert(record_decl);
2896 uint32_t child_idx = 0;
2897
2898 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2899
2900 if (cxx_record_decl)
2901 {
2902 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2903 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2904 base_class != base_class_end;
2905 ++base_class)
2906 {
2907 // Skip empty base classes
2908 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2909 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2910 continue;
2911
2912 if (base_class->getType().getAsString().compare (name) == 0)
2913 return child_idx;
2914 ++child_idx;
2915 }
2916 }
2917
2918 // Try and find a field that matches NAME
2919 RecordDecl::field_iterator field, field_end;
2920 StringRef name_sref(name);
2921 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2922 field != field_end;
2923 ++field, ++child_idx)
2924 {
2925 if (field->getName().equals (name_sref))
2926 return child_idx;
2927 }
2928
2929 }
2930 break;
2931
Greg Clayton9488b742010-07-28 02:04:09 +00002932 case clang::Type::ObjCObject:
2933 case clang::Type::ObjCInterface:
2934 {
2935 StringRef name_sref(name);
2936 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2937 assert (objc_class_type);
2938 if (objc_class_type)
2939 {
2940 uint32_t child_idx = 0;
2941 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2942
2943 if (class_interface_decl)
2944 {
2945 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2946 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2947
2948 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2949 {
2950 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2951
2952 if (ivar_decl->getName().equals (name_sref))
2953 {
2954 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2955 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2956 ++child_idx;
2957
2958 return child_idx;
2959 }
2960 }
2961
2962 if (superclass_interface_decl)
2963 {
2964 if (superclass_interface_decl->getName().equals (name_sref))
2965 return 0;
2966 }
2967 }
2968 }
2969 }
2970 break;
2971
2972 case clang::Type::ObjCObjectPointer:
2973 {
2974 return GetIndexOfChildWithName (ast_context,
2975 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2976 name,
2977 omit_empty_base_classes);
2978 }
2979 break;
2980
Greg Clayton1674b122010-07-21 22:12:05 +00002981 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002982 {
2983// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2984// const uint64_t element_count = array->getSize().getLimitedValue();
2985//
2986// if (idx < element_count)
2987// {
2988// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2989//
2990// char element_name[32];
2991// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2992//
2993// child_name.assign(element_name);
2994// assert(field_type_info.first % 8 == 0);
2995// child_byte_size = field_type_info.first / 8;
2996// child_byte_offset = idx * child_byte_size;
2997// return array->getElementType().getAsOpaquePtr();
2998// }
2999 }
3000 break;
3001
Greg Clayton1674b122010-07-21 22:12:05 +00003002// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00003003// {
3004// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3005// QualType pointee_type = mem_ptr_type->getPointeeType();
3006//
3007// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3008// {
3009// return GetIndexOfChildWithName (ast_context,
3010// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3011// name);
3012// }
3013// }
3014// break;
3015//
Greg Clayton1674b122010-07-21 22:12:05 +00003016 case clang::Type::LValueReference:
3017 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003018 {
3019 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3020 QualType pointee_type = reference_type->getPointeeType();
3021
3022 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3023 {
3024 return GetIndexOfChildWithName (ast_context,
3025 reference_type->getPointeeType().getAsOpaquePtr(),
3026 name,
3027 omit_empty_base_classes);
3028 }
3029 }
3030 break;
3031
Greg Clayton1674b122010-07-21 22:12:05 +00003032 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003033 {
3034 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3035 QualType pointee_type = pointer_type->getPointeeType();
3036
3037 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3038 {
3039 return GetIndexOfChildWithName (ast_context,
3040 pointer_type->getPointeeType().getAsOpaquePtr(),
3041 name,
3042 omit_empty_base_classes);
3043 }
3044 else
3045 {
3046// if (parent_name)
3047// {
3048// child_name.assign(1, '*');
3049// child_name += parent_name;
3050// }
3051//
3052// // We have a pointer to an simple type
3053// if (idx == 0)
3054// {
3055// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3056// assert(clang_type_info.first % 8 == 0);
3057// child_byte_size = clang_type_info.first / 8;
3058// child_byte_offset = 0;
3059// return pointee_type.getAsOpaquePtr();
3060// }
3061 }
3062 }
3063 break;
3064
Greg Clayton1674b122010-07-21 22:12:05 +00003065 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003066 return GetIndexOfChildWithName (ast_context,
3067 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3068 name,
3069 omit_empty_base_classes);
3070
3071 default:
3072 break;
3073 }
3074 }
3075 return UINT32_MAX;
3076}
3077
3078#pragma mark TagType
3079
3080bool
Greg Clayton462d4142010-09-29 01:12:09 +00003081ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003082{
3083 if (tag_clang_type)
3084 {
3085 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003086 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003087 if (clang_type)
3088 {
3089 TagType *tag_type = dyn_cast<TagType>(clang_type);
3090 if (tag_type)
3091 {
3092 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3093 if (tag_decl)
3094 {
3095 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3096 return true;
3097 }
3098 }
3099 }
3100 }
3101 return false;
3102}
3103
3104
3105#pragma mark DeclContext Functions
3106
3107DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003108ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003109{
3110 if (clang_type == NULL)
3111 return NULL;
3112
3113 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003114 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3115 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003116 {
Greg Clayton9488b742010-07-28 02:04:09 +00003117 case clang::Type::FunctionNoProto: break;
3118 case clang::Type::FunctionProto: break;
3119 case clang::Type::IncompleteArray: break;
3120 case clang::Type::VariableArray: break;
3121 case clang::Type::ConstantArray: break;
3122 case clang::Type::ExtVector: break;
3123 case clang::Type::Vector: break;
3124 case clang::Type::Builtin: break;
3125 case clang::Type::BlockPointer: break;
3126 case clang::Type::Pointer: break;
3127 case clang::Type::LValueReference: break;
3128 case clang::Type::RValueReference: break;
3129 case clang::Type::MemberPointer: break;
3130 case clang::Type::Complex: break;
3131 case clang::Type::ObjCObject: break;
3132 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3133 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3134 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3135 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
3136 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003137
Greg Clayton9488b742010-07-28 02:04:09 +00003138 case clang::Type::TypeOfExpr: break;
3139 case clang::Type::TypeOf: break;
3140 case clang::Type::Decltype: break;
3141 //case clang::Type::QualifiedName: break;
3142 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003143 }
3144 // No DeclContext in this type...
3145 return NULL;
3146}
3147
3148#pragma mark Namespace Declarations
3149
3150NamespaceDecl *
3151ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3152{
3153 // TODO: Do something intelligent with the Declaration object passed in
3154 // like maybe filling in the SourceLocation with it...
3155 if (name)
3156 {
3157 ASTContext *ast_context = getASTContext();
3158 if (decl_ctx == NULL)
3159 decl_ctx = ast_context->getTranslationUnitDecl();
3160 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3161 }
3162 return NULL;
3163}
3164
3165
3166#pragma mark Function Types
3167
3168FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003169ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003170{
3171 if (name)
3172 {
3173 ASTContext *ast_context = getASTContext();
3174 assert (ast_context != NULL);
3175
3176 if (name && name[0])
3177 {
3178 return FunctionDecl::Create(*ast_context,
3179 ast_context->getTranslationUnitDecl(),
3180 SourceLocation(),
3181 DeclarationName (&ast_context->Idents.get(name)),
3182 QualType::getFromOpaquePtr(function_clang_type),
3183 NULL,
3184 (FunctionDecl::StorageClass)storage,
3185 (FunctionDecl::StorageClass)storage,
3186 is_inline);
3187 }
3188 else
3189 {
3190 return FunctionDecl::Create(*ast_context,
3191 ast_context->getTranslationUnitDecl(),
3192 SourceLocation(),
3193 DeclarationName (),
3194 QualType::getFromOpaquePtr(function_clang_type),
3195 NULL,
3196 (FunctionDecl::StorageClass)storage,
3197 (FunctionDecl::StorageClass)storage,
3198 is_inline);
3199 }
3200 }
3201 return NULL;
3202}
3203
Greg Clayton462d4142010-09-29 01:12:09 +00003204clang_type_t
3205ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3206 clang_type_t result_type,
3207 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003208 unsigned num_args,
3209 bool is_variadic,
3210 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003211{
Chris Lattner24943d22010-06-08 16:52:24 +00003212 assert (ast_context != NULL);
3213 std::vector<QualType> qual_type_args;
3214 for (unsigned i=0; i<num_args; ++i)
3215 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3216
3217 // TODO: Detect calling convention in DWARF?
3218 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003219 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003220 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003221 is_variadic,
3222 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003223 false, // hasExceptionSpec
3224 false, // hasAnyExceptionSpec,
3225 0, // NumExs
3226 0, // const QualType *ExArray
3227 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3228}
3229
3230ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003231ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003232{
3233 ASTContext *ast_context = getASTContext();
3234 assert (ast_context != NULL);
3235 return ParmVarDecl::Create(*ast_context,
3236 ast_context->getTranslationUnitDecl(),
3237 SourceLocation(),
3238 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003239 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003240 NULL,
3241 (VarDecl::StorageClass)storage,
3242 (VarDecl::StorageClass)storage,
3243 0);
3244}
3245
3246void
3247ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3248{
3249 if (function_decl)
3250 function_decl->setParams (params, num_params);
3251}
3252
3253
3254#pragma mark Array Types
3255
Greg Clayton462d4142010-09-29 01:12:09 +00003256clang_type_t
3257ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003258{
3259 if (element_type)
3260 {
3261 ASTContext *ast_context = getASTContext();
3262 assert (ast_context != NULL);
3263 llvm::APInt ap_element_count (64, element_count);
3264 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3265 ap_element_count,
3266 ArrayType::Normal,
3267 0).getAsOpaquePtr(); // ElemQuals
3268 }
3269 return NULL;
3270}
3271
3272
3273#pragma mark TagDecl
3274
3275bool
Greg Clayton462d4142010-09-29 01:12:09 +00003276ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003277{
3278 if (clang_type)
3279 {
3280 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003281 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003282 if (t)
3283 {
3284 TagType *tag_type = dyn_cast<TagType>(t);
3285 if (tag_type)
3286 {
3287 TagDecl *tag_decl = tag_type->getDecl();
3288 if (tag_decl)
3289 {
3290 tag_decl->startDefinition();
3291 return true;
3292 }
3293 }
3294 }
3295 }
3296 return false;
3297}
3298
3299bool
Greg Clayton462d4142010-09-29 01:12:09 +00003300ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003301{
3302 if (clang_type)
3303 {
3304 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00003305
3306 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3307
3308 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003309 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003310 cxx_record_decl->completeDefinition();
3311
3312 return true;
3313 }
3314
Sean Callanan04325062010-10-25 00:29:48 +00003315 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3316
3317 if (objc_class_type)
3318 {
3319 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3320
3321 class_interface_decl->setForwardDecl(false);
3322 }
3323
Greg Clayton55b6c532010-09-29 03:44:17 +00003324 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3325
3326 if (enum_type)
3327 {
3328 EnumDecl *enum_decl = enum_type->getDecl();
3329
3330 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003331 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003332 /// TODO This really needs to be fixed.
3333
3334 unsigned NumPositiveBits = 1;
3335 unsigned NumNegativeBits = 0;
3336
Greg Clayton48fbdf72010-10-12 04:29:14 +00003337 ASTContext *ast_context = getASTContext();
3338
3339 QualType promotion_qual_type;
3340 // If the enum integer type is less than an integer in bit width,
3341 // then we must promote it to an integer size.
3342 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3343 {
3344 if (enum_decl->getIntegerType()->isSignedIntegerType())
3345 promotion_qual_type = ast_context->IntTy;
3346 else
3347 promotion_qual_type = ast_context->UnsignedIntTy;
3348 }
3349 else
3350 promotion_qual_type = enum_decl->getIntegerType();
3351
3352 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003353 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003354 }
3355 }
3356 }
3357 return false;
3358}
3359
3360
3361#pragma mark Enumeration Types
3362
Greg Clayton462d4142010-09-29 01:12:09 +00003363clang_type_t
3364ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003365{
3366 // TODO: Do something intelligent with the Declaration object passed in
3367 // like maybe filling in the SourceLocation with it...
3368 ASTContext *ast_context = getASTContext();
3369 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003370
3371 // TODO: ask about these...
3372// const bool IsScoped = false;
3373// const bool IsFixed = false;
3374
3375 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3376 ast_context->getTranslationUnitDecl(),
3377 SourceLocation(),
3378 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3379 SourceLocation(),
Sean Callanan8950c9a2010-10-29 18:38:40 +00003380 NULL, false, false); //IsScoped, IsFixed);
Chris Lattner24943d22010-06-08 16:52:24 +00003381 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003382 {
3383 // TODO: check if we should be setting the promotion type too?
3384 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003385 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003386 }
Chris Lattner24943d22010-06-08 16:52:24 +00003387 return NULL;
3388}
3389
Greg Clayton462d4142010-09-29 01:12:09 +00003390clang_type_t
3391ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3392{
3393 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3394
3395 clang::Type *clang_type = enum_qual_type.getTypePtr();
3396 if (clang_type)
3397 {
3398 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3399 if (enum_type)
3400 {
3401 EnumDecl *enum_decl = enum_type->getDecl();
3402 if (enum_decl)
3403 return enum_decl->getIntegerType().getAsOpaquePtr();
3404 }
3405 }
3406 return NULL;
3407}
Chris Lattner24943d22010-06-08 16:52:24 +00003408bool
3409ClangASTContext::AddEnumerationValueToEnumerationType
3410(
Greg Clayton462d4142010-09-29 01:12:09 +00003411 clang_type_t enum_clang_type,
3412 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003413 const Declaration &decl,
3414 const char *name,
3415 int64_t enum_value,
3416 uint32_t enum_value_bit_size
3417)
3418{
3419 if (enum_clang_type && enumerator_clang_type && name)
3420 {
3421 // TODO: Do something intelligent with the Declaration object passed in
3422 // like maybe filling in the SourceLocation with it...
3423 ASTContext *ast_context = getASTContext();
3424 IdentifierTable *identifier_table = getIdentifierTable();
3425
3426 assert (ast_context != NULL);
3427 assert (identifier_table != NULL);
3428 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3429
Greg Clayton1674b122010-07-21 22:12:05 +00003430 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003431 if (clang_type)
3432 {
3433 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3434
3435 if (enum_type)
3436 {
3437 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3438 enum_llvm_apsint = enum_value;
3439 EnumConstantDecl *enumerator_decl =
3440 EnumConstantDecl::Create(*ast_context,
3441 enum_type->getDecl(),
3442 SourceLocation(),
3443 name ? &identifier_table->get(name) : NULL, // Identifier
3444 QualType::getFromOpaquePtr(enumerator_clang_type),
3445 NULL,
3446 enum_llvm_apsint);
3447
3448 if (enumerator_decl)
3449 {
3450 enum_type->getDecl()->addDecl(enumerator_decl);
3451 return true;
3452 }
3453 }
3454 }
3455 }
3456 return false;
3457}
3458
3459#pragma mark Pointers & References
3460
Greg Clayton462d4142010-09-29 01:12:09 +00003461clang_type_t
3462ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003463{
3464 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003465 {
3466 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3467
Greg Clayton03e0f972010-09-13 03:32:57 +00003468 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3469 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003470 {
3471 case clang::Type::ObjCObject:
3472 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003473 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3474
Greg Clayton7b541032010-07-29 20:06:32 +00003475 default:
3476 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3477 }
3478 }
Chris Lattner24943d22010-06-08 16:52:24 +00003479 return NULL;
3480}
3481
Greg Clayton462d4142010-09-29 01:12:09 +00003482clang_type_t
3483ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003484{
3485 if (clang_type)
3486 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3487 return NULL;
3488}
3489
Greg Clayton462d4142010-09-29 01:12:09 +00003490clang_type_t
3491ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003492{
3493 if (clang_type)
3494 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3495 return NULL;
3496}
3497
Greg Clayton462d4142010-09-29 01:12:09 +00003498clang_type_t
3499ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003500{
3501 if (clang_pointee_type && clang_pointee_type)
3502 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3503 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3504 return NULL;
3505}
3506
Chris Lattner24943d22010-06-08 16:52:24 +00003507size_t
3508ClangASTContext::GetPointerBitSize ()
3509{
3510 ASTContext *ast_context = getASTContext();
3511 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3512}
3513
3514bool
Greg Clayton462d4142010-09-29 01:12:09 +00003515ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003516{
3517 if (clang_type == NULL)
3518 return false;
3519
3520 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003521 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3522 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003523 {
Sean Callanan04325062010-10-25 00:29:48 +00003524 case clang::Type::Builtin:
3525 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3526 {
3527 default:
3528 break;
3529 case clang::BuiltinType::ObjCId:
3530 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003531 return true;
3532 }
3533 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003534 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003535 if (target_type)
3536 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3537 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003538 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003539 if (target_type)
3540 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3541 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003542 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003543 if (target_type)
3544 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3545 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003546 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003547 if (target_type)
3548 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3549 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003550 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003551 if (target_type)
3552 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3553 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003554 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003555 if (target_type)
3556 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3557 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003558 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003559 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3560 default:
3561 break;
3562 }
3563 return false;
3564}
3565
Chris Lattner24943d22010-06-08 16:52:24 +00003566bool
Greg Clayton462d4142010-09-29 01:12:09 +00003567ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003568{
3569 if (!clang_type)
3570 return false;
3571
3572 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3573 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3574
3575 if (builtin_type)
3576 {
3577 if (builtin_type->isInteger())
3578 is_signed = builtin_type->isSignedInteger();
3579
3580 return true;
3581 }
3582
3583 return false;
3584}
3585
3586bool
Greg Clayton462d4142010-09-29 01:12:09 +00003587ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003588{
3589 if (clang_type)
3590 {
3591 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003592 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3593 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003594 {
Sean Callanan04325062010-10-25 00:29:48 +00003595 case clang::Type::Builtin:
3596 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3597 {
3598 default:
3599 break;
3600 case clang::BuiltinType::ObjCId:
3601 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003602 return true;
3603 }
3604 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003605 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003606 if (target_type)
3607 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3608 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003609 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003610 if (target_type)
3611 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3612 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003613 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003614 if (target_type)
3615 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3616 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003617 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003618 if (target_type)
3619 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().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(), target_type);
3623 default:
3624 break;
3625 }
3626 }
3627 return false;
3628}
3629
3630bool
Greg Clayton462d4142010-09-29 01:12:09 +00003631ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003632{
3633 if (clang_type)
3634 {
3635 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3636
3637 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3638 {
3639 clang::BuiltinType::Kind kind = BT->getKind();
3640 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3641 {
3642 count = 1;
3643 is_complex = false;
3644 return true;
3645 }
3646 }
3647 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3648 {
3649 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3650 {
3651 count = 2;
3652 is_complex = true;
3653 return true;
3654 }
3655 }
3656 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3657 {
3658 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3659 {
3660 count = VT->getNumElements();
3661 is_complex = false;
3662 return true;
3663 }
3664 }
3665 }
3666 return false;
3667}
3668
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003669
3670bool
3671ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3672{
3673 if (clang_type)
3674 {
3675 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3676
3677 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3678 if (cxx_record_decl)
3679 {
3680 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3681 return true;
3682 }
3683 }
3684 class_name.clear();
3685 return false;
3686}
3687
3688
Greg Clayton1d8173f2010-09-24 05:15:53 +00003689bool
Greg Clayton462d4142010-09-29 01:12:09 +00003690ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003691{
3692 if (clang_type)
3693 {
3694 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3695 if (qual_type->getAsCXXRecordDecl() != NULL)
3696 return true;
3697 }
3698 return false;
3699}
3700
3701bool
Greg Clayton462d4142010-09-29 01:12:09 +00003702ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003703{
3704 if (clang_type)
3705 {
3706 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3707 if (qual_type->isObjCObjectOrInterfaceType())
3708 return true;
3709 }
3710 return false;
3711}
3712
3713
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003714bool
3715ClangASTContext::IsCharType (clang_type_t clang_type)
3716{
3717 if (clang_type)
3718 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3719 return false;
3720}
Chris Lattner24943d22010-06-08 16:52:24 +00003721
3722bool
Greg Clayton462d4142010-09-29 01:12:09 +00003723ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003724{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003725 clang_type_t pointee_or_element_clang_type = NULL;
3726 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3727
3728 if (pointee_or_element_clang_type == NULL)
3729 return false;
3730
3731 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003732 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003733 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3734
3735 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003736 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003737 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3738 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003739 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003740 // We know the size of the array and it could be a C string
3741 // since it is an array of characters
3742 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3743 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003744 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003745 else
Chris Lattner24943d22010-06-08 16:52:24 +00003746 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003747 length = 0;
3748 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003749 }
Chris Lattner24943d22010-06-08 16:52:24 +00003750
Chris Lattner24943d22010-06-08 16:52:24 +00003751 }
3752 }
3753 return false;
3754}
3755
3756bool
Greg Clayton462d4142010-09-29 01:12:09 +00003757ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003758{
3759 if (clang_type)
3760 {
3761 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3762
3763 if (qual_type->isFunctionPointerType())
3764 return true;
3765
3766 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3767 switch (type_class)
3768 {
3769 case clang::Type::Typedef:
3770 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3771
3772 case clang::Type::LValueReference:
3773 case clang::Type::RValueReference:
3774 {
3775 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3776 if (reference_type)
3777 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3778 }
3779 break;
3780 }
3781 }
3782 return false;
3783}
3784
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003785size_t
3786ClangASTContext::GetArraySize (clang_type_t clang_type)
3787{
3788 if (clang_type)
3789 {
3790 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3791 if (array)
3792 return array->getSize().getLimitedValue();
3793 }
3794 return 0;
3795}
Greg Clayton03e0f972010-09-13 03:32:57 +00003796
3797bool
Greg Clayton462d4142010-09-29 01:12:09 +00003798ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003799{
3800 if (!clang_type)
3801 return false;
3802
3803 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3804
Greg Clayton03e0f972010-09-13 03:32:57 +00003805 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3806 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003807 {
Greg Clayton1674b122010-07-21 22:12:05 +00003808 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003809 if (member_type)
3810 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3811 if (size)
3812 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3813 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003814 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003815 if (member_type)
3816 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3817 if (size)
3818 *size = 0;
3819 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003820 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003821 if (member_type)
3822 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3823 if (size)
3824 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003825 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003826 if (member_type)
3827 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3828 if (size)
3829 *size = 0;
3830 return true;
3831 }
3832 return false;
3833}
3834
3835
3836#pragma mark Typedefs
3837
Greg Clayton462d4142010-09-29 01:12:09 +00003838clang_type_t
3839ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003840{
3841 if (clang_type)
3842 {
3843 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3844 ASTContext *ast_context = getASTContext();
3845 IdentifierTable *identifier_table = getIdentifierTable();
3846 assert (ast_context != NULL);
3847 assert (identifier_table != NULL);
3848 if (decl_ctx == NULL)
3849 decl_ctx = ast_context->getTranslationUnitDecl();
3850 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3851 decl_ctx,
3852 SourceLocation(),
3853 name ? &identifier_table->get(name) : NULL, // Identifier
3854 ast_context->CreateTypeSourceInfo(qual_type));
3855
3856 // Get a uniqued QualType for the typedef decl type
3857 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3858 }
3859 return NULL;
3860}
3861
3862
3863std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003864ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003865{
3866 std::string return_name;
3867
Greg Clayton462d4142010-09-29 01:12:09 +00003868 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003869
Greg Clayton462d4142010-09-29 01:12:09 +00003870 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003871 if (typedef_type)
3872 {
Greg Clayton462d4142010-09-29 01:12:09 +00003873 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003874 return_name = typedef_decl->getQualifiedNameAsString();
3875 }
3876 else
3877 {
3878 return_name = qual_type.getAsString();
3879 }
3880
3881 return return_name;
3882}
3883
3884// Disable this for now since I can't seem to get a nicely formatted float
3885// out of the APFloat class without just getting the float, double or quad
3886// and then using a formatted print on it which defeats the purpose. We ideally
3887// would like to get perfect string values for any kind of float semantics
3888// so we can support remote targets. The code below also requires a patch to
3889// llvm::APInt.
3890//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003891//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 +00003892//{
3893// uint32_t count = 0;
3894// bool is_complex = false;
3895// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3896// {
3897// unsigned num_bytes_per_float = byte_size / count;
3898// unsigned num_bits_per_float = num_bytes_per_float * 8;
3899//
3900// float_str.clear();
3901// uint32_t i;
3902// for (i=0; i<count; i++)
3903// {
3904// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3905// bool is_ieee = false;
3906// APFloat ap_float(ap_int, is_ieee);
3907// char s[1024];
3908// unsigned int hex_digits = 0;
3909// bool upper_case = false;
3910//
3911// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3912// {
3913// if (i > 0)
3914// float_str.append(", ");
3915// float_str.append(s);
3916// if (i == 1 && is_complex)
3917// float_str.append(1, 'i');
3918// }
3919// }
3920// return !float_str.empty();
3921// }
3922// return false;
3923//}
3924
3925size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003926ClangASTContext::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 +00003927{
3928 if (clang_type)
3929 {
3930 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3931 uint32_t count = 0;
3932 bool is_complex = false;
3933 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3934 {
3935 // TODO: handle complex and vector types
3936 if (count != 1)
3937 return false;
3938
3939 StringRef s_sref(s);
3940 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3941
3942 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3943 const uint64_t byte_size = bit_size / 8;
3944 if (dst_size >= byte_size)
3945 {
3946 if (bit_size == sizeof(float)*8)
3947 {
3948 float float32 = ap_float.convertToFloat();
3949 ::memcpy (dst, &float32, byte_size);
3950 return byte_size;
3951 }
3952 else if (bit_size >= 64)
3953 {
3954 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3955 ::memcpy (dst, ap_int.getRawData(), byte_size);
3956 return byte_size;
3957 }
3958 }
3959 }
3960 }
3961 return 0;
3962}
Sean Callanana751f7b2010-09-17 02:24:29 +00003963
3964unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00003965ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00003966{
3967 assert (clang_type);
3968
3969 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3970
3971 return qual_type.getQualifiers().getCVRQualifiers();
3972}