blob: efea85acb45b490ceb72da271ca0284dc02aad8f [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"
26#include "clang/Basic/SourceManager.h"
27#include "clang/Basic/TargetInfo.h"
28#include "clang/Basic/TargetOptions.h"
29#include "clang/Frontend/FrontendOptions.h"
30#include "clang/Frontend/LangStandard.h"
Sean Callananbc4f0f52010-07-08 18:16:16 +000031#undef NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000032
Chris Lattner24943d22010-06-08 16:52:24 +000033#include "lldb/Core/dwarf.h"
Greg Claytonf3d0b0c2010-10-27 03:32:59 +000034#include "lldb/Core/Flags.h"
Sean Callanan839fde42010-10-28 18:19:36 +000035#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036
Eli Friedmanf05633b2010-06-13 19:06:42 +000037#include <stdio.h>
38
Greg Clayton585660c2010-08-05 01:57:25 +000039using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000040using namespace lldb_private;
41using namespace llvm;
42using namespace clang;
43
Greg Clayton84f80752010-07-22 18:30:50 +000044static AccessSpecifier
Greg Clayton585660c2010-08-05 01:57:25 +000045ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000046{
47 switch (access)
48 {
Greg Clayton585660c2010-08-05 01:57:25 +000049 default: break;
50 case eAccessNone: return AS_none;
51 case eAccessPublic: return AS_public;
52 case eAccessPrivate: return AS_private;
53 case eAccessProtected: return AS_protected;
Greg Clayton84f80752010-07-22 18:30:50 +000054 }
55 return AS_none;
56}
57
58static ObjCIvarDecl::AccessControl
Greg Clayton585660c2010-08-05 01:57:25 +000059ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000060{
61 switch (access)
62 {
Greg Clayton585660c2010-08-05 01:57:25 +000063 default: break;
64 case eAccessNone: return ObjCIvarDecl::None;
65 case eAccessPublic: return ObjCIvarDecl::Public;
66 case eAccessPrivate: return ObjCIvarDecl::Private;
67 case eAccessProtected: return ObjCIvarDecl::Protected;
68 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton84f80752010-07-22 18:30:50 +000069 }
70 return ObjCIvarDecl::None;
71}
72
73
Chris Lattner24943d22010-06-08 16:52:24 +000074static void
75ParseLangArgs
76(
77 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000078 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000079)
80{
81 // FIXME: Cleanup per-file based stuff.
82
83 // Set some properties which depend soley on the input kind; it would be nice
84 // to move these to the language standard, and have the driver resolve the
85 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000086 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000087 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000088 } else if (IK == IK_ObjC ||
89 IK == IK_ObjCXX ||
90 IK == IK_PreprocessedObjC ||
91 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000092 Opts.ObjC1 = Opts.ObjC2 = 1;
93 }
94
95 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
96
97 if (LangStd == LangStandard::lang_unspecified) {
98 // Based on the base language, pick one.
99 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +0000100 case IK_None:
101 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +0000102 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +0000103 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +0000104 LangStd = LangStandard::lang_opencl;
105 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000106 case IK_Asm:
107 case IK_C:
108 case IK_PreprocessedC:
109 case IK_ObjC:
110 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +0000111 LangStd = LangStandard::lang_gnu99;
112 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000113 case IK_CXX:
114 case IK_PreprocessedCXX:
115 case IK_ObjCXX:
116 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +0000117 LangStd = LangStandard::lang_gnucxx98;
118 break;
119 }
120 }
121
122 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
123 Opts.BCPLComment = Std.hasBCPLComments();
124 Opts.C99 = Std.isC99();
125 Opts.CPlusPlus = Std.isCPlusPlus();
126 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
127 Opts.Digraphs = Std.hasDigraphs();
128 Opts.GNUMode = Std.isGNUMode();
129 Opts.GNUInline = !Std.isC99();
130 Opts.HexFloats = Std.hasHexFloats();
131 Opts.ImplicitInt = Std.hasImplicitInt();
132
133 // OpenCL has some additional defaults.
134 if (LangStd == LangStandard::lang_opencl) {
135 Opts.OpenCL = 1;
136 Opts.AltiVec = 1;
137 Opts.CXXOperatorNames = 1;
138 Opts.LaxVectorConversions = 1;
139 }
140
141 // OpenCL and C++ both have bool, true, false keywords.
142 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
143
144// if (Opts.CPlusPlus)
145// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
146//
147// if (Args.hasArg(OPT_fobjc_gc_only))
148// Opts.setGCMode(LangOptions::GCOnly);
149// else if (Args.hasArg(OPT_fobjc_gc))
150// Opts.setGCMode(LangOptions::HybridGC);
151//
152// if (Args.hasArg(OPT_print_ivar_layout))
153// Opts.ObjCGCBitmapPrint = 1;
154//
155// if (Args.hasArg(OPT_faltivec))
156// Opts.AltiVec = 1;
157//
158// if (Args.hasArg(OPT_pthread))
159// Opts.POSIXThreads = 1;
160//
161// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
162// "default");
163// if (Vis == "default")
164 Opts.setVisibilityMode(LangOptions::Default);
165// else if (Vis == "hidden")
166// Opts.setVisibilityMode(LangOptions::Hidden);
167// else if (Vis == "protected")
168// Opts.setVisibilityMode(LangOptions::Protected);
169// else
170// Diags.Report(diag::err_drv_invalid_value)
171// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
172
173// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
174
175 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
176 // is specified, or -std is set to a conforming mode.
177 Opts.Trigraphs = !Opts.GNUMode;
178// if (Args.hasArg(OPT_trigraphs))
179// Opts.Trigraphs = 1;
180//
181// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
182// OPT_fno_dollars_in_identifiers,
183// !Opts.AsmPreprocessor);
184// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
185// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
186// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
187// if (Args.hasArg(OPT_fno_lax_vector_conversions))
188// Opts.LaxVectorConversions = 0;
189// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
190// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
191// Opts.Blocks = Args.hasArg(OPT_fblocks);
192// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
193// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
194// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
195// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
196// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
197// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
198// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
199// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
200// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
201// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
202// Diags);
203// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
204// Opts.ObjCConstantStringClass = getLastArgValue(Args,
205// OPT_fconstant_string_class);
206// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
207// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
208// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
209// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
210// Opts.Static = Args.hasArg(OPT_static_define);
211 Opts.OptimizeSize = 0;
212
213 // FIXME: Eliminate this dependency.
214// unsigned Opt =
215// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
216// Opts.Optimize = Opt != 0;
217 unsigned Opt = 0;
218
219 // This is the __NO_INLINE__ define, which just depends on things like the
220 // optimization level and -fno-inline, not actually whether the backend has
221 // inlining enabled.
222 //
223 // FIXME: This is affected by other options (-fno-inline).
224 Opts.NoInline = !Opt;
225
226// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
227// switch (SSP) {
228// default:
229// Diags.Report(diag::err_drv_invalid_value)
230// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
231// break;
232// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
233// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
234// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
235// }
236}
237
Chris Lattner24943d22010-06-08 16:52:24 +0000238
Chris Lattner24943d22010-06-08 16:52:24 +0000239ClangASTContext::ClangASTContext(const char *target_triple) :
240 m_target_triple(),
241 m_ast_context_ap(),
242 m_language_options_ap(),
243 m_source_manager_ap(),
244 m_diagnostic_ap(),
245 m_target_options_ap(),
246 m_target_info_ap(),
247 m_identifier_table_ap(),
248 m_selector_table_ap(),
249 m_builtins_ap()
250{
251 if (target_triple && target_triple[0])
252 m_target_triple.assign (target_triple);
253}
254
255//----------------------------------------------------------------------
256// Destructor
257//----------------------------------------------------------------------
258ClangASTContext::~ClangASTContext()
259{
260 m_builtins_ap.reset();
261 m_selector_table_ap.reset();
262 m_identifier_table_ap.reset();
263 m_target_info_ap.reset();
264 m_target_options_ap.reset();
265 m_diagnostic_ap.reset();
266 m_source_manager_ap.reset();
267 m_language_options_ap.reset();
268 m_ast_context_ap.reset();
269}
270
271
272void
273ClangASTContext::Clear()
274{
275 m_ast_context_ap.reset();
276 m_language_options_ap.reset();
277 m_source_manager_ap.reset();
278 m_diagnostic_ap.reset();
279 m_target_options_ap.reset();
280 m_target_info_ap.reset();
281 m_identifier_table_ap.reset();
282 m_selector_table_ap.reset();
283 m_builtins_ap.reset();
284}
285
286const char *
287ClangASTContext::GetTargetTriple ()
288{
289 return m_target_triple.c_str();
290}
291
292void
293ClangASTContext::SetTargetTriple (const char *target_triple)
294{
295 Clear();
296 m_target_triple.assign(target_triple);
297}
298
299
300ASTContext *
301ClangASTContext::getASTContext()
302{
303 if (m_ast_context_ap.get() == NULL)
304 {
305 m_ast_context_ap.reset(
306 new ASTContext(
307 *getLanguageOptions(),
308 *getSourceManager(),
309 *getTargetInfo(),
310 *getIdentifierTable(),
311 *getSelectorTable(),
Greg Clayton6e713402010-07-30 20:30:44 +0000312 *getBuiltinContext(),
313 0));
Chris Lattner24943d22010-06-08 16:52:24 +0000314 }
315 return m_ast_context_ap.get();
316}
317
318Builtin::Context *
319ClangASTContext::getBuiltinContext()
320{
321 if (m_builtins_ap.get() == NULL)
322 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
323 return m_builtins_ap.get();
324}
325
326IdentifierTable *
327ClangASTContext::getIdentifierTable()
328{
329 if (m_identifier_table_ap.get() == NULL)
330 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
331 return m_identifier_table_ap.get();
332}
333
334LangOptions *
335ClangASTContext::getLanguageOptions()
336{
337 if (m_language_options_ap.get() == NULL)
338 {
339 m_language_options_ap.reset(new LangOptions());
Greg Claytone41c4b22010-06-13 17:34:29 +0000340 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
341// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner24943d22010-06-08 16:52:24 +0000342 }
343 return m_language_options_ap.get();
344}
345
346SelectorTable *
347ClangASTContext::getSelectorTable()
348{
349 if (m_selector_table_ap.get() == NULL)
350 m_selector_table_ap.reset (new SelectorTable());
351 return m_selector_table_ap.get();
352}
353
Greg Clayton1674b122010-07-21 22:12:05 +0000354clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000355ClangASTContext::getSourceManager()
356{
357 if (m_source_manager_ap.get() == NULL)
Greg Clayton1674b122010-07-21 22:12:05 +0000358 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic()));
Chris Lattner24943d22010-06-08 16:52:24 +0000359 return m_source_manager_ap.get();
360}
361
362Diagnostic *
363ClangASTContext::getDiagnostic()
364{
365 if (m_diagnostic_ap.get() == NULL)
366 m_diagnostic_ap.reset(new Diagnostic());
367 return m_diagnostic_ap.get();
368}
369
370TargetOptions *
371ClangASTContext::getTargetOptions()
372{
373 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
374 {
375 m_target_options_ap.reset (new TargetOptions());
376 if (m_target_options_ap.get())
377 m_target_options_ap->Triple = m_target_triple;
378 }
379 return m_target_options_ap.get();
380}
381
382
383TargetInfo *
384ClangASTContext::getTargetInfo()
385{
386 // target_triple should be something like "x86_64-apple-darwin10"
387 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
388 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
389 return m_target_info_ap.get();
390}
391
392#pragma mark Basic Types
393
394static inline bool
395QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
396{
397 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
398 if (qual_type_bit_size == bit_size)
399 return true;
400 return false;
401}
402
Greg Clayton462d4142010-09-29 01:12:09 +0000403clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000404ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000405{
406 ASTContext *ast_context = getASTContext();
407
408 assert (ast_context != NULL);
409
410 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
411}
412
Greg Clayton462d4142010-09-29 01:12:09 +0000413clang_type_t
414ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000415{
416 if (!ast_context)
417 return NULL;
418
419 switch (encoding)
420 {
Greg Clayton585660c2010-08-05 01:57:25 +0000421 case eEncodingInvalid:
Chris Lattner24943d22010-06-08 16:52:24 +0000422 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
423 return ast_context->VoidPtrTy.getAsOpaquePtr();
424 break;
425
Greg Clayton585660c2010-08-05 01:57:25 +0000426 case eEncodingUint:
Chris Lattner24943d22010-06-08 16:52:24 +0000427 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
428 return ast_context->UnsignedCharTy.getAsOpaquePtr();
429 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
430 return ast_context->UnsignedShortTy.getAsOpaquePtr();
431 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
432 return ast_context->UnsignedIntTy.getAsOpaquePtr();
433 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
434 return ast_context->UnsignedLongTy.getAsOpaquePtr();
435 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
436 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
437 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
438 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
439 break;
440
Greg Clayton585660c2010-08-05 01:57:25 +0000441 case eEncodingSint:
Chris Lattner24943d22010-06-08 16:52:24 +0000442 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
443 return ast_context->CharTy.getAsOpaquePtr();
444 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
445 return ast_context->ShortTy.getAsOpaquePtr();
446 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
447 return ast_context->IntTy.getAsOpaquePtr();
448 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
449 return ast_context->LongTy.getAsOpaquePtr();
450 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
451 return ast_context->LongLongTy.getAsOpaquePtr();
452 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
453 return ast_context->Int128Ty.getAsOpaquePtr();
454 break;
455
Greg Clayton585660c2010-08-05 01:57:25 +0000456 case eEncodingIEEE754:
Chris Lattner24943d22010-06-08 16:52:24 +0000457 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
458 return ast_context->FloatTy.getAsOpaquePtr();
459 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
460 return ast_context->DoubleTy.getAsOpaquePtr();
461 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
462 return ast_context->LongDoubleTy.getAsOpaquePtr();
463 break;
464
Greg Clayton585660c2010-08-05 01:57:25 +0000465 case eEncodingVector:
Chris Lattner24943d22010-06-08 16:52:24 +0000466 default:
467 break;
468 }
469
470 return NULL;
471}
472
Greg Clayton462d4142010-09-29 01:12:09 +0000473clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000474ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
475{
476 ASTContext *ast_context = getASTContext();
477
478 #define streq(a,b) strcmp(a,b) == 0
479 assert (ast_context != NULL);
480 if (ast_context)
481 {
482 switch (dw_ate)
483 {
484 default:
485 break;
486
487 case DW_ATE_address:
488 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
489 return ast_context->VoidPtrTy.getAsOpaquePtr();
490 break;
491
492 case DW_ATE_boolean:
493 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
494 return ast_context->BoolTy.getAsOpaquePtr();
495 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
496 return ast_context->UnsignedCharTy.getAsOpaquePtr();
497 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
498 return ast_context->UnsignedShortTy.getAsOpaquePtr();
499 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
500 return ast_context->UnsignedIntTy.getAsOpaquePtr();
501 break;
502
503 case DW_ATE_complex_float:
504 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
505 return ast_context->FloatComplexTy.getAsOpaquePtr();
506 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
507 return ast_context->DoubleComplexTy.getAsOpaquePtr();
508 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
509 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
510 break;
511
512 case DW_ATE_float:
513 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
514 return ast_context->FloatTy.getAsOpaquePtr();
515 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
516 return ast_context->DoubleTy.getAsOpaquePtr();
517 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
518 return ast_context->LongDoubleTy.getAsOpaquePtr();
519 break;
520
521 case DW_ATE_signed:
522 if (type_name)
523 {
524 if (streq(type_name, "int") ||
525 streq(type_name, "signed int"))
526 {
527 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
528 return ast_context->IntTy.getAsOpaquePtr();
529 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
530 return ast_context->Int128Ty.getAsOpaquePtr();
531 }
532
533 if (streq(type_name, "long int") ||
534 streq(type_name, "long long int") ||
535 streq(type_name, "signed long long"))
536 {
537 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
538 return ast_context->LongTy.getAsOpaquePtr();
539 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
540 return ast_context->LongLongTy.getAsOpaquePtr();
541 }
542
543 if (streq(type_name, "short") ||
544 streq(type_name, "short int") ||
545 streq(type_name, "signed short") ||
546 streq(type_name, "short signed int"))
547 {
548 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
549 return ast_context->ShortTy.getAsOpaquePtr();
550 }
551
552 if (streq(type_name, "char") ||
553 streq(type_name, "signed char"))
554 {
555 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
556 return ast_context->CharTy.getAsOpaquePtr();
557 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
558 return ast_context->SignedCharTy.getAsOpaquePtr();
559 }
560
561 if (streq(type_name, "wchar_t"))
562 {
563 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
564 return ast_context->WCharTy.getAsOpaquePtr();
565 }
566
567 }
568 // We weren't able to match up a type name, just search by size
569 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
570 return ast_context->CharTy.getAsOpaquePtr();
571 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
572 return ast_context->ShortTy.getAsOpaquePtr();
573 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
574 return ast_context->IntTy.getAsOpaquePtr();
575 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
576 return ast_context->LongTy.getAsOpaquePtr();
577 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
578 return ast_context->LongLongTy.getAsOpaquePtr();
579 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
580 return ast_context->Int128Ty.getAsOpaquePtr();
581 break;
582
583 case DW_ATE_signed_char:
584 if (type_name)
585 {
586 if (streq(type_name, "signed char"))
587 {
588 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
589 return ast_context->SignedCharTy.getAsOpaquePtr();
590 }
591 }
592 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
593 return ast_context->CharTy.getAsOpaquePtr();
594 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
595 return ast_context->SignedCharTy.getAsOpaquePtr();
596 break;
597
598 case DW_ATE_unsigned:
599 if (type_name)
600 {
601 if (streq(type_name, "unsigned int"))
602 {
603 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
604 return ast_context->UnsignedIntTy.getAsOpaquePtr();
605 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
606 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
607 }
608
609 if (streq(type_name, "unsigned int") ||
610 streq(type_name, "long unsigned int") ||
611 streq(type_name, "unsigned long long"))
612 {
613 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
614 return ast_context->UnsignedLongTy.getAsOpaquePtr();
615 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
616 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
617 }
618
619 if (streq(type_name, "unsigned short") ||
620 streq(type_name, "short unsigned int"))
621 {
622 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
623 return ast_context->UnsignedShortTy.getAsOpaquePtr();
624 }
625 if (streq(type_name, "unsigned char"))
626 {
627 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
628 return ast_context->UnsignedCharTy.getAsOpaquePtr();
629 }
630
631 }
632 // We weren't able to match up a type name, just search by size
633 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
634 return ast_context->UnsignedCharTy.getAsOpaquePtr();
635 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
636 return ast_context->UnsignedShortTy.getAsOpaquePtr();
637 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
638 return ast_context->UnsignedIntTy.getAsOpaquePtr();
639 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
640 return ast_context->UnsignedLongTy.getAsOpaquePtr();
641 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
642 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
643 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
644 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
645 break;
646
647 case DW_ATE_unsigned_char:
648 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
649 return ast_context->UnsignedCharTy.getAsOpaquePtr();
650 break;
651
652 case DW_ATE_imaginary_float:
653 break;
654 }
655 }
656 // This assert should fire for anything that we don't catch above so we know
657 // to fix any issues we run into.
658 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
659 return NULL;
660}
661
Greg Clayton462d4142010-09-29 01:12:09 +0000662clang_type_t
663ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
Chris Lattner24943d22010-06-08 16:52:24 +0000664{
Sean Callanana751f7b2010-09-17 02:24:29 +0000665 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000666}
667
Greg Clayton462d4142010-09-29 01:12:09 +0000668clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000669ClangASTContext::GetBuiltInType_objc_id()
670{
Sean Callanan04325062010-10-25 00:29:48 +0000671 return getASTContext()->ObjCBuiltinIdTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000672}
673
Greg Clayton462d4142010-09-29 01:12:09 +0000674clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000675ClangASTContext::GetBuiltInType_objc_Class()
676{
Sean Callanan04325062010-10-25 00:29:48 +0000677 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000678}
679
Greg Clayton462d4142010-09-29 01:12:09 +0000680clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000681ClangASTContext::GetBuiltInType_objc_selector()
682{
Sean Callanan04325062010-10-25 00:29:48 +0000683 return getASTContext()->ObjCBuiltinSelTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000684}
685
Greg Clayton462d4142010-09-29 01:12:09 +0000686clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000687ClangASTContext::GetCStringType (bool is_const)
688{
689 QualType char_type(getASTContext()->CharTy);
690
691 if (is_const)
692 char_type.addConst();
693
694 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
695}
696
Greg Clayton462d4142010-09-29 01:12:09 +0000697clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000698ClangASTContext::GetVoidPtrType (bool is_const)
699{
700 return GetVoidPtrType(getASTContext(), is_const);
701}
702
Greg Clayton462d4142010-09-29 01:12:09 +0000703clang_type_t
704ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
Chris Lattner24943d22010-06-08 16:52:24 +0000705{
706 QualType void_ptr_type(ast_context->VoidPtrTy);
707
708 if (is_const)
709 void_ptr_type.addConst();
710
711 return void_ptr_type.getAsOpaquePtr();
712}
713
Sean Callanan839fde42010-10-28 18:19:36 +0000714class NullDiagnosticClient : public DiagnosticClient
715{
716public:
717 NullDiagnosticClient ()
718 {
719 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
720 }
721
722 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
723 {
724 if (m_log)
725 {
726 llvm::SmallVectorImpl<char> diag_str(10);
727 info.FormatDiagnostic(diag_str);
728 diag_str.push_back('\0');
729 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
730 }
731 }
732private:
733 Log *m_log;
734};
735
Greg Clayton462d4142010-09-29 01:12:09 +0000736clang_type_t
737ClangASTContext::CopyType (ASTContext *dest_context,
738 ASTContext *source_context,
739 clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000740{
Sean Callanan839fde42010-10-28 18:19:36 +0000741 NullDiagnosticClient *null_client = new NullDiagnosticClient;
742 Diagnostic diagnostics(null_client);
Chris Lattner24943d22010-06-08 16:52:24 +0000743 FileManager file_manager;
744 ASTImporter importer(diagnostics,
745 *dest_context, file_manager,
746 *source_context, file_manager);
747 QualType ret = importer.Import(QualType::getFromOpaquePtr(clang_type));
748 return ret.getAsOpaquePtr();
749}
750
Sean Callanan8d825062010-07-16 00:00:27 +0000751bool
Greg Clayton462d4142010-09-29 01:12:09 +0000752ClangASTContext::AreTypesSame(ASTContext *ast_context,
753 clang_type_t type1,
754 clang_type_t type2)
Sean Callanan5510ddd2010-07-15 22:30:52 +0000755{
756 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
757 QualType::getFromOpaquePtr(type2));
758}
759
Chris Lattner24943d22010-06-08 16:52:24 +0000760#pragma mark CVR modifiers
761
Greg Clayton462d4142010-09-29 01:12:09 +0000762clang_type_t
763ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000764{
765 if (clang_type)
766 {
767 QualType result(QualType::getFromOpaquePtr(clang_type));
768 result.addConst();
769 return result.getAsOpaquePtr();
770 }
771 return NULL;
772}
773
Greg Clayton462d4142010-09-29 01:12:09 +0000774clang_type_t
775ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000776{
777 if (clang_type)
778 {
779 QualType result(QualType::getFromOpaquePtr(clang_type));
780 result.getQualifiers().setRestrict (true);
781 return result.getAsOpaquePtr();
782 }
783 return NULL;
784}
785
Greg Clayton462d4142010-09-29 01:12:09 +0000786clang_type_t
787ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000788{
789 if (clang_type)
790 {
791 QualType result(QualType::getFromOpaquePtr(clang_type));
792 result.getQualifiers().setVolatile (true);
793 return result.getAsOpaquePtr();
794 }
795 return NULL;
796}
797
798#pragma mark Structure, Unions, Classes
799
Greg Clayton462d4142010-09-29 01:12:09 +0000800clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000801ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000802{
803 ASTContext *ast_context = getASTContext();
804 assert (ast_context != NULL);
Sean Callanan04325062010-10-25 00:29:48 +0000805
Chris Lattner24943d22010-06-08 16:52:24 +0000806 if (decl_ctx == NULL)
807 decl_ctx = ast_context->getTranslationUnitDecl();
808
Greg Clayton9488b742010-07-28 02:04:09 +0000809
Greg Clayton585660c2010-08-05 01:57:25 +0000810 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000811 {
Greg Clayton306edca2010-10-11 02:25:34 +0000812 bool isForwardDecl = true;
Greg Clayton9488b742010-07-28 02:04:09 +0000813 bool isInternal = false;
814 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
815 }
816
Chris Lattner24943d22010-06-08 16:52:24 +0000817 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
818 // we will need to update this code. I was told to currently always use
819 // the CXXRecordDecl class since we often don't know from debug information
820 // if something is struct or a class, so we default to always use the more
821 // complete definition just in case.
822 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
823 (TagDecl::TagKind)kind,
824 decl_ctx,
825 SourceLocation(),
826 name && name[0] ? &ast_context->Idents.get(name) : NULL);
827
828 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
829}
830
Greg Claytondbf26152010-10-01 23:13:49 +0000831static bool
832IsOperator (const char *name, OverloadedOperatorKind &op_kind)
833{
834 if (name == NULL || name[0] == '\0')
835 return false;
836
837 if (::strstr(name, "operator ") != name)
838 return false;
839
840 const char *post_op_name = name + 9;
841
842 // This is an operator, set the overloaded operator kind to invalid
843 // in case this is a conversion operator...
844 op_kind = NUM_OVERLOADED_OPERATORS;
845
846 switch (post_op_name[0])
847 {
848 case 'n':
849 if (strcmp (post_op_name, "new") == 0)
850 op_kind = OO_New;
851 else if (strcmp (post_op_name, "new[]") == 0)
852 op_kind = OO_Array_New;
853 break;
854
855 case 'd':
856 if (strcmp (post_op_name, "delete") == 0)
857 op_kind = OO_Delete;
858 else if (strcmp (post_op_name, "delete[]") == 0)
859 op_kind = OO_Array_Delete;
860 break;
861
862 case '+':
863 if (post_op_name[1] == '\0')
864 op_kind = OO_Plus;
865 else if (post_op_name[2] == '\0')
866 {
867 if (post_op_name[1] == '=')
868 op_kind = OO_PlusEqual;
869 else if (post_op_name[1] == '+')
870 op_kind = OO_PlusPlus;
871 }
872 break;
873
874 case '-':
875 if (post_op_name[1] == '\0')
876 op_kind = OO_Minus;
877 else if (post_op_name[2] == '\0')
878 {
879 switch (post_op_name[1])
880 {
881 case '=': op_kind = OO_MinusEqual; break;
882 case '-': op_kind = OO_MinusMinus; break;
883 case '>': op_kind = OO_Arrow; break;
884 }
885 }
886 else if (post_op_name[3] == '\0')
887 {
888 if (post_op_name[2] == '*')
889 op_kind = OO_ArrowStar; break;
890 }
891 break;
892
893 case '*':
894 if (post_op_name[1] == '\0')
895 op_kind = OO_Star;
896 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
897 op_kind = OO_StarEqual;
898 break;
899
900 case '/':
901 if (post_op_name[1] == '\0')
902 op_kind = OO_Slash;
903 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
904 op_kind = OO_SlashEqual;
905 break;
906
907 case '%':
908 if (post_op_name[1] == '\0')
909 op_kind = OO_Percent;
910 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
911 op_kind = OO_PercentEqual;
912 break;
913
914
915 case '^':
916 if (post_op_name[1] == '\0')
917 op_kind = OO_Caret;
918 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
919 op_kind = OO_CaretEqual;
920 break;
921
922 case '&':
923 if (post_op_name[1] == '\0')
924 op_kind = OO_Amp;
925 else if (post_op_name[2] == '\0')
926 {
927 switch (post_op_name[1])
928 {
929 case '=': op_kind = OO_AmpEqual; break;
930 case '&': op_kind = OO_AmpAmp; break;
931 }
932 }
933 break;
934
935 case '|':
936 if (post_op_name[1] == '\0')
937 op_kind = OO_Pipe;
938 else if (post_op_name[2] == '\0')
939 {
940 switch (post_op_name[1])
941 {
942 case '=': op_kind = OO_PipeEqual; break;
943 case '|': op_kind = OO_PipePipe; break;
944 }
945 }
946 break;
947
948 case '~':
949 if (post_op_name[1] == '\0')
950 op_kind = OO_Tilde;
951 break;
952
953 case '!':
954 if (post_op_name[1] == '\0')
955 op_kind = OO_Exclaim;
956 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
957 op_kind = OO_ExclaimEqual;
958 break;
959
960 case '=':
961 if (post_op_name[1] == '\0')
962 op_kind = OO_Equal;
963 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
964 op_kind = OO_EqualEqual;
965 break;
966
967 case '<':
968 if (post_op_name[1] == '\0')
969 op_kind = OO_Less;
970 else if (post_op_name[2] == '\0')
971 {
972 switch (post_op_name[1])
973 {
974 case '<': op_kind = OO_LessLess; break;
975 case '=': op_kind = OO_LessEqual; break;
976 }
977 }
978 else if (post_op_name[3] == '\0')
979 {
980 if (post_op_name[2] == '=')
981 op_kind = OO_LessLessEqual;
982 }
983 break;
984
985 case '>':
986 if (post_op_name[1] == '\0')
987 op_kind = OO_Greater;
988 else if (post_op_name[2] == '\0')
989 {
990 switch (post_op_name[1])
991 {
992 case '>': op_kind = OO_GreaterGreater; break;
993 case '=': op_kind = OO_GreaterEqual; break;
994 }
995 }
996 else if (post_op_name[1] == '>' &&
997 post_op_name[2] == '=' &&
998 post_op_name[3] == '\0')
999 {
1000 op_kind = OO_GreaterGreaterEqual;
1001 }
1002 break;
1003
1004 case ',':
1005 if (post_op_name[1] == '\0')
1006 op_kind = OO_Comma;
1007 break;
1008
1009 case '(':
1010 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1011 op_kind = OO_Call;
1012 break;
1013
1014 case '[':
1015 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1016 op_kind = OO_Subscript;
1017 break;
1018 }
1019
1020 return true;
1021}
Greg Clayton412440a2010-09-23 01:09:21 +00001022CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +00001023ClangASTContext::AddMethodToCXXRecordType
1024(
Greg Clayton462d4142010-09-29 01:12:09 +00001025 ASTContext *ast_context,
1026 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001027 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001028 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001029 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001030 bool is_virtual,
1031 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001032 bool is_inline,
1033 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +00001034)
Sean Callanan79523002010-09-17 02:58:26 +00001035{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001036 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +00001037 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001038
1039 assert(ast_context);
1040
1041 IdentifierTable *identifier_table = &ast_context->Idents;
1042
1043 assert(identifier_table);
1044
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001045 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +00001046
1047 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +00001048
Greg Clayton1d8173f2010-09-24 05:15:53 +00001049 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001050 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001051
Greg Clayton1d8173f2010-09-24 05:15:53 +00001052 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +00001053
Greg Clayton1d8173f2010-09-24 05:15:53 +00001054 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001055 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001056
Greg Clayton1d8173f2010-09-24 05:15:53 +00001057 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +00001058
Greg Clayton1d8173f2010-09-24 05:15:53 +00001059 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001060 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001061
1062 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1063
Greg Clayton1d8173f2010-09-24 05:15:53 +00001064 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001065 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001066
Greg Clayton1d8173f2010-09-24 05:15:53 +00001067 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001068
Greg Clayton30449d52010-10-01 02:31:07 +00001069 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001070
Greg Clayton30449d52010-10-01 02:31:07 +00001071 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001072
Greg Clayton90e325d2010-10-01 03:45:20 +00001073 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001074
Greg Clayton5325a362010-10-02 01:40:05 +00001075 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001076
Greg Clayton5325a362010-10-02 01:40:05 +00001077 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001078 return NULL;
1079
Greg Clayton5325a362010-10-02 01:40:05 +00001080 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001081
1082 if (!method_function_prototype)
1083 return NULL;
1084
1085 unsigned int num_params = method_function_prototype->getNumArgs();
1086
1087 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001088 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001089 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1090 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001091 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001092 method_qual_type,
1093 is_inline,
1094 is_implicitly_declared);
1095 }
1096 else if (decl_name == record_decl->getDeclName())
1097 {
Greg Clayton30449d52010-10-01 02:31:07 +00001098 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1099 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001100 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001101 method_qual_type,
1102 NULL, // TypeSourceInfo *
1103 is_explicit,
1104 is_inline,
1105 is_implicitly_declared);
1106 }
1107 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001108 {
Greg Claytondbf26152010-10-01 23:13:49 +00001109
1110 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1111 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001112 {
Greg Claytondbf26152010-10-01 23:13:49 +00001113 if (op_kind != NUM_OVERLOADED_OPERATORS)
1114 {
1115 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001116 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001117 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001118 method_qual_type,
1119 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001120 is_static,
1121 SC_None,
1122 is_inline);
1123 }
1124 else if (num_params == 0)
1125 {
1126 // Conversion operators don't take params...
1127 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1128 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001129 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001130 method_qual_type,
1131 NULL, // TypeSourceInfo *
1132 is_inline,
1133 is_explicit);
1134 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001135 }
Greg Claytondbf26152010-10-01 23:13:49 +00001136
1137 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001138 {
1139 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1140 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001141 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001142 method_qual_type,
1143 NULL, // TypeSourceInfo *
1144 is_static,
1145 SC_None,
1146 is_inline);
1147 }
Greg Clayton30449d52010-10-01 02:31:07 +00001148 }
Greg Claytondbf26152010-10-01 23:13:49 +00001149
Greg Clayton462d4142010-09-29 01:12:09 +00001150 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001151
1152 cxx_method_decl->setAccess (access_specifier);
1153 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001154
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001155 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001156
1157 ParmVarDecl *params[num_params];
1158
1159 for (int param_index = 0;
1160 param_index < num_params;
1161 ++param_index)
1162 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001163 params[param_index] = ParmVarDecl::Create (*ast_context,
1164 cxx_method_decl,
1165 SourceLocation(),
1166 NULL, // anonymous
1167 method_function_prototype->getArgType(param_index),
1168 NULL,
1169 SC_None,
1170 SC_None,
1171 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001172 }
1173
Greg Clayton1d8173f2010-09-24 05:15:53 +00001174 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001175
Greg Clayton1d8173f2010-09-24 05:15:53 +00001176 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001177
Greg Clayton412440a2010-09-23 01:09:21 +00001178 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001179}
1180
1181bool
Greg Clayton84f80752010-07-22 18:30:50 +00001182ClangASTContext::AddFieldToRecordType
1183(
Greg Clayton462d4142010-09-29 01:12:09 +00001184 ASTContext *ast_context,
1185 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001186 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001187 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001188 AccessType access,
1189 uint32_t bitfield_bit_size
1190)
Chris Lattner24943d22010-06-08 16:52:24 +00001191{
1192 if (record_clang_type == NULL || field_type == NULL)
1193 return false;
1194
Sean Callanan60a0ced2010-09-16 20:01:08 +00001195 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001196
1197 assert (ast_context != NULL);
1198 assert (identifier_table != NULL);
1199
1200 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1201
Greg Clayton1674b122010-07-21 22:12:05 +00001202 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001203 if (clang_type)
1204 {
1205 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1206
1207 if (record_type)
1208 {
1209 RecordDecl *record_decl = record_type->getDecl();
1210
Chris Lattner24943d22010-06-08 16:52:24 +00001211 clang::Expr *bit_width = NULL;
1212 if (bitfield_bit_size != 0)
1213 {
1214 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001215 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001216 }
Greg Clayton84f80752010-07-22 18:30:50 +00001217 FieldDecl *field = FieldDecl::Create (*ast_context,
1218 record_decl,
1219 SourceLocation(),
1220 name ? &identifier_table->get(name) : NULL, // Identifier
1221 QualType::getFromOpaquePtr(field_type), // Field type
1222 NULL, // DeclaratorInfo *
1223 bit_width, // BitWidth
1224 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001225
Greg Clayton84f80752010-07-22 18:30:50 +00001226 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001227
1228 if (field)
1229 {
1230 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001231 }
1232 }
Greg Clayton9488b742010-07-28 02:04:09 +00001233 else
1234 {
1235 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1236 if (objc_class_type)
1237 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001238 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001239 ClangASTContext::AddObjCClassIVar (ast_context,
1240 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001241 name,
1242 field_type,
1243 access,
1244 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001245 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001246 }
1247 }
Chris Lattner24943d22010-06-08 16:52:24 +00001248 }
1249 return false;
1250}
1251
1252bool
1253ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1254{
1255 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1256}
1257
1258bool
1259ClangASTContext::FieldIsBitfield
1260(
1261 ASTContext *ast_context,
1262 FieldDecl* field,
1263 uint32_t& bitfield_bit_size
1264)
1265{
1266 if (ast_context == NULL || field == NULL)
1267 return false;
1268
1269 if (field->isBitField())
1270 {
1271 Expr* bit_width_expr = field->getBitWidth();
1272 if (bit_width_expr)
1273 {
1274 llvm::APSInt bit_width_apsint;
1275 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1276 {
1277 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1278 return true;
1279 }
1280 }
1281 }
1282 return false;
1283}
1284
1285bool
1286ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1287{
1288 if (record_decl == NULL)
1289 return false;
1290
1291 if (!record_decl->field_empty())
1292 return true;
1293
1294 // No fields, lets check this is a CXX record and check the base classes
1295 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1296 if (cxx_record_decl)
1297 {
1298 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1299 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1300 base_class != base_class_end;
1301 ++base_class)
1302 {
1303 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1304 if (RecordHasFields(base_class_decl))
1305 return true;
1306 }
1307 }
1308 return false;
1309}
1310
1311void
Greg Clayton462d4142010-09-29 01:12:09 +00001312ClangASTContext::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 +00001313{
1314 if (clang_qual_type)
1315 {
1316 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001317 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001318 if (clang_type)
1319 {
1320 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1321 if (record_type)
1322 {
1323 RecordDecl *record_decl = record_type->getDecl();
1324 if (record_decl)
1325 {
1326 uint32_t field_idx;
1327 RecordDecl::field_iterator field, field_end;
1328 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1329 field != field_end;
1330 ++field, ++field_idx)
1331 {
1332 // If no accessibility was assigned, assign the correct one
1333 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1334 field->setAccess ((AccessSpecifier)default_accessibility);
1335 }
1336 }
1337 }
1338 }
1339 }
1340}
1341
1342#pragma mark C++ Base Classes
1343
1344CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001345ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001346{
1347 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001348 return new CXXBaseSpecifier (SourceRange(),
1349 is_virtual,
1350 base_of_class,
1351 ConvertAccessTypeToAccessSpecifier (access),
1352 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001353 return NULL;
1354}
1355
Greg Claytone9d0df42010-07-02 01:29:13 +00001356void
1357ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1358{
1359 for (unsigned i=0; i<num_base_classes; ++i)
1360 {
1361 delete base_classes[i];
1362 base_classes[i] = NULL;
1363 }
1364}
1365
Chris Lattner24943d22010-06-08 16:52:24 +00001366bool
Greg Clayton462d4142010-09-29 01:12:09 +00001367ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001368{
1369 if (class_clang_type)
1370 {
Greg Clayton1674b122010-07-21 22:12:05 +00001371 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001372 if (clang_type)
1373 {
1374 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1375 if (record_type)
1376 {
1377 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1378 if (cxx_record_decl)
1379 {
Chris Lattner24943d22010-06-08 16:52:24 +00001380 cxx_record_decl->setBases(base_classes, num_base_classes);
1381 return true;
1382 }
1383 }
1384 }
1385 }
1386 return false;
1387}
Greg Clayton84f80752010-07-22 18:30:50 +00001388#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001389
Greg Clayton462d4142010-09-29 01:12:09 +00001390clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001391ClangASTContext::CreateObjCClass
1392(
1393 const char *name,
1394 DeclContext *decl_ctx,
1395 bool isForwardDecl,
1396 bool isInternal
1397)
1398{
1399 ASTContext *ast_context = getASTContext();
1400 assert (ast_context != NULL);
1401 assert (name && name[0]);
1402 if (decl_ctx == NULL)
1403 decl_ctx = ast_context->getTranslationUnitDecl();
1404
1405 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1406 // we will need to update this code. I was told to currently always use
1407 // the CXXRecordDecl class since we often don't know from debug information
1408 // if something is struct or a class, so we default to always use the more
1409 // complete definition just in case.
1410 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1411 decl_ctx,
1412 SourceLocation(),
1413 &ast_context->Idents.get(name),
1414 SourceLocation(),
1415 isForwardDecl,
1416 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001417
1418 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001419}
1420
1421bool
Greg Clayton462d4142010-09-29 01:12:09 +00001422ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001423{
1424 if (class_opaque_type && super_opaque_type)
1425 {
1426 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1427 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1428 clang::Type *class_type = class_qual_type.getTypePtr();
1429 clang::Type *super_type = super_qual_type.getTypePtr();
1430 if (class_type && super_type)
1431 {
1432 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1433 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1434 if (objc_class_type && objc_super_type)
1435 {
1436 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1437 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1438 if (class_interface_decl && super_interface_decl)
1439 {
1440 class_interface_decl->setSuperClass(super_interface_decl);
1441 return true;
1442 }
1443 }
1444 }
1445 }
1446 return false;
1447}
1448
1449
1450bool
1451ClangASTContext::AddObjCClassIVar
1452(
Greg Clayton462d4142010-09-29 01:12:09 +00001453 ASTContext *ast_context,
1454 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001455 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001456 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001457 AccessType access,
1458 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001459 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001460)
1461{
1462 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1463 return false;
1464
Sean Callanan60a0ced2010-09-16 20:01:08 +00001465 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001466
1467 assert (ast_context != NULL);
1468 assert (identifier_table != NULL);
1469
1470 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1471
1472 clang::Type *class_type = class_qual_type.getTypePtr();
1473 if (class_type)
1474 {
1475 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1476
1477 if (objc_class_type)
1478 {
1479 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1480
1481 if (class_interface_decl)
1482 {
1483 clang::Expr *bit_width = NULL;
1484 if (bitfield_bit_size != 0)
1485 {
1486 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001487 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001488 }
1489
Greg Clayton9488b742010-07-28 02:04:09 +00001490 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1491 class_interface_decl,
1492 SourceLocation(),
1493 &identifier_table->get(name), // Identifier
1494 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1495 NULL, // TypeSourceInfo *
1496 ConvertAccessTypeToObjCIvarAccessControl (access),
1497 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001498 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001499
1500 if (field)
1501 {
1502 class_interface_decl->addDecl(field);
1503 return true;
1504 }
Greg Clayton84f80752010-07-22 18:30:50 +00001505 }
1506 }
1507 }
1508 return false;
1509}
Chris Lattner24943d22010-06-08 16:52:24 +00001510
Greg Clayton9488b742010-07-28 02:04:09 +00001511
1512bool
Greg Clayton462d4142010-09-29 01:12:09 +00001513ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001514{
1515 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1516
1517 clang::Type *class_type = class_qual_type.getTypePtr();
1518 if (class_type)
1519 {
1520 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1521
1522 if (objc_class_type)
1523 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1524 }
1525 return false;
1526}
1527
1528bool
1529ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1530{
1531 while (class_interface_decl)
1532 {
1533 if (class_interface_decl->ivar_size() > 0)
1534 return true;
1535
1536 if (check_superclass)
1537 class_interface_decl = class_interface_decl->getSuperClass();
1538 else
1539 break;
1540 }
1541 return false;
1542}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001543
Greg Clayton462d4142010-09-29 01:12:09 +00001544ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001545ClangASTContext::AddMethodToObjCObjectType
1546(
Greg Clayton462d4142010-09-29 01:12:09 +00001547 ASTContext *ast_context,
1548 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001549 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001550 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001551 lldb::AccessType access
1552)
1553{
1554 if (class_opaque_type == NULL || method_opaque_type == NULL)
1555 return NULL;
1556
1557 IdentifierTable *identifier_table = &ast_context->Idents;
1558
1559 assert (ast_context != NULL);
1560 assert (identifier_table != NULL);
1561
1562 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1563
1564 clang::Type *class_type = class_qual_type.getTypePtr();
1565 if (class_type == NULL)
1566 return NULL;
1567
1568 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1569
1570 if (objc_class_type == NULL)
1571 return NULL;
1572
1573 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1574
1575 if (class_interface_decl == NULL)
1576 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001577
Greg Clayton1d8173f2010-09-24 05:15:53 +00001578 const char *selector_start = ::strchr (name, ' ');
1579 if (selector_start == NULL)
1580 return NULL;
1581
1582 selector_start++;
1583 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1584 return NULL;
1585 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1586
Greg Claytonad60bf42010-10-12 02:24:53 +00001587 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001588 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001589 //printf ("name = '%s'\n", name);
1590
1591 unsigned num_selectors_with_args = 0;
1592 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001593 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001594 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001595 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001596 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001597 bool has_arg = (start[len] == ':');
1598 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001599 ++num_selectors_with_args;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001600 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001601 if (has_arg)
1602 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001603 }
1604
1605
1606 if (selector_idents.size() == 0)
1607 return 0;
1608
Greg Claytonad60bf42010-10-12 02:24:53 +00001609 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001610 selector_idents.data());
1611
1612 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1613
1614 // Populate the method decl with parameter decls
1615 clang::Type *method_type(method_qual_type.getTypePtr());
1616
1617 if (method_type == NULL)
1618 return NULL;
1619
1620 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1621
1622 if (!method_function_prototype)
1623 return NULL;
1624
1625
1626 bool is_variadic = false;
1627 bool is_synthesized = false;
1628 bool is_defined = false;
1629 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1630
1631 const unsigned num_args = method_function_prototype->getNumArgs();
1632
1633 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1634 SourceLocation(), // beginLoc,
1635 SourceLocation(), // endLoc,
1636 method_selector,
1637 method_function_prototype->getResultType(),
1638 NULL, // TypeSourceInfo *ResultTInfo,
1639 GetDeclContextForType (class_opaque_type),
1640 name[0] == '-',
1641 is_variadic,
1642 is_synthesized,
1643 is_defined,
1644 imp_control,
1645 num_args);
1646
1647
1648 if (objc_method_decl == NULL)
1649 return NULL;
1650
1651 if (num_args > 0)
1652 {
1653 llvm::SmallVector<ParmVarDecl *, 12> params;
1654
1655 for (int param_index = 0; param_index < num_args; ++param_index)
1656 {
1657 params.push_back (ParmVarDecl::Create (*ast_context,
1658 objc_method_decl,
1659 SourceLocation(),
1660 NULL, // anonymous
1661 method_function_prototype->getArgType(param_index),
1662 NULL,
1663 SC_Auto,
1664 SC_Auto,
1665 NULL));
1666 }
1667
1668 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1669 }
1670
1671 class_interface_decl->addDecl (objc_method_decl);
1672
1673
1674 return objc_method_decl;
1675}
1676
1677
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001678uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001679ClangASTContext::GetTypeInfo
1680(
1681 clang_type_t clang_type,
1682 clang::ASTContext *ast_context,
1683 clang_type_t *pointee_or_element_clang_type
1684)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001685{
1686 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001687 return 0;
1688
1689 if (pointee_or_element_clang_type)
1690 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001691
1692 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1693
1694 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1695 switch (type_class)
1696 {
Sean Callanan04325062010-10-25 00:29:48 +00001697 case clang::Type::Builtin:
1698 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1699 {
Sean Callanan04325062010-10-25 00:29:48 +00001700 case clang::BuiltinType::ObjCId:
1701 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001702 if (ast_context && pointee_or_element_clang_type)
1703 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001704 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001705
1706 default:
1707 break;
Sean Callanan04325062010-10-25 00:29:48 +00001708 }
1709 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001710
1711 case clang::Type::BlockPointer:
1712 if (pointee_or_element_clang_type)
1713 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1714 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1715
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001716 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001717
1718 case clang::Type::ConstantArray:
1719 case clang::Type::DependentSizedArray:
1720 case clang::Type::IncompleteArray:
1721 case clang::Type::VariableArray:
1722 if (pointee_or_element_clang_type)
1723 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1724 return eTypeHasChildren | eTypeIsArray;
1725
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001726 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001727 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1728 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1729 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001730
1731 case clang::Type::Enum:
1732 if (pointee_or_element_clang_type)
1733 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1734 return eTypeIsEnumeration | eTypeHasValue;
1735
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001736 case clang::Type::Elaborated: return 0;
1737 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1738 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1739 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001740 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001741
1742 case clang::Type::LValueReference:
1743 case clang::Type::RValueReference:
1744 if (pointee_or_element_clang_type)
1745 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1746 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1747
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001748 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001749
1750 case clang::Type::ObjCObjectPointer:
1751 if (pointee_or_element_clang_type)
1752 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1753 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1754
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001755 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1756 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001757
1758 case clang::Type::Pointer:
1759 if (pointee_or_element_clang_type)
1760 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1761 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1762
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001763 case clang::Type::Record:
1764 if (qual_type->getAsCXXRecordDecl())
1765 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1766 else
1767 return eTypeHasChildren | eTypeIsStructUnion;
1768 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001769 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1770 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1771 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001772
1773 case clang::Type::Typedef:
1774 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1775 ast_context,
1776 pointee_or_element_clang_type);
1777
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001778 case clang::Type::TypeOfExpr: return 0;
1779 case clang::Type::TypeOf: return 0;
1780 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001781 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1782 default: return 0;
1783 }
1784 return 0;
1785}
1786
Greg Clayton9488b742010-07-28 02:04:09 +00001787
Chris Lattner24943d22010-06-08 16:52:24 +00001788#pragma mark Aggregate Types
1789
1790bool
Greg Clayton462d4142010-09-29 01:12:09 +00001791ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001792{
1793 if (clang_type == NULL)
1794 return false;
1795
1796 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1797
1798 if (qual_type->isAggregateType ())
1799 return true;
1800
Greg Clayton03e0f972010-09-13 03:32:57 +00001801 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1802 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001803 {
Greg Clayton1674b122010-07-21 22:12:05 +00001804 case clang::Type::IncompleteArray:
1805 case clang::Type::VariableArray:
1806 case clang::Type::ConstantArray:
1807 case clang::Type::ExtVector:
1808 case clang::Type::Vector:
1809 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001810 case clang::Type::ObjCObject:
1811 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001812 return true;
1813
Greg Clayton1674b122010-07-21 22:12:05 +00001814 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001815 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1816
1817 default:
1818 break;
1819 }
1820 // The clang type does have a value
1821 return false;
1822}
1823
1824uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001825ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001826{
1827 if (clang_qual_type == NULL)
1828 return 0;
1829
1830 uint32_t num_children = 0;
1831 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001832 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1833 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001834 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001835 case clang::Type::Builtin:
1836 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1837 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001838 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001839 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001840 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001841 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001842
1843 default:
1844 break;
1845 }
1846 break;
1847
Greg Clayton1674b122010-07-21 22:12:05 +00001848 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001849 {
1850 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1851 const RecordDecl *record_decl = record_type->getDecl();
1852 assert(record_decl);
1853 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1854 if (cxx_record_decl)
1855 {
1856 if (omit_empty_base_classes)
1857 {
1858 // Check each base classes to see if it or any of its
1859 // base classes contain any fields. This can help
1860 // limit the noise in variable views by not having to
1861 // show base classes that contain no members.
1862 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1863 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1864 base_class != base_class_end;
1865 ++base_class)
1866 {
1867 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1868
1869 // Skip empty base classes
1870 if (RecordHasFields(base_class_decl) == false)
1871 continue;
1872
1873 num_children++;
1874 }
1875 }
1876 else
1877 {
1878 // Include all base classes
1879 num_children += cxx_record_decl->getNumBases();
1880 }
1881
1882 }
1883 RecordDecl::field_iterator field, field_end;
1884 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1885 ++num_children;
1886 }
1887 break;
1888
Greg Clayton9488b742010-07-28 02:04:09 +00001889 case clang::Type::ObjCObject:
1890 case clang::Type::ObjCInterface:
1891 {
1892 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1893 assert (objc_class_type);
1894 if (objc_class_type)
1895 {
1896 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1897
1898 if (class_interface_decl)
1899 {
1900
1901 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1902 if (superclass_interface_decl)
1903 {
1904 if (omit_empty_base_classes)
1905 {
1906 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1907 ++num_children;
1908 }
1909 else
1910 ++num_children;
1911 }
1912
1913 num_children += class_interface_decl->ivar_size();
1914 }
1915 }
1916 }
1917 break;
1918
1919 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001920 {
1921 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1922 QualType pointee_type = pointer_type->getPointeeType();
1923 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1924 omit_empty_base_classes);
1925 // If this type points to a simple type, then it has 1 child
1926 if (num_pointee_children == 0)
1927 num_children = 1;
1928 else
1929 num_children = num_pointee_children;
1930 }
1931 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001932
Greg Clayton1674b122010-07-21 22:12:05 +00001933 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001934 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1935 break;
1936
Greg Clayton1674b122010-07-21 22:12:05 +00001937 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001938 {
1939 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1940 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001941 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1942 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001943 // If this type points to a simple type, then it has 1 child
1944 if (num_pointee_children == 0)
1945 num_children = 1;
1946 else
1947 num_children = num_pointee_children;
1948 }
1949 break;
1950
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001951 case clang::Type::LValueReference:
1952 case clang::Type::RValueReference:
1953 {
1954 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1955 QualType pointee_type = reference_type->getPointeeType();
1956 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1957 omit_empty_base_classes);
1958 // If this type points to a simple type, then it has 1 child
1959 if (num_pointee_children == 0)
1960 num_children = 1;
1961 else
1962 num_children = num_pointee_children;
1963 }
1964 break;
1965
1966
Greg Clayton1674b122010-07-21 22:12:05 +00001967 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001968 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1969 break;
1970
1971 default:
1972 break;
1973 }
1974 return num_children;
1975}
1976
1977
Greg Clayton462d4142010-09-29 01:12:09 +00001978clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00001979ClangASTContext::GetChildClangTypeAtIndex
1980(
1981 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00001982 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00001983 uint32_t idx,
1984 bool transparent_pointers,
1985 bool omit_empty_base_classes,
1986 std::string& child_name,
1987 uint32_t &child_byte_size,
1988 int32_t &child_byte_offset,
1989 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001990 uint32_t &child_bitfield_bit_offset,
1991 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00001992)
1993{
1994 if (parent_clang_type)
1995
1996 return GetChildClangTypeAtIndex (getASTContext(),
1997 parent_name,
1998 parent_clang_type,
1999 idx,
2000 transparent_pointers,
2001 omit_empty_base_classes,
2002 child_name,
2003 child_byte_size,
2004 child_byte_offset,
2005 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002006 child_bitfield_bit_offset,
2007 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002008 return NULL;
2009}
2010
Greg Clayton462d4142010-09-29 01:12:09 +00002011clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002012ClangASTContext::GetChildClangTypeAtIndex
2013(
2014 ASTContext *ast_context,
2015 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002016 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002017 uint32_t idx,
2018 bool transparent_pointers,
2019 bool omit_empty_base_classes,
2020 std::string& child_name,
2021 uint32_t &child_byte_size,
2022 int32_t &child_byte_offset,
2023 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002024 uint32_t &child_bitfield_bit_offset,
2025 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002026)
2027{
2028 if (parent_clang_type == NULL)
2029 return NULL;
2030
2031 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2032 {
2033 uint32_t bit_offset;
2034 child_bitfield_bit_size = 0;
2035 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002036 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002037 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002038 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2039 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002040 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002041 case clang::Type::Builtin:
2042 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2043 {
2044 case clang::BuiltinType::ObjCId:
2045 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002046 child_name = "isa";
2047 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002048 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2049
Greg Clayton960d6a42010-08-03 00:35:52 +00002050 default:
2051 break;
2052 }
2053 break;
2054
2055
Greg Clayton1674b122010-07-21 22:12:05 +00002056 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002057 {
2058 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2059 const RecordDecl *record_decl = record_type->getDecl();
2060 assert(record_decl);
2061 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2062 uint32_t child_idx = 0;
2063
2064 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2065 if (cxx_record_decl)
2066 {
2067 // We might have base classes to print out first
2068 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2069 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2070 base_class != base_class_end;
2071 ++base_class)
2072 {
2073 const CXXRecordDecl *base_class_decl = NULL;
2074
2075 // Skip empty base classes
2076 if (omit_empty_base_classes)
2077 {
2078 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2079 if (RecordHasFields(base_class_decl) == false)
2080 continue;
2081 }
2082
2083 if (idx == child_idx)
2084 {
2085 if (base_class_decl == NULL)
2086 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2087
2088
2089 if (base_class->isVirtual())
2090 bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
2091 else
2092 bit_offset = record_layout.getBaseClassOffset(base_class_decl);
2093
2094 // Base classes should be a multiple of 8 bits in size
2095 assert (bit_offset % 8 == 0);
2096 child_byte_offset = bit_offset/8;
2097 std::string base_class_type_name(base_class->getType().getAsString());
2098
2099 child_name.assign(base_class_type_name.c_str());
2100
2101 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2102
2103 // Base classes biut sizes should be a multiple of 8 bits in size
2104 assert (clang_type_info_bit_size % 8 == 0);
2105 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002106 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002107 return base_class->getType().getAsOpaquePtr();
2108 }
2109 // We don't increment the child index in the for loop since we might
2110 // be skipping empty base classes
2111 ++child_idx;
2112 }
2113 }
Chris Lattner24943d22010-06-08 16:52:24 +00002114 // Make sure index is in range...
2115 uint32_t field_idx = 0;
2116 RecordDecl::field_iterator field, field_end;
2117 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2118 {
2119 if (idx == child_idx)
2120 {
2121 // Print the member type if requested
2122 // Print the member name and equal sign
2123 child_name.assign(field->getNameAsString().c_str());
2124
2125 // Figure out the type byte size (field_type_info.first) and
2126 // alignment (field_type_info.second) from the AST context.
2127 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002128 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002129
2130 child_byte_size = field_type_info.first / 8;
2131
2132 // Figure out the field offset within the current struct/union/class type
2133 bit_offset = record_layout.getFieldOffset (field_idx);
2134 child_byte_offset = bit_offset / 8;
2135 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2136 child_bitfield_bit_offset = bit_offset % 8;
2137
2138 return field->getType().getAsOpaquePtr();
2139 }
2140 }
2141 }
2142 break;
2143
Greg Clayton9488b742010-07-28 02:04:09 +00002144 case clang::Type::ObjCObject:
2145 case clang::Type::ObjCInterface:
2146 {
2147 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2148 assert (objc_class_type);
2149 if (objc_class_type)
2150 {
2151 uint32_t child_idx = 0;
2152 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2153
2154 if (class_interface_decl)
2155 {
2156
2157 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2158 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2159 if (superclass_interface_decl)
2160 {
2161 if (omit_empty_base_classes)
2162 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002163 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002164 {
2165 if (idx == 0)
2166 {
2167 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2168
2169
2170 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2171
2172 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2173
2174 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002175 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002176 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002177
2178 return ivar_qual_type.getAsOpaquePtr();
2179 }
2180
2181 ++child_idx;
2182 }
2183 }
2184 else
2185 ++child_idx;
2186 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002187
2188 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002189
2190 if (idx < (child_idx + class_interface_decl->ivar_size()))
2191 {
2192 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2193
2194 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2195 {
2196 if (child_idx == idx)
2197 {
2198 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2199
2200 QualType ivar_qual_type(ivar_decl->getType());
2201
2202 child_name.assign(ivar_decl->getNameAsString().c_str());
2203
2204 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2205
2206 child_byte_size = ivar_type_info.first / 8;
2207
2208 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002209 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002210 child_byte_offset = bit_offset / 8;
2211
2212 return ivar_qual_type.getAsOpaquePtr();
2213 }
2214 ++child_idx;
2215 }
2216 }
2217 }
2218 }
2219 }
2220 break;
2221
2222 case clang::Type::ObjCObjectPointer:
2223 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002224 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2225 QualType pointee_type = pointer_type->getPointeeType();
2226
2227 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2228 {
2229 return GetChildClangTypeAtIndex (ast_context,
2230 parent_name,
2231 pointer_type->getPointeeType().getAsOpaquePtr(),
2232 idx,
2233 transparent_pointers,
2234 omit_empty_base_classes,
2235 child_name,
2236 child_byte_size,
2237 child_byte_offset,
2238 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002239 child_bitfield_bit_offset,
2240 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002241 }
2242 else
2243 {
2244 if (parent_name)
2245 {
2246 child_name.assign(1, '*');
2247 child_name += parent_name;
2248 }
2249
2250 // We have a pointer to an simple type
2251 if (idx == 0)
2252 {
2253 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2254 assert(clang_type_info.first % 8 == 0);
2255 child_byte_size = clang_type_info.first / 8;
2256 child_byte_offset = 0;
2257 return pointee_type.getAsOpaquePtr();
2258 }
2259 }
Greg Clayton9488b742010-07-28 02:04:09 +00002260 }
2261 break;
2262
Greg Clayton1674b122010-07-21 22:12:05 +00002263 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002264 {
2265 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2266 const uint64_t element_count = array->getSize().getLimitedValue();
2267
2268 if (idx < element_count)
2269 {
2270 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2271
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002272 char element_name[64];
2273 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002274
2275 child_name.assign(element_name);
2276 assert(field_type_info.first % 8 == 0);
2277 child_byte_size = field_type_info.first / 8;
2278 child_byte_offset = idx * child_byte_size;
2279 return array->getElementType().getAsOpaquePtr();
2280 }
2281 }
2282 break;
2283
Greg Clayton1674b122010-07-21 22:12:05 +00002284 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002285 {
2286 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2287 QualType pointee_type = pointer_type->getPointeeType();
2288
2289 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2290 {
2291 return GetChildClangTypeAtIndex (ast_context,
2292 parent_name,
2293 pointer_type->getPointeeType().getAsOpaquePtr(),
2294 idx,
2295 transparent_pointers,
2296 omit_empty_base_classes,
2297 child_name,
2298 child_byte_size,
2299 child_byte_offset,
2300 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002301 child_bitfield_bit_offset,
2302 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002303 }
2304 else
2305 {
2306 if (parent_name)
2307 {
2308 child_name.assign(1, '*');
2309 child_name += parent_name;
2310 }
2311
2312 // We have a pointer to an simple type
2313 if (idx == 0)
2314 {
2315 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2316 assert(clang_type_info.first % 8 == 0);
2317 child_byte_size = clang_type_info.first / 8;
2318 child_byte_offset = 0;
2319 return pointee_type.getAsOpaquePtr();
2320 }
2321 }
2322 }
2323 break;
2324
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002325 case clang::Type::LValueReference:
2326 case clang::Type::RValueReference:
2327 {
2328 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2329 QualType pointee_type(reference_type->getPointeeType());
2330 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2331 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2332 {
2333 return GetChildClangTypeAtIndex (ast_context,
2334 parent_name,
2335 pointee_clang_type,
2336 idx,
2337 transparent_pointers,
2338 omit_empty_base_classes,
2339 child_name,
2340 child_byte_size,
2341 child_byte_offset,
2342 child_bitfield_bit_size,
2343 child_bitfield_bit_offset,
2344 child_is_base_class);
2345 }
2346 else
2347 {
2348 if (parent_name)
2349 {
2350 child_name.assign(1, '&');
2351 child_name += parent_name;
2352 }
2353
2354 // We have a pointer to an simple type
2355 if (idx == 0)
2356 {
2357 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2358 assert(clang_type_info.first % 8 == 0);
2359 child_byte_size = clang_type_info.first / 8;
2360 child_byte_offset = 0;
2361 return pointee_type.getAsOpaquePtr();
2362 }
2363 }
2364 }
2365 break;
2366
Greg Clayton1674b122010-07-21 22:12:05 +00002367 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002368 return GetChildClangTypeAtIndex (ast_context,
2369 parent_name,
2370 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2371 idx,
2372 transparent_pointers,
2373 omit_empty_base_classes,
2374 child_name,
2375 child_byte_size,
2376 child_byte_offset,
2377 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002378 child_bitfield_bit_offset,
2379 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002380 break;
2381
2382 default:
2383 break;
2384 }
2385 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002386 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002387}
2388
2389static inline bool
2390BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2391{
2392 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2393}
2394
2395static uint32_t
2396GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2397{
2398 uint32_t num_bases = 0;
2399 if (cxx_record_decl)
2400 {
2401 if (omit_empty_base_classes)
2402 {
2403 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2404 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2405 base_class != base_class_end;
2406 ++base_class)
2407 {
2408 // Skip empty base classes
2409 if (omit_empty_base_classes)
2410 {
2411 if (BaseSpecifierIsEmpty (base_class))
2412 continue;
2413 }
2414 ++num_bases;
2415 }
2416 }
2417 else
2418 num_bases = cxx_record_decl->getNumBases();
2419 }
2420 return num_bases;
2421}
2422
2423
2424static uint32_t
2425GetIndexForRecordBase
2426(
2427 const RecordDecl *record_decl,
2428 const CXXBaseSpecifier *base_spec,
2429 bool omit_empty_base_classes
2430)
2431{
2432 uint32_t child_idx = 0;
2433
2434 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2435
2436// const char *super_name = record_decl->getNameAsCString();
2437// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2438// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2439//
2440 if (cxx_record_decl)
2441 {
2442 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2443 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2444 base_class != base_class_end;
2445 ++base_class)
2446 {
2447 if (omit_empty_base_classes)
2448 {
2449 if (BaseSpecifierIsEmpty (base_class))
2450 continue;
2451 }
2452
2453// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2454// child_idx,
2455// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2456//
2457//
2458 if (base_class == base_spec)
2459 return child_idx;
2460 ++child_idx;
2461 }
2462 }
2463
2464 return UINT32_MAX;
2465}
2466
2467
2468static uint32_t
2469GetIndexForRecordChild
2470(
2471 const RecordDecl *record_decl,
2472 NamedDecl *canonical_decl,
2473 bool omit_empty_base_classes
2474)
2475{
2476 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2477
2478// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2479//
2480//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2481// if (cxx_record_decl)
2482// {
2483// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2484// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2485// base_class != base_class_end;
2486// ++base_class)
2487// {
2488// if (omit_empty_base_classes)
2489// {
2490// if (BaseSpecifierIsEmpty (base_class))
2491// continue;
2492// }
2493//
2494//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2495//// record_decl->getNameAsCString(),
2496//// canonical_decl->getNameAsCString(),
2497//// child_idx,
2498//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2499//
2500//
2501// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2502// if (curr_base_class_decl == canonical_decl)
2503// {
2504// return child_idx;
2505// }
2506// ++child_idx;
2507// }
2508// }
2509//
2510// const uint32_t num_bases = child_idx;
2511 RecordDecl::field_iterator field, field_end;
2512 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2513 field != field_end;
2514 ++field, ++child_idx)
2515 {
2516// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2517// record_decl->getNameAsCString(),
2518// canonical_decl->getNameAsCString(),
2519// child_idx - num_bases,
2520// field->getNameAsCString());
2521
2522 if (field->getCanonicalDecl() == canonical_decl)
2523 return child_idx;
2524 }
2525
2526 return UINT32_MAX;
2527}
2528
2529// Look for a child member (doesn't include base classes, but it does include
2530// their members) in the type hierarchy. Returns an index path into "clang_type"
2531// on how to reach the appropriate member.
2532//
2533// class A
2534// {
2535// public:
2536// int m_a;
2537// int m_b;
2538// };
2539//
2540// class B
2541// {
2542// };
2543//
2544// class C :
2545// public B,
2546// public A
2547// {
2548// };
2549//
2550// If we have a clang type that describes "class C", and we wanted to looked
2551// "m_b" in it:
2552//
2553// With omit_empty_base_classes == false we would get an integer array back with:
2554// { 1, 1 }
2555// The first index 1 is the child index for "class A" within class C
2556// The second index 1 is the child index for "m_b" within class A
2557//
2558// With omit_empty_base_classes == true we would get an integer array back with:
2559// { 0, 1 }
2560// 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)
2561// The second index 1 is the child index for "m_b" within class A
2562
2563size_t
2564ClangASTContext::GetIndexOfChildMemberWithName
2565(
2566 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002567 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002568 const char *name,
2569 bool omit_empty_base_classes,
2570 std::vector<uint32_t>& child_indexes
2571)
2572{
2573 if (clang_type && name && name[0])
2574 {
2575 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002576 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2577 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002578 {
Greg Clayton1674b122010-07-21 22:12:05 +00002579 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002580 {
2581 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2582 const RecordDecl *record_decl = record_type->getDecl();
2583
2584 assert(record_decl);
2585 uint32_t child_idx = 0;
2586
2587 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2588
2589 // Try and find a field that matches NAME
2590 RecordDecl::field_iterator field, field_end;
2591 StringRef name_sref(name);
2592 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2593 field != field_end;
2594 ++field, ++child_idx)
2595 {
2596 if (field->getName().equals (name_sref))
2597 {
2598 // We have to add on the number of base classes to this index!
2599 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2600 return child_indexes.size();
2601 }
2602 }
2603
2604 if (cxx_record_decl)
2605 {
2606 const RecordDecl *parent_record_decl = cxx_record_decl;
2607
2608 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2609
2610 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2611 // Didn't find things easily, lets let clang do its thang...
2612 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2613 DeclarationName decl_name(&ident_ref);
2614
2615 CXXBasePaths paths;
2616 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2617 decl_name.getAsOpaquePtr(),
2618 paths))
2619 {
Chris Lattner24943d22010-06-08 16:52:24 +00002620 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2621 for (path = paths.begin(); path != path_end; ++path)
2622 {
2623 const size_t num_path_elements = path->size();
2624 for (size_t e=0; e<num_path_elements; ++e)
2625 {
2626 CXXBasePathElement elem = (*path)[e];
2627
2628 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2629 if (child_idx == UINT32_MAX)
2630 {
2631 child_indexes.clear();
2632 return 0;
2633 }
2634 else
2635 {
2636 child_indexes.push_back (child_idx);
2637 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2638 }
2639 }
2640 DeclContext::lookup_iterator named_decl_pos;
2641 for (named_decl_pos = path->Decls.first;
2642 named_decl_pos != path->Decls.second && parent_record_decl;
2643 ++named_decl_pos)
2644 {
2645 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2646
2647 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2648 if (child_idx == UINT32_MAX)
2649 {
2650 child_indexes.clear();
2651 return 0;
2652 }
2653 else
2654 {
2655 child_indexes.push_back (child_idx);
2656 }
2657 }
2658 }
2659 return child_indexes.size();
2660 }
2661 }
2662
2663 }
2664 break;
2665
Greg Clayton9488b742010-07-28 02:04:09 +00002666 case clang::Type::ObjCObject:
2667 case clang::Type::ObjCInterface:
2668 {
2669 StringRef name_sref(name);
2670 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2671 assert (objc_class_type);
2672 if (objc_class_type)
2673 {
2674 uint32_t child_idx = 0;
2675 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2676
2677 if (class_interface_decl)
2678 {
2679 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2680 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2681
Greg Clayton823533e2010-09-18 02:11:07 +00002682 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002683 {
2684 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2685
2686 if (ivar_decl->getName().equals (name_sref))
2687 {
2688 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2689 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2690 ++child_idx;
2691
2692 child_indexes.push_back (child_idx);
2693 return child_indexes.size();
2694 }
2695 }
2696
2697 if (superclass_interface_decl)
2698 {
2699 // The super class index is always zero for ObjC classes,
2700 // so we push it onto the child indexes in case we find
2701 // an ivar in our superclass...
2702 child_indexes.push_back (0);
2703
2704 if (GetIndexOfChildMemberWithName (ast_context,
2705 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2706 name,
2707 omit_empty_base_classes,
2708 child_indexes))
2709 {
2710 // We did find an ivar in a superclass so just
2711 // return the results!
2712 return child_indexes.size();
2713 }
2714
2715 // We didn't find an ivar matching "name" in our
2716 // superclass, pop the superclass zero index that
2717 // we pushed on above.
2718 child_indexes.pop_back();
2719 }
2720 }
2721 }
2722 }
2723 break;
2724
2725 case clang::Type::ObjCObjectPointer:
2726 {
2727 return GetIndexOfChildMemberWithName (ast_context,
2728 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2729 name,
2730 omit_empty_base_classes,
2731 child_indexes);
2732 }
2733 break;
2734
2735
Greg Clayton1674b122010-07-21 22:12:05 +00002736 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002737 {
2738// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2739// const uint64_t element_count = array->getSize().getLimitedValue();
2740//
2741// if (idx < element_count)
2742// {
2743// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2744//
2745// char element_name[32];
2746// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2747//
2748// child_name.assign(element_name);
2749// assert(field_type_info.first % 8 == 0);
2750// child_byte_size = field_type_info.first / 8;
2751// child_byte_offset = idx * child_byte_size;
2752// return array->getElementType().getAsOpaquePtr();
2753// }
2754 }
2755 break;
2756
Greg Clayton1674b122010-07-21 22:12:05 +00002757// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002758// {
2759// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2760// QualType pointee_type = mem_ptr_type->getPointeeType();
2761//
2762// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2763// {
2764// return GetIndexOfChildWithName (ast_context,
2765// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2766// name);
2767// }
2768// }
2769// break;
2770//
Greg Clayton1674b122010-07-21 22:12:05 +00002771 case clang::Type::LValueReference:
2772 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002773 {
2774 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2775 QualType pointee_type = reference_type->getPointeeType();
2776
2777 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2778 {
2779 return GetIndexOfChildMemberWithName (ast_context,
2780 reference_type->getPointeeType().getAsOpaquePtr(),
2781 name,
2782 omit_empty_base_classes,
2783 child_indexes);
2784 }
2785 }
2786 break;
2787
Greg Clayton1674b122010-07-21 22:12:05 +00002788 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002789 {
2790 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2791 QualType pointee_type = pointer_type->getPointeeType();
2792
2793 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2794 {
2795 return GetIndexOfChildMemberWithName (ast_context,
2796 pointer_type->getPointeeType().getAsOpaquePtr(),
2797 name,
2798 omit_empty_base_classes,
2799 child_indexes);
2800 }
2801 else
2802 {
2803// if (parent_name)
2804// {
2805// child_name.assign(1, '*');
2806// child_name += parent_name;
2807// }
2808//
2809// // We have a pointer to an simple type
2810// if (idx == 0)
2811// {
2812// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2813// assert(clang_type_info.first % 8 == 0);
2814// child_byte_size = clang_type_info.first / 8;
2815// child_byte_offset = 0;
2816// return pointee_type.getAsOpaquePtr();
2817// }
2818 }
2819 }
2820 break;
2821
Greg Clayton1674b122010-07-21 22:12:05 +00002822 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002823 return GetIndexOfChildMemberWithName (ast_context,
2824 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2825 name,
2826 omit_empty_base_classes,
2827 child_indexes);
2828
2829 default:
2830 break;
2831 }
2832 }
2833 return 0;
2834}
2835
2836
2837// Get the index of the child of "clang_type" whose name matches. This function
2838// doesn't descend into the children, but only looks one level deep and name
2839// matches can include base class names.
2840
2841uint32_t
2842ClangASTContext::GetIndexOfChildWithName
2843(
2844 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002845 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002846 const char *name,
2847 bool omit_empty_base_classes
2848)
2849{
2850 if (clang_type && name && name[0])
2851 {
2852 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002853
Greg Clayton03e0f972010-09-13 03:32:57 +00002854 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002855
Greg Clayton03e0f972010-09-13 03:32:57 +00002856 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002857 {
Greg Clayton1674b122010-07-21 22:12:05 +00002858 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002859 {
2860 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2861 const RecordDecl *record_decl = record_type->getDecl();
2862
2863 assert(record_decl);
2864 uint32_t child_idx = 0;
2865
2866 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2867
2868 if (cxx_record_decl)
2869 {
2870 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2871 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2872 base_class != base_class_end;
2873 ++base_class)
2874 {
2875 // Skip empty base classes
2876 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2877 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2878 continue;
2879
2880 if (base_class->getType().getAsString().compare (name) == 0)
2881 return child_idx;
2882 ++child_idx;
2883 }
2884 }
2885
2886 // Try and find a field that matches NAME
2887 RecordDecl::field_iterator field, field_end;
2888 StringRef name_sref(name);
2889 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2890 field != field_end;
2891 ++field, ++child_idx)
2892 {
2893 if (field->getName().equals (name_sref))
2894 return child_idx;
2895 }
2896
2897 }
2898 break;
2899
Greg Clayton9488b742010-07-28 02:04:09 +00002900 case clang::Type::ObjCObject:
2901 case clang::Type::ObjCInterface:
2902 {
2903 StringRef name_sref(name);
2904 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2905 assert (objc_class_type);
2906 if (objc_class_type)
2907 {
2908 uint32_t child_idx = 0;
2909 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2910
2911 if (class_interface_decl)
2912 {
2913 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2914 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2915
2916 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2917 {
2918 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2919
2920 if (ivar_decl->getName().equals (name_sref))
2921 {
2922 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2923 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2924 ++child_idx;
2925
2926 return child_idx;
2927 }
2928 }
2929
2930 if (superclass_interface_decl)
2931 {
2932 if (superclass_interface_decl->getName().equals (name_sref))
2933 return 0;
2934 }
2935 }
2936 }
2937 }
2938 break;
2939
2940 case clang::Type::ObjCObjectPointer:
2941 {
2942 return GetIndexOfChildWithName (ast_context,
2943 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2944 name,
2945 omit_empty_base_classes);
2946 }
2947 break;
2948
Greg Clayton1674b122010-07-21 22:12:05 +00002949 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002950 {
2951// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2952// const uint64_t element_count = array->getSize().getLimitedValue();
2953//
2954// if (idx < element_count)
2955// {
2956// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2957//
2958// char element_name[32];
2959// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2960//
2961// child_name.assign(element_name);
2962// assert(field_type_info.first % 8 == 0);
2963// child_byte_size = field_type_info.first / 8;
2964// child_byte_offset = idx * child_byte_size;
2965// return array->getElementType().getAsOpaquePtr();
2966// }
2967 }
2968 break;
2969
Greg Clayton1674b122010-07-21 22:12:05 +00002970// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002971// {
2972// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2973// QualType pointee_type = mem_ptr_type->getPointeeType();
2974//
2975// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2976// {
2977// return GetIndexOfChildWithName (ast_context,
2978// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2979// name);
2980// }
2981// }
2982// break;
2983//
Greg Clayton1674b122010-07-21 22:12:05 +00002984 case clang::Type::LValueReference:
2985 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002986 {
2987 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2988 QualType pointee_type = reference_type->getPointeeType();
2989
2990 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2991 {
2992 return GetIndexOfChildWithName (ast_context,
2993 reference_type->getPointeeType().getAsOpaquePtr(),
2994 name,
2995 omit_empty_base_classes);
2996 }
2997 }
2998 break;
2999
Greg Clayton1674b122010-07-21 22:12:05 +00003000 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003001 {
3002 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3003 QualType pointee_type = pointer_type->getPointeeType();
3004
3005 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3006 {
3007 return GetIndexOfChildWithName (ast_context,
3008 pointer_type->getPointeeType().getAsOpaquePtr(),
3009 name,
3010 omit_empty_base_classes);
3011 }
3012 else
3013 {
3014// if (parent_name)
3015// {
3016// child_name.assign(1, '*');
3017// child_name += parent_name;
3018// }
3019//
3020// // We have a pointer to an simple type
3021// if (idx == 0)
3022// {
3023// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3024// assert(clang_type_info.first % 8 == 0);
3025// child_byte_size = clang_type_info.first / 8;
3026// child_byte_offset = 0;
3027// return pointee_type.getAsOpaquePtr();
3028// }
3029 }
3030 }
3031 break;
3032
Greg Clayton1674b122010-07-21 22:12:05 +00003033 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003034 return GetIndexOfChildWithName (ast_context,
3035 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3036 name,
3037 omit_empty_base_classes);
3038
3039 default:
3040 break;
3041 }
3042 }
3043 return UINT32_MAX;
3044}
3045
3046#pragma mark TagType
3047
3048bool
Greg Clayton462d4142010-09-29 01:12:09 +00003049ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003050{
3051 if (tag_clang_type)
3052 {
3053 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003054 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003055 if (clang_type)
3056 {
3057 TagType *tag_type = dyn_cast<TagType>(clang_type);
3058 if (tag_type)
3059 {
3060 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3061 if (tag_decl)
3062 {
3063 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3064 return true;
3065 }
3066 }
3067 }
3068 }
3069 return false;
3070}
3071
3072
3073#pragma mark DeclContext Functions
3074
3075DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003076ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003077{
3078 if (clang_type == NULL)
3079 return NULL;
3080
3081 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003082 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3083 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003084 {
Greg Clayton9488b742010-07-28 02:04:09 +00003085 case clang::Type::FunctionNoProto: break;
3086 case clang::Type::FunctionProto: break;
3087 case clang::Type::IncompleteArray: break;
3088 case clang::Type::VariableArray: break;
3089 case clang::Type::ConstantArray: break;
3090 case clang::Type::ExtVector: break;
3091 case clang::Type::Vector: break;
3092 case clang::Type::Builtin: break;
3093 case clang::Type::BlockPointer: break;
3094 case clang::Type::Pointer: break;
3095 case clang::Type::LValueReference: break;
3096 case clang::Type::RValueReference: break;
3097 case clang::Type::MemberPointer: break;
3098 case clang::Type::Complex: break;
3099 case clang::Type::ObjCObject: break;
3100 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3101 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3102 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3103 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
3104 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003105
Greg Clayton9488b742010-07-28 02:04:09 +00003106 case clang::Type::TypeOfExpr: break;
3107 case clang::Type::TypeOf: break;
3108 case clang::Type::Decltype: break;
3109 //case clang::Type::QualifiedName: break;
3110 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003111 }
3112 // No DeclContext in this type...
3113 return NULL;
3114}
3115
3116#pragma mark Namespace Declarations
3117
3118NamespaceDecl *
3119ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3120{
3121 // TODO: Do something intelligent with the Declaration object passed in
3122 // like maybe filling in the SourceLocation with it...
3123 if (name)
3124 {
3125 ASTContext *ast_context = getASTContext();
3126 if (decl_ctx == NULL)
3127 decl_ctx = ast_context->getTranslationUnitDecl();
3128 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3129 }
3130 return NULL;
3131}
3132
3133
3134#pragma mark Function Types
3135
3136FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003137ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003138{
3139 if (name)
3140 {
3141 ASTContext *ast_context = getASTContext();
3142 assert (ast_context != NULL);
3143
3144 if (name && name[0])
3145 {
3146 return FunctionDecl::Create(*ast_context,
3147 ast_context->getTranslationUnitDecl(),
3148 SourceLocation(),
3149 DeclarationName (&ast_context->Idents.get(name)),
3150 QualType::getFromOpaquePtr(function_clang_type),
3151 NULL,
3152 (FunctionDecl::StorageClass)storage,
3153 (FunctionDecl::StorageClass)storage,
3154 is_inline);
3155 }
3156 else
3157 {
3158 return FunctionDecl::Create(*ast_context,
3159 ast_context->getTranslationUnitDecl(),
3160 SourceLocation(),
3161 DeclarationName (),
3162 QualType::getFromOpaquePtr(function_clang_type),
3163 NULL,
3164 (FunctionDecl::StorageClass)storage,
3165 (FunctionDecl::StorageClass)storage,
3166 is_inline);
3167 }
3168 }
3169 return NULL;
3170}
3171
Greg Clayton462d4142010-09-29 01:12:09 +00003172clang_type_t
3173ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3174 clang_type_t result_type,
3175 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003176 unsigned num_args,
3177 bool is_variadic,
3178 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003179{
Chris Lattner24943d22010-06-08 16:52:24 +00003180 assert (ast_context != NULL);
3181 std::vector<QualType> qual_type_args;
3182 for (unsigned i=0; i<num_args; ++i)
3183 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3184
3185 // TODO: Detect calling convention in DWARF?
3186 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003187 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003188 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003189 is_variadic,
3190 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003191 false, // hasExceptionSpec
3192 false, // hasAnyExceptionSpec,
3193 0, // NumExs
3194 0, // const QualType *ExArray
3195 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3196}
3197
3198ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003199ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003200{
3201 ASTContext *ast_context = getASTContext();
3202 assert (ast_context != NULL);
3203 return ParmVarDecl::Create(*ast_context,
3204 ast_context->getTranslationUnitDecl(),
3205 SourceLocation(),
3206 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003207 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003208 NULL,
3209 (VarDecl::StorageClass)storage,
3210 (VarDecl::StorageClass)storage,
3211 0);
3212}
3213
3214void
3215ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3216{
3217 if (function_decl)
3218 function_decl->setParams (params, num_params);
3219}
3220
3221
3222#pragma mark Array Types
3223
Greg Clayton462d4142010-09-29 01:12:09 +00003224clang_type_t
3225ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003226{
3227 if (element_type)
3228 {
3229 ASTContext *ast_context = getASTContext();
3230 assert (ast_context != NULL);
3231 llvm::APInt ap_element_count (64, element_count);
3232 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3233 ap_element_count,
3234 ArrayType::Normal,
3235 0).getAsOpaquePtr(); // ElemQuals
3236 }
3237 return NULL;
3238}
3239
3240
3241#pragma mark TagDecl
3242
3243bool
Greg Clayton462d4142010-09-29 01:12:09 +00003244ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003245{
3246 if (clang_type)
3247 {
3248 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003249 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003250 if (t)
3251 {
3252 TagType *tag_type = dyn_cast<TagType>(t);
3253 if (tag_type)
3254 {
3255 TagDecl *tag_decl = tag_type->getDecl();
3256 if (tag_decl)
3257 {
3258 tag_decl->startDefinition();
3259 return true;
3260 }
3261 }
3262 }
3263 }
3264 return false;
3265}
3266
3267bool
Greg Clayton462d4142010-09-29 01:12:09 +00003268ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003269{
3270 if (clang_type)
3271 {
3272 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00003273
3274 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3275
3276 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003277 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003278 cxx_record_decl->completeDefinition();
3279
3280 return true;
3281 }
3282
Sean Callanan04325062010-10-25 00:29:48 +00003283 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3284
3285 if (objc_class_type)
3286 {
3287 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3288
3289 class_interface_decl->setForwardDecl(false);
3290 }
3291
Greg Clayton55b6c532010-09-29 03:44:17 +00003292 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3293
3294 if (enum_type)
3295 {
3296 EnumDecl *enum_decl = enum_type->getDecl();
3297
3298 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003299 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003300 /// TODO This really needs to be fixed.
3301
3302 unsigned NumPositiveBits = 1;
3303 unsigned NumNegativeBits = 0;
3304
Greg Clayton48fbdf72010-10-12 04:29:14 +00003305 ASTContext *ast_context = getASTContext();
3306
3307 QualType promotion_qual_type;
3308 // If the enum integer type is less than an integer in bit width,
3309 // then we must promote it to an integer size.
3310 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3311 {
3312 if (enum_decl->getIntegerType()->isSignedIntegerType())
3313 promotion_qual_type = ast_context->IntTy;
3314 else
3315 promotion_qual_type = ast_context->UnsignedIntTy;
3316 }
3317 else
3318 promotion_qual_type = enum_decl->getIntegerType();
3319
3320 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003321 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003322 }
3323 }
3324 }
3325 return false;
3326}
3327
3328
3329#pragma mark Enumeration Types
3330
Greg Clayton462d4142010-09-29 01:12:09 +00003331clang_type_t
3332ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003333{
3334 // TODO: Do something intelligent with the Declaration object passed in
3335 // like maybe filling in the SourceLocation with it...
3336 ASTContext *ast_context = getASTContext();
3337 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003338
3339 // TODO: ask about these...
3340// const bool IsScoped = false;
3341// const bool IsFixed = false;
3342
3343 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3344 ast_context->getTranslationUnitDecl(),
3345 SourceLocation(),
3346 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3347 SourceLocation(),
3348 NULL); //IsScoped, IsFixed);
Chris Lattner24943d22010-06-08 16:52:24 +00003349 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003350 {
3351 // TODO: check if we should be setting the promotion type too?
3352 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003353 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003354 }
Chris Lattner24943d22010-06-08 16:52:24 +00003355 return NULL;
3356}
3357
Greg Clayton462d4142010-09-29 01:12:09 +00003358clang_type_t
3359ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3360{
3361 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3362
3363 clang::Type *clang_type = enum_qual_type.getTypePtr();
3364 if (clang_type)
3365 {
3366 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3367 if (enum_type)
3368 {
3369 EnumDecl *enum_decl = enum_type->getDecl();
3370 if (enum_decl)
3371 return enum_decl->getIntegerType().getAsOpaquePtr();
3372 }
3373 }
3374 return NULL;
3375}
Chris Lattner24943d22010-06-08 16:52:24 +00003376bool
3377ClangASTContext::AddEnumerationValueToEnumerationType
3378(
Greg Clayton462d4142010-09-29 01:12:09 +00003379 clang_type_t enum_clang_type,
3380 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003381 const Declaration &decl,
3382 const char *name,
3383 int64_t enum_value,
3384 uint32_t enum_value_bit_size
3385)
3386{
3387 if (enum_clang_type && enumerator_clang_type && name)
3388 {
3389 // TODO: Do something intelligent with the Declaration object passed in
3390 // like maybe filling in the SourceLocation with it...
3391 ASTContext *ast_context = getASTContext();
3392 IdentifierTable *identifier_table = getIdentifierTable();
3393
3394 assert (ast_context != NULL);
3395 assert (identifier_table != NULL);
3396 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3397
Greg Clayton1674b122010-07-21 22:12:05 +00003398 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003399 if (clang_type)
3400 {
3401 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3402
3403 if (enum_type)
3404 {
3405 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3406 enum_llvm_apsint = enum_value;
3407 EnumConstantDecl *enumerator_decl =
3408 EnumConstantDecl::Create(*ast_context,
3409 enum_type->getDecl(),
3410 SourceLocation(),
3411 name ? &identifier_table->get(name) : NULL, // Identifier
3412 QualType::getFromOpaquePtr(enumerator_clang_type),
3413 NULL,
3414 enum_llvm_apsint);
3415
3416 if (enumerator_decl)
3417 {
3418 enum_type->getDecl()->addDecl(enumerator_decl);
3419 return true;
3420 }
3421 }
3422 }
3423 }
3424 return false;
3425}
3426
3427#pragma mark Pointers & References
3428
Greg Clayton462d4142010-09-29 01:12:09 +00003429clang_type_t
3430ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003431{
3432 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003433 {
3434 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3435
Greg Clayton03e0f972010-09-13 03:32:57 +00003436 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3437 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003438 {
3439 case clang::Type::ObjCObject:
3440 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003441 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3442
Greg Clayton7b541032010-07-29 20:06:32 +00003443 default:
3444 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3445 }
3446 }
Chris Lattner24943d22010-06-08 16:52:24 +00003447 return NULL;
3448}
3449
Greg Clayton462d4142010-09-29 01:12:09 +00003450clang_type_t
3451ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003452{
3453 if (clang_type)
3454 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3455 return NULL;
3456}
3457
Greg Clayton462d4142010-09-29 01:12:09 +00003458clang_type_t
3459ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003460{
3461 if (clang_type)
3462 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3463 return NULL;
3464}
3465
Greg Clayton462d4142010-09-29 01:12:09 +00003466clang_type_t
3467ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003468{
3469 if (clang_pointee_type && clang_pointee_type)
3470 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3471 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3472 return NULL;
3473}
3474
Chris Lattner24943d22010-06-08 16:52:24 +00003475size_t
3476ClangASTContext::GetPointerBitSize ()
3477{
3478 ASTContext *ast_context = getASTContext();
3479 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3480}
3481
3482bool
Greg Clayton462d4142010-09-29 01:12:09 +00003483ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003484{
3485 if (clang_type == NULL)
3486 return false;
3487
3488 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003489 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3490 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003491 {
Sean Callanan04325062010-10-25 00:29:48 +00003492 case clang::Type::Builtin:
3493 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3494 {
3495 default:
3496 break;
3497 case clang::BuiltinType::ObjCId:
3498 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003499 return true;
3500 }
3501 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003502 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003503 if (target_type)
3504 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3505 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003506 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003507 if (target_type)
3508 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3509 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003510 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003511 if (target_type)
3512 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3513 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003514 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003515 if (target_type)
3516 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3517 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003518 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003519 if (target_type)
3520 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3521 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003522 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003523 if (target_type)
3524 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3525 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003526 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003527 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3528 default:
3529 break;
3530 }
3531 return false;
3532}
3533
Chris Lattner24943d22010-06-08 16:52:24 +00003534bool
Greg Clayton462d4142010-09-29 01:12:09 +00003535ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003536{
3537 if (!clang_type)
3538 return false;
3539
3540 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3541 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3542
3543 if (builtin_type)
3544 {
3545 if (builtin_type->isInteger())
3546 is_signed = builtin_type->isSignedInteger();
3547
3548 return true;
3549 }
3550
3551 return false;
3552}
3553
3554bool
Greg Clayton462d4142010-09-29 01:12:09 +00003555ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003556{
3557 if (clang_type)
3558 {
3559 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003560 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3561 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003562 {
Sean Callanan04325062010-10-25 00:29:48 +00003563 case clang::Type::Builtin:
3564 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3565 {
3566 default:
3567 break;
3568 case clang::BuiltinType::ObjCId:
3569 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003570 return true;
3571 }
3572 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003573 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003574 if (target_type)
3575 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3576 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003577 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003578 if (target_type)
3579 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3580 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003581 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003582 if (target_type)
3583 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3584 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003585 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003586 if (target_type)
3587 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3588 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003589 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003590 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3591 default:
3592 break;
3593 }
3594 }
3595 return false;
3596}
3597
3598bool
Greg Clayton462d4142010-09-29 01:12:09 +00003599ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003600{
3601 if (clang_type)
3602 {
3603 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3604
3605 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3606 {
3607 clang::BuiltinType::Kind kind = BT->getKind();
3608 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3609 {
3610 count = 1;
3611 is_complex = false;
3612 return true;
3613 }
3614 }
3615 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3616 {
3617 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3618 {
3619 count = 2;
3620 is_complex = true;
3621 return true;
3622 }
3623 }
3624 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3625 {
3626 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3627 {
3628 count = VT->getNumElements();
3629 is_complex = false;
3630 return true;
3631 }
3632 }
3633 }
3634 return false;
3635}
3636
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003637
3638bool
3639ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3640{
3641 if (clang_type)
3642 {
3643 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3644
3645 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3646 if (cxx_record_decl)
3647 {
3648 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3649 return true;
3650 }
3651 }
3652 class_name.clear();
3653 return false;
3654}
3655
3656
Greg Clayton1d8173f2010-09-24 05:15:53 +00003657bool
Greg Clayton462d4142010-09-29 01:12:09 +00003658ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003659{
3660 if (clang_type)
3661 {
3662 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3663 if (qual_type->getAsCXXRecordDecl() != NULL)
3664 return true;
3665 }
3666 return false;
3667}
3668
3669bool
Greg Clayton462d4142010-09-29 01:12:09 +00003670ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003671{
3672 if (clang_type)
3673 {
3674 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3675 if (qual_type->isObjCObjectOrInterfaceType())
3676 return true;
3677 }
3678 return false;
3679}
3680
3681
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003682bool
3683ClangASTContext::IsCharType (clang_type_t clang_type)
3684{
3685 if (clang_type)
3686 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3687 return false;
3688}
Chris Lattner24943d22010-06-08 16:52:24 +00003689
3690bool
Greg Clayton462d4142010-09-29 01:12:09 +00003691ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003692{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003693 clang_type_t pointee_or_element_clang_type = NULL;
3694 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3695
3696 if (pointee_or_element_clang_type == NULL)
3697 return false;
3698
3699 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003700 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003701 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3702
3703 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003704 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003705 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3706 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003707 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003708 // We know the size of the array and it could be a C string
3709 // since it is an array of characters
3710 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3711 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003712 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003713 else
Chris Lattner24943d22010-06-08 16:52:24 +00003714 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003715 length = 0;
3716 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003717 }
Chris Lattner24943d22010-06-08 16:52:24 +00003718
Chris Lattner24943d22010-06-08 16:52:24 +00003719 }
3720 }
3721 return false;
3722}
3723
3724bool
Greg Clayton462d4142010-09-29 01:12:09 +00003725ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003726{
3727 if (clang_type)
3728 {
3729 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3730
3731 if (qual_type->isFunctionPointerType())
3732 return true;
3733
3734 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3735 switch (type_class)
3736 {
3737 case clang::Type::Typedef:
3738 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3739
3740 case clang::Type::LValueReference:
3741 case clang::Type::RValueReference:
3742 {
3743 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3744 if (reference_type)
3745 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3746 }
3747 break;
3748 }
3749 }
3750 return false;
3751}
3752
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003753size_t
3754ClangASTContext::GetArraySize (clang_type_t clang_type)
3755{
3756 if (clang_type)
3757 {
3758 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3759 if (array)
3760 return array->getSize().getLimitedValue();
3761 }
3762 return 0;
3763}
Greg Clayton03e0f972010-09-13 03:32:57 +00003764
3765bool
Greg Clayton462d4142010-09-29 01:12:09 +00003766ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003767{
3768 if (!clang_type)
3769 return false;
3770
3771 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3772
Greg Clayton03e0f972010-09-13 03:32:57 +00003773 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3774 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003775 {
Greg Clayton1674b122010-07-21 22:12:05 +00003776 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003777 if (member_type)
3778 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3779 if (size)
3780 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3781 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003782 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003783 if (member_type)
3784 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3785 if (size)
3786 *size = 0;
3787 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003788 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003789 if (member_type)
3790 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3791 if (size)
3792 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003793 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003794 if (member_type)
3795 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3796 if (size)
3797 *size = 0;
3798 return true;
3799 }
3800 return false;
3801}
3802
3803
3804#pragma mark Typedefs
3805
Greg Clayton462d4142010-09-29 01:12:09 +00003806clang_type_t
3807ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003808{
3809 if (clang_type)
3810 {
3811 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3812 ASTContext *ast_context = getASTContext();
3813 IdentifierTable *identifier_table = getIdentifierTable();
3814 assert (ast_context != NULL);
3815 assert (identifier_table != NULL);
3816 if (decl_ctx == NULL)
3817 decl_ctx = ast_context->getTranslationUnitDecl();
3818 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3819 decl_ctx,
3820 SourceLocation(),
3821 name ? &identifier_table->get(name) : NULL, // Identifier
3822 ast_context->CreateTypeSourceInfo(qual_type));
3823
3824 // Get a uniqued QualType for the typedef decl type
3825 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3826 }
3827 return NULL;
3828}
3829
3830
3831std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003832ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003833{
3834 std::string return_name;
3835
Greg Clayton462d4142010-09-29 01:12:09 +00003836 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003837
Greg Clayton462d4142010-09-29 01:12:09 +00003838 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003839 if (typedef_type)
3840 {
Greg Clayton462d4142010-09-29 01:12:09 +00003841 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003842 return_name = typedef_decl->getQualifiedNameAsString();
3843 }
3844 else
3845 {
3846 return_name = qual_type.getAsString();
3847 }
3848
3849 return return_name;
3850}
3851
3852// Disable this for now since I can't seem to get a nicely formatted float
3853// out of the APFloat class without just getting the float, double or quad
3854// and then using a formatted print on it which defeats the purpose. We ideally
3855// would like to get perfect string values for any kind of float semantics
3856// so we can support remote targets. The code below also requires a patch to
3857// llvm::APInt.
3858//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003859//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 +00003860//{
3861// uint32_t count = 0;
3862// bool is_complex = false;
3863// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3864// {
3865// unsigned num_bytes_per_float = byte_size / count;
3866// unsigned num_bits_per_float = num_bytes_per_float * 8;
3867//
3868// float_str.clear();
3869// uint32_t i;
3870// for (i=0; i<count; i++)
3871// {
3872// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3873// bool is_ieee = false;
3874// APFloat ap_float(ap_int, is_ieee);
3875// char s[1024];
3876// unsigned int hex_digits = 0;
3877// bool upper_case = false;
3878//
3879// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3880// {
3881// if (i > 0)
3882// float_str.append(", ");
3883// float_str.append(s);
3884// if (i == 1 && is_complex)
3885// float_str.append(1, 'i');
3886// }
3887// }
3888// return !float_str.empty();
3889// }
3890// return false;
3891//}
3892
3893size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003894ClangASTContext::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 +00003895{
3896 if (clang_type)
3897 {
3898 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3899 uint32_t count = 0;
3900 bool is_complex = false;
3901 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3902 {
3903 // TODO: handle complex and vector types
3904 if (count != 1)
3905 return false;
3906
3907 StringRef s_sref(s);
3908 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3909
3910 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3911 const uint64_t byte_size = bit_size / 8;
3912 if (dst_size >= byte_size)
3913 {
3914 if (bit_size == sizeof(float)*8)
3915 {
3916 float float32 = ap_float.convertToFloat();
3917 ::memcpy (dst, &float32, byte_size);
3918 return byte_size;
3919 }
3920 else if (bit_size >= 64)
3921 {
3922 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3923 ::memcpy (dst, ap_int.getRawData(), byte_size);
3924 return byte_size;
3925 }
3926 }
3927 }
3928 }
3929 return 0;
3930}
Sean Callanana751f7b2010-09-17 02:24:29 +00003931
3932unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00003933ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00003934{
3935 assert (clang_type);
3936
3937 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3938
3939 return qual_type.getQualifiers().getCVRQualifiers();
3940}