blob: d93fc59c1a6d7cb326164e990af55bdf3a5564c5 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedmanf05633b2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Sean Callananbc4f0f52010-07-08 18:16:16 +000017#define NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "clang/AST/ASTContext.h"
19#include "clang/AST/ASTImporter.h"
20#include "clang/AST/CXXInheritance.h"
Greg Clayton84f80752010-07-22 18:30:50 +000021#include "clang/AST/DeclObjC.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "clang/AST/RecordLayout.h"
23#include "clang/AST/Type.h"
24#include "clang/Basic/Builtins.h"
25#include "clang/Basic/FileManager.h"
Sean Callanan8a3b0a82010-11-18 02:56:27 +000026#include "clang/Basic/FileSystemOptions.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "clang/Basic/SourceManager.h"
28#include "clang/Basic/TargetInfo.h"
29#include "clang/Basic/TargetOptions.h"
30#include "clang/Frontend/FrontendOptions.h"
31#include "clang/Frontend/LangStandard.h"
Sean Callananbc4f0f52010-07-08 18:16:16 +000032#undef NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000033
Chris Lattner24943d22010-06-08 16:52:24 +000034#include "lldb/Core/dwarf.h"
Greg Claytonf3d0b0c2010-10-27 03:32:59 +000035#include "lldb/Core/Flags.h"
Sean Callanan839fde42010-10-28 18:19:36 +000036#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037
Eli Friedmanf05633b2010-06-13 19:06:42 +000038#include <stdio.h>
39
Greg Clayton585660c2010-08-05 01:57:25 +000040using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000041using namespace lldb_private;
42using namespace llvm;
43using namespace clang;
44
Greg Clayton84f80752010-07-22 18:30:50 +000045static AccessSpecifier
Greg Clayton585660c2010-08-05 01:57:25 +000046ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000047{
48 switch (access)
49 {
Greg Clayton585660c2010-08-05 01:57:25 +000050 default: break;
51 case eAccessNone: return AS_none;
52 case eAccessPublic: return AS_public;
53 case eAccessPrivate: return AS_private;
54 case eAccessProtected: return AS_protected;
Greg Clayton84f80752010-07-22 18:30:50 +000055 }
56 return AS_none;
57}
58
59static ObjCIvarDecl::AccessControl
Greg Clayton585660c2010-08-05 01:57:25 +000060ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000061{
62 switch (access)
63 {
Greg Clayton585660c2010-08-05 01:57:25 +000064 default: break;
65 case eAccessNone: return ObjCIvarDecl::None;
66 case eAccessPublic: return ObjCIvarDecl::Public;
67 case eAccessPrivate: return ObjCIvarDecl::Private;
68 case eAccessProtected: return ObjCIvarDecl::Protected;
69 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton84f80752010-07-22 18:30:50 +000070 }
71 return ObjCIvarDecl::None;
72}
73
74
Chris Lattner24943d22010-06-08 16:52:24 +000075static void
76ParseLangArgs
77(
78 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000079 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000080)
81{
82 // FIXME: Cleanup per-file based stuff.
83
84 // Set some properties which depend soley on the input kind; it would be nice
85 // to move these to the language standard, and have the driver resolve the
86 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000087 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000088 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000089 } else if (IK == IK_ObjC ||
90 IK == IK_ObjCXX ||
91 IK == IK_PreprocessedObjC ||
92 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000093 Opts.ObjC1 = Opts.ObjC2 = 1;
94 }
95
96 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
97
98 if (LangStd == LangStandard::lang_unspecified) {
99 // Based on the base language, pick one.
100 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +0000101 case IK_None:
102 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +0000103 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +0000104 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +0000105 LangStd = LangStandard::lang_opencl;
106 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000107 case IK_Asm:
108 case IK_C:
109 case IK_PreprocessedC:
110 case IK_ObjC:
111 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +0000112 LangStd = LangStandard::lang_gnu99;
113 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000114 case IK_CXX:
115 case IK_PreprocessedCXX:
116 case IK_ObjCXX:
117 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +0000118 LangStd = LangStandard::lang_gnucxx98;
119 break;
120 }
121 }
122
123 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
124 Opts.BCPLComment = Std.hasBCPLComments();
125 Opts.C99 = Std.isC99();
126 Opts.CPlusPlus = Std.isCPlusPlus();
127 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
128 Opts.Digraphs = Std.hasDigraphs();
129 Opts.GNUMode = Std.isGNUMode();
130 Opts.GNUInline = !Std.isC99();
131 Opts.HexFloats = Std.hasHexFloats();
132 Opts.ImplicitInt = Std.hasImplicitInt();
133
134 // OpenCL has some additional defaults.
135 if (LangStd == LangStandard::lang_opencl) {
136 Opts.OpenCL = 1;
137 Opts.AltiVec = 1;
138 Opts.CXXOperatorNames = 1;
139 Opts.LaxVectorConversions = 1;
140 }
141
142 // OpenCL and C++ both have bool, true, false keywords.
143 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
144
145// if (Opts.CPlusPlus)
146// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
147//
148// if (Args.hasArg(OPT_fobjc_gc_only))
149// Opts.setGCMode(LangOptions::GCOnly);
150// else if (Args.hasArg(OPT_fobjc_gc))
151// Opts.setGCMode(LangOptions::HybridGC);
152//
153// if (Args.hasArg(OPT_print_ivar_layout))
154// Opts.ObjCGCBitmapPrint = 1;
155//
156// if (Args.hasArg(OPT_faltivec))
157// Opts.AltiVec = 1;
158//
159// if (Args.hasArg(OPT_pthread))
160// Opts.POSIXThreads = 1;
161//
162// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
163// "default");
164// if (Vis == "default")
Sean Callanan8950c9a2010-10-29 18:38:40 +0000165 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner24943d22010-06-08 16:52:24 +0000166// else if (Vis == "hidden")
167// Opts.setVisibilityMode(LangOptions::Hidden);
168// else if (Vis == "protected")
169// Opts.setVisibilityMode(LangOptions::Protected);
170// else
171// Diags.Report(diag::err_drv_invalid_value)
172// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
173
174// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
175
176 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
177 // is specified, or -std is set to a conforming mode.
178 Opts.Trigraphs = !Opts.GNUMode;
179// if (Args.hasArg(OPT_trigraphs))
180// Opts.Trigraphs = 1;
181//
182// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
183// OPT_fno_dollars_in_identifiers,
184// !Opts.AsmPreprocessor);
185// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
186// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
187// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
188// if (Args.hasArg(OPT_fno_lax_vector_conversions))
189// Opts.LaxVectorConversions = 0;
190// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
191// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
192// Opts.Blocks = Args.hasArg(OPT_fblocks);
193// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
194// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
195// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
196// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
197// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
198// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
199// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
200// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
201// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
202// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
203// Diags);
204// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
205// Opts.ObjCConstantStringClass = getLastArgValue(Args,
206// OPT_fconstant_string_class);
207// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
208// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
209// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
210// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
211// Opts.Static = Args.hasArg(OPT_static_define);
212 Opts.OptimizeSize = 0;
213
214 // FIXME: Eliminate this dependency.
215// unsigned Opt =
216// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
217// Opts.Optimize = Opt != 0;
218 unsigned Opt = 0;
219
220 // This is the __NO_INLINE__ define, which just depends on things like the
221 // optimization level and -fno-inline, not actually whether the backend has
222 // inlining enabled.
223 //
224 // FIXME: This is affected by other options (-fno-inline).
225 Opts.NoInline = !Opt;
226
227// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
228// switch (SSP) {
229// default:
230// Diags.Report(diag::err_drv_invalid_value)
231// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
232// break;
233// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
234// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
235// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
236// }
237}
238
Chris Lattner24943d22010-06-08 16:52:24 +0000239
Chris Lattner24943d22010-06-08 16:52:24 +0000240ClangASTContext::ClangASTContext(const char *target_triple) :
241 m_target_triple(),
242 m_ast_context_ap(),
243 m_language_options_ap(),
244 m_source_manager_ap(),
245 m_diagnostic_ap(),
246 m_target_options_ap(),
247 m_target_info_ap(),
248 m_identifier_table_ap(),
249 m_selector_table_ap(),
250 m_builtins_ap()
251{
252 if (target_triple && target_triple[0])
253 m_target_triple.assign (target_triple);
254}
255
256//----------------------------------------------------------------------
257// Destructor
258//----------------------------------------------------------------------
259ClangASTContext::~ClangASTContext()
260{
261 m_builtins_ap.reset();
262 m_selector_table_ap.reset();
263 m_identifier_table_ap.reset();
264 m_target_info_ap.reset();
265 m_target_options_ap.reset();
266 m_diagnostic_ap.reset();
267 m_source_manager_ap.reset();
268 m_language_options_ap.reset();
269 m_ast_context_ap.reset();
270}
271
272
273void
274ClangASTContext::Clear()
275{
276 m_ast_context_ap.reset();
277 m_language_options_ap.reset();
278 m_source_manager_ap.reset();
279 m_diagnostic_ap.reset();
280 m_target_options_ap.reset();
281 m_target_info_ap.reset();
282 m_identifier_table_ap.reset();
283 m_selector_table_ap.reset();
284 m_builtins_ap.reset();
285}
286
287const char *
288ClangASTContext::GetTargetTriple ()
289{
290 return m_target_triple.c_str();
291}
292
293void
294ClangASTContext::SetTargetTriple (const char *target_triple)
295{
296 Clear();
297 m_target_triple.assign(target_triple);
298}
299
300
301ASTContext *
302ClangASTContext::getASTContext()
303{
304 if (m_ast_context_ap.get() == NULL)
305 {
306 m_ast_context_ap.reset(
307 new ASTContext(
308 *getLanguageOptions(),
309 *getSourceManager(),
310 *getTargetInfo(),
311 *getIdentifierTable(),
312 *getSelectorTable(),
Greg Clayton6e713402010-07-30 20:30:44 +0000313 *getBuiltinContext(),
314 0));
Chris Lattner24943d22010-06-08 16:52:24 +0000315 }
316 return m_ast_context_ap.get();
317}
318
319Builtin::Context *
320ClangASTContext::getBuiltinContext()
321{
322 if (m_builtins_ap.get() == NULL)
323 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
324 return m_builtins_ap.get();
325}
326
327IdentifierTable *
328ClangASTContext::getIdentifierTable()
329{
330 if (m_identifier_table_ap.get() == NULL)
331 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
332 return m_identifier_table_ap.get();
333}
334
335LangOptions *
336ClangASTContext::getLanguageOptions()
337{
338 if (m_language_options_ap.get() == NULL)
339 {
340 m_language_options_ap.reset(new LangOptions());
Greg Claytone41c4b22010-06-13 17:34:29 +0000341 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
342// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner24943d22010-06-08 16:52:24 +0000343 }
344 return m_language_options_ap.get();
345}
346
347SelectorTable *
348ClangASTContext::getSelectorTable()
349{
350 if (m_selector_table_ap.get() == NULL)
351 m_selector_table_ap.reset (new SelectorTable());
352 return m_selector_table_ap.get();
353}
354
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000355clang::FileManager *
356ClangASTContext::getFileManager()
357{
358 if (m_file_manager_ap.get() == NULL)
Greg Clayton22defe82010-12-02 23:20:03 +0000359 {
360 clang::FileSystemOptions file_system_options;
361 m_file_manager_ap.reset(new clang::FileManager(file_system_options));
362 }
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000363 return m_file_manager_ap.get();
364}
365
Greg Clayton1674b122010-07-21 22:12:05 +0000366clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000367ClangASTContext::getSourceManager()
368{
369 if (m_source_manager_ap.get() == NULL)
Greg Clayton22defe82010-12-02 23:20:03 +0000370 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
Chris Lattner24943d22010-06-08 16:52:24 +0000371 return m_source_manager_ap.get();
372}
373
374Diagnostic *
375ClangASTContext::getDiagnostic()
376{
377 if (m_diagnostic_ap.get() == NULL)
Greg Claytoneae91242010-11-19 21:46:54 +0000378 {
379 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
380 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
381 }
Chris Lattner24943d22010-06-08 16:52:24 +0000382 return m_diagnostic_ap.get();
383}
384
385TargetOptions *
386ClangASTContext::getTargetOptions()
387{
388 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
389 {
390 m_target_options_ap.reset (new TargetOptions());
391 if (m_target_options_ap.get())
392 m_target_options_ap->Triple = m_target_triple;
393 }
394 return m_target_options_ap.get();
395}
396
397
398TargetInfo *
399ClangASTContext::getTargetInfo()
400{
401 // target_triple should be something like "x86_64-apple-darwin10"
402 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
403 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
404 return m_target_info_ap.get();
405}
406
407#pragma mark Basic Types
408
409static inline bool
410QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
411{
412 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
413 if (qual_type_bit_size == bit_size)
414 return true;
415 return false;
416}
417
Greg Clayton462d4142010-09-29 01:12:09 +0000418clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000419ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000420{
421 ASTContext *ast_context = getASTContext();
422
423 assert (ast_context != NULL);
424
425 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
426}
427
Greg Clayton462d4142010-09-29 01:12:09 +0000428clang_type_t
429ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000430{
431 if (!ast_context)
432 return NULL;
433
434 switch (encoding)
435 {
Greg Clayton585660c2010-08-05 01:57:25 +0000436 case eEncodingInvalid:
Chris Lattner24943d22010-06-08 16:52:24 +0000437 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
438 return ast_context->VoidPtrTy.getAsOpaquePtr();
439 break;
440
Greg Clayton585660c2010-08-05 01:57:25 +0000441 case eEncodingUint:
Chris Lattner24943d22010-06-08 16:52:24 +0000442 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
443 return ast_context->UnsignedCharTy.getAsOpaquePtr();
444 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
445 return ast_context->UnsignedShortTy.getAsOpaquePtr();
446 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
447 return ast_context->UnsignedIntTy.getAsOpaquePtr();
448 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
449 return ast_context->UnsignedLongTy.getAsOpaquePtr();
450 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
451 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
452 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
453 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
454 break;
455
Greg Clayton585660c2010-08-05 01:57:25 +0000456 case eEncodingSint:
Chris Lattner24943d22010-06-08 16:52:24 +0000457 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
458 return ast_context->CharTy.getAsOpaquePtr();
459 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
460 return ast_context->ShortTy.getAsOpaquePtr();
461 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
462 return ast_context->IntTy.getAsOpaquePtr();
463 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
464 return ast_context->LongTy.getAsOpaquePtr();
465 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
466 return ast_context->LongLongTy.getAsOpaquePtr();
467 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
468 return ast_context->Int128Ty.getAsOpaquePtr();
469 break;
470
Greg Clayton585660c2010-08-05 01:57:25 +0000471 case eEncodingIEEE754:
Chris Lattner24943d22010-06-08 16:52:24 +0000472 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
473 return ast_context->FloatTy.getAsOpaquePtr();
474 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
475 return ast_context->DoubleTy.getAsOpaquePtr();
476 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
477 return ast_context->LongDoubleTy.getAsOpaquePtr();
478 break;
479
Greg Clayton585660c2010-08-05 01:57:25 +0000480 case eEncodingVector:
Chris Lattner24943d22010-06-08 16:52:24 +0000481 default:
482 break;
483 }
484
485 return NULL;
486}
487
Greg Clayton462d4142010-09-29 01:12:09 +0000488clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000489ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
490{
491 ASTContext *ast_context = getASTContext();
492
493 #define streq(a,b) strcmp(a,b) == 0
494 assert (ast_context != NULL);
495 if (ast_context)
496 {
497 switch (dw_ate)
498 {
499 default:
500 break;
501
502 case DW_ATE_address:
503 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
504 return ast_context->VoidPtrTy.getAsOpaquePtr();
505 break;
506
507 case DW_ATE_boolean:
508 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
509 return ast_context->BoolTy.getAsOpaquePtr();
510 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
511 return ast_context->UnsignedCharTy.getAsOpaquePtr();
512 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
513 return ast_context->UnsignedShortTy.getAsOpaquePtr();
514 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
515 return ast_context->UnsignedIntTy.getAsOpaquePtr();
516 break;
517
518 case DW_ATE_complex_float:
519 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
520 return ast_context->FloatComplexTy.getAsOpaquePtr();
521 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
522 return ast_context->DoubleComplexTy.getAsOpaquePtr();
523 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
524 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
525 break;
526
527 case DW_ATE_float:
528 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
529 return ast_context->FloatTy.getAsOpaquePtr();
530 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
531 return ast_context->DoubleTy.getAsOpaquePtr();
532 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
533 return ast_context->LongDoubleTy.getAsOpaquePtr();
534 break;
535
536 case DW_ATE_signed:
537 if (type_name)
538 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000539 if (strstr(type_name, "long long"))
Chris Lattner24943d22010-06-08 16:52:24 +0000540 {
Chris Lattner24943d22010-06-08 16:52:24 +0000541 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
542 return ast_context->LongLongTy.getAsOpaquePtr();
543 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000544 else if (strstr(type_name, "long"))
545 {
546 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
547 return ast_context->LongTy.getAsOpaquePtr();
548 }
549 else if (strstr(type_name, "short"))
Chris Lattner24943d22010-06-08 16:52:24 +0000550 {
551 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
552 return ast_context->ShortTy.getAsOpaquePtr();
553 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000554 else if (strstr(type_name, "char"))
Chris Lattner24943d22010-06-08 16:52:24 +0000555 {
556 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
557 return ast_context->CharTy.getAsOpaquePtr();
558 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
559 return ast_context->SignedCharTy.getAsOpaquePtr();
560 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000561 else if (strstr(type_name, "int"))
562 {
563 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
564 return ast_context->IntTy.getAsOpaquePtr();
565 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
566 return ast_context->Int128Ty.getAsOpaquePtr();
567 }
568 else if (streq(type_name, "wchar_t"))
Chris Lattner24943d22010-06-08 16:52:24 +0000569 {
570 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
571 return ast_context->WCharTy.getAsOpaquePtr();
572 }
Chris Lattner24943d22010-06-08 16:52:24 +0000573 }
574 // We weren't able to match up a type name, just search by size
575 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
576 return ast_context->CharTy.getAsOpaquePtr();
577 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
578 return ast_context->ShortTy.getAsOpaquePtr();
579 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
580 return ast_context->IntTy.getAsOpaquePtr();
581 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
582 return ast_context->LongTy.getAsOpaquePtr();
583 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
584 return ast_context->LongLongTy.getAsOpaquePtr();
585 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
586 return ast_context->Int128Ty.getAsOpaquePtr();
587 break;
588
589 case DW_ATE_signed_char:
590 if (type_name)
591 {
592 if (streq(type_name, "signed char"))
593 {
594 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
595 return ast_context->SignedCharTy.getAsOpaquePtr();
596 }
597 }
598 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
599 return ast_context->CharTy.getAsOpaquePtr();
600 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
601 return ast_context->SignedCharTy.getAsOpaquePtr();
602 break;
603
604 case DW_ATE_unsigned:
605 if (type_name)
606 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000607 if (strstr(type_name, "long long"))
608 {
609 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
610 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
611 }
612 else if (strstr(type_name, "long"))
613 {
614 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
615 return ast_context->UnsignedLongTy.getAsOpaquePtr();
616 }
617 else if (strstr(type_name, "short"))
618 {
619 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
620 return ast_context->UnsignedShortTy.getAsOpaquePtr();
621 }
622 else if (strstr(type_name, "char"))
623 {
624 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
625 return ast_context->UnsignedCharTy.getAsOpaquePtr();
626 }
627 else if (strstr(type_name, "int"))
Chris Lattner24943d22010-06-08 16:52:24 +0000628 {
629 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
630 return ast_context->UnsignedIntTy.getAsOpaquePtr();
631 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
632 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
633 }
Chris Lattner24943d22010-06-08 16:52:24 +0000634 }
635 // We weren't able to match up a type name, just search by size
636 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
637 return ast_context->UnsignedCharTy.getAsOpaquePtr();
638 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
639 return ast_context->UnsignedShortTy.getAsOpaquePtr();
640 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
641 return ast_context->UnsignedIntTy.getAsOpaquePtr();
642 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
643 return ast_context->UnsignedLongTy.getAsOpaquePtr();
644 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
645 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
646 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
647 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
648 break;
649
650 case DW_ATE_unsigned_char:
651 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
652 return ast_context->UnsignedCharTy.getAsOpaquePtr();
653 break;
654
655 case DW_ATE_imaginary_float:
656 break;
657 }
658 }
659 // This assert should fire for anything that we don't catch above so we know
660 // to fix any issues we run into.
661 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
662 return NULL;
663}
664
Greg Clayton462d4142010-09-29 01:12:09 +0000665clang_type_t
666ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
Chris Lattner24943d22010-06-08 16:52:24 +0000667{
Sean Callanana751f7b2010-09-17 02:24:29 +0000668 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000669}
670
Greg Clayton462d4142010-09-29 01:12:09 +0000671clang_type_t
Sean Callanana91dd992010-11-19 02:52:21 +0000672ClangASTContext::GetBuiltInType_bool()
673{
674 return getASTContext()->BoolTy.getAsOpaquePtr();
675}
676
677clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000678ClangASTContext::GetBuiltInType_objc_id()
679{
Sean Callananc4217a62010-12-06 23:53:20 +0000680 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000681}
682
Greg Clayton462d4142010-09-29 01:12:09 +0000683clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000684ClangASTContext::GetBuiltInType_objc_Class()
685{
Sean Callanan04325062010-10-25 00:29:48 +0000686 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000687}
688
Greg Clayton462d4142010-09-29 01:12:09 +0000689clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000690ClangASTContext::GetBuiltInType_objc_selector()
691{
Sean Callananc4217a62010-12-06 23:53:20 +0000692 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000693}
694
Greg Clayton462d4142010-09-29 01:12:09 +0000695clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000696ClangASTContext::GetCStringType (bool is_const)
697{
698 QualType char_type(getASTContext()->CharTy);
699
700 if (is_const)
701 char_type.addConst();
702
703 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
704}
705
Greg Clayton462d4142010-09-29 01:12:09 +0000706clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000707ClangASTContext::GetVoidPtrType (bool is_const)
708{
709 return GetVoidPtrType(getASTContext(), is_const);
710}
711
Greg Clayton462d4142010-09-29 01:12:09 +0000712clang_type_t
713ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
Chris Lattner24943d22010-06-08 16:52:24 +0000714{
715 QualType void_ptr_type(ast_context->VoidPtrTy);
716
717 if (is_const)
718 void_ptr_type.addConst();
719
720 return void_ptr_type.getAsOpaquePtr();
721}
722
Sean Callanan839fde42010-10-28 18:19:36 +0000723class NullDiagnosticClient : public DiagnosticClient
724{
725public:
726 NullDiagnosticClient ()
727 {
728 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
729 }
730
731 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
732 {
733 if (m_log)
734 {
735 llvm::SmallVectorImpl<char> diag_str(10);
736 info.FormatDiagnostic(diag_str);
737 diag_str.push_back('\0');
738 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
739 }
740 }
741private:
Greg Claytone005f2c2010-11-06 01:53:30 +0000742 LogSP m_log;
Sean Callanan839fde42010-10-28 18:19:36 +0000743};
744
Greg Clayton462d4142010-09-29 01:12:09 +0000745clang_type_t
Greg Clayton22defe82010-12-02 23:20:03 +0000746ClangASTContext::CopyType (ASTContext *dst_ast,
747 ASTContext *src_ast,
Greg Clayton462d4142010-09-29 01:12:09 +0000748 clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000749{
Sean Callananad5b61b2010-10-28 18:43:33 +0000750 // null_client's ownership is transferred to diagnostics
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000751 FileSystemOptions file_system_options;
Greg Clayton22defe82010-12-02 23:20:03 +0000752 FileManager file_manager (file_system_options);
753 ASTImporter importer(*dst_ast, file_manager,
754 *src_ast, file_manager);
Sean Callanancf18faa2010-11-09 22:37:10 +0000755
Greg Clayton22defe82010-12-02 23:20:03 +0000756 QualType src (QualType::getFromOpaquePtr(clang_type));
757 QualType dst (importer.Import(src));
Sean Callanancf18faa2010-11-09 22:37:10 +0000758
759 return dst.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000760}
761
Greg Clayton6916e352010-11-13 03:52:47 +0000762
763clang::Decl *
Greg Clayton22defe82010-12-02 23:20:03 +0000764ClangASTContext::CopyDecl (ASTContext *dst_ast,
765 ASTContext *src_ast,
Greg Clayton6916e352010-11-13 03:52:47 +0000766 clang::Decl *source_decl)
767{
768 // null_client's ownership is transferred to diagnostics
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000769 FileSystemOptions file_system_options;
Greg Clayton22defe82010-12-02 23:20:03 +0000770 FileManager file_manager (file_system_options);
771 ASTImporter importer(*dst_ast, file_manager,
772 *src_ast, file_manager);
Greg Clayton6916e352010-11-13 03:52:47 +0000773
774 return importer.Import(source_decl);
775}
776
Sean Callanan8d825062010-07-16 00:00:27 +0000777bool
Greg Clayton462d4142010-09-29 01:12:09 +0000778ClangASTContext::AreTypesSame(ASTContext *ast_context,
779 clang_type_t type1,
780 clang_type_t type2)
Sean Callanan5510ddd2010-07-15 22:30:52 +0000781{
782 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
783 QualType::getFromOpaquePtr(type2));
784}
785
Chris Lattner24943d22010-06-08 16:52:24 +0000786#pragma mark CVR modifiers
787
Greg Clayton462d4142010-09-29 01:12:09 +0000788clang_type_t
789ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000790{
791 if (clang_type)
792 {
793 QualType result(QualType::getFromOpaquePtr(clang_type));
794 result.addConst();
795 return result.getAsOpaquePtr();
796 }
797 return NULL;
798}
799
Greg Clayton462d4142010-09-29 01:12:09 +0000800clang_type_t
801ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000802{
803 if (clang_type)
804 {
805 QualType result(QualType::getFromOpaquePtr(clang_type));
806 result.getQualifiers().setRestrict (true);
807 return result.getAsOpaquePtr();
808 }
809 return NULL;
810}
811
Greg Clayton462d4142010-09-29 01:12:09 +0000812clang_type_t
813ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000814{
815 if (clang_type)
816 {
817 QualType result(QualType::getFromOpaquePtr(clang_type));
818 result.getQualifiers().setVolatile (true);
819 return result.getAsOpaquePtr();
820 }
821 return NULL;
822}
823
824#pragma mark Structure, Unions, Classes
825
Greg Clayton462d4142010-09-29 01:12:09 +0000826clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000827ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000828{
829 ASTContext *ast_context = getASTContext();
830 assert (ast_context != NULL);
Sean Callanan04325062010-10-25 00:29:48 +0000831
Chris Lattner24943d22010-06-08 16:52:24 +0000832 if (decl_ctx == NULL)
833 decl_ctx = ast_context->getTranslationUnitDecl();
834
Greg Clayton9488b742010-07-28 02:04:09 +0000835
Greg Clayton585660c2010-08-05 01:57:25 +0000836 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000837 {
Greg Clayton306edca2010-10-11 02:25:34 +0000838 bool isForwardDecl = true;
Greg Clayton9488b742010-07-28 02:04:09 +0000839 bool isInternal = false;
840 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
841 }
842
Chris Lattner24943d22010-06-08 16:52:24 +0000843 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
844 // we will need to update this code. I was told to currently always use
845 // the CXXRecordDecl class since we often don't know from debug information
846 // if something is struct or a class, so we default to always use the more
847 // complete definition just in case.
848 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
849 (TagDecl::TagKind)kind,
850 decl_ctx,
851 SourceLocation(),
852 name && name[0] ? &ast_context->Idents.get(name) : NULL);
853
854 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
855}
856
Greg Claytondbf26152010-10-01 23:13:49 +0000857static bool
858IsOperator (const char *name, OverloadedOperatorKind &op_kind)
859{
860 if (name == NULL || name[0] == '\0')
861 return false;
862
863 if (::strstr(name, "operator ") != name)
864 return false;
865
866 const char *post_op_name = name + 9;
867
868 // This is an operator, set the overloaded operator kind to invalid
869 // in case this is a conversion operator...
870 op_kind = NUM_OVERLOADED_OPERATORS;
871
872 switch (post_op_name[0])
873 {
874 case 'n':
875 if (strcmp (post_op_name, "new") == 0)
876 op_kind = OO_New;
877 else if (strcmp (post_op_name, "new[]") == 0)
878 op_kind = OO_Array_New;
879 break;
880
881 case 'd':
882 if (strcmp (post_op_name, "delete") == 0)
883 op_kind = OO_Delete;
884 else if (strcmp (post_op_name, "delete[]") == 0)
885 op_kind = OO_Array_Delete;
886 break;
887
888 case '+':
889 if (post_op_name[1] == '\0')
890 op_kind = OO_Plus;
891 else if (post_op_name[2] == '\0')
892 {
893 if (post_op_name[1] == '=')
894 op_kind = OO_PlusEqual;
895 else if (post_op_name[1] == '+')
896 op_kind = OO_PlusPlus;
897 }
898 break;
899
900 case '-':
901 if (post_op_name[1] == '\0')
902 op_kind = OO_Minus;
903 else if (post_op_name[2] == '\0')
904 {
905 switch (post_op_name[1])
906 {
907 case '=': op_kind = OO_MinusEqual; break;
908 case '-': op_kind = OO_MinusMinus; break;
909 case '>': op_kind = OO_Arrow; break;
910 }
911 }
912 else if (post_op_name[3] == '\0')
913 {
914 if (post_op_name[2] == '*')
915 op_kind = OO_ArrowStar; break;
916 }
917 break;
918
919 case '*':
920 if (post_op_name[1] == '\0')
921 op_kind = OO_Star;
922 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
923 op_kind = OO_StarEqual;
924 break;
925
926 case '/':
927 if (post_op_name[1] == '\0')
928 op_kind = OO_Slash;
929 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
930 op_kind = OO_SlashEqual;
931 break;
932
933 case '%':
934 if (post_op_name[1] == '\0')
935 op_kind = OO_Percent;
936 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
937 op_kind = OO_PercentEqual;
938 break;
939
940
941 case '^':
942 if (post_op_name[1] == '\0')
943 op_kind = OO_Caret;
944 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
945 op_kind = OO_CaretEqual;
946 break;
947
948 case '&':
949 if (post_op_name[1] == '\0')
950 op_kind = OO_Amp;
951 else if (post_op_name[2] == '\0')
952 {
953 switch (post_op_name[1])
954 {
955 case '=': op_kind = OO_AmpEqual; break;
956 case '&': op_kind = OO_AmpAmp; break;
957 }
958 }
959 break;
960
961 case '|':
962 if (post_op_name[1] == '\0')
963 op_kind = OO_Pipe;
964 else if (post_op_name[2] == '\0')
965 {
966 switch (post_op_name[1])
967 {
968 case '=': op_kind = OO_PipeEqual; break;
969 case '|': op_kind = OO_PipePipe; break;
970 }
971 }
972 break;
973
974 case '~':
975 if (post_op_name[1] == '\0')
976 op_kind = OO_Tilde;
977 break;
978
979 case '!':
980 if (post_op_name[1] == '\0')
981 op_kind = OO_Exclaim;
982 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
983 op_kind = OO_ExclaimEqual;
984 break;
985
986 case '=':
987 if (post_op_name[1] == '\0')
988 op_kind = OO_Equal;
989 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
990 op_kind = OO_EqualEqual;
991 break;
992
993 case '<':
994 if (post_op_name[1] == '\0')
995 op_kind = OO_Less;
996 else if (post_op_name[2] == '\0')
997 {
998 switch (post_op_name[1])
999 {
1000 case '<': op_kind = OO_LessLess; break;
1001 case '=': op_kind = OO_LessEqual; break;
1002 }
1003 }
1004 else if (post_op_name[3] == '\0')
1005 {
1006 if (post_op_name[2] == '=')
1007 op_kind = OO_LessLessEqual;
1008 }
1009 break;
1010
1011 case '>':
1012 if (post_op_name[1] == '\0')
1013 op_kind = OO_Greater;
1014 else if (post_op_name[2] == '\0')
1015 {
1016 switch (post_op_name[1])
1017 {
1018 case '>': op_kind = OO_GreaterGreater; break;
1019 case '=': op_kind = OO_GreaterEqual; break;
1020 }
1021 }
1022 else if (post_op_name[1] == '>' &&
1023 post_op_name[2] == '=' &&
1024 post_op_name[3] == '\0')
1025 {
1026 op_kind = OO_GreaterGreaterEqual;
1027 }
1028 break;
1029
1030 case ',':
1031 if (post_op_name[1] == '\0')
1032 op_kind = OO_Comma;
1033 break;
1034
1035 case '(':
1036 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1037 op_kind = OO_Call;
1038 break;
1039
1040 case '[':
1041 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1042 op_kind = OO_Subscript;
1043 break;
1044 }
1045
1046 return true;
1047}
Greg Clayton412440a2010-09-23 01:09:21 +00001048CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +00001049ClangASTContext::AddMethodToCXXRecordType
1050(
Greg Clayton462d4142010-09-29 01:12:09 +00001051 ASTContext *ast_context,
1052 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001053 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001054 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001055 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001056 bool is_virtual,
1057 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001058 bool is_inline,
1059 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +00001060)
Sean Callanan79523002010-09-17 02:58:26 +00001061{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001062 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +00001063 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001064
1065 assert(ast_context);
1066
1067 IdentifierTable *identifier_table = &ast_context->Idents;
1068
1069 assert(identifier_table);
1070
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001071 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +00001072
1073 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +00001074
Greg Clayton1d8173f2010-09-24 05:15:53 +00001075 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001076 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001077
Greg Clayton1d8173f2010-09-24 05:15:53 +00001078 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +00001079
Greg Clayton1d8173f2010-09-24 05:15:53 +00001080 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001081 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001082
Greg Clayton1d8173f2010-09-24 05:15:53 +00001083 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +00001084
Greg Clayton1d8173f2010-09-24 05:15:53 +00001085 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001086 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001087
1088 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1089
Greg Clayton1d8173f2010-09-24 05:15:53 +00001090 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001091 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001092
Greg Clayton1d8173f2010-09-24 05:15:53 +00001093 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001094
Greg Clayton30449d52010-10-01 02:31:07 +00001095 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001096
Greg Clayton30449d52010-10-01 02:31:07 +00001097 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001098
Greg Clayton90e325d2010-10-01 03:45:20 +00001099 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001100
Greg Clayton5325a362010-10-02 01:40:05 +00001101 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001102
Greg Clayton5325a362010-10-02 01:40:05 +00001103 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001104 return NULL;
1105
Greg Clayton5325a362010-10-02 01:40:05 +00001106 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001107
1108 if (!method_function_prototype)
1109 return NULL;
1110
1111 unsigned int num_params = method_function_prototype->getNumArgs();
1112
1113 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001114 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001115 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1116 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001117 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001118 method_qual_type,
Sean Callanan8950c9a2010-10-29 18:38:40 +00001119 NULL,
Greg Clayton90e325d2010-10-01 03:45:20 +00001120 is_inline,
1121 is_implicitly_declared);
1122 }
1123 else if (decl_name == record_decl->getDeclName())
1124 {
Greg Clayton30449d52010-10-01 02:31:07 +00001125 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1126 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001127 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001128 method_qual_type,
1129 NULL, // TypeSourceInfo *
1130 is_explicit,
1131 is_inline,
1132 is_implicitly_declared);
1133 }
1134 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001135 {
Greg Claytondbf26152010-10-01 23:13:49 +00001136
1137 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1138 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001139 {
Greg Claytondbf26152010-10-01 23:13:49 +00001140 if (op_kind != NUM_OVERLOADED_OPERATORS)
1141 {
1142 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001143 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001144 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001145 method_qual_type,
1146 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001147 is_static,
1148 SC_None,
1149 is_inline);
1150 }
1151 else if (num_params == 0)
1152 {
1153 // Conversion operators don't take params...
1154 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1155 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001156 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001157 method_qual_type,
1158 NULL, // TypeSourceInfo *
1159 is_inline,
1160 is_explicit);
1161 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001162 }
Greg Claytondbf26152010-10-01 23:13:49 +00001163
1164 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001165 {
1166 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1167 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001168 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001169 method_qual_type,
1170 NULL, // TypeSourceInfo *
1171 is_static,
1172 SC_None,
1173 is_inline);
1174 }
Greg Clayton30449d52010-10-01 02:31:07 +00001175 }
Greg Claytondbf26152010-10-01 23:13:49 +00001176
Greg Clayton462d4142010-09-29 01:12:09 +00001177 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001178
1179 cxx_method_decl->setAccess (access_specifier);
1180 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001181
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001182 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001183
1184 ParmVarDecl *params[num_params];
1185
1186 for (int param_index = 0;
1187 param_index < num_params;
1188 ++param_index)
1189 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001190 params[param_index] = ParmVarDecl::Create (*ast_context,
1191 cxx_method_decl,
1192 SourceLocation(),
1193 NULL, // anonymous
1194 method_function_prototype->getArgType(param_index),
1195 NULL,
1196 SC_None,
1197 SC_None,
1198 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001199 }
1200
Greg Clayton1d8173f2010-09-24 05:15:53 +00001201 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001202
Greg Clayton1d8173f2010-09-24 05:15:53 +00001203 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001204
Greg Clayton412440a2010-09-23 01:09:21 +00001205 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001206}
1207
1208bool
Greg Clayton84f80752010-07-22 18:30:50 +00001209ClangASTContext::AddFieldToRecordType
1210(
Greg Clayton462d4142010-09-29 01:12:09 +00001211 ASTContext *ast_context,
1212 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001213 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001214 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001215 AccessType access,
1216 uint32_t bitfield_bit_size
1217)
Chris Lattner24943d22010-06-08 16:52:24 +00001218{
1219 if (record_clang_type == NULL || field_type == NULL)
1220 return false;
1221
Sean Callanan60a0ced2010-09-16 20:01:08 +00001222 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001223
1224 assert (ast_context != NULL);
1225 assert (identifier_table != NULL);
1226
1227 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1228
Greg Clayton1674b122010-07-21 22:12:05 +00001229 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001230 if (clang_type)
1231 {
1232 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1233
1234 if (record_type)
1235 {
1236 RecordDecl *record_decl = record_type->getDecl();
1237
Chris Lattner24943d22010-06-08 16:52:24 +00001238 clang::Expr *bit_width = NULL;
1239 if (bitfield_bit_size != 0)
1240 {
1241 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001242 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001243 }
Greg Clayton84f80752010-07-22 18:30:50 +00001244 FieldDecl *field = FieldDecl::Create (*ast_context,
1245 record_decl,
1246 SourceLocation(),
1247 name ? &identifier_table->get(name) : NULL, // Identifier
1248 QualType::getFromOpaquePtr(field_type), // Field type
1249 NULL, // DeclaratorInfo *
1250 bit_width, // BitWidth
1251 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001252
Greg Clayton84f80752010-07-22 18:30:50 +00001253 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001254
1255 if (field)
1256 {
1257 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001258 }
1259 }
Greg Clayton9488b742010-07-28 02:04:09 +00001260 else
1261 {
1262 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1263 if (objc_class_type)
1264 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001265 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001266 ClangASTContext::AddObjCClassIVar (ast_context,
1267 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001268 name,
1269 field_type,
1270 access,
1271 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001272 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001273 }
1274 }
Chris Lattner24943d22010-06-08 16:52:24 +00001275 }
1276 return false;
1277}
1278
1279bool
1280ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1281{
1282 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1283}
1284
1285bool
1286ClangASTContext::FieldIsBitfield
1287(
1288 ASTContext *ast_context,
1289 FieldDecl* field,
1290 uint32_t& bitfield_bit_size
1291)
1292{
1293 if (ast_context == NULL || field == NULL)
1294 return false;
1295
1296 if (field->isBitField())
1297 {
1298 Expr* bit_width_expr = field->getBitWidth();
1299 if (bit_width_expr)
1300 {
1301 llvm::APSInt bit_width_apsint;
1302 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1303 {
1304 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1305 return true;
1306 }
1307 }
1308 }
1309 return false;
1310}
1311
1312bool
1313ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1314{
1315 if (record_decl == NULL)
1316 return false;
1317
1318 if (!record_decl->field_empty())
1319 return true;
1320
1321 // No fields, lets check this is a CXX record and check the base classes
1322 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1323 if (cxx_record_decl)
1324 {
1325 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1326 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1327 base_class != base_class_end;
1328 ++base_class)
1329 {
1330 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1331 if (RecordHasFields(base_class_decl))
1332 return true;
1333 }
1334 }
1335 return false;
1336}
1337
1338void
Greg Clayton462d4142010-09-29 01:12:09 +00001339ClangASTContext::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 +00001340{
1341 if (clang_qual_type)
1342 {
1343 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001344 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001345 if (clang_type)
1346 {
1347 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1348 if (record_type)
1349 {
1350 RecordDecl *record_decl = record_type->getDecl();
1351 if (record_decl)
1352 {
1353 uint32_t field_idx;
1354 RecordDecl::field_iterator field, field_end;
1355 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1356 field != field_end;
1357 ++field, ++field_idx)
1358 {
1359 // If no accessibility was assigned, assign the correct one
1360 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1361 field->setAccess ((AccessSpecifier)default_accessibility);
1362 }
1363 }
1364 }
1365 }
1366 }
1367}
1368
1369#pragma mark C++ Base Classes
1370
1371CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001372ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001373{
1374 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001375 return new CXXBaseSpecifier (SourceRange(),
1376 is_virtual,
1377 base_of_class,
1378 ConvertAccessTypeToAccessSpecifier (access),
1379 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001380 return NULL;
1381}
1382
Greg Claytone9d0df42010-07-02 01:29:13 +00001383void
1384ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1385{
1386 for (unsigned i=0; i<num_base_classes; ++i)
1387 {
1388 delete base_classes[i];
1389 base_classes[i] = NULL;
1390 }
1391}
1392
Chris Lattner24943d22010-06-08 16:52:24 +00001393bool
Greg Clayton462d4142010-09-29 01:12:09 +00001394ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001395{
1396 if (class_clang_type)
1397 {
Greg Clayton1674b122010-07-21 22:12:05 +00001398 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001399 if (clang_type)
1400 {
1401 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1402 if (record_type)
1403 {
1404 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1405 if (cxx_record_decl)
1406 {
Chris Lattner24943d22010-06-08 16:52:24 +00001407 cxx_record_decl->setBases(base_classes, num_base_classes);
1408 return true;
1409 }
1410 }
1411 }
1412 }
1413 return false;
1414}
Greg Clayton84f80752010-07-22 18:30:50 +00001415#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001416
Greg Clayton462d4142010-09-29 01:12:09 +00001417clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001418ClangASTContext::CreateObjCClass
1419(
1420 const char *name,
1421 DeclContext *decl_ctx,
1422 bool isForwardDecl,
1423 bool isInternal
1424)
1425{
1426 ASTContext *ast_context = getASTContext();
1427 assert (ast_context != NULL);
1428 assert (name && name[0]);
1429 if (decl_ctx == NULL)
1430 decl_ctx = ast_context->getTranslationUnitDecl();
1431
1432 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1433 // we will need to update this code. I was told to currently always use
1434 // the CXXRecordDecl class since we often don't know from debug information
1435 // if something is struct or a class, so we default to always use the more
1436 // complete definition just in case.
1437 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1438 decl_ctx,
1439 SourceLocation(),
1440 &ast_context->Idents.get(name),
1441 SourceLocation(),
1442 isForwardDecl,
1443 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001444
1445 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001446}
1447
1448bool
Greg Clayton462d4142010-09-29 01:12:09 +00001449ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001450{
1451 if (class_opaque_type && super_opaque_type)
1452 {
1453 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1454 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1455 clang::Type *class_type = class_qual_type.getTypePtr();
1456 clang::Type *super_type = super_qual_type.getTypePtr();
1457 if (class_type && super_type)
1458 {
1459 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1460 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1461 if (objc_class_type && objc_super_type)
1462 {
1463 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1464 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1465 if (class_interface_decl && super_interface_decl)
1466 {
1467 class_interface_decl->setSuperClass(super_interface_decl);
1468 return true;
1469 }
1470 }
1471 }
1472 }
1473 return false;
1474}
1475
1476
1477bool
1478ClangASTContext::AddObjCClassIVar
1479(
Greg Clayton462d4142010-09-29 01:12:09 +00001480 ASTContext *ast_context,
1481 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001482 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001483 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001484 AccessType access,
1485 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001486 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001487)
1488{
1489 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1490 return false;
1491
Sean Callanan60a0ced2010-09-16 20:01:08 +00001492 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001493
1494 assert (ast_context != NULL);
1495 assert (identifier_table != NULL);
1496
1497 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1498
1499 clang::Type *class_type = class_qual_type.getTypePtr();
1500 if (class_type)
1501 {
1502 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1503
1504 if (objc_class_type)
1505 {
1506 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1507
1508 if (class_interface_decl)
1509 {
1510 clang::Expr *bit_width = NULL;
1511 if (bitfield_bit_size != 0)
1512 {
1513 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001514 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001515 }
1516
Greg Clayton9488b742010-07-28 02:04:09 +00001517 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1518 class_interface_decl,
1519 SourceLocation(),
1520 &identifier_table->get(name), // Identifier
1521 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1522 NULL, // TypeSourceInfo *
1523 ConvertAccessTypeToObjCIvarAccessControl (access),
1524 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001525 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001526
1527 if (field)
1528 {
1529 class_interface_decl->addDecl(field);
1530 return true;
1531 }
Greg Clayton84f80752010-07-22 18:30:50 +00001532 }
1533 }
1534 }
1535 return false;
1536}
Chris Lattner24943d22010-06-08 16:52:24 +00001537
Greg Clayton9488b742010-07-28 02:04:09 +00001538
1539bool
Greg Clayton462d4142010-09-29 01:12:09 +00001540ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001541{
1542 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1543
1544 clang::Type *class_type = class_qual_type.getTypePtr();
1545 if (class_type)
1546 {
1547 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1548
1549 if (objc_class_type)
1550 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1551 }
1552 return false;
1553}
1554
1555bool
1556ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1557{
1558 while (class_interface_decl)
1559 {
1560 if (class_interface_decl->ivar_size() > 0)
1561 return true;
1562
1563 if (check_superclass)
1564 class_interface_decl = class_interface_decl->getSuperClass();
1565 else
1566 break;
1567 }
1568 return false;
1569}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001570
Greg Clayton462d4142010-09-29 01:12:09 +00001571ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001572ClangASTContext::AddMethodToObjCObjectType
1573(
Greg Clayton462d4142010-09-29 01:12:09 +00001574 ASTContext *ast_context,
1575 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001576 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001577 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001578 lldb::AccessType access
1579)
1580{
1581 if (class_opaque_type == NULL || method_opaque_type == NULL)
1582 return NULL;
1583
1584 IdentifierTable *identifier_table = &ast_context->Idents;
1585
1586 assert (ast_context != NULL);
1587 assert (identifier_table != NULL);
1588
1589 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1590
1591 clang::Type *class_type = class_qual_type.getTypePtr();
1592 if (class_type == NULL)
1593 return NULL;
1594
1595 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1596
1597 if (objc_class_type == NULL)
1598 return NULL;
1599
1600 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1601
1602 if (class_interface_decl == NULL)
1603 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001604
Greg Clayton1d8173f2010-09-24 05:15:53 +00001605 const char *selector_start = ::strchr (name, ' ');
1606 if (selector_start == NULL)
1607 return NULL;
1608
1609 selector_start++;
1610 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1611 return NULL;
1612 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1613
Greg Claytonad60bf42010-10-12 02:24:53 +00001614 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001615 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001616 //printf ("name = '%s'\n", name);
1617
1618 unsigned num_selectors_with_args = 0;
1619 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001620 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001621 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001622 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001623 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001624 bool has_arg = (start[len] == ':');
1625 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001626 ++num_selectors_with_args;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001627 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001628 if (has_arg)
1629 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001630 }
1631
1632
1633 if (selector_idents.size() == 0)
1634 return 0;
1635
Greg Claytonad60bf42010-10-12 02:24:53 +00001636 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001637 selector_idents.data());
1638
1639 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1640
1641 // Populate the method decl with parameter decls
1642 clang::Type *method_type(method_qual_type.getTypePtr());
1643
1644 if (method_type == NULL)
1645 return NULL;
1646
1647 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1648
1649 if (!method_function_prototype)
1650 return NULL;
1651
1652
1653 bool is_variadic = false;
1654 bool is_synthesized = false;
1655 bool is_defined = false;
1656 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1657
1658 const unsigned num_args = method_function_prototype->getNumArgs();
1659
1660 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1661 SourceLocation(), // beginLoc,
1662 SourceLocation(), // endLoc,
1663 method_selector,
1664 method_function_prototype->getResultType(),
1665 NULL, // TypeSourceInfo *ResultTInfo,
1666 GetDeclContextForType (class_opaque_type),
1667 name[0] == '-',
1668 is_variadic,
1669 is_synthesized,
1670 is_defined,
1671 imp_control,
1672 num_args);
1673
1674
1675 if (objc_method_decl == NULL)
1676 return NULL;
1677
1678 if (num_args > 0)
1679 {
1680 llvm::SmallVector<ParmVarDecl *, 12> params;
1681
1682 for (int param_index = 0; param_index < num_args; ++param_index)
1683 {
1684 params.push_back (ParmVarDecl::Create (*ast_context,
1685 objc_method_decl,
1686 SourceLocation(),
1687 NULL, // anonymous
1688 method_function_prototype->getArgType(param_index),
1689 NULL,
1690 SC_Auto,
1691 SC_Auto,
1692 NULL));
1693 }
1694
1695 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1696 }
1697
1698 class_interface_decl->addDecl (objc_method_decl);
1699
1700
1701 return objc_method_decl;
1702}
1703
1704
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001705uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001706ClangASTContext::GetTypeInfo
1707(
1708 clang_type_t clang_type,
1709 clang::ASTContext *ast_context,
1710 clang_type_t *pointee_or_element_clang_type
1711)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001712{
1713 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001714 return 0;
1715
1716 if (pointee_or_element_clang_type)
1717 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001718
1719 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1720
1721 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1722 switch (type_class)
1723 {
Sean Callanan04325062010-10-25 00:29:48 +00001724 case clang::Type::Builtin:
1725 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1726 {
Sean Callanan04325062010-10-25 00:29:48 +00001727 case clang::BuiltinType::ObjCId:
1728 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001729 if (ast_context && pointee_or_element_clang_type)
1730 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001731 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001732
1733 default:
1734 break;
Sean Callanan04325062010-10-25 00:29:48 +00001735 }
1736 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001737
1738 case clang::Type::BlockPointer:
1739 if (pointee_or_element_clang_type)
1740 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1741 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1742
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001743 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001744
1745 case clang::Type::ConstantArray:
1746 case clang::Type::DependentSizedArray:
1747 case clang::Type::IncompleteArray:
1748 case clang::Type::VariableArray:
1749 if (pointee_or_element_clang_type)
1750 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1751 return eTypeHasChildren | eTypeIsArray;
1752
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001753 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001754 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1755 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1756 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001757
1758 case clang::Type::Enum:
1759 if (pointee_or_element_clang_type)
1760 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1761 return eTypeIsEnumeration | eTypeHasValue;
1762
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001763 case clang::Type::Elaborated: return 0;
1764 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1765 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1766 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001767 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001768
1769 case clang::Type::LValueReference:
1770 case clang::Type::RValueReference:
1771 if (pointee_or_element_clang_type)
1772 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1773 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1774
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001775 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001776
1777 case clang::Type::ObjCObjectPointer:
1778 if (pointee_or_element_clang_type)
1779 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1780 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1781
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001782 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1783 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001784
1785 case clang::Type::Pointer:
1786 if (pointee_or_element_clang_type)
1787 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1788 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1789
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001790 case clang::Type::Record:
1791 if (qual_type->getAsCXXRecordDecl())
1792 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1793 else
1794 return eTypeHasChildren | eTypeIsStructUnion;
1795 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001796 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1797 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1798 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001799
1800 case clang::Type::Typedef:
1801 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1802 ast_context,
1803 pointee_or_element_clang_type);
1804
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001805 case clang::Type::TypeOfExpr: return 0;
1806 case clang::Type::TypeOf: return 0;
1807 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001808 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1809 default: return 0;
1810 }
1811 return 0;
1812}
1813
Greg Clayton9488b742010-07-28 02:04:09 +00001814
Chris Lattner24943d22010-06-08 16:52:24 +00001815#pragma mark Aggregate Types
1816
1817bool
Greg Clayton462d4142010-09-29 01:12:09 +00001818ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001819{
1820 if (clang_type == NULL)
1821 return false;
1822
1823 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1824
Greg Clayton03e0f972010-09-13 03:32:57 +00001825 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1826 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001827 {
Greg Clayton1674b122010-07-21 22:12:05 +00001828 case clang::Type::IncompleteArray:
1829 case clang::Type::VariableArray:
1830 case clang::Type::ConstantArray:
1831 case clang::Type::ExtVector:
1832 case clang::Type::Vector:
1833 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001834 case clang::Type::ObjCObject:
1835 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001836 return true;
1837
Greg Clayton1674b122010-07-21 22:12:05 +00001838 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001839 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1840
1841 default:
1842 break;
1843 }
1844 // The clang type does have a value
1845 return false;
1846}
1847
1848uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001849ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001850{
1851 if (clang_qual_type == NULL)
1852 return 0;
1853
1854 uint32_t num_children = 0;
1855 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001856 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1857 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001858 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001859 case clang::Type::Builtin:
1860 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1861 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001862 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001863 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001864 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001865 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001866
1867 default:
1868 break;
1869 }
1870 break;
1871
Greg Clayton1674b122010-07-21 22:12:05 +00001872 case clang::Type::Record:
Greg Clayton53d287b2010-11-11 02:14:53 +00001873 if (ClangASTType::IsDefined (clang_qual_type))
Chris Lattner24943d22010-06-08 16:52:24 +00001874 {
1875 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1876 const RecordDecl *record_decl = record_type->getDecl();
1877 assert(record_decl);
1878 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1879 if (cxx_record_decl)
1880 {
1881 if (omit_empty_base_classes)
1882 {
1883 // Check each base classes to see if it or any of its
1884 // base classes contain any fields. This can help
1885 // limit the noise in variable views by not having to
1886 // show base classes that contain no members.
1887 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1888 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1889 base_class != base_class_end;
1890 ++base_class)
1891 {
1892 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1893
1894 // Skip empty base classes
1895 if (RecordHasFields(base_class_decl) == false)
1896 continue;
1897
1898 num_children++;
1899 }
1900 }
1901 else
1902 {
1903 // Include all base classes
1904 num_children += cxx_record_decl->getNumBases();
1905 }
1906
1907 }
1908 RecordDecl::field_iterator field, field_end;
1909 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1910 ++num_children;
1911 }
1912 break;
1913
Greg Clayton9488b742010-07-28 02:04:09 +00001914 case clang::Type::ObjCObject:
1915 case clang::Type::ObjCInterface:
1916 {
1917 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1918 assert (objc_class_type);
1919 if (objc_class_type)
1920 {
1921 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1922
1923 if (class_interface_decl)
1924 {
1925
1926 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1927 if (superclass_interface_decl)
1928 {
1929 if (omit_empty_base_classes)
1930 {
1931 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1932 ++num_children;
1933 }
1934 else
1935 ++num_children;
1936 }
1937
1938 num_children += class_interface_decl->ivar_size();
1939 }
1940 }
1941 }
1942 break;
1943
1944 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001945 {
1946 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1947 QualType pointee_type = pointer_type->getPointeeType();
1948 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1949 omit_empty_base_classes);
1950 // If this type points to a simple type, then it has 1 child
1951 if (num_pointee_children == 0)
1952 num_children = 1;
1953 else
1954 num_children = num_pointee_children;
1955 }
1956 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001957
Greg Clayton1674b122010-07-21 22:12:05 +00001958 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001959 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1960 break;
1961
Greg Clayton1674b122010-07-21 22:12:05 +00001962 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001963 {
1964 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1965 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001966 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1967 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001968 // If this type points to a simple type, then it has 1 child
1969 if (num_pointee_children == 0)
1970 num_children = 1;
1971 else
1972 num_children = num_pointee_children;
1973 }
1974 break;
1975
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001976 case clang::Type::LValueReference:
1977 case clang::Type::RValueReference:
1978 {
1979 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1980 QualType pointee_type = reference_type->getPointeeType();
1981 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1982 omit_empty_base_classes);
1983 // If this type points to a simple type, then it has 1 child
1984 if (num_pointee_children == 0)
1985 num_children = 1;
1986 else
1987 num_children = num_pointee_children;
1988 }
1989 break;
1990
1991
Greg Clayton1674b122010-07-21 22:12:05 +00001992 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001993 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1994 break;
1995
1996 default:
1997 break;
1998 }
1999 return num_children;
2000}
2001
2002
Greg Clayton462d4142010-09-29 01:12:09 +00002003clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002004ClangASTContext::GetChildClangTypeAtIndex
2005(
2006 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002007 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002008 uint32_t idx,
2009 bool transparent_pointers,
2010 bool omit_empty_base_classes,
2011 std::string& child_name,
2012 uint32_t &child_byte_size,
2013 int32_t &child_byte_offset,
2014 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002015 uint32_t &child_bitfield_bit_offset,
2016 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002017)
2018{
2019 if (parent_clang_type)
2020
2021 return GetChildClangTypeAtIndex (getASTContext(),
2022 parent_name,
2023 parent_clang_type,
2024 idx,
2025 transparent_pointers,
2026 omit_empty_base_classes,
2027 child_name,
2028 child_byte_size,
2029 child_byte_offset,
2030 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002031 child_bitfield_bit_offset,
2032 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002033 return NULL;
2034}
2035
Greg Clayton462d4142010-09-29 01:12:09 +00002036clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002037ClangASTContext::GetChildClangTypeAtIndex
2038(
2039 ASTContext *ast_context,
2040 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002041 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002042 uint32_t idx,
2043 bool transparent_pointers,
2044 bool omit_empty_base_classes,
2045 std::string& child_name,
2046 uint32_t &child_byte_size,
2047 int32_t &child_byte_offset,
2048 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002049 uint32_t &child_bitfield_bit_offset,
2050 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002051)
2052{
2053 if (parent_clang_type == NULL)
2054 return NULL;
2055
2056 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2057 {
2058 uint32_t bit_offset;
2059 child_bitfield_bit_size = 0;
2060 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002061 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002062 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002063 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2064 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002065 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002066 case clang::Type::Builtin:
2067 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2068 {
2069 case clang::BuiltinType::ObjCId:
2070 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002071 child_name = "isa";
2072 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002073 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2074
Greg Clayton960d6a42010-08-03 00:35:52 +00002075 default:
2076 break;
2077 }
2078 break;
2079
2080
Greg Clayton1674b122010-07-21 22:12:05 +00002081 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002082 {
2083 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2084 const RecordDecl *record_decl = record_type->getDecl();
2085 assert(record_decl);
2086 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2087 uint32_t child_idx = 0;
2088
2089 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2090 if (cxx_record_decl)
2091 {
2092 // We might have base classes to print out first
2093 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2094 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2095 base_class != base_class_end;
2096 ++base_class)
2097 {
2098 const CXXRecordDecl *base_class_decl = NULL;
2099
2100 // Skip empty base classes
2101 if (omit_empty_base_classes)
2102 {
2103 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2104 if (RecordHasFields(base_class_decl) == false)
2105 continue;
2106 }
2107
2108 if (idx == child_idx)
2109 {
2110 if (base_class_decl == NULL)
2111 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2112
2113
2114 if (base_class->isVirtual())
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002115 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002116 else
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002117 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002118
2119 // Base classes should be a multiple of 8 bits in size
2120 assert (bit_offset % 8 == 0);
2121 child_byte_offset = bit_offset/8;
2122 std::string base_class_type_name(base_class->getType().getAsString());
2123
2124 child_name.assign(base_class_type_name.c_str());
2125
2126 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2127
2128 // Base classes biut sizes should be a multiple of 8 bits in size
2129 assert (clang_type_info_bit_size % 8 == 0);
2130 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002131 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002132 return base_class->getType().getAsOpaquePtr();
2133 }
2134 // We don't increment the child index in the for loop since we might
2135 // be skipping empty base classes
2136 ++child_idx;
2137 }
2138 }
Chris Lattner24943d22010-06-08 16:52:24 +00002139 // Make sure index is in range...
2140 uint32_t field_idx = 0;
2141 RecordDecl::field_iterator field, field_end;
2142 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2143 {
2144 if (idx == child_idx)
2145 {
2146 // Print the member type if requested
2147 // Print the member name and equal sign
2148 child_name.assign(field->getNameAsString().c_str());
2149
2150 // Figure out the type byte size (field_type_info.first) and
2151 // alignment (field_type_info.second) from the AST context.
2152 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002153 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002154
2155 child_byte_size = field_type_info.first / 8;
2156
2157 // Figure out the field offset within the current struct/union/class type
2158 bit_offset = record_layout.getFieldOffset (field_idx);
2159 child_byte_offset = bit_offset / 8;
2160 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2161 child_bitfield_bit_offset = bit_offset % 8;
2162
2163 return field->getType().getAsOpaquePtr();
2164 }
2165 }
2166 }
2167 break;
2168
Greg Clayton9488b742010-07-28 02:04:09 +00002169 case clang::Type::ObjCObject:
2170 case clang::Type::ObjCInterface:
2171 {
2172 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2173 assert (objc_class_type);
2174 if (objc_class_type)
2175 {
2176 uint32_t child_idx = 0;
2177 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2178
2179 if (class_interface_decl)
2180 {
2181
2182 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2183 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2184 if (superclass_interface_decl)
2185 {
2186 if (omit_empty_base_classes)
2187 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002188 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002189 {
2190 if (idx == 0)
2191 {
2192 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2193
2194
2195 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2196
2197 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2198
2199 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002200 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002201 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002202
2203 return ivar_qual_type.getAsOpaquePtr();
2204 }
2205
2206 ++child_idx;
2207 }
2208 }
2209 else
2210 ++child_idx;
2211 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002212
2213 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002214
2215 if (idx < (child_idx + class_interface_decl->ivar_size()))
2216 {
2217 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2218
2219 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2220 {
2221 if (child_idx == idx)
2222 {
2223 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2224
2225 QualType ivar_qual_type(ivar_decl->getType());
2226
2227 child_name.assign(ivar_decl->getNameAsString().c_str());
2228
2229 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2230
2231 child_byte_size = ivar_type_info.first / 8;
2232
2233 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002234 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002235 child_byte_offset = bit_offset / 8;
2236
2237 return ivar_qual_type.getAsOpaquePtr();
2238 }
2239 ++child_idx;
2240 }
2241 }
2242 }
2243 }
2244 }
2245 break;
2246
2247 case clang::Type::ObjCObjectPointer:
2248 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002249 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2250 QualType pointee_type = pointer_type->getPointeeType();
2251
2252 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2253 {
2254 return GetChildClangTypeAtIndex (ast_context,
2255 parent_name,
2256 pointer_type->getPointeeType().getAsOpaquePtr(),
2257 idx,
2258 transparent_pointers,
2259 omit_empty_base_classes,
2260 child_name,
2261 child_byte_size,
2262 child_byte_offset,
2263 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002264 child_bitfield_bit_offset,
2265 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002266 }
2267 else
2268 {
2269 if (parent_name)
2270 {
2271 child_name.assign(1, '*');
2272 child_name += parent_name;
2273 }
2274
2275 // We have a pointer to an simple type
2276 if (idx == 0)
2277 {
2278 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2279 assert(clang_type_info.first % 8 == 0);
2280 child_byte_size = clang_type_info.first / 8;
2281 child_byte_offset = 0;
2282 return pointee_type.getAsOpaquePtr();
2283 }
2284 }
Greg Clayton9488b742010-07-28 02:04:09 +00002285 }
2286 break;
2287
Greg Clayton1674b122010-07-21 22:12:05 +00002288 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002289 {
2290 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2291 const uint64_t element_count = array->getSize().getLimitedValue();
2292
2293 if (idx < element_count)
2294 {
2295 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2296
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002297 char element_name[64];
2298 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002299
2300 child_name.assign(element_name);
2301 assert(field_type_info.first % 8 == 0);
2302 child_byte_size = field_type_info.first / 8;
2303 child_byte_offset = idx * child_byte_size;
2304 return array->getElementType().getAsOpaquePtr();
2305 }
2306 }
2307 break;
2308
Greg Clayton1674b122010-07-21 22:12:05 +00002309 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002310 {
2311 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2312 QualType pointee_type = pointer_type->getPointeeType();
2313
2314 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2315 {
2316 return GetChildClangTypeAtIndex (ast_context,
2317 parent_name,
2318 pointer_type->getPointeeType().getAsOpaquePtr(),
2319 idx,
2320 transparent_pointers,
2321 omit_empty_base_classes,
2322 child_name,
2323 child_byte_size,
2324 child_byte_offset,
2325 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002326 child_bitfield_bit_offset,
2327 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002328 }
2329 else
2330 {
2331 if (parent_name)
2332 {
2333 child_name.assign(1, '*');
2334 child_name += parent_name;
2335 }
2336
2337 // We have a pointer to an simple type
2338 if (idx == 0)
2339 {
2340 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2341 assert(clang_type_info.first % 8 == 0);
2342 child_byte_size = clang_type_info.first / 8;
2343 child_byte_offset = 0;
2344 return pointee_type.getAsOpaquePtr();
2345 }
2346 }
2347 }
2348 break;
2349
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002350 case clang::Type::LValueReference:
2351 case clang::Type::RValueReference:
2352 {
2353 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2354 QualType pointee_type(reference_type->getPointeeType());
2355 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2356 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2357 {
2358 return GetChildClangTypeAtIndex (ast_context,
2359 parent_name,
2360 pointee_clang_type,
2361 idx,
2362 transparent_pointers,
2363 omit_empty_base_classes,
2364 child_name,
2365 child_byte_size,
2366 child_byte_offset,
2367 child_bitfield_bit_size,
2368 child_bitfield_bit_offset,
2369 child_is_base_class);
2370 }
2371 else
2372 {
2373 if (parent_name)
2374 {
2375 child_name.assign(1, '&');
2376 child_name += parent_name;
2377 }
2378
2379 // We have a pointer to an simple type
2380 if (idx == 0)
2381 {
2382 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2383 assert(clang_type_info.first % 8 == 0);
2384 child_byte_size = clang_type_info.first / 8;
2385 child_byte_offset = 0;
2386 return pointee_type.getAsOpaquePtr();
2387 }
2388 }
2389 }
2390 break;
2391
Greg Clayton1674b122010-07-21 22:12:05 +00002392 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002393 return GetChildClangTypeAtIndex (ast_context,
2394 parent_name,
2395 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2396 idx,
2397 transparent_pointers,
2398 omit_empty_base_classes,
2399 child_name,
2400 child_byte_size,
2401 child_byte_offset,
2402 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002403 child_bitfield_bit_offset,
2404 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002405 break;
2406
2407 default:
2408 break;
2409 }
2410 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002411 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002412}
2413
2414static inline bool
2415BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2416{
2417 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2418}
2419
2420static uint32_t
2421GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2422{
2423 uint32_t num_bases = 0;
2424 if (cxx_record_decl)
2425 {
2426 if (omit_empty_base_classes)
2427 {
2428 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2429 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2430 base_class != base_class_end;
2431 ++base_class)
2432 {
2433 // Skip empty base classes
2434 if (omit_empty_base_classes)
2435 {
2436 if (BaseSpecifierIsEmpty (base_class))
2437 continue;
2438 }
2439 ++num_bases;
2440 }
2441 }
2442 else
2443 num_bases = cxx_record_decl->getNumBases();
2444 }
2445 return num_bases;
2446}
2447
2448
2449static uint32_t
2450GetIndexForRecordBase
2451(
2452 const RecordDecl *record_decl,
2453 const CXXBaseSpecifier *base_spec,
2454 bool omit_empty_base_classes
2455)
2456{
2457 uint32_t child_idx = 0;
2458
2459 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2460
2461// const char *super_name = record_decl->getNameAsCString();
2462// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2463// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2464//
2465 if (cxx_record_decl)
2466 {
2467 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2468 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2469 base_class != base_class_end;
2470 ++base_class)
2471 {
2472 if (omit_empty_base_classes)
2473 {
2474 if (BaseSpecifierIsEmpty (base_class))
2475 continue;
2476 }
2477
2478// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2479// child_idx,
2480// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2481//
2482//
2483 if (base_class == base_spec)
2484 return child_idx;
2485 ++child_idx;
2486 }
2487 }
2488
2489 return UINT32_MAX;
2490}
2491
2492
2493static uint32_t
2494GetIndexForRecordChild
2495(
2496 const RecordDecl *record_decl,
2497 NamedDecl *canonical_decl,
2498 bool omit_empty_base_classes
2499)
2500{
2501 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2502
2503// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2504//
2505//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2506// if (cxx_record_decl)
2507// {
2508// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2509// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2510// base_class != base_class_end;
2511// ++base_class)
2512// {
2513// if (omit_empty_base_classes)
2514// {
2515// if (BaseSpecifierIsEmpty (base_class))
2516// continue;
2517// }
2518//
2519//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2520//// record_decl->getNameAsCString(),
2521//// canonical_decl->getNameAsCString(),
2522//// child_idx,
2523//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2524//
2525//
2526// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2527// if (curr_base_class_decl == canonical_decl)
2528// {
2529// return child_idx;
2530// }
2531// ++child_idx;
2532// }
2533// }
2534//
2535// const uint32_t num_bases = child_idx;
2536 RecordDecl::field_iterator field, field_end;
2537 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2538 field != field_end;
2539 ++field, ++child_idx)
2540 {
2541// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2542// record_decl->getNameAsCString(),
2543// canonical_decl->getNameAsCString(),
2544// child_idx - num_bases,
2545// field->getNameAsCString());
2546
2547 if (field->getCanonicalDecl() == canonical_decl)
2548 return child_idx;
2549 }
2550
2551 return UINT32_MAX;
2552}
2553
2554// Look for a child member (doesn't include base classes, but it does include
2555// their members) in the type hierarchy. Returns an index path into "clang_type"
2556// on how to reach the appropriate member.
2557//
2558// class A
2559// {
2560// public:
2561// int m_a;
2562// int m_b;
2563// };
2564//
2565// class B
2566// {
2567// };
2568//
2569// class C :
2570// public B,
2571// public A
2572// {
2573// };
2574//
2575// If we have a clang type that describes "class C", and we wanted to looked
2576// "m_b" in it:
2577//
2578// With omit_empty_base_classes == false we would get an integer array back with:
2579// { 1, 1 }
2580// The first index 1 is the child index for "class A" within class C
2581// The second index 1 is the child index for "m_b" within class A
2582//
2583// With omit_empty_base_classes == true we would get an integer array back with:
2584// { 0, 1 }
2585// 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)
2586// The second index 1 is the child index for "m_b" within class A
2587
2588size_t
2589ClangASTContext::GetIndexOfChildMemberWithName
2590(
2591 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002592 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002593 const char *name,
2594 bool omit_empty_base_classes,
2595 std::vector<uint32_t>& child_indexes
2596)
2597{
2598 if (clang_type && name && name[0])
2599 {
2600 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002601 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2602 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002603 {
Greg Clayton1674b122010-07-21 22:12:05 +00002604 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002605 {
2606 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2607 const RecordDecl *record_decl = record_type->getDecl();
2608
2609 assert(record_decl);
2610 uint32_t child_idx = 0;
2611
2612 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2613
2614 // Try and find a field that matches NAME
2615 RecordDecl::field_iterator field, field_end;
2616 StringRef name_sref(name);
2617 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2618 field != field_end;
2619 ++field, ++child_idx)
2620 {
2621 if (field->getName().equals (name_sref))
2622 {
2623 // We have to add on the number of base classes to this index!
2624 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2625 return child_indexes.size();
2626 }
2627 }
2628
2629 if (cxx_record_decl)
2630 {
2631 const RecordDecl *parent_record_decl = cxx_record_decl;
2632
2633 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2634
2635 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2636 // Didn't find things easily, lets let clang do its thang...
2637 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2638 DeclarationName decl_name(&ident_ref);
2639
2640 CXXBasePaths paths;
2641 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2642 decl_name.getAsOpaquePtr(),
2643 paths))
2644 {
Chris Lattner24943d22010-06-08 16:52:24 +00002645 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2646 for (path = paths.begin(); path != path_end; ++path)
2647 {
2648 const size_t num_path_elements = path->size();
2649 for (size_t e=0; e<num_path_elements; ++e)
2650 {
2651 CXXBasePathElement elem = (*path)[e];
2652
2653 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2654 if (child_idx == UINT32_MAX)
2655 {
2656 child_indexes.clear();
2657 return 0;
2658 }
2659 else
2660 {
2661 child_indexes.push_back (child_idx);
2662 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2663 }
2664 }
2665 DeclContext::lookup_iterator named_decl_pos;
2666 for (named_decl_pos = path->Decls.first;
2667 named_decl_pos != path->Decls.second && parent_record_decl;
2668 ++named_decl_pos)
2669 {
2670 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2671
2672 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2673 if (child_idx == UINT32_MAX)
2674 {
2675 child_indexes.clear();
2676 return 0;
2677 }
2678 else
2679 {
2680 child_indexes.push_back (child_idx);
2681 }
2682 }
2683 }
2684 return child_indexes.size();
2685 }
2686 }
2687
2688 }
2689 break;
2690
Greg Clayton9488b742010-07-28 02:04:09 +00002691 case clang::Type::ObjCObject:
2692 case clang::Type::ObjCInterface:
2693 {
2694 StringRef name_sref(name);
2695 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2696 assert (objc_class_type);
2697 if (objc_class_type)
2698 {
2699 uint32_t child_idx = 0;
2700 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2701
2702 if (class_interface_decl)
2703 {
2704 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2705 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2706
Greg Clayton823533e2010-09-18 02:11:07 +00002707 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002708 {
2709 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2710
2711 if (ivar_decl->getName().equals (name_sref))
2712 {
2713 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2714 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2715 ++child_idx;
2716
2717 child_indexes.push_back (child_idx);
2718 return child_indexes.size();
2719 }
2720 }
2721
2722 if (superclass_interface_decl)
2723 {
2724 // The super class index is always zero for ObjC classes,
2725 // so we push it onto the child indexes in case we find
2726 // an ivar in our superclass...
2727 child_indexes.push_back (0);
2728
2729 if (GetIndexOfChildMemberWithName (ast_context,
2730 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2731 name,
2732 omit_empty_base_classes,
2733 child_indexes))
2734 {
2735 // We did find an ivar in a superclass so just
2736 // return the results!
2737 return child_indexes.size();
2738 }
2739
2740 // We didn't find an ivar matching "name" in our
2741 // superclass, pop the superclass zero index that
2742 // we pushed on above.
2743 child_indexes.pop_back();
2744 }
2745 }
2746 }
2747 }
2748 break;
2749
2750 case clang::Type::ObjCObjectPointer:
2751 {
2752 return GetIndexOfChildMemberWithName (ast_context,
2753 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2754 name,
2755 omit_empty_base_classes,
2756 child_indexes);
2757 }
2758 break;
2759
2760
Greg Clayton1674b122010-07-21 22:12:05 +00002761 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002762 {
2763// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2764// const uint64_t element_count = array->getSize().getLimitedValue();
2765//
2766// if (idx < element_count)
2767// {
2768// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2769//
2770// char element_name[32];
2771// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2772//
2773// child_name.assign(element_name);
2774// assert(field_type_info.first % 8 == 0);
2775// child_byte_size = field_type_info.first / 8;
2776// child_byte_offset = idx * child_byte_size;
2777// return array->getElementType().getAsOpaquePtr();
2778// }
2779 }
2780 break;
2781
Greg Clayton1674b122010-07-21 22:12:05 +00002782// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002783// {
2784// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2785// QualType pointee_type = mem_ptr_type->getPointeeType();
2786//
2787// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2788// {
2789// return GetIndexOfChildWithName (ast_context,
2790// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2791// name);
2792// }
2793// }
2794// break;
2795//
Greg Clayton1674b122010-07-21 22:12:05 +00002796 case clang::Type::LValueReference:
2797 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002798 {
2799 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2800 QualType pointee_type = reference_type->getPointeeType();
2801
2802 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2803 {
2804 return GetIndexOfChildMemberWithName (ast_context,
2805 reference_type->getPointeeType().getAsOpaquePtr(),
2806 name,
2807 omit_empty_base_classes,
2808 child_indexes);
2809 }
2810 }
2811 break;
2812
Greg Clayton1674b122010-07-21 22:12:05 +00002813 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002814 {
2815 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2816 QualType pointee_type = pointer_type->getPointeeType();
2817
2818 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2819 {
2820 return GetIndexOfChildMemberWithName (ast_context,
2821 pointer_type->getPointeeType().getAsOpaquePtr(),
2822 name,
2823 omit_empty_base_classes,
2824 child_indexes);
2825 }
2826 else
2827 {
2828// if (parent_name)
2829// {
2830// child_name.assign(1, '*');
2831// child_name += parent_name;
2832// }
2833//
2834// // We have a pointer to an simple type
2835// if (idx == 0)
2836// {
2837// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2838// assert(clang_type_info.first % 8 == 0);
2839// child_byte_size = clang_type_info.first / 8;
2840// child_byte_offset = 0;
2841// return pointee_type.getAsOpaquePtr();
2842// }
2843 }
2844 }
2845 break;
2846
Greg Clayton1674b122010-07-21 22:12:05 +00002847 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002848 return GetIndexOfChildMemberWithName (ast_context,
2849 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2850 name,
2851 omit_empty_base_classes,
2852 child_indexes);
2853
2854 default:
2855 break;
2856 }
2857 }
2858 return 0;
2859}
2860
2861
2862// Get the index of the child of "clang_type" whose name matches. This function
2863// doesn't descend into the children, but only looks one level deep and name
2864// matches can include base class names.
2865
2866uint32_t
2867ClangASTContext::GetIndexOfChildWithName
2868(
2869 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002870 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002871 const char *name,
2872 bool omit_empty_base_classes
2873)
2874{
2875 if (clang_type && name && name[0])
2876 {
2877 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002878
Greg Clayton03e0f972010-09-13 03:32:57 +00002879 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002880
Greg Clayton03e0f972010-09-13 03:32:57 +00002881 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002882 {
Greg Clayton1674b122010-07-21 22:12:05 +00002883 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002884 {
2885 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2886 const RecordDecl *record_decl = record_type->getDecl();
2887
2888 assert(record_decl);
2889 uint32_t child_idx = 0;
2890
2891 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2892
2893 if (cxx_record_decl)
2894 {
2895 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2896 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2897 base_class != base_class_end;
2898 ++base_class)
2899 {
2900 // Skip empty base classes
2901 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2902 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2903 continue;
2904
2905 if (base_class->getType().getAsString().compare (name) == 0)
2906 return child_idx;
2907 ++child_idx;
2908 }
2909 }
2910
2911 // Try and find a field that matches NAME
2912 RecordDecl::field_iterator field, field_end;
2913 StringRef name_sref(name);
2914 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2915 field != field_end;
2916 ++field, ++child_idx)
2917 {
2918 if (field->getName().equals (name_sref))
2919 return child_idx;
2920 }
2921
2922 }
2923 break;
2924
Greg Clayton9488b742010-07-28 02:04:09 +00002925 case clang::Type::ObjCObject:
2926 case clang::Type::ObjCInterface:
2927 {
2928 StringRef name_sref(name);
2929 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2930 assert (objc_class_type);
2931 if (objc_class_type)
2932 {
2933 uint32_t child_idx = 0;
2934 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2935
2936 if (class_interface_decl)
2937 {
2938 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2939 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2940
2941 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2942 {
2943 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2944
2945 if (ivar_decl->getName().equals (name_sref))
2946 {
2947 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2948 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2949 ++child_idx;
2950
2951 return child_idx;
2952 }
2953 }
2954
2955 if (superclass_interface_decl)
2956 {
2957 if (superclass_interface_decl->getName().equals (name_sref))
2958 return 0;
2959 }
2960 }
2961 }
2962 }
2963 break;
2964
2965 case clang::Type::ObjCObjectPointer:
2966 {
2967 return GetIndexOfChildWithName (ast_context,
2968 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2969 name,
2970 omit_empty_base_classes);
2971 }
2972 break;
2973
Greg Clayton1674b122010-07-21 22:12:05 +00002974 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002975 {
2976// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2977// const uint64_t element_count = array->getSize().getLimitedValue();
2978//
2979// if (idx < element_count)
2980// {
2981// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2982//
2983// char element_name[32];
2984// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2985//
2986// child_name.assign(element_name);
2987// assert(field_type_info.first % 8 == 0);
2988// child_byte_size = field_type_info.first / 8;
2989// child_byte_offset = idx * child_byte_size;
2990// return array->getElementType().getAsOpaquePtr();
2991// }
2992 }
2993 break;
2994
Greg Clayton1674b122010-07-21 22:12:05 +00002995// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002996// {
2997// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2998// QualType pointee_type = mem_ptr_type->getPointeeType();
2999//
3000// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3001// {
3002// return GetIndexOfChildWithName (ast_context,
3003// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3004// name);
3005// }
3006// }
3007// break;
3008//
Greg Clayton1674b122010-07-21 22:12:05 +00003009 case clang::Type::LValueReference:
3010 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003011 {
3012 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3013 QualType pointee_type = reference_type->getPointeeType();
3014
3015 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3016 {
3017 return GetIndexOfChildWithName (ast_context,
3018 reference_type->getPointeeType().getAsOpaquePtr(),
3019 name,
3020 omit_empty_base_classes);
3021 }
3022 }
3023 break;
3024
Greg Clayton1674b122010-07-21 22:12:05 +00003025 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003026 {
3027 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3028 QualType pointee_type = pointer_type->getPointeeType();
3029
3030 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3031 {
3032 return GetIndexOfChildWithName (ast_context,
3033 pointer_type->getPointeeType().getAsOpaquePtr(),
3034 name,
3035 omit_empty_base_classes);
3036 }
3037 else
3038 {
3039// if (parent_name)
3040// {
3041// child_name.assign(1, '*');
3042// child_name += parent_name;
3043// }
3044//
3045// // We have a pointer to an simple type
3046// if (idx == 0)
3047// {
3048// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3049// assert(clang_type_info.first % 8 == 0);
3050// child_byte_size = clang_type_info.first / 8;
3051// child_byte_offset = 0;
3052// return pointee_type.getAsOpaquePtr();
3053// }
3054 }
3055 }
3056 break;
3057
Greg Clayton1674b122010-07-21 22:12:05 +00003058 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003059 return GetIndexOfChildWithName (ast_context,
3060 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3061 name,
3062 omit_empty_base_classes);
3063
3064 default:
3065 break;
3066 }
3067 }
3068 return UINT32_MAX;
3069}
3070
3071#pragma mark TagType
3072
3073bool
Greg Clayton462d4142010-09-29 01:12:09 +00003074ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003075{
3076 if (tag_clang_type)
3077 {
3078 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003079 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003080 if (clang_type)
3081 {
3082 TagType *tag_type = dyn_cast<TagType>(clang_type);
3083 if (tag_type)
3084 {
3085 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3086 if (tag_decl)
3087 {
3088 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3089 return true;
3090 }
3091 }
3092 }
3093 }
3094 return false;
3095}
3096
3097
3098#pragma mark DeclContext Functions
3099
3100DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003101ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003102{
3103 if (clang_type == NULL)
3104 return NULL;
3105
3106 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003107 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3108 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003109 {
Greg Clayton9488b742010-07-28 02:04:09 +00003110 case clang::Type::FunctionNoProto: break;
3111 case clang::Type::FunctionProto: break;
3112 case clang::Type::IncompleteArray: break;
3113 case clang::Type::VariableArray: break;
3114 case clang::Type::ConstantArray: break;
3115 case clang::Type::ExtVector: break;
3116 case clang::Type::Vector: break;
3117 case clang::Type::Builtin: break;
3118 case clang::Type::BlockPointer: break;
3119 case clang::Type::Pointer: break;
3120 case clang::Type::LValueReference: break;
3121 case clang::Type::RValueReference: break;
3122 case clang::Type::MemberPointer: break;
3123 case clang::Type::Complex: break;
3124 case clang::Type::ObjCObject: break;
3125 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3126 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3127 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3128 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
3129 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003130
Greg Clayton9488b742010-07-28 02:04:09 +00003131 case clang::Type::TypeOfExpr: break;
3132 case clang::Type::TypeOf: break;
3133 case clang::Type::Decltype: break;
3134 //case clang::Type::QualifiedName: break;
3135 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003136 }
3137 // No DeclContext in this type...
3138 return NULL;
3139}
3140
3141#pragma mark Namespace Declarations
3142
3143NamespaceDecl *
3144ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3145{
3146 // TODO: Do something intelligent with the Declaration object passed in
3147 // like maybe filling in the SourceLocation with it...
3148 if (name)
3149 {
3150 ASTContext *ast_context = getASTContext();
3151 if (decl_ctx == NULL)
3152 decl_ctx = ast_context->getTranslationUnitDecl();
3153 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3154 }
3155 return NULL;
3156}
3157
3158
3159#pragma mark Function Types
3160
3161FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003162ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003163{
3164 if (name)
3165 {
3166 ASTContext *ast_context = getASTContext();
3167 assert (ast_context != NULL);
3168
3169 if (name && name[0])
3170 {
3171 return FunctionDecl::Create(*ast_context,
3172 ast_context->getTranslationUnitDecl(),
3173 SourceLocation(),
3174 DeclarationName (&ast_context->Idents.get(name)),
3175 QualType::getFromOpaquePtr(function_clang_type),
3176 NULL,
3177 (FunctionDecl::StorageClass)storage,
3178 (FunctionDecl::StorageClass)storage,
3179 is_inline);
3180 }
3181 else
3182 {
3183 return FunctionDecl::Create(*ast_context,
3184 ast_context->getTranslationUnitDecl(),
3185 SourceLocation(),
3186 DeclarationName (),
3187 QualType::getFromOpaquePtr(function_clang_type),
3188 NULL,
3189 (FunctionDecl::StorageClass)storage,
3190 (FunctionDecl::StorageClass)storage,
3191 is_inline);
3192 }
3193 }
3194 return NULL;
3195}
3196
Greg Clayton462d4142010-09-29 01:12:09 +00003197clang_type_t
3198ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3199 clang_type_t result_type,
3200 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003201 unsigned num_args,
3202 bool is_variadic,
3203 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003204{
Chris Lattner24943d22010-06-08 16:52:24 +00003205 assert (ast_context != NULL);
3206 std::vector<QualType> qual_type_args;
3207 for (unsigned i=0; i<num_args; ++i)
3208 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3209
3210 // TODO: Detect calling convention in DWARF?
3211 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003212 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003213 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003214 is_variadic,
3215 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003216 false, // hasExceptionSpec
3217 false, // hasAnyExceptionSpec,
3218 0, // NumExs
3219 0, // const QualType *ExArray
3220 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3221}
3222
3223ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003224ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003225{
3226 ASTContext *ast_context = getASTContext();
3227 assert (ast_context != NULL);
3228 return ParmVarDecl::Create(*ast_context,
3229 ast_context->getTranslationUnitDecl(),
3230 SourceLocation(),
3231 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003232 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003233 NULL,
3234 (VarDecl::StorageClass)storage,
3235 (VarDecl::StorageClass)storage,
3236 0);
3237}
3238
3239void
3240ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3241{
3242 if (function_decl)
3243 function_decl->setParams (params, num_params);
3244}
3245
3246
3247#pragma mark Array Types
3248
Greg Clayton462d4142010-09-29 01:12:09 +00003249clang_type_t
3250ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003251{
3252 if (element_type)
3253 {
3254 ASTContext *ast_context = getASTContext();
3255 assert (ast_context != NULL);
3256 llvm::APInt ap_element_count (64, element_count);
3257 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3258 ap_element_count,
3259 ArrayType::Normal,
3260 0).getAsOpaquePtr(); // ElemQuals
3261 }
3262 return NULL;
3263}
3264
3265
3266#pragma mark TagDecl
3267
3268bool
Greg Clayton462d4142010-09-29 01:12:09 +00003269ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003270{
3271 if (clang_type)
3272 {
3273 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003274 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003275 if (t)
3276 {
3277 TagType *tag_type = dyn_cast<TagType>(t);
3278 if (tag_type)
3279 {
3280 TagDecl *tag_decl = tag_type->getDecl();
3281 if (tag_decl)
3282 {
3283 tag_decl->startDefinition();
3284 return true;
3285 }
3286 }
3287 }
3288 }
3289 return false;
3290}
3291
3292bool
Greg Clayton462d4142010-09-29 01:12:09 +00003293ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003294{
3295 if (clang_type)
3296 {
3297 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00003298
3299 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3300
3301 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003302 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003303 cxx_record_decl->completeDefinition();
3304
3305 return true;
3306 }
3307
Sean Callanan04325062010-10-25 00:29:48 +00003308 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3309
3310 if (objc_class_type)
3311 {
3312 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3313
3314 class_interface_decl->setForwardDecl(false);
3315 }
3316
Greg Clayton55b6c532010-09-29 03:44:17 +00003317 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3318
3319 if (enum_type)
3320 {
3321 EnumDecl *enum_decl = enum_type->getDecl();
3322
3323 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003324 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003325 /// TODO This really needs to be fixed.
3326
3327 unsigned NumPositiveBits = 1;
3328 unsigned NumNegativeBits = 0;
3329
Greg Clayton48fbdf72010-10-12 04:29:14 +00003330 ASTContext *ast_context = getASTContext();
3331
3332 QualType promotion_qual_type;
3333 // If the enum integer type is less than an integer in bit width,
3334 // then we must promote it to an integer size.
3335 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3336 {
3337 if (enum_decl->getIntegerType()->isSignedIntegerType())
3338 promotion_qual_type = ast_context->IntTy;
3339 else
3340 promotion_qual_type = ast_context->UnsignedIntTy;
3341 }
3342 else
3343 promotion_qual_type = enum_decl->getIntegerType();
3344
3345 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003346 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003347 }
3348 }
3349 }
3350 return false;
3351}
3352
3353
3354#pragma mark Enumeration Types
3355
Greg Clayton462d4142010-09-29 01:12:09 +00003356clang_type_t
3357ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003358{
3359 // TODO: Do something intelligent with the Declaration object passed in
3360 // like maybe filling in the SourceLocation with it...
3361 ASTContext *ast_context = getASTContext();
3362 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003363
3364 // TODO: ask about these...
3365// const bool IsScoped = false;
3366// const bool IsFixed = false;
3367
3368 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3369 ast_context->getTranslationUnitDecl(),
3370 SourceLocation(),
3371 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3372 SourceLocation(),
Sean Callanan8950c9a2010-10-29 18:38:40 +00003373 NULL, false, false); //IsScoped, IsFixed);
Chris Lattner24943d22010-06-08 16:52:24 +00003374 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003375 {
3376 // TODO: check if we should be setting the promotion type too?
3377 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003378 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003379 }
Chris Lattner24943d22010-06-08 16:52:24 +00003380 return NULL;
3381}
3382
Greg Clayton462d4142010-09-29 01:12:09 +00003383clang_type_t
3384ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3385{
3386 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3387
3388 clang::Type *clang_type = enum_qual_type.getTypePtr();
3389 if (clang_type)
3390 {
3391 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3392 if (enum_type)
3393 {
3394 EnumDecl *enum_decl = enum_type->getDecl();
3395 if (enum_decl)
3396 return enum_decl->getIntegerType().getAsOpaquePtr();
3397 }
3398 }
3399 return NULL;
3400}
Chris Lattner24943d22010-06-08 16:52:24 +00003401bool
3402ClangASTContext::AddEnumerationValueToEnumerationType
3403(
Greg Clayton462d4142010-09-29 01:12:09 +00003404 clang_type_t enum_clang_type,
3405 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003406 const Declaration &decl,
3407 const char *name,
3408 int64_t enum_value,
3409 uint32_t enum_value_bit_size
3410)
3411{
3412 if (enum_clang_type && enumerator_clang_type && name)
3413 {
3414 // TODO: Do something intelligent with the Declaration object passed in
3415 // like maybe filling in the SourceLocation with it...
3416 ASTContext *ast_context = getASTContext();
3417 IdentifierTable *identifier_table = getIdentifierTable();
3418
3419 assert (ast_context != NULL);
3420 assert (identifier_table != NULL);
3421 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3422
Greg Clayton1674b122010-07-21 22:12:05 +00003423 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003424 if (clang_type)
3425 {
3426 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3427
3428 if (enum_type)
3429 {
3430 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3431 enum_llvm_apsint = enum_value;
3432 EnumConstantDecl *enumerator_decl =
3433 EnumConstantDecl::Create(*ast_context,
3434 enum_type->getDecl(),
3435 SourceLocation(),
3436 name ? &identifier_table->get(name) : NULL, // Identifier
3437 QualType::getFromOpaquePtr(enumerator_clang_type),
3438 NULL,
3439 enum_llvm_apsint);
3440
3441 if (enumerator_decl)
3442 {
3443 enum_type->getDecl()->addDecl(enumerator_decl);
3444 return true;
3445 }
3446 }
3447 }
3448 }
3449 return false;
3450}
3451
3452#pragma mark Pointers & References
3453
Greg Clayton462d4142010-09-29 01:12:09 +00003454clang_type_t
3455ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003456{
3457 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003458 {
3459 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3460
Greg Clayton03e0f972010-09-13 03:32:57 +00003461 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3462 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003463 {
3464 case clang::Type::ObjCObject:
3465 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003466 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3467
Greg Clayton7b541032010-07-29 20:06:32 +00003468 default:
3469 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3470 }
3471 }
Chris Lattner24943d22010-06-08 16:52:24 +00003472 return NULL;
3473}
3474
Greg Clayton462d4142010-09-29 01:12:09 +00003475clang_type_t
3476ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003477{
3478 if (clang_type)
3479 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3480 return NULL;
3481}
3482
Greg Clayton462d4142010-09-29 01:12:09 +00003483clang_type_t
3484ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003485{
3486 if (clang_type)
3487 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3488 return NULL;
3489}
3490
Greg Clayton462d4142010-09-29 01:12:09 +00003491clang_type_t
3492ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003493{
3494 if (clang_pointee_type && clang_pointee_type)
3495 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3496 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3497 return NULL;
3498}
3499
Chris Lattner24943d22010-06-08 16:52:24 +00003500size_t
3501ClangASTContext::GetPointerBitSize ()
3502{
3503 ASTContext *ast_context = getASTContext();
3504 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3505}
3506
3507bool
Greg Clayton462d4142010-09-29 01:12:09 +00003508ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003509{
3510 if (clang_type == NULL)
3511 return false;
3512
3513 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003514 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3515 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003516 {
Sean Callanan04325062010-10-25 00:29:48 +00003517 case clang::Type::Builtin:
3518 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3519 {
3520 default:
3521 break;
3522 case clang::BuiltinType::ObjCId:
3523 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003524 return true;
3525 }
3526 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003527 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003528 if (target_type)
3529 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3530 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003531 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003532 if (target_type)
3533 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3534 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003535 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003536 if (target_type)
3537 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3538 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003539 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003540 if (target_type)
3541 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3542 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003543 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003544 if (target_type)
3545 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3546 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003547 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003548 if (target_type)
3549 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3550 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003551 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003552 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3553 default:
3554 break;
3555 }
3556 return false;
3557}
3558
Chris Lattner24943d22010-06-08 16:52:24 +00003559bool
Greg Clayton462d4142010-09-29 01:12:09 +00003560ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003561{
3562 if (!clang_type)
3563 return false;
3564
3565 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3566 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3567
3568 if (builtin_type)
3569 {
3570 if (builtin_type->isInteger())
3571 is_signed = builtin_type->isSignedInteger();
3572
3573 return true;
3574 }
3575
3576 return false;
3577}
3578
3579bool
Greg Clayton462d4142010-09-29 01:12:09 +00003580ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003581{
3582 if (clang_type)
3583 {
3584 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003585 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3586 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003587 {
Sean Callanan04325062010-10-25 00:29:48 +00003588 case clang::Type::Builtin:
3589 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3590 {
3591 default:
3592 break;
3593 case clang::BuiltinType::ObjCId:
3594 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003595 return true;
3596 }
3597 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003598 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003599 if (target_type)
3600 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3601 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003602 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003603 if (target_type)
3604 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3605 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003606 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003607 if (target_type)
3608 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3609 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003610 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003611 if (target_type)
3612 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3613 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003614 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003615 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3616 default:
3617 break;
3618 }
3619 }
3620 return false;
3621}
3622
3623bool
Greg Clayton462d4142010-09-29 01:12:09 +00003624ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003625{
3626 if (clang_type)
3627 {
3628 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3629
3630 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3631 {
3632 clang::BuiltinType::Kind kind = BT->getKind();
3633 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3634 {
3635 count = 1;
3636 is_complex = false;
3637 return true;
3638 }
3639 }
3640 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3641 {
3642 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3643 {
3644 count = 2;
3645 is_complex = true;
3646 return true;
3647 }
3648 }
3649 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3650 {
3651 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3652 {
3653 count = VT->getNumElements();
3654 is_complex = false;
3655 return true;
3656 }
3657 }
3658 }
3659 return false;
3660}
3661
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003662
3663bool
3664ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3665{
3666 if (clang_type)
3667 {
3668 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3669
3670 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3671 if (cxx_record_decl)
3672 {
3673 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3674 return true;
3675 }
3676 }
3677 class_name.clear();
3678 return false;
3679}
3680
3681
Greg Clayton1d8173f2010-09-24 05:15:53 +00003682bool
Greg Clayton462d4142010-09-29 01:12:09 +00003683ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003684{
3685 if (clang_type)
3686 {
3687 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3688 if (qual_type->getAsCXXRecordDecl() != NULL)
3689 return true;
3690 }
3691 return false;
3692}
3693
3694bool
Greg Clayton462d4142010-09-29 01:12:09 +00003695ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003696{
3697 if (clang_type)
3698 {
3699 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3700 if (qual_type->isObjCObjectOrInterfaceType())
3701 return true;
3702 }
3703 return false;
3704}
3705
3706
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003707bool
3708ClangASTContext::IsCharType (clang_type_t clang_type)
3709{
3710 if (clang_type)
3711 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3712 return false;
3713}
Chris Lattner24943d22010-06-08 16:52:24 +00003714
3715bool
Greg Clayton462d4142010-09-29 01:12:09 +00003716ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003717{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003718 clang_type_t pointee_or_element_clang_type = NULL;
3719 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3720
3721 if (pointee_or_element_clang_type == NULL)
3722 return false;
3723
3724 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003725 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003726 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3727
3728 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003729 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003730 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3731 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003732 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003733 // We know the size of the array and it could be a C string
3734 // since it is an array of characters
3735 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3736 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003737 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003738 else
Chris Lattner24943d22010-06-08 16:52:24 +00003739 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003740 length = 0;
3741 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003742 }
Chris Lattner24943d22010-06-08 16:52:24 +00003743
Chris Lattner24943d22010-06-08 16:52:24 +00003744 }
3745 }
3746 return false;
3747}
3748
3749bool
Greg Clayton462d4142010-09-29 01:12:09 +00003750ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003751{
3752 if (clang_type)
3753 {
3754 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3755
3756 if (qual_type->isFunctionPointerType())
3757 return true;
3758
3759 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3760 switch (type_class)
3761 {
3762 case clang::Type::Typedef:
3763 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3764
3765 case clang::Type::LValueReference:
3766 case clang::Type::RValueReference:
3767 {
3768 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3769 if (reference_type)
3770 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3771 }
3772 break;
3773 }
3774 }
3775 return false;
3776}
3777
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003778size_t
3779ClangASTContext::GetArraySize (clang_type_t clang_type)
3780{
3781 if (clang_type)
3782 {
3783 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3784 if (array)
3785 return array->getSize().getLimitedValue();
3786 }
3787 return 0;
3788}
Greg Clayton03e0f972010-09-13 03:32:57 +00003789
3790bool
Greg Clayton462d4142010-09-29 01:12:09 +00003791ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003792{
3793 if (!clang_type)
3794 return false;
3795
3796 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3797
Greg Clayton03e0f972010-09-13 03:32:57 +00003798 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3799 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003800 {
Greg Clayton1674b122010-07-21 22:12:05 +00003801 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003802 if (member_type)
3803 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3804 if (size)
3805 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3806 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003807 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003808 if (member_type)
3809 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3810 if (size)
3811 *size = 0;
3812 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003813 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003814 if (member_type)
3815 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3816 if (size)
3817 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003818 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003819 if (member_type)
3820 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3821 if (size)
3822 *size = 0;
3823 return true;
3824 }
3825 return false;
3826}
3827
3828
3829#pragma mark Typedefs
3830
Greg Clayton462d4142010-09-29 01:12:09 +00003831clang_type_t
3832ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003833{
3834 if (clang_type)
3835 {
3836 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3837 ASTContext *ast_context = getASTContext();
3838 IdentifierTable *identifier_table = getIdentifierTable();
3839 assert (ast_context != NULL);
3840 assert (identifier_table != NULL);
3841 if (decl_ctx == NULL)
3842 decl_ctx = ast_context->getTranslationUnitDecl();
3843 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3844 decl_ctx,
3845 SourceLocation(),
3846 name ? &identifier_table->get(name) : NULL, // Identifier
3847 ast_context->CreateTypeSourceInfo(qual_type));
3848
3849 // Get a uniqued QualType for the typedef decl type
3850 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3851 }
3852 return NULL;
3853}
3854
3855
3856std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003857ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003858{
3859 std::string return_name;
3860
Greg Clayton462d4142010-09-29 01:12:09 +00003861 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003862
Greg Clayton462d4142010-09-29 01:12:09 +00003863 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003864 if (typedef_type)
3865 {
Greg Clayton462d4142010-09-29 01:12:09 +00003866 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003867 return_name = typedef_decl->getQualifiedNameAsString();
3868 }
3869 else
3870 {
3871 return_name = qual_type.getAsString();
3872 }
3873
3874 return return_name;
3875}
3876
3877// Disable this for now since I can't seem to get a nicely formatted float
3878// out of the APFloat class without just getting the float, double or quad
3879// and then using a formatted print on it which defeats the purpose. We ideally
3880// would like to get perfect string values for any kind of float semantics
3881// so we can support remote targets. The code below also requires a patch to
3882// llvm::APInt.
3883//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003884//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 +00003885//{
3886// uint32_t count = 0;
3887// bool is_complex = false;
3888// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3889// {
3890// unsigned num_bytes_per_float = byte_size / count;
3891// unsigned num_bits_per_float = num_bytes_per_float * 8;
3892//
3893// float_str.clear();
3894// uint32_t i;
3895// for (i=0; i<count; i++)
3896// {
3897// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3898// bool is_ieee = false;
3899// APFloat ap_float(ap_int, is_ieee);
3900// char s[1024];
3901// unsigned int hex_digits = 0;
3902// bool upper_case = false;
3903//
3904// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3905// {
3906// if (i > 0)
3907// float_str.append(", ");
3908// float_str.append(s);
3909// if (i == 1 && is_complex)
3910// float_str.append(1, 'i');
3911// }
3912// }
3913// return !float_str.empty();
3914// }
3915// return false;
3916//}
3917
3918size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003919ClangASTContext::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 +00003920{
3921 if (clang_type)
3922 {
3923 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3924 uint32_t count = 0;
3925 bool is_complex = false;
3926 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3927 {
3928 // TODO: handle complex and vector types
3929 if (count != 1)
3930 return false;
3931
3932 StringRef s_sref(s);
3933 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3934
3935 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3936 const uint64_t byte_size = bit_size / 8;
3937 if (dst_size >= byte_size)
3938 {
3939 if (bit_size == sizeof(float)*8)
3940 {
3941 float float32 = ap_float.convertToFloat();
3942 ::memcpy (dst, &float32, byte_size);
3943 return byte_size;
3944 }
3945 else if (bit_size >= 64)
3946 {
3947 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3948 ::memcpy (dst, ap_int.getRawData(), byte_size);
3949 return byte_size;
3950 }
3951 }
3952 }
3953 }
3954 return 0;
3955}
Sean Callanana751f7b2010-09-17 02:24:29 +00003956
3957unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00003958ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00003959{
3960 assert (clang_type);
3961
3962 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3963
3964 return qual_type.getQualifiers().getCVRQualifiers();
3965}