blob: 13302756339ef01a11a21914194b8607099ee14a [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedmanf05633b2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Sean Callananbc4f0f52010-07-08 18:16:16 +000017#define NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "clang/AST/ASTContext.h"
19#include "clang/AST/ASTImporter.h"
20#include "clang/AST/CXXInheritance.h"
Greg Clayton84f80752010-07-22 18:30:50 +000021#include "clang/AST/DeclObjC.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "clang/AST/RecordLayout.h"
23#include "clang/AST/Type.h"
24#include "clang/Basic/Builtins.h"
25#include "clang/Basic/FileManager.h"
Sean Callanan8a3b0a82010-11-18 02:56:27 +000026#include "clang/Basic/FileSystemOptions.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "clang/Basic/SourceManager.h"
28#include "clang/Basic/TargetInfo.h"
29#include "clang/Basic/TargetOptions.h"
30#include "clang/Frontend/FrontendOptions.h"
31#include "clang/Frontend/LangStandard.h"
Sean Callananbc4f0f52010-07-08 18:16:16 +000032#undef NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000033
Chris Lattner24943d22010-06-08 16:52:24 +000034#include "lldb/Core/dwarf.h"
Greg Claytonf3d0b0c2010-10-27 03:32:59 +000035#include "lldb/Core/Flags.h"
Sean Callanan839fde42010-10-28 18:19:36 +000036#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037
Eli Friedmanf05633b2010-06-13 19:06:42 +000038#include <stdio.h>
39
Greg Clayton585660c2010-08-05 01:57:25 +000040using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000041using namespace lldb_private;
42using namespace llvm;
43using namespace clang;
44
Greg Clayton84f80752010-07-22 18:30:50 +000045static AccessSpecifier
Greg Clayton585660c2010-08-05 01:57:25 +000046ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000047{
48 switch (access)
49 {
Greg Clayton585660c2010-08-05 01:57:25 +000050 default: break;
51 case eAccessNone: return AS_none;
52 case eAccessPublic: return AS_public;
53 case eAccessPrivate: return AS_private;
54 case eAccessProtected: return AS_protected;
Greg Clayton84f80752010-07-22 18:30:50 +000055 }
56 return AS_none;
57}
58
59static ObjCIvarDecl::AccessControl
Greg Clayton585660c2010-08-05 01:57:25 +000060ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000061{
62 switch (access)
63 {
Greg Clayton585660c2010-08-05 01:57:25 +000064 default: break;
65 case eAccessNone: return ObjCIvarDecl::None;
66 case eAccessPublic: return ObjCIvarDecl::Public;
67 case eAccessPrivate: return ObjCIvarDecl::Private;
68 case eAccessProtected: return ObjCIvarDecl::Protected;
69 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton84f80752010-07-22 18:30:50 +000070 }
71 return ObjCIvarDecl::None;
72}
73
74
Chris Lattner24943d22010-06-08 16:52:24 +000075static void
76ParseLangArgs
77(
78 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000079 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000080)
81{
82 // FIXME: Cleanup per-file based stuff.
83
84 // Set some properties which depend soley on the input kind; it would be nice
85 // to move these to the language standard, and have the driver resolve the
86 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000087 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000088 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000089 } else if (IK == IK_ObjC ||
90 IK == IK_ObjCXX ||
91 IK == IK_PreprocessedObjC ||
92 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000093 Opts.ObjC1 = Opts.ObjC2 = 1;
94 }
95
96 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
97
98 if (LangStd == LangStandard::lang_unspecified) {
99 // Based on the base language, pick one.
100 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +0000101 case IK_None:
102 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +0000103 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +0000104 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +0000105 LangStd = LangStandard::lang_opencl;
106 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000107 case IK_Asm:
108 case IK_C:
109 case IK_PreprocessedC:
110 case IK_ObjC:
111 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +0000112 LangStd = LangStandard::lang_gnu99;
113 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000114 case IK_CXX:
115 case IK_PreprocessedCXX:
116 case IK_ObjCXX:
117 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +0000118 LangStd = LangStandard::lang_gnucxx98;
119 break;
120 }
121 }
122
123 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
124 Opts.BCPLComment = Std.hasBCPLComments();
125 Opts.C99 = Std.isC99();
126 Opts.CPlusPlus = Std.isCPlusPlus();
127 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
128 Opts.Digraphs = Std.hasDigraphs();
129 Opts.GNUMode = Std.isGNUMode();
130 Opts.GNUInline = !Std.isC99();
131 Opts.HexFloats = Std.hasHexFloats();
132 Opts.ImplicitInt = Std.hasImplicitInt();
133
134 // OpenCL has some additional defaults.
135 if (LangStd == LangStandard::lang_opencl) {
136 Opts.OpenCL = 1;
137 Opts.AltiVec = 1;
138 Opts.CXXOperatorNames = 1;
139 Opts.LaxVectorConversions = 1;
140 }
141
142 // OpenCL and C++ both have bool, true, false keywords.
143 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
144
145// if (Opts.CPlusPlus)
146// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
147//
148// if (Args.hasArg(OPT_fobjc_gc_only))
149// Opts.setGCMode(LangOptions::GCOnly);
150// else if (Args.hasArg(OPT_fobjc_gc))
151// Opts.setGCMode(LangOptions::HybridGC);
152//
153// if (Args.hasArg(OPT_print_ivar_layout))
154// Opts.ObjCGCBitmapPrint = 1;
155//
156// if (Args.hasArg(OPT_faltivec))
157// Opts.AltiVec = 1;
158//
159// if (Args.hasArg(OPT_pthread))
160// Opts.POSIXThreads = 1;
161//
162// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
163// "default");
164// if (Vis == "default")
Sean Callanan8950c9a2010-10-29 18:38:40 +0000165 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner24943d22010-06-08 16:52:24 +0000166// else if (Vis == "hidden")
167// Opts.setVisibilityMode(LangOptions::Hidden);
168// else if (Vis == "protected")
169// Opts.setVisibilityMode(LangOptions::Protected);
170// else
171// Diags.Report(diag::err_drv_invalid_value)
172// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
173
174// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
175
176 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
177 // is specified, or -std is set to a conforming mode.
178 Opts.Trigraphs = !Opts.GNUMode;
179// if (Args.hasArg(OPT_trigraphs))
180// Opts.Trigraphs = 1;
181//
182// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
183// OPT_fno_dollars_in_identifiers,
184// !Opts.AsmPreprocessor);
185// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
186// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
187// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
188// if (Args.hasArg(OPT_fno_lax_vector_conversions))
189// Opts.LaxVectorConversions = 0;
190// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
191// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
192// Opts.Blocks = Args.hasArg(OPT_fblocks);
193// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
194// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
195// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
196// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
197// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
198// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
199// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
200// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
201// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
202// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
203// Diags);
204// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
205// Opts.ObjCConstantStringClass = getLastArgValue(Args,
206// OPT_fconstant_string_class);
207// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
208// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
209// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
210// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
211// Opts.Static = Args.hasArg(OPT_static_define);
212 Opts.OptimizeSize = 0;
213
214 // FIXME: Eliminate this dependency.
215// unsigned Opt =
216// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
217// Opts.Optimize = Opt != 0;
218 unsigned Opt = 0;
219
220 // This is the __NO_INLINE__ define, which just depends on things like the
221 // optimization level and -fno-inline, not actually whether the backend has
222 // inlining enabled.
223 //
224 // FIXME: This is affected by other options (-fno-inline).
225 Opts.NoInline = !Opt;
226
227// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
228// switch (SSP) {
229// default:
230// Diags.Report(diag::err_drv_invalid_value)
231// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
232// break;
233// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
234// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
235// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
236// }
237}
238
Chris Lattner24943d22010-06-08 16:52:24 +0000239
Chris Lattner24943d22010-06-08 16:52:24 +0000240ClangASTContext::ClangASTContext(const char *target_triple) :
241 m_target_triple(),
242 m_ast_context_ap(),
243 m_language_options_ap(),
244 m_source_manager_ap(),
245 m_diagnostic_ap(),
246 m_target_options_ap(),
247 m_target_info_ap(),
248 m_identifier_table_ap(),
249 m_selector_table_ap(),
250 m_builtins_ap()
251{
252 if (target_triple && target_triple[0])
253 m_target_triple.assign (target_triple);
254}
255
256//----------------------------------------------------------------------
257// Destructor
258//----------------------------------------------------------------------
259ClangASTContext::~ClangASTContext()
260{
261 m_builtins_ap.reset();
262 m_selector_table_ap.reset();
263 m_identifier_table_ap.reset();
264 m_target_info_ap.reset();
265 m_target_options_ap.reset();
266 m_diagnostic_ap.reset();
267 m_source_manager_ap.reset();
268 m_language_options_ap.reset();
269 m_ast_context_ap.reset();
270}
271
272
273void
274ClangASTContext::Clear()
275{
276 m_ast_context_ap.reset();
277 m_language_options_ap.reset();
278 m_source_manager_ap.reset();
279 m_diagnostic_ap.reset();
280 m_target_options_ap.reset();
281 m_target_info_ap.reset();
282 m_identifier_table_ap.reset();
283 m_selector_table_ap.reset();
284 m_builtins_ap.reset();
285}
286
287const char *
288ClangASTContext::GetTargetTriple ()
289{
290 return m_target_triple.c_str();
291}
292
293void
294ClangASTContext::SetTargetTriple (const char *target_triple)
295{
296 Clear();
297 m_target_triple.assign(target_triple);
298}
299
300
301ASTContext *
302ClangASTContext::getASTContext()
303{
304 if (m_ast_context_ap.get() == NULL)
305 {
306 m_ast_context_ap.reset(
307 new ASTContext(
308 *getLanguageOptions(),
309 *getSourceManager(),
310 *getTargetInfo(),
311 *getIdentifierTable(),
312 *getSelectorTable(),
Greg Clayton6e713402010-07-30 20:30:44 +0000313 *getBuiltinContext(),
314 0));
Chris Lattner24943d22010-06-08 16:52:24 +0000315 }
316 return m_ast_context_ap.get();
317}
318
319Builtin::Context *
320ClangASTContext::getBuiltinContext()
321{
322 if (m_builtins_ap.get() == NULL)
323 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
324 return m_builtins_ap.get();
325}
326
327IdentifierTable *
328ClangASTContext::getIdentifierTable()
329{
330 if (m_identifier_table_ap.get() == NULL)
331 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
332 return m_identifier_table_ap.get();
333}
334
335LangOptions *
336ClangASTContext::getLanguageOptions()
337{
338 if (m_language_options_ap.get() == NULL)
339 {
340 m_language_options_ap.reset(new LangOptions());
Greg Claytone41c4b22010-06-13 17:34:29 +0000341 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
342// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner24943d22010-06-08 16:52:24 +0000343 }
344 return m_language_options_ap.get();
345}
346
347SelectorTable *
348ClangASTContext::getSelectorTable()
349{
350 if (m_selector_table_ap.get() == NULL)
351 m_selector_table_ap.reset (new SelectorTable());
352 return m_selector_table_ap.get();
353}
354
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000355clang::FileManager *
356ClangASTContext::getFileManager()
357{
358 if (m_file_manager_ap.get() == NULL)
359 m_file_manager_ap.reset(new clang::FileManager());
360 return m_file_manager_ap.get();
361}
362
363clang::FileSystemOptions *
364ClangASTContext::getFileSystemOptions()
365{
366 if (m_file_system_options_ap.get() == NULL)
367 m_file_system_options_ap.reset(new clang::FileSystemOptions());
368 return m_file_system_options_ap.get();
369}
370
Greg Clayton1674b122010-07-21 22:12:05 +0000371clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000372ClangASTContext::getSourceManager()
373{
374 if (m_source_manager_ap.get() == NULL)
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000375 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager(), *getFileSystemOptions()));
Chris Lattner24943d22010-06-08 16:52:24 +0000376 return m_source_manager_ap.get();
377}
378
379Diagnostic *
380ClangASTContext::getDiagnostic()
381{
382 if (m_diagnostic_ap.get() == NULL)
383 m_diagnostic_ap.reset(new Diagnostic());
384 return m_diagnostic_ap.get();
385}
386
387TargetOptions *
388ClangASTContext::getTargetOptions()
389{
390 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
391 {
392 m_target_options_ap.reset (new TargetOptions());
393 if (m_target_options_ap.get())
394 m_target_options_ap->Triple = m_target_triple;
395 }
396 return m_target_options_ap.get();
397}
398
399
400TargetInfo *
401ClangASTContext::getTargetInfo()
402{
403 // target_triple should be something like "x86_64-apple-darwin10"
404 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
405 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
406 return m_target_info_ap.get();
407}
408
409#pragma mark Basic Types
410
411static inline bool
412QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
413{
414 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
415 if (qual_type_bit_size == bit_size)
416 return true;
417 return false;
418}
419
Greg Clayton462d4142010-09-29 01:12:09 +0000420clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000421ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000422{
423 ASTContext *ast_context = getASTContext();
424
425 assert (ast_context != NULL);
426
427 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
428}
429
Greg Clayton462d4142010-09-29 01:12:09 +0000430clang_type_t
431ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000432{
433 if (!ast_context)
434 return NULL;
435
436 switch (encoding)
437 {
Greg Clayton585660c2010-08-05 01:57:25 +0000438 case eEncodingInvalid:
Chris Lattner24943d22010-06-08 16:52:24 +0000439 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
440 return ast_context->VoidPtrTy.getAsOpaquePtr();
441 break;
442
Greg Clayton585660c2010-08-05 01:57:25 +0000443 case eEncodingUint:
Chris Lattner24943d22010-06-08 16:52:24 +0000444 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
445 return ast_context->UnsignedCharTy.getAsOpaquePtr();
446 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
447 return ast_context->UnsignedShortTy.getAsOpaquePtr();
448 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
449 return ast_context->UnsignedIntTy.getAsOpaquePtr();
450 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
451 return ast_context->UnsignedLongTy.getAsOpaquePtr();
452 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
453 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
454 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
455 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
456 break;
457
Greg Clayton585660c2010-08-05 01:57:25 +0000458 case eEncodingSint:
Chris Lattner24943d22010-06-08 16:52:24 +0000459 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
460 return ast_context->CharTy.getAsOpaquePtr();
461 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
462 return ast_context->ShortTy.getAsOpaquePtr();
463 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
464 return ast_context->IntTy.getAsOpaquePtr();
465 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
466 return ast_context->LongTy.getAsOpaquePtr();
467 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
468 return ast_context->LongLongTy.getAsOpaquePtr();
469 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
470 return ast_context->Int128Ty.getAsOpaquePtr();
471 break;
472
Greg Clayton585660c2010-08-05 01:57:25 +0000473 case eEncodingIEEE754:
Chris Lattner24943d22010-06-08 16:52:24 +0000474 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
475 return ast_context->FloatTy.getAsOpaquePtr();
476 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
477 return ast_context->DoubleTy.getAsOpaquePtr();
478 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
479 return ast_context->LongDoubleTy.getAsOpaquePtr();
480 break;
481
Greg Clayton585660c2010-08-05 01:57:25 +0000482 case eEncodingVector:
Chris Lattner24943d22010-06-08 16:52:24 +0000483 default:
484 break;
485 }
486
487 return NULL;
488}
489
Greg Clayton462d4142010-09-29 01:12:09 +0000490clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000491ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
492{
493 ASTContext *ast_context = getASTContext();
494
495 #define streq(a,b) strcmp(a,b) == 0
496 assert (ast_context != NULL);
497 if (ast_context)
498 {
499 switch (dw_ate)
500 {
501 default:
502 break;
503
504 case DW_ATE_address:
505 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
506 return ast_context->VoidPtrTy.getAsOpaquePtr();
507 break;
508
509 case DW_ATE_boolean:
510 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
511 return ast_context->BoolTy.getAsOpaquePtr();
512 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
513 return ast_context->UnsignedCharTy.getAsOpaquePtr();
514 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
515 return ast_context->UnsignedShortTy.getAsOpaquePtr();
516 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
517 return ast_context->UnsignedIntTy.getAsOpaquePtr();
518 break;
519
520 case DW_ATE_complex_float:
521 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
522 return ast_context->FloatComplexTy.getAsOpaquePtr();
523 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
524 return ast_context->DoubleComplexTy.getAsOpaquePtr();
525 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
526 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
527 break;
528
529 case DW_ATE_float:
530 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
531 return ast_context->FloatTy.getAsOpaquePtr();
532 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
533 return ast_context->DoubleTy.getAsOpaquePtr();
534 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
535 return ast_context->LongDoubleTy.getAsOpaquePtr();
536 break;
537
538 case DW_ATE_signed:
539 if (type_name)
540 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000541 if (strstr(type_name, "long long"))
Chris Lattner24943d22010-06-08 16:52:24 +0000542 {
Chris Lattner24943d22010-06-08 16:52:24 +0000543 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
544 return ast_context->LongLongTy.getAsOpaquePtr();
545 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000546 else if (strstr(type_name, "long"))
547 {
548 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
549 return ast_context->LongTy.getAsOpaquePtr();
550 }
551 else if (strstr(type_name, "short"))
Chris Lattner24943d22010-06-08 16:52:24 +0000552 {
553 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
554 return ast_context->ShortTy.getAsOpaquePtr();
555 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000556 else if (strstr(type_name, "char"))
Chris Lattner24943d22010-06-08 16:52:24 +0000557 {
558 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
559 return ast_context->CharTy.getAsOpaquePtr();
560 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
561 return ast_context->SignedCharTy.getAsOpaquePtr();
562 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000563 else if (strstr(type_name, "int"))
564 {
565 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
566 return ast_context->IntTy.getAsOpaquePtr();
567 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
568 return ast_context->Int128Ty.getAsOpaquePtr();
569 }
570 else if (streq(type_name, "wchar_t"))
Chris Lattner24943d22010-06-08 16:52:24 +0000571 {
572 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
573 return ast_context->WCharTy.getAsOpaquePtr();
574 }
Chris Lattner24943d22010-06-08 16:52:24 +0000575 }
576 // We weren't able to match up a type name, just search by size
577 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
578 return ast_context->CharTy.getAsOpaquePtr();
579 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
580 return ast_context->ShortTy.getAsOpaquePtr();
581 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
582 return ast_context->IntTy.getAsOpaquePtr();
583 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
584 return ast_context->LongTy.getAsOpaquePtr();
585 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
586 return ast_context->LongLongTy.getAsOpaquePtr();
587 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
588 return ast_context->Int128Ty.getAsOpaquePtr();
589 break;
590
591 case DW_ATE_signed_char:
592 if (type_name)
593 {
594 if (streq(type_name, "signed char"))
595 {
596 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
597 return ast_context->SignedCharTy.getAsOpaquePtr();
598 }
599 }
600 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
601 return ast_context->CharTy.getAsOpaquePtr();
602 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
603 return ast_context->SignedCharTy.getAsOpaquePtr();
604 break;
605
606 case DW_ATE_unsigned:
607 if (type_name)
608 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000609 if (strstr(type_name, "long long"))
610 {
611 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
612 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
613 }
614 else if (strstr(type_name, "long"))
615 {
616 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
617 return ast_context->UnsignedLongTy.getAsOpaquePtr();
618 }
619 else if (strstr(type_name, "short"))
620 {
621 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
622 return ast_context->UnsignedShortTy.getAsOpaquePtr();
623 }
624 else if (strstr(type_name, "char"))
625 {
626 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
627 return ast_context->UnsignedCharTy.getAsOpaquePtr();
628 }
629 else if (strstr(type_name, "int"))
Chris Lattner24943d22010-06-08 16:52:24 +0000630 {
631 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
632 return ast_context->UnsignedIntTy.getAsOpaquePtr();
633 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
634 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
635 }
Chris Lattner24943d22010-06-08 16:52:24 +0000636 }
637 // We weren't able to match up a type name, just search by size
638 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
639 return ast_context->UnsignedCharTy.getAsOpaquePtr();
640 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
641 return ast_context->UnsignedShortTy.getAsOpaquePtr();
642 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
643 return ast_context->UnsignedIntTy.getAsOpaquePtr();
644 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
645 return ast_context->UnsignedLongTy.getAsOpaquePtr();
646 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
647 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
648 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
649 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
650 break;
651
652 case DW_ATE_unsigned_char:
653 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
654 return ast_context->UnsignedCharTy.getAsOpaquePtr();
655 break;
656
657 case DW_ATE_imaginary_float:
658 break;
659 }
660 }
661 // This assert should fire for anything that we don't catch above so we know
662 // to fix any issues we run into.
663 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
664 return NULL;
665}
666
Greg Clayton462d4142010-09-29 01:12:09 +0000667clang_type_t
668ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
Chris Lattner24943d22010-06-08 16:52:24 +0000669{
Sean Callanana751f7b2010-09-17 02:24:29 +0000670 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000671}
672
Greg Clayton462d4142010-09-29 01:12:09 +0000673clang_type_t
Sean Callanana91dd992010-11-19 02:52:21 +0000674ClangASTContext::GetBuiltInType_bool()
675{
676 return getASTContext()->BoolTy.getAsOpaquePtr();
677}
678
679clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000680ClangASTContext::GetBuiltInType_objc_id()
681{
Sean Callanan04325062010-10-25 00:29:48 +0000682 return getASTContext()->ObjCBuiltinIdTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000683}
684
Greg Clayton462d4142010-09-29 01:12:09 +0000685clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000686ClangASTContext::GetBuiltInType_objc_Class()
687{
Sean Callanan04325062010-10-25 00:29:48 +0000688 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000689}
690
Greg Clayton462d4142010-09-29 01:12:09 +0000691clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000692ClangASTContext::GetBuiltInType_objc_selector()
693{
Sean Callanan04325062010-10-25 00:29:48 +0000694 return getASTContext()->ObjCBuiltinSelTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000695}
696
Greg Clayton462d4142010-09-29 01:12:09 +0000697clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000698ClangASTContext::GetCStringType (bool is_const)
699{
700 QualType char_type(getASTContext()->CharTy);
701
702 if (is_const)
703 char_type.addConst();
704
705 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
706}
707
Greg Clayton462d4142010-09-29 01:12:09 +0000708clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000709ClangASTContext::GetVoidPtrType (bool is_const)
710{
711 return GetVoidPtrType(getASTContext(), is_const);
712}
713
Greg Clayton462d4142010-09-29 01:12:09 +0000714clang_type_t
715ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
Chris Lattner24943d22010-06-08 16:52:24 +0000716{
717 QualType void_ptr_type(ast_context->VoidPtrTy);
718
719 if (is_const)
720 void_ptr_type.addConst();
721
722 return void_ptr_type.getAsOpaquePtr();
723}
724
Sean Callanan839fde42010-10-28 18:19:36 +0000725class NullDiagnosticClient : public DiagnosticClient
726{
727public:
728 NullDiagnosticClient ()
729 {
730 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
731 }
732
733 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
734 {
735 if (m_log)
736 {
737 llvm::SmallVectorImpl<char> diag_str(10);
738 info.FormatDiagnostic(diag_str);
739 diag_str.push_back('\0');
740 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
741 }
742 }
743private:
Greg Claytone005f2c2010-11-06 01:53:30 +0000744 LogSP m_log;
Sean Callanan839fde42010-10-28 18:19:36 +0000745};
746
Greg Clayton462d4142010-09-29 01:12:09 +0000747clang_type_t
748ClangASTContext::CopyType (ASTContext *dest_context,
749 ASTContext *source_context,
750 clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000751{
Sean Callananad5b61b2010-10-28 18:43:33 +0000752 // null_client's ownership is transferred to diagnostics
Sean Callanan839fde42010-10-28 18:19:36 +0000753 NullDiagnosticClient *null_client = new NullDiagnosticClient;
754 Diagnostic diagnostics(null_client);
Chris Lattner24943d22010-06-08 16:52:24 +0000755 FileManager file_manager;
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000756 FileSystemOptions file_system_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000757 ASTImporter importer(diagnostics,
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000758 *dest_context, file_manager, file_system_options,
759 *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
774 NullDiagnosticClient *null_client = new NullDiagnosticClient;
775 Diagnostic diagnostics(null_client);
776 FileManager file_manager;
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000777 FileSystemOptions file_system_options;
Greg Clayton6916e352010-11-13 03:52:47 +0000778 ASTImporter importer(diagnostics,
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000779 *dest_context, file_manager, file_system_options,
780 *source_context, file_manager, file_system_options);
Greg Clayton6916e352010-11-13 03:52:47 +0000781
782 return importer.Import(source_decl);
783}
784
Sean Callanan8d825062010-07-16 00:00:27 +0000785bool
Greg Clayton462d4142010-09-29 01:12:09 +0000786ClangASTContext::AreTypesSame(ASTContext *ast_context,
787 clang_type_t type1,
788 clang_type_t type2)
Sean Callanan5510ddd2010-07-15 22:30:52 +0000789{
790 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
791 QualType::getFromOpaquePtr(type2));
792}
793
Chris Lattner24943d22010-06-08 16:52:24 +0000794#pragma mark CVR modifiers
795
Greg Clayton462d4142010-09-29 01:12:09 +0000796clang_type_t
797ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000798{
799 if (clang_type)
800 {
801 QualType result(QualType::getFromOpaquePtr(clang_type));
802 result.addConst();
803 return result.getAsOpaquePtr();
804 }
805 return NULL;
806}
807
Greg Clayton462d4142010-09-29 01:12:09 +0000808clang_type_t
809ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000810{
811 if (clang_type)
812 {
813 QualType result(QualType::getFromOpaquePtr(clang_type));
814 result.getQualifiers().setRestrict (true);
815 return result.getAsOpaquePtr();
816 }
817 return NULL;
818}
819
Greg Clayton462d4142010-09-29 01:12:09 +0000820clang_type_t
821ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000822{
823 if (clang_type)
824 {
825 QualType result(QualType::getFromOpaquePtr(clang_type));
826 result.getQualifiers().setVolatile (true);
827 return result.getAsOpaquePtr();
828 }
829 return NULL;
830}
831
832#pragma mark Structure, Unions, Classes
833
Greg Clayton462d4142010-09-29 01:12:09 +0000834clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000835ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000836{
837 ASTContext *ast_context = getASTContext();
838 assert (ast_context != NULL);
Sean Callanan04325062010-10-25 00:29:48 +0000839
Chris Lattner24943d22010-06-08 16:52:24 +0000840 if (decl_ctx == NULL)
841 decl_ctx = ast_context->getTranslationUnitDecl();
842
Greg Clayton9488b742010-07-28 02:04:09 +0000843
Greg Clayton585660c2010-08-05 01:57:25 +0000844 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000845 {
Greg Clayton306edca2010-10-11 02:25:34 +0000846 bool isForwardDecl = true;
Greg Clayton9488b742010-07-28 02:04:09 +0000847 bool isInternal = false;
848 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
849 }
850
Chris Lattner24943d22010-06-08 16:52:24 +0000851 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
852 // we will need to update this code. I was told to currently always use
853 // the CXXRecordDecl class since we often don't know from debug information
854 // if something is struct or a class, so we default to always use the more
855 // complete definition just in case.
856 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
857 (TagDecl::TagKind)kind,
858 decl_ctx,
859 SourceLocation(),
860 name && name[0] ? &ast_context->Idents.get(name) : NULL);
861
862 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
863}
864
Greg Claytondbf26152010-10-01 23:13:49 +0000865static bool
866IsOperator (const char *name, OverloadedOperatorKind &op_kind)
867{
868 if (name == NULL || name[0] == '\0')
869 return false;
870
871 if (::strstr(name, "operator ") != name)
872 return false;
873
874 const char *post_op_name = name + 9;
875
876 // This is an operator, set the overloaded operator kind to invalid
877 // in case this is a conversion operator...
878 op_kind = NUM_OVERLOADED_OPERATORS;
879
880 switch (post_op_name[0])
881 {
882 case 'n':
883 if (strcmp (post_op_name, "new") == 0)
884 op_kind = OO_New;
885 else if (strcmp (post_op_name, "new[]") == 0)
886 op_kind = OO_Array_New;
887 break;
888
889 case 'd':
890 if (strcmp (post_op_name, "delete") == 0)
891 op_kind = OO_Delete;
892 else if (strcmp (post_op_name, "delete[]") == 0)
893 op_kind = OO_Array_Delete;
894 break;
895
896 case '+':
897 if (post_op_name[1] == '\0')
898 op_kind = OO_Plus;
899 else if (post_op_name[2] == '\0')
900 {
901 if (post_op_name[1] == '=')
902 op_kind = OO_PlusEqual;
903 else if (post_op_name[1] == '+')
904 op_kind = OO_PlusPlus;
905 }
906 break;
907
908 case '-':
909 if (post_op_name[1] == '\0')
910 op_kind = OO_Minus;
911 else if (post_op_name[2] == '\0')
912 {
913 switch (post_op_name[1])
914 {
915 case '=': op_kind = OO_MinusEqual; break;
916 case '-': op_kind = OO_MinusMinus; break;
917 case '>': op_kind = OO_Arrow; break;
918 }
919 }
920 else if (post_op_name[3] == '\0')
921 {
922 if (post_op_name[2] == '*')
923 op_kind = OO_ArrowStar; break;
924 }
925 break;
926
927 case '*':
928 if (post_op_name[1] == '\0')
929 op_kind = OO_Star;
930 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
931 op_kind = OO_StarEqual;
932 break;
933
934 case '/':
935 if (post_op_name[1] == '\0')
936 op_kind = OO_Slash;
937 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
938 op_kind = OO_SlashEqual;
939 break;
940
941 case '%':
942 if (post_op_name[1] == '\0')
943 op_kind = OO_Percent;
944 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
945 op_kind = OO_PercentEqual;
946 break;
947
948
949 case '^':
950 if (post_op_name[1] == '\0')
951 op_kind = OO_Caret;
952 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
953 op_kind = OO_CaretEqual;
954 break;
955
956 case '&':
957 if (post_op_name[1] == '\0')
958 op_kind = OO_Amp;
959 else if (post_op_name[2] == '\0')
960 {
961 switch (post_op_name[1])
962 {
963 case '=': op_kind = OO_AmpEqual; break;
964 case '&': op_kind = OO_AmpAmp; break;
965 }
966 }
967 break;
968
969 case '|':
970 if (post_op_name[1] == '\0')
971 op_kind = OO_Pipe;
972 else if (post_op_name[2] == '\0')
973 {
974 switch (post_op_name[1])
975 {
976 case '=': op_kind = OO_PipeEqual; break;
977 case '|': op_kind = OO_PipePipe; break;
978 }
979 }
980 break;
981
982 case '~':
983 if (post_op_name[1] == '\0')
984 op_kind = OO_Tilde;
985 break;
986
987 case '!':
988 if (post_op_name[1] == '\0')
989 op_kind = OO_Exclaim;
990 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
991 op_kind = OO_ExclaimEqual;
992 break;
993
994 case '=':
995 if (post_op_name[1] == '\0')
996 op_kind = OO_Equal;
997 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
998 op_kind = OO_EqualEqual;
999 break;
1000
1001 case '<':
1002 if (post_op_name[1] == '\0')
1003 op_kind = OO_Less;
1004 else if (post_op_name[2] == '\0')
1005 {
1006 switch (post_op_name[1])
1007 {
1008 case '<': op_kind = OO_LessLess; break;
1009 case '=': op_kind = OO_LessEqual; break;
1010 }
1011 }
1012 else if (post_op_name[3] == '\0')
1013 {
1014 if (post_op_name[2] == '=')
1015 op_kind = OO_LessLessEqual;
1016 }
1017 break;
1018
1019 case '>':
1020 if (post_op_name[1] == '\0')
1021 op_kind = OO_Greater;
1022 else if (post_op_name[2] == '\0')
1023 {
1024 switch (post_op_name[1])
1025 {
1026 case '>': op_kind = OO_GreaterGreater; break;
1027 case '=': op_kind = OO_GreaterEqual; break;
1028 }
1029 }
1030 else if (post_op_name[1] == '>' &&
1031 post_op_name[2] == '=' &&
1032 post_op_name[3] == '\0')
1033 {
1034 op_kind = OO_GreaterGreaterEqual;
1035 }
1036 break;
1037
1038 case ',':
1039 if (post_op_name[1] == '\0')
1040 op_kind = OO_Comma;
1041 break;
1042
1043 case '(':
1044 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1045 op_kind = OO_Call;
1046 break;
1047
1048 case '[':
1049 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1050 op_kind = OO_Subscript;
1051 break;
1052 }
1053
1054 return true;
1055}
Greg Clayton412440a2010-09-23 01:09:21 +00001056CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +00001057ClangASTContext::AddMethodToCXXRecordType
1058(
Greg Clayton462d4142010-09-29 01:12:09 +00001059 ASTContext *ast_context,
1060 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001061 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001062 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001063 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001064 bool is_virtual,
1065 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001066 bool is_inline,
1067 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +00001068)
Sean Callanan79523002010-09-17 02:58:26 +00001069{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001070 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +00001071 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001072
1073 assert(ast_context);
1074
1075 IdentifierTable *identifier_table = &ast_context->Idents;
1076
1077 assert(identifier_table);
1078
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001079 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +00001080
1081 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +00001082
Greg Clayton1d8173f2010-09-24 05:15:53 +00001083 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001084 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001085
Greg Clayton1d8173f2010-09-24 05:15:53 +00001086 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +00001087
Greg Clayton1d8173f2010-09-24 05:15:53 +00001088 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001089 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001090
Greg Clayton1d8173f2010-09-24 05:15:53 +00001091 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +00001092
Greg Clayton1d8173f2010-09-24 05:15:53 +00001093 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001094 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001095
1096 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1097
Greg Clayton1d8173f2010-09-24 05:15:53 +00001098 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001099 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001100
Greg Clayton1d8173f2010-09-24 05:15:53 +00001101 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001102
Greg Clayton30449d52010-10-01 02:31:07 +00001103 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001104
Greg Clayton30449d52010-10-01 02:31:07 +00001105 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001106
Greg Clayton90e325d2010-10-01 03:45:20 +00001107 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001108
Greg Clayton5325a362010-10-02 01:40:05 +00001109 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001110
Greg Clayton5325a362010-10-02 01:40:05 +00001111 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001112 return NULL;
1113
Greg Clayton5325a362010-10-02 01:40:05 +00001114 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001115
1116 if (!method_function_prototype)
1117 return NULL;
1118
1119 unsigned int num_params = method_function_prototype->getNumArgs();
1120
1121 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001122 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001123 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1124 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001125 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001126 method_qual_type,
Sean Callanan8950c9a2010-10-29 18:38:40 +00001127 NULL,
Greg Clayton90e325d2010-10-01 03:45:20 +00001128 is_inline,
1129 is_implicitly_declared);
1130 }
1131 else if (decl_name == record_decl->getDeclName())
1132 {
Greg Clayton30449d52010-10-01 02:31:07 +00001133 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1134 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001135 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001136 method_qual_type,
1137 NULL, // TypeSourceInfo *
1138 is_explicit,
1139 is_inline,
1140 is_implicitly_declared);
1141 }
1142 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001143 {
Greg Claytondbf26152010-10-01 23:13:49 +00001144
1145 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1146 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001147 {
Greg Claytondbf26152010-10-01 23:13:49 +00001148 if (op_kind != NUM_OVERLOADED_OPERATORS)
1149 {
1150 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001151 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001152 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001153 method_qual_type,
1154 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001155 is_static,
1156 SC_None,
1157 is_inline);
1158 }
1159 else if (num_params == 0)
1160 {
1161 // Conversion operators don't take params...
1162 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1163 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001164 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001165 method_qual_type,
1166 NULL, // TypeSourceInfo *
1167 is_inline,
1168 is_explicit);
1169 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001170 }
Greg Claytondbf26152010-10-01 23:13:49 +00001171
1172 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001173 {
1174 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1175 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001176 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001177 method_qual_type,
1178 NULL, // TypeSourceInfo *
1179 is_static,
1180 SC_None,
1181 is_inline);
1182 }
Greg Clayton30449d52010-10-01 02:31:07 +00001183 }
Greg Claytondbf26152010-10-01 23:13:49 +00001184
Greg Clayton462d4142010-09-29 01:12:09 +00001185 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001186
1187 cxx_method_decl->setAccess (access_specifier);
1188 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001189
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001190 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001191
1192 ParmVarDecl *params[num_params];
1193
1194 for (int param_index = 0;
1195 param_index < num_params;
1196 ++param_index)
1197 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001198 params[param_index] = ParmVarDecl::Create (*ast_context,
1199 cxx_method_decl,
1200 SourceLocation(),
1201 NULL, // anonymous
1202 method_function_prototype->getArgType(param_index),
1203 NULL,
1204 SC_None,
1205 SC_None,
1206 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001207 }
1208
Greg Clayton1d8173f2010-09-24 05:15:53 +00001209 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001210
Greg Clayton1d8173f2010-09-24 05:15:53 +00001211 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001212
Greg Clayton412440a2010-09-23 01:09:21 +00001213 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001214}
1215
1216bool
Greg Clayton84f80752010-07-22 18:30:50 +00001217ClangASTContext::AddFieldToRecordType
1218(
Greg Clayton462d4142010-09-29 01:12:09 +00001219 ASTContext *ast_context,
1220 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001221 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001222 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001223 AccessType access,
1224 uint32_t bitfield_bit_size
1225)
Chris Lattner24943d22010-06-08 16:52:24 +00001226{
1227 if (record_clang_type == NULL || field_type == NULL)
1228 return false;
1229
Sean Callanan60a0ced2010-09-16 20:01:08 +00001230 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001231
1232 assert (ast_context != NULL);
1233 assert (identifier_table != NULL);
1234
1235 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1236
Greg Clayton1674b122010-07-21 22:12:05 +00001237 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001238 if (clang_type)
1239 {
1240 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1241
1242 if (record_type)
1243 {
1244 RecordDecl *record_decl = record_type->getDecl();
1245
Chris Lattner24943d22010-06-08 16:52:24 +00001246 clang::Expr *bit_width = NULL;
1247 if (bitfield_bit_size != 0)
1248 {
1249 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001250 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001251 }
Greg Clayton84f80752010-07-22 18:30:50 +00001252 FieldDecl *field = FieldDecl::Create (*ast_context,
1253 record_decl,
1254 SourceLocation(),
1255 name ? &identifier_table->get(name) : NULL, // Identifier
1256 QualType::getFromOpaquePtr(field_type), // Field type
1257 NULL, // DeclaratorInfo *
1258 bit_width, // BitWidth
1259 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001260
Greg Clayton84f80752010-07-22 18:30:50 +00001261 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001262
1263 if (field)
1264 {
1265 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001266 }
1267 }
Greg Clayton9488b742010-07-28 02:04:09 +00001268 else
1269 {
1270 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1271 if (objc_class_type)
1272 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001273 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001274 ClangASTContext::AddObjCClassIVar (ast_context,
1275 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001276 name,
1277 field_type,
1278 access,
1279 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001280 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001281 }
1282 }
Chris Lattner24943d22010-06-08 16:52:24 +00001283 }
1284 return false;
1285}
1286
1287bool
1288ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1289{
1290 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1291}
1292
1293bool
1294ClangASTContext::FieldIsBitfield
1295(
1296 ASTContext *ast_context,
1297 FieldDecl* field,
1298 uint32_t& bitfield_bit_size
1299)
1300{
1301 if (ast_context == NULL || field == NULL)
1302 return false;
1303
1304 if (field->isBitField())
1305 {
1306 Expr* bit_width_expr = field->getBitWidth();
1307 if (bit_width_expr)
1308 {
1309 llvm::APSInt bit_width_apsint;
1310 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1311 {
1312 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1313 return true;
1314 }
1315 }
1316 }
1317 return false;
1318}
1319
1320bool
1321ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1322{
1323 if (record_decl == NULL)
1324 return false;
1325
1326 if (!record_decl->field_empty())
1327 return true;
1328
1329 // No fields, lets check this is a CXX record and check the base classes
1330 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1331 if (cxx_record_decl)
1332 {
1333 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1334 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1335 base_class != base_class_end;
1336 ++base_class)
1337 {
1338 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1339 if (RecordHasFields(base_class_decl))
1340 return true;
1341 }
1342 }
1343 return false;
1344}
1345
1346void
Greg Clayton462d4142010-09-29 01:12:09 +00001347ClangASTContext::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 +00001348{
1349 if (clang_qual_type)
1350 {
1351 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001352 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001353 if (clang_type)
1354 {
1355 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1356 if (record_type)
1357 {
1358 RecordDecl *record_decl = record_type->getDecl();
1359 if (record_decl)
1360 {
1361 uint32_t field_idx;
1362 RecordDecl::field_iterator field, field_end;
1363 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1364 field != field_end;
1365 ++field, ++field_idx)
1366 {
1367 // If no accessibility was assigned, assign the correct one
1368 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1369 field->setAccess ((AccessSpecifier)default_accessibility);
1370 }
1371 }
1372 }
1373 }
1374 }
1375}
1376
1377#pragma mark C++ Base Classes
1378
1379CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001380ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001381{
1382 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001383 return new CXXBaseSpecifier (SourceRange(),
1384 is_virtual,
1385 base_of_class,
1386 ConvertAccessTypeToAccessSpecifier (access),
1387 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001388 return NULL;
1389}
1390
Greg Claytone9d0df42010-07-02 01:29:13 +00001391void
1392ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1393{
1394 for (unsigned i=0; i<num_base_classes; ++i)
1395 {
1396 delete base_classes[i];
1397 base_classes[i] = NULL;
1398 }
1399}
1400
Chris Lattner24943d22010-06-08 16:52:24 +00001401bool
Greg Clayton462d4142010-09-29 01:12:09 +00001402ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001403{
1404 if (class_clang_type)
1405 {
Greg Clayton1674b122010-07-21 22:12:05 +00001406 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001407 if (clang_type)
1408 {
1409 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1410 if (record_type)
1411 {
1412 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1413 if (cxx_record_decl)
1414 {
Chris Lattner24943d22010-06-08 16:52:24 +00001415 cxx_record_decl->setBases(base_classes, num_base_classes);
1416 return true;
1417 }
1418 }
1419 }
1420 }
1421 return false;
1422}
Greg Clayton84f80752010-07-22 18:30:50 +00001423#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001424
Greg Clayton462d4142010-09-29 01:12:09 +00001425clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001426ClangASTContext::CreateObjCClass
1427(
1428 const char *name,
1429 DeclContext *decl_ctx,
1430 bool isForwardDecl,
1431 bool isInternal
1432)
1433{
1434 ASTContext *ast_context = getASTContext();
1435 assert (ast_context != NULL);
1436 assert (name && name[0]);
1437 if (decl_ctx == NULL)
1438 decl_ctx = ast_context->getTranslationUnitDecl();
1439
1440 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1441 // we will need to update this code. I was told to currently always use
1442 // the CXXRecordDecl class since we often don't know from debug information
1443 // if something is struct or a class, so we default to always use the more
1444 // complete definition just in case.
1445 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1446 decl_ctx,
1447 SourceLocation(),
1448 &ast_context->Idents.get(name),
1449 SourceLocation(),
1450 isForwardDecl,
1451 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001452
1453 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001454}
1455
1456bool
Greg Clayton462d4142010-09-29 01:12:09 +00001457ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001458{
1459 if (class_opaque_type && super_opaque_type)
1460 {
1461 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1462 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1463 clang::Type *class_type = class_qual_type.getTypePtr();
1464 clang::Type *super_type = super_qual_type.getTypePtr();
1465 if (class_type && super_type)
1466 {
1467 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1468 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1469 if (objc_class_type && objc_super_type)
1470 {
1471 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1472 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1473 if (class_interface_decl && super_interface_decl)
1474 {
1475 class_interface_decl->setSuperClass(super_interface_decl);
1476 return true;
1477 }
1478 }
1479 }
1480 }
1481 return false;
1482}
1483
1484
1485bool
1486ClangASTContext::AddObjCClassIVar
1487(
Greg Clayton462d4142010-09-29 01:12:09 +00001488 ASTContext *ast_context,
1489 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001490 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001491 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001492 AccessType access,
1493 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001494 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001495)
1496{
1497 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1498 return false;
1499
Sean Callanan60a0ced2010-09-16 20:01:08 +00001500 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001501
1502 assert (ast_context != NULL);
1503 assert (identifier_table != NULL);
1504
1505 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1506
1507 clang::Type *class_type = class_qual_type.getTypePtr();
1508 if (class_type)
1509 {
1510 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1511
1512 if (objc_class_type)
1513 {
1514 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1515
1516 if (class_interface_decl)
1517 {
1518 clang::Expr *bit_width = NULL;
1519 if (bitfield_bit_size != 0)
1520 {
1521 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001522 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001523 }
1524
Greg Clayton9488b742010-07-28 02:04:09 +00001525 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1526 class_interface_decl,
1527 SourceLocation(),
1528 &identifier_table->get(name), // Identifier
1529 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1530 NULL, // TypeSourceInfo *
1531 ConvertAccessTypeToObjCIvarAccessControl (access),
1532 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001533 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001534
1535 if (field)
1536 {
1537 class_interface_decl->addDecl(field);
1538 return true;
1539 }
Greg Clayton84f80752010-07-22 18:30:50 +00001540 }
1541 }
1542 }
1543 return false;
1544}
Chris Lattner24943d22010-06-08 16:52:24 +00001545
Greg Clayton9488b742010-07-28 02:04:09 +00001546
1547bool
Greg Clayton462d4142010-09-29 01:12:09 +00001548ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001549{
1550 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1551
1552 clang::Type *class_type = class_qual_type.getTypePtr();
1553 if (class_type)
1554 {
1555 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1556
1557 if (objc_class_type)
1558 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1559 }
1560 return false;
1561}
1562
1563bool
1564ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1565{
1566 while (class_interface_decl)
1567 {
1568 if (class_interface_decl->ivar_size() > 0)
1569 return true;
1570
1571 if (check_superclass)
1572 class_interface_decl = class_interface_decl->getSuperClass();
1573 else
1574 break;
1575 }
1576 return false;
1577}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001578
Greg Clayton462d4142010-09-29 01:12:09 +00001579ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001580ClangASTContext::AddMethodToObjCObjectType
1581(
Greg Clayton462d4142010-09-29 01:12:09 +00001582 ASTContext *ast_context,
1583 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001584 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001585 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001586 lldb::AccessType access
1587)
1588{
1589 if (class_opaque_type == NULL || method_opaque_type == NULL)
1590 return NULL;
1591
1592 IdentifierTable *identifier_table = &ast_context->Idents;
1593
1594 assert (ast_context != NULL);
1595 assert (identifier_table != NULL);
1596
1597 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1598
1599 clang::Type *class_type = class_qual_type.getTypePtr();
1600 if (class_type == NULL)
1601 return NULL;
1602
1603 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1604
1605 if (objc_class_type == NULL)
1606 return NULL;
1607
1608 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1609
1610 if (class_interface_decl == NULL)
1611 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001612
Greg Clayton1d8173f2010-09-24 05:15:53 +00001613 const char *selector_start = ::strchr (name, ' ');
1614 if (selector_start == NULL)
1615 return NULL;
1616
1617 selector_start++;
1618 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1619 return NULL;
1620 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1621
Greg Claytonad60bf42010-10-12 02:24:53 +00001622 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001623 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001624 //printf ("name = '%s'\n", name);
1625
1626 unsigned num_selectors_with_args = 0;
1627 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001628 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001629 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001630 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001631 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001632 bool has_arg = (start[len] == ':');
1633 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001634 ++num_selectors_with_args;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001635 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001636 if (has_arg)
1637 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001638 }
1639
1640
1641 if (selector_idents.size() == 0)
1642 return 0;
1643
Greg Claytonad60bf42010-10-12 02:24:53 +00001644 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001645 selector_idents.data());
1646
1647 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1648
1649 // Populate the method decl with parameter decls
1650 clang::Type *method_type(method_qual_type.getTypePtr());
1651
1652 if (method_type == NULL)
1653 return NULL;
1654
1655 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1656
1657 if (!method_function_prototype)
1658 return NULL;
1659
1660
1661 bool is_variadic = false;
1662 bool is_synthesized = false;
1663 bool is_defined = false;
1664 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1665
1666 const unsigned num_args = method_function_prototype->getNumArgs();
1667
1668 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1669 SourceLocation(), // beginLoc,
1670 SourceLocation(), // endLoc,
1671 method_selector,
1672 method_function_prototype->getResultType(),
1673 NULL, // TypeSourceInfo *ResultTInfo,
1674 GetDeclContextForType (class_opaque_type),
1675 name[0] == '-',
1676 is_variadic,
1677 is_synthesized,
1678 is_defined,
1679 imp_control,
1680 num_args);
1681
1682
1683 if (objc_method_decl == NULL)
1684 return NULL;
1685
1686 if (num_args > 0)
1687 {
1688 llvm::SmallVector<ParmVarDecl *, 12> params;
1689
1690 for (int param_index = 0; param_index < num_args; ++param_index)
1691 {
1692 params.push_back (ParmVarDecl::Create (*ast_context,
1693 objc_method_decl,
1694 SourceLocation(),
1695 NULL, // anonymous
1696 method_function_prototype->getArgType(param_index),
1697 NULL,
1698 SC_Auto,
1699 SC_Auto,
1700 NULL));
1701 }
1702
1703 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1704 }
1705
1706 class_interface_decl->addDecl (objc_method_decl);
1707
1708
1709 return objc_method_decl;
1710}
1711
1712
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001713uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001714ClangASTContext::GetTypeInfo
1715(
1716 clang_type_t clang_type,
1717 clang::ASTContext *ast_context,
1718 clang_type_t *pointee_or_element_clang_type
1719)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001720{
1721 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001722 return 0;
1723
1724 if (pointee_or_element_clang_type)
1725 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001726
1727 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1728
1729 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1730 switch (type_class)
1731 {
Sean Callanan04325062010-10-25 00:29:48 +00001732 case clang::Type::Builtin:
1733 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1734 {
Sean Callanan04325062010-10-25 00:29:48 +00001735 case clang::BuiltinType::ObjCId:
1736 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001737 if (ast_context && pointee_or_element_clang_type)
1738 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001739 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001740
1741 default:
1742 break;
Sean Callanan04325062010-10-25 00:29:48 +00001743 }
1744 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001745
1746 case clang::Type::BlockPointer:
1747 if (pointee_or_element_clang_type)
1748 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1749 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1750
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001751 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001752
1753 case clang::Type::ConstantArray:
1754 case clang::Type::DependentSizedArray:
1755 case clang::Type::IncompleteArray:
1756 case clang::Type::VariableArray:
1757 if (pointee_or_element_clang_type)
1758 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1759 return eTypeHasChildren | eTypeIsArray;
1760
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001761 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001762 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1763 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1764 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001765
1766 case clang::Type::Enum:
1767 if (pointee_or_element_clang_type)
1768 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1769 return eTypeIsEnumeration | eTypeHasValue;
1770
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001771 case clang::Type::Elaborated: return 0;
1772 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1773 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1774 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001775 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001776
1777 case clang::Type::LValueReference:
1778 case clang::Type::RValueReference:
1779 if (pointee_or_element_clang_type)
1780 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1781 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1782
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001783 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001784
1785 case clang::Type::ObjCObjectPointer:
1786 if (pointee_or_element_clang_type)
1787 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1788 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1789
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001790 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1791 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001792
1793 case clang::Type::Pointer:
1794 if (pointee_or_element_clang_type)
1795 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1796 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1797
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001798 case clang::Type::Record:
1799 if (qual_type->getAsCXXRecordDecl())
1800 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1801 else
1802 return eTypeHasChildren | eTypeIsStructUnion;
1803 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001804 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1805 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1806 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001807
1808 case clang::Type::Typedef:
1809 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1810 ast_context,
1811 pointee_or_element_clang_type);
1812
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001813 case clang::Type::TypeOfExpr: return 0;
1814 case clang::Type::TypeOf: return 0;
1815 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001816 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1817 default: return 0;
1818 }
1819 return 0;
1820}
1821
Greg Clayton9488b742010-07-28 02:04:09 +00001822
Chris Lattner24943d22010-06-08 16:52:24 +00001823#pragma mark Aggregate Types
1824
1825bool
Greg Clayton462d4142010-09-29 01:12:09 +00001826ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001827{
1828 if (clang_type == NULL)
1829 return false;
1830
1831 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1832
Greg Clayton03e0f972010-09-13 03:32:57 +00001833 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1834 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001835 {
Greg Clayton1674b122010-07-21 22:12:05 +00001836 case clang::Type::IncompleteArray:
1837 case clang::Type::VariableArray:
1838 case clang::Type::ConstantArray:
1839 case clang::Type::ExtVector:
1840 case clang::Type::Vector:
1841 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001842 case clang::Type::ObjCObject:
1843 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001844 return true;
1845
Greg Clayton1674b122010-07-21 22:12:05 +00001846 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001847 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1848
1849 default:
1850 break;
1851 }
1852 // The clang type does have a value
1853 return false;
1854}
1855
1856uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001857ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001858{
1859 if (clang_qual_type == NULL)
1860 return 0;
1861
1862 uint32_t num_children = 0;
1863 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001864 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1865 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001866 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001867 case clang::Type::Builtin:
1868 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1869 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001870 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001871 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001872 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001873 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001874
1875 default:
1876 break;
1877 }
1878 break;
1879
Greg Clayton1674b122010-07-21 22:12:05 +00001880 case clang::Type::Record:
Greg Clayton53d287b2010-11-11 02:14:53 +00001881 if (ClangASTType::IsDefined (clang_qual_type))
Chris Lattner24943d22010-06-08 16:52:24 +00001882 {
1883 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1884 const RecordDecl *record_decl = record_type->getDecl();
1885 assert(record_decl);
1886 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1887 if (cxx_record_decl)
1888 {
1889 if (omit_empty_base_classes)
1890 {
1891 // Check each base classes to see if it or any of its
1892 // base classes contain any fields. This can help
1893 // limit the noise in variable views by not having to
1894 // show base classes that contain no members.
1895 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1896 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1897 base_class != base_class_end;
1898 ++base_class)
1899 {
1900 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1901
1902 // Skip empty base classes
1903 if (RecordHasFields(base_class_decl) == false)
1904 continue;
1905
1906 num_children++;
1907 }
1908 }
1909 else
1910 {
1911 // Include all base classes
1912 num_children += cxx_record_decl->getNumBases();
1913 }
1914
1915 }
1916 RecordDecl::field_iterator field, field_end;
1917 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1918 ++num_children;
1919 }
1920 break;
1921
Greg Clayton9488b742010-07-28 02:04:09 +00001922 case clang::Type::ObjCObject:
1923 case clang::Type::ObjCInterface:
1924 {
1925 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1926 assert (objc_class_type);
1927 if (objc_class_type)
1928 {
1929 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1930
1931 if (class_interface_decl)
1932 {
1933
1934 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1935 if (superclass_interface_decl)
1936 {
1937 if (omit_empty_base_classes)
1938 {
1939 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1940 ++num_children;
1941 }
1942 else
1943 ++num_children;
1944 }
1945
1946 num_children += class_interface_decl->ivar_size();
1947 }
1948 }
1949 }
1950 break;
1951
1952 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001953 {
1954 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1955 QualType pointee_type = pointer_type->getPointeeType();
1956 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1957 omit_empty_base_classes);
1958 // If this type points to a simple type, then it has 1 child
1959 if (num_pointee_children == 0)
1960 num_children = 1;
1961 else
1962 num_children = num_pointee_children;
1963 }
1964 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001965
Greg Clayton1674b122010-07-21 22:12:05 +00001966 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001967 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1968 break;
1969
Greg Clayton1674b122010-07-21 22:12:05 +00001970 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001971 {
1972 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1973 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001974 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1975 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001976 // If this type points to a simple type, then it has 1 child
1977 if (num_pointee_children == 0)
1978 num_children = 1;
1979 else
1980 num_children = num_pointee_children;
1981 }
1982 break;
1983
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001984 case clang::Type::LValueReference:
1985 case clang::Type::RValueReference:
1986 {
1987 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1988 QualType pointee_type = reference_type->getPointeeType();
1989 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1990 omit_empty_base_classes);
1991 // If this type points to a simple type, then it has 1 child
1992 if (num_pointee_children == 0)
1993 num_children = 1;
1994 else
1995 num_children = num_pointee_children;
1996 }
1997 break;
1998
1999
Greg Clayton1674b122010-07-21 22:12:05 +00002000 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002001 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
2002 break;
2003
2004 default:
2005 break;
2006 }
2007 return num_children;
2008}
2009
2010
Greg Clayton462d4142010-09-29 01:12:09 +00002011clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002012ClangASTContext::GetChildClangTypeAtIndex
2013(
2014 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002015 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002016 uint32_t idx,
2017 bool transparent_pointers,
2018 bool omit_empty_base_classes,
2019 std::string& child_name,
2020 uint32_t &child_byte_size,
2021 int32_t &child_byte_offset,
2022 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002023 uint32_t &child_bitfield_bit_offset,
2024 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002025)
2026{
2027 if (parent_clang_type)
2028
2029 return GetChildClangTypeAtIndex (getASTContext(),
2030 parent_name,
2031 parent_clang_type,
2032 idx,
2033 transparent_pointers,
2034 omit_empty_base_classes,
2035 child_name,
2036 child_byte_size,
2037 child_byte_offset,
2038 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002039 child_bitfield_bit_offset,
2040 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002041 return NULL;
2042}
2043
Greg Clayton462d4142010-09-29 01:12:09 +00002044clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002045ClangASTContext::GetChildClangTypeAtIndex
2046(
2047 ASTContext *ast_context,
2048 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002049 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002050 uint32_t idx,
2051 bool transparent_pointers,
2052 bool omit_empty_base_classes,
2053 std::string& child_name,
2054 uint32_t &child_byte_size,
2055 int32_t &child_byte_offset,
2056 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002057 uint32_t &child_bitfield_bit_offset,
2058 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002059)
2060{
2061 if (parent_clang_type == NULL)
2062 return NULL;
2063
2064 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2065 {
2066 uint32_t bit_offset;
2067 child_bitfield_bit_size = 0;
2068 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002069 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002070 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002071 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2072 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002073 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002074 case clang::Type::Builtin:
2075 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2076 {
2077 case clang::BuiltinType::ObjCId:
2078 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002079 child_name = "isa";
2080 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002081 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2082
Greg Clayton960d6a42010-08-03 00:35:52 +00002083 default:
2084 break;
2085 }
2086 break;
2087
2088
Greg Clayton1674b122010-07-21 22:12:05 +00002089 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002090 {
2091 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2092 const RecordDecl *record_decl = record_type->getDecl();
2093 assert(record_decl);
2094 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2095 uint32_t child_idx = 0;
2096
2097 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2098 if (cxx_record_decl)
2099 {
2100 // We might have base classes to print out first
2101 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2102 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2103 base_class != base_class_end;
2104 ++base_class)
2105 {
2106 const CXXRecordDecl *base_class_decl = NULL;
2107
2108 // Skip empty base classes
2109 if (omit_empty_base_classes)
2110 {
2111 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2112 if (RecordHasFields(base_class_decl) == false)
2113 continue;
2114 }
2115
2116 if (idx == child_idx)
2117 {
2118 if (base_class_decl == NULL)
2119 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2120
2121
2122 if (base_class->isVirtual())
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002123 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002124 else
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002125 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002126
2127 // Base classes should be a multiple of 8 bits in size
2128 assert (bit_offset % 8 == 0);
2129 child_byte_offset = bit_offset/8;
2130 std::string base_class_type_name(base_class->getType().getAsString());
2131
2132 child_name.assign(base_class_type_name.c_str());
2133
2134 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2135
2136 // Base classes biut sizes should be a multiple of 8 bits in size
2137 assert (clang_type_info_bit_size % 8 == 0);
2138 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002139 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002140 return base_class->getType().getAsOpaquePtr();
2141 }
2142 // We don't increment the child index in the for loop since we might
2143 // be skipping empty base classes
2144 ++child_idx;
2145 }
2146 }
Chris Lattner24943d22010-06-08 16:52:24 +00002147 // Make sure index is in range...
2148 uint32_t field_idx = 0;
2149 RecordDecl::field_iterator field, field_end;
2150 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2151 {
2152 if (idx == child_idx)
2153 {
2154 // Print the member type if requested
2155 // Print the member name and equal sign
2156 child_name.assign(field->getNameAsString().c_str());
2157
2158 // Figure out the type byte size (field_type_info.first) and
2159 // alignment (field_type_info.second) from the AST context.
2160 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002161 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002162
2163 child_byte_size = field_type_info.first / 8;
2164
2165 // Figure out the field offset within the current struct/union/class type
2166 bit_offset = record_layout.getFieldOffset (field_idx);
2167 child_byte_offset = bit_offset / 8;
2168 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2169 child_bitfield_bit_offset = bit_offset % 8;
2170
2171 return field->getType().getAsOpaquePtr();
2172 }
2173 }
2174 }
2175 break;
2176
Greg Clayton9488b742010-07-28 02:04:09 +00002177 case clang::Type::ObjCObject:
2178 case clang::Type::ObjCInterface:
2179 {
2180 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2181 assert (objc_class_type);
2182 if (objc_class_type)
2183 {
2184 uint32_t child_idx = 0;
2185 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2186
2187 if (class_interface_decl)
2188 {
2189
2190 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2191 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2192 if (superclass_interface_decl)
2193 {
2194 if (omit_empty_base_classes)
2195 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002196 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002197 {
2198 if (idx == 0)
2199 {
2200 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2201
2202
2203 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2204
2205 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2206
2207 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002208 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002209 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002210
2211 return ivar_qual_type.getAsOpaquePtr();
2212 }
2213
2214 ++child_idx;
2215 }
2216 }
2217 else
2218 ++child_idx;
2219 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002220
2221 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002222
2223 if (idx < (child_idx + class_interface_decl->ivar_size()))
2224 {
2225 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2226
2227 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2228 {
2229 if (child_idx == idx)
2230 {
2231 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2232
2233 QualType ivar_qual_type(ivar_decl->getType());
2234
2235 child_name.assign(ivar_decl->getNameAsString().c_str());
2236
2237 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2238
2239 child_byte_size = ivar_type_info.first / 8;
2240
2241 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002242 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002243 child_byte_offset = bit_offset / 8;
2244
2245 return ivar_qual_type.getAsOpaquePtr();
2246 }
2247 ++child_idx;
2248 }
2249 }
2250 }
2251 }
2252 }
2253 break;
2254
2255 case clang::Type::ObjCObjectPointer:
2256 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002257 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2258 QualType pointee_type = pointer_type->getPointeeType();
2259
2260 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2261 {
2262 return GetChildClangTypeAtIndex (ast_context,
2263 parent_name,
2264 pointer_type->getPointeeType().getAsOpaquePtr(),
2265 idx,
2266 transparent_pointers,
2267 omit_empty_base_classes,
2268 child_name,
2269 child_byte_size,
2270 child_byte_offset,
2271 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002272 child_bitfield_bit_offset,
2273 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002274 }
2275 else
2276 {
2277 if (parent_name)
2278 {
2279 child_name.assign(1, '*');
2280 child_name += parent_name;
2281 }
2282
2283 // We have a pointer to an simple type
2284 if (idx == 0)
2285 {
2286 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2287 assert(clang_type_info.first % 8 == 0);
2288 child_byte_size = clang_type_info.first / 8;
2289 child_byte_offset = 0;
2290 return pointee_type.getAsOpaquePtr();
2291 }
2292 }
Greg Clayton9488b742010-07-28 02:04:09 +00002293 }
2294 break;
2295
Greg Clayton1674b122010-07-21 22:12:05 +00002296 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002297 {
2298 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2299 const uint64_t element_count = array->getSize().getLimitedValue();
2300
2301 if (idx < element_count)
2302 {
2303 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2304
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002305 char element_name[64];
2306 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002307
2308 child_name.assign(element_name);
2309 assert(field_type_info.first % 8 == 0);
2310 child_byte_size = field_type_info.first / 8;
2311 child_byte_offset = idx * child_byte_size;
2312 return array->getElementType().getAsOpaquePtr();
2313 }
2314 }
2315 break;
2316
Greg Clayton1674b122010-07-21 22:12:05 +00002317 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002318 {
2319 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2320 QualType pointee_type = pointer_type->getPointeeType();
2321
2322 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2323 {
2324 return GetChildClangTypeAtIndex (ast_context,
2325 parent_name,
2326 pointer_type->getPointeeType().getAsOpaquePtr(),
2327 idx,
2328 transparent_pointers,
2329 omit_empty_base_classes,
2330 child_name,
2331 child_byte_size,
2332 child_byte_offset,
2333 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002334 child_bitfield_bit_offset,
2335 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002336 }
2337 else
2338 {
2339 if (parent_name)
2340 {
2341 child_name.assign(1, '*');
2342 child_name += parent_name;
2343 }
2344
2345 // We have a pointer to an simple type
2346 if (idx == 0)
2347 {
2348 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2349 assert(clang_type_info.first % 8 == 0);
2350 child_byte_size = clang_type_info.first / 8;
2351 child_byte_offset = 0;
2352 return pointee_type.getAsOpaquePtr();
2353 }
2354 }
2355 }
2356 break;
2357
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002358 case clang::Type::LValueReference:
2359 case clang::Type::RValueReference:
2360 {
2361 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2362 QualType pointee_type(reference_type->getPointeeType());
2363 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2364 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2365 {
2366 return GetChildClangTypeAtIndex (ast_context,
2367 parent_name,
2368 pointee_clang_type,
2369 idx,
2370 transparent_pointers,
2371 omit_empty_base_classes,
2372 child_name,
2373 child_byte_size,
2374 child_byte_offset,
2375 child_bitfield_bit_size,
2376 child_bitfield_bit_offset,
2377 child_is_base_class);
2378 }
2379 else
2380 {
2381 if (parent_name)
2382 {
2383 child_name.assign(1, '&');
2384 child_name += parent_name;
2385 }
2386
2387 // We have a pointer to an simple type
2388 if (idx == 0)
2389 {
2390 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2391 assert(clang_type_info.first % 8 == 0);
2392 child_byte_size = clang_type_info.first / 8;
2393 child_byte_offset = 0;
2394 return pointee_type.getAsOpaquePtr();
2395 }
2396 }
2397 }
2398 break;
2399
Greg Clayton1674b122010-07-21 22:12:05 +00002400 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002401 return GetChildClangTypeAtIndex (ast_context,
2402 parent_name,
2403 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2404 idx,
2405 transparent_pointers,
2406 omit_empty_base_classes,
2407 child_name,
2408 child_byte_size,
2409 child_byte_offset,
2410 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002411 child_bitfield_bit_offset,
2412 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002413 break;
2414
2415 default:
2416 break;
2417 }
2418 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002419 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002420}
2421
2422static inline bool
2423BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2424{
2425 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2426}
2427
2428static uint32_t
2429GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2430{
2431 uint32_t num_bases = 0;
2432 if (cxx_record_decl)
2433 {
2434 if (omit_empty_base_classes)
2435 {
2436 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2437 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2438 base_class != base_class_end;
2439 ++base_class)
2440 {
2441 // Skip empty base classes
2442 if (omit_empty_base_classes)
2443 {
2444 if (BaseSpecifierIsEmpty (base_class))
2445 continue;
2446 }
2447 ++num_bases;
2448 }
2449 }
2450 else
2451 num_bases = cxx_record_decl->getNumBases();
2452 }
2453 return num_bases;
2454}
2455
2456
2457static uint32_t
2458GetIndexForRecordBase
2459(
2460 const RecordDecl *record_decl,
2461 const CXXBaseSpecifier *base_spec,
2462 bool omit_empty_base_classes
2463)
2464{
2465 uint32_t child_idx = 0;
2466
2467 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2468
2469// const char *super_name = record_decl->getNameAsCString();
2470// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2471// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2472//
2473 if (cxx_record_decl)
2474 {
2475 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2476 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2477 base_class != base_class_end;
2478 ++base_class)
2479 {
2480 if (omit_empty_base_classes)
2481 {
2482 if (BaseSpecifierIsEmpty (base_class))
2483 continue;
2484 }
2485
2486// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2487// child_idx,
2488// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2489//
2490//
2491 if (base_class == base_spec)
2492 return child_idx;
2493 ++child_idx;
2494 }
2495 }
2496
2497 return UINT32_MAX;
2498}
2499
2500
2501static uint32_t
2502GetIndexForRecordChild
2503(
2504 const RecordDecl *record_decl,
2505 NamedDecl *canonical_decl,
2506 bool omit_empty_base_classes
2507)
2508{
2509 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2510
2511// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2512//
2513//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2514// if (cxx_record_decl)
2515// {
2516// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2517// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2518// base_class != base_class_end;
2519// ++base_class)
2520// {
2521// if (omit_empty_base_classes)
2522// {
2523// if (BaseSpecifierIsEmpty (base_class))
2524// continue;
2525// }
2526//
2527//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2528//// record_decl->getNameAsCString(),
2529//// canonical_decl->getNameAsCString(),
2530//// child_idx,
2531//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2532//
2533//
2534// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2535// if (curr_base_class_decl == canonical_decl)
2536// {
2537// return child_idx;
2538// }
2539// ++child_idx;
2540// }
2541// }
2542//
2543// const uint32_t num_bases = child_idx;
2544 RecordDecl::field_iterator field, field_end;
2545 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2546 field != field_end;
2547 ++field, ++child_idx)
2548 {
2549// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2550// record_decl->getNameAsCString(),
2551// canonical_decl->getNameAsCString(),
2552// child_idx - num_bases,
2553// field->getNameAsCString());
2554
2555 if (field->getCanonicalDecl() == canonical_decl)
2556 return child_idx;
2557 }
2558
2559 return UINT32_MAX;
2560}
2561
2562// Look for a child member (doesn't include base classes, but it does include
2563// their members) in the type hierarchy. Returns an index path into "clang_type"
2564// on how to reach the appropriate member.
2565//
2566// class A
2567// {
2568// public:
2569// int m_a;
2570// int m_b;
2571// };
2572//
2573// class B
2574// {
2575// };
2576//
2577// class C :
2578// public B,
2579// public A
2580// {
2581// };
2582//
2583// If we have a clang type that describes "class C", and we wanted to looked
2584// "m_b" in it:
2585//
2586// With omit_empty_base_classes == false we would get an integer array back with:
2587// { 1, 1 }
2588// The first index 1 is the child index for "class A" within class C
2589// The second index 1 is the child index for "m_b" within class A
2590//
2591// With omit_empty_base_classes == true we would get an integer array back with:
2592// { 0, 1 }
2593// 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)
2594// The second index 1 is the child index for "m_b" within class A
2595
2596size_t
2597ClangASTContext::GetIndexOfChildMemberWithName
2598(
2599 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002600 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002601 const char *name,
2602 bool omit_empty_base_classes,
2603 std::vector<uint32_t>& child_indexes
2604)
2605{
2606 if (clang_type && name && name[0])
2607 {
2608 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002609 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2610 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002611 {
Greg Clayton1674b122010-07-21 22:12:05 +00002612 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002613 {
2614 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2615 const RecordDecl *record_decl = record_type->getDecl();
2616
2617 assert(record_decl);
2618 uint32_t child_idx = 0;
2619
2620 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2621
2622 // Try and find a field that matches NAME
2623 RecordDecl::field_iterator field, field_end;
2624 StringRef name_sref(name);
2625 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2626 field != field_end;
2627 ++field, ++child_idx)
2628 {
2629 if (field->getName().equals (name_sref))
2630 {
2631 // We have to add on the number of base classes to this index!
2632 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2633 return child_indexes.size();
2634 }
2635 }
2636
2637 if (cxx_record_decl)
2638 {
2639 const RecordDecl *parent_record_decl = cxx_record_decl;
2640
2641 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2642
2643 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2644 // Didn't find things easily, lets let clang do its thang...
2645 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2646 DeclarationName decl_name(&ident_ref);
2647
2648 CXXBasePaths paths;
2649 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2650 decl_name.getAsOpaquePtr(),
2651 paths))
2652 {
Chris Lattner24943d22010-06-08 16:52:24 +00002653 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2654 for (path = paths.begin(); path != path_end; ++path)
2655 {
2656 const size_t num_path_elements = path->size();
2657 for (size_t e=0; e<num_path_elements; ++e)
2658 {
2659 CXXBasePathElement elem = (*path)[e];
2660
2661 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2662 if (child_idx == UINT32_MAX)
2663 {
2664 child_indexes.clear();
2665 return 0;
2666 }
2667 else
2668 {
2669 child_indexes.push_back (child_idx);
2670 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2671 }
2672 }
2673 DeclContext::lookup_iterator named_decl_pos;
2674 for (named_decl_pos = path->Decls.first;
2675 named_decl_pos != path->Decls.second && parent_record_decl;
2676 ++named_decl_pos)
2677 {
2678 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2679
2680 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2681 if (child_idx == UINT32_MAX)
2682 {
2683 child_indexes.clear();
2684 return 0;
2685 }
2686 else
2687 {
2688 child_indexes.push_back (child_idx);
2689 }
2690 }
2691 }
2692 return child_indexes.size();
2693 }
2694 }
2695
2696 }
2697 break;
2698
Greg Clayton9488b742010-07-28 02:04:09 +00002699 case clang::Type::ObjCObject:
2700 case clang::Type::ObjCInterface:
2701 {
2702 StringRef name_sref(name);
2703 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2704 assert (objc_class_type);
2705 if (objc_class_type)
2706 {
2707 uint32_t child_idx = 0;
2708 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2709
2710 if (class_interface_decl)
2711 {
2712 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2713 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2714
Greg Clayton823533e2010-09-18 02:11:07 +00002715 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002716 {
2717 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2718
2719 if (ivar_decl->getName().equals (name_sref))
2720 {
2721 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2722 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2723 ++child_idx;
2724
2725 child_indexes.push_back (child_idx);
2726 return child_indexes.size();
2727 }
2728 }
2729
2730 if (superclass_interface_decl)
2731 {
2732 // The super class index is always zero for ObjC classes,
2733 // so we push it onto the child indexes in case we find
2734 // an ivar in our superclass...
2735 child_indexes.push_back (0);
2736
2737 if (GetIndexOfChildMemberWithName (ast_context,
2738 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2739 name,
2740 omit_empty_base_classes,
2741 child_indexes))
2742 {
2743 // We did find an ivar in a superclass so just
2744 // return the results!
2745 return child_indexes.size();
2746 }
2747
2748 // We didn't find an ivar matching "name" in our
2749 // superclass, pop the superclass zero index that
2750 // we pushed on above.
2751 child_indexes.pop_back();
2752 }
2753 }
2754 }
2755 }
2756 break;
2757
2758 case clang::Type::ObjCObjectPointer:
2759 {
2760 return GetIndexOfChildMemberWithName (ast_context,
2761 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2762 name,
2763 omit_empty_base_classes,
2764 child_indexes);
2765 }
2766 break;
2767
2768
Greg Clayton1674b122010-07-21 22:12:05 +00002769 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002770 {
2771// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2772// const uint64_t element_count = array->getSize().getLimitedValue();
2773//
2774// if (idx < element_count)
2775// {
2776// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2777//
2778// char element_name[32];
2779// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2780//
2781// child_name.assign(element_name);
2782// assert(field_type_info.first % 8 == 0);
2783// child_byte_size = field_type_info.first / 8;
2784// child_byte_offset = idx * child_byte_size;
2785// return array->getElementType().getAsOpaquePtr();
2786// }
2787 }
2788 break;
2789
Greg Clayton1674b122010-07-21 22:12:05 +00002790// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002791// {
2792// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2793// QualType pointee_type = mem_ptr_type->getPointeeType();
2794//
2795// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2796// {
2797// return GetIndexOfChildWithName (ast_context,
2798// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2799// name);
2800// }
2801// }
2802// break;
2803//
Greg Clayton1674b122010-07-21 22:12:05 +00002804 case clang::Type::LValueReference:
2805 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002806 {
2807 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2808 QualType pointee_type = reference_type->getPointeeType();
2809
2810 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2811 {
2812 return GetIndexOfChildMemberWithName (ast_context,
2813 reference_type->getPointeeType().getAsOpaquePtr(),
2814 name,
2815 omit_empty_base_classes,
2816 child_indexes);
2817 }
2818 }
2819 break;
2820
Greg Clayton1674b122010-07-21 22:12:05 +00002821 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002822 {
2823 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2824 QualType pointee_type = pointer_type->getPointeeType();
2825
2826 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2827 {
2828 return GetIndexOfChildMemberWithName (ast_context,
2829 pointer_type->getPointeeType().getAsOpaquePtr(),
2830 name,
2831 omit_empty_base_classes,
2832 child_indexes);
2833 }
2834 else
2835 {
2836// if (parent_name)
2837// {
2838// child_name.assign(1, '*');
2839// child_name += parent_name;
2840// }
2841//
2842// // We have a pointer to an simple type
2843// if (idx == 0)
2844// {
2845// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2846// assert(clang_type_info.first % 8 == 0);
2847// child_byte_size = clang_type_info.first / 8;
2848// child_byte_offset = 0;
2849// return pointee_type.getAsOpaquePtr();
2850// }
2851 }
2852 }
2853 break;
2854
Greg Clayton1674b122010-07-21 22:12:05 +00002855 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002856 return GetIndexOfChildMemberWithName (ast_context,
2857 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2858 name,
2859 omit_empty_base_classes,
2860 child_indexes);
2861
2862 default:
2863 break;
2864 }
2865 }
2866 return 0;
2867}
2868
2869
2870// Get the index of the child of "clang_type" whose name matches. This function
2871// doesn't descend into the children, but only looks one level deep and name
2872// matches can include base class names.
2873
2874uint32_t
2875ClangASTContext::GetIndexOfChildWithName
2876(
2877 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002878 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002879 const char *name,
2880 bool omit_empty_base_classes
2881)
2882{
2883 if (clang_type && name && name[0])
2884 {
2885 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002886
Greg Clayton03e0f972010-09-13 03:32:57 +00002887 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002888
Greg Clayton03e0f972010-09-13 03:32:57 +00002889 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002890 {
Greg Clayton1674b122010-07-21 22:12:05 +00002891 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002892 {
2893 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2894 const RecordDecl *record_decl = record_type->getDecl();
2895
2896 assert(record_decl);
2897 uint32_t child_idx = 0;
2898
2899 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2900
2901 if (cxx_record_decl)
2902 {
2903 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2904 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2905 base_class != base_class_end;
2906 ++base_class)
2907 {
2908 // Skip empty base classes
2909 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2910 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2911 continue;
2912
2913 if (base_class->getType().getAsString().compare (name) == 0)
2914 return child_idx;
2915 ++child_idx;
2916 }
2917 }
2918
2919 // Try and find a field that matches NAME
2920 RecordDecl::field_iterator field, field_end;
2921 StringRef name_sref(name);
2922 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2923 field != field_end;
2924 ++field, ++child_idx)
2925 {
2926 if (field->getName().equals (name_sref))
2927 return child_idx;
2928 }
2929
2930 }
2931 break;
2932
Greg Clayton9488b742010-07-28 02:04:09 +00002933 case clang::Type::ObjCObject:
2934 case clang::Type::ObjCInterface:
2935 {
2936 StringRef name_sref(name);
2937 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2938 assert (objc_class_type);
2939 if (objc_class_type)
2940 {
2941 uint32_t child_idx = 0;
2942 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2943
2944 if (class_interface_decl)
2945 {
2946 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2947 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2948
2949 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2950 {
2951 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2952
2953 if (ivar_decl->getName().equals (name_sref))
2954 {
2955 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2956 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2957 ++child_idx;
2958
2959 return child_idx;
2960 }
2961 }
2962
2963 if (superclass_interface_decl)
2964 {
2965 if (superclass_interface_decl->getName().equals (name_sref))
2966 return 0;
2967 }
2968 }
2969 }
2970 }
2971 break;
2972
2973 case clang::Type::ObjCObjectPointer:
2974 {
2975 return GetIndexOfChildWithName (ast_context,
2976 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2977 name,
2978 omit_empty_base_classes);
2979 }
2980 break;
2981
Greg Clayton1674b122010-07-21 22:12:05 +00002982 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002983 {
2984// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2985// const uint64_t element_count = array->getSize().getLimitedValue();
2986//
2987// if (idx < element_count)
2988// {
2989// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2990//
2991// char element_name[32];
2992// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2993//
2994// child_name.assign(element_name);
2995// assert(field_type_info.first % 8 == 0);
2996// child_byte_size = field_type_info.first / 8;
2997// child_byte_offset = idx * child_byte_size;
2998// return array->getElementType().getAsOpaquePtr();
2999// }
3000 }
3001 break;
3002
Greg Clayton1674b122010-07-21 22:12:05 +00003003// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00003004// {
3005// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3006// QualType pointee_type = mem_ptr_type->getPointeeType();
3007//
3008// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3009// {
3010// return GetIndexOfChildWithName (ast_context,
3011// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3012// name);
3013// }
3014// }
3015// break;
3016//
Greg Clayton1674b122010-07-21 22:12:05 +00003017 case clang::Type::LValueReference:
3018 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003019 {
3020 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3021 QualType pointee_type = reference_type->getPointeeType();
3022
3023 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3024 {
3025 return GetIndexOfChildWithName (ast_context,
3026 reference_type->getPointeeType().getAsOpaquePtr(),
3027 name,
3028 omit_empty_base_classes);
3029 }
3030 }
3031 break;
3032
Greg Clayton1674b122010-07-21 22:12:05 +00003033 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003034 {
3035 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3036 QualType pointee_type = pointer_type->getPointeeType();
3037
3038 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3039 {
3040 return GetIndexOfChildWithName (ast_context,
3041 pointer_type->getPointeeType().getAsOpaquePtr(),
3042 name,
3043 omit_empty_base_classes);
3044 }
3045 else
3046 {
3047// if (parent_name)
3048// {
3049// child_name.assign(1, '*');
3050// child_name += parent_name;
3051// }
3052//
3053// // We have a pointer to an simple type
3054// if (idx == 0)
3055// {
3056// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3057// assert(clang_type_info.first % 8 == 0);
3058// child_byte_size = clang_type_info.first / 8;
3059// child_byte_offset = 0;
3060// return pointee_type.getAsOpaquePtr();
3061// }
3062 }
3063 }
3064 break;
3065
Greg Clayton1674b122010-07-21 22:12:05 +00003066 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003067 return GetIndexOfChildWithName (ast_context,
3068 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3069 name,
3070 omit_empty_base_classes);
3071
3072 default:
3073 break;
3074 }
3075 }
3076 return UINT32_MAX;
3077}
3078
3079#pragma mark TagType
3080
3081bool
Greg Clayton462d4142010-09-29 01:12:09 +00003082ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003083{
3084 if (tag_clang_type)
3085 {
3086 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003087 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003088 if (clang_type)
3089 {
3090 TagType *tag_type = dyn_cast<TagType>(clang_type);
3091 if (tag_type)
3092 {
3093 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3094 if (tag_decl)
3095 {
3096 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3097 return true;
3098 }
3099 }
3100 }
3101 }
3102 return false;
3103}
3104
3105
3106#pragma mark DeclContext Functions
3107
3108DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003109ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003110{
3111 if (clang_type == NULL)
3112 return NULL;
3113
3114 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003115 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3116 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003117 {
Greg Clayton9488b742010-07-28 02:04:09 +00003118 case clang::Type::FunctionNoProto: break;
3119 case clang::Type::FunctionProto: break;
3120 case clang::Type::IncompleteArray: break;
3121 case clang::Type::VariableArray: break;
3122 case clang::Type::ConstantArray: break;
3123 case clang::Type::ExtVector: break;
3124 case clang::Type::Vector: break;
3125 case clang::Type::Builtin: break;
3126 case clang::Type::BlockPointer: break;
3127 case clang::Type::Pointer: break;
3128 case clang::Type::LValueReference: break;
3129 case clang::Type::RValueReference: break;
3130 case clang::Type::MemberPointer: break;
3131 case clang::Type::Complex: break;
3132 case clang::Type::ObjCObject: break;
3133 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3134 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3135 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3136 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
3137 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003138
Greg Clayton9488b742010-07-28 02:04:09 +00003139 case clang::Type::TypeOfExpr: break;
3140 case clang::Type::TypeOf: break;
3141 case clang::Type::Decltype: break;
3142 //case clang::Type::QualifiedName: break;
3143 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003144 }
3145 // No DeclContext in this type...
3146 return NULL;
3147}
3148
3149#pragma mark Namespace Declarations
3150
3151NamespaceDecl *
3152ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3153{
3154 // TODO: Do something intelligent with the Declaration object passed in
3155 // like maybe filling in the SourceLocation with it...
3156 if (name)
3157 {
3158 ASTContext *ast_context = getASTContext();
3159 if (decl_ctx == NULL)
3160 decl_ctx = ast_context->getTranslationUnitDecl();
3161 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3162 }
3163 return NULL;
3164}
3165
3166
3167#pragma mark Function Types
3168
3169FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003170ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003171{
3172 if (name)
3173 {
3174 ASTContext *ast_context = getASTContext();
3175 assert (ast_context != NULL);
3176
3177 if (name && name[0])
3178 {
3179 return FunctionDecl::Create(*ast_context,
3180 ast_context->getTranslationUnitDecl(),
3181 SourceLocation(),
3182 DeclarationName (&ast_context->Idents.get(name)),
3183 QualType::getFromOpaquePtr(function_clang_type),
3184 NULL,
3185 (FunctionDecl::StorageClass)storage,
3186 (FunctionDecl::StorageClass)storage,
3187 is_inline);
3188 }
3189 else
3190 {
3191 return FunctionDecl::Create(*ast_context,
3192 ast_context->getTranslationUnitDecl(),
3193 SourceLocation(),
3194 DeclarationName (),
3195 QualType::getFromOpaquePtr(function_clang_type),
3196 NULL,
3197 (FunctionDecl::StorageClass)storage,
3198 (FunctionDecl::StorageClass)storage,
3199 is_inline);
3200 }
3201 }
3202 return NULL;
3203}
3204
Greg Clayton462d4142010-09-29 01:12:09 +00003205clang_type_t
3206ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3207 clang_type_t result_type,
3208 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003209 unsigned num_args,
3210 bool is_variadic,
3211 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003212{
Chris Lattner24943d22010-06-08 16:52:24 +00003213 assert (ast_context != NULL);
3214 std::vector<QualType> qual_type_args;
3215 for (unsigned i=0; i<num_args; ++i)
3216 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3217
3218 // TODO: Detect calling convention in DWARF?
3219 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003220 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003221 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003222 is_variadic,
3223 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003224 false, // hasExceptionSpec
3225 false, // hasAnyExceptionSpec,
3226 0, // NumExs
3227 0, // const QualType *ExArray
3228 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3229}
3230
3231ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003232ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003233{
3234 ASTContext *ast_context = getASTContext();
3235 assert (ast_context != NULL);
3236 return ParmVarDecl::Create(*ast_context,
3237 ast_context->getTranslationUnitDecl(),
3238 SourceLocation(),
3239 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003240 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003241 NULL,
3242 (VarDecl::StorageClass)storage,
3243 (VarDecl::StorageClass)storage,
3244 0);
3245}
3246
3247void
3248ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3249{
3250 if (function_decl)
3251 function_decl->setParams (params, num_params);
3252}
3253
3254
3255#pragma mark Array Types
3256
Greg Clayton462d4142010-09-29 01:12:09 +00003257clang_type_t
3258ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003259{
3260 if (element_type)
3261 {
3262 ASTContext *ast_context = getASTContext();
3263 assert (ast_context != NULL);
3264 llvm::APInt ap_element_count (64, element_count);
3265 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3266 ap_element_count,
3267 ArrayType::Normal,
3268 0).getAsOpaquePtr(); // ElemQuals
3269 }
3270 return NULL;
3271}
3272
3273
3274#pragma mark TagDecl
3275
3276bool
Greg Clayton462d4142010-09-29 01:12:09 +00003277ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003278{
3279 if (clang_type)
3280 {
3281 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003282 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003283 if (t)
3284 {
3285 TagType *tag_type = dyn_cast<TagType>(t);
3286 if (tag_type)
3287 {
3288 TagDecl *tag_decl = tag_type->getDecl();
3289 if (tag_decl)
3290 {
3291 tag_decl->startDefinition();
3292 return true;
3293 }
3294 }
3295 }
3296 }
3297 return false;
3298}
3299
3300bool
Greg Clayton462d4142010-09-29 01:12:09 +00003301ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003302{
3303 if (clang_type)
3304 {
3305 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00003306
3307 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3308
3309 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003310 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003311 cxx_record_decl->completeDefinition();
3312
3313 return true;
3314 }
3315
Sean Callanan04325062010-10-25 00:29:48 +00003316 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3317
3318 if (objc_class_type)
3319 {
3320 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3321
3322 class_interface_decl->setForwardDecl(false);
3323 }
3324
Greg Clayton55b6c532010-09-29 03:44:17 +00003325 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3326
3327 if (enum_type)
3328 {
3329 EnumDecl *enum_decl = enum_type->getDecl();
3330
3331 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003332 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003333 /// TODO This really needs to be fixed.
3334
3335 unsigned NumPositiveBits = 1;
3336 unsigned NumNegativeBits = 0;
3337
Greg Clayton48fbdf72010-10-12 04:29:14 +00003338 ASTContext *ast_context = getASTContext();
3339
3340 QualType promotion_qual_type;
3341 // If the enum integer type is less than an integer in bit width,
3342 // then we must promote it to an integer size.
3343 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3344 {
3345 if (enum_decl->getIntegerType()->isSignedIntegerType())
3346 promotion_qual_type = ast_context->IntTy;
3347 else
3348 promotion_qual_type = ast_context->UnsignedIntTy;
3349 }
3350 else
3351 promotion_qual_type = enum_decl->getIntegerType();
3352
3353 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003354 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003355 }
3356 }
3357 }
3358 return false;
3359}
3360
3361
3362#pragma mark Enumeration Types
3363
Greg Clayton462d4142010-09-29 01:12:09 +00003364clang_type_t
3365ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003366{
3367 // TODO: Do something intelligent with the Declaration object passed in
3368 // like maybe filling in the SourceLocation with it...
3369 ASTContext *ast_context = getASTContext();
3370 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003371
3372 // TODO: ask about these...
3373// const bool IsScoped = false;
3374// const bool IsFixed = false;
3375
3376 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3377 ast_context->getTranslationUnitDecl(),
3378 SourceLocation(),
3379 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3380 SourceLocation(),
Sean Callanan8950c9a2010-10-29 18:38:40 +00003381 NULL, false, false); //IsScoped, IsFixed);
Chris Lattner24943d22010-06-08 16:52:24 +00003382 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003383 {
3384 // TODO: check if we should be setting the promotion type too?
3385 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003386 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003387 }
Chris Lattner24943d22010-06-08 16:52:24 +00003388 return NULL;
3389}
3390
Greg Clayton462d4142010-09-29 01:12:09 +00003391clang_type_t
3392ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3393{
3394 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3395
3396 clang::Type *clang_type = enum_qual_type.getTypePtr();
3397 if (clang_type)
3398 {
3399 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3400 if (enum_type)
3401 {
3402 EnumDecl *enum_decl = enum_type->getDecl();
3403 if (enum_decl)
3404 return enum_decl->getIntegerType().getAsOpaquePtr();
3405 }
3406 }
3407 return NULL;
3408}
Chris Lattner24943d22010-06-08 16:52:24 +00003409bool
3410ClangASTContext::AddEnumerationValueToEnumerationType
3411(
Greg Clayton462d4142010-09-29 01:12:09 +00003412 clang_type_t enum_clang_type,
3413 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003414 const Declaration &decl,
3415 const char *name,
3416 int64_t enum_value,
3417 uint32_t enum_value_bit_size
3418)
3419{
3420 if (enum_clang_type && enumerator_clang_type && name)
3421 {
3422 // TODO: Do something intelligent with the Declaration object passed in
3423 // like maybe filling in the SourceLocation with it...
3424 ASTContext *ast_context = getASTContext();
3425 IdentifierTable *identifier_table = getIdentifierTable();
3426
3427 assert (ast_context != NULL);
3428 assert (identifier_table != NULL);
3429 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3430
Greg Clayton1674b122010-07-21 22:12:05 +00003431 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003432 if (clang_type)
3433 {
3434 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3435
3436 if (enum_type)
3437 {
3438 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3439 enum_llvm_apsint = enum_value;
3440 EnumConstantDecl *enumerator_decl =
3441 EnumConstantDecl::Create(*ast_context,
3442 enum_type->getDecl(),
3443 SourceLocation(),
3444 name ? &identifier_table->get(name) : NULL, // Identifier
3445 QualType::getFromOpaquePtr(enumerator_clang_type),
3446 NULL,
3447 enum_llvm_apsint);
3448
3449 if (enumerator_decl)
3450 {
3451 enum_type->getDecl()->addDecl(enumerator_decl);
3452 return true;
3453 }
3454 }
3455 }
3456 }
3457 return false;
3458}
3459
3460#pragma mark Pointers & References
3461
Greg Clayton462d4142010-09-29 01:12:09 +00003462clang_type_t
3463ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003464{
3465 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003466 {
3467 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3468
Greg Clayton03e0f972010-09-13 03:32:57 +00003469 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3470 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003471 {
3472 case clang::Type::ObjCObject:
3473 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003474 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3475
Greg Clayton7b541032010-07-29 20:06:32 +00003476 default:
3477 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3478 }
3479 }
Chris Lattner24943d22010-06-08 16:52:24 +00003480 return NULL;
3481}
3482
Greg Clayton462d4142010-09-29 01:12:09 +00003483clang_type_t
3484ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003485{
3486 if (clang_type)
3487 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3488 return NULL;
3489}
3490
Greg Clayton462d4142010-09-29 01:12:09 +00003491clang_type_t
3492ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003493{
3494 if (clang_type)
3495 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3496 return NULL;
3497}
3498
Greg Clayton462d4142010-09-29 01:12:09 +00003499clang_type_t
3500ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003501{
3502 if (clang_pointee_type && clang_pointee_type)
3503 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3504 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3505 return NULL;
3506}
3507
Chris Lattner24943d22010-06-08 16:52:24 +00003508size_t
3509ClangASTContext::GetPointerBitSize ()
3510{
3511 ASTContext *ast_context = getASTContext();
3512 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3513}
3514
3515bool
Greg Clayton462d4142010-09-29 01:12:09 +00003516ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003517{
3518 if (clang_type == NULL)
3519 return false;
3520
3521 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003522 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3523 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003524 {
Sean Callanan04325062010-10-25 00:29:48 +00003525 case clang::Type::Builtin:
3526 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3527 {
3528 default:
3529 break;
3530 case clang::BuiltinType::ObjCId:
3531 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003532 return true;
3533 }
3534 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003535 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003536 if (target_type)
3537 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3538 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003539 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003540 if (target_type)
3541 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3542 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003543 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003544 if (target_type)
3545 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3546 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003547 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003548 if (target_type)
3549 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3550 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003551 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003552 if (target_type)
3553 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3554 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003555 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003556 if (target_type)
3557 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3558 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003559 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003560 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3561 default:
3562 break;
3563 }
3564 return false;
3565}
3566
Chris Lattner24943d22010-06-08 16:52:24 +00003567bool
Greg Clayton462d4142010-09-29 01:12:09 +00003568ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003569{
3570 if (!clang_type)
3571 return false;
3572
3573 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3574 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3575
3576 if (builtin_type)
3577 {
3578 if (builtin_type->isInteger())
3579 is_signed = builtin_type->isSignedInteger();
3580
3581 return true;
3582 }
3583
3584 return false;
3585}
3586
3587bool
Greg Clayton462d4142010-09-29 01:12:09 +00003588ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003589{
3590 if (clang_type)
3591 {
3592 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003593 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3594 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003595 {
Sean Callanan04325062010-10-25 00:29:48 +00003596 case clang::Type::Builtin:
3597 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3598 {
3599 default:
3600 break;
3601 case clang::BuiltinType::ObjCId:
3602 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003603 return true;
3604 }
3605 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003606 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003607 if (target_type)
3608 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3609 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003610 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003611 if (target_type)
3612 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3613 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003614 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003615 if (target_type)
3616 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3617 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003618 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003619 if (target_type)
3620 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3621 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003622 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003623 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3624 default:
3625 break;
3626 }
3627 }
3628 return false;
3629}
3630
3631bool
Greg Clayton462d4142010-09-29 01:12:09 +00003632ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003633{
3634 if (clang_type)
3635 {
3636 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3637
3638 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3639 {
3640 clang::BuiltinType::Kind kind = BT->getKind();
3641 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3642 {
3643 count = 1;
3644 is_complex = false;
3645 return true;
3646 }
3647 }
3648 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3649 {
3650 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3651 {
3652 count = 2;
3653 is_complex = true;
3654 return true;
3655 }
3656 }
3657 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3658 {
3659 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3660 {
3661 count = VT->getNumElements();
3662 is_complex = false;
3663 return true;
3664 }
3665 }
3666 }
3667 return false;
3668}
3669
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003670
3671bool
3672ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3673{
3674 if (clang_type)
3675 {
3676 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3677
3678 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3679 if (cxx_record_decl)
3680 {
3681 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3682 return true;
3683 }
3684 }
3685 class_name.clear();
3686 return false;
3687}
3688
3689
Greg Clayton1d8173f2010-09-24 05:15:53 +00003690bool
Greg Clayton462d4142010-09-29 01:12:09 +00003691ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003692{
3693 if (clang_type)
3694 {
3695 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3696 if (qual_type->getAsCXXRecordDecl() != NULL)
3697 return true;
3698 }
3699 return false;
3700}
3701
3702bool
Greg Clayton462d4142010-09-29 01:12:09 +00003703ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003704{
3705 if (clang_type)
3706 {
3707 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3708 if (qual_type->isObjCObjectOrInterfaceType())
3709 return true;
3710 }
3711 return false;
3712}
3713
3714
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003715bool
3716ClangASTContext::IsCharType (clang_type_t clang_type)
3717{
3718 if (clang_type)
3719 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3720 return false;
3721}
Chris Lattner24943d22010-06-08 16:52:24 +00003722
3723bool
Greg Clayton462d4142010-09-29 01:12:09 +00003724ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003725{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003726 clang_type_t pointee_or_element_clang_type = NULL;
3727 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3728
3729 if (pointee_or_element_clang_type == NULL)
3730 return false;
3731
3732 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003733 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003734 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3735
3736 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003737 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003738 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3739 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003740 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003741 // We know the size of the array and it could be a C string
3742 // since it is an array of characters
3743 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3744 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003745 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003746 else
Chris Lattner24943d22010-06-08 16:52:24 +00003747 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003748 length = 0;
3749 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003750 }
Chris Lattner24943d22010-06-08 16:52:24 +00003751
Chris Lattner24943d22010-06-08 16:52:24 +00003752 }
3753 }
3754 return false;
3755}
3756
3757bool
Greg Clayton462d4142010-09-29 01:12:09 +00003758ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003759{
3760 if (clang_type)
3761 {
3762 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3763
3764 if (qual_type->isFunctionPointerType())
3765 return true;
3766
3767 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3768 switch (type_class)
3769 {
3770 case clang::Type::Typedef:
3771 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3772
3773 case clang::Type::LValueReference:
3774 case clang::Type::RValueReference:
3775 {
3776 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3777 if (reference_type)
3778 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3779 }
3780 break;
3781 }
3782 }
3783 return false;
3784}
3785
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003786size_t
3787ClangASTContext::GetArraySize (clang_type_t clang_type)
3788{
3789 if (clang_type)
3790 {
3791 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3792 if (array)
3793 return array->getSize().getLimitedValue();
3794 }
3795 return 0;
3796}
Greg Clayton03e0f972010-09-13 03:32:57 +00003797
3798bool
Greg Clayton462d4142010-09-29 01:12:09 +00003799ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003800{
3801 if (!clang_type)
3802 return false;
3803
3804 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3805
Greg Clayton03e0f972010-09-13 03:32:57 +00003806 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3807 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003808 {
Greg Clayton1674b122010-07-21 22:12:05 +00003809 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003810 if (member_type)
3811 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3812 if (size)
3813 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3814 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003815 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003816 if (member_type)
3817 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3818 if (size)
3819 *size = 0;
3820 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003821 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003822 if (member_type)
3823 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3824 if (size)
3825 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003826 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003827 if (member_type)
3828 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3829 if (size)
3830 *size = 0;
3831 return true;
3832 }
3833 return false;
3834}
3835
3836
3837#pragma mark Typedefs
3838
Greg Clayton462d4142010-09-29 01:12:09 +00003839clang_type_t
3840ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003841{
3842 if (clang_type)
3843 {
3844 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3845 ASTContext *ast_context = getASTContext();
3846 IdentifierTable *identifier_table = getIdentifierTable();
3847 assert (ast_context != NULL);
3848 assert (identifier_table != NULL);
3849 if (decl_ctx == NULL)
3850 decl_ctx = ast_context->getTranslationUnitDecl();
3851 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3852 decl_ctx,
3853 SourceLocation(),
3854 name ? &identifier_table->get(name) : NULL, // Identifier
3855 ast_context->CreateTypeSourceInfo(qual_type));
3856
3857 // Get a uniqued QualType for the typedef decl type
3858 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3859 }
3860 return NULL;
3861}
3862
3863
3864std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003865ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003866{
3867 std::string return_name;
3868
Greg Clayton462d4142010-09-29 01:12:09 +00003869 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003870
Greg Clayton462d4142010-09-29 01:12:09 +00003871 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003872 if (typedef_type)
3873 {
Greg Clayton462d4142010-09-29 01:12:09 +00003874 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003875 return_name = typedef_decl->getQualifiedNameAsString();
3876 }
3877 else
3878 {
3879 return_name = qual_type.getAsString();
3880 }
3881
3882 return return_name;
3883}
3884
3885// Disable this for now since I can't seem to get a nicely formatted float
3886// out of the APFloat class without just getting the float, double or quad
3887// and then using a formatted print on it which defeats the purpose. We ideally
3888// would like to get perfect string values for any kind of float semantics
3889// so we can support remote targets. The code below also requires a patch to
3890// llvm::APInt.
3891//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003892//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 +00003893//{
3894// uint32_t count = 0;
3895// bool is_complex = false;
3896// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3897// {
3898// unsigned num_bytes_per_float = byte_size / count;
3899// unsigned num_bits_per_float = num_bytes_per_float * 8;
3900//
3901// float_str.clear();
3902// uint32_t i;
3903// for (i=0; i<count; i++)
3904// {
3905// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3906// bool is_ieee = false;
3907// APFloat ap_float(ap_int, is_ieee);
3908// char s[1024];
3909// unsigned int hex_digits = 0;
3910// bool upper_case = false;
3911//
3912// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3913// {
3914// if (i > 0)
3915// float_str.append(", ");
3916// float_str.append(s);
3917// if (i == 1 && is_complex)
3918// float_str.append(1, 'i');
3919// }
3920// }
3921// return !float_str.empty();
3922// }
3923// return false;
3924//}
3925
3926size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003927ClangASTContext::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 +00003928{
3929 if (clang_type)
3930 {
3931 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3932 uint32_t count = 0;
3933 bool is_complex = false;
3934 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3935 {
3936 // TODO: handle complex and vector types
3937 if (count != 1)
3938 return false;
3939
3940 StringRef s_sref(s);
3941 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3942
3943 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3944 const uint64_t byte_size = bit_size / 8;
3945 if (dst_size >= byte_size)
3946 {
3947 if (bit_size == sizeof(float)*8)
3948 {
3949 float float32 = ap_float.convertToFloat();
3950 ::memcpy (dst, &float32, byte_size);
3951 return byte_size;
3952 }
3953 else if (bit_size >= 64)
3954 {
3955 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3956 ::memcpy (dst, ap_int.getRawData(), byte_size);
3957 return byte_size;
3958 }
3959 }
3960 }
3961 }
3962 return 0;
3963}
Sean Callanana751f7b2010-09-17 02:24:29 +00003964
3965unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00003966ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00003967{
3968 assert (clang_type);
3969
3970 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3971
3972 return qual_type.getQualifiers().getCVRQualifiers();
3973}