blob: c5d1cc611368569f3fb18f21190ae7212142f2d6 [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"
Chris Lattner24943d22010-06-08 16:52:24 +000035
Eli Friedmanf05633b2010-06-13 19:06:42 +000036#include <stdio.h>
37
Greg Clayton585660c2010-08-05 01:57:25 +000038using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000039using namespace lldb_private;
40using namespace llvm;
41using namespace clang;
42
Greg Clayton84f80752010-07-22 18:30:50 +000043static AccessSpecifier
Greg Clayton585660c2010-08-05 01:57:25 +000044ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000045{
46 switch (access)
47 {
Greg Clayton585660c2010-08-05 01:57:25 +000048 default: break;
49 case eAccessNone: return AS_none;
50 case eAccessPublic: return AS_public;
51 case eAccessPrivate: return AS_private;
52 case eAccessProtected: return AS_protected;
Greg Clayton84f80752010-07-22 18:30:50 +000053 }
54 return AS_none;
55}
56
57static ObjCIvarDecl::AccessControl
Greg Clayton585660c2010-08-05 01:57:25 +000058ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000059{
60 switch (access)
61 {
Greg Clayton585660c2010-08-05 01:57:25 +000062 default: break;
63 case eAccessNone: return ObjCIvarDecl::None;
64 case eAccessPublic: return ObjCIvarDecl::Public;
65 case eAccessPrivate: return ObjCIvarDecl::Private;
66 case eAccessProtected: return ObjCIvarDecl::Protected;
67 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton84f80752010-07-22 18:30:50 +000068 }
69 return ObjCIvarDecl::None;
70}
71
72
Chris Lattner24943d22010-06-08 16:52:24 +000073static void
74ParseLangArgs
75(
76 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000077 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000078)
79{
80 // FIXME: Cleanup per-file based stuff.
81
82 // Set some properties which depend soley on the input kind; it would be nice
83 // to move these to the language standard, and have the driver resolve the
84 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000085 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000086 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000087 } else if (IK == IK_ObjC ||
88 IK == IK_ObjCXX ||
89 IK == IK_PreprocessedObjC ||
90 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000091 Opts.ObjC1 = Opts.ObjC2 = 1;
92 }
93
94 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
95
96 if (LangStd == LangStandard::lang_unspecified) {
97 // Based on the base language, pick one.
98 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +000099 case IK_None:
100 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +0000101 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +0000102 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +0000103 LangStd = LangStandard::lang_opencl;
104 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000105 case IK_Asm:
106 case IK_C:
107 case IK_PreprocessedC:
108 case IK_ObjC:
109 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +0000110 LangStd = LangStandard::lang_gnu99;
111 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000112 case IK_CXX:
113 case IK_PreprocessedCXX:
114 case IK_ObjCXX:
115 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +0000116 LangStd = LangStandard::lang_gnucxx98;
117 break;
118 }
119 }
120
121 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
122 Opts.BCPLComment = Std.hasBCPLComments();
123 Opts.C99 = Std.isC99();
124 Opts.CPlusPlus = Std.isCPlusPlus();
125 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
126 Opts.Digraphs = Std.hasDigraphs();
127 Opts.GNUMode = Std.isGNUMode();
128 Opts.GNUInline = !Std.isC99();
129 Opts.HexFloats = Std.hasHexFloats();
130 Opts.ImplicitInt = Std.hasImplicitInt();
131
132 // OpenCL has some additional defaults.
133 if (LangStd == LangStandard::lang_opencl) {
134 Opts.OpenCL = 1;
135 Opts.AltiVec = 1;
136 Opts.CXXOperatorNames = 1;
137 Opts.LaxVectorConversions = 1;
138 }
139
140 // OpenCL and C++ both have bool, true, false keywords.
141 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
142
143// if (Opts.CPlusPlus)
144// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
145//
146// if (Args.hasArg(OPT_fobjc_gc_only))
147// Opts.setGCMode(LangOptions::GCOnly);
148// else if (Args.hasArg(OPT_fobjc_gc))
149// Opts.setGCMode(LangOptions::HybridGC);
150//
151// if (Args.hasArg(OPT_print_ivar_layout))
152// Opts.ObjCGCBitmapPrint = 1;
153//
154// if (Args.hasArg(OPT_faltivec))
155// Opts.AltiVec = 1;
156//
157// if (Args.hasArg(OPT_pthread))
158// Opts.POSIXThreads = 1;
159//
160// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
161// "default");
162// if (Vis == "default")
163 Opts.setVisibilityMode(LangOptions::Default);
164// else if (Vis == "hidden")
165// Opts.setVisibilityMode(LangOptions::Hidden);
166// else if (Vis == "protected")
167// Opts.setVisibilityMode(LangOptions::Protected);
168// else
169// Diags.Report(diag::err_drv_invalid_value)
170// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
171
172// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
173
174 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
175 // is specified, or -std is set to a conforming mode.
176 Opts.Trigraphs = !Opts.GNUMode;
177// if (Args.hasArg(OPT_trigraphs))
178// Opts.Trigraphs = 1;
179//
180// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
181// OPT_fno_dollars_in_identifiers,
182// !Opts.AsmPreprocessor);
183// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
184// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
185// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
186// if (Args.hasArg(OPT_fno_lax_vector_conversions))
187// Opts.LaxVectorConversions = 0;
188// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
189// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
190// Opts.Blocks = Args.hasArg(OPT_fblocks);
191// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
192// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
193// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
194// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
195// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
196// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
197// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
198// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
199// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
200// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
201// Diags);
202// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
203// Opts.ObjCConstantStringClass = getLastArgValue(Args,
204// OPT_fconstant_string_class);
205// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
206// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
207// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
208// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
209// Opts.Static = Args.hasArg(OPT_static_define);
210 Opts.OptimizeSize = 0;
211
212 // FIXME: Eliminate this dependency.
213// unsigned Opt =
214// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
215// Opts.Optimize = Opt != 0;
216 unsigned Opt = 0;
217
218 // This is the __NO_INLINE__ define, which just depends on things like the
219 // optimization level and -fno-inline, not actually whether the backend has
220 // inlining enabled.
221 //
222 // FIXME: This is affected by other options (-fno-inline).
223 Opts.NoInline = !Opt;
224
225// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
226// switch (SSP) {
227// default:
228// Diags.Report(diag::err_drv_invalid_value)
229// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
230// break;
231// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
232// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
233// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
234// }
235}
236
Chris Lattner24943d22010-06-08 16:52:24 +0000237
Chris Lattner24943d22010-06-08 16:52:24 +0000238ClangASTContext::ClangASTContext(const char *target_triple) :
239 m_target_triple(),
240 m_ast_context_ap(),
241 m_language_options_ap(),
242 m_source_manager_ap(),
243 m_diagnostic_ap(),
244 m_target_options_ap(),
245 m_target_info_ap(),
246 m_identifier_table_ap(),
247 m_selector_table_ap(),
248 m_builtins_ap()
249{
250 if (target_triple && target_triple[0])
251 m_target_triple.assign (target_triple);
252}
253
254//----------------------------------------------------------------------
255// Destructor
256//----------------------------------------------------------------------
257ClangASTContext::~ClangASTContext()
258{
259 m_builtins_ap.reset();
260 m_selector_table_ap.reset();
261 m_identifier_table_ap.reset();
262 m_target_info_ap.reset();
263 m_target_options_ap.reset();
264 m_diagnostic_ap.reset();
265 m_source_manager_ap.reset();
266 m_language_options_ap.reset();
267 m_ast_context_ap.reset();
268}
269
270
271void
272ClangASTContext::Clear()
273{
274 m_ast_context_ap.reset();
275 m_language_options_ap.reset();
276 m_source_manager_ap.reset();
277 m_diagnostic_ap.reset();
278 m_target_options_ap.reset();
279 m_target_info_ap.reset();
280 m_identifier_table_ap.reset();
281 m_selector_table_ap.reset();
282 m_builtins_ap.reset();
283}
284
285const char *
286ClangASTContext::GetTargetTriple ()
287{
288 return m_target_triple.c_str();
289}
290
291void
292ClangASTContext::SetTargetTriple (const char *target_triple)
293{
294 Clear();
295 m_target_triple.assign(target_triple);
296}
297
298
299ASTContext *
300ClangASTContext::getASTContext()
301{
302 if (m_ast_context_ap.get() == NULL)
303 {
304 m_ast_context_ap.reset(
305 new ASTContext(
306 *getLanguageOptions(),
307 *getSourceManager(),
308 *getTargetInfo(),
309 *getIdentifierTable(),
310 *getSelectorTable(),
Greg Clayton6e713402010-07-30 20:30:44 +0000311 *getBuiltinContext(),
312 0));
Chris Lattner24943d22010-06-08 16:52:24 +0000313 }
314 return m_ast_context_ap.get();
315}
316
317Builtin::Context *
318ClangASTContext::getBuiltinContext()
319{
320 if (m_builtins_ap.get() == NULL)
321 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
322 return m_builtins_ap.get();
323}
324
325IdentifierTable *
326ClangASTContext::getIdentifierTable()
327{
328 if (m_identifier_table_ap.get() == NULL)
329 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
330 return m_identifier_table_ap.get();
331}
332
333LangOptions *
334ClangASTContext::getLanguageOptions()
335{
336 if (m_language_options_ap.get() == NULL)
337 {
338 m_language_options_ap.reset(new LangOptions());
Greg Claytone41c4b22010-06-13 17:34:29 +0000339 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
340// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner24943d22010-06-08 16:52:24 +0000341 }
342 return m_language_options_ap.get();
343}
344
345SelectorTable *
346ClangASTContext::getSelectorTable()
347{
348 if (m_selector_table_ap.get() == NULL)
349 m_selector_table_ap.reset (new SelectorTable());
350 return m_selector_table_ap.get();
351}
352
Greg Clayton1674b122010-07-21 22:12:05 +0000353clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000354ClangASTContext::getSourceManager()
355{
356 if (m_source_manager_ap.get() == NULL)
Greg Clayton1674b122010-07-21 22:12:05 +0000357 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic()));
Chris Lattner24943d22010-06-08 16:52:24 +0000358 return m_source_manager_ap.get();
359}
360
361Diagnostic *
362ClangASTContext::getDiagnostic()
363{
364 if (m_diagnostic_ap.get() == NULL)
365 m_diagnostic_ap.reset(new Diagnostic());
366 return m_diagnostic_ap.get();
367}
368
369TargetOptions *
370ClangASTContext::getTargetOptions()
371{
372 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
373 {
374 m_target_options_ap.reset (new TargetOptions());
375 if (m_target_options_ap.get())
376 m_target_options_ap->Triple = m_target_triple;
377 }
378 return m_target_options_ap.get();
379}
380
381
382TargetInfo *
383ClangASTContext::getTargetInfo()
384{
385 // target_triple should be something like "x86_64-apple-darwin10"
386 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
387 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
388 return m_target_info_ap.get();
389}
390
391#pragma mark Basic Types
392
393static inline bool
394QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
395{
396 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
397 if (qual_type_bit_size == bit_size)
398 return true;
399 return false;
400}
401
Greg Clayton462d4142010-09-29 01:12:09 +0000402clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000403ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000404{
405 ASTContext *ast_context = getASTContext();
406
407 assert (ast_context != NULL);
408
409 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
410}
411
Greg Clayton462d4142010-09-29 01:12:09 +0000412clang_type_t
413ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000414{
415 if (!ast_context)
416 return NULL;
417
418 switch (encoding)
419 {
Greg Clayton585660c2010-08-05 01:57:25 +0000420 case eEncodingInvalid:
Chris Lattner24943d22010-06-08 16:52:24 +0000421 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
422 return ast_context->VoidPtrTy.getAsOpaquePtr();
423 break;
424
Greg Clayton585660c2010-08-05 01:57:25 +0000425 case eEncodingUint:
Chris Lattner24943d22010-06-08 16:52:24 +0000426 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
427 return ast_context->UnsignedCharTy.getAsOpaquePtr();
428 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
429 return ast_context->UnsignedShortTy.getAsOpaquePtr();
430 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
431 return ast_context->UnsignedIntTy.getAsOpaquePtr();
432 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
433 return ast_context->UnsignedLongTy.getAsOpaquePtr();
434 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
435 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
436 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
437 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
438 break;
439
Greg Clayton585660c2010-08-05 01:57:25 +0000440 case eEncodingSint:
Chris Lattner24943d22010-06-08 16:52:24 +0000441 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
442 return ast_context->CharTy.getAsOpaquePtr();
443 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
444 return ast_context->ShortTy.getAsOpaquePtr();
445 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
446 return ast_context->IntTy.getAsOpaquePtr();
447 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
448 return ast_context->LongTy.getAsOpaquePtr();
449 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
450 return ast_context->LongLongTy.getAsOpaquePtr();
451 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
452 return ast_context->Int128Ty.getAsOpaquePtr();
453 break;
454
Greg Clayton585660c2010-08-05 01:57:25 +0000455 case eEncodingIEEE754:
Chris Lattner24943d22010-06-08 16:52:24 +0000456 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
457 return ast_context->FloatTy.getAsOpaquePtr();
458 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
459 return ast_context->DoubleTy.getAsOpaquePtr();
460 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
461 return ast_context->LongDoubleTy.getAsOpaquePtr();
462 break;
463
Greg Clayton585660c2010-08-05 01:57:25 +0000464 case eEncodingVector:
Chris Lattner24943d22010-06-08 16:52:24 +0000465 default:
466 break;
467 }
468
469 return NULL;
470}
471
Greg Clayton462d4142010-09-29 01:12:09 +0000472clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000473ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
474{
475 ASTContext *ast_context = getASTContext();
476
477 #define streq(a,b) strcmp(a,b) == 0
478 assert (ast_context != NULL);
479 if (ast_context)
480 {
481 switch (dw_ate)
482 {
483 default:
484 break;
485
486 case DW_ATE_address:
487 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
488 return ast_context->VoidPtrTy.getAsOpaquePtr();
489 break;
490
491 case DW_ATE_boolean:
492 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
493 return ast_context->BoolTy.getAsOpaquePtr();
494 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
495 return ast_context->UnsignedCharTy.getAsOpaquePtr();
496 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
497 return ast_context->UnsignedShortTy.getAsOpaquePtr();
498 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
499 return ast_context->UnsignedIntTy.getAsOpaquePtr();
500 break;
501
502 case DW_ATE_complex_float:
503 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
504 return ast_context->FloatComplexTy.getAsOpaquePtr();
505 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
506 return ast_context->DoubleComplexTy.getAsOpaquePtr();
507 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
508 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
509 break;
510
511 case DW_ATE_float:
512 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
513 return ast_context->FloatTy.getAsOpaquePtr();
514 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
515 return ast_context->DoubleTy.getAsOpaquePtr();
516 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
517 return ast_context->LongDoubleTy.getAsOpaquePtr();
518 break;
519
520 case DW_ATE_signed:
521 if (type_name)
522 {
523 if (streq(type_name, "int") ||
524 streq(type_name, "signed int"))
525 {
526 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
527 return ast_context->IntTy.getAsOpaquePtr();
528 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
529 return ast_context->Int128Ty.getAsOpaquePtr();
530 }
531
532 if (streq(type_name, "long int") ||
533 streq(type_name, "long long int") ||
534 streq(type_name, "signed long long"))
535 {
536 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
537 return ast_context->LongTy.getAsOpaquePtr();
538 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
539 return ast_context->LongLongTy.getAsOpaquePtr();
540 }
541
542 if (streq(type_name, "short") ||
543 streq(type_name, "short int") ||
544 streq(type_name, "signed short") ||
545 streq(type_name, "short signed int"))
546 {
547 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
548 return ast_context->ShortTy.getAsOpaquePtr();
549 }
550
551 if (streq(type_name, "char") ||
552 streq(type_name, "signed char"))
553 {
554 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
555 return ast_context->CharTy.getAsOpaquePtr();
556 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
557 return ast_context->SignedCharTy.getAsOpaquePtr();
558 }
559
560 if (streq(type_name, "wchar_t"))
561 {
562 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
563 return ast_context->WCharTy.getAsOpaquePtr();
564 }
565
566 }
567 // We weren't able to match up a type name, just search by size
568 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
569 return ast_context->CharTy.getAsOpaquePtr();
570 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
571 return ast_context->ShortTy.getAsOpaquePtr();
572 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
573 return ast_context->IntTy.getAsOpaquePtr();
574 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
575 return ast_context->LongTy.getAsOpaquePtr();
576 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
577 return ast_context->LongLongTy.getAsOpaquePtr();
578 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
579 return ast_context->Int128Ty.getAsOpaquePtr();
580 break;
581
582 case DW_ATE_signed_char:
583 if (type_name)
584 {
585 if (streq(type_name, "signed char"))
586 {
587 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
588 return ast_context->SignedCharTy.getAsOpaquePtr();
589 }
590 }
591 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
592 return ast_context->CharTy.getAsOpaquePtr();
593 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
594 return ast_context->SignedCharTy.getAsOpaquePtr();
595 break;
596
597 case DW_ATE_unsigned:
598 if (type_name)
599 {
600 if (streq(type_name, "unsigned int"))
601 {
602 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
603 return ast_context->UnsignedIntTy.getAsOpaquePtr();
604 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
605 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
606 }
607
608 if (streq(type_name, "unsigned int") ||
609 streq(type_name, "long unsigned int") ||
610 streq(type_name, "unsigned long long"))
611 {
612 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
613 return ast_context->UnsignedLongTy.getAsOpaquePtr();
614 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
615 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
616 }
617
618 if (streq(type_name, "unsigned short") ||
619 streq(type_name, "short unsigned int"))
620 {
621 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
622 return ast_context->UnsignedShortTy.getAsOpaquePtr();
623 }
624 if (streq(type_name, "unsigned char"))
625 {
626 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
627 return ast_context->UnsignedCharTy.getAsOpaquePtr();
628 }
629
630 }
631 // We weren't able to match up a type name, just search by size
632 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
633 return ast_context->UnsignedCharTy.getAsOpaquePtr();
634 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
635 return ast_context->UnsignedShortTy.getAsOpaquePtr();
636 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
637 return ast_context->UnsignedIntTy.getAsOpaquePtr();
638 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
639 return ast_context->UnsignedLongTy.getAsOpaquePtr();
640 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
641 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
642 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
643 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
644 break;
645
646 case DW_ATE_unsigned_char:
647 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
648 return ast_context->UnsignedCharTy.getAsOpaquePtr();
649 break;
650
651 case DW_ATE_imaginary_float:
652 break;
653 }
654 }
655 // This assert should fire for anything that we don't catch above so we know
656 // to fix any issues we run into.
657 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
658 return NULL;
659}
660
Greg Clayton462d4142010-09-29 01:12:09 +0000661clang_type_t
662ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
Chris Lattner24943d22010-06-08 16:52:24 +0000663{
Sean Callanana751f7b2010-09-17 02:24:29 +0000664 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000665}
666
Greg Clayton462d4142010-09-29 01:12:09 +0000667clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000668ClangASTContext::GetBuiltInType_objc_id()
669{
Sean Callanan04325062010-10-25 00:29:48 +0000670 return getASTContext()->ObjCBuiltinIdTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000671}
672
Greg Clayton462d4142010-09-29 01:12:09 +0000673clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000674ClangASTContext::GetBuiltInType_objc_Class()
675{
Sean Callanan04325062010-10-25 00:29:48 +0000676 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000677}
678
Greg Clayton462d4142010-09-29 01:12:09 +0000679clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000680ClangASTContext::GetBuiltInType_objc_selector()
681{
Sean Callanan04325062010-10-25 00:29:48 +0000682 return getASTContext()->ObjCBuiltinSelTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000683}
684
Greg Clayton462d4142010-09-29 01:12:09 +0000685clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000686ClangASTContext::GetCStringType (bool is_const)
687{
688 QualType char_type(getASTContext()->CharTy);
689
690 if (is_const)
691 char_type.addConst();
692
693 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
694}
695
Greg Clayton462d4142010-09-29 01:12:09 +0000696clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000697ClangASTContext::GetVoidPtrType (bool is_const)
698{
699 return GetVoidPtrType(getASTContext(), is_const);
700}
701
Greg Clayton462d4142010-09-29 01:12:09 +0000702clang_type_t
703ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
Chris Lattner24943d22010-06-08 16:52:24 +0000704{
705 QualType void_ptr_type(ast_context->VoidPtrTy);
706
707 if (is_const)
708 void_ptr_type.addConst();
709
710 return void_ptr_type.getAsOpaquePtr();
711}
712
Greg Clayton462d4142010-09-29 01:12:09 +0000713clang_type_t
714ClangASTContext::CopyType (ASTContext *dest_context,
715 ASTContext *source_context,
716 clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000717{
718 Diagnostic diagnostics;
719 FileManager file_manager;
720 ASTImporter importer(diagnostics,
721 *dest_context, file_manager,
722 *source_context, file_manager);
723 QualType ret = importer.Import(QualType::getFromOpaquePtr(clang_type));
724 return ret.getAsOpaquePtr();
725}
726
Sean Callanan8d825062010-07-16 00:00:27 +0000727bool
Greg Clayton462d4142010-09-29 01:12:09 +0000728ClangASTContext::AreTypesSame(ASTContext *ast_context,
729 clang_type_t type1,
730 clang_type_t type2)
Sean Callanan5510ddd2010-07-15 22:30:52 +0000731{
732 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
733 QualType::getFromOpaquePtr(type2));
734}
735
Chris Lattner24943d22010-06-08 16:52:24 +0000736#pragma mark CVR modifiers
737
Greg Clayton462d4142010-09-29 01:12:09 +0000738clang_type_t
739ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000740{
741 if (clang_type)
742 {
743 QualType result(QualType::getFromOpaquePtr(clang_type));
744 result.addConst();
745 return result.getAsOpaquePtr();
746 }
747 return NULL;
748}
749
Greg Clayton462d4142010-09-29 01:12:09 +0000750clang_type_t
751ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000752{
753 if (clang_type)
754 {
755 QualType result(QualType::getFromOpaquePtr(clang_type));
756 result.getQualifiers().setRestrict (true);
757 return result.getAsOpaquePtr();
758 }
759 return NULL;
760}
761
Greg Clayton462d4142010-09-29 01:12:09 +0000762clang_type_t
763ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000764{
765 if (clang_type)
766 {
767 QualType result(QualType::getFromOpaquePtr(clang_type));
768 result.getQualifiers().setVolatile (true);
769 return result.getAsOpaquePtr();
770 }
771 return NULL;
772}
773
774#pragma mark Structure, Unions, Classes
775
Greg Clayton462d4142010-09-29 01:12:09 +0000776clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000777ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000778{
779 ASTContext *ast_context = getASTContext();
780 assert (ast_context != NULL);
Sean Callanan04325062010-10-25 00:29:48 +0000781
Chris Lattner24943d22010-06-08 16:52:24 +0000782 if (decl_ctx == NULL)
783 decl_ctx = ast_context->getTranslationUnitDecl();
784
Greg Clayton9488b742010-07-28 02:04:09 +0000785
Greg Clayton585660c2010-08-05 01:57:25 +0000786 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000787 {
Greg Clayton306edca2010-10-11 02:25:34 +0000788 bool isForwardDecl = true;
Greg Clayton9488b742010-07-28 02:04:09 +0000789 bool isInternal = false;
790 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
791 }
792
Chris Lattner24943d22010-06-08 16:52:24 +0000793 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
794 // we will need to update this code. I was told to currently always use
795 // the CXXRecordDecl class since we often don't know from debug information
796 // if something is struct or a class, so we default to always use the more
797 // complete definition just in case.
798 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
799 (TagDecl::TagKind)kind,
800 decl_ctx,
801 SourceLocation(),
802 name && name[0] ? &ast_context->Idents.get(name) : NULL);
803
804 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
805}
806
Greg Claytondbf26152010-10-01 23:13:49 +0000807static bool
808IsOperator (const char *name, OverloadedOperatorKind &op_kind)
809{
810 if (name == NULL || name[0] == '\0')
811 return false;
812
813 if (::strstr(name, "operator ") != name)
814 return false;
815
816 const char *post_op_name = name + 9;
817
818 // This is an operator, set the overloaded operator kind to invalid
819 // in case this is a conversion operator...
820 op_kind = NUM_OVERLOADED_OPERATORS;
821
822 switch (post_op_name[0])
823 {
824 case 'n':
825 if (strcmp (post_op_name, "new") == 0)
826 op_kind = OO_New;
827 else if (strcmp (post_op_name, "new[]") == 0)
828 op_kind = OO_Array_New;
829 break;
830
831 case 'd':
832 if (strcmp (post_op_name, "delete") == 0)
833 op_kind = OO_Delete;
834 else if (strcmp (post_op_name, "delete[]") == 0)
835 op_kind = OO_Array_Delete;
836 break;
837
838 case '+':
839 if (post_op_name[1] == '\0')
840 op_kind = OO_Plus;
841 else if (post_op_name[2] == '\0')
842 {
843 if (post_op_name[1] == '=')
844 op_kind = OO_PlusEqual;
845 else if (post_op_name[1] == '+')
846 op_kind = OO_PlusPlus;
847 }
848 break;
849
850 case '-':
851 if (post_op_name[1] == '\0')
852 op_kind = OO_Minus;
853 else if (post_op_name[2] == '\0')
854 {
855 switch (post_op_name[1])
856 {
857 case '=': op_kind = OO_MinusEqual; break;
858 case '-': op_kind = OO_MinusMinus; break;
859 case '>': op_kind = OO_Arrow; break;
860 }
861 }
862 else if (post_op_name[3] == '\0')
863 {
864 if (post_op_name[2] == '*')
865 op_kind = OO_ArrowStar; break;
866 }
867 break;
868
869 case '*':
870 if (post_op_name[1] == '\0')
871 op_kind = OO_Star;
872 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
873 op_kind = OO_StarEqual;
874 break;
875
876 case '/':
877 if (post_op_name[1] == '\0')
878 op_kind = OO_Slash;
879 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
880 op_kind = OO_SlashEqual;
881 break;
882
883 case '%':
884 if (post_op_name[1] == '\0')
885 op_kind = OO_Percent;
886 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
887 op_kind = OO_PercentEqual;
888 break;
889
890
891 case '^':
892 if (post_op_name[1] == '\0')
893 op_kind = OO_Caret;
894 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
895 op_kind = OO_CaretEqual;
896 break;
897
898 case '&':
899 if (post_op_name[1] == '\0')
900 op_kind = OO_Amp;
901 else if (post_op_name[2] == '\0')
902 {
903 switch (post_op_name[1])
904 {
905 case '=': op_kind = OO_AmpEqual; break;
906 case '&': op_kind = OO_AmpAmp; break;
907 }
908 }
909 break;
910
911 case '|':
912 if (post_op_name[1] == '\0')
913 op_kind = OO_Pipe;
914 else if (post_op_name[2] == '\0')
915 {
916 switch (post_op_name[1])
917 {
918 case '=': op_kind = OO_PipeEqual; break;
919 case '|': op_kind = OO_PipePipe; break;
920 }
921 }
922 break;
923
924 case '~':
925 if (post_op_name[1] == '\0')
926 op_kind = OO_Tilde;
927 break;
928
929 case '!':
930 if (post_op_name[1] == '\0')
931 op_kind = OO_Exclaim;
932 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
933 op_kind = OO_ExclaimEqual;
934 break;
935
936 case '=':
937 if (post_op_name[1] == '\0')
938 op_kind = OO_Equal;
939 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
940 op_kind = OO_EqualEqual;
941 break;
942
943 case '<':
944 if (post_op_name[1] == '\0')
945 op_kind = OO_Less;
946 else if (post_op_name[2] == '\0')
947 {
948 switch (post_op_name[1])
949 {
950 case '<': op_kind = OO_LessLess; break;
951 case '=': op_kind = OO_LessEqual; break;
952 }
953 }
954 else if (post_op_name[3] == '\0')
955 {
956 if (post_op_name[2] == '=')
957 op_kind = OO_LessLessEqual;
958 }
959 break;
960
961 case '>':
962 if (post_op_name[1] == '\0')
963 op_kind = OO_Greater;
964 else if (post_op_name[2] == '\0')
965 {
966 switch (post_op_name[1])
967 {
968 case '>': op_kind = OO_GreaterGreater; break;
969 case '=': op_kind = OO_GreaterEqual; break;
970 }
971 }
972 else if (post_op_name[1] == '>' &&
973 post_op_name[2] == '=' &&
974 post_op_name[3] == '\0')
975 {
976 op_kind = OO_GreaterGreaterEqual;
977 }
978 break;
979
980 case ',':
981 if (post_op_name[1] == '\0')
982 op_kind = OO_Comma;
983 break;
984
985 case '(':
986 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
987 op_kind = OO_Call;
988 break;
989
990 case '[':
991 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
992 op_kind = OO_Subscript;
993 break;
994 }
995
996 return true;
997}
Greg Clayton412440a2010-09-23 01:09:21 +0000998CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +0000999ClangASTContext::AddMethodToCXXRecordType
1000(
Greg Clayton462d4142010-09-29 01:12:09 +00001001 ASTContext *ast_context,
1002 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001003 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001004 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001005 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001006 bool is_virtual,
1007 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001008 bool is_inline,
1009 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +00001010)
Sean Callanan79523002010-09-17 02:58:26 +00001011{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001012 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +00001013 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001014
1015 assert(ast_context);
1016
1017 IdentifierTable *identifier_table = &ast_context->Idents;
1018
1019 assert(identifier_table);
1020
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001021 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +00001022
1023 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +00001024
Greg Clayton1d8173f2010-09-24 05:15:53 +00001025 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001026 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001027
Greg Clayton1d8173f2010-09-24 05:15:53 +00001028 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +00001029
Greg Clayton1d8173f2010-09-24 05:15:53 +00001030 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001031 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001032
Greg Clayton1d8173f2010-09-24 05:15:53 +00001033 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +00001034
Greg Clayton1d8173f2010-09-24 05:15:53 +00001035 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001036 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001037
1038 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1039
Greg Clayton1d8173f2010-09-24 05:15:53 +00001040 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001041 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001042
Greg Clayton1d8173f2010-09-24 05:15:53 +00001043 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001044
Greg Clayton30449d52010-10-01 02:31:07 +00001045 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001046
Greg Clayton30449d52010-10-01 02:31:07 +00001047 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001048
Greg Clayton90e325d2010-10-01 03:45:20 +00001049 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001050
Greg Clayton5325a362010-10-02 01:40:05 +00001051 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001052
Greg Clayton5325a362010-10-02 01:40:05 +00001053 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001054 return NULL;
1055
Greg Clayton5325a362010-10-02 01:40:05 +00001056 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001057
1058 if (!method_function_prototype)
1059 return NULL;
1060
1061 unsigned int num_params = method_function_prototype->getNumArgs();
1062
1063 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001064 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001065 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1066 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001067 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001068 method_qual_type,
1069 is_inline,
1070 is_implicitly_declared);
1071 }
1072 else if (decl_name == record_decl->getDeclName())
1073 {
Greg Clayton30449d52010-10-01 02:31:07 +00001074 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1075 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001076 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001077 method_qual_type,
1078 NULL, // TypeSourceInfo *
1079 is_explicit,
1080 is_inline,
1081 is_implicitly_declared);
1082 }
1083 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001084 {
Greg Claytondbf26152010-10-01 23:13:49 +00001085
1086 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1087 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001088 {
Greg Claytondbf26152010-10-01 23:13:49 +00001089 if (op_kind != NUM_OVERLOADED_OPERATORS)
1090 {
1091 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001092 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001093 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001094 method_qual_type,
1095 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001096 is_static,
1097 SC_None,
1098 is_inline);
1099 }
1100 else if (num_params == 0)
1101 {
1102 // Conversion operators don't take params...
1103 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1104 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001105 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001106 method_qual_type,
1107 NULL, // TypeSourceInfo *
1108 is_inline,
1109 is_explicit);
1110 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001111 }
Greg Claytondbf26152010-10-01 23:13:49 +00001112
1113 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001114 {
1115 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1116 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001117 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001118 method_qual_type,
1119 NULL, // TypeSourceInfo *
1120 is_static,
1121 SC_None,
1122 is_inline);
1123 }
Greg Clayton30449d52010-10-01 02:31:07 +00001124 }
Greg Claytondbf26152010-10-01 23:13:49 +00001125
Greg Clayton462d4142010-09-29 01:12:09 +00001126 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001127
1128 cxx_method_decl->setAccess (access_specifier);
1129 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001130
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001131 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001132
1133 ParmVarDecl *params[num_params];
1134
1135 for (int param_index = 0;
1136 param_index < num_params;
1137 ++param_index)
1138 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001139 params[param_index] = ParmVarDecl::Create (*ast_context,
1140 cxx_method_decl,
1141 SourceLocation(),
1142 NULL, // anonymous
1143 method_function_prototype->getArgType(param_index),
1144 NULL,
1145 SC_None,
1146 SC_None,
1147 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001148 }
1149
Greg Clayton1d8173f2010-09-24 05:15:53 +00001150 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001151
Greg Clayton1d8173f2010-09-24 05:15:53 +00001152 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001153
Greg Clayton412440a2010-09-23 01:09:21 +00001154 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001155}
1156
1157bool
Greg Clayton84f80752010-07-22 18:30:50 +00001158ClangASTContext::AddFieldToRecordType
1159(
Greg Clayton462d4142010-09-29 01:12:09 +00001160 ASTContext *ast_context,
1161 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001162 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001163 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001164 AccessType access,
1165 uint32_t bitfield_bit_size
1166)
Chris Lattner24943d22010-06-08 16:52:24 +00001167{
1168 if (record_clang_type == NULL || field_type == NULL)
1169 return false;
1170
Sean Callanan60a0ced2010-09-16 20:01:08 +00001171 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001172
1173 assert (ast_context != NULL);
1174 assert (identifier_table != NULL);
1175
1176 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1177
Greg Clayton1674b122010-07-21 22:12:05 +00001178 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001179 if (clang_type)
1180 {
1181 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1182
1183 if (record_type)
1184 {
1185 RecordDecl *record_decl = record_type->getDecl();
1186
Chris Lattner24943d22010-06-08 16:52:24 +00001187 clang::Expr *bit_width = NULL;
1188 if (bitfield_bit_size != 0)
1189 {
1190 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001191 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001192 }
Greg Clayton84f80752010-07-22 18:30:50 +00001193 FieldDecl *field = FieldDecl::Create (*ast_context,
1194 record_decl,
1195 SourceLocation(),
1196 name ? &identifier_table->get(name) : NULL, // Identifier
1197 QualType::getFromOpaquePtr(field_type), // Field type
1198 NULL, // DeclaratorInfo *
1199 bit_width, // BitWidth
1200 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001201
Greg Clayton84f80752010-07-22 18:30:50 +00001202 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001203
1204 if (field)
1205 {
1206 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001207 }
1208 }
Greg Clayton9488b742010-07-28 02:04:09 +00001209 else
1210 {
1211 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1212 if (objc_class_type)
1213 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001214 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001215 ClangASTContext::AddObjCClassIVar (ast_context,
1216 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001217 name,
1218 field_type,
1219 access,
1220 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001221 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001222 }
1223 }
Chris Lattner24943d22010-06-08 16:52:24 +00001224 }
1225 return false;
1226}
1227
1228bool
1229ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1230{
1231 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1232}
1233
1234bool
1235ClangASTContext::FieldIsBitfield
1236(
1237 ASTContext *ast_context,
1238 FieldDecl* field,
1239 uint32_t& bitfield_bit_size
1240)
1241{
1242 if (ast_context == NULL || field == NULL)
1243 return false;
1244
1245 if (field->isBitField())
1246 {
1247 Expr* bit_width_expr = field->getBitWidth();
1248 if (bit_width_expr)
1249 {
1250 llvm::APSInt bit_width_apsint;
1251 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1252 {
1253 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1254 return true;
1255 }
1256 }
1257 }
1258 return false;
1259}
1260
1261bool
1262ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1263{
1264 if (record_decl == NULL)
1265 return false;
1266
1267 if (!record_decl->field_empty())
1268 return true;
1269
1270 // No fields, lets check this is a CXX record and check the base classes
1271 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1272 if (cxx_record_decl)
1273 {
1274 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1275 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1276 base_class != base_class_end;
1277 ++base_class)
1278 {
1279 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1280 if (RecordHasFields(base_class_decl))
1281 return true;
1282 }
1283 }
1284 return false;
1285}
1286
1287void
Greg Clayton462d4142010-09-29 01:12:09 +00001288ClangASTContext::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 +00001289{
1290 if (clang_qual_type)
1291 {
1292 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001293 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001294 if (clang_type)
1295 {
1296 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1297 if (record_type)
1298 {
1299 RecordDecl *record_decl = record_type->getDecl();
1300 if (record_decl)
1301 {
1302 uint32_t field_idx;
1303 RecordDecl::field_iterator field, field_end;
1304 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1305 field != field_end;
1306 ++field, ++field_idx)
1307 {
1308 // If no accessibility was assigned, assign the correct one
1309 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1310 field->setAccess ((AccessSpecifier)default_accessibility);
1311 }
1312 }
1313 }
1314 }
1315 }
1316}
1317
1318#pragma mark C++ Base Classes
1319
1320CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001321ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001322{
1323 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001324 return new CXXBaseSpecifier (SourceRange(),
1325 is_virtual,
1326 base_of_class,
1327 ConvertAccessTypeToAccessSpecifier (access),
1328 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001329 return NULL;
1330}
1331
Greg Claytone9d0df42010-07-02 01:29:13 +00001332void
1333ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1334{
1335 for (unsigned i=0; i<num_base_classes; ++i)
1336 {
1337 delete base_classes[i];
1338 base_classes[i] = NULL;
1339 }
1340}
1341
Chris Lattner24943d22010-06-08 16:52:24 +00001342bool
Greg Clayton462d4142010-09-29 01:12:09 +00001343ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001344{
1345 if (class_clang_type)
1346 {
Greg Clayton1674b122010-07-21 22:12:05 +00001347 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001348 if (clang_type)
1349 {
1350 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1351 if (record_type)
1352 {
1353 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1354 if (cxx_record_decl)
1355 {
Chris Lattner24943d22010-06-08 16:52:24 +00001356 cxx_record_decl->setBases(base_classes, num_base_classes);
1357 return true;
1358 }
1359 }
1360 }
1361 }
1362 return false;
1363}
Greg Clayton84f80752010-07-22 18:30:50 +00001364#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001365
Greg Clayton462d4142010-09-29 01:12:09 +00001366clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001367ClangASTContext::CreateObjCClass
1368(
1369 const char *name,
1370 DeclContext *decl_ctx,
1371 bool isForwardDecl,
1372 bool isInternal
1373)
1374{
1375 ASTContext *ast_context = getASTContext();
1376 assert (ast_context != NULL);
1377 assert (name && name[0]);
1378 if (decl_ctx == NULL)
1379 decl_ctx = ast_context->getTranslationUnitDecl();
1380
1381 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1382 // we will need to update this code. I was told to currently always use
1383 // the CXXRecordDecl class since we often don't know from debug information
1384 // if something is struct or a class, so we default to always use the more
1385 // complete definition just in case.
1386 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1387 decl_ctx,
1388 SourceLocation(),
1389 &ast_context->Idents.get(name),
1390 SourceLocation(),
1391 isForwardDecl,
1392 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001393
1394 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001395}
1396
1397bool
Greg Clayton462d4142010-09-29 01:12:09 +00001398ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001399{
1400 if (class_opaque_type && super_opaque_type)
1401 {
1402 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1403 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1404 clang::Type *class_type = class_qual_type.getTypePtr();
1405 clang::Type *super_type = super_qual_type.getTypePtr();
1406 if (class_type && super_type)
1407 {
1408 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1409 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1410 if (objc_class_type && objc_super_type)
1411 {
1412 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1413 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1414 if (class_interface_decl && super_interface_decl)
1415 {
1416 class_interface_decl->setSuperClass(super_interface_decl);
1417 return true;
1418 }
1419 }
1420 }
1421 }
1422 return false;
1423}
1424
1425
1426bool
1427ClangASTContext::AddObjCClassIVar
1428(
Greg Clayton462d4142010-09-29 01:12:09 +00001429 ASTContext *ast_context,
1430 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001431 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001432 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001433 AccessType access,
1434 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001435 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001436)
1437{
1438 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1439 return false;
1440
Sean Callanan60a0ced2010-09-16 20:01:08 +00001441 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001442
1443 assert (ast_context != NULL);
1444 assert (identifier_table != NULL);
1445
1446 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1447
1448 clang::Type *class_type = class_qual_type.getTypePtr();
1449 if (class_type)
1450 {
1451 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1452
1453 if (objc_class_type)
1454 {
1455 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1456
1457 if (class_interface_decl)
1458 {
1459 clang::Expr *bit_width = NULL;
1460 if (bitfield_bit_size != 0)
1461 {
1462 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001463 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001464 }
1465
Greg Clayton9488b742010-07-28 02:04:09 +00001466 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1467 class_interface_decl,
1468 SourceLocation(),
1469 &identifier_table->get(name), // Identifier
1470 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1471 NULL, // TypeSourceInfo *
1472 ConvertAccessTypeToObjCIvarAccessControl (access),
1473 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001474 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001475
1476 if (field)
1477 {
1478 class_interface_decl->addDecl(field);
1479 return true;
1480 }
Greg Clayton84f80752010-07-22 18:30:50 +00001481 }
1482 }
1483 }
1484 return false;
1485}
Chris Lattner24943d22010-06-08 16:52:24 +00001486
Greg Clayton9488b742010-07-28 02:04:09 +00001487
1488bool
Greg Clayton462d4142010-09-29 01:12:09 +00001489ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001490{
1491 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1492
1493 clang::Type *class_type = class_qual_type.getTypePtr();
1494 if (class_type)
1495 {
1496 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1497
1498 if (objc_class_type)
1499 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1500 }
1501 return false;
1502}
1503
1504bool
1505ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1506{
1507 while (class_interface_decl)
1508 {
1509 if (class_interface_decl->ivar_size() > 0)
1510 return true;
1511
1512 if (check_superclass)
1513 class_interface_decl = class_interface_decl->getSuperClass();
1514 else
1515 break;
1516 }
1517 return false;
1518}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001519
Greg Clayton462d4142010-09-29 01:12:09 +00001520ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001521ClangASTContext::AddMethodToObjCObjectType
1522(
Greg Clayton462d4142010-09-29 01:12:09 +00001523 ASTContext *ast_context,
1524 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001525 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001526 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001527 lldb::AccessType access
1528)
1529{
1530 if (class_opaque_type == NULL || method_opaque_type == NULL)
1531 return NULL;
1532
1533 IdentifierTable *identifier_table = &ast_context->Idents;
1534
1535 assert (ast_context != NULL);
1536 assert (identifier_table != NULL);
1537
1538 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1539
1540 clang::Type *class_type = class_qual_type.getTypePtr();
1541 if (class_type == NULL)
1542 return NULL;
1543
1544 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1545
1546 if (objc_class_type == NULL)
1547 return NULL;
1548
1549 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1550
1551 if (class_interface_decl == NULL)
1552 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001553
Greg Clayton1d8173f2010-09-24 05:15:53 +00001554 const char *selector_start = ::strchr (name, ' ');
1555 if (selector_start == NULL)
1556 return NULL;
1557
1558 selector_start++;
1559 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1560 return NULL;
1561 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1562
Greg Claytonad60bf42010-10-12 02:24:53 +00001563 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001564 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001565 //printf ("name = '%s'\n", name);
1566
1567 unsigned num_selectors_with_args = 0;
1568 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001569 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001570 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001571 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001572 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001573 bool has_arg = (start[len] == ':');
1574 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001575 ++num_selectors_with_args;
Greg Clayton6bc44a42010-10-27 04:01:14 +00001576 printf ("@selector[%zu] = '%.*s'\n", selector_idents.size(), (int)len, start);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001577 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001578 if (has_arg)
1579 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001580 }
1581
1582
1583 if (selector_idents.size() == 0)
1584 return 0;
1585
Greg Claytonad60bf42010-10-12 02:24:53 +00001586 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001587 selector_idents.data());
1588
1589 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1590
1591 // Populate the method decl with parameter decls
1592 clang::Type *method_type(method_qual_type.getTypePtr());
1593
1594 if (method_type == NULL)
1595 return NULL;
1596
1597 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1598
1599 if (!method_function_prototype)
1600 return NULL;
1601
1602
1603 bool is_variadic = false;
1604 bool is_synthesized = false;
1605 bool is_defined = false;
1606 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1607
1608 const unsigned num_args = method_function_prototype->getNumArgs();
1609
1610 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1611 SourceLocation(), // beginLoc,
1612 SourceLocation(), // endLoc,
1613 method_selector,
1614 method_function_prototype->getResultType(),
1615 NULL, // TypeSourceInfo *ResultTInfo,
1616 GetDeclContextForType (class_opaque_type),
1617 name[0] == '-',
1618 is_variadic,
1619 is_synthesized,
1620 is_defined,
1621 imp_control,
1622 num_args);
1623
1624
1625 if (objc_method_decl == NULL)
1626 return NULL;
1627
1628 if (num_args > 0)
1629 {
1630 llvm::SmallVector<ParmVarDecl *, 12> params;
1631
1632 for (int param_index = 0; param_index < num_args; ++param_index)
1633 {
1634 params.push_back (ParmVarDecl::Create (*ast_context,
1635 objc_method_decl,
1636 SourceLocation(),
1637 NULL, // anonymous
1638 method_function_prototype->getArgType(param_index),
1639 NULL,
1640 SC_Auto,
1641 SC_Auto,
1642 NULL));
1643 }
1644
1645 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1646 }
1647
1648 class_interface_decl->addDecl (objc_method_decl);
1649
1650
1651 return objc_method_decl;
1652}
1653
1654
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001655uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001656ClangASTContext::GetTypeInfo
1657(
1658 clang_type_t clang_type,
1659 clang::ASTContext *ast_context,
1660 clang_type_t *pointee_or_element_clang_type
1661)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001662{
1663 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001664 return 0;
1665
1666 if (pointee_or_element_clang_type)
1667 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001668
1669 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1670
1671 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1672 switch (type_class)
1673 {
Sean Callanan04325062010-10-25 00:29:48 +00001674 case clang::Type::Builtin:
1675 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1676 {
Sean Callanan04325062010-10-25 00:29:48 +00001677 case clang::BuiltinType::ObjCId:
1678 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001679 if (ast_context && pointee_or_element_clang_type)
1680 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001681 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001682
1683 default:
1684 break;
Sean Callanan04325062010-10-25 00:29:48 +00001685 }
1686 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001687
1688 case clang::Type::BlockPointer:
1689 if (pointee_or_element_clang_type)
1690 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1691 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1692
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001693 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001694
1695 case clang::Type::ConstantArray:
1696 case clang::Type::DependentSizedArray:
1697 case clang::Type::IncompleteArray:
1698 case clang::Type::VariableArray:
1699 if (pointee_or_element_clang_type)
1700 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1701 return eTypeHasChildren | eTypeIsArray;
1702
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001703 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001704 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1705 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1706 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001707
1708 case clang::Type::Enum:
1709 if (pointee_or_element_clang_type)
1710 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1711 return eTypeIsEnumeration | eTypeHasValue;
1712
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001713 case clang::Type::Elaborated: return 0;
1714 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1715 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1716 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001717 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001718
1719 case clang::Type::LValueReference:
1720 case clang::Type::RValueReference:
1721 if (pointee_or_element_clang_type)
1722 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1723 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1724
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001725 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001726
1727 case clang::Type::ObjCObjectPointer:
1728 if (pointee_or_element_clang_type)
1729 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1730 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1731
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001732 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1733 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001734
1735 case clang::Type::Pointer:
1736 if (pointee_or_element_clang_type)
1737 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1738 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1739
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001740 case clang::Type::Record:
1741 if (qual_type->getAsCXXRecordDecl())
1742 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1743 else
1744 return eTypeHasChildren | eTypeIsStructUnion;
1745 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001746 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1747 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1748 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001749
1750 case clang::Type::Typedef:
1751 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
1752 ast_context,
1753 pointee_or_element_clang_type);
1754
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001755 case clang::Type::TypeOfExpr: return 0;
1756 case clang::Type::TypeOf: return 0;
1757 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001758 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1759 default: return 0;
1760 }
1761 return 0;
1762}
1763
Greg Clayton9488b742010-07-28 02:04:09 +00001764
Chris Lattner24943d22010-06-08 16:52:24 +00001765#pragma mark Aggregate Types
1766
1767bool
Greg Clayton462d4142010-09-29 01:12:09 +00001768ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001769{
1770 if (clang_type == NULL)
1771 return false;
1772
1773 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1774
1775 if (qual_type->isAggregateType ())
1776 return true;
1777
Greg Clayton03e0f972010-09-13 03:32:57 +00001778 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1779 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001780 {
Greg Clayton1674b122010-07-21 22:12:05 +00001781 case clang::Type::IncompleteArray:
1782 case clang::Type::VariableArray:
1783 case clang::Type::ConstantArray:
1784 case clang::Type::ExtVector:
1785 case clang::Type::Vector:
1786 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001787 case clang::Type::ObjCObject:
1788 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001789 return true;
1790
Greg Clayton1674b122010-07-21 22:12:05 +00001791 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001792 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
1793
1794 default:
1795 break;
1796 }
1797 // The clang type does have a value
1798 return false;
1799}
1800
1801uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001802ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001803{
1804 if (clang_qual_type == NULL)
1805 return 0;
1806
1807 uint32_t num_children = 0;
1808 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001809 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1810 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001811 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001812 case clang::Type::Builtin:
1813 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1814 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001815 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001816 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001817 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001818 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001819
1820 default:
1821 break;
1822 }
1823 break;
1824
Greg Clayton1674b122010-07-21 22:12:05 +00001825 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00001826 {
1827 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1828 const RecordDecl *record_decl = record_type->getDecl();
1829 assert(record_decl);
1830 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1831 if (cxx_record_decl)
1832 {
1833 if (omit_empty_base_classes)
1834 {
1835 // Check each base classes to see if it or any of its
1836 // base classes contain any fields. This can help
1837 // limit the noise in variable views by not having to
1838 // show base classes that contain no members.
1839 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1840 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1841 base_class != base_class_end;
1842 ++base_class)
1843 {
1844 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1845
1846 // Skip empty base classes
1847 if (RecordHasFields(base_class_decl) == false)
1848 continue;
1849
1850 num_children++;
1851 }
1852 }
1853 else
1854 {
1855 // Include all base classes
1856 num_children += cxx_record_decl->getNumBases();
1857 }
1858
1859 }
1860 RecordDecl::field_iterator field, field_end;
1861 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1862 ++num_children;
1863 }
1864 break;
1865
Greg Clayton9488b742010-07-28 02:04:09 +00001866 case clang::Type::ObjCObject:
1867 case clang::Type::ObjCInterface:
1868 {
1869 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1870 assert (objc_class_type);
1871 if (objc_class_type)
1872 {
1873 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1874
1875 if (class_interface_decl)
1876 {
1877
1878 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1879 if (superclass_interface_decl)
1880 {
1881 if (omit_empty_base_classes)
1882 {
1883 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1884 ++num_children;
1885 }
1886 else
1887 ++num_children;
1888 }
1889
1890 num_children += class_interface_decl->ivar_size();
1891 }
1892 }
1893 }
1894 break;
1895
1896 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001897 {
1898 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1899 QualType pointee_type = pointer_type->getPointeeType();
1900 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1901 omit_empty_base_classes);
1902 // If this type points to a simple type, then it has 1 child
1903 if (num_pointee_children == 0)
1904 num_children = 1;
1905 else
1906 num_children = num_pointee_children;
1907 }
1908 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001909
Greg Clayton1674b122010-07-21 22:12:05 +00001910 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001911 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1912 break;
1913
Greg Clayton1674b122010-07-21 22:12:05 +00001914 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001915 {
1916 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1917 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001918 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1919 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001920 // If this type points to a simple type, then it has 1 child
1921 if (num_pointee_children == 0)
1922 num_children = 1;
1923 else
1924 num_children = num_pointee_children;
1925 }
1926 break;
1927
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001928 case clang::Type::LValueReference:
1929 case clang::Type::RValueReference:
1930 {
1931 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
1932 QualType pointee_type = reference_type->getPointeeType();
1933 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1934 omit_empty_base_classes);
1935 // If this type points to a simple type, then it has 1 child
1936 if (num_pointee_children == 0)
1937 num_children = 1;
1938 else
1939 num_children = num_pointee_children;
1940 }
1941 break;
1942
1943
Greg Clayton1674b122010-07-21 22:12:05 +00001944 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00001945 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes);
1946 break;
1947
1948 default:
1949 break;
1950 }
1951 return num_children;
1952}
1953
1954
Greg Clayton462d4142010-09-29 01:12:09 +00001955clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00001956ClangASTContext::GetChildClangTypeAtIndex
1957(
1958 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00001959 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00001960 uint32_t idx,
1961 bool transparent_pointers,
1962 bool omit_empty_base_classes,
1963 std::string& child_name,
1964 uint32_t &child_byte_size,
1965 int32_t &child_byte_offset,
1966 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001967 uint32_t &child_bitfield_bit_offset,
1968 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00001969)
1970{
1971 if (parent_clang_type)
1972
1973 return GetChildClangTypeAtIndex (getASTContext(),
1974 parent_name,
1975 parent_clang_type,
1976 idx,
1977 transparent_pointers,
1978 omit_empty_base_classes,
1979 child_name,
1980 child_byte_size,
1981 child_byte_offset,
1982 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001983 child_bitfield_bit_offset,
1984 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00001985 return NULL;
1986}
1987
Greg Clayton462d4142010-09-29 01:12:09 +00001988clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00001989ClangASTContext::GetChildClangTypeAtIndex
1990(
1991 ASTContext *ast_context,
1992 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00001993 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00001994 uint32_t idx,
1995 bool transparent_pointers,
1996 bool omit_empty_base_classes,
1997 std::string& child_name,
1998 uint32_t &child_byte_size,
1999 int32_t &child_byte_offset,
2000 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002001 uint32_t &child_bitfield_bit_offset,
2002 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002003)
2004{
2005 if (parent_clang_type == NULL)
2006 return NULL;
2007
2008 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2009 {
2010 uint32_t bit_offset;
2011 child_bitfield_bit_size = 0;
2012 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002013 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002014 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002015 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2016 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002017 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002018 case clang::Type::Builtin:
2019 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2020 {
2021 case clang::BuiltinType::ObjCId:
2022 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002023 child_name = "isa";
2024 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002025 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2026
Greg Clayton960d6a42010-08-03 00:35:52 +00002027 default:
2028 break;
2029 }
2030 break;
2031
2032
Greg Clayton1674b122010-07-21 22:12:05 +00002033 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002034 {
2035 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2036 const RecordDecl *record_decl = record_type->getDecl();
2037 assert(record_decl);
2038 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2039 uint32_t child_idx = 0;
2040
2041 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2042 if (cxx_record_decl)
2043 {
2044 // We might have base classes to print out first
2045 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2046 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2047 base_class != base_class_end;
2048 ++base_class)
2049 {
2050 const CXXRecordDecl *base_class_decl = NULL;
2051
2052 // Skip empty base classes
2053 if (omit_empty_base_classes)
2054 {
2055 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2056 if (RecordHasFields(base_class_decl) == false)
2057 continue;
2058 }
2059
2060 if (idx == child_idx)
2061 {
2062 if (base_class_decl == NULL)
2063 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2064
2065
2066 if (base_class->isVirtual())
2067 bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
2068 else
2069 bit_offset = record_layout.getBaseClassOffset(base_class_decl);
2070
2071 // Base classes should be a multiple of 8 bits in size
2072 assert (bit_offset % 8 == 0);
2073 child_byte_offset = bit_offset/8;
2074 std::string base_class_type_name(base_class->getType().getAsString());
2075
2076 child_name.assign(base_class_type_name.c_str());
2077
2078 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2079
2080 // Base classes biut sizes should be a multiple of 8 bits in size
2081 assert (clang_type_info_bit_size % 8 == 0);
2082 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002083 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002084 return base_class->getType().getAsOpaquePtr();
2085 }
2086 // We don't increment the child index in the for loop since we might
2087 // be skipping empty base classes
2088 ++child_idx;
2089 }
2090 }
Chris Lattner24943d22010-06-08 16:52:24 +00002091 // Make sure index is in range...
2092 uint32_t field_idx = 0;
2093 RecordDecl::field_iterator field, field_end;
2094 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2095 {
2096 if (idx == child_idx)
2097 {
2098 // Print the member type if requested
2099 // Print the member name and equal sign
2100 child_name.assign(field->getNameAsString().c_str());
2101
2102 // Figure out the type byte size (field_type_info.first) and
2103 // alignment (field_type_info.second) from the AST context.
2104 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002105 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002106
2107 child_byte_size = field_type_info.first / 8;
2108
2109 // Figure out the field offset within the current struct/union/class type
2110 bit_offset = record_layout.getFieldOffset (field_idx);
2111 child_byte_offset = bit_offset / 8;
2112 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2113 child_bitfield_bit_offset = bit_offset % 8;
2114
2115 return field->getType().getAsOpaquePtr();
2116 }
2117 }
2118 }
2119 break;
2120
Greg Clayton9488b742010-07-28 02:04:09 +00002121 case clang::Type::ObjCObject:
2122 case clang::Type::ObjCInterface:
2123 {
2124 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2125 assert (objc_class_type);
2126 if (objc_class_type)
2127 {
2128 uint32_t child_idx = 0;
2129 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2130
2131 if (class_interface_decl)
2132 {
2133
2134 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2135 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2136 if (superclass_interface_decl)
2137 {
2138 if (omit_empty_base_classes)
2139 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002140 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002141 {
2142 if (idx == 0)
2143 {
2144 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2145
2146
2147 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2148
2149 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2150
2151 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002152 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002153 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002154
2155 return ivar_qual_type.getAsOpaquePtr();
2156 }
2157
2158 ++child_idx;
2159 }
2160 }
2161 else
2162 ++child_idx;
2163 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002164
2165 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002166
2167 if (idx < (child_idx + class_interface_decl->ivar_size()))
2168 {
2169 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2170
2171 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2172 {
2173 if (child_idx == idx)
2174 {
2175 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2176
2177 QualType ivar_qual_type(ivar_decl->getType());
2178
2179 child_name.assign(ivar_decl->getNameAsString().c_str());
2180
2181 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2182
2183 child_byte_size = ivar_type_info.first / 8;
2184
2185 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002186 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002187 child_byte_offset = bit_offset / 8;
2188
2189 return ivar_qual_type.getAsOpaquePtr();
2190 }
2191 ++child_idx;
2192 }
2193 }
2194 }
2195 }
2196 }
2197 break;
2198
2199 case clang::Type::ObjCObjectPointer:
2200 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002201 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2202 QualType pointee_type = pointer_type->getPointeeType();
2203
2204 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2205 {
2206 return GetChildClangTypeAtIndex (ast_context,
2207 parent_name,
2208 pointer_type->getPointeeType().getAsOpaquePtr(),
2209 idx,
2210 transparent_pointers,
2211 omit_empty_base_classes,
2212 child_name,
2213 child_byte_size,
2214 child_byte_offset,
2215 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002216 child_bitfield_bit_offset,
2217 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002218 }
2219 else
2220 {
2221 if (parent_name)
2222 {
2223 child_name.assign(1, '*');
2224 child_name += parent_name;
2225 }
2226
2227 // We have a pointer to an simple type
2228 if (idx == 0)
2229 {
2230 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2231 assert(clang_type_info.first % 8 == 0);
2232 child_byte_size = clang_type_info.first / 8;
2233 child_byte_offset = 0;
2234 return pointee_type.getAsOpaquePtr();
2235 }
2236 }
Greg Clayton9488b742010-07-28 02:04:09 +00002237 }
2238 break;
2239
Greg Clayton1674b122010-07-21 22:12:05 +00002240 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002241 {
2242 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2243 const uint64_t element_count = array->getSize().getLimitedValue();
2244
2245 if (idx < element_count)
2246 {
2247 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2248
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002249 char element_name[64];
2250 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002251
2252 child_name.assign(element_name);
2253 assert(field_type_info.first % 8 == 0);
2254 child_byte_size = field_type_info.first / 8;
2255 child_byte_offset = idx * child_byte_size;
2256 return array->getElementType().getAsOpaquePtr();
2257 }
2258 }
2259 break;
2260
Greg Clayton1674b122010-07-21 22:12:05 +00002261 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002262 {
2263 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2264 QualType pointee_type = pointer_type->getPointeeType();
2265
2266 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2267 {
2268 return GetChildClangTypeAtIndex (ast_context,
2269 parent_name,
2270 pointer_type->getPointeeType().getAsOpaquePtr(),
2271 idx,
2272 transparent_pointers,
2273 omit_empty_base_classes,
2274 child_name,
2275 child_byte_size,
2276 child_byte_offset,
2277 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002278 child_bitfield_bit_offset,
2279 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002280 }
2281 else
2282 {
2283 if (parent_name)
2284 {
2285 child_name.assign(1, '*');
2286 child_name += parent_name;
2287 }
2288
2289 // We have a pointer to an simple type
2290 if (idx == 0)
2291 {
2292 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2293 assert(clang_type_info.first % 8 == 0);
2294 child_byte_size = clang_type_info.first / 8;
2295 child_byte_offset = 0;
2296 return pointee_type.getAsOpaquePtr();
2297 }
2298 }
2299 }
2300 break;
2301
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002302 case clang::Type::LValueReference:
2303 case clang::Type::RValueReference:
2304 {
2305 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2306 QualType pointee_type(reference_type->getPointeeType());
2307 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2308 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2309 {
2310 return GetChildClangTypeAtIndex (ast_context,
2311 parent_name,
2312 pointee_clang_type,
2313 idx,
2314 transparent_pointers,
2315 omit_empty_base_classes,
2316 child_name,
2317 child_byte_size,
2318 child_byte_offset,
2319 child_bitfield_bit_size,
2320 child_bitfield_bit_offset,
2321 child_is_base_class);
2322 }
2323 else
2324 {
2325 if (parent_name)
2326 {
2327 child_name.assign(1, '&');
2328 child_name += parent_name;
2329 }
2330
2331 // We have a pointer to an simple type
2332 if (idx == 0)
2333 {
2334 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2335 assert(clang_type_info.first % 8 == 0);
2336 child_byte_size = clang_type_info.first / 8;
2337 child_byte_offset = 0;
2338 return pointee_type.getAsOpaquePtr();
2339 }
2340 }
2341 }
2342 break;
2343
Greg Clayton1674b122010-07-21 22:12:05 +00002344 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002345 return GetChildClangTypeAtIndex (ast_context,
2346 parent_name,
2347 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2348 idx,
2349 transparent_pointers,
2350 omit_empty_base_classes,
2351 child_name,
2352 child_byte_size,
2353 child_byte_offset,
2354 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002355 child_bitfield_bit_offset,
2356 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002357 break;
2358
2359 default:
2360 break;
2361 }
2362 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002363 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002364}
2365
2366static inline bool
2367BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2368{
2369 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2370}
2371
2372static uint32_t
2373GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2374{
2375 uint32_t num_bases = 0;
2376 if (cxx_record_decl)
2377 {
2378 if (omit_empty_base_classes)
2379 {
2380 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2381 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2382 base_class != base_class_end;
2383 ++base_class)
2384 {
2385 // Skip empty base classes
2386 if (omit_empty_base_classes)
2387 {
2388 if (BaseSpecifierIsEmpty (base_class))
2389 continue;
2390 }
2391 ++num_bases;
2392 }
2393 }
2394 else
2395 num_bases = cxx_record_decl->getNumBases();
2396 }
2397 return num_bases;
2398}
2399
2400
2401static uint32_t
2402GetIndexForRecordBase
2403(
2404 const RecordDecl *record_decl,
2405 const CXXBaseSpecifier *base_spec,
2406 bool omit_empty_base_classes
2407)
2408{
2409 uint32_t child_idx = 0;
2410
2411 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2412
2413// const char *super_name = record_decl->getNameAsCString();
2414// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2415// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2416//
2417 if (cxx_record_decl)
2418 {
2419 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2420 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2421 base_class != base_class_end;
2422 ++base_class)
2423 {
2424 if (omit_empty_base_classes)
2425 {
2426 if (BaseSpecifierIsEmpty (base_class))
2427 continue;
2428 }
2429
2430// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2431// child_idx,
2432// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2433//
2434//
2435 if (base_class == base_spec)
2436 return child_idx;
2437 ++child_idx;
2438 }
2439 }
2440
2441 return UINT32_MAX;
2442}
2443
2444
2445static uint32_t
2446GetIndexForRecordChild
2447(
2448 const RecordDecl *record_decl,
2449 NamedDecl *canonical_decl,
2450 bool omit_empty_base_classes
2451)
2452{
2453 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2454
2455// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2456//
2457//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2458// if (cxx_record_decl)
2459// {
2460// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2461// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2462// base_class != base_class_end;
2463// ++base_class)
2464// {
2465// if (omit_empty_base_classes)
2466// {
2467// if (BaseSpecifierIsEmpty (base_class))
2468// continue;
2469// }
2470//
2471//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2472//// record_decl->getNameAsCString(),
2473//// canonical_decl->getNameAsCString(),
2474//// child_idx,
2475//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2476//
2477//
2478// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2479// if (curr_base_class_decl == canonical_decl)
2480// {
2481// return child_idx;
2482// }
2483// ++child_idx;
2484// }
2485// }
2486//
2487// const uint32_t num_bases = child_idx;
2488 RecordDecl::field_iterator field, field_end;
2489 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2490 field != field_end;
2491 ++field, ++child_idx)
2492 {
2493// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2494// record_decl->getNameAsCString(),
2495// canonical_decl->getNameAsCString(),
2496// child_idx - num_bases,
2497// field->getNameAsCString());
2498
2499 if (field->getCanonicalDecl() == canonical_decl)
2500 return child_idx;
2501 }
2502
2503 return UINT32_MAX;
2504}
2505
2506// Look for a child member (doesn't include base classes, but it does include
2507// their members) in the type hierarchy. Returns an index path into "clang_type"
2508// on how to reach the appropriate member.
2509//
2510// class A
2511// {
2512// public:
2513// int m_a;
2514// int m_b;
2515// };
2516//
2517// class B
2518// {
2519// };
2520//
2521// class C :
2522// public B,
2523// public A
2524// {
2525// };
2526//
2527// If we have a clang type that describes "class C", and we wanted to looked
2528// "m_b" in it:
2529//
2530// With omit_empty_base_classes == false we would get an integer array back with:
2531// { 1, 1 }
2532// The first index 1 is the child index for "class A" within class C
2533// The second index 1 is the child index for "m_b" within class A
2534//
2535// With omit_empty_base_classes == true we would get an integer array back with:
2536// { 0, 1 }
2537// 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)
2538// The second index 1 is the child index for "m_b" within class A
2539
2540size_t
2541ClangASTContext::GetIndexOfChildMemberWithName
2542(
2543 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002544 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002545 const char *name,
2546 bool omit_empty_base_classes,
2547 std::vector<uint32_t>& child_indexes
2548)
2549{
2550 if (clang_type && name && name[0])
2551 {
2552 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002553 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2554 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002555 {
Greg Clayton1674b122010-07-21 22:12:05 +00002556 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002557 {
2558 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2559 const RecordDecl *record_decl = record_type->getDecl();
2560
2561 assert(record_decl);
2562 uint32_t child_idx = 0;
2563
2564 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2565
2566 // Try and find a field that matches NAME
2567 RecordDecl::field_iterator field, field_end;
2568 StringRef name_sref(name);
2569 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2570 field != field_end;
2571 ++field, ++child_idx)
2572 {
2573 if (field->getName().equals (name_sref))
2574 {
2575 // We have to add on the number of base classes to this index!
2576 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2577 return child_indexes.size();
2578 }
2579 }
2580
2581 if (cxx_record_decl)
2582 {
2583 const RecordDecl *parent_record_decl = cxx_record_decl;
2584
2585 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2586
2587 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2588 // Didn't find things easily, lets let clang do its thang...
2589 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2590 DeclarationName decl_name(&ident_ref);
2591
2592 CXXBasePaths paths;
2593 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2594 decl_name.getAsOpaquePtr(),
2595 paths))
2596 {
Chris Lattner24943d22010-06-08 16:52:24 +00002597 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2598 for (path = paths.begin(); path != path_end; ++path)
2599 {
2600 const size_t num_path_elements = path->size();
2601 for (size_t e=0; e<num_path_elements; ++e)
2602 {
2603 CXXBasePathElement elem = (*path)[e];
2604
2605 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2606 if (child_idx == UINT32_MAX)
2607 {
2608 child_indexes.clear();
2609 return 0;
2610 }
2611 else
2612 {
2613 child_indexes.push_back (child_idx);
2614 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2615 }
2616 }
2617 DeclContext::lookup_iterator named_decl_pos;
2618 for (named_decl_pos = path->Decls.first;
2619 named_decl_pos != path->Decls.second && parent_record_decl;
2620 ++named_decl_pos)
2621 {
2622 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2623
2624 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2625 if (child_idx == UINT32_MAX)
2626 {
2627 child_indexes.clear();
2628 return 0;
2629 }
2630 else
2631 {
2632 child_indexes.push_back (child_idx);
2633 }
2634 }
2635 }
2636 return child_indexes.size();
2637 }
2638 }
2639
2640 }
2641 break;
2642
Greg Clayton9488b742010-07-28 02:04:09 +00002643 case clang::Type::ObjCObject:
2644 case clang::Type::ObjCInterface:
2645 {
2646 StringRef name_sref(name);
2647 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2648 assert (objc_class_type);
2649 if (objc_class_type)
2650 {
2651 uint32_t child_idx = 0;
2652 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2653
2654 if (class_interface_decl)
2655 {
2656 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2657 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2658
Greg Clayton823533e2010-09-18 02:11:07 +00002659 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002660 {
2661 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2662
2663 if (ivar_decl->getName().equals (name_sref))
2664 {
2665 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2666 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2667 ++child_idx;
2668
2669 child_indexes.push_back (child_idx);
2670 return child_indexes.size();
2671 }
2672 }
2673
2674 if (superclass_interface_decl)
2675 {
2676 // The super class index is always zero for ObjC classes,
2677 // so we push it onto the child indexes in case we find
2678 // an ivar in our superclass...
2679 child_indexes.push_back (0);
2680
2681 if (GetIndexOfChildMemberWithName (ast_context,
2682 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2683 name,
2684 omit_empty_base_classes,
2685 child_indexes))
2686 {
2687 // We did find an ivar in a superclass so just
2688 // return the results!
2689 return child_indexes.size();
2690 }
2691
2692 // We didn't find an ivar matching "name" in our
2693 // superclass, pop the superclass zero index that
2694 // we pushed on above.
2695 child_indexes.pop_back();
2696 }
2697 }
2698 }
2699 }
2700 break;
2701
2702 case clang::Type::ObjCObjectPointer:
2703 {
2704 return GetIndexOfChildMemberWithName (ast_context,
2705 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2706 name,
2707 omit_empty_base_classes,
2708 child_indexes);
2709 }
2710 break;
2711
2712
Greg Clayton1674b122010-07-21 22:12:05 +00002713 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002714 {
2715// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2716// const uint64_t element_count = array->getSize().getLimitedValue();
2717//
2718// if (idx < element_count)
2719// {
2720// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2721//
2722// char element_name[32];
2723// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2724//
2725// child_name.assign(element_name);
2726// assert(field_type_info.first % 8 == 0);
2727// child_byte_size = field_type_info.first / 8;
2728// child_byte_offset = idx * child_byte_size;
2729// return array->getElementType().getAsOpaquePtr();
2730// }
2731 }
2732 break;
2733
Greg Clayton1674b122010-07-21 22:12:05 +00002734// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002735// {
2736// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2737// QualType pointee_type = mem_ptr_type->getPointeeType();
2738//
2739// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2740// {
2741// return GetIndexOfChildWithName (ast_context,
2742// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2743// name);
2744// }
2745// }
2746// break;
2747//
Greg Clayton1674b122010-07-21 22:12:05 +00002748 case clang::Type::LValueReference:
2749 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002750 {
2751 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2752 QualType pointee_type = reference_type->getPointeeType();
2753
2754 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2755 {
2756 return GetIndexOfChildMemberWithName (ast_context,
2757 reference_type->getPointeeType().getAsOpaquePtr(),
2758 name,
2759 omit_empty_base_classes,
2760 child_indexes);
2761 }
2762 }
2763 break;
2764
Greg Clayton1674b122010-07-21 22:12:05 +00002765 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002766 {
2767 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2768 QualType pointee_type = pointer_type->getPointeeType();
2769
2770 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2771 {
2772 return GetIndexOfChildMemberWithName (ast_context,
2773 pointer_type->getPointeeType().getAsOpaquePtr(),
2774 name,
2775 omit_empty_base_classes,
2776 child_indexes);
2777 }
2778 else
2779 {
2780// if (parent_name)
2781// {
2782// child_name.assign(1, '*');
2783// child_name += parent_name;
2784// }
2785//
2786// // We have a pointer to an simple type
2787// if (idx == 0)
2788// {
2789// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2790// assert(clang_type_info.first % 8 == 0);
2791// child_byte_size = clang_type_info.first / 8;
2792// child_byte_offset = 0;
2793// return pointee_type.getAsOpaquePtr();
2794// }
2795 }
2796 }
2797 break;
2798
Greg Clayton1674b122010-07-21 22:12:05 +00002799 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002800 return GetIndexOfChildMemberWithName (ast_context,
2801 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
2802 name,
2803 omit_empty_base_classes,
2804 child_indexes);
2805
2806 default:
2807 break;
2808 }
2809 }
2810 return 0;
2811}
2812
2813
2814// Get the index of the child of "clang_type" whose name matches. This function
2815// doesn't descend into the children, but only looks one level deep and name
2816// matches can include base class names.
2817
2818uint32_t
2819ClangASTContext::GetIndexOfChildWithName
2820(
2821 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002822 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002823 const char *name,
2824 bool omit_empty_base_classes
2825)
2826{
2827 if (clang_type && name && name[0])
2828 {
2829 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002830
Greg Clayton03e0f972010-09-13 03:32:57 +00002831 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002832
Greg Clayton03e0f972010-09-13 03:32:57 +00002833 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002834 {
Greg Clayton1674b122010-07-21 22:12:05 +00002835 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002836 {
2837 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2838 const RecordDecl *record_decl = record_type->getDecl();
2839
2840 assert(record_decl);
2841 uint32_t child_idx = 0;
2842
2843 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2844
2845 if (cxx_record_decl)
2846 {
2847 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2848 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2849 base_class != base_class_end;
2850 ++base_class)
2851 {
2852 // Skip empty base classes
2853 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2854 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2855 continue;
2856
2857 if (base_class->getType().getAsString().compare (name) == 0)
2858 return child_idx;
2859 ++child_idx;
2860 }
2861 }
2862
2863 // Try and find a field that matches NAME
2864 RecordDecl::field_iterator field, field_end;
2865 StringRef name_sref(name);
2866 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2867 field != field_end;
2868 ++field, ++child_idx)
2869 {
2870 if (field->getName().equals (name_sref))
2871 return child_idx;
2872 }
2873
2874 }
2875 break;
2876
Greg Clayton9488b742010-07-28 02:04:09 +00002877 case clang::Type::ObjCObject:
2878 case clang::Type::ObjCInterface:
2879 {
2880 StringRef name_sref(name);
2881 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2882 assert (objc_class_type);
2883 if (objc_class_type)
2884 {
2885 uint32_t child_idx = 0;
2886 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2887
2888 if (class_interface_decl)
2889 {
2890 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2891 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2892
2893 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2894 {
2895 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2896
2897 if (ivar_decl->getName().equals (name_sref))
2898 {
2899 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2900 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2901 ++child_idx;
2902
2903 return child_idx;
2904 }
2905 }
2906
2907 if (superclass_interface_decl)
2908 {
2909 if (superclass_interface_decl->getName().equals (name_sref))
2910 return 0;
2911 }
2912 }
2913 }
2914 }
2915 break;
2916
2917 case clang::Type::ObjCObjectPointer:
2918 {
2919 return GetIndexOfChildWithName (ast_context,
2920 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2921 name,
2922 omit_empty_base_classes);
2923 }
2924 break;
2925
Greg Clayton1674b122010-07-21 22:12:05 +00002926 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002927 {
2928// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2929// const uint64_t element_count = array->getSize().getLimitedValue();
2930//
2931// if (idx < element_count)
2932// {
2933// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2934//
2935// char element_name[32];
2936// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2937//
2938// child_name.assign(element_name);
2939// assert(field_type_info.first % 8 == 0);
2940// child_byte_size = field_type_info.first / 8;
2941// child_byte_offset = idx * child_byte_size;
2942// return array->getElementType().getAsOpaquePtr();
2943// }
2944 }
2945 break;
2946
Greg Clayton1674b122010-07-21 22:12:05 +00002947// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002948// {
2949// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2950// QualType pointee_type = mem_ptr_type->getPointeeType();
2951//
2952// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2953// {
2954// return GetIndexOfChildWithName (ast_context,
2955// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2956// name);
2957// }
2958// }
2959// break;
2960//
Greg Clayton1674b122010-07-21 22:12:05 +00002961 case clang::Type::LValueReference:
2962 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002963 {
2964 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2965 QualType pointee_type = reference_type->getPointeeType();
2966
2967 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2968 {
2969 return GetIndexOfChildWithName (ast_context,
2970 reference_type->getPointeeType().getAsOpaquePtr(),
2971 name,
2972 omit_empty_base_classes);
2973 }
2974 }
2975 break;
2976
Greg Clayton1674b122010-07-21 22:12:05 +00002977 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002978 {
2979 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2980 QualType pointee_type = pointer_type->getPointeeType();
2981
2982 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2983 {
2984 return GetIndexOfChildWithName (ast_context,
2985 pointer_type->getPointeeType().getAsOpaquePtr(),
2986 name,
2987 omit_empty_base_classes);
2988 }
2989 else
2990 {
2991// if (parent_name)
2992// {
2993// child_name.assign(1, '*');
2994// child_name += parent_name;
2995// }
2996//
2997// // We have a pointer to an simple type
2998// if (idx == 0)
2999// {
3000// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3001// assert(clang_type_info.first % 8 == 0);
3002// child_byte_size = clang_type_info.first / 8;
3003// child_byte_offset = 0;
3004// return pointee_type.getAsOpaquePtr();
3005// }
3006 }
3007 }
3008 break;
3009
Greg Clayton1674b122010-07-21 22:12:05 +00003010 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003011 return GetIndexOfChildWithName (ast_context,
3012 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(),
3013 name,
3014 omit_empty_base_classes);
3015
3016 default:
3017 break;
3018 }
3019 }
3020 return UINT32_MAX;
3021}
3022
3023#pragma mark TagType
3024
3025bool
Greg Clayton462d4142010-09-29 01:12:09 +00003026ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003027{
3028 if (tag_clang_type)
3029 {
3030 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003031 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003032 if (clang_type)
3033 {
3034 TagType *tag_type = dyn_cast<TagType>(clang_type);
3035 if (tag_type)
3036 {
3037 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3038 if (tag_decl)
3039 {
3040 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3041 return true;
3042 }
3043 }
3044 }
3045 }
3046 return false;
3047}
3048
3049
3050#pragma mark DeclContext Functions
3051
3052DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003053ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003054{
3055 if (clang_type == NULL)
3056 return NULL;
3057
3058 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003059 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3060 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003061 {
Greg Clayton9488b742010-07-28 02:04:09 +00003062 case clang::Type::FunctionNoProto: break;
3063 case clang::Type::FunctionProto: break;
3064 case clang::Type::IncompleteArray: break;
3065 case clang::Type::VariableArray: break;
3066 case clang::Type::ConstantArray: break;
3067 case clang::Type::ExtVector: break;
3068 case clang::Type::Vector: break;
3069 case clang::Type::Builtin: break;
3070 case clang::Type::BlockPointer: break;
3071 case clang::Type::Pointer: break;
3072 case clang::Type::LValueReference: break;
3073 case clang::Type::RValueReference: break;
3074 case clang::Type::MemberPointer: break;
3075 case clang::Type::Complex: break;
3076 case clang::Type::ObjCObject: break;
3077 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3078 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3079 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3080 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
3081 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003082
Greg Clayton9488b742010-07-28 02:04:09 +00003083 case clang::Type::TypeOfExpr: break;
3084 case clang::Type::TypeOf: break;
3085 case clang::Type::Decltype: break;
3086 //case clang::Type::QualifiedName: break;
3087 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003088 }
3089 // No DeclContext in this type...
3090 return NULL;
3091}
3092
3093#pragma mark Namespace Declarations
3094
3095NamespaceDecl *
3096ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3097{
3098 // TODO: Do something intelligent with the Declaration object passed in
3099 // like maybe filling in the SourceLocation with it...
3100 if (name)
3101 {
3102 ASTContext *ast_context = getASTContext();
3103 if (decl_ctx == NULL)
3104 decl_ctx = ast_context->getTranslationUnitDecl();
3105 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3106 }
3107 return NULL;
3108}
3109
3110
3111#pragma mark Function Types
3112
3113FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003114ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003115{
3116 if (name)
3117 {
3118 ASTContext *ast_context = getASTContext();
3119 assert (ast_context != NULL);
3120
3121 if (name && name[0])
3122 {
3123 return FunctionDecl::Create(*ast_context,
3124 ast_context->getTranslationUnitDecl(),
3125 SourceLocation(),
3126 DeclarationName (&ast_context->Idents.get(name)),
3127 QualType::getFromOpaquePtr(function_clang_type),
3128 NULL,
3129 (FunctionDecl::StorageClass)storage,
3130 (FunctionDecl::StorageClass)storage,
3131 is_inline);
3132 }
3133 else
3134 {
3135 return FunctionDecl::Create(*ast_context,
3136 ast_context->getTranslationUnitDecl(),
3137 SourceLocation(),
3138 DeclarationName (),
3139 QualType::getFromOpaquePtr(function_clang_type),
3140 NULL,
3141 (FunctionDecl::StorageClass)storage,
3142 (FunctionDecl::StorageClass)storage,
3143 is_inline);
3144 }
3145 }
3146 return NULL;
3147}
3148
Greg Clayton462d4142010-09-29 01:12:09 +00003149clang_type_t
3150ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3151 clang_type_t result_type,
3152 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003153 unsigned num_args,
3154 bool is_variadic,
3155 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003156{
Chris Lattner24943d22010-06-08 16:52:24 +00003157 assert (ast_context != NULL);
3158 std::vector<QualType> qual_type_args;
3159 for (unsigned i=0; i<num_args; ++i)
3160 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3161
3162 // TODO: Detect calling convention in DWARF?
3163 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003164 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003165 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003166 is_variadic,
3167 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003168 false, // hasExceptionSpec
3169 false, // hasAnyExceptionSpec,
3170 0, // NumExs
3171 0, // const QualType *ExArray
3172 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3173}
3174
3175ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003176ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003177{
3178 ASTContext *ast_context = getASTContext();
3179 assert (ast_context != NULL);
3180 return ParmVarDecl::Create(*ast_context,
3181 ast_context->getTranslationUnitDecl(),
3182 SourceLocation(),
3183 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003184 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003185 NULL,
3186 (VarDecl::StorageClass)storage,
3187 (VarDecl::StorageClass)storage,
3188 0);
3189}
3190
3191void
3192ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3193{
3194 if (function_decl)
3195 function_decl->setParams (params, num_params);
3196}
3197
3198
3199#pragma mark Array Types
3200
Greg Clayton462d4142010-09-29 01:12:09 +00003201clang_type_t
3202ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003203{
3204 if (element_type)
3205 {
3206 ASTContext *ast_context = getASTContext();
3207 assert (ast_context != NULL);
3208 llvm::APInt ap_element_count (64, element_count);
3209 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3210 ap_element_count,
3211 ArrayType::Normal,
3212 0).getAsOpaquePtr(); // ElemQuals
3213 }
3214 return NULL;
3215}
3216
3217
3218#pragma mark TagDecl
3219
3220bool
Greg Clayton462d4142010-09-29 01:12:09 +00003221ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003222{
3223 if (clang_type)
3224 {
3225 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003226 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003227 if (t)
3228 {
3229 TagType *tag_type = dyn_cast<TagType>(t);
3230 if (tag_type)
3231 {
3232 TagDecl *tag_decl = tag_type->getDecl();
3233 if (tag_decl)
3234 {
3235 tag_decl->startDefinition();
3236 return true;
3237 }
3238 }
3239 }
3240 }
3241 return false;
3242}
3243
3244bool
Greg Clayton462d4142010-09-29 01:12:09 +00003245ClangASTContext::CompleteTagDeclarationDefinition (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 Clayton55b6c532010-09-29 03:44:17 +00003250
3251 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3252
3253 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003254 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003255 cxx_record_decl->completeDefinition();
3256
3257 return true;
3258 }
3259
Sean Callanan04325062010-10-25 00:29:48 +00003260 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3261
3262 if (objc_class_type)
3263 {
3264 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3265
3266 class_interface_decl->setForwardDecl(false);
3267 }
3268
Greg Clayton55b6c532010-09-29 03:44:17 +00003269 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3270
3271 if (enum_type)
3272 {
3273 EnumDecl *enum_decl = enum_type->getDecl();
3274
3275 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003276 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003277 /// TODO This really needs to be fixed.
3278
3279 unsigned NumPositiveBits = 1;
3280 unsigned NumNegativeBits = 0;
3281
Greg Clayton48fbdf72010-10-12 04:29:14 +00003282 ASTContext *ast_context = getASTContext();
3283
3284 QualType promotion_qual_type;
3285 // If the enum integer type is less than an integer in bit width,
3286 // then we must promote it to an integer size.
3287 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3288 {
3289 if (enum_decl->getIntegerType()->isSignedIntegerType())
3290 promotion_qual_type = ast_context->IntTy;
3291 else
3292 promotion_qual_type = ast_context->UnsignedIntTy;
3293 }
3294 else
3295 promotion_qual_type = enum_decl->getIntegerType();
3296
3297 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003298 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003299 }
3300 }
3301 }
3302 return false;
3303}
3304
3305
3306#pragma mark Enumeration Types
3307
Greg Clayton462d4142010-09-29 01:12:09 +00003308clang_type_t
3309ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003310{
3311 // TODO: Do something intelligent with the Declaration object passed in
3312 // like maybe filling in the SourceLocation with it...
3313 ASTContext *ast_context = getASTContext();
3314 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003315
3316 // TODO: ask about these...
3317// const bool IsScoped = false;
3318// const bool IsFixed = false;
3319
3320 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3321 ast_context->getTranslationUnitDecl(),
3322 SourceLocation(),
3323 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3324 SourceLocation(),
3325 NULL); //IsScoped, IsFixed);
Chris Lattner24943d22010-06-08 16:52:24 +00003326 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003327 {
3328 // TODO: check if we should be setting the promotion type too?
3329 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003330 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003331 }
Chris Lattner24943d22010-06-08 16:52:24 +00003332 return NULL;
3333}
3334
Greg Clayton462d4142010-09-29 01:12:09 +00003335clang_type_t
3336ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3337{
3338 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3339
3340 clang::Type *clang_type = enum_qual_type.getTypePtr();
3341 if (clang_type)
3342 {
3343 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3344 if (enum_type)
3345 {
3346 EnumDecl *enum_decl = enum_type->getDecl();
3347 if (enum_decl)
3348 return enum_decl->getIntegerType().getAsOpaquePtr();
3349 }
3350 }
3351 return NULL;
3352}
Chris Lattner24943d22010-06-08 16:52:24 +00003353bool
3354ClangASTContext::AddEnumerationValueToEnumerationType
3355(
Greg Clayton462d4142010-09-29 01:12:09 +00003356 clang_type_t enum_clang_type,
3357 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003358 const Declaration &decl,
3359 const char *name,
3360 int64_t enum_value,
3361 uint32_t enum_value_bit_size
3362)
3363{
3364 if (enum_clang_type && enumerator_clang_type && name)
3365 {
3366 // TODO: Do something intelligent with the Declaration object passed in
3367 // like maybe filling in the SourceLocation with it...
3368 ASTContext *ast_context = getASTContext();
3369 IdentifierTable *identifier_table = getIdentifierTable();
3370
3371 assert (ast_context != NULL);
3372 assert (identifier_table != NULL);
3373 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3374
Greg Clayton1674b122010-07-21 22:12:05 +00003375 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003376 if (clang_type)
3377 {
3378 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3379
3380 if (enum_type)
3381 {
3382 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3383 enum_llvm_apsint = enum_value;
3384 EnumConstantDecl *enumerator_decl =
3385 EnumConstantDecl::Create(*ast_context,
3386 enum_type->getDecl(),
3387 SourceLocation(),
3388 name ? &identifier_table->get(name) : NULL, // Identifier
3389 QualType::getFromOpaquePtr(enumerator_clang_type),
3390 NULL,
3391 enum_llvm_apsint);
3392
3393 if (enumerator_decl)
3394 {
3395 enum_type->getDecl()->addDecl(enumerator_decl);
3396 return true;
3397 }
3398 }
3399 }
3400 }
3401 return false;
3402}
3403
3404#pragma mark Pointers & References
3405
Greg Clayton462d4142010-09-29 01:12:09 +00003406clang_type_t
3407ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003408{
3409 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003410 {
3411 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3412
Greg Clayton03e0f972010-09-13 03:32:57 +00003413 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3414 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003415 {
3416 case clang::Type::ObjCObject:
3417 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003418 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3419
Greg Clayton7b541032010-07-29 20:06:32 +00003420 default:
3421 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3422 }
3423 }
Chris Lattner24943d22010-06-08 16:52:24 +00003424 return NULL;
3425}
3426
Greg Clayton462d4142010-09-29 01:12:09 +00003427clang_type_t
3428ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003429{
3430 if (clang_type)
3431 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3432 return NULL;
3433}
3434
Greg Clayton462d4142010-09-29 01:12:09 +00003435clang_type_t
3436ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003437{
3438 if (clang_type)
3439 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3440 return NULL;
3441}
3442
Greg Clayton462d4142010-09-29 01:12:09 +00003443clang_type_t
3444ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003445{
3446 if (clang_pointee_type && clang_pointee_type)
3447 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3448 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3449 return NULL;
3450}
3451
Chris Lattner24943d22010-06-08 16:52:24 +00003452size_t
3453ClangASTContext::GetPointerBitSize ()
3454{
3455 ASTContext *ast_context = getASTContext();
3456 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3457}
3458
3459bool
Greg Clayton462d4142010-09-29 01:12:09 +00003460ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003461{
3462 if (clang_type == NULL)
3463 return false;
3464
3465 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003466 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3467 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003468 {
Sean Callanan04325062010-10-25 00:29:48 +00003469 case clang::Type::Builtin:
3470 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3471 {
3472 default:
3473 break;
3474 case clang::BuiltinType::ObjCId:
3475 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003476 return true;
3477 }
3478 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003479 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003480 if (target_type)
3481 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3482 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003483 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003484 if (target_type)
3485 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3486 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003487 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003488 if (target_type)
3489 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3490 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003491 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003492 if (target_type)
3493 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3494 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003495 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003496 if (target_type)
3497 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3498 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003499 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003500 if (target_type)
3501 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3502 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003503 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003504 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3505 default:
3506 break;
3507 }
3508 return false;
3509}
3510
Chris Lattner24943d22010-06-08 16:52:24 +00003511bool
Greg Clayton462d4142010-09-29 01:12:09 +00003512ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003513{
3514 if (!clang_type)
3515 return false;
3516
3517 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3518 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3519
3520 if (builtin_type)
3521 {
3522 if (builtin_type->isInteger())
3523 is_signed = builtin_type->isSignedInteger();
3524
3525 return true;
3526 }
3527
3528 return false;
3529}
3530
3531bool
Greg Clayton462d4142010-09-29 01:12:09 +00003532ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003533{
3534 if (clang_type)
3535 {
3536 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003537 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3538 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003539 {
Sean Callanan04325062010-10-25 00:29:48 +00003540 case clang::Type::Builtin:
3541 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3542 {
3543 default:
3544 break;
3545 case clang::BuiltinType::ObjCId:
3546 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003547 return true;
3548 }
3549 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003550 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003551 if (target_type)
3552 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3553 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003554 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003555 if (target_type)
3556 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3557 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003558 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003559 if (target_type)
3560 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3561 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003562 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003563 if (target_type)
3564 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3565 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003566 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003567 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type);
3568 default:
3569 break;
3570 }
3571 }
3572 return false;
3573}
3574
3575bool
Greg Clayton462d4142010-09-29 01:12:09 +00003576ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003577{
3578 if (clang_type)
3579 {
3580 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3581
3582 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3583 {
3584 clang::BuiltinType::Kind kind = BT->getKind();
3585 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3586 {
3587 count = 1;
3588 is_complex = false;
3589 return true;
3590 }
3591 }
3592 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3593 {
3594 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3595 {
3596 count = 2;
3597 is_complex = true;
3598 return true;
3599 }
3600 }
3601 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3602 {
3603 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3604 {
3605 count = VT->getNumElements();
3606 is_complex = false;
3607 return true;
3608 }
3609 }
3610 }
3611 return false;
3612}
3613
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003614
3615bool
3616ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3617{
3618 if (clang_type)
3619 {
3620 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3621
3622 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3623 if (cxx_record_decl)
3624 {
3625 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3626 return true;
3627 }
3628 }
3629 class_name.clear();
3630 return false;
3631}
3632
3633
Greg Clayton1d8173f2010-09-24 05:15:53 +00003634bool
Greg Clayton462d4142010-09-29 01:12:09 +00003635ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003636{
3637 if (clang_type)
3638 {
3639 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3640 if (qual_type->getAsCXXRecordDecl() != NULL)
3641 return true;
3642 }
3643 return false;
3644}
3645
3646bool
Greg Clayton462d4142010-09-29 01:12:09 +00003647ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003648{
3649 if (clang_type)
3650 {
3651 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3652 if (qual_type->isObjCObjectOrInterfaceType())
3653 return true;
3654 }
3655 return false;
3656}
3657
3658
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003659bool
3660ClangASTContext::IsCharType (clang_type_t clang_type)
3661{
3662 if (clang_type)
3663 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3664 return false;
3665}
Chris Lattner24943d22010-06-08 16:52:24 +00003666
3667bool
Greg Clayton462d4142010-09-29 01:12:09 +00003668ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003669{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003670 clang_type_t pointee_or_element_clang_type = NULL;
3671 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3672
3673 if (pointee_or_element_clang_type == NULL)
3674 return false;
3675
3676 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003677 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003678 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3679
3680 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003681 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003682 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3683 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003684 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003685 // We know the size of the array and it could be a C string
3686 // since it is an array of characters
3687 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3688 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003689 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003690 else
Chris Lattner24943d22010-06-08 16:52:24 +00003691 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003692 length = 0;
3693 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003694 }
Chris Lattner24943d22010-06-08 16:52:24 +00003695
Chris Lattner24943d22010-06-08 16:52:24 +00003696 }
3697 }
3698 return false;
3699}
3700
3701bool
Greg Clayton462d4142010-09-29 01:12:09 +00003702ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003703{
3704 if (clang_type)
3705 {
3706 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3707
3708 if (qual_type->isFunctionPointerType())
3709 return true;
3710
3711 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3712 switch (type_class)
3713 {
3714 case clang::Type::Typedef:
3715 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
3716
3717 case clang::Type::LValueReference:
3718 case clang::Type::RValueReference:
3719 {
3720 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3721 if (reference_type)
3722 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3723 }
3724 break;
3725 }
3726 }
3727 return false;
3728}
3729
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003730size_t
3731ClangASTContext::GetArraySize (clang_type_t clang_type)
3732{
3733 if (clang_type)
3734 {
3735 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3736 if (array)
3737 return array->getSize().getLimitedValue();
3738 }
3739 return 0;
3740}
Greg Clayton03e0f972010-09-13 03:32:57 +00003741
3742bool
Greg Clayton462d4142010-09-29 01:12:09 +00003743ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003744{
3745 if (!clang_type)
3746 return false;
3747
3748 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3749
Greg Clayton03e0f972010-09-13 03:32:57 +00003750 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3751 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003752 {
Greg Clayton1674b122010-07-21 22:12:05 +00003753 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003754 if (member_type)
3755 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3756 if (size)
3757 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3758 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003759 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003760 if (member_type)
3761 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3762 if (size)
3763 *size = 0;
3764 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003765 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003766 if (member_type)
3767 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3768 if (size)
3769 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003770 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003771 if (member_type)
3772 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3773 if (size)
3774 *size = 0;
3775 return true;
3776 }
3777 return false;
3778}
3779
3780
3781#pragma mark Typedefs
3782
Greg Clayton462d4142010-09-29 01:12:09 +00003783clang_type_t
3784ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003785{
3786 if (clang_type)
3787 {
3788 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3789 ASTContext *ast_context = getASTContext();
3790 IdentifierTable *identifier_table = getIdentifierTable();
3791 assert (ast_context != NULL);
3792 assert (identifier_table != NULL);
3793 if (decl_ctx == NULL)
3794 decl_ctx = ast_context->getTranslationUnitDecl();
3795 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3796 decl_ctx,
3797 SourceLocation(),
3798 name ? &identifier_table->get(name) : NULL, // Identifier
3799 ast_context->CreateTypeSourceInfo(qual_type));
3800
3801 // Get a uniqued QualType for the typedef decl type
3802 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3803 }
3804 return NULL;
3805}
3806
3807
3808std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003809ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003810{
3811 std::string return_name;
3812
Greg Clayton462d4142010-09-29 01:12:09 +00003813 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003814
Greg Clayton462d4142010-09-29 01:12:09 +00003815 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003816 if (typedef_type)
3817 {
Greg Clayton462d4142010-09-29 01:12:09 +00003818 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003819 return_name = typedef_decl->getQualifiedNameAsString();
3820 }
3821 else
3822 {
3823 return_name = qual_type.getAsString();
3824 }
3825
3826 return return_name;
3827}
3828
3829// Disable this for now since I can't seem to get a nicely formatted float
3830// out of the APFloat class without just getting the float, double or quad
3831// and then using a formatted print on it which defeats the purpose. We ideally
3832// would like to get perfect string values for any kind of float semantics
3833// so we can support remote targets. The code below also requires a patch to
3834// llvm::APInt.
3835//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003836//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 +00003837//{
3838// uint32_t count = 0;
3839// bool is_complex = false;
3840// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3841// {
3842// unsigned num_bytes_per_float = byte_size / count;
3843// unsigned num_bits_per_float = num_bytes_per_float * 8;
3844//
3845// float_str.clear();
3846// uint32_t i;
3847// for (i=0; i<count; i++)
3848// {
3849// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3850// bool is_ieee = false;
3851// APFloat ap_float(ap_int, is_ieee);
3852// char s[1024];
3853// unsigned int hex_digits = 0;
3854// bool upper_case = false;
3855//
3856// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3857// {
3858// if (i > 0)
3859// float_str.append(", ");
3860// float_str.append(s);
3861// if (i == 1 && is_complex)
3862// float_str.append(1, 'i');
3863// }
3864// }
3865// return !float_str.empty();
3866// }
3867// return false;
3868//}
3869
3870size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003871ClangASTContext::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 +00003872{
3873 if (clang_type)
3874 {
3875 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3876 uint32_t count = 0;
3877 bool is_complex = false;
3878 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3879 {
3880 // TODO: handle complex and vector types
3881 if (count != 1)
3882 return false;
3883
3884 StringRef s_sref(s);
3885 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3886
3887 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3888 const uint64_t byte_size = bit_size / 8;
3889 if (dst_size >= byte_size)
3890 {
3891 if (bit_size == sizeof(float)*8)
3892 {
3893 float float32 = ap_float.convertToFloat();
3894 ::memcpy (dst, &float32, byte_size);
3895 return byte_size;
3896 }
3897 else if (bit_size >= 64)
3898 {
3899 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3900 ::memcpy (dst, ap_int.getRawData(), byte_size);
3901 return byte_size;
3902 }
3903 }
3904 }
3905 }
3906 return 0;
3907}
Sean Callanana751f7b2010-09-17 02:24:29 +00003908
3909unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00003910ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00003911{
3912 assert (clang_type);
3913
3914 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3915
3916 return qual_type.getQualifiers().getCVRQualifiers();
3917}