blob: 566c3ea9e833c743a06bdf960b6e18d362a44408 [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 Clayton30449d52010-10-01 02:31:07 +00001100 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001101
Greg Clayton30449d52010-10-01 02:31:07 +00001102 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001103
Greg Clayton90e325d2010-10-01 03:45:20 +00001104 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001105
Greg Clayton5325a362010-10-02 01:40:05 +00001106 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001107
Greg Clayton5325a362010-10-02 01:40:05 +00001108 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001109 return NULL;
1110
Greg Clayton5325a362010-10-02 01:40:05 +00001111 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001112
1113 if (!method_function_prototype)
1114 return NULL;
1115
1116 unsigned int num_params = method_function_prototype->getNumArgs();
1117
1118 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001119 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001120 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1121 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001122 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001123 method_qual_type,
Sean Callanan8950c9a2010-10-29 18:38:40 +00001124 NULL,
Greg Clayton90e325d2010-10-01 03:45:20 +00001125 is_inline,
1126 is_implicitly_declared);
1127 }
1128 else if (decl_name == record_decl->getDeclName())
1129 {
Greg Clayton30449d52010-10-01 02:31:07 +00001130 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1131 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001132 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001133 method_qual_type,
1134 NULL, // TypeSourceInfo *
1135 is_explicit,
1136 is_inline,
1137 is_implicitly_declared);
1138 }
1139 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001140 {
Greg Claytondbf26152010-10-01 23:13:49 +00001141
1142 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1143 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001144 {
Greg Claytondbf26152010-10-01 23:13:49 +00001145 if (op_kind != NUM_OVERLOADED_OPERATORS)
1146 {
1147 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001148 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001149 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001150 method_qual_type,
1151 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001152 is_static,
1153 SC_None,
1154 is_inline);
1155 }
1156 else if (num_params == 0)
1157 {
1158 // Conversion operators don't take params...
1159 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1160 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001161 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001162 method_qual_type,
1163 NULL, // TypeSourceInfo *
1164 is_inline,
1165 is_explicit);
1166 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001167 }
Greg Claytondbf26152010-10-01 23:13:49 +00001168
1169 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001170 {
1171 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1172 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001173 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001174 method_qual_type,
1175 NULL, // TypeSourceInfo *
1176 is_static,
1177 SC_None,
1178 is_inline);
1179 }
Greg Clayton30449d52010-10-01 02:31:07 +00001180 }
Greg Claytondbf26152010-10-01 23:13:49 +00001181
Greg Clayton462d4142010-09-29 01:12:09 +00001182 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001183
1184 cxx_method_decl->setAccess (access_specifier);
1185 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001186
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001187 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001188
1189 ParmVarDecl *params[num_params];
1190
1191 for (int param_index = 0;
1192 param_index < num_params;
1193 ++param_index)
1194 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001195 params[param_index] = ParmVarDecl::Create (*ast_context,
1196 cxx_method_decl,
1197 SourceLocation(),
1198 NULL, // anonymous
1199 method_function_prototype->getArgType(param_index),
1200 NULL,
1201 SC_None,
1202 SC_None,
1203 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001204 }
1205
Greg Clayton1d8173f2010-09-24 05:15:53 +00001206 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001207
Greg Clayton1d8173f2010-09-24 05:15:53 +00001208 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001209
Greg Clayton412440a2010-09-23 01:09:21 +00001210 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001211}
1212
1213bool
Greg Clayton84f80752010-07-22 18:30:50 +00001214ClangASTContext::AddFieldToRecordType
1215(
Greg Clayton462d4142010-09-29 01:12:09 +00001216 ASTContext *ast_context,
1217 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001218 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001219 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001220 AccessType access,
1221 uint32_t bitfield_bit_size
1222)
Chris Lattner24943d22010-06-08 16:52:24 +00001223{
1224 if (record_clang_type == NULL || field_type == NULL)
1225 return false;
1226
Sean Callanan60a0ced2010-09-16 20:01:08 +00001227 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001228
1229 assert (ast_context != NULL);
1230 assert (identifier_table != NULL);
1231
1232 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1233
Greg Clayton1674b122010-07-21 22:12:05 +00001234 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001235 if (clang_type)
1236 {
1237 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1238
1239 if (record_type)
1240 {
1241 RecordDecl *record_decl = record_type->getDecl();
1242
Chris Lattner24943d22010-06-08 16:52:24 +00001243 clang::Expr *bit_width = NULL;
1244 if (bitfield_bit_size != 0)
1245 {
1246 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001247 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001248 }
Greg Clayton84f80752010-07-22 18:30:50 +00001249 FieldDecl *field = FieldDecl::Create (*ast_context,
1250 record_decl,
1251 SourceLocation(),
1252 name ? &identifier_table->get(name) : NULL, // Identifier
1253 QualType::getFromOpaquePtr(field_type), // Field type
1254 NULL, // DeclaratorInfo *
1255 bit_width, // BitWidth
1256 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001257
Greg Clayton84f80752010-07-22 18:30:50 +00001258 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001259
1260 if (field)
1261 {
1262 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001263 }
1264 }
Greg Clayton9488b742010-07-28 02:04:09 +00001265 else
1266 {
1267 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1268 if (objc_class_type)
1269 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001270 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001271 ClangASTContext::AddObjCClassIVar (ast_context,
1272 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001273 name,
1274 field_type,
1275 access,
1276 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001277 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001278 }
1279 }
Chris Lattner24943d22010-06-08 16:52:24 +00001280 }
1281 return false;
1282}
1283
1284bool
1285ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1286{
1287 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1288}
1289
1290bool
1291ClangASTContext::FieldIsBitfield
1292(
1293 ASTContext *ast_context,
1294 FieldDecl* field,
1295 uint32_t& bitfield_bit_size
1296)
1297{
1298 if (ast_context == NULL || field == NULL)
1299 return false;
1300
1301 if (field->isBitField())
1302 {
1303 Expr* bit_width_expr = field->getBitWidth();
1304 if (bit_width_expr)
1305 {
1306 llvm::APSInt bit_width_apsint;
1307 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1308 {
1309 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1310 return true;
1311 }
1312 }
1313 }
1314 return false;
1315}
1316
1317bool
1318ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1319{
1320 if (record_decl == NULL)
1321 return false;
1322
1323 if (!record_decl->field_empty())
1324 return true;
1325
1326 // No fields, lets check this is a CXX record and check the base classes
1327 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1328 if (cxx_record_decl)
1329 {
1330 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1331 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1332 base_class != base_class_end;
1333 ++base_class)
1334 {
1335 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1336 if (RecordHasFields(base_class_decl))
1337 return true;
1338 }
1339 }
1340 return false;
1341}
1342
1343void
Greg Clayton462d4142010-09-29 01:12:09 +00001344ClangASTContext::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 +00001345{
1346 if (clang_qual_type)
1347 {
1348 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001349 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001350 if (clang_type)
1351 {
1352 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1353 if (record_type)
1354 {
1355 RecordDecl *record_decl = record_type->getDecl();
1356 if (record_decl)
1357 {
1358 uint32_t field_idx;
1359 RecordDecl::field_iterator field, field_end;
1360 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1361 field != field_end;
1362 ++field, ++field_idx)
1363 {
1364 // If no accessibility was assigned, assign the correct one
1365 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1366 field->setAccess ((AccessSpecifier)default_accessibility);
1367 }
1368 }
1369 }
1370 }
1371 }
1372}
1373
1374#pragma mark C++ Base Classes
1375
1376CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001377ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001378{
1379 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001380 return new CXXBaseSpecifier (SourceRange(),
1381 is_virtual,
1382 base_of_class,
1383 ConvertAccessTypeToAccessSpecifier (access),
1384 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001385 return NULL;
1386}
1387
Greg Claytone9d0df42010-07-02 01:29:13 +00001388void
1389ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1390{
1391 for (unsigned i=0; i<num_base_classes; ++i)
1392 {
1393 delete base_classes[i];
1394 base_classes[i] = NULL;
1395 }
1396}
1397
Chris Lattner24943d22010-06-08 16:52:24 +00001398bool
Greg Clayton462d4142010-09-29 01:12:09 +00001399ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001400{
1401 if (class_clang_type)
1402 {
Greg Clayton1674b122010-07-21 22:12:05 +00001403 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001404 if (clang_type)
1405 {
1406 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1407 if (record_type)
1408 {
1409 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1410 if (cxx_record_decl)
1411 {
Chris Lattner24943d22010-06-08 16:52:24 +00001412 cxx_record_decl->setBases(base_classes, num_base_classes);
1413 return true;
1414 }
1415 }
1416 }
1417 }
1418 return false;
1419}
Greg Clayton84f80752010-07-22 18:30:50 +00001420#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001421
Greg Clayton462d4142010-09-29 01:12:09 +00001422clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001423ClangASTContext::CreateObjCClass
1424(
1425 const char *name,
1426 DeclContext *decl_ctx,
1427 bool isForwardDecl,
1428 bool isInternal
1429)
1430{
1431 ASTContext *ast_context = getASTContext();
1432 assert (ast_context != NULL);
1433 assert (name && name[0]);
1434 if (decl_ctx == NULL)
1435 decl_ctx = ast_context->getTranslationUnitDecl();
1436
1437 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1438 // we will need to update this code. I was told to currently always use
1439 // the CXXRecordDecl class since we often don't know from debug information
1440 // if something is struct or a class, so we default to always use the more
1441 // complete definition just in case.
1442 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1443 decl_ctx,
1444 SourceLocation(),
1445 &ast_context->Idents.get(name),
1446 SourceLocation(),
1447 isForwardDecl,
1448 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001449
1450 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001451}
1452
1453bool
Greg Clayton462d4142010-09-29 01:12:09 +00001454ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001455{
1456 if (class_opaque_type && super_opaque_type)
1457 {
1458 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1459 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1460 clang::Type *class_type = class_qual_type.getTypePtr();
1461 clang::Type *super_type = super_qual_type.getTypePtr();
1462 if (class_type && super_type)
1463 {
1464 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1465 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1466 if (objc_class_type && objc_super_type)
1467 {
1468 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1469 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1470 if (class_interface_decl && super_interface_decl)
1471 {
1472 class_interface_decl->setSuperClass(super_interface_decl);
1473 return true;
1474 }
1475 }
1476 }
1477 }
1478 return false;
1479}
1480
1481
1482bool
1483ClangASTContext::AddObjCClassIVar
1484(
Greg Clayton462d4142010-09-29 01:12:09 +00001485 ASTContext *ast_context,
1486 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001487 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001488 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001489 AccessType access,
1490 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001491 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001492)
1493{
1494 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1495 return false;
1496
Sean Callanan60a0ced2010-09-16 20:01:08 +00001497 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001498
1499 assert (ast_context != NULL);
1500 assert (identifier_table != NULL);
1501
1502 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1503
1504 clang::Type *class_type = class_qual_type.getTypePtr();
1505 if (class_type)
1506 {
1507 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1508
1509 if (objc_class_type)
1510 {
1511 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1512
1513 if (class_interface_decl)
1514 {
1515 clang::Expr *bit_width = NULL;
1516 if (bitfield_bit_size != 0)
1517 {
1518 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001519 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001520 }
1521
Greg Clayton9488b742010-07-28 02:04:09 +00001522 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1523 class_interface_decl,
1524 SourceLocation(),
1525 &identifier_table->get(name), // Identifier
1526 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1527 NULL, // TypeSourceInfo *
1528 ConvertAccessTypeToObjCIvarAccessControl (access),
1529 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001530 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001531
1532 if (field)
1533 {
1534 class_interface_decl->addDecl(field);
1535 return true;
1536 }
Greg Clayton84f80752010-07-22 18:30:50 +00001537 }
1538 }
1539 }
1540 return false;
1541}
Chris Lattner24943d22010-06-08 16:52:24 +00001542
Greg Clayton9488b742010-07-28 02:04:09 +00001543
1544bool
Greg Clayton462d4142010-09-29 01:12:09 +00001545ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001546{
1547 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1548
1549 clang::Type *class_type = class_qual_type.getTypePtr();
1550 if (class_type)
1551 {
1552 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1553
1554 if (objc_class_type)
1555 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1556 }
1557 return false;
1558}
1559
1560bool
1561ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1562{
1563 while (class_interface_decl)
1564 {
1565 if (class_interface_decl->ivar_size() > 0)
1566 return true;
1567
1568 if (check_superclass)
1569 class_interface_decl = class_interface_decl->getSuperClass();
1570 else
1571 break;
1572 }
1573 return false;
1574}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001575
Greg Clayton462d4142010-09-29 01:12:09 +00001576ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001577ClangASTContext::AddMethodToObjCObjectType
1578(
Greg Clayton462d4142010-09-29 01:12:09 +00001579 ASTContext *ast_context,
1580 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001581 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001582 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001583 lldb::AccessType access
1584)
1585{
1586 if (class_opaque_type == NULL || method_opaque_type == NULL)
1587 return NULL;
1588
1589 IdentifierTable *identifier_table = &ast_context->Idents;
1590
1591 assert (ast_context != NULL);
1592 assert (identifier_table != NULL);
1593
1594 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1595
1596 clang::Type *class_type = class_qual_type.getTypePtr();
1597 if (class_type == NULL)
1598 return NULL;
1599
1600 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1601
1602 if (objc_class_type == NULL)
1603 return NULL;
1604
1605 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1606
1607 if (class_interface_decl == NULL)
1608 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001609
Greg Clayton1d8173f2010-09-24 05:15:53 +00001610 const char *selector_start = ::strchr (name, ' ');
1611 if (selector_start == NULL)
1612 return NULL;
1613
1614 selector_start++;
1615 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1616 return NULL;
1617 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1618
Greg Claytonad60bf42010-10-12 02:24:53 +00001619 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001620 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001621 //printf ("name = '%s'\n", name);
1622
1623 unsigned num_selectors_with_args = 0;
1624 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001625 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001626 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001627 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001628 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001629 bool has_arg = (start[len] == ':');
1630 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001631 ++num_selectors_with_args;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001632 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001633 if (has_arg)
1634 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001635 }
1636
1637
1638 if (selector_idents.size() == 0)
1639 return 0;
1640
Greg Claytonad60bf42010-10-12 02:24:53 +00001641 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001642 selector_idents.data());
1643
1644 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1645
1646 // Populate the method decl with parameter decls
1647 clang::Type *method_type(method_qual_type.getTypePtr());
1648
1649 if (method_type == NULL)
1650 return NULL;
1651
1652 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1653
1654 if (!method_function_prototype)
1655 return NULL;
1656
1657
1658 bool is_variadic = false;
1659 bool is_synthesized = false;
1660 bool is_defined = false;
1661 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1662
1663 const unsigned num_args = method_function_prototype->getNumArgs();
1664
1665 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1666 SourceLocation(), // beginLoc,
1667 SourceLocation(), // endLoc,
1668 method_selector,
1669 method_function_prototype->getResultType(),
1670 NULL, // TypeSourceInfo *ResultTInfo,
1671 GetDeclContextForType (class_opaque_type),
1672 name[0] == '-',
1673 is_variadic,
1674 is_synthesized,
1675 is_defined,
1676 imp_control,
1677 num_args);
1678
1679
1680 if (objc_method_decl == NULL)
1681 return NULL;
1682
1683 if (num_args > 0)
1684 {
1685 llvm::SmallVector<ParmVarDecl *, 12> params;
1686
1687 for (int param_index = 0; param_index < num_args; ++param_index)
1688 {
1689 params.push_back (ParmVarDecl::Create (*ast_context,
1690 objc_method_decl,
1691 SourceLocation(),
1692 NULL, // anonymous
1693 method_function_prototype->getArgType(param_index),
1694 NULL,
1695 SC_Auto,
1696 SC_Auto,
1697 NULL));
1698 }
1699
1700 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1701 }
1702
1703 class_interface_decl->addDecl (objc_method_decl);
1704
1705
1706 return objc_method_decl;
1707}
1708
1709
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001710uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001711ClangASTContext::GetTypeInfo
1712(
1713 clang_type_t clang_type,
1714 clang::ASTContext *ast_context,
1715 clang_type_t *pointee_or_element_clang_type
1716)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001717{
1718 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001719 return 0;
1720
1721 if (pointee_or_element_clang_type)
1722 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001723
1724 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1725
1726 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1727 switch (type_class)
1728 {
Sean Callanan04325062010-10-25 00:29:48 +00001729 case clang::Type::Builtin:
1730 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1731 {
Sean Callanan04325062010-10-25 00:29:48 +00001732 case clang::BuiltinType::ObjCId:
1733 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001734 if (ast_context && pointee_or_element_clang_type)
1735 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001736 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001737
1738 default:
1739 break;
Sean Callanan04325062010-10-25 00:29:48 +00001740 }
1741 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001742
1743 case clang::Type::BlockPointer:
1744 if (pointee_or_element_clang_type)
1745 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1746 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1747
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001748 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001749
1750 case clang::Type::ConstantArray:
1751 case clang::Type::DependentSizedArray:
1752 case clang::Type::IncompleteArray:
1753 case clang::Type::VariableArray:
1754 if (pointee_or_element_clang_type)
1755 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1756 return eTypeHasChildren | eTypeIsArray;
1757
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001758 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001759 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1760 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1761 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001762
1763 case clang::Type::Enum:
1764 if (pointee_or_element_clang_type)
1765 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1766 return eTypeIsEnumeration | eTypeHasValue;
1767
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001768 case clang::Type::Elaborated: return 0;
1769 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1770 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1771 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001772 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001773
1774 case clang::Type::LValueReference:
1775 case clang::Type::RValueReference:
1776 if (pointee_or_element_clang_type)
1777 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1778 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1779
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001780 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001781
1782 case clang::Type::ObjCObjectPointer:
1783 if (pointee_or_element_clang_type)
1784 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1785 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1786
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001787 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1788 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001789
1790 case clang::Type::Pointer:
1791 if (pointee_or_element_clang_type)
1792 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1793 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1794
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001795 case clang::Type::Record:
1796 if (qual_type->getAsCXXRecordDecl())
1797 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1798 else
1799 return eTypeHasChildren | eTypeIsStructUnion;
1800 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001801 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1802 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1803 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001804
1805 case clang::Type::Typedef:
1806 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1807 ast_context,
1808 pointee_or_element_clang_type);
1809
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001810 case clang::Type::TypeOfExpr: return 0;
1811 case clang::Type::TypeOf: return 0;
1812 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001813 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1814 default: return 0;
1815 }
1816 return 0;
1817}
1818
Greg Clayton9488b742010-07-28 02:04:09 +00001819
Chris Lattner24943d22010-06-08 16:52:24 +00001820#pragma mark Aggregate Types
1821
1822bool
Greg Clayton462d4142010-09-29 01:12:09 +00001823ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001824{
1825 if (clang_type == NULL)
1826 return false;
1827
1828 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1829
Greg Clayton03e0f972010-09-13 03:32:57 +00001830 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1831 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001832 {
Greg Clayton1674b122010-07-21 22:12:05 +00001833 case clang::Type::IncompleteArray:
1834 case clang::Type::VariableArray:
1835 case clang::Type::ConstantArray:
1836 case clang::Type::ExtVector:
1837 case clang::Type::Vector:
1838 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001839 case clang::Type::ObjCObject:
1840 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001841 return true;
1842
Greg Clayton1674b122010-07-21 22:12:05 +00001843 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001844 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1845
1846 default:
1847 break;
1848 }
1849 // The clang type does have a value
1850 return false;
1851}
1852
1853uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001854ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001855{
1856 if (clang_qual_type == NULL)
1857 return 0;
1858
1859 uint32_t num_children = 0;
1860 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001861 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1862 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001863 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001864 case clang::Type::Builtin:
1865 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1866 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001867 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001868 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001869 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001870 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001871
1872 default:
1873 break;
1874 }
1875 break;
1876
Greg Clayton1674b122010-07-21 22:12:05 +00001877 case clang::Type::Record:
Greg Clayton53d287b2010-11-11 02:14:53 +00001878 if (ClangASTType::IsDefined (clang_qual_type))
Chris Lattner24943d22010-06-08 16:52:24 +00001879 {
1880 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1881 const RecordDecl *record_decl = record_type->getDecl();
1882 assert(record_decl);
1883 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1884 if (cxx_record_decl)
1885 {
1886 if (omit_empty_base_classes)
1887 {
1888 // Check each base classes to see if it or any of its
1889 // base classes contain any fields. This can help
1890 // limit the noise in variable views by not having to
1891 // show base classes that contain no members.
1892 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1893 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1894 base_class != base_class_end;
1895 ++base_class)
1896 {
1897 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1898
1899 // Skip empty base classes
1900 if (RecordHasFields(base_class_decl) == false)
1901 continue;
1902
1903 num_children++;
1904 }
1905 }
1906 else
1907 {
1908 // Include all base classes
1909 num_children += cxx_record_decl->getNumBases();
1910 }
1911
1912 }
1913 RecordDecl::field_iterator field, field_end;
1914 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1915 ++num_children;
1916 }
1917 break;
1918
Greg Clayton9488b742010-07-28 02:04:09 +00001919 case clang::Type::ObjCObject:
1920 case clang::Type::ObjCInterface:
1921 {
1922 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1923 assert (objc_class_type);
1924 if (objc_class_type)
1925 {
1926 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1927
1928 if (class_interface_decl)
1929 {
1930
1931 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1932 if (superclass_interface_decl)
1933 {
1934 if (omit_empty_base_classes)
1935 {
1936 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1937 ++num_children;
1938 }
1939 else
1940 ++num_children;
1941 }
1942
1943 num_children += class_interface_decl->ivar_size();
1944 }
1945 }
1946 }
1947 break;
1948
1949 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001950 {
1951 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1952 QualType pointee_type = pointer_type->getPointeeType();
1953 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1954 omit_empty_base_classes);
1955 // If this type points to a simple type, then it has 1 child
1956 if (num_pointee_children == 0)
1957 num_children = 1;
1958 else
1959 num_children = num_pointee_children;
1960 }
1961 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001962
Greg Clayton1674b122010-07-21 22:12:05 +00001963 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001964 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1965 break;
1966
Greg Clayton1674b122010-07-21 22:12:05 +00001967 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001968 {
1969 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1970 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001971 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1972 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001973 // If this type points to a simple type, then it has 1 child
1974 if (num_pointee_children == 0)
1975 num_children = 1;
1976 else
1977 num_children = num_pointee_children;
1978 }
1979 break;
1980
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001981 case clang::Type::LValueReference:
1982 case clang::Type::RValueReference:
1983 {
1984 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1985 QualType pointee_type = reference_type->getPointeeType();
1986 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1987 omit_empty_base_classes);
1988 // If this type points to a simple type, then it has 1 child
1989 if (num_pointee_children == 0)
1990 num_children = 1;
1991 else
1992 num_children = num_pointee_children;
1993 }
1994 break;
1995
1996
Greg Clayton1674b122010-07-21 22:12:05 +00001997 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001998 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1999 break;
2000
2001 default:
2002 break;
2003 }
2004 return num_children;
2005}
2006
2007
Greg Clayton462d4142010-09-29 01:12:09 +00002008clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002009ClangASTContext::GetChildClangTypeAtIndex
2010(
2011 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002012 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002013 uint32_t idx,
2014 bool transparent_pointers,
2015 bool omit_empty_base_classes,
2016 std::string& child_name,
2017 uint32_t &child_byte_size,
2018 int32_t &child_byte_offset,
2019 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002020 uint32_t &child_bitfield_bit_offset,
2021 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002022)
2023{
2024 if (parent_clang_type)
2025
2026 return GetChildClangTypeAtIndex (getASTContext(),
2027 parent_name,
2028 parent_clang_type,
2029 idx,
2030 transparent_pointers,
2031 omit_empty_base_classes,
2032 child_name,
2033 child_byte_size,
2034 child_byte_offset,
2035 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002036 child_bitfield_bit_offset,
2037 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002038 return NULL;
2039}
2040
Greg Clayton462d4142010-09-29 01:12:09 +00002041clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002042ClangASTContext::GetChildClangTypeAtIndex
2043(
2044 ASTContext *ast_context,
2045 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002046 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002047 uint32_t idx,
2048 bool transparent_pointers,
2049 bool omit_empty_base_classes,
2050 std::string& child_name,
2051 uint32_t &child_byte_size,
2052 int32_t &child_byte_offset,
2053 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002054 uint32_t &child_bitfield_bit_offset,
2055 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002056)
2057{
2058 if (parent_clang_type == NULL)
2059 return NULL;
2060
2061 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2062 {
2063 uint32_t bit_offset;
2064 child_bitfield_bit_size = 0;
2065 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002066 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002067 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002068 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2069 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002070 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002071 case clang::Type::Builtin:
2072 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2073 {
2074 case clang::BuiltinType::ObjCId:
2075 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002076 child_name = "isa";
2077 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002078 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2079
Greg Clayton960d6a42010-08-03 00:35:52 +00002080 default:
2081 break;
2082 }
2083 break;
2084
2085
Greg Clayton1674b122010-07-21 22:12:05 +00002086 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002087 {
2088 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2089 const RecordDecl *record_decl = record_type->getDecl();
2090 assert(record_decl);
2091 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2092 uint32_t child_idx = 0;
2093
2094 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2095 if (cxx_record_decl)
2096 {
2097 // We might have base classes to print out first
2098 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2099 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2100 base_class != base_class_end;
2101 ++base_class)
2102 {
2103 const CXXRecordDecl *base_class_decl = NULL;
2104
2105 // Skip empty base classes
2106 if (omit_empty_base_classes)
2107 {
2108 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2109 if (RecordHasFields(base_class_decl) == false)
2110 continue;
2111 }
2112
2113 if (idx == child_idx)
2114 {
2115 if (base_class_decl == NULL)
2116 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2117
2118
2119 if (base_class->isVirtual())
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002120 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002121 else
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002122 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002123
2124 // Base classes should be a multiple of 8 bits in size
2125 assert (bit_offset % 8 == 0);
2126 child_byte_offset = bit_offset/8;
2127 std::string base_class_type_name(base_class->getType().getAsString());
2128
2129 child_name.assign(base_class_type_name.c_str());
2130
2131 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2132
2133 // Base classes biut sizes should be a multiple of 8 bits in size
2134 assert (clang_type_info_bit_size % 8 == 0);
2135 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002136 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002137 return base_class->getType().getAsOpaquePtr();
2138 }
2139 // We don't increment the child index in the for loop since we might
2140 // be skipping empty base classes
2141 ++child_idx;
2142 }
2143 }
Chris Lattner24943d22010-06-08 16:52:24 +00002144 // Make sure index is in range...
2145 uint32_t field_idx = 0;
2146 RecordDecl::field_iterator field, field_end;
2147 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2148 {
2149 if (idx == child_idx)
2150 {
2151 // Print the member type if requested
2152 // Print the member name and equal sign
2153 child_name.assign(field->getNameAsString().c_str());
2154
2155 // Figure out the type byte size (field_type_info.first) and
2156 // alignment (field_type_info.second) from the AST context.
2157 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002158 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002159
2160 child_byte_size = field_type_info.first / 8;
2161
2162 // Figure out the field offset within the current struct/union/class type
2163 bit_offset = record_layout.getFieldOffset (field_idx);
2164 child_byte_offset = bit_offset / 8;
2165 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2166 child_bitfield_bit_offset = bit_offset % 8;
2167
2168 return field->getType().getAsOpaquePtr();
2169 }
2170 }
2171 }
2172 break;
2173
Greg Clayton9488b742010-07-28 02:04:09 +00002174 case clang::Type::ObjCObject:
2175 case clang::Type::ObjCInterface:
2176 {
2177 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2178 assert (objc_class_type);
2179 if (objc_class_type)
2180 {
2181 uint32_t child_idx = 0;
2182 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2183
2184 if (class_interface_decl)
2185 {
2186
2187 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2188 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2189 if (superclass_interface_decl)
2190 {
2191 if (omit_empty_base_classes)
2192 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002193 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002194 {
2195 if (idx == 0)
2196 {
2197 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2198
2199
2200 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2201
2202 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2203
2204 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002205 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002206 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002207
2208 return ivar_qual_type.getAsOpaquePtr();
2209 }
2210
2211 ++child_idx;
2212 }
2213 }
2214 else
2215 ++child_idx;
2216 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002217
2218 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002219
2220 if (idx < (child_idx + class_interface_decl->ivar_size()))
2221 {
2222 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2223
2224 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2225 {
2226 if (child_idx == idx)
2227 {
2228 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2229
2230 QualType ivar_qual_type(ivar_decl->getType());
2231
2232 child_name.assign(ivar_decl->getNameAsString().c_str());
2233
2234 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2235
2236 child_byte_size = ivar_type_info.first / 8;
2237
2238 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002239 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002240 child_byte_offset = bit_offset / 8;
2241
2242 return ivar_qual_type.getAsOpaquePtr();
2243 }
2244 ++child_idx;
2245 }
2246 }
2247 }
2248 }
2249 }
2250 break;
2251
2252 case clang::Type::ObjCObjectPointer:
2253 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002254 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2255 QualType pointee_type = pointer_type->getPointeeType();
2256
2257 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2258 {
2259 return GetChildClangTypeAtIndex (ast_context,
2260 parent_name,
2261 pointer_type->getPointeeType().getAsOpaquePtr(),
2262 idx,
2263 transparent_pointers,
2264 omit_empty_base_classes,
2265 child_name,
2266 child_byte_size,
2267 child_byte_offset,
2268 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002269 child_bitfield_bit_offset,
2270 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002271 }
2272 else
2273 {
2274 if (parent_name)
2275 {
2276 child_name.assign(1, '*');
2277 child_name += parent_name;
2278 }
2279
2280 // We have a pointer to an simple type
2281 if (idx == 0)
2282 {
2283 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2284 assert(clang_type_info.first % 8 == 0);
2285 child_byte_size = clang_type_info.first / 8;
2286 child_byte_offset = 0;
2287 return pointee_type.getAsOpaquePtr();
2288 }
2289 }
Greg Clayton9488b742010-07-28 02:04:09 +00002290 }
2291 break;
2292
Greg Clayton1674b122010-07-21 22:12:05 +00002293 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002294 {
2295 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2296 const uint64_t element_count = array->getSize().getLimitedValue();
2297
2298 if (idx < element_count)
2299 {
2300 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2301
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002302 char element_name[64];
2303 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002304
2305 child_name.assign(element_name);
2306 assert(field_type_info.first % 8 == 0);
2307 child_byte_size = field_type_info.first / 8;
2308 child_byte_offset = idx * child_byte_size;
2309 return array->getElementType().getAsOpaquePtr();
2310 }
2311 }
2312 break;
2313
Greg Clayton1674b122010-07-21 22:12:05 +00002314 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002315 {
2316 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2317 QualType pointee_type = pointer_type->getPointeeType();
2318
2319 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2320 {
2321 return GetChildClangTypeAtIndex (ast_context,
2322 parent_name,
2323 pointer_type->getPointeeType().getAsOpaquePtr(),
2324 idx,
2325 transparent_pointers,
2326 omit_empty_base_classes,
2327 child_name,
2328 child_byte_size,
2329 child_byte_offset,
2330 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002331 child_bitfield_bit_offset,
2332 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002333 }
2334 else
2335 {
2336 if (parent_name)
2337 {
2338 child_name.assign(1, '*');
2339 child_name += parent_name;
2340 }
2341
2342 // We have a pointer to an simple type
2343 if (idx == 0)
2344 {
2345 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2346 assert(clang_type_info.first % 8 == 0);
2347 child_byte_size = clang_type_info.first / 8;
2348 child_byte_offset = 0;
2349 return pointee_type.getAsOpaquePtr();
2350 }
2351 }
2352 }
2353 break;
2354
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002355 case clang::Type::LValueReference:
2356 case clang::Type::RValueReference:
2357 {
2358 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2359 QualType pointee_type(reference_type->getPointeeType());
2360 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2361 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2362 {
2363 return GetChildClangTypeAtIndex (ast_context,
2364 parent_name,
2365 pointee_clang_type,
2366 idx,
2367 transparent_pointers,
2368 omit_empty_base_classes,
2369 child_name,
2370 child_byte_size,
2371 child_byte_offset,
2372 child_bitfield_bit_size,
2373 child_bitfield_bit_offset,
2374 child_is_base_class);
2375 }
2376 else
2377 {
2378 if (parent_name)
2379 {
2380 child_name.assign(1, '&');
2381 child_name += parent_name;
2382 }
2383
2384 // We have a pointer to an simple type
2385 if (idx == 0)
2386 {
2387 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2388 assert(clang_type_info.first % 8 == 0);
2389 child_byte_size = clang_type_info.first / 8;
2390 child_byte_offset = 0;
2391 return pointee_type.getAsOpaquePtr();
2392 }
2393 }
2394 }
2395 break;
2396
Greg Clayton1674b122010-07-21 22:12:05 +00002397 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002398 return GetChildClangTypeAtIndex (ast_context,
2399 parent_name,
2400 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2401 idx,
2402 transparent_pointers,
2403 omit_empty_base_classes,
2404 child_name,
2405 child_byte_size,
2406 child_byte_offset,
2407 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002408 child_bitfield_bit_offset,
2409 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002410 break;
2411
2412 default:
2413 break;
2414 }
2415 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002416 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002417}
2418
2419static inline bool
2420BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2421{
2422 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2423}
2424
2425static uint32_t
2426GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2427{
2428 uint32_t num_bases = 0;
2429 if (cxx_record_decl)
2430 {
2431 if (omit_empty_base_classes)
2432 {
2433 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2434 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2435 base_class != base_class_end;
2436 ++base_class)
2437 {
2438 // Skip empty base classes
2439 if (omit_empty_base_classes)
2440 {
2441 if (BaseSpecifierIsEmpty (base_class))
2442 continue;
2443 }
2444 ++num_bases;
2445 }
2446 }
2447 else
2448 num_bases = cxx_record_decl->getNumBases();
2449 }
2450 return num_bases;
2451}
2452
2453
2454static uint32_t
2455GetIndexForRecordBase
2456(
2457 const RecordDecl *record_decl,
2458 const CXXBaseSpecifier *base_spec,
2459 bool omit_empty_base_classes
2460)
2461{
2462 uint32_t child_idx = 0;
2463
2464 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2465
2466// const char *super_name = record_decl->getNameAsCString();
2467// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2468// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2469//
2470 if (cxx_record_decl)
2471 {
2472 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2473 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2474 base_class != base_class_end;
2475 ++base_class)
2476 {
2477 if (omit_empty_base_classes)
2478 {
2479 if (BaseSpecifierIsEmpty (base_class))
2480 continue;
2481 }
2482
2483// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2484// child_idx,
2485// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2486//
2487//
2488 if (base_class == base_spec)
2489 return child_idx;
2490 ++child_idx;
2491 }
2492 }
2493
2494 return UINT32_MAX;
2495}
2496
2497
2498static uint32_t
2499GetIndexForRecordChild
2500(
2501 const RecordDecl *record_decl,
2502 NamedDecl *canonical_decl,
2503 bool omit_empty_base_classes
2504)
2505{
2506 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2507
2508// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2509//
2510//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2511// if (cxx_record_decl)
2512// {
2513// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2514// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2515// base_class != base_class_end;
2516// ++base_class)
2517// {
2518// if (omit_empty_base_classes)
2519// {
2520// if (BaseSpecifierIsEmpty (base_class))
2521// continue;
2522// }
2523//
2524//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2525//// record_decl->getNameAsCString(),
2526//// canonical_decl->getNameAsCString(),
2527//// child_idx,
2528//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2529//
2530//
2531// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2532// if (curr_base_class_decl == canonical_decl)
2533// {
2534// return child_idx;
2535// }
2536// ++child_idx;
2537// }
2538// }
2539//
2540// const uint32_t num_bases = child_idx;
2541 RecordDecl::field_iterator field, field_end;
2542 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2543 field != field_end;
2544 ++field, ++child_idx)
2545 {
2546// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2547// record_decl->getNameAsCString(),
2548// canonical_decl->getNameAsCString(),
2549// child_idx - num_bases,
2550// field->getNameAsCString());
2551
2552 if (field->getCanonicalDecl() == canonical_decl)
2553 return child_idx;
2554 }
2555
2556 return UINT32_MAX;
2557}
2558
2559// Look for a child member (doesn't include base classes, but it does include
2560// their members) in the type hierarchy. Returns an index path into "clang_type"
2561// on how to reach the appropriate member.
2562//
2563// class A
2564// {
2565// public:
2566// int m_a;
2567// int m_b;
2568// };
2569//
2570// class B
2571// {
2572// };
2573//
2574// class C :
2575// public B,
2576// public A
2577// {
2578// };
2579//
2580// If we have a clang type that describes "class C", and we wanted to looked
2581// "m_b" in it:
2582//
2583// With omit_empty_base_classes == false we would get an integer array back with:
2584// { 1, 1 }
2585// The first index 1 is the child index for "class A" within class C
2586// The second index 1 is the child index for "m_b" within class A
2587//
2588// With omit_empty_base_classes == true we would get an integer array back with:
2589// { 0, 1 }
2590// 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)
2591// The second index 1 is the child index for "m_b" within class A
2592
2593size_t
2594ClangASTContext::GetIndexOfChildMemberWithName
2595(
2596 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002597 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002598 const char *name,
2599 bool omit_empty_base_classes,
2600 std::vector<uint32_t>& child_indexes
2601)
2602{
2603 if (clang_type && name && name[0])
2604 {
2605 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002606 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2607 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002608 {
Greg Clayton1674b122010-07-21 22:12:05 +00002609 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002610 {
2611 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2612 const RecordDecl *record_decl = record_type->getDecl();
2613
2614 assert(record_decl);
2615 uint32_t child_idx = 0;
2616
2617 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2618
2619 // Try and find a field that matches NAME
2620 RecordDecl::field_iterator field, field_end;
2621 StringRef name_sref(name);
2622 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2623 field != field_end;
2624 ++field, ++child_idx)
2625 {
2626 if (field->getName().equals (name_sref))
2627 {
2628 // We have to add on the number of base classes to this index!
2629 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2630 return child_indexes.size();
2631 }
2632 }
2633
2634 if (cxx_record_decl)
2635 {
2636 const RecordDecl *parent_record_decl = cxx_record_decl;
2637
2638 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2639
2640 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2641 // Didn't find things easily, lets let clang do its thang...
2642 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2643 DeclarationName decl_name(&ident_ref);
2644
2645 CXXBasePaths paths;
2646 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2647 decl_name.getAsOpaquePtr(),
2648 paths))
2649 {
Chris Lattner24943d22010-06-08 16:52:24 +00002650 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2651 for (path = paths.begin(); path != path_end; ++path)
2652 {
2653 const size_t num_path_elements = path->size();
2654 for (size_t e=0; e<num_path_elements; ++e)
2655 {
2656 CXXBasePathElement elem = (*path)[e];
2657
2658 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2659 if (child_idx == UINT32_MAX)
2660 {
2661 child_indexes.clear();
2662 return 0;
2663 }
2664 else
2665 {
2666 child_indexes.push_back (child_idx);
2667 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2668 }
2669 }
2670 DeclContext::lookup_iterator named_decl_pos;
2671 for (named_decl_pos = path->Decls.first;
2672 named_decl_pos != path->Decls.second && parent_record_decl;
2673 ++named_decl_pos)
2674 {
2675 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2676
2677 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2678 if (child_idx == UINT32_MAX)
2679 {
2680 child_indexes.clear();
2681 return 0;
2682 }
2683 else
2684 {
2685 child_indexes.push_back (child_idx);
2686 }
2687 }
2688 }
2689 return child_indexes.size();
2690 }
2691 }
2692
2693 }
2694 break;
2695
Greg Clayton9488b742010-07-28 02:04:09 +00002696 case clang::Type::ObjCObject:
2697 case clang::Type::ObjCInterface:
2698 {
2699 StringRef name_sref(name);
2700 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2701 assert (objc_class_type);
2702 if (objc_class_type)
2703 {
2704 uint32_t child_idx = 0;
2705 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2706
2707 if (class_interface_decl)
2708 {
2709 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2710 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2711
Greg Clayton823533e2010-09-18 02:11:07 +00002712 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002713 {
2714 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2715
2716 if (ivar_decl->getName().equals (name_sref))
2717 {
2718 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2719 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2720 ++child_idx;
2721
2722 child_indexes.push_back (child_idx);
2723 return child_indexes.size();
2724 }
2725 }
2726
2727 if (superclass_interface_decl)
2728 {
2729 // The super class index is always zero for ObjC classes,
2730 // so we push it onto the child indexes in case we find
2731 // an ivar in our superclass...
2732 child_indexes.push_back (0);
2733
2734 if (GetIndexOfChildMemberWithName (ast_context,
2735 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2736 name,
2737 omit_empty_base_classes,
2738 child_indexes))
2739 {
2740 // We did find an ivar in a superclass so just
2741 // return the results!
2742 return child_indexes.size();
2743 }
2744
2745 // We didn't find an ivar matching "name" in our
2746 // superclass, pop the superclass zero index that
2747 // we pushed on above.
2748 child_indexes.pop_back();
2749 }
2750 }
2751 }
2752 }
2753 break;
2754
2755 case clang::Type::ObjCObjectPointer:
2756 {
2757 return GetIndexOfChildMemberWithName (ast_context,
2758 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2759 name,
2760 omit_empty_base_classes,
2761 child_indexes);
2762 }
2763 break;
2764
2765
Greg Clayton1674b122010-07-21 22:12:05 +00002766 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002767 {
2768// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2769// const uint64_t element_count = array->getSize().getLimitedValue();
2770//
2771// if (idx < element_count)
2772// {
2773// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2774//
2775// char element_name[32];
2776// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2777//
2778// child_name.assign(element_name);
2779// assert(field_type_info.first % 8 == 0);
2780// child_byte_size = field_type_info.first / 8;
2781// child_byte_offset = idx * child_byte_size;
2782// return array->getElementType().getAsOpaquePtr();
2783// }
2784 }
2785 break;
2786
Greg Clayton1674b122010-07-21 22:12:05 +00002787// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002788// {
2789// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2790// QualType pointee_type = mem_ptr_type->getPointeeType();
2791//
2792// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2793// {
2794// return GetIndexOfChildWithName (ast_context,
2795// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2796// name);
2797// }
2798// }
2799// break;
2800//
Greg Clayton1674b122010-07-21 22:12:05 +00002801 case clang::Type::LValueReference:
2802 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002803 {
2804 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2805 QualType pointee_type = reference_type->getPointeeType();
2806
2807 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2808 {
2809 return GetIndexOfChildMemberWithName (ast_context,
2810 reference_type->getPointeeType().getAsOpaquePtr(),
2811 name,
2812 omit_empty_base_classes,
2813 child_indexes);
2814 }
2815 }
2816 break;
2817
Greg Clayton1674b122010-07-21 22:12:05 +00002818 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002819 {
2820 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2821 QualType pointee_type = pointer_type->getPointeeType();
2822
2823 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2824 {
2825 return GetIndexOfChildMemberWithName (ast_context,
2826 pointer_type->getPointeeType().getAsOpaquePtr(),
2827 name,
2828 omit_empty_base_classes,
2829 child_indexes);
2830 }
2831 else
2832 {
2833// if (parent_name)
2834// {
2835// child_name.assign(1, '*');
2836// child_name += parent_name;
2837// }
2838//
2839// // We have a pointer to an simple type
2840// if (idx == 0)
2841// {
2842// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2843// assert(clang_type_info.first % 8 == 0);
2844// child_byte_size = clang_type_info.first / 8;
2845// child_byte_offset = 0;
2846// return pointee_type.getAsOpaquePtr();
2847// }
2848 }
2849 }
2850 break;
2851
Greg Clayton1674b122010-07-21 22:12:05 +00002852 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002853 return GetIndexOfChildMemberWithName (ast_context,
2854 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2855 name,
2856 omit_empty_base_classes,
2857 child_indexes);
2858
2859 default:
2860 break;
2861 }
2862 }
2863 return 0;
2864}
2865
2866
2867// Get the index of the child of "clang_type" whose name matches. This function
2868// doesn't descend into the children, but only looks one level deep and name
2869// matches can include base class names.
2870
2871uint32_t
2872ClangASTContext::GetIndexOfChildWithName
2873(
2874 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002875 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002876 const char *name,
2877 bool omit_empty_base_classes
2878)
2879{
2880 if (clang_type && name && name[0])
2881 {
2882 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002883
Greg Clayton03e0f972010-09-13 03:32:57 +00002884 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002885
Greg Clayton03e0f972010-09-13 03:32:57 +00002886 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002887 {
Greg Clayton1674b122010-07-21 22:12:05 +00002888 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002889 {
2890 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2891 const RecordDecl *record_decl = record_type->getDecl();
2892
2893 assert(record_decl);
2894 uint32_t child_idx = 0;
2895
2896 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2897
2898 if (cxx_record_decl)
2899 {
2900 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2901 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2902 base_class != base_class_end;
2903 ++base_class)
2904 {
2905 // Skip empty base classes
2906 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2907 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2908 continue;
2909
2910 if (base_class->getType().getAsString().compare (name) == 0)
2911 return child_idx;
2912 ++child_idx;
2913 }
2914 }
2915
2916 // Try and find a field that matches NAME
2917 RecordDecl::field_iterator field, field_end;
2918 StringRef name_sref(name);
2919 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2920 field != field_end;
2921 ++field, ++child_idx)
2922 {
2923 if (field->getName().equals (name_sref))
2924 return child_idx;
2925 }
2926
2927 }
2928 break;
2929
Greg Clayton9488b742010-07-28 02:04:09 +00002930 case clang::Type::ObjCObject:
2931 case clang::Type::ObjCInterface:
2932 {
2933 StringRef name_sref(name);
2934 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2935 assert (objc_class_type);
2936 if (objc_class_type)
2937 {
2938 uint32_t child_idx = 0;
2939 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2940
2941 if (class_interface_decl)
2942 {
2943 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2944 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2945
2946 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2947 {
2948 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2949
2950 if (ivar_decl->getName().equals (name_sref))
2951 {
2952 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2953 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2954 ++child_idx;
2955
2956 return child_idx;
2957 }
2958 }
2959
2960 if (superclass_interface_decl)
2961 {
2962 if (superclass_interface_decl->getName().equals (name_sref))
2963 return 0;
2964 }
2965 }
2966 }
2967 }
2968 break;
2969
2970 case clang::Type::ObjCObjectPointer:
2971 {
2972 return GetIndexOfChildWithName (ast_context,
2973 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2974 name,
2975 omit_empty_base_classes);
2976 }
2977 break;
2978
Greg Clayton1674b122010-07-21 22:12:05 +00002979 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002980 {
2981// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2982// const uint64_t element_count = array->getSize().getLimitedValue();
2983//
2984// if (idx < element_count)
2985// {
2986// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2987//
2988// char element_name[32];
2989// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2990//
2991// child_name.assign(element_name);
2992// assert(field_type_info.first % 8 == 0);
2993// child_byte_size = field_type_info.first / 8;
2994// child_byte_offset = idx * child_byte_size;
2995// return array->getElementType().getAsOpaquePtr();
2996// }
2997 }
2998 break;
2999
Greg Clayton1674b122010-07-21 22:12:05 +00003000// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00003001// {
3002// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3003// QualType pointee_type = mem_ptr_type->getPointeeType();
3004//
3005// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3006// {
3007// return GetIndexOfChildWithName (ast_context,
3008// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3009// name);
3010// }
3011// }
3012// break;
3013//
Greg Clayton1674b122010-07-21 22:12:05 +00003014 case clang::Type::LValueReference:
3015 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003016 {
3017 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3018 QualType pointee_type = reference_type->getPointeeType();
3019
3020 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3021 {
3022 return GetIndexOfChildWithName (ast_context,
3023 reference_type->getPointeeType().getAsOpaquePtr(),
3024 name,
3025 omit_empty_base_classes);
3026 }
3027 }
3028 break;
3029
Greg Clayton1674b122010-07-21 22:12:05 +00003030 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003031 {
3032 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3033 QualType pointee_type = pointer_type->getPointeeType();
3034
3035 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3036 {
3037 return GetIndexOfChildWithName (ast_context,
3038 pointer_type->getPointeeType().getAsOpaquePtr(),
3039 name,
3040 omit_empty_base_classes);
3041 }
3042 else
3043 {
3044// if (parent_name)
3045// {
3046// child_name.assign(1, '*');
3047// child_name += parent_name;
3048// }
3049//
3050// // We have a pointer to an simple type
3051// if (idx == 0)
3052// {
3053// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3054// assert(clang_type_info.first % 8 == 0);
3055// child_byte_size = clang_type_info.first / 8;
3056// child_byte_offset = 0;
3057// return pointee_type.getAsOpaquePtr();
3058// }
3059 }
3060 }
3061 break;
3062
Greg Clayton1674b122010-07-21 22:12:05 +00003063 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003064 return GetIndexOfChildWithName (ast_context,
3065 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3066 name,
3067 omit_empty_base_classes);
3068
3069 default:
3070 break;
3071 }
3072 }
3073 return UINT32_MAX;
3074}
3075
3076#pragma mark TagType
3077
3078bool
Greg Clayton462d4142010-09-29 01:12:09 +00003079ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003080{
3081 if (tag_clang_type)
3082 {
3083 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003084 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003085 if (clang_type)
3086 {
3087 TagType *tag_type = dyn_cast<TagType>(clang_type);
3088 if (tag_type)
3089 {
3090 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3091 if (tag_decl)
3092 {
3093 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3094 return true;
3095 }
3096 }
3097 }
3098 }
3099 return false;
3100}
3101
3102
3103#pragma mark DeclContext Functions
3104
3105DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003106ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003107{
3108 if (clang_type == NULL)
3109 return NULL;
3110
3111 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003112 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3113 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003114 {
Greg Clayton9488b742010-07-28 02:04:09 +00003115 case clang::Type::FunctionNoProto: break;
3116 case clang::Type::FunctionProto: break;
3117 case clang::Type::IncompleteArray: break;
3118 case clang::Type::VariableArray: break;
3119 case clang::Type::ConstantArray: break;
3120 case clang::Type::ExtVector: break;
3121 case clang::Type::Vector: break;
3122 case clang::Type::Builtin: break;
3123 case clang::Type::BlockPointer: break;
3124 case clang::Type::Pointer: break;
3125 case clang::Type::LValueReference: break;
3126 case clang::Type::RValueReference: break;
3127 case clang::Type::MemberPointer: break;
3128 case clang::Type::Complex: break;
3129 case clang::Type::ObjCObject: break;
3130 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3131 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3132 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3133 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
3134 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003135
Greg Clayton9488b742010-07-28 02:04:09 +00003136 case clang::Type::TypeOfExpr: break;
3137 case clang::Type::TypeOf: break;
3138 case clang::Type::Decltype: break;
3139 //case clang::Type::QualifiedName: break;
3140 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003141 }
3142 // No DeclContext in this type...
3143 return NULL;
3144}
3145
3146#pragma mark Namespace Declarations
3147
3148NamespaceDecl *
3149ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3150{
3151 // TODO: Do something intelligent with the Declaration object passed in
3152 // like maybe filling in the SourceLocation with it...
3153 if (name)
3154 {
3155 ASTContext *ast_context = getASTContext();
3156 if (decl_ctx == NULL)
3157 decl_ctx = ast_context->getTranslationUnitDecl();
3158 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3159 }
3160 return NULL;
3161}
3162
3163
3164#pragma mark Function Types
3165
3166FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003167ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003168{
3169 if (name)
3170 {
3171 ASTContext *ast_context = getASTContext();
3172 assert (ast_context != NULL);
3173
3174 if (name && name[0])
3175 {
3176 return FunctionDecl::Create(*ast_context,
3177 ast_context->getTranslationUnitDecl(),
3178 SourceLocation(),
3179 DeclarationName (&ast_context->Idents.get(name)),
3180 QualType::getFromOpaquePtr(function_clang_type),
3181 NULL,
3182 (FunctionDecl::StorageClass)storage,
3183 (FunctionDecl::StorageClass)storage,
3184 is_inline);
3185 }
3186 else
3187 {
3188 return FunctionDecl::Create(*ast_context,
3189 ast_context->getTranslationUnitDecl(),
3190 SourceLocation(),
3191 DeclarationName (),
3192 QualType::getFromOpaquePtr(function_clang_type),
3193 NULL,
3194 (FunctionDecl::StorageClass)storage,
3195 (FunctionDecl::StorageClass)storage,
3196 is_inline);
3197 }
3198 }
3199 return NULL;
3200}
3201
Greg Clayton462d4142010-09-29 01:12:09 +00003202clang_type_t
3203ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3204 clang_type_t result_type,
3205 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003206 unsigned num_args,
3207 bool is_variadic,
3208 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003209{
Chris Lattner24943d22010-06-08 16:52:24 +00003210 assert (ast_context != NULL);
3211 std::vector<QualType> qual_type_args;
3212 for (unsigned i=0; i<num_args; ++i)
3213 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3214
3215 // TODO: Detect calling convention in DWARF?
3216 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003217 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003218 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003219 is_variadic,
3220 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003221 false, // hasExceptionSpec
3222 false, // hasAnyExceptionSpec,
3223 0, // NumExs
3224 0, // const QualType *ExArray
3225 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3226}
3227
3228ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003229ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003230{
3231 ASTContext *ast_context = getASTContext();
3232 assert (ast_context != NULL);
3233 return ParmVarDecl::Create(*ast_context,
3234 ast_context->getTranslationUnitDecl(),
3235 SourceLocation(),
3236 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003237 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003238 NULL,
3239 (VarDecl::StorageClass)storage,
3240 (VarDecl::StorageClass)storage,
3241 0);
3242}
3243
3244void
3245ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3246{
3247 if (function_decl)
3248 function_decl->setParams (params, num_params);
3249}
3250
3251
3252#pragma mark Array Types
3253
Greg Clayton462d4142010-09-29 01:12:09 +00003254clang_type_t
3255ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003256{
3257 if (element_type)
3258 {
3259 ASTContext *ast_context = getASTContext();
3260 assert (ast_context != NULL);
3261 llvm::APInt ap_element_count (64, element_count);
3262 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3263 ap_element_count,
3264 ArrayType::Normal,
3265 0).getAsOpaquePtr(); // ElemQuals
3266 }
3267 return NULL;
3268}
3269
3270
3271#pragma mark TagDecl
3272
3273bool
Greg Clayton462d4142010-09-29 01:12:09 +00003274ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003275{
3276 if (clang_type)
3277 {
3278 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003279 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003280 if (t)
3281 {
3282 TagType *tag_type = dyn_cast<TagType>(t);
3283 if (tag_type)
3284 {
3285 TagDecl *tag_decl = tag_type->getDecl();
3286 if (tag_decl)
3287 {
3288 tag_decl->startDefinition();
3289 return true;
3290 }
3291 }
3292 }
3293 }
3294 return false;
3295}
3296
3297bool
Greg Clayton462d4142010-09-29 01:12:09 +00003298ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003299{
3300 if (clang_type)
3301 {
3302 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00003303
3304 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3305
3306 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003307 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003308 cxx_record_decl->completeDefinition();
3309
3310 return true;
3311 }
3312
Sean Callanan04325062010-10-25 00:29:48 +00003313 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3314
3315 if (objc_class_type)
3316 {
3317 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3318
3319 class_interface_decl->setForwardDecl(false);
3320 }
3321
Greg Clayton55b6c532010-09-29 03:44:17 +00003322 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3323
3324 if (enum_type)
3325 {
3326 EnumDecl *enum_decl = enum_type->getDecl();
3327
3328 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003329 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003330 /// TODO This really needs to be fixed.
3331
3332 unsigned NumPositiveBits = 1;
3333 unsigned NumNegativeBits = 0;
3334
Greg Clayton48fbdf72010-10-12 04:29:14 +00003335 ASTContext *ast_context = getASTContext();
3336
3337 QualType promotion_qual_type;
3338 // If the enum integer type is less than an integer in bit width,
3339 // then we must promote it to an integer size.
3340 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3341 {
3342 if (enum_decl->getIntegerType()->isSignedIntegerType())
3343 promotion_qual_type = ast_context->IntTy;
3344 else
3345 promotion_qual_type = ast_context->UnsignedIntTy;
3346 }
3347 else
3348 promotion_qual_type = enum_decl->getIntegerType();
3349
3350 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003351 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003352 }
3353 }
3354 }
3355 return false;
3356}
3357
3358
3359#pragma mark Enumeration Types
3360
Greg Clayton462d4142010-09-29 01:12:09 +00003361clang_type_t
3362ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003363{
3364 // TODO: Do something intelligent with the Declaration object passed in
3365 // like maybe filling in the SourceLocation with it...
3366 ASTContext *ast_context = getASTContext();
3367 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003368
3369 // TODO: ask about these...
3370// const bool IsScoped = false;
3371// const bool IsFixed = false;
3372
3373 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3374 ast_context->getTranslationUnitDecl(),
3375 SourceLocation(),
3376 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3377 SourceLocation(),
Sean Callanan8950c9a2010-10-29 18:38:40 +00003378 NULL, false, false); //IsScoped, IsFixed);
Chris Lattner24943d22010-06-08 16:52:24 +00003379 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003380 {
3381 // TODO: check if we should be setting the promotion type too?
3382 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003383 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003384 }
Chris Lattner24943d22010-06-08 16:52:24 +00003385 return NULL;
3386}
3387
Greg Clayton462d4142010-09-29 01:12:09 +00003388clang_type_t
3389ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3390{
3391 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3392
3393 clang::Type *clang_type = enum_qual_type.getTypePtr();
3394 if (clang_type)
3395 {
3396 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3397 if (enum_type)
3398 {
3399 EnumDecl *enum_decl = enum_type->getDecl();
3400 if (enum_decl)
3401 return enum_decl->getIntegerType().getAsOpaquePtr();
3402 }
3403 }
3404 return NULL;
3405}
Chris Lattner24943d22010-06-08 16:52:24 +00003406bool
3407ClangASTContext::AddEnumerationValueToEnumerationType
3408(
Greg Clayton462d4142010-09-29 01:12:09 +00003409 clang_type_t enum_clang_type,
3410 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003411 const Declaration &decl,
3412 const char *name,
3413 int64_t enum_value,
3414 uint32_t enum_value_bit_size
3415)
3416{
3417 if (enum_clang_type && enumerator_clang_type && name)
3418 {
3419 // TODO: Do something intelligent with the Declaration object passed in
3420 // like maybe filling in the SourceLocation with it...
3421 ASTContext *ast_context = getASTContext();
3422 IdentifierTable *identifier_table = getIdentifierTable();
3423
3424 assert (ast_context != NULL);
3425 assert (identifier_table != NULL);
3426 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3427
Greg Clayton1674b122010-07-21 22:12:05 +00003428 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003429 if (clang_type)
3430 {
3431 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3432
3433 if (enum_type)
3434 {
3435 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3436 enum_llvm_apsint = enum_value;
3437 EnumConstantDecl *enumerator_decl =
3438 EnumConstantDecl::Create(*ast_context,
3439 enum_type->getDecl(),
3440 SourceLocation(),
3441 name ? &identifier_table->get(name) : NULL, // Identifier
3442 QualType::getFromOpaquePtr(enumerator_clang_type),
3443 NULL,
3444 enum_llvm_apsint);
3445
3446 if (enumerator_decl)
3447 {
3448 enum_type->getDecl()->addDecl(enumerator_decl);
3449 return true;
3450 }
3451 }
3452 }
3453 }
3454 return false;
3455}
3456
3457#pragma mark Pointers & References
3458
Greg Clayton462d4142010-09-29 01:12:09 +00003459clang_type_t
3460ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003461{
3462 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003463 {
3464 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3465
Greg Clayton03e0f972010-09-13 03:32:57 +00003466 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3467 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003468 {
3469 case clang::Type::ObjCObject:
3470 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003471 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3472
Greg Clayton7b541032010-07-29 20:06:32 +00003473 default:
3474 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3475 }
3476 }
Chris Lattner24943d22010-06-08 16:52:24 +00003477 return NULL;
3478}
3479
Greg Clayton462d4142010-09-29 01:12:09 +00003480clang_type_t
3481ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003482{
3483 if (clang_type)
3484 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3485 return NULL;
3486}
3487
Greg Clayton462d4142010-09-29 01:12:09 +00003488clang_type_t
3489ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003490{
3491 if (clang_type)
3492 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3493 return NULL;
3494}
3495
Greg Clayton462d4142010-09-29 01:12:09 +00003496clang_type_t
3497ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003498{
3499 if (clang_pointee_type && clang_pointee_type)
3500 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3501 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3502 return NULL;
3503}
3504
Chris Lattner24943d22010-06-08 16:52:24 +00003505size_t
3506ClangASTContext::GetPointerBitSize ()
3507{
3508 ASTContext *ast_context = getASTContext();
3509 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3510}
3511
3512bool
Greg Clayton462d4142010-09-29 01:12:09 +00003513ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003514{
3515 if (clang_type == NULL)
3516 return false;
3517
3518 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003519 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3520 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003521 {
Sean Callanan04325062010-10-25 00:29:48 +00003522 case clang::Type::Builtin:
3523 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3524 {
3525 default:
3526 break;
3527 case clang::BuiltinType::ObjCId:
3528 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003529 return true;
3530 }
3531 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003532 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003533 if (target_type)
3534 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3535 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003536 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003537 if (target_type)
3538 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3539 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003540 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003541 if (target_type)
3542 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3543 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003544 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003545 if (target_type)
3546 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3547 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003548 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003549 if (target_type)
3550 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3551 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003552 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003553 if (target_type)
3554 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3555 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003556 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003557 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3558 default:
3559 break;
3560 }
3561 return false;
3562}
3563
Chris Lattner24943d22010-06-08 16:52:24 +00003564bool
Greg Clayton462d4142010-09-29 01:12:09 +00003565ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003566{
3567 if (!clang_type)
3568 return false;
3569
3570 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3571 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3572
3573 if (builtin_type)
3574 {
3575 if (builtin_type->isInteger())
3576 is_signed = builtin_type->isSignedInteger();
3577
3578 return true;
3579 }
3580
3581 return false;
3582}
3583
3584bool
Greg Clayton462d4142010-09-29 01:12:09 +00003585ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003586{
3587 if (clang_type)
3588 {
3589 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003590 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3591 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003592 {
Sean Callanan04325062010-10-25 00:29:48 +00003593 case clang::Type::Builtin:
3594 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3595 {
3596 default:
3597 break;
3598 case clang::BuiltinType::ObjCId:
3599 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003600 return true;
3601 }
3602 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003603 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003604 if (target_type)
3605 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3606 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003607 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003608 if (target_type)
3609 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3610 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003611 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003612 if (target_type)
3613 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3614 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003615 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003616 if (target_type)
3617 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3618 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003619 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003620 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3621 default:
3622 break;
3623 }
3624 }
3625 return false;
3626}
3627
3628bool
Greg Clayton462d4142010-09-29 01:12:09 +00003629ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003630{
3631 if (clang_type)
3632 {
3633 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3634
3635 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3636 {
3637 clang::BuiltinType::Kind kind = BT->getKind();
3638 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3639 {
3640 count = 1;
3641 is_complex = false;
3642 return true;
3643 }
3644 }
3645 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3646 {
3647 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3648 {
3649 count = 2;
3650 is_complex = true;
3651 return true;
3652 }
3653 }
3654 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3655 {
3656 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3657 {
3658 count = VT->getNumElements();
3659 is_complex = false;
3660 return true;
3661 }
3662 }
3663 }
3664 return false;
3665}
3666
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003667
3668bool
3669ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3670{
3671 if (clang_type)
3672 {
3673 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3674
3675 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3676 if (cxx_record_decl)
3677 {
3678 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3679 return true;
3680 }
3681 }
3682 class_name.clear();
3683 return false;
3684}
3685
3686
Greg Clayton1d8173f2010-09-24 05:15:53 +00003687bool
Greg Clayton462d4142010-09-29 01:12:09 +00003688ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003689{
3690 if (clang_type)
3691 {
3692 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3693 if (qual_type->getAsCXXRecordDecl() != NULL)
3694 return true;
3695 }
3696 return false;
3697}
3698
3699bool
Greg Clayton462d4142010-09-29 01:12:09 +00003700ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003701{
3702 if (clang_type)
3703 {
3704 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3705 if (qual_type->isObjCObjectOrInterfaceType())
3706 return true;
3707 }
3708 return false;
3709}
3710
3711
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003712bool
3713ClangASTContext::IsCharType (clang_type_t clang_type)
3714{
3715 if (clang_type)
3716 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3717 return false;
3718}
Chris Lattner24943d22010-06-08 16:52:24 +00003719
3720bool
Greg Clayton462d4142010-09-29 01:12:09 +00003721ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003722{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003723 clang_type_t pointee_or_element_clang_type = NULL;
3724 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3725
3726 if (pointee_or_element_clang_type == NULL)
3727 return false;
3728
3729 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003730 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003731 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3732
3733 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003734 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003735 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3736 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003737 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003738 // We know the size of the array and it could be a C string
3739 // since it is an array of characters
3740 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3741 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003742 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003743 else
Chris Lattner24943d22010-06-08 16:52:24 +00003744 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003745 length = 0;
3746 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003747 }
Chris Lattner24943d22010-06-08 16:52:24 +00003748
Chris Lattner24943d22010-06-08 16:52:24 +00003749 }
3750 }
3751 return false;
3752}
3753
3754bool
Greg Clayton462d4142010-09-29 01:12:09 +00003755ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003756{
3757 if (clang_type)
3758 {
3759 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3760
3761 if (qual_type->isFunctionPointerType())
3762 return true;
3763
3764 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3765 switch (type_class)
3766 {
3767 case clang::Type::Typedef:
3768 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3769
3770 case clang::Type::LValueReference:
3771 case clang::Type::RValueReference:
3772 {
3773 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3774 if (reference_type)
3775 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3776 }
3777 break;
3778 }
3779 }
3780 return false;
3781}
3782
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003783size_t
3784ClangASTContext::GetArraySize (clang_type_t clang_type)
3785{
3786 if (clang_type)
3787 {
3788 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3789 if (array)
3790 return array->getSize().getLimitedValue();
3791 }
3792 return 0;
3793}
Greg Clayton03e0f972010-09-13 03:32:57 +00003794
3795bool
Greg Clayton462d4142010-09-29 01:12:09 +00003796ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003797{
3798 if (!clang_type)
3799 return false;
3800
3801 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3802
Greg Clayton03e0f972010-09-13 03:32:57 +00003803 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3804 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003805 {
Greg Clayton1674b122010-07-21 22:12:05 +00003806 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003807 if (member_type)
3808 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3809 if (size)
3810 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3811 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003812 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003813 if (member_type)
3814 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3815 if (size)
3816 *size = 0;
3817 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003818 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003819 if (member_type)
3820 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3821 if (size)
3822 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003823 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003824 if (member_type)
3825 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3826 if (size)
3827 *size = 0;
3828 return true;
3829 }
3830 return false;
3831}
3832
3833
3834#pragma mark Typedefs
3835
Greg Clayton462d4142010-09-29 01:12:09 +00003836clang_type_t
3837ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003838{
3839 if (clang_type)
3840 {
3841 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3842 ASTContext *ast_context = getASTContext();
3843 IdentifierTable *identifier_table = getIdentifierTable();
3844 assert (ast_context != NULL);
3845 assert (identifier_table != NULL);
3846 if (decl_ctx == NULL)
3847 decl_ctx = ast_context->getTranslationUnitDecl();
3848 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3849 decl_ctx,
3850 SourceLocation(),
3851 name ? &identifier_table->get(name) : NULL, // Identifier
3852 ast_context->CreateTypeSourceInfo(qual_type));
3853
3854 // Get a uniqued QualType for the typedef decl type
3855 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3856 }
3857 return NULL;
3858}
3859
3860
3861std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003862ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003863{
3864 std::string return_name;
3865
Greg Clayton462d4142010-09-29 01:12:09 +00003866 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003867
Greg Clayton462d4142010-09-29 01:12:09 +00003868 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003869 if (typedef_type)
3870 {
Greg Clayton462d4142010-09-29 01:12:09 +00003871 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003872 return_name = typedef_decl->getQualifiedNameAsString();
3873 }
3874 else
3875 {
3876 return_name = qual_type.getAsString();
3877 }
3878
3879 return return_name;
3880}
3881
3882// Disable this for now since I can't seem to get a nicely formatted float
3883// out of the APFloat class without just getting the float, double or quad
3884// and then using a formatted print on it which defeats the purpose. We ideally
3885// would like to get perfect string values for any kind of float semantics
3886// so we can support remote targets. The code below also requires a patch to
3887// llvm::APInt.
3888//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003889//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 +00003890//{
3891// uint32_t count = 0;
3892// bool is_complex = false;
3893// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3894// {
3895// unsigned num_bytes_per_float = byte_size / count;
3896// unsigned num_bits_per_float = num_bytes_per_float * 8;
3897//
3898// float_str.clear();
3899// uint32_t i;
3900// for (i=0; i<count; i++)
3901// {
3902// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3903// bool is_ieee = false;
3904// APFloat ap_float(ap_int, is_ieee);
3905// char s[1024];
3906// unsigned int hex_digits = 0;
3907// bool upper_case = false;
3908//
3909// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3910// {
3911// if (i > 0)
3912// float_str.append(", ");
3913// float_str.append(s);
3914// if (i == 1 && is_complex)
3915// float_str.append(1, 'i');
3916// }
3917// }
3918// return !float_str.empty();
3919// }
3920// return false;
3921//}
3922
3923size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003924ClangASTContext::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 +00003925{
3926 if (clang_type)
3927 {
3928 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3929 uint32_t count = 0;
3930 bool is_complex = false;
3931 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3932 {
3933 // TODO: handle complex and vector types
3934 if (count != 1)
3935 return false;
3936
3937 StringRef s_sref(s);
3938 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3939
3940 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3941 const uint64_t byte_size = bit_size / 8;
3942 if (dst_size >= byte_size)
3943 {
3944 if (bit_size == sizeof(float)*8)
3945 {
3946 float float32 = ap_float.convertToFloat();
3947 ::memcpy (dst, &float32, byte_size);
3948 return byte_size;
3949 }
3950 else if (bit_size >= 64)
3951 {
3952 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3953 ::memcpy (dst, ap_int.getRawData(), byte_size);
3954 return byte_size;
3955 }
3956 }
3957 }
3958 }
3959 return 0;
3960}
Sean Callanana751f7b2010-09-17 02:24:29 +00003961
3962unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00003963ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00003964{
3965 assert (clang_type);
3966
3967 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3968
3969 return qual_type.getQualifiers().getCVRQualifiers();
3970}