blob: 760d8ecba5982f9191e7ad084d0c22d79e3b75fc [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 Callananad5b61b2010-10-28 18:43:33 +0000741 // null_client's ownership is transferred to diagnostics
Sean Callanan839fde42010-10-28 18:19:36 +0000742 NullDiagnosticClient *null_client = new NullDiagnosticClient;
743 Diagnostic diagnostics(null_client);
Chris Lattner24943d22010-06-08 16:52:24 +0000744 FileManager file_manager;
745 ASTImporter importer(diagnostics,
746 *dest_context, file_manager,
747 *source_context, file_manager);
748 QualType ret = importer.Import(QualType::getFromOpaquePtr(clang_type));
749 return ret.getAsOpaquePtr();
750}
751
Sean Callanan8d825062010-07-16 00:00:27 +0000752bool
Greg Clayton462d4142010-09-29 01:12:09 +0000753ClangASTContext::AreTypesSame(ASTContext *ast_context,
754 clang_type_t type1,
755 clang_type_t type2)
Sean Callanan5510ddd2010-07-15 22:30:52 +0000756{
757 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
758 QualType::getFromOpaquePtr(type2));
759}
760
Chris Lattner24943d22010-06-08 16:52:24 +0000761#pragma mark CVR modifiers
762
Greg Clayton462d4142010-09-29 01:12:09 +0000763clang_type_t
764ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000765{
766 if (clang_type)
767 {
768 QualType result(QualType::getFromOpaquePtr(clang_type));
769 result.addConst();
770 return result.getAsOpaquePtr();
771 }
772 return NULL;
773}
774
Greg Clayton462d4142010-09-29 01:12:09 +0000775clang_type_t
776ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000777{
778 if (clang_type)
779 {
780 QualType result(QualType::getFromOpaquePtr(clang_type));
781 result.getQualifiers().setRestrict (true);
782 return result.getAsOpaquePtr();
783 }
784 return NULL;
785}
786
Greg Clayton462d4142010-09-29 01:12:09 +0000787clang_type_t
788ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000789{
790 if (clang_type)
791 {
792 QualType result(QualType::getFromOpaquePtr(clang_type));
793 result.getQualifiers().setVolatile (true);
794 return result.getAsOpaquePtr();
795 }
796 return NULL;
797}
798
799#pragma mark Structure, Unions, Classes
800
Greg Clayton462d4142010-09-29 01:12:09 +0000801clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000802ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000803{
804 ASTContext *ast_context = getASTContext();
805 assert (ast_context != NULL);
Sean Callanan04325062010-10-25 00:29:48 +0000806
Chris Lattner24943d22010-06-08 16:52:24 +0000807 if (decl_ctx == NULL)
808 decl_ctx = ast_context->getTranslationUnitDecl();
809
Greg Clayton9488b742010-07-28 02:04:09 +0000810
Greg Clayton585660c2010-08-05 01:57:25 +0000811 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000812 {
Greg Clayton306edca2010-10-11 02:25:34 +0000813 bool isForwardDecl = true;
Greg Clayton9488b742010-07-28 02:04:09 +0000814 bool isInternal = false;
815 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
816 }
817
Chris Lattner24943d22010-06-08 16:52:24 +0000818 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
819 // we will need to update this code. I was told to currently always use
820 // the CXXRecordDecl class since we often don't know from debug information
821 // if something is struct or a class, so we default to always use the more
822 // complete definition just in case.
823 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
824 (TagDecl::TagKind)kind,
825 decl_ctx,
826 SourceLocation(),
827 name && name[0] ? &ast_context->Idents.get(name) : NULL);
828
829 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
830}
831
Greg Claytondbf26152010-10-01 23:13:49 +0000832static bool
833IsOperator (const char *name, OverloadedOperatorKind &op_kind)
834{
835 if (name == NULL || name[0] == '\0')
836 return false;
837
838 if (::strstr(name, "operator ") != name)
839 return false;
840
841 const char *post_op_name = name + 9;
842
843 // This is an operator, set the overloaded operator kind to invalid
844 // in case this is a conversion operator...
845 op_kind = NUM_OVERLOADED_OPERATORS;
846
847 switch (post_op_name[0])
848 {
849 case 'n':
850 if (strcmp (post_op_name, "new") == 0)
851 op_kind = OO_New;
852 else if (strcmp (post_op_name, "new[]") == 0)
853 op_kind = OO_Array_New;
854 break;
855
856 case 'd':
857 if (strcmp (post_op_name, "delete") == 0)
858 op_kind = OO_Delete;
859 else if (strcmp (post_op_name, "delete[]") == 0)
860 op_kind = OO_Array_Delete;
861 break;
862
863 case '+':
864 if (post_op_name[1] == '\0')
865 op_kind = OO_Plus;
866 else if (post_op_name[2] == '\0')
867 {
868 if (post_op_name[1] == '=')
869 op_kind = OO_PlusEqual;
870 else if (post_op_name[1] == '+')
871 op_kind = OO_PlusPlus;
872 }
873 break;
874
875 case '-':
876 if (post_op_name[1] == '\0')
877 op_kind = OO_Minus;
878 else if (post_op_name[2] == '\0')
879 {
880 switch (post_op_name[1])
881 {
882 case '=': op_kind = OO_MinusEqual; break;
883 case '-': op_kind = OO_MinusMinus; break;
884 case '>': op_kind = OO_Arrow; break;
885 }
886 }
887 else if (post_op_name[3] == '\0')
888 {
889 if (post_op_name[2] == '*')
890 op_kind = OO_ArrowStar; break;
891 }
892 break;
893
894 case '*':
895 if (post_op_name[1] == '\0')
896 op_kind = OO_Star;
897 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
898 op_kind = OO_StarEqual;
899 break;
900
901 case '/':
902 if (post_op_name[1] == '\0')
903 op_kind = OO_Slash;
904 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
905 op_kind = OO_SlashEqual;
906 break;
907
908 case '%':
909 if (post_op_name[1] == '\0')
910 op_kind = OO_Percent;
911 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
912 op_kind = OO_PercentEqual;
913 break;
914
915
916 case '^':
917 if (post_op_name[1] == '\0')
918 op_kind = OO_Caret;
919 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
920 op_kind = OO_CaretEqual;
921 break;
922
923 case '&':
924 if (post_op_name[1] == '\0')
925 op_kind = OO_Amp;
926 else if (post_op_name[2] == '\0')
927 {
928 switch (post_op_name[1])
929 {
930 case '=': op_kind = OO_AmpEqual; break;
931 case '&': op_kind = OO_AmpAmp; break;
932 }
933 }
934 break;
935
936 case '|':
937 if (post_op_name[1] == '\0')
938 op_kind = OO_Pipe;
939 else if (post_op_name[2] == '\0')
940 {
941 switch (post_op_name[1])
942 {
943 case '=': op_kind = OO_PipeEqual; break;
944 case '|': op_kind = OO_PipePipe; break;
945 }
946 }
947 break;
948
949 case '~':
950 if (post_op_name[1] == '\0')
951 op_kind = OO_Tilde;
952 break;
953
954 case '!':
955 if (post_op_name[1] == '\0')
956 op_kind = OO_Exclaim;
957 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
958 op_kind = OO_ExclaimEqual;
959 break;
960
961 case '=':
962 if (post_op_name[1] == '\0')
963 op_kind = OO_Equal;
964 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
965 op_kind = OO_EqualEqual;
966 break;
967
968 case '<':
969 if (post_op_name[1] == '\0')
970 op_kind = OO_Less;
971 else if (post_op_name[2] == '\0')
972 {
973 switch (post_op_name[1])
974 {
975 case '<': op_kind = OO_LessLess; break;
976 case '=': op_kind = OO_LessEqual; break;
977 }
978 }
979 else if (post_op_name[3] == '\0')
980 {
981 if (post_op_name[2] == '=')
982 op_kind = OO_LessLessEqual;
983 }
984 break;
985
986 case '>':
987 if (post_op_name[1] == '\0')
988 op_kind = OO_Greater;
989 else if (post_op_name[2] == '\0')
990 {
991 switch (post_op_name[1])
992 {
993 case '>': op_kind = OO_GreaterGreater; break;
994 case '=': op_kind = OO_GreaterEqual; break;
995 }
996 }
997 else if (post_op_name[1] == '>' &&
998 post_op_name[2] == '=' &&
999 post_op_name[3] == '\0')
1000 {
1001 op_kind = OO_GreaterGreaterEqual;
1002 }
1003 break;
1004
1005 case ',':
1006 if (post_op_name[1] == '\0')
1007 op_kind = OO_Comma;
1008 break;
1009
1010 case '(':
1011 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1012 op_kind = OO_Call;
1013 break;
1014
1015 case '[':
1016 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1017 op_kind = OO_Subscript;
1018 break;
1019 }
1020
1021 return true;
1022}
Greg Clayton412440a2010-09-23 01:09:21 +00001023CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +00001024ClangASTContext::AddMethodToCXXRecordType
1025(
Greg Clayton462d4142010-09-29 01:12:09 +00001026 ASTContext *ast_context,
1027 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001028 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001029 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001030 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001031 bool is_virtual,
1032 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001033 bool is_inline,
1034 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +00001035)
Sean Callanan79523002010-09-17 02:58:26 +00001036{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001037 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +00001038 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001039
1040 assert(ast_context);
1041
1042 IdentifierTable *identifier_table = &ast_context->Idents;
1043
1044 assert(identifier_table);
1045
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001046 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +00001047
1048 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +00001049
Greg Clayton1d8173f2010-09-24 05:15:53 +00001050 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001051 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001052
Greg Clayton1d8173f2010-09-24 05:15:53 +00001053 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +00001054
Greg Clayton1d8173f2010-09-24 05:15:53 +00001055 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001056 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001057
Greg Clayton1d8173f2010-09-24 05:15:53 +00001058 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +00001059
Greg Clayton1d8173f2010-09-24 05:15:53 +00001060 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001061 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001062
1063 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1064
Greg Clayton1d8173f2010-09-24 05:15:53 +00001065 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001066 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001067
Greg Clayton1d8173f2010-09-24 05:15:53 +00001068 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001069
Greg Clayton30449d52010-10-01 02:31:07 +00001070 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001071
Greg Clayton30449d52010-10-01 02:31:07 +00001072 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001073
Greg Clayton90e325d2010-10-01 03:45:20 +00001074 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001075
Greg Clayton5325a362010-10-02 01:40:05 +00001076 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001077
Greg Clayton5325a362010-10-02 01:40:05 +00001078 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001079 return NULL;
1080
Greg Clayton5325a362010-10-02 01:40:05 +00001081 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001082
1083 if (!method_function_prototype)
1084 return NULL;
1085
1086 unsigned int num_params = method_function_prototype->getNumArgs();
1087
1088 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001089 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001090 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1091 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001092 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001093 method_qual_type,
1094 is_inline,
1095 is_implicitly_declared);
1096 }
1097 else if (decl_name == record_decl->getDeclName())
1098 {
Greg Clayton30449d52010-10-01 02:31:07 +00001099 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1100 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001101 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001102 method_qual_type,
1103 NULL, // TypeSourceInfo *
1104 is_explicit,
1105 is_inline,
1106 is_implicitly_declared);
1107 }
1108 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001109 {
Greg Claytondbf26152010-10-01 23:13:49 +00001110
1111 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1112 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001113 {
Greg Claytondbf26152010-10-01 23:13:49 +00001114 if (op_kind != NUM_OVERLOADED_OPERATORS)
1115 {
1116 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001117 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001118 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001119 method_qual_type,
1120 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001121 is_static,
1122 SC_None,
1123 is_inline);
1124 }
1125 else if (num_params == 0)
1126 {
1127 // Conversion operators don't take params...
1128 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1129 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001130 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001131 method_qual_type,
1132 NULL, // TypeSourceInfo *
1133 is_inline,
1134 is_explicit);
1135 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001136 }
Greg Claytondbf26152010-10-01 23:13:49 +00001137
1138 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001139 {
1140 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1141 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001142 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001143 method_qual_type,
1144 NULL, // TypeSourceInfo *
1145 is_static,
1146 SC_None,
1147 is_inline);
1148 }
Greg Clayton30449d52010-10-01 02:31:07 +00001149 }
Greg Claytondbf26152010-10-01 23:13:49 +00001150
Greg Clayton462d4142010-09-29 01:12:09 +00001151 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001152
1153 cxx_method_decl->setAccess (access_specifier);
1154 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001155
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001156 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001157
1158 ParmVarDecl *params[num_params];
1159
1160 for (int param_index = 0;
1161 param_index < num_params;
1162 ++param_index)
1163 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001164 params[param_index] = ParmVarDecl::Create (*ast_context,
1165 cxx_method_decl,
1166 SourceLocation(),
1167 NULL, // anonymous
1168 method_function_prototype->getArgType(param_index),
1169 NULL,
1170 SC_None,
1171 SC_None,
1172 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001173 }
1174
Greg Clayton1d8173f2010-09-24 05:15:53 +00001175 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001176
Greg Clayton1d8173f2010-09-24 05:15:53 +00001177 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001178
Greg Clayton412440a2010-09-23 01:09:21 +00001179 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001180}
1181
1182bool
Greg Clayton84f80752010-07-22 18:30:50 +00001183ClangASTContext::AddFieldToRecordType
1184(
Greg Clayton462d4142010-09-29 01:12:09 +00001185 ASTContext *ast_context,
1186 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001187 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001188 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001189 AccessType access,
1190 uint32_t bitfield_bit_size
1191)
Chris Lattner24943d22010-06-08 16:52:24 +00001192{
1193 if (record_clang_type == NULL || field_type == NULL)
1194 return false;
1195
Sean Callanan60a0ced2010-09-16 20:01:08 +00001196 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001197
1198 assert (ast_context != NULL);
1199 assert (identifier_table != NULL);
1200
1201 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1202
Greg Clayton1674b122010-07-21 22:12:05 +00001203 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001204 if (clang_type)
1205 {
1206 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1207
1208 if (record_type)
1209 {
1210 RecordDecl *record_decl = record_type->getDecl();
1211
Chris Lattner24943d22010-06-08 16:52:24 +00001212 clang::Expr *bit_width = NULL;
1213 if (bitfield_bit_size != 0)
1214 {
1215 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001216 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001217 }
Greg Clayton84f80752010-07-22 18:30:50 +00001218 FieldDecl *field = FieldDecl::Create (*ast_context,
1219 record_decl,
1220 SourceLocation(),
1221 name ? &identifier_table->get(name) : NULL, // Identifier
1222 QualType::getFromOpaquePtr(field_type), // Field type
1223 NULL, // DeclaratorInfo *
1224 bit_width, // BitWidth
1225 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001226
Greg Clayton84f80752010-07-22 18:30:50 +00001227 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001228
1229 if (field)
1230 {
1231 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001232 }
1233 }
Greg Clayton9488b742010-07-28 02:04:09 +00001234 else
1235 {
1236 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1237 if (objc_class_type)
1238 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001239 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001240 ClangASTContext::AddObjCClassIVar (ast_context,
1241 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001242 name,
1243 field_type,
1244 access,
1245 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001246 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001247 }
1248 }
Chris Lattner24943d22010-06-08 16:52:24 +00001249 }
1250 return false;
1251}
1252
1253bool
1254ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1255{
1256 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1257}
1258
1259bool
1260ClangASTContext::FieldIsBitfield
1261(
1262 ASTContext *ast_context,
1263 FieldDecl* field,
1264 uint32_t& bitfield_bit_size
1265)
1266{
1267 if (ast_context == NULL || field == NULL)
1268 return false;
1269
1270 if (field->isBitField())
1271 {
1272 Expr* bit_width_expr = field->getBitWidth();
1273 if (bit_width_expr)
1274 {
1275 llvm::APSInt bit_width_apsint;
1276 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1277 {
1278 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1279 return true;
1280 }
1281 }
1282 }
1283 return false;
1284}
1285
1286bool
1287ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1288{
1289 if (record_decl == NULL)
1290 return false;
1291
1292 if (!record_decl->field_empty())
1293 return true;
1294
1295 // No fields, lets check this is a CXX record and check the base classes
1296 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1297 if (cxx_record_decl)
1298 {
1299 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1300 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1301 base_class != base_class_end;
1302 ++base_class)
1303 {
1304 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1305 if (RecordHasFields(base_class_decl))
1306 return true;
1307 }
1308 }
1309 return false;
1310}
1311
1312void
Greg Clayton462d4142010-09-29 01:12:09 +00001313ClangASTContext::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 +00001314{
1315 if (clang_qual_type)
1316 {
1317 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001318 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001319 if (clang_type)
1320 {
1321 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1322 if (record_type)
1323 {
1324 RecordDecl *record_decl = record_type->getDecl();
1325 if (record_decl)
1326 {
1327 uint32_t field_idx;
1328 RecordDecl::field_iterator field, field_end;
1329 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1330 field != field_end;
1331 ++field, ++field_idx)
1332 {
1333 // If no accessibility was assigned, assign the correct one
1334 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1335 field->setAccess ((AccessSpecifier)default_accessibility);
1336 }
1337 }
1338 }
1339 }
1340 }
1341}
1342
1343#pragma mark C++ Base Classes
1344
1345CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001346ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001347{
1348 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001349 return new CXXBaseSpecifier (SourceRange(),
1350 is_virtual,
1351 base_of_class,
1352 ConvertAccessTypeToAccessSpecifier (access),
1353 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001354 return NULL;
1355}
1356
Greg Claytone9d0df42010-07-02 01:29:13 +00001357void
1358ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1359{
1360 for (unsigned i=0; i<num_base_classes; ++i)
1361 {
1362 delete base_classes[i];
1363 base_classes[i] = NULL;
1364 }
1365}
1366
Chris Lattner24943d22010-06-08 16:52:24 +00001367bool
Greg Clayton462d4142010-09-29 01:12:09 +00001368ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001369{
1370 if (class_clang_type)
1371 {
Greg Clayton1674b122010-07-21 22:12:05 +00001372 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001373 if (clang_type)
1374 {
1375 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1376 if (record_type)
1377 {
1378 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1379 if (cxx_record_decl)
1380 {
Chris Lattner24943d22010-06-08 16:52:24 +00001381 cxx_record_decl->setBases(base_classes, num_base_classes);
1382 return true;
1383 }
1384 }
1385 }
1386 }
1387 return false;
1388}
Greg Clayton84f80752010-07-22 18:30:50 +00001389#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001390
Greg Clayton462d4142010-09-29 01:12:09 +00001391clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001392ClangASTContext::CreateObjCClass
1393(
1394 const char *name,
1395 DeclContext *decl_ctx,
1396 bool isForwardDecl,
1397 bool isInternal
1398)
1399{
1400 ASTContext *ast_context = getASTContext();
1401 assert (ast_context != NULL);
1402 assert (name && name[0]);
1403 if (decl_ctx == NULL)
1404 decl_ctx = ast_context->getTranslationUnitDecl();
1405
1406 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1407 // we will need to update this code. I was told to currently always use
1408 // the CXXRecordDecl class since we often don't know from debug information
1409 // if something is struct or a class, so we default to always use the more
1410 // complete definition just in case.
1411 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1412 decl_ctx,
1413 SourceLocation(),
1414 &ast_context->Idents.get(name),
1415 SourceLocation(),
1416 isForwardDecl,
1417 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001418
1419 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001420}
1421
1422bool
Greg Clayton462d4142010-09-29 01:12:09 +00001423ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001424{
1425 if (class_opaque_type && super_opaque_type)
1426 {
1427 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1428 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1429 clang::Type *class_type = class_qual_type.getTypePtr();
1430 clang::Type *super_type = super_qual_type.getTypePtr();
1431 if (class_type && super_type)
1432 {
1433 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1434 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1435 if (objc_class_type && objc_super_type)
1436 {
1437 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1438 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1439 if (class_interface_decl && super_interface_decl)
1440 {
1441 class_interface_decl->setSuperClass(super_interface_decl);
1442 return true;
1443 }
1444 }
1445 }
1446 }
1447 return false;
1448}
1449
1450
1451bool
1452ClangASTContext::AddObjCClassIVar
1453(
Greg Clayton462d4142010-09-29 01:12:09 +00001454 ASTContext *ast_context,
1455 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001456 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001457 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001458 AccessType access,
1459 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001460 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001461)
1462{
1463 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1464 return false;
1465
Sean Callanan60a0ced2010-09-16 20:01:08 +00001466 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001467
1468 assert (ast_context != NULL);
1469 assert (identifier_table != NULL);
1470
1471 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1472
1473 clang::Type *class_type = class_qual_type.getTypePtr();
1474 if (class_type)
1475 {
1476 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1477
1478 if (objc_class_type)
1479 {
1480 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1481
1482 if (class_interface_decl)
1483 {
1484 clang::Expr *bit_width = NULL;
1485 if (bitfield_bit_size != 0)
1486 {
1487 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001488 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001489 }
1490
Greg Clayton9488b742010-07-28 02:04:09 +00001491 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1492 class_interface_decl,
1493 SourceLocation(),
1494 &identifier_table->get(name), // Identifier
1495 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1496 NULL, // TypeSourceInfo *
1497 ConvertAccessTypeToObjCIvarAccessControl (access),
1498 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001499 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001500
1501 if (field)
1502 {
1503 class_interface_decl->addDecl(field);
1504 return true;
1505 }
Greg Clayton84f80752010-07-22 18:30:50 +00001506 }
1507 }
1508 }
1509 return false;
1510}
Chris Lattner24943d22010-06-08 16:52:24 +00001511
Greg Clayton9488b742010-07-28 02:04:09 +00001512
1513bool
Greg Clayton462d4142010-09-29 01:12:09 +00001514ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001515{
1516 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1517
1518 clang::Type *class_type = class_qual_type.getTypePtr();
1519 if (class_type)
1520 {
1521 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1522
1523 if (objc_class_type)
1524 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1525 }
1526 return false;
1527}
1528
1529bool
1530ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1531{
1532 while (class_interface_decl)
1533 {
1534 if (class_interface_decl->ivar_size() > 0)
1535 return true;
1536
1537 if (check_superclass)
1538 class_interface_decl = class_interface_decl->getSuperClass();
1539 else
1540 break;
1541 }
1542 return false;
1543}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001544
Greg Clayton462d4142010-09-29 01:12:09 +00001545ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001546ClangASTContext::AddMethodToObjCObjectType
1547(
Greg Clayton462d4142010-09-29 01:12:09 +00001548 ASTContext *ast_context,
1549 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001550 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001551 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001552 lldb::AccessType access
1553)
1554{
1555 if (class_opaque_type == NULL || method_opaque_type == NULL)
1556 return NULL;
1557
1558 IdentifierTable *identifier_table = &ast_context->Idents;
1559
1560 assert (ast_context != NULL);
1561 assert (identifier_table != NULL);
1562
1563 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1564
1565 clang::Type *class_type = class_qual_type.getTypePtr();
1566 if (class_type == NULL)
1567 return NULL;
1568
1569 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1570
1571 if (objc_class_type == NULL)
1572 return NULL;
1573
1574 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1575
1576 if (class_interface_decl == NULL)
1577 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001578
Greg Clayton1d8173f2010-09-24 05:15:53 +00001579 const char *selector_start = ::strchr (name, ' ');
1580 if (selector_start == NULL)
1581 return NULL;
1582
1583 selector_start++;
1584 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1585 return NULL;
1586 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1587
Greg Claytonad60bf42010-10-12 02:24:53 +00001588 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001589 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001590 //printf ("name = '%s'\n", name);
1591
1592 unsigned num_selectors_with_args = 0;
1593 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001594 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001595 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001596 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001597 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001598 bool has_arg = (start[len] == ':');
1599 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001600 ++num_selectors_with_args;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001601 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001602 if (has_arg)
1603 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001604 }
1605
1606
1607 if (selector_idents.size() == 0)
1608 return 0;
1609
Greg Claytonad60bf42010-10-12 02:24:53 +00001610 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001611 selector_idents.data());
1612
1613 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1614
1615 // Populate the method decl with parameter decls
1616 clang::Type *method_type(method_qual_type.getTypePtr());
1617
1618 if (method_type == NULL)
1619 return NULL;
1620
1621 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1622
1623 if (!method_function_prototype)
1624 return NULL;
1625
1626
1627 bool is_variadic = false;
1628 bool is_synthesized = false;
1629 bool is_defined = false;
1630 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1631
1632 const unsigned num_args = method_function_prototype->getNumArgs();
1633
1634 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1635 SourceLocation(), // beginLoc,
1636 SourceLocation(), // endLoc,
1637 method_selector,
1638 method_function_prototype->getResultType(),
1639 NULL, // TypeSourceInfo *ResultTInfo,
1640 GetDeclContextForType (class_opaque_type),
1641 name[0] == '-',
1642 is_variadic,
1643 is_synthesized,
1644 is_defined,
1645 imp_control,
1646 num_args);
1647
1648
1649 if (objc_method_decl == NULL)
1650 return NULL;
1651
1652 if (num_args > 0)
1653 {
1654 llvm::SmallVector<ParmVarDecl *, 12> params;
1655
1656 for (int param_index = 0; param_index < num_args; ++param_index)
1657 {
1658 params.push_back (ParmVarDecl::Create (*ast_context,
1659 objc_method_decl,
1660 SourceLocation(),
1661 NULL, // anonymous
1662 method_function_prototype->getArgType(param_index),
1663 NULL,
1664 SC_Auto,
1665 SC_Auto,
1666 NULL));
1667 }
1668
1669 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1670 }
1671
1672 class_interface_decl->addDecl (objc_method_decl);
1673
1674
1675 return objc_method_decl;
1676}
1677
1678
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001679uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001680ClangASTContext::GetTypeInfo
1681(
1682 clang_type_t clang_type,
1683 clang::ASTContext *ast_context,
1684 clang_type_t *pointee_or_element_clang_type
1685)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001686{
1687 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001688 return 0;
1689
1690 if (pointee_or_element_clang_type)
1691 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001692
1693 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1694
1695 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1696 switch (type_class)
1697 {
Sean Callanan04325062010-10-25 00:29:48 +00001698 case clang::Type::Builtin:
1699 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1700 {
Sean Callanan04325062010-10-25 00:29:48 +00001701 case clang::BuiltinType::ObjCId:
1702 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001703 if (ast_context && pointee_or_element_clang_type)
1704 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001705 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001706
1707 default:
1708 break;
Sean Callanan04325062010-10-25 00:29:48 +00001709 }
1710 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001711
1712 case clang::Type::BlockPointer:
1713 if (pointee_or_element_clang_type)
1714 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1715 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1716
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001717 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001718
1719 case clang::Type::ConstantArray:
1720 case clang::Type::DependentSizedArray:
1721 case clang::Type::IncompleteArray:
1722 case clang::Type::VariableArray:
1723 if (pointee_or_element_clang_type)
1724 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1725 return eTypeHasChildren | eTypeIsArray;
1726
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001727 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001728 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1729 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1730 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001731
1732 case clang::Type::Enum:
1733 if (pointee_or_element_clang_type)
1734 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1735 return eTypeIsEnumeration | eTypeHasValue;
1736
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001737 case clang::Type::Elaborated: return 0;
1738 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1739 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1740 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001741 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001742
1743 case clang::Type::LValueReference:
1744 case clang::Type::RValueReference:
1745 if (pointee_or_element_clang_type)
1746 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1747 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1748
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001749 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001750
1751 case clang::Type::ObjCObjectPointer:
1752 if (pointee_or_element_clang_type)
1753 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1754 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1755
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001756 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1757 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001758
1759 case clang::Type::Pointer:
1760 if (pointee_or_element_clang_type)
1761 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1762 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1763
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001764 case clang::Type::Record:
1765 if (qual_type->getAsCXXRecordDecl())
1766 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1767 else
1768 return eTypeHasChildren | eTypeIsStructUnion;
1769 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001770 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1771 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1772 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001773
1774 case clang::Type::Typedef:
1775 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1776 ast_context,
1777 pointee_or_element_clang_type);
1778
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001779 case clang::Type::TypeOfExpr: return 0;
1780 case clang::Type::TypeOf: return 0;
1781 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001782 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1783 default: return 0;
1784 }
1785 return 0;
1786}
1787
Greg Clayton9488b742010-07-28 02:04:09 +00001788
Chris Lattner24943d22010-06-08 16:52:24 +00001789#pragma mark Aggregate Types
1790
1791bool
Greg Clayton462d4142010-09-29 01:12:09 +00001792ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001793{
1794 if (clang_type == NULL)
1795 return false;
1796
1797 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1798
1799 if (qual_type->isAggregateType ())
1800 return true;
1801
Greg Clayton03e0f972010-09-13 03:32:57 +00001802 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1803 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001804 {
Greg Clayton1674b122010-07-21 22:12:05 +00001805 case clang::Type::IncompleteArray:
1806 case clang::Type::VariableArray:
1807 case clang::Type::ConstantArray:
1808 case clang::Type::ExtVector:
1809 case clang::Type::Vector:
1810 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001811 case clang::Type::ObjCObject:
1812 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001813 return true;
1814
Greg Clayton1674b122010-07-21 22:12:05 +00001815 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001816 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1817
1818 default:
1819 break;
1820 }
1821 // The clang type does have a value
1822 return false;
1823}
1824
1825uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001826ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001827{
1828 if (clang_qual_type == NULL)
1829 return 0;
1830
1831 uint32_t num_children = 0;
1832 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001833 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1834 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001835 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001836 case clang::Type::Builtin:
1837 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1838 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001839 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001840 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001841 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001842 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001843
1844 default:
1845 break;
1846 }
1847 break;
1848
Greg Clayton1674b122010-07-21 22:12:05 +00001849 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001850 {
1851 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1852 const RecordDecl *record_decl = record_type->getDecl();
1853 assert(record_decl);
1854 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1855 if (cxx_record_decl)
1856 {
1857 if (omit_empty_base_classes)
1858 {
1859 // Check each base classes to see if it or any of its
1860 // base classes contain any fields. This can help
1861 // limit the noise in variable views by not having to
1862 // show base classes that contain no members.
1863 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1864 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1865 base_class != base_class_end;
1866 ++base_class)
1867 {
1868 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1869
1870 // Skip empty base classes
1871 if (RecordHasFields(base_class_decl) == false)
1872 continue;
1873
1874 num_children++;
1875 }
1876 }
1877 else
1878 {
1879 // Include all base classes
1880 num_children += cxx_record_decl->getNumBases();
1881 }
1882
1883 }
1884 RecordDecl::field_iterator field, field_end;
1885 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1886 ++num_children;
1887 }
1888 break;
1889
Greg Clayton9488b742010-07-28 02:04:09 +00001890 case clang::Type::ObjCObject:
1891 case clang::Type::ObjCInterface:
1892 {
1893 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1894 assert (objc_class_type);
1895 if (objc_class_type)
1896 {
1897 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1898
1899 if (class_interface_decl)
1900 {
1901
1902 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1903 if (superclass_interface_decl)
1904 {
1905 if (omit_empty_base_classes)
1906 {
1907 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1908 ++num_children;
1909 }
1910 else
1911 ++num_children;
1912 }
1913
1914 num_children += class_interface_decl->ivar_size();
1915 }
1916 }
1917 }
1918 break;
1919
1920 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001921 {
1922 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1923 QualType pointee_type = pointer_type->getPointeeType();
1924 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1925 omit_empty_base_classes);
1926 // If this type points to a simple type, then it has 1 child
1927 if (num_pointee_children == 0)
1928 num_children = 1;
1929 else
1930 num_children = num_pointee_children;
1931 }
1932 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001933
Greg Clayton1674b122010-07-21 22:12:05 +00001934 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001935 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1936 break;
1937
Greg Clayton1674b122010-07-21 22:12:05 +00001938 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001939 {
1940 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1941 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001942 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1943 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001944 // If this type points to a simple type, then it has 1 child
1945 if (num_pointee_children == 0)
1946 num_children = 1;
1947 else
1948 num_children = num_pointee_children;
1949 }
1950 break;
1951
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001952 case clang::Type::LValueReference:
1953 case clang::Type::RValueReference:
1954 {
1955 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1956 QualType pointee_type = reference_type->getPointeeType();
1957 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1958 omit_empty_base_classes);
1959 // If this type points to a simple type, then it has 1 child
1960 if (num_pointee_children == 0)
1961 num_children = 1;
1962 else
1963 num_children = num_pointee_children;
1964 }
1965 break;
1966
1967
Greg Clayton1674b122010-07-21 22:12:05 +00001968 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001969 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1970 break;
1971
1972 default:
1973 break;
1974 }
1975 return num_children;
1976}
1977
1978
Greg Clayton462d4142010-09-29 01:12:09 +00001979clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00001980ClangASTContext::GetChildClangTypeAtIndex
1981(
1982 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00001983 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00001984 uint32_t idx,
1985 bool transparent_pointers,
1986 bool omit_empty_base_classes,
1987 std::string& child_name,
1988 uint32_t &child_byte_size,
1989 int32_t &child_byte_offset,
1990 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001991 uint32_t &child_bitfield_bit_offset,
1992 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00001993)
1994{
1995 if (parent_clang_type)
1996
1997 return GetChildClangTypeAtIndex (getASTContext(),
1998 parent_name,
1999 parent_clang_type,
2000 idx,
2001 transparent_pointers,
2002 omit_empty_base_classes,
2003 child_name,
2004 child_byte_size,
2005 child_byte_offset,
2006 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002007 child_bitfield_bit_offset,
2008 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002009 return NULL;
2010}
2011
Greg Clayton462d4142010-09-29 01:12:09 +00002012clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002013ClangASTContext::GetChildClangTypeAtIndex
2014(
2015 ASTContext *ast_context,
2016 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002017 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002018 uint32_t idx,
2019 bool transparent_pointers,
2020 bool omit_empty_base_classes,
2021 std::string& child_name,
2022 uint32_t &child_byte_size,
2023 int32_t &child_byte_offset,
2024 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002025 uint32_t &child_bitfield_bit_offset,
2026 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002027)
2028{
2029 if (parent_clang_type == NULL)
2030 return NULL;
2031
2032 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2033 {
2034 uint32_t bit_offset;
2035 child_bitfield_bit_size = 0;
2036 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002037 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002038 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002039 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2040 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002041 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002042 case clang::Type::Builtin:
2043 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2044 {
2045 case clang::BuiltinType::ObjCId:
2046 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002047 child_name = "isa";
2048 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002049 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2050
Greg Clayton960d6a42010-08-03 00:35:52 +00002051 default:
2052 break;
2053 }
2054 break;
2055
2056
Greg Clayton1674b122010-07-21 22:12:05 +00002057 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002058 {
2059 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2060 const RecordDecl *record_decl = record_type->getDecl();
2061 assert(record_decl);
2062 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2063 uint32_t child_idx = 0;
2064
2065 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2066 if (cxx_record_decl)
2067 {
2068 // We might have base classes to print out first
2069 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2070 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2071 base_class != base_class_end;
2072 ++base_class)
2073 {
2074 const CXXRecordDecl *base_class_decl = NULL;
2075
2076 // Skip empty base classes
2077 if (omit_empty_base_classes)
2078 {
2079 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2080 if (RecordHasFields(base_class_decl) == false)
2081 continue;
2082 }
2083
2084 if (idx == child_idx)
2085 {
2086 if (base_class_decl == NULL)
2087 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2088
2089
2090 if (base_class->isVirtual())
2091 bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
2092 else
2093 bit_offset = record_layout.getBaseClassOffset(base_class_decl);
2094
2095 // Base classes should be a multiple of 8 bits in size
2096 assert (bit_offset % 8 == 0);
2097 child_byte_offset = bit_offset/8;
2098 std::string base_class_type_name(base_class->getType().getAsString());
2099
2100 child_name.assign(base_class_type_name.c_str());
2101
2102 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2103
2104 // Base classes biut sizes should be a multiple of 8 bits in size
2105 assert (clang_type_info_bit_size % 8 == 0);
2106 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002107 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002108 return base_class->getType().getAsOpaquePtr();
2109 }
2110 // We don't increment the child index in the for loop since we might
2111 // be skipping empty base classes
2112 ++child_idx;
2113 }
2114 }
Chris Lattner24943d22010-06-08 16:52:24 +00002115 // Make sure index is in range...
2116 uint32_t field_idx = 0;
2117 RecordDecl::field_iterator field, field_end;
2118 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2119 {
2120 if (idx == child_idx)
2121 {
2122 // Print the member type if requested
2123 // Print the member name and equal sign
2124 child_name.assign(field->getNameAsString().c_str());
2125
2126 // Figure out the type byte size (field_type_info.first) and
2127 // alignment (field_type_info.second) from the AST context.
2128 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002129 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002130
2131 child_byte_size = field_type_info.first / 8;
2132
2133 // Figure out the field offset within the current struct/union/class type
2134 bit_offset = record_layout.getFieldOffset (field_idx);
2135 child_byte_offset = bit_offset / 8;
2136 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2137 child_bitfield_bit_offset = bit_offset % 8;
2138
2139 return field->getType().getAsOpaquePtr();
2140 }
2141 }
2142 }
2143 break;
2144
Greg Clayton9488b742010-07-28 02:04:09 +00002145 case clang::Type::ObjCObject:
2146 case clang::Type::ObjCInterface:
2147 {
2148 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2149 assert (objc_class_type);
2150 if (objc_class_type)
2151 {
2152 uint32_t child_idx = 0;
2153 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2154
2155 if (class_interface_decl)
2156 {
2157
2158 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2159 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2160 if (superclass_interface_decl)
2161 {
2162 if (omit_empty_base_classes)
2163 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002164 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002165 {
2166 if (idx == 0)
2167 {
2168 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2169
2170
2171 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2172
2173 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2174
2175 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002176 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002177 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002178
2179 return ivar_qual_type.getAsOpaquePtr();
2180 }
2181
2182 ++child_idx;
2183 }
2184 }
2185 else
2186 ++child_idx;
2187 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002188
2189 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002190
2191 if (idx < (child_idx + class_interface_decl->ivar_size()))
2192 {
2193 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2194
2195 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2196 {
2197 if (child_idx == idx)
2198 {
2199 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2200
2201 QualType ivar_qual_type(ivar_decl->getType());
2202
2203 child_name.assign(ivar_decl->getNameAsString().c_str());
2204
2205 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2206
2207 child_byte_size = ivar_type_info.first / 8;
2208
2209 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002210 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002211 child_byte_offset = bit_offset / 8;
2212
2213 return ivar_qual_type.getAsOpaquePtr();
2214 }
2215 ++child_idx;
2216 }
2217 }
2218 }
2219 }
2220 }
2221 break;
2222
2223 case clang::Type::ObjCObjectPointer:
2224 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002225 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2226 QualType pointee_type = pointer_type->getPointeeType();
2227
2228 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2229 {
2230 return GetChildClangTypeAtIndex (ast_context,
2231 parent_name,
2232 pointer_type->getPointeeType().getAsOpaquePtr(),
2233 idx,
2234 transparent_pointers,
2235 omit_empty_base_classes,
2236 child_name,
2237 child_byte_size,
2238 child_byte_offset,
2239 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002240 child_bitfield_bit_offset,
2241 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002242 }
2243 else
2244 {
2245 if (parent_name)
2246 {
2247 child_name.assign(1, '*');
2248 child_name += parent_name;
2249 }
2250
2251 // We have a pointer to an simple type
2252 if (idx == 0)
2253 {
2254 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2255 assert(clang_type_info.first % 8 == 0);
2256 child_byte_size = clang_type_info.first / 8;
2257 child_byte_offset = 0;
2258 return pointee_type.getAsOpaquePtr();
2259 }
2260 }
Greg Clayton9488b742010-07-28 02:04:09 +00002261 }
2262 break;
2263
Greg Clayton1674b122010-07-21 22:12:05 +00002264 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002265 {
2266 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2267 const uint64_t element_count = array->getSize().getLimitedValue();
2268
2269 if (idx < element_count)
2270 {
2271 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2272
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002273 char element_name[64];
2274 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002275
2276 child_name.assign(element_name);
2277 assert(field_type_info.first % 8 == 0);
2278 child_byte_size = field_type_info.first / 8;
2279 child_byte_offset = idx * child_byte_size;
2280 return array->getElementType().getAsOpaquePtr();
2281 }
2282 }
2283 break;
2284
Greg Clayton1674b122010-07-21 22:12:05 +00002285 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002286 {
2287 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2288 QualType pointee_type = pointer_type->getPointeeType();
2289
2290 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2291 {
2292 return GetChildClangTypeAtIndex (ast_context,
2293 parent_name,
2294 pointer_type->getPointeeType().getAsOpaquePtr(),
2295 idx,
2296 transparent_pointers,
2297 omit_empty_base_classes,
2298 child_name,
2299 child_byte_size,
2300 child_byte_offset,
2301 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002302 child_bitfield_bit_offset,
2303 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002304 }
2305 else
2306 {
2307 if (parent_name)
2308 {
2309 child_name.assign(1, '*');
2310 child_name += parent_name;
2311 }
2312
2313 // We have a pointer to an simple type
2314 if (idx == 0)
2315 {
2316 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2317 assert(clang_type_info.first % 8 == 0);
2318 child_byte_size = clang_type_info.first / 8;
2319 child_byte_offset = 0;
2320 return pointee_type.getAsOpaquePtr();
2321 }
2322 }
2323 }
2324 break;
2325
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002326 case clang::Type::LValueReference:
2327 case clang::Type::RValueReference:
2328 {
2329 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2330 QualType pointee_type(reference_type->getPointeeType());
2331 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2332 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2333 {
2334 return GetChildClangTypeAtIndex (ast_context,
2335 parent_name,
2336 pointee_clang_type,
2337 idx,
2338 transparent_pointers,
2339 omit_empty_base_classes,
2340 child_name,
2341 child_byte_size,
2342 child_byte_offset,
2343 child_bitfield_bit_size,
2344 child_bitfield_bit_offset,
2345 child_is_base_class);
2346 }
2347 else
2348 {
2349 if (parent_name)
2350 {
2351 child_name.assign(1, '&');
2352 child_name += parent_name;
2353 }
2354
2355 // We have a pointer to an simple type
2356 if (idx == 0)
2357 {
2358 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2359 assert(clang_type_info.first % 8 == 0);
2360 child_byte_size = clang_type_info.first / 8;
2361 child_byte_offset = 0;
2362 return pointee_type.getAsOpaquePtr();
2363 }
2364 }
2365 }
2366 break;
2367
Greg Clayton1674b122010-07-21 22:12:05 +00002368 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002369 return GetChildClangTypeAtIndex (ast_context,
2370 parent_name,
2371 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2372 idx,
2373 transparent_pointers,
2374 omit_empty_base_classes,
2375 child_name,
2376 child_byte_size,
2377 child_byte_offset,
2378 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002379 child_bitfield_bit_offset,
2380 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002381 break;
2382
2383 default:
2384 break;
2385 }
2386 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002387 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002388}
2389
2390static inline bool
2391BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2392{
2393 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2394}
2395
2396static uint32_t
2397GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2398{
2399 uint32_t num_bases = 0;
2400 if (cxx_record_decl)
2401 {
2402 if (omit_empty_base_classes)
2403 {
2404 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2405 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2406 base_class != base_class_end;
2407 ++base_class)
2408 {
2409 // Skip empty base classes
2410 if (omit_empty_base_classes)
2411 {
2412 if (BaseSpecifierIsEmpty (base_class))
2413 continue;
2414 }
2415 ++num_bases;
2416 }
2417 }
2418 else
2419 num_bases = cxx_record_decl->getNumBases();
2420 }
2421 return num_bases;
2422}
2423
2424
2425static uint32_t
2426GetIndexForRecordBase
2427(
2428 const RecordDecl *record_decl,
2429 const CXXBaseSpecifier *base_spec,
2430 bool omit_empty_base_classes
2431)
2432{
2433 uint32_t child_idx = 0;
2434
2435 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2436
2437// const char *super_name = record_decl->getNameAsCString();
2438// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2439// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2440//
2441 if (cxx_record_decl)
2442 {
2443 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2444 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2445 base_class != base_class_end;
2446 ++base_class)
2447 {
2448 if (omit_empty_base_classes)
2449 {
2450 if (BaseSpecifierIsEmpty (base_class))
2451 continue;
2452 }
2453
2454// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2455// child_idx,
2456// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2457//
2458//
2459 if (base_class == base_spec)
2460 return child_idx;
2461 ++child_idx;
2462 }
2463 }
2464
2465 return UINT32_MAX;
2466}
2467
2468
2469static uint32_t
2470GetIndexForRecordChild
2471(
2472 const RecordDecl *record_decl,
2473 NamedDecl *canonical_decl,
2474 bool omit_empty_base_classes
2475)
2476{
2477 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2478
2479// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2480//
2481//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2482// if (cxx_record_decl)
2483// {
2484// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2485// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2486// base_class != base_class_end;
2487// ++base_class)
2488// {
2489// if (omit_empty_base_classes)
2490// {
2491// if (BaseSpecifierIsEmpty (base_class))
2492// continue;
2493// }
2494//
2495//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2496//// record_decl->getNameAsCString(),
2497//// canonical_decl->getNameAsCString(),
2498//// child_idx,
2499//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2500//
2501//
2502// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2503// if (curr_base_class_decl == canonical_decl)
2504// {
2505// return child_idx;
2506// }
2507// ++child_idx;
2508// }
2509// }
2510//
2511// const uint32_t num_bases = child_idx;
2512 RecordDecl::field_iterator field, field_end;
2513 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2514 field != field_end;
2515 ++field, ++child_idx)
2516 {
2517// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2518// record_decl->getNameAsCString(),
2519// canonical_decl->getNameAsCString(),
2520// child_idx - num_bases,
2521// field->getNameAsCString());
2522
2523 if (field->getCanonicalDecl() == canonical_decl)
2524 return child_idx;
2525 }
2526
2527 return UINT32_MAX;
2528}
2529
2530// Look for a child member (doesn't include base classes, but it does include
2531// their members) in the type hierarchy. Returns an index path into "clang_type"
2532// on how to reach the appropriate member.
2533//
2534// class A
2535// {
2536// public:
2537// int m_a;
2538// int m_b;
2539// };
2540//
2541// class B
2542// {
2543// };
2544//
2545// class C :
2546// public B,
2547// public A
2548// {
2549// };
2550//
2551// If we have a clang type that describes "class C", and we wanted to looked
2552// "m_b" in it:
2553//
2554// With omit_empty_base_classes == false we would get an integer array back with:
2555// { 1, 1 }
2556// The first index 1 is the child index for "class A" within class C
2557// The second index 1 is the child index for "m_b" within class A
2558//
2559// With omit_empty_base_classes == true we would get an integer array back with:
2560// { 0, 1 }
2561// 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)
2562// The second index 1 is the child index for "m_b" within class A
2563
2564size_t
2565ClangASTContext::GetIndexOfChildMemberWithName
2566(
2567 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002568 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002569 const char *name,
2570 bool omit_empty_base_classes,
2571 std::vector<uint32_t>& child_indexes
2572)
2573{
2574 if (clang_type && name && name[0])
2575 {
2576 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002577 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2578 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002579 {
Greg Clayton1674b122010-07-21 22:12:05 +00002580 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002581 {
2582 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2583 const RecordDecl *record_decl = record_type->getDecl();
2584
2585 assert(record_decl);
2586 uint32_t child_idx = 0;
2587
2588 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2589
2590 // Try and find a field that matches NAME
2591 RecordDecl::field_iterator field, field_end;
2592 StringRef name_sref(name);
2593 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2594 field != field_end;
2595 ++field, ++child_idx)
2596 {
2597 if (field->getName().equals (name_sref))
2598 {
2599 // We have to add on the number of base classes to this index!
2600 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2601 return child_indexes.size();
2602 }
2603 }
2604
2605 if (cxx_record_decl)
2606 {
2607 const RecordDecl *parent_record_decl = cxx_record_decl;
2608
2609 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2610
2611 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2612 // Didn't find things easily, lets let clang do its thang...
2613 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2614 DeclarationName decl_name(&ident_ref);
2615
2616 CXXBasePaths paths;
2617 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2618 decl_name.getAsOpaquePtr(),
2619 paths))
2620 {
Chris Lattner24943d22010-06-08 16:52:24 +00002621 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2622 for (path = paths.begin(); path != path_end; ++path)
2623 {
2624 const size_t num_path_elements = path->size();
2625 for (size_t e=0; e<num_path_elements; ++e)
2626 {
2627 CXXBasePathElement elem = (*path)[e];
2628
2629 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2630 if (child_idx == UINT32_MAX)
2631 {
2632 child_indexes.clear();
2633 return 0;
2634 }
2635 else
2636 {
2637 child_indexes.push_back (child_idx);
2638 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2639 }
2640 }
2641 DeclContext::lookup_iterator named_decl_pos;
2642 for (named_decl_pos = path->Decls.first;
2643 named_decl_pos != path->Decls.second && parent_record_decl;
2644 ++named_decl_pos)
2645 {
2646 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2647
2648 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2649 if (child_idx == UINT32_MAX)
2650 {
2651 child_indexes.clear();
2652 return 0;
2653 }
2654 else
2655 {
2656 child_indexes.push_back (child_idx);
2657 }
2658 }
2659 }
2660 return child_indexes.size();
2661 }
2662 }
2663
2664 }
2665 break;
2666
Greg Clayton9488b742010-07-28 02:04:09 +00002667 case clang::Type::ObjCObject:
2668 case clang::Type::ObjCInterface:
2669 {
2670 StringRef name_sref(name);
2671 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2672 assert (objc_class_type);
2673 if (objc_class_type)
2674 {
2675 uint32_t child_idx = 0;
2676 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2677
2678 if (class_interface_decl)
2679 {
2680 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2681 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2682
Greg Clayton823533e2010-09-18 02:11:07 +00002683 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002684 {
2685 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2686
2687 if (ivar_decl->getName().equals (name_sref))
2688 {
2689 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2690 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2691 ++child_idx;
2692
2693 child_indexes.push_back (child_idx);
2694 return child_indexes.size();
2695 }
2696 }
2697
2698 if (superclass_interface_decl)
2699 {
2700 // The super class index is always zero for ObjC classes,
2701 // so we push it onto the child indexes in case we find
2702 // an ivar in our superclass...
2703 child_indexes.push_back (0);
2704
2705 if (GetIndexOfChildMemberWithName (ast_context,
2706 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2707 name,
2708 omit_empty_base_classes,
2709 child_indexes))
2710 {
2711 // We did find an ivar in a superclass so just
2712 // return the results!
2713 return child_indexes.size();
2714 }
2715
2716 // We didn't find an ivar matching "name" in our
2717 // superclass, pop the superclass zero index that
2718 // we pushed on above.
2719 child_indexes.pop_back();
2720 }
2721 }
2722 }
2723 }
2724 break;
2725
2726 case clang::Type::ObjCObjectPointer:
2727 {
2728 return GetIndexOfChildMemberWithName (ast_context,
2729 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2730 name,
2731 omit_empty_base_classes,
2732 child_indexes);
2733 }
2734 break;
2735
2736
Greg Clayton1674b122010-07-21 22:12:05 +00002737 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002738 {
2739// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2740// const uint64_t element_count = array->getSize().getLimitedValue();
2741//
2742// if (idx < element_count)
2743// {
2744// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2745//
2746// char element_name[32];
2747// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2748//
2749// child_name.assign(element_name);
2750// assert(field_type_info.first % 8 == 0);
2751// child_byte_size = field_type_info.first / 8;
2752// child_byte_offset = idx * child_byte_size;
2753// return array->getElementType().getAsOpaquePtr();
2754// }
2755 }
2756 break;
2757
Greg Clayton1674b122010-07-21 22:12:05 +00002758// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002759// {
2760// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2761// QualType pointee_type = mem_ptr_type->getPointeeType();
2762//
2763// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2764// {
2765// return GetIndexOfChildWithName (ast_context,
2766// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2767// name);
2768// }
2769// }
2770// break;
2771//
Greg Clayton1674b122010-07-21 22:12:05 +00002772 case clang::Type::LValueReference:
2773 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002774 {
2775 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2776 QualType pointee_type = reference_type->getPointeeType();
2777
2778 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2779 {
2780 return GetIndexOfChildMemberWithName (ast_context,
2781 reference_type->getPointeeType().getAsOpaquePtr(),
2782 name,
2783 omit_empty_base_classes,
2784 child_indexes);
2785 }
2786 }
2787 break;
2788
Greg Clayton1674b122010-07-21 22:12:05 +00002789 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002790 {
2791 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2792 QualType pointee_type = pointer_type->getPointeeType();
2793
2794 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2795 {
2796 return GetIndexOfChildMemberWithName (ast_context,
2797 pointer_type->getPointeeType().getAsOpaquePtr(),
2798 name,
2799 omit_empty_base_classes,
2800 child_indexes);
2801 }
2802 else
2803 {
2804// if (parent_name)
2805// {
2806// child_name.assign(1, '*');
2807// child_name += parent_name;
2808// }
2809//
2810// // We have a pointer to an simple type
2811// if (idx == 0)
2812// {
2813// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2814// assert(clang_type_info.first % 8 == 0);
2815// child_byte_size = clang_type_info.first / 8;
2816// child_byte_offset = 0;
2817// return pointee_type.getAsOpaquePtr();
2818// }
2819 }
2820 }
2821 break;
2822
Greg Clayton1674b122010-07-21 22:12:05 +00002823 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002824 return GetIndexOfChildMemberWithName (ast_context,
2825 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2826 name,
2827 omit_empty_base_classes,
2828 child_indexes);
2829
2830 default:
2831 break;
2832 }
2833 }
2834 return 0;
2835}
2836
2837
2838// Get the index of the child of "clang_type" whose name matches. This function
2839// doesn't descend into the children, but only looks one level deep and name
2840// matches can include base class names.
2841
2842uint32_t
2843ClangASTContext::GetIndexOfChildWithName
2844(
2845 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002846 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002847 const char *name,
2848 bool omit_empty_base_classes
2849)
2850{
2851 if (clang_type && name && name[0])
2852 {
2853 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002854
Greg Clayton03e0f972010-09-13 03:32:57 +00002855 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002856
Greg Clayton03e0f972010-09-13 03:32:57 +00002857 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002858 {
Greg Clayton1674b122010-07-21 22:12:05 +00002859 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002860 {
2861 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2862 const RecordDecl *record_decl = record_type->getDecl();
2863
2864 assert(record_decl);
2865 uint32_t child_idx = 0;
2866
2867 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2868
2869 if (cxx_record_decl)
2870 {
2871 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2872 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2873 base_class != base_class_end;
2874 ++base_class)
2875 {
2876 // Skip empty base classes
2877 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2878 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2879 continue;
2880
2881 if (base_class->getType().getAsString().compare (name) == 0)
2882 return child_idx;
2883 ++child_idx;
2884 }
2885 }
2886
2887 // Try and find a field that matches NAME
2888 RecordDecl::field_iterator field, field_end;
2889 StringRef name_sref(name);
2890 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2891 field != field_end;
2892 ++field, ++child_idx)
2893 {
2894 if (field->getName().equals (name_sref))
2895 return child_idx;
2896 }
2897
2898 }
2899 break;
2900
Greg Clayton9488b742010-07-28 02:04:09 +00002901 case clang::Type::ObjCObject:
2902 case clang::Type::ObjCInterface:
2903 {
2904 StringRef name_sref(name);
2905 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2906 assert (objc_class_type);
2907 if (objc_class_type)
2908 {
2909 uint32_t child_idx = 0;
2910 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2911
2912 if (class_interface_decl)
2913 {
2914 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2915 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2916
2917 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2918 {
2919 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2920
2921 if (ivar_decl->getName().equals (name_sref))
2922 {
2923 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2924 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2925 ++child_idx;
2926
2927 return child_idx;
2928 }
2929 }
2930
2931 if (superclass_interface_decl)
2932 {
2933 if (superclass_interface_decl->getName().equals (name_sref))
2934 return 0;
2935 }
2936 }
2937 }
2938 }
2939 break;
2940
2941 case clang::Type::ObjCObjectPointer:
2942 {
2943 return GetIndexOfChildWithName (ast_context,
2944 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2945 name,
2946 omit_empty_base_classes);
2947 }
2948 break;
2949
Greg Clayton1674b122010-07-21 22:12:05 +00002950 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002951 {
2952// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2953// const uint64_t element_count = array->getSize().getLimitedValue();
2954//
2955// if (idx < element_count)
2956// {
2957// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2958//
2959// char element_name[32];
2960// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2961//
2962// child_name.assign(element_name);
2963// assert(field_type_info.first % 8 == 0);
2964// child_byte_size = field_type_info.first / 8;
2965// child_byte_offset = idx * child_byte_size;
2966// return array->getElementType().getAsOpaquePtr();
2967// }
2968 }
2969 break;
2970
Greg Clayton1674b122010-07-21 22:12:05 +00002971// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002972// {
2973// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2974// QualType pointee_type = mem_ptr_type->getPointeeType();
2975//
2976// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2977// {
2978// return GetIndexOfChildWithName (ast_context,
2979// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2980// name);
2981// }
2982// }
2983// break;
2984//
Greg Clayton1674b122010-07-21 22:12:05 +00002985 case clang::Type::LValueReference:
2986 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002987 {
2988 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2989 QualType pointee_type = reference_type->getPointeeType();
2990
2991 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2992 {
2993 return GetIndexOfChildWithName (ast_context,
2994 reference_type->getPointeeType().getAsOpaquePtr(),
2995 name,
2996 omit_empty_base_classes);
2997 }
2998 }
2999 break;
3000
Greg Clayton1674b122010-07-21 22:12:05 +00003001 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003002 {
3003 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3004 QualType pointee_type = pointer_type->getPointeeType();
3005
3006 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3007 {
3008 return GetIndexOfChildWithName (ast_context,
3009 pointer_type->getPointeeType().getAsOpaquePtr(),
3010 name,
3011 omit_empty_base_classes);
3012 }
3013 else
3014 {
3015// if (parent_name)
3016// {
3017// child_name.assign(1, '*');
3018// child_name += parent_name;
3019// }
3020//
3021// // We have a pointer to an simple type
3022// if (idx == 0)
3023// {
3024// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3025// assert(clang_type_info.first % 8 == 0);
3026// child_byte_size = clang_type_info.first / 8;
3027// child_byte_offset = 0;
3028// return pointee_type.getAsOpaquePtr();
3029// }
3030 }
3031 }
3032 break;
3033
Greg Clayton1674b122010-07-21 22:12:05 +00003034 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003035 return GetIndexOfChildWithName (ast_context,
3036 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3037 name,
3038 omit_empty_base_classes);
3039
3040 default:
3041 break;
3042 }
3043 }
3044 return UINT32_MAX;
3045}
3046
3047#pragma mark TagType
3048
3049bool
Greg Clayton462d4142010-09-29 01:12:09 +00003050ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003051{
3052 if (tag_clang_type)
3053 {
3054 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003055 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003056 if (clang_type)
3057 {
3058 TagType *tag_type = dyn_cast<TagType>(clang_type);
3059 if (tag_type)
3060 {
3061 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3062 if (tag_decl)
3063 {
3064 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3065 return true;
3066 }
3067 }
3068 }
3069 }
3070 return false;
3071}
3072
3073
3074#pragma mark DeclContext Functions
3075
3076DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003077ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003078{
3079 if (clang_type == NULL)
3080 return NULL;
3081
3082 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003083 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3084 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003085 {
Greg Clayton9488b742010-07-28 02:04:09 +00003086 case clang::Type::FunctionNoProto: break;
3087 case clang::Type::FunctionProto: break;
3088 case clang::Type::IncompleteArray: break;
3089 case clang::Type::VariableArray: break;
3090 case clang::Type::ConstantArray: break;
3091 case clang::Type::ExtVector: break;
3092 case clang::Type::Vector: break;
3093 case clang::Type::Builtin: break;
3094 case clang::Type::BlockPointer: break;
3095 case clang::Type::Pointer: break;
3096 case clang::Type::LValueReference: break;
3097 case clang::Type::RValueReference: break;
3098 case clang::Type::MemberPointer: break;
3099 case clang::Type::Complex: break;
3100 case clang::Type::ObjCObject: break;
3101 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3102 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3103 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3104 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
3105 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003106
Greg Clayton9488b742010-07-28 02:04:09 +00003107 case clang::Type::TypeOfExpr: break;
3108 case clang::Type::TypeOf: break;
3109 case clang::Type::Decltype: break;
3110 //case clang::Type::QualifiedName: break;
3111 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003112 }
3113 // No DeclContext in this type...
3114 return NULL;
3115}
3116
3117#pragma mark Namespace Declarations
3118
3119NamespaceDecl *
3120ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3121{
3122 // TODO: Do something intelligent with the Declaration object passed in
3123 // like maybe filling in the SourceLocation with it...
3124 if (name)
3125 {
3126 ASTContext *ast_context = getASTContext();
3127 if (decl_ctx == NULL)
3128 decl_ctx = ast_context->getTranslationUnitDecl();
3129 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3130 }
3131 return NULL;
3132}
3133
3134
3135#pragma mark Function Types
3136
3137FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003138ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003139{
3140 if (name)
3141 {
3142 ASTContext *ast_context = getASTContext();
3143 assert (ast_context != NULL);
3144
3145 if (name && name[0])
3146 {
3147 return FunctionDecl::Create(*ast_context,
3148 ast_context->getTranslationUnitDecl(),
3149 SourceLocation(),
3150 DeclarationName (&ast_context->Idents.get(name)),
3151 QualType::getFromOpaquePtr(function_clang_type),
3152 NULL,
3153 (FunctionDecl::StorageClass)storage,
3154 (FunctionDecl::StorageClass)storage,
3155 is_inline);
3156 }
3157 else
3158 {
3159 return FunctionDecl::Create(*ast_context,
3160 ast_context->getTranslationUnitDecl(),
3161 SourceLocation(),
3162 DeclarationName (),
3163 QualType::getFromOpaquePtr(function_clang_type),
3164 NULL,
3165 (FunctionDecl::StorageClass)storage,
3166 (FunctionDecl::StorageClass)storage,
3167 is_inline);
3168 }
3169 }
3170 return NULL;
3171}
3172
Greg Clayton462d4142010-09-29 01:12:09 +00003173clang_type_t
3174ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3175 clang_type_t result_type,
3176 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003177 unsigned num_args,
3178 bool is_variadic,
3179 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003180{
Chris Lattner24943d22010-06-08 16:52:24 +00003181 assert (ast_context != NULL);
3182 std::vector<QualType> qual_type_args;
3183 for (unsigned i=0; i<num_args; ++i)
3184 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3185
3186 // TODO: Detect calling convention in DWARF?
3187 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003188 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003189 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003190 is_variadic,
3191 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003192 false, // hasExceptionSpec
3193 false, // hasAnyExceptionSpec,
3194 0, // NumExs
3195 0, // const QualType *ExArray
3196 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3197}
3198
3199ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003200ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003201{
3202 ASTContext *ast_context = getASTContext();
3203 assert (ast_context != NULL);
3204 return ParmVarDecl::Create(*ast_context,
3205 ast_context->getTranslationUnitDecl(),
3206 SourceLocation(),
3207 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003208 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003209 NULL,
3210 (VarDecl::StorageClass)storage,
3211 (VarDecl::StorageClass)storage,
3212 0);
3213}
3214
3215void
3216ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3217{
3218 if (function_decl)
3219 function_decl->setParams (params, num_params);
3220}
3221
3222
3223#pragma mark Array Types
3224
Greg Clayton462d4142010-09-29 01:12:09 +00003225clang_type_t
3226ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003227{
3228 if (element_type)
3229 {
3230 ASTContext *ast_context = getASTContext();
3231 assert (ast_context != NULL);
3232 llvm::APInt ap_element_count (64, element_count);
3233 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3234 ap_element_count,
3235 ArrayType::Normal,
3236 0).getAsOpaquePtr(); // ElemQuals
3237 }
3238 return NULL;
3239}
3240
3241
3242#pragma mark TagDecl
3243
3244bool
Greg Clayton462d4142010-09-29 01:12:09 +00003245ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003246{
3247 if (clang_type)
3248 {
3249 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003250 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003251 if (t)
3252 {
3253 TagType *tag_type = dyn_cast<TagType>(t);
3254 if (tag_type)
3255 {
3256 TagDecl *tag_decl = tag_type->getDecl();
3257 if (tag_decl)
3258 {
3259 tag_decl->startDefinition();
3260 return true;
3261 }
3262 }
3263 }
3264 }
3265 return false;
3266}
3267
3268bool
Greg Clayton462d4142010-09-29 01:12:09 +00003269ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003270{
3271 if (clang_type)
3272 {
3273 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00003274
3275 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3276
3277 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003278 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003279 cxx_record_decl->completeDefinition();
3280
3281 return true;
3282 }
3283
Sean Callanan04325062010-10-25 00:29:48 +00003284 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3285
3286 if (objc_class_type)
3287 {
3288 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3289
3290 class_interface_decl->setForwardDecl(false);
3291 }
3292
Greg Clayton55b6c532010-09-29 03:44:17 +00003293 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3294
3295 if (enum_type)
3296 {
3297 EnumDecl *enum_decl = enum_type->getDecl();
3298
3299 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003300 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003301 /// TODO This really needs to be fixed.
3302
3303 unsigned NumPositiveBits = 1;
3304 unsigned NumNegativeBits = 0;
3305
Greg Clayton48fbdf72010-10-12 04:29:14 +00003306 ASTContext *ast_context = getASTContext();
3307
3308 QualType promotion_qual_type;
3309 // If the enum integer type is less than an integer in bit width,
3310 // then we must promote it to an integer size.
3311 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3312 {
3313 if (enum_decl->getIntegerType()->isSignedIntegerType())
3314 promotion_qual_type = ast_context->IntTy;
3315 else
3316 promotion_qual_type = ast_context->UnsignedIntTy;
3317 }
3318 else
3319 promotion_qual_type = enum_decl->getIntegerType();
3320
3321 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003322 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003323 }
3324 }
3325 }
3326 return false;
3327}
3328
3329
3330#pragma mark Enumeration Types
3331
Greg Clayton462d4142010-09-29 01:12:09 +00003332clang_type_t
3333ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003334{
3335 // TODO: Do something intelligent with the Declaration object passed in
3336 // like maybe filling in the SourceLocation with it...
3337 ASTContext *ast_context = getASTContext();
3338 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003339
3340 // TODO: ask about these...
3341// const bool IsScoped = false;
3342// const bool IsFixed = false;
3343
3344 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3345 ast_context->getTranslationUnitDecl(),
3346 SourceLocation(),
3347 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3348 SourceLocation(),
3349 NULL); //IsScoped, IsFixed);
Chris Lattner24943d22010-06-08 16:52:24 +00003350 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003351 {
3352 // TODO: check if we should be setting the promotion type too?
3353 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003354 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003355 }
Chris Lattner24943d22010-06-08 16:52:24 +00003356 return NULL;
3357}
3358
Greg Clayton462d4142010-09-29 01:12:09 +00003359clang_type_t
3360ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3361{
3362 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3363
3364 clang::Type *clang_type = enum_qual_type.getTypePtr();
3365 if (clang_type)
3366 {
3367 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3368 if (enum_type)
3369 {
3370 EnumDecl *enum_decl = enum_type->getDecl();
3371 if (enum_decl)
3372 return enum_decl->getIntegerType().getAsOpaquePtr();
3373 }
3374 }
3375 return NULL;
3376}
Chris Lattner24943d22010-06-08 16:52:24 +00003377bool
3378ClangASTContext::AddEnumerationValueToEnumerationType
3379(
Greg Clayton462d4142010-09-29 01:12:09 +00003380 clang_type_t enum_clang_type,
3381 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003382 const Declaration &decl,
3383 const char *name,
3384 int64_t enum_value,
3385 uint32_t enum_value_bit_size
3386)
3387{
3388 if (enum_clang_type && enumerator_clang_type && name)
3389 {
3390 // TODO: Do something intelligent with the Declaration object passed in
3391 // like maybe filling in the SourceLocation with it...
3392 ASTContext *ast_context = getASTContext();
3393 IdentifierTable *identifier_table = getIdentifierTable();
3394
3395 assert (ast_context != NULL);
3396 assert (identifier_table != NULL);
3397 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3398
Greg Clayton1674b122010-07-21 22:12:05 +00003399 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003400 if (clang_type)
3401 {
3402 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3403
3404 if (enum_type)
3405 {
3406 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3407 enum_llvm_apsint = enum_value;
3408 EnumConstantDecl *enumerator_decl =
3409 EnumConstantDecl::Create(*ast_context,
3410 enum_type->getDecl(),
3411 SourceLocation(),
3412 name ? &identifier_table->get(name) : NULL, // Identifier
3413 QualType::getFromOpaquePtr(enumerator_clang_type),
3414 NULL,
3415 enum_llvm_apsint);
3416
3417 if (enumerator_decl)
3418 {
3419 enum_type->getDecl()->addDecl(enumerator_decl);
3420 return true;
3421 }
3422 }
3423 }
3424 }
3425 return false;
3426}
3427
3428#pragma mark Pointers & References
3429
Greg Clayton462d4142010-09-29 01:12:09 +00003430clang_type_t
3431ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003432{
3433 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003434 {
3435 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3436
Greg Clayton03e0f972010-09-13 03:32:57 +00003437 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3438 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003439 {
3440 case clang::Type::ObjCObject:
3441 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003442 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3443
Greg Clayton7b541032010-07-29 20:06:32 +00003444 default:
3445 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3446 }
3447 }
Chris Lattner24943d22010-06-08 16:52:24 +00003448 return NULL;
3449}
3450
Greg Clayton462d4142010-09-29 01:12:09 +00003451clang_type_t
3452ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003453{
3454 if (clang_type)
3455 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3456 return NULL;
3457}
3458
Greg Clayton462d4142010-09-29 01:12:09 +00003459clang_type_t
3460ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003461{
3462 if (clang_type)
3463 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3464 return NULL;
3465}
3466
Greg Clayton462d4142010-09-29 01:12:09 +00003467clang_type_t
3468ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003469{
3470 if (clang_pointee_type && clang_pointee_type)
3471 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3472 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3473 return NULL;
3474}
3475
Chris Lattner24943d22010-06-08 16:52:24 +00003476size_t
3477ClangASTContext::GetPointerBitSize ()
3478{
3479 ASTContext *ast_context = getASTContext();
3480 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3481}
3482
3483bool
Greg Clayton462d4142010-09-29 01:12:09 +00003484ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003485{
3486 if (clang_type == NULL)
3487 return false;
3488
3489 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003490 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3491 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003492 {
Sean Callanan04325062010-10-25 00:29:48 +00003493 case clang::Type::Builtin:
3494 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3495 {
3496 default:
3497 break;
3498 case clang::BuiltinType::ObjCId:
3499 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003500 return true;
3501 }
3502 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003503 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003504 if (target_type)
3505 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3506 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003507 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003508 if (target_type)
3509 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3510 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003511 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003512 if (target_type)
3513 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3514 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003515 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003516 if (target_type)
3517 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3518 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003519 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003520 if (target_type)
3521 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3522 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003523 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003524 if (target_type)
3525 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3526 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003527 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003528 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3529 default:
3530 break;
3531 }
3532 return false;
3533}
3534
Chris Lattner24943d22010-06-08 16:52:24 +00003535bool
Greg Clayton462d4142010-09-29 01:12:09 +00003536ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003537{
3538 if (!clang_type)
3539 return false;
3540
3541 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3542 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3543
3544 if (builtin_type)
3545 {
3546 if (builtin_type->isInteger())
3547 is_signed = builtin_type->isSignedInteger();
3548
3549 return true;
3550 }
3551
3552 return false;
3553}
3554
3555bool
Greg Clayton462d4142010-09-29 01:12:09 +00003556ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003557{
3558 if (clang_type)
3559 {
3560 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003561 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3562 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003563 {
Sean Callanan04325062010-10-25 00:29:48 +00003564 case clang::Type::Builtin:
3565 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3566 {
3567 default:
3568 break;
3569 case clang::BuiltinType::ObjCId:
3570 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003571 return true;
3572 }
3573 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003574 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003575 if (target_type)
3576 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3577 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003578 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003579 if (target_type)
3580 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3581 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003582 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003583 if (target_type)
3584 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3585 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003586 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003587 if (target_type)
3588 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3589 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003590 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003591 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3592 default:
3593 break;
3594 }
3595 }
3596 return false;
3597}
3598
3599bool
Greg Clayton462d4142010-09-29 01:12:09 +00003600ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003601{
3602 if (clang_type)
3603 {
3604 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3605
3606 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3607 {
3608 clang::BuiltinType::Kind kind = BT->getKind();
3609 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3610 {
3611 count = 1;
3612 is_complex = false;
3613 return true;
3614 }
3615 }
3616 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3617 {
3618 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3619 {
3620 count = 2;
3621 is_complex = true;
3622 return true;
3623 }
3624 }
3625 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3626 {
3627 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3628 {
3629 count = VT->getNumElements();
3630 is_complex = false;
3631 return true;
3632 }
3633 }
3634 }
3635 return false;
3636}
3637
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003638
3639bool
3640ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3641{
3642 if (clang_type)
3643 {
3644 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3645
3646 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3647 if (cxx_record_decl)
3648 {
3649 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3650 return true;
3651 }
3652 }
3653 class_name.clear();
3654 return false;
3655}
3656
3657
Greg Clayton1d8173f2010-09-24 05:15:53 +00003658bool
Greg Clayton462d4142010-09-29 01:12:09 +00003659ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003660{
3661 if (clang_type)
3662 {
3663 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3664 if (qual_type->getAsCXXRecordDecl() != NULL)
3665 return true;
3666 }
3667 return false;
3668}
3669
3670bool
Greg Clayton462d4142010-09-29 01:12:09 +00003671ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003672{
3673 if (clang_type)
3674 {
3675 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3676 if (qual_type->isObjCObjectOrInterfaceType())
3677 return true;
3678 }
3679 return false;
3680}
3681
3682
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003683bool
3684ClangASTContext::IsCharType (clang_type_t clang_type)
3685{
3686 if (clang_type)
3687 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3688 return false;
3689}
Chris Lattner24943d22010-06-08 16:52:24 +00003690
3691bool
Greg Clayton462d4142010-09-29 01:12:09 +00003692ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003693{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003694 clang_type_t pointee_or_element_clang_type = NULL;
3695 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3696
3697 if (pointee_or_element_clang_type == NULL)
3698 return false;
3699
3700 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003701 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003702 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3703
3704 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003705 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003706 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3707 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003708 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003709 // We know the size of the array and it could be a C string
3710 // since it is an array of characters
3711 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3712 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003713 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003714 else
Chris Lattner24943d22010-06-08 16:52:24 +00003715 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003716 length = 0;
3717 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003718 }
Chris Lattner24943d22010-06-08 16:52:24 +00003719
Chris Lattner24943d22010-06-08 16:52:24 +00003720 }
3721 }
3722 return false;
3723}
3724
3725bool
Greg Clayton462d4142010-09-29 01:12:09 +00003726ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003727{
3728 if (clang_type)
3729 {
3730 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3731
3732 if (qual_type->isFunctionPointerType())
3733 return true;
3734
3735 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3736 switch (type_class)
3737 {
3738 case clang::Type::Typedef:
3739 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3740
3741 case clang::Type::LValueReference:
3742 case clang::Type::RValueReference:
3743 {
3744 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3745 if (reference_type)
3746 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3747 }
3748 break;
3749 }
3750 }
3751 return false;
3752}
3753
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003754size_t
3755ClangASTContext::GetArraySize (clang_type_t clang_type)
3756{
3757 if (clang_type)
3758 {
3759 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3760 if (array)
3761 return array->getSize().getLimitedValue();
3762 }
3763 return 0;
3764}
Greg Clayton03e0f972010-09-13 03:32:57 +00003765
3766bool
Greg Clayton462d4142010-09-29 01:12:09 +00003767ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003768{
3769 if (!clang_type)
3770 return false;
3771
3772 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3773
Greg Clayton03e0f972010-09-13 03:32:57 +00003774 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3775 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003776 {
Greg Clayton1674b122010-07-21 22:12:05 +00003777 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003778 if (member_type)
3779 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3780 if (size)
3781 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3782 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003783 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003784 if (member_type)
3785 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3786 if (size)
3787 *size = 0;
3788 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003789 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003790 if (member_type)
3791 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3792 if (size)
3793 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003794 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003795 if (member_type)
3796 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3797 if (size)
3798 *size = 0;
3799 return true;
3800 }
3801 return false;
3802}
3803
3804
3805#pragma mark Typedefs
3806
Greg Clayton462d4142010-09-29 01:12:09 +00003807clang_type_t
3808ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003809{
3810 if (clang_type)
3811 {
3812 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3813 ASTContext *ast_context = getASTContext();
3814 IdentifierTable *identifier_table = getIdentifierTable();
3815 assert (ast_context != NULL);
3816 assert (identifier_table != NULL);
3817 if (decl_ctx == NULL)
3818 decl_ctx = ast_context->getTranslationUnitDecl();
3819 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3820 decl_ctx,
3821 SourceLocation(),
3822 name ? &identifier_table->get(name) : NULL, // Identifier
3823 ast_context->CreateTypeSourceInfo(qual_type));
3824
3825 // Get a uniqued QualType for the typedef decl type
3826 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3827 }
3828 return NULL;
3829}
3830
3831
3832std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003833ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003834{
3835 std::string return_name;
3836
Greg Clayton462d4142010-09-29 01:12:09 +00003837 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003838
Greg Clayton462d4142010-09-29 01:12:09 +00003839 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003840 if (typedef_type)
3841 {
Greg Clayton462d4142010-09-29 01:12:09 +00003842 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003843 return_name = typedef_decl->getQualifiedNameAsString();
3844 }
3845 else
3846 {
3847 return_name = qual_type.getAsString();
3848 }
3849
3850 return return_name;
3851}
3852
3853// Disable this for now since I can't seem to get a nicely formatted float
3854// out of the APFloat class without just getting the float, double or quad
3855// and then using a formatted print on it which defeats the purpose. We ideally
3856// would like to get perfect string values for any kind of float semantics
3857// so we can support remote targets. The code below also requires a patch to
3858// llvm::APInt.
3859//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003860//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 +00003861//{
3862// uint32_t count = 0;
3863// bool is_complex = false;
3864// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3865// {
3866// unsigned num_bytes_per_float = byte_size / count;
3867// unsigned num_bits_per_float = num_bytes_per_float * 8;
3868//
3869// float_str.clear();
3870// uint32_t i;
3871// for (i=0; i<count; i++)
3872// {
3873// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3874// bool is_ieee = false;
3875// APFloat ap_float(ap_int, is_ieee);
3876// char s[1024];
3877// unsigned int hex_digits = 0;
3878// bool upper_case = false;
3879//
3880// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3881// {
3882// if (i > 0)
3883// float_str.append(", ");
3884// float_str.append(s);
3885// if (i == 1 && is_complex)
3886// float_str.append(1, 'i');
3887// }
3888// }
3889// return !float_str.empty();
3890// }
3891// return false;
3892//}
3893
3894size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003895ClangASTContext::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 +00003896{
3897 if (clang_type)
3898 {
3899 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3900 uint32_t count = 0;
3901 bool is_complex = false;
3902 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3903 {
3904 // TODO: handle complex and vector types
3905 if (count != 1)
3906 return false;
3907
3908 StringRef s_sref(s);
3909 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3910
3911 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3912 const uint64_t byte_size = bit_size / 8;
3913 if (dst_size >= byte_size)
3914 {
3915 if (bit_size == sizeof(float)*8)
3916 {
3917 float float32 = ap_float.convertToFloat();
3918 ::memcpy (dst, &float32, byte_size);
3919 return byte_size;
3920 }
3921 else if (bit_size >= 64)
3922 {
3923 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3924 ::memcpy (dst, ap_int.getRawData(), byte_size);
3925 return byte_size;
3926 }
3927 }
3928 }
3929 }
3930 return 0;
3931}
Sean Callanana751f7b2010-09-17 02:24:29 +00003932
3933unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00003934ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00003935{
3936 assert (clang_type);
3937
3938 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3939
3940 return qual_type.getQualifiers().getCVRQualifiers();
3941}