blob: 90a1352f236679fc5fd865d8a19d1dd9ef845c89 [file] [log] [blame]
Chris Lattner30fdc8d2010-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 Friedman932197d2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Sean Callanan246549c2010-07-08 18:16:16 +000017#define NDEBUG
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "clang/AST/ASTContext.h"
19#include "clang/AST/ASTImporter.h"
20#include "clang/AST/CXXInheritance.h"
Greg Clayton8cf05932010-07-22 18:30:50 +000021#include "clang/AST/DeclObjC.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "clang/AST/RecordLayout.h"
23#include "clang/AST/Type.h"
24#include "clang/Basic/Builtins.h"
25#include "clang/Basic/FileManager.h"
Sean Callanan79439e82010-11-18 02:56:27 +000026#include "clang/Basic/FileSystemOptions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "clang/Basic/SourceManager.h"
28#include "clang/Basic/TargetInfo.h"
29#include "clang/Basic/TargetOptions.h"
30#include "clang/Frontend/FrontendOptions.h"
31#include "clang/Frontend/LangStandard.h"
Sean Callanan246549c2010-07-08 18:16:16 +000032#undef NDEBUG
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Core/dwarf.h"
Greg Clayton73b472d2010-10-27 03:32:59 +000035#include "lldb/Core/Flags.h"
Sean Callananfb8b7092010-10-28 18:19:36 +000036#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037
Eli Friedman932197d2010-06-13 19:06:42 +000038#include <stdio.h>
39
Greg Claytonc86103d2010-08-05 01:57:25 +000040using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041using namespace lldb_private;
42using namespace llvm;
43using namespace clang;
44
Greg Clayton8cf05932010-07-22 18:30:50 +000045static AccessSpecifier
Greg Claytonc86103d2010-08-05 01:57:25 +000046ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +000047{
48 switch (access)
49 {
Greg Claytonc86103d2010-08-05 01:57:25 +000050 default: break;
51 case eAccessNone: return AS_none;
52 case eAccessPublic: return AS_public;
53 case eAccessPrivate: return AS_private;
54 case eAccessProtected: return AS_protected;
Greg Clayton8cf05932010-07-22 18:30:50 +000055 }
56 return AS_none;
57}
58
59static ObjCIvarDecl::AccessControl
Greg Claytonc86103d2010-08-05 01:57:25 +000060ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +000061{
62 switch (access)
63 {
Greg Claytonc86103d2010-08-05 01:57:25 +000064 default: break;
65 case eAccessNone: return ObjCIvarDecl::None;
66 case eAccessPublic: return ObjCIvarDecl::Public;
67 case eAccessPrivate: return ObjCIvarDecl::Private;
68 case eAccessProtected: return ObjCIvarDecl::Protected;
69 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton8cf05932010-07-22 18:30:50 +000070 }
71 return ObjCIvarDecl::None;
72}
73
74
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075static void
76ParseLangArgs
77(
78 LangOptions &Opts,
Greg Clayton94e5d782010-06-13 17:34:29 +000079 InputKind IK
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080)
81{
82 // FIXME: Cleanup per-file based stuff.
83
84 // Set some properties which depend soley on the input kind; it would be nice
85 // to move these to the language standard, and have the driver resolve the
86 // input kind + language standard.
Greg Clayton94e5d782010-06-13 17:34:29 +000087 if (IK == IK_Asm) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088 Opts.AsmPreprocessor = 1;
Greg Clayton94e5d782010-06-13 17:34:29 +000089 } else if (IK == IK_ObjC ||
90 IK == IK_ObjCXX ||
91 IK == IK_PreprocessedObjC ||
92 IK == IK_PreprocessedObjCXX) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093 Opts.ObjC1 = Opts.ObjC2 = 1;
94 }
95
96 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
97
98 if (LangStd == LangStandard::lang_unspecified) {
99 // Based on the base language, pick one.
100 switch (IK) {
Greg Clayton94e5d782010-06-13 17:34:29 +0000101 case IK_None:
102 case IK_AST:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103 assert(0 && "Invalid input kind!");
Greg Clayton94e5d782010-06-13 17:34:29 +0000104 case IK_OpenCL:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105 LangStd = LangStandard::lang_opencl;
106 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000107 case IK_Asm:
108 case IK_C:
109 case IK_PreprocessedC:
110 case IK_ObjC:
111 case IK_PreprocessedObjC:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112 LangStd = LangStandard::lang_gnu99;
113 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000114 case IK_CXX:
115 case IK_PreprocessedCXX:
116 case IK_ObjCXX:
117 case IK_PreprocessedObjCXX:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118 LangStd = LangStandard::lang_gnucxx98;
119 break;
120 }
121 }
122
123 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
124 Opts.BCPLComment = Std.hasBCPLComments();
125 Opts.C99 = Std.isC99();
126 Opts.CPlusPlus = Std.isCPlusPlus();
127 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
128 Opts.Digraphs = Std.hasDigraphs();
129 Opts.GNUMode = Std.isGNUMode();
130 Opts.GNUInline = !Std.isC99();
131 Opts.HexFloats = Std.hasHexFloats();
132 Opts.ImplicitInt = Std.hasImplicitInt();
133
134 // OpenCL has some additional defaults.
135 if (LangStd == LangStandard::lang_opencl) {
136 Opts.OpenCL = 1;
137 Opts.AltiVec = 1;
138 Opts.CXXOperatorNames = 1;
139 Opts.LaxVectorConversions = 1;
140 }
141
142 // OpenCL and C++ both have bool, true, false keywords.
143 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
144
145// if (Opts.CPlusPlus)
146// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
147//
148// if (Args.hasArg(OPT_fobjc_gc_only))
149// Opts.setGCMode(LangOptions::GCOnly);
150// else if (Args.hasArg(OPT_fobjc_gc))
151// Opts.setGCMode(LangOptions::HybridGC);
152//
153// if (Args.hasArg(OPT_print_ivar_layout))
154// Opts.ObjCGCBitmapPrint = 1;
155//
156// if (Args.hasArg(OPT_faltivec))
157// Opts.AltiVec = 1;
158//
159// if (Args.hasArg(OPT_pthread))
160// Opts.POSIXThreads = 1;
161//
162// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
163// "default");
164// if (Vis == "default")
Sean Callanan31e851c2010-10-29 18:38:40 +0000165 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166// else if (Vis == "hidden")
167// Opts.setVisibilityMode(LangOptions::Hidden);
168// else if (Vis == "protected")
169// Opts.setVisibilityMode(LangOptions::Protected);
170// else
171// Diags.Report(diag::err_drv_invalid_value)
172// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
173
174// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
175
176 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
177 // is specified, or -std is set to a conforming mode.
178 Opts.Trigraphs = !Opts.GNUMode;
179// if (Args.hasArg(OPT_trigraphs))
180// Opts.Trigraphs = 1;
181//
182// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
183// OPT_fno_dollars_in_identifiers,
184// !Opts.AsmPreprocessor);
185// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
186// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
187// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
188// if (Args.hasArg(OPT_fno_lax_vector_conversions))
189// Opts.LaxVectorConversions = 0;
190// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
191// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
192// Opts.Blocks = Args.hasArg(OPT_fblocks);
193// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
194// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
195// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
196// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
197// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
198// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
199// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
200// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
201// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
202// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
203// Diags);
204// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
205// Opts.ObjCConstantStringClass = getLastArgValue(Args,
206// OPT_fconstant_string_class);
207// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
208// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
209// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
210// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
211// Opts.Static = Args.hasArg(OPT_static_define);
212 Opts.OptimizeSize = 0;
213
214 // FIXME: Eliminate this dependency.
215// unsigned Opt =
216// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
217// Opts.Optimize = Opt != 0;
218 unsigned Opt = 0;
219
220 // This is the __NO_INLINE__ define, which just depends on things like the
221 // optimization level and -fno-inline, not actually whether the backend has
222 // inlining enabled.
223 //
224 // FIXME: This is affected by other options (-fno-inline).
225 Opts.NoInline = !Opt;
226
227// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
228// switch (SSP) {
229// default:
230// Diags.Report(diag::err_drv_invalid_value)
231// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
232// break;
233// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
234// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
235// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
236// }
237}
238
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240ClangASTContext::ClangASTContext(const char *target_triple) :
241 m_target_triple(),
242 m_ast_context_ap(),
243 m_language_options_ap(),
244 m_source_manager_ap(),
245 m_diagnostic_ap(),
246 m_target_options_ap(),
247 m_target_info_ap(),
248 m_identifier_table_ap(),
249 m_selector_table_ap(),
250 m_builtins_ap()
251{
252 if (target_triple && target_triple[0])
253 m_target_triple.assign (target_triple);
254}
255
256//----------------------------------------------------------------------
257// Destructor
258//----------------------------------------------------------------------
259ClangASTContext::~ClangASTContext()
260{
261 m_builtins_ap.reset();
262 m_selector_table_ap.reset();
263 m_identifier_table_ap.reset();
264 m_target_info_ap.reset();
265 m_target_options_ap.reset();
266 m_diagnostic_ap.reset();
267 m_source_manager_ap.reset();
268 m_language_options_ap.reset();
269 m_ast_context_ap.reset();
270}
271
272
273void
274ClangASTContext::Clear()
275{
276 m_ast_context_ap.reset();
277 m_language_options_ap.reset();
278 m_source_manager_ap.reset();
279 m_diagnostic_ap.reset();
280 m_target_options_ap.reset();
281 m_target_info_ap.reset();
282 m_identifier_table_ap.reset();
283 m_selector_table_ap.reset();
284 m_builtins_ap.reset();
285}
286
287const char *
288ClangASTContext::GetTargetTriple ()
289{
290 return m_target_triple.c_str();
291}
292
293void
294ClangASTContext::SetTargetTriple (const char *target_triple)
295{
296 Clear();
297 m_target_triple.assign(target_triple);
298}
299
300
301ASTContext *
302ClangASTContext::getASTContext()
303{
304 if (m_ast_context_ap.get() == NULL)
305 {
306 m_ast_context_ap.reset(
307 new ASTContext(
308 *getLanguageOptions(),
309 *getSourceManager(),
310 *getTargetInfo(),
311 *getIdentifierTable(),
312 *getSelectorTable(),
Greg Claytone6371122010-07-30 20:30:44 +0000313 *getBuiltinContext(),
314 0));
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000315
316 m_ast_context_ap->getDiagnostics().setClient(getDiagnosticClient(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317 }
318 return m_ast_context_ap.get();
319}
320
321Builtin::Context *
322ClangASTContext::getBuiltinContext()
323{
324 if (m_builtins_ap.get() == NULL)
325 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
326 return m_builtins_ap.get();
327}
328
329IdentifierTable *
330ClangASTContext::getIdentifierTable()
331{
332 if (m_identifier_table_ap.get() == NULL)
333 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
334 return m_identifier_table_ap.get();
335}
336
337LangOptions *
338ClangASTContext::getLanguageOptions()
339{
340 if (m_language_options_ap.get() == NULL)
341 {
342 m_language_options_ap.reset(new LangOptions());
Greg Clayton94e5d782010-06-13 17:34:29 +0000343 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
344// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345 }
346 return m_language_options_ap.get();
347}
348
349SelectorTable *
350ClangASTContext::getSelectorTable()
351{
352 if (m_selector_table_ap.get() == NULL)
353 m_selector_table_ap.reset (new SelectorTable());
354 return m_selector_table_ap.get();
355}
356
Sean Callanan79439e82010-11-18 02:56:27 +0000357clang::FileManager *
358ClangASTContext::getFileManager()
359{
360 if (m_file_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000361 {
362 clang::FileSystemOptions file_system_options;
363 m_file_manager_ap.reset(new clang::FileManager(file_system_options));
364 }
Sean Callanan79439e82010-11-18 02:56:27 +0000365 return m_file_manager_ap.get();
366}
367
Greg Claytone1a916a2010-07-21 22:12:05 +0000368clang::SourceManager *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369ClangASTContext::getSourceManager()
370{
371 if (m_source_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000372 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373 return m_source_manager_ap.get();
374}
375
376Diagnostic *
377ClangASTContext::getDiagnostic()
378{
379 if (m_diagnostic_ap.get() == NULL)
Greg Claytona651b532010-11-19 21:46:54 +0000380 {
381 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
382 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
383 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 return m_diagnostic_ap.get();
385}
386
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000387class NullDiagnosticClient : public DiagnosticClient
388{
389public:
390 NullDiagnosticClient ()
391 {
392 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
393 }
394
395 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
396 {
397 if (m_log)
398 {
399 llvm::SmallVectorImpl<char> diag_str(10);
400 info.FormatDiagnostic(diag_str);
401 diag_str.push_back('\0');
402 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
403 }
404 }
405private:
406 LogSP m_log;
407};
408
409DiagnosticClient *
410ClangASTContext::getDiagnosticClient()
411{
412 if (m_diagnostic_client_ap.get() == NULL)
413 m_diagnostic_client_ap.reset(new NullDiagnosticClient);
414
415 return m_diagnostic_client_ap.get();
416}
417
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000418TargetOptions *
419ClangASTContext::getTargetOptions()
420{
421 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
422 {
423 m_target_options_ap.reset (new TargetOptions());
424 if (m_target_options_ap.get())
425 m_target_options_ap->Triple = m_target_triple;
426 }
427 return m_target_options_ap.get();
428}
429
430
431TargetInfo *
432ClangASTContext::getTargetInfo()
433{
434 // target_triple should be something like "x86_64-apple-darwin10"
435 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
436 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
437 return m_target_info_ap.get();
438}
439
440#pragma mark Basic Types
441
442static inline bool
443QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type)
444{
445 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type);
446 if (qual_type_bit_size == bit_size)
447 return true;
448 return false;
449}
450
Greg Clayton1be10fc2010-09-29 01:12:09 +0000451clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +0000452ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453{
454 ASTContext *ast_context = getASTContext();
455
456 assert (ast_context != NULL);
457
458 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size);
459}
460
Greg Clayton1be10fc2010-09-29 01:12:09 +0000461clang_type_t
462ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463{
464 if (!ast_context)
465 return NULL;
466
467 switch (encoding)
468 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000469 case eEncodingInvalid:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000470 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
471 return ast_context->VoidPtrTy.getAsOpaquePtr();
472 break;
473
Greg Claytonc86103d2010-08-05 01:57:25 +0000474 case eEncodingUint:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
476 return ast_context->UnsignedCharTy.getAsOpaquePtr();
477 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
478 return ast_context->UnsignedShortTy.getAsOpaquePtr();
479 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
480 return ast_context->UnsignedIntTy.getAsOpaquePtr();
481 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
482 return ast_context->UnsignedLongTy.getAsOpaquePtr();
483 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
484 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
485 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
486 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
487 break;
488
Greg Claytonc86103d2010-08-05 01:57:25 +0000489 case eEncodingSint:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
491 return ast_context->CharTy.getAsOpaquePtr();
492 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
493 return ast_context->ShortTy.getAsOpaquePtr();
494 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
495 return ast_context->IntTy.getAsOpaquePtr();
496 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
497 return ast_context->LongTy.getAsOpaquePtr();
498 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
499 return ast_context->LongLongTy.getAsOpaquePtr();
500 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
501 return ast_context->Int128Ty.getAsOpaquePtr();
502 break;
503
Greg Claytonc86103d2010-08-05 01:57:25 +0000504 case eEncodingIEEE754:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000505 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
506 return ast_context->FloatTy.getAsOpaquePtr();
507 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
508 return ast_context->DoubleTy.getAsOpaquePtr();
509 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
510 return ast_context->LongDoubleTy.getAsOpaquePtr();
511 break;
512
Greg Claytonc86103d2010-08-05 01:57:25 +0000513 case eEncodingVector:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514 default:
515 break;
516 }
517
518 return NULL;
519}
520
Greg Clayton1be10fc2010-09-29 01:12:09 +0000521clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000522ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
523{
524 ASTContext *ast_context = getASTContext();
525
526 #define streq(a,b) strcmp(a,b) == 0
527 assert (ast_context != NULL);
528 if (ast_context)
529 {
530 switch (dw_ate)
531 {
532 default:
533 break;
534
535 case DW_ATE_address:
536 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy))
537 return ast_context->VoidPtrTy.getAsOpaquePtr();
538 break;
539
540 case DW_ATE_boolean:
541 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy))
542 return ast_context->BoolTy.getAsOpaquePtr();
543 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
544 return ast_context->UnsignedCharTy.getAsOpaquePtr();
545 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
546 return ast_context->UnsignedShortTy.getAsOpaquePtr();
547 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
548 return ast_context->UnsignedIntTy.getAsOpaquePtr();
549 break;
550
Greg Clayton49462ea2011-01-15 02:52:14 +0000551 case DW_ATE_lo_user:
552 // This has been seen to mean DW_AT_complex_integer
553 if (strcmp(type_name, "complex") == 0)
554 {
555 clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
556 return ast_context->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
557 }
558 break;
559
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000560 case DW_ATE_complex_float:
561 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
562 return ast_context->FloatComplexTy.getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000563 else if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564 return ast_context->DoubleComplexTy.getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000565 else if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000566 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000567 else
568 {
569 clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
570 return ast_context->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
571 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000572 break;
573
574 case DW_ATE_float:
575 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
576 return ast_context->FloatTy.getAsOpaquePtr();
577 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
578 return ast_context->DoubleTy.getAsOpaquePtr();
579 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
580 return ast_context->LongDoubleTy.getAsOpaquePtr();
581 break;
582
583 case DW_ATE_signed:
584 if (type_name)
585 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000586 if (strstr(type_name, "long long"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000587 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000588 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
589 return ast_context->LongLongTy.getAsOpaquePtr();
590 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000591 else if (strstr(type_name, "long"))
592 {
593 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
594 return ast_context->LongTy.getAsOpaquePtr();
595 }
596 else if (strstr(type_name, "short"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000597 {
598 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
599 return ast_context->ShortTy.getAsOpaquePtr();
600 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000601 else if (strstr(type_name, "char"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602 {
603 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
604 return ast_context->CharTy.getAsOpaquePtr();
605 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
606 return ast_context->SignedCharTy.getAsOpaquePtr();
607 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000608 else if (strstr(type_name, "int"))
609 {
610 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
611 return ast_context->IntTy.getAsOpaquePtr();
612 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
613 return ast_context->Int128Ty.getAsOpaquePtr();
614 }
615 else if (streq(type_name, "wchar_t"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000616 {
617 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
618 return ast_context->WCharTy.getAsOpaquePtr();
619 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000620 }
621 // We weren't able to match up a type name, just search by size
622 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
623 return ast_context->CharTy.getAsOpaquePtr();
624 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
625 return ast_context->ShortTy.getAsOpaquePtr();
626 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
627 return ast_context->IntTy.getAsOpaquePtr();
628 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
629 return ast_context->LongTy.getAsOpaquePtr();
630 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
631 return ast_context->LongLongTy.getAsOpaquePtr();
632 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
633 return ast_context->Int128Ty.getAsOpaquePtr();
634 break;
635
636 case DW_ATE_signed_char:
637 if (type_name)
638 {
639 if (streq(type_name, "signed char"))
640 {
641 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
642 return ast_context->SignedCharTy.getAsOpaquePtr();
643 }
644 }
645 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
646 return ast_context->CharTy.getAsOpaquePtr();
647 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
648 return ast_context->SignedCharTy.getAsOpaquePtr();
649 break;
650
651 case DW_ATE_unsigned:
652 if (type_name)
653 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000654 if (strstr(type_name, "long long"))
655 {
656 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
657 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
658 }
659 else if (strstr(type_name, "long"))
660 {
661 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
662 return ast_context->UnsignedLongTy.getAsOpaquePtr();
663 }
664 else if (strstr(type_name, "short"))
665 {
666 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
667 return ast_context->UnsignedShortTy.getAsOpaquePtr();
668 }
669 else if (strstr(type_name, "char"))
670 {
671 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
672 return ast_context->UnsignedCharTy.getAsOpaquePtr();
673 }
674 else if (strstr(type_name, "int"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000675 {
676 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
677 return ast_context->UnsignedIntTy.getAsOpaquePtr();
678 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
679 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
680 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681 }
682 // We weren't able to match up a type name, just search by size
683 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
684 return ast_context->UnsignedCharTy.getAsOpaquePtr();
685 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
686 return ast_context->UnsignedShortTy.getAsOpaquePtr();
687 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
688 return ast_context->UnsignedIntTy.getAsOpaquePtr();
689 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
690 return ast_context->UnsignedLongTy.getAsOpaquePtr();
691 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
692 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
693 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
694 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
695 break;
696
697 case DW_ATE_unsigned_char:
698 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
699 return ast_context->UnsignedCharTy.getAsOpaquePtr();
700 break;
701
702 case DW_ATE_imaginary_float:
703 break;
704 }
705 }
706 // This assert should fire for anything that we don't catch above so we know
707 // to fix any issues we run into.
708 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
709 return NULL;
710}
711
Greg Clayton1be10fc2010-09-29 01:12:09 +0000712clang_type_t
713ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714{
Sean Callanan6fe64b52010-09-17 02:24:29 +0000715 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716}
717
Greg Clayton1be10fc2010-09-29 01:12:09 +0000718clang_type_t
Sean Callananf7c3e272010-11-19 02:52:21 +0000719ClangASTContext::GetBuiltInType_bool()
720{
721 return getASTContext()->BoolTy.getAsOpaquePtr();
722}
723
724clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000725ClangASTContext::GetBuiltInType_objc_id()
726{
Sean Callananf6c73082010-12-06 23:53:20 +0000727 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000728}
729
Greg Clayton1be10fc2010-09-29 01:12:09 +0000730clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000731ClangASTContext::GetBuiltInType_objc_Class()
732{
Sean Callanana2424172010-10-25 00:29:48 +0000733 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000734}
735
Greg Clayton1be10fc2010-09-29 01:12:09 +0000736clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000737ClangASTContext::GetBuiltInType_objc_selector()
738{
Sean Callananf6c73082010-12-06 23:53:20 +0000739 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000740}
741
Greg Clayton1be10fc2010-09-29 01:12:09 +0000742clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000743ClangASTContext::GetCStringType (bool is_const)
744{
745 QualType char_type(getASTContext()->CharTy);
746
747 if (is_const)
748 char_type.addConst();
749
750 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
751}
752
Greg Clayton1be10fc2010-09-29 01:12:09 +0000753clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754ClangASTContext::GetVoidPtrType (bool is_const)
755{
756 return GetVoidPtrType(getASTContext(), is_const);
757}
758
Greg Clayton1be10fc2010-09-29 01:12:09 +0000759clang_type_t
760ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761{
762 QualType void_ptr_type(ast_context->VoidPtrTy);
763
764 if (is_const)
765 void_ptr_type.addConst();
766
767 return void_ptr_type.getAsOpaquePtr();
768}
769
Greg Clayton1be10fc2010-09-29 01:12:09 +0000770clang_type_t
Greg Clayton38a61402010-12-02 23:20:03 +0000771ClangASTContext::CopyType (ASTContext *dst_ast,
772 ASTContext *src_ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000773 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774{
Sean Callanan79439e82010-11-18 02:56:27 +0000775 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000776 FileManager file_manager (file_system_options);
777 ASTImporter importer(*dst_ast, file_manager,
778 *src_ast, file_manager);
Sean Callanan0617fcb2010-11-09 22:37:10 +0000779
Greg Clayton38a61402010-12-02 23:20:03 +0000780 QualType src (QualType::getFromOpaquePtr(clang_type));
781 QualType dst (importer.Import(src));
Sean Callanan0617fcb2010-11-09 22:37:10 +0000782
783 return dst.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000784}
785
Greg Clayton526e5af2010-11-13 03:52:47 +0000786
787clang::Decl *
Greg Clayton38a61402010-12-02 23:20:03 +0000788ClangASTContext::CopyDecl (ASTContext *dst_ast,
789 ASTContext *src_ast,
Greg Clayton526e5af2010-11-13 03:52:47 +0000790 clang::Decl *source_decl)
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000791{
Sean Callanan79439e82010-11-18 02:56:27 +0000792 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000793 FileManager file_manager (file_system_options);
794 ASTImporter importer(*dst_ast, file_manager,
795 *src_ast, file_manager);
Greg Clayton526e5af2010-11-13 03:52:47 +0000796
797 return importer.Import(source_decl);
798}
799
Sean Callanan23a30272010-07-16 00:00:27 +0000800bool
Greg Clayton1be10fc2010-09-29 01:12:09 +0000801ClangASTContext::AreTypesSame(ASTContext *ast_context,
802 clang_type_t type1,
803 clang_type_t type2)
Sean Callanan4dcca2622010-07-15 22:30:52 +0000804{
805 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
806 QualType::getFromOpaquePtr(type2));
807}
808
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000809#pragma mark CVR modifiers
810
Greg Clayton1be10fc2010-09-29 01:12:09 +0000811clang_type_t
812ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000813{
814 if (clang_type)
815 {
816 QualType result(QualType::getFromOpaquePtr(clang_type));
817 result.addConst();
818 return result.getAsOpaquePtr();
819 }
820 return NULL;
821}
822
Greg Clayton1be10fc2010-09-29 01:12:09 +0000823clang_type_t
824ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000825{
826 if (clang_type)
827 {
828 QualType result(QualType::getFromOpaquePtr(clang_type));
829 result.getQualifiers().setRestrict (true);
830 return result.getAsOpaquePtr();
831 }
832 return NULL;
833}
834
Greg Clayton1be10fc2010-09-29 01:12:09 +0000835clang_type_t
836ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837{
838 if (clang_type)
839 {
840 QualType result(QualType::getFromOpaquePtr(clang_type));
841 result.getQualifiers().setVolatile (true);
842 return result.getAsOpaquePtr();
843 }
844 return NULL;
845}
846
847#pragma mark Structure, Unions, Classes
848
Greg Clayton1be10fc2010-09-29 01:12:09 +0000849clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +0000850ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851{
852 ASTContext *ast_context = getASTContext();
853 assert (ast_context != NULL);
Sean Callanana2424172010-10-25 00:29:48 +0000854
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000855 if (decl_ctx == NULL)
856 decl_ctx = ast_context->getTranslationUnitDecl();
857
Greg Clayton9e409562010-07-28 02:04:09 +0000858
Greg Claytonc86103d2010-08-05 01:57:25 +0000859 if (language == eLanguageTypeObjC)
Greg Clayton9e409562010-07-28 02:04:09 +0000860 {
Greg Claytonaaf99e02010-10-11 02:25:34 +0000861 bool isForwardDecl = true;
Greg Clayton9e409562010-07-28 02:04:09 +0000862 bool isInternal = false;
863 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
864 }
865
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000866 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
867 // we will need to update this code. I was told to currently always use
868 // the CXXRecordDecl class since we often don't know from debug information
869 // if something is struct or a class, so we default to always use the more
870 // complete definition just in case.
871 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
872 (TagDecl::TagKind)kind,
873 decl_ctx,
874 SourceLocation(),
875 name && name[0] ? &ast_context->Idents.get(name) : NULL);
876
877 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
878}
879
Greg Claytona3c444a2010-10-01 23:13:49 +0000880static bool
881IsOperator (const char *name, OverloadedOperatorKind &op_kind)
882{
883 if (name == NULL || name[0] == '\0')
884 return false;
885
Sean Callanana43f20d2010-12-10 19:51:54 +0000886#define OPERATOR_PREFIX "operator"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000887#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
Sean Callananbfeff8c2010-12-10 02:15:55 +0000888
889 const char *post_op_name = NULL;
890
Sean Callanana43f20d2010-12-10 19:51:54 +0000891 bool no_space = true;
Sean Callananbfeff8c2010-12-10 02:15:55 +0000892
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000893 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
Greg Claytona3c444a2010-10-01 23:13:49 +0000894 return false;
895
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000896 post_op_name = name + OPERATOR_PREFIX_LENGTH;
897
Sean Callanana43f20d2010-12-10 19:51:54 +0000898 if (post_op_name[0] == ' ')
899 {
900 post_op_name++;
901 no_space = false;
902 }
903
904#undef OPERATOR_PREFIX
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000905#undef OPERATOR_PREFIX_LENGTH
Sean Callanana43f20d2010-12-10 19:51:54 +0000906
Greg Claytona3c444a2010-10-01 23:13:49 +0000907 // This is an operator, set the overloaded operator kind to invalid
908 // in case this is a conversion operator...
909 op_kind = NUM_OVERLOADED_OPERATORS;
910
911 switch (post_op_name[0])
912 {
Sean Callananbfeff8c2010-12-10 02:15:55 +0000913 default:
914 if (no_space)
915 return false;
916 break;
Greg Claytona3c444a2010-10-01 23:13:49 +0000917 case 'n':
Sean Callananbfeff8c2010-12-10 02:15:55 +0000918 if (no_space)
919 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +0000920 if (strcmp (post_op_name, "new") == 0)
921 op_kind = OO_New;
922 else if (strcmp (post_op_name, "new[]") == 0)
923 op_kind = OO_Array_New;
924 break;
925
926 case 'd':
Sean Callananbfeff8c2010-12-10 02:15:55 +0000927 if (no_space)
928 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +0000929 if (strcmp (post_op_name, "delete") == 0)
930 op_kind = OO_Delete;
931 else if (strcmp (post_op_name, "delete[]") == 0)
932 op_kind = OO_Array_Delete;
933 break;
934
935 case '+':
936 if (post_op_name[1] == '\0')
937 op_kind = OO_Plus;
938 else if (post_op_name[2] == '\0')
939 {
940 if (post_op_name[1] == '=')
941 op_kind = OO_PlusEqual;
942 else if (post_op_name[1] == '+')
943 op_kind = OO_PlusPlus;
944 }
945 break;
946
947 case '-':
948 if (post_op_name[1] == '\0')
949 op_kind = OO_Minus;
950 else if (post_op_name[2] == '\0')
951 {
952 switch (post_op_name[1])
953 {
954 case '=': op_kind = OO_MinusEqual; break;
955 case '-': op_kind = OO_MinusMinus; break;
956 case '>': op_kind = OO_Arrow; break;
957 }
958 }
959 else if (post_op_name[3] == '\0')
960 {
961 if (post_op_name[2] == '*')
962 op_kind = OO_ArrowStar; break;
963 }
964 break;
965
966 case '*':
967 if (post_op_name[1] == '\0')
968 op_kind = OO_Star;
969 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
970 op_kind = OO_StarEqual;
971 break;
972
973 case '/':
974 if (post_op_name[1] == '\0')
975 op_kind = OO_Slash;
976 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
977 op_kind = OO_SlashEqual;
978 break;
979
980 case '%':
981 if (post_op_name[1] == '\0')
982 op_kind = OO_Percent;
983 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
984 op_kind = OO_PercentEqual;
985 break;
986
987
988 case '^':
989 if (post_op_name[1] == '\0')
990 op_kind = OO_Caret;
991 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
992 op_kind = OO_CaretEqual;
993 break;
994
995 case '&':
996 if (post_op_name[1] == '\0')
997 op_kind = OO_Amp;
998 else if (post_op_name[2] == '\0')
999 {
1000 switch (post_op_name[1])
1001 {
1002 case '=': op_kind = OO_AmpEqual; break;
1003 case '&': op_kind = OO_AmpAmp; break;
1004 }
1005 }
1006 break;
1007
1008 case '|':
1009 if (post_op_name[1] == '\0')
1010 op_kind = OO_Pipe;
1011 else if (post_op_name[2] == '\0')
1012 {
1013 switch (post_op_name[1])
1014 {
1015 case '=': op_kind = OO_PipeEqual; break;
1016 case '|': op_kind = OO_PipePipe; break;
1017 }
1018 }
1019 break;
1020
1021 case '~':
1022 if (post_op_name[1] == '\0')
1023 op_kind = OO_Tilde;
1024 break;
1025
1026 case '!':
1027 if (post_op_name[1] == '\0')
1028 op_kind = OO_Exclaim;
1029 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1030 op_kind = OO_ExclaimEqual;
1031 break;
1032
1033 case '=':
1034 if (post_op_name[1] == '\0')
1035 op_kind = OO_Equal;
1036 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1037 op_kind = OO_EqualEqual;
1038 break;
1039
1040 case '<':
1041 if (post_op_name[1] == '\0')
1042 op_kind = OO_Less;
1043 else if (post_op_name[2] == '\0')
1044 {
1045 switch (post_op_name[1])
1046 {
1047 case '<': op_kind = OO_LessLess; break;
1048 case '=': op_kind = OO_LessEqual; break;
1049 }
1050 }
1051 else if (post_op_name[3] == '\0')
1052 {
1053 if (post_op_name[2] == '=')
1054 op_kind = OO_LessLessEqual;
1055 }
1056 break;
1057
1058 case '>':
1059 if (post_op_name[1] == '\0')
1060 op_kind = OO_Greater;
1061 else if (post_op_name[2] == '\0')
1062 {
1063 switch (post_op_name[1])
1064 {
1065 case '>': op_kind = OO_GreaterGreater; break;
1066 case '=': op_kind = OO_GreaterEqual; break;
1067 }
1068 }
1069 else if (post_op_name[1] == '>' &&
1070 post_op_name[2] == '=' &&
1071 post_op_name[3] == '\0')
1072 {
1073 op_kind = OO_GreaterGreaterEqual;
1074 }
1075 break;
1076
1077 case ',':
1078 if (post_op_name[1] == '\0')
1079 op_kind = OO_Comma;
1080 break;
1081
1082 case '(':
1083 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1084 op_kind = OO_Call;
1085 break;
1086
1087 case '[':
1088 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1089 op_kind = OO_Subscript;
1090 break;
1091 }
1092
1093 return true;
1094}
Greg Claytona51ed9b2010-09-23 01:09:21 +00001095CXXMethodDecl *
Sean Callanan61da09b2010-09-17 02:58:26 +00001096ClangASTContext::AddMethodToCXXRecordType
1097(
Greg Clayton1be10fc2010-09-29 01:12:09 +00001098 ASTContext *ast_context,
1099 clang_type_t record_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001100 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001101 clang_type_t method_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001102 lldb::AccessType access,
Greg Clayton0fffff52010-09-24 05:15:53 +00001103 bool is_virtual,
1104 bool is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00001105 bool is_inline,
1106 bool is_explicit
Greg Claytona51ed9b2010-09-23 01:09:21 +00001107)
Sean Callanan61da09b2010-09-17 02:58:26 +00001108{
Sean Callananfc55f5d2010-09-21 00:44:12 +00001109 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chend440bcc2010-09-28 16:10:54 +00001110 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001111
1112 assert(ast_context);
1113
1114 IdentifierTable *identifier_table = &ast_context->Idents;
1115
1116 assert(identifier_table);
1117
Sean Callananfc55f5d2010-09-21 00:44:12 +00001118 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001119
1120 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan61da09b2010-09-17 02:58:26 +00001121
Greg Clayton0fffff52010-09-24 05:15:53 +00001122 if (clang_type == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001123 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001124
Greg Clayton0fffff52010-09-24 05:15:53 +00001125 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan61da09b2010-09-17 02:58:26 +00001126
Greg Clayton0fffff52010-09-24 05:15:53 +00001127 if (record_clang_type == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001128 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001129
Greg Clayton0fffff52010-09-24 05:15:53 +00001130 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan61da09b2010-09-17 02:58:26 +00001131
Greg Clayton0fffff52010-09-24 05:15:53 +00001132 if (record_decl == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001133 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001134
1135 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1136
Greg Clayton0fffff52010-09-24 05:15:53 +00001137 if (cxx_record_decl == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001138 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001139
Greg Clayton0fffff52010-09-24 05:15:53 +00001140 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001141
Greg Claytonf51de672010-10-01 02:31:07 +00001142 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001143
Greg Claytonf51de672010-10-01 02:31:07 +00001144 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton878eaf12010-10-01 03:45:20 +00001145
Greg Clayton878eaf12010-10-01 03:45:20 +00001146 const bool is_implicitly_declared = false;
Greg Claytonf51de672010-10-01 02:31:07 +00001147
Greg Clayton90a2acd2010-10-02 01:40:05 +00001148 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton878eaf12010-10-01 03:45:20 +00001149
Greg Clayton90a2acd2010-10-02 01:40:05 +00001150 if (function_Type == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001151 return NULL;
1152
Greg Clayton90a2acd2010-10-02 01:40:05 +00001153 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton878eaf12010-10-01 03:45:20 +00001154
1155 if (!method_function_prototype)
1156 return NULL;
1157
1158 unsigned int num_params = method_function_prototype->getNumArgs();
1159
1160 if (name[0] == '~')
Greg Claytonf51de672010-10-01 02:31:07 +00001161 {
Greg Clayton878eaf12010-10-01 03:45:20 +00001162 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1163 cxx_record_decl,
Greg Clayton90a2acd2010-10-02 01:40:05 +00001164 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001165 method_qual_type,
Sean Callanan31e851c2010-10-29 18:38:40 +00001166 NULL,
Greg Clayton878eaf12010-10-01 03:45:20 +00001167 is_inline,
1168 is_implicitly_declared);
1169 }
1170 else if (decl_name == record_decl->getDeclName())
1171 {
Greg Claytonf51de672010-10-01 02:31:07 +00001172 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1173 cxx_record_decl,
Greg Clayton90a2acd2010-10-02 01:40:05 +00001174 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Claytonf51de672010-10-01 02:31:07 +00001175 method_qual_type,
1176 NULL, // TypeSourceInfo *
1177 is_explicit,
1178 is_inline,
1179 is_implicitly_declared);
1180 }
1181 else
Greg Clayton878eaf12010-10-01 03:45:20 +00001182 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001183
1184 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1185 if (IsOperator (name, op_kind))
Greg Clayton878eaf12010-10-01 03:45:20 +00001186 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001187 if (op_kind != NUM_OVERLOADED_OPERATORS)
1188 {
1189 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton878eaf12010-10-01 03:45:20 +00001190 cxx_record_decl,
Greg Claytona3c444a2010-10-01 23:13:49 +00001191 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001192 method_qual_type,
1193 NULL, // TypeSourceInfo *
Greg Claytona3c444a2010-10-01 23:13:49 +00001194 is_static,
1195 SC_None,
1196 is_inline);
1197 }
1198 else if (num_params == 0)
1199 {
1200 // Conversion operators don't take params...
1201 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1202 cxx_record_decl,
Greg Clayton90a2acd2010-10-02 01:40:05 +00001203 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytona3c444a2010-10-01 23:13:49 +00001204 method_qual_type,
1205 NULL, // TypeSourceInfo *
1206 is_inline,
1207 is_explicit);
1208 }
Greg Clayton878eaf12010-10-01 03:45:20 +00001209 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001210
1211 if (cxx_method_decl == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001212 {
1213 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1214 cxx_record_decl,
Greg Claytona3c444a2010-10-01 23:13:49 +00001215 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001216 method_qual_type,
1217 NULL, // TypeSourceInfo *
1218 is_static,
1219 SC_None,
1220 is_inline);
1221 }
Greg Claytonf51de672010-10-01 02:31:07 +00001222 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001223
Greg Clayton1be10fc2010-09-29 01:12:09 +00001224 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton0fffff52010-09-24 05:15:53 +00001225
1226 cxx_method_decl->setAccess (access_specifier);
1227 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001228
Sean Callananfc55f5d2010-09-21 00:44:12 +00001229 // Populate the method decl with parameter decls
Sean Callananfc55f5d2010-09-21 00:44:12 +00001230
1231 ParmVarDecl *params[num_params];
1232
1233 for (int param_index = 0;
1234 param_index < num_params;
1235 ++param_index)
1236 {
Greg Clayton0fffff52010-09-24 05:15:53 +00001237 params[param_index] = ParmVarDecl::Create (*ast_context,
1238 cxx_method_decl,
1239 SourceLocation(),
1240 NULL, // anonymous
1241 method_function_prototype->getArgType(param_index),
1242 NULL,
1243 SC_None,
1244 SC_None,
1245 NULL);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001246 }
1247
Greg Clayton0fffff52010-09-24 05:15:53 +00001248 cxx_method_decl->setParams (params, num_params);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001249
Greg Clayton0fffff52010-09-24 05:15:53 +00001250 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan61da09b2010-09-17 02:58:26 +00001251
Greg Claytona51ed9b2010-09-23 01:09:21 +00001252 return cxx_method_decl;
Sean Callanan61da09b2010-09-17 02:58:26 +00001253}
1254
1255bool
Greg Clayton8cf05932010-07-22 18:30:50 +00001256ClangASTContext::AddFieldToRecordType
1257(
Greg Clayton1be10fc2010-09-29 01:12:09 +00001258 ASTContext *ast_context,
1259 clang_type_t record_clang_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001260 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001261 clang_type_t field_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001262 AccessType access,
1263 uint32_t bitfield_bit_size
1264)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001265{
1266 if (record_clang_type == NULL || field_type == NULL)
1267 return false;
1268
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001269 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001270
1271 assert (ast_context != NULL);
1272 assert (identifier_table != NULL);
1273
1274 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1275
Greg Claytone1a916a2010-07-21 22:12:05 +00001276 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001277 if (clang_type)
1278 {
1279 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1280
1281 if (record_type)
1282 {
1283 RecordDecl *record_decl = record_type->getDecl();
1284
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001285 clang::Expr *bit_width = NULL;
1286 if (bitfield_bit_size != 0)
1287 {
1288 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001289 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001290 }
Greg Clayton8cf05932010-07-22 18:30:50 +00001291 FieldDecl *field = FieldDecl::Create (*ast_context,
1292 record_decl,
1293 SourceLocation(),
1294 name ? &identifier_table->get(name) : NULL, // Identifier
1295 QualType::getFromOpaquePtr(field_type), // Field type
1296 NULL, // DeclaratorInfo *
1297 bit_width, // BitWidth
1298 false); // Mutable
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001299
Greg Clayton8cf05932010-07-22 18:30:50 +00001300 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001301
1302 if (field)
1303 {
1304 record_decl->addDecl(field);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001305 }
1306 }
Greg Clayton9e409562010-07-28 02:04:09 +00001307 else
1308 {
1309 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1310 if (objc_class_type)
1311 {
Greg Clayton0fffff52010-09-24 05:15:53 +00001312 bool is_synthesized = false;
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001313 ClangASTContext::AddObjCClassIVar (ast_context,
1314 record_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001315 name,
1316 field_type,
1317 access,
1318 bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001319 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001320 }
1321 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001322 }
1323 return false;
1324}
1325
1326bool
1327ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1328{
1329 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1330}
1331
1332bool
1333ClangASTContext::FieldIsBitfield
1334(
1335 ASTContext *ast_context,
1336 FieldDecl* field,
1337 uint32_t& bitfield_bit_size
1338)
1339{
1340 if (ast_context == NULL || field == NULL)
1341 return false;
1342
1343 if (field->isBitField())
1344 {
1345 Expr* bit_width_expr = field->getBitWidth();
1346 if (bit_width_expr)
1347 {
1348 llvm::APSInt bit_width_apsint;
1349 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1350 {
1351 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1352 return true;
1353 }
1354 }
1355 }
1356 return false;
1357}
1358
1359bool
1360ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1361{
1362 if (record_decl == NULL)
1363 return false;
1364
1365 if (!record_decl->field_empty())
1366 return true;
1367
1368 // No fields, lets check this is a CXX record and check the base classes
1369 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1370 if (cxx_record_decl)
1371 {
1372 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1373 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1374 base_class != base_class_end;
1375 ++base_class)
1376 {
1377 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1378 if (RecordHasFields(base_class_decl))
1379 return true;
1380 }
1381 }
1382 return false;
1383}
1384
1385void
Greg Clayton1be10fc2010-09-29 01:12:09 +00001386ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001387{
1388 if (clang_qual_type)
1389 {
1390 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Claytone1a916a2010-07-21 22:12:05 +00001391 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001392 if (clang_type)
1393 {
1394 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1395 if (record_type)
1396 {
1397 RecordDecl *record_decl = record_type->getDecl();
1398 if (record_decl)
1399 {
1400 uint32_t field_idx;
1401 RecordDecl::field_iterator field, field_end;
1402 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1403 field != field_end;
1404 ++field, ++field_idx)
1405 {
1406 // If no accessibility was assigned, assign the correct one
1407 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1408 field->setAccess ((AccessSpecifier)default_accessibility);
1409 }
1410 }
1411 }
1412 }
1413 }
1414}
1415
1416#pragma mark C++ Base Classes
1417
1418CXXBaseSpecifier *
Greg Clayton1be10fc2010-09-29 01:12:09 +00001419ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001420{
1421 if (base_class_type)
Greg Claytone6371122010-07-30 20:30:44 +00001422 return new CXXBaseSpecifier (SourceRange(),
1423 is_virtual,
1424 base_of_class,
1425 ConvertAccessTypeToAccessSpecifier (access),
1426 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001427 return NULL;
1428}
1429
Greg Clayton0b42ac32010-07-02 01:29:13 +00001430void
1431ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1432{
1433 for (unsigned i=0; i<num_base_classes; ++i)
1434 {
1435 delete base_classes[i];
1436 base_classes[i] = NULL;
1437 }
1438}
1439
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001440bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001441ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001442{
1443 if (class_clang_type)
1444 {
Greg Claytone1a916a2010-07-21 22:12:05 +00001445 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001446 if (clang_type)
1447 {
1448 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1449 if (record_type)
1450 {
1451 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1452 if (cxx_record_decl)
1453 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001454 cxx_record_decl->setBases(base_classes, num_base_classes);
1455 return true;
1456 }
1457 }
1458 }
1459 }
1460 return false;
1461}
Greg Clayton8cf05932010-07-22 18:30:50 +00001462#pragma mark Objective C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001463
Greg Clayton1be10fc2010-09-29 01:12:09 +00001464clang_type_t
Greg Clayton8cf05932010-07-22 18:30:50 +00001465ClangASTContext::CreateObjCClass
1466(
1467 const char *name,
1468 DeclContext *decl_ctx,
1469 bool isForwardDecl,
1470 bool isInternal
1471)
1472{
1473 ASTContext *ast_context = getASTContext();
1474 assert (ast_context != NULL);
1475 assert (name && name[0]);
1476 if (decl_ctx == NULL)
1477 decl_ctx = ast_context->getTranslationUnitDecl();
1478
1479 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1480 // we will need to update this code. I was told to currently always use
1481 // the CXXRecordDecl class since we often don't know from debug information
1482 // if something is struct or a class, so we default to always use the more
1483 // complete definition just in case.
1484 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1485 decl_ctx,
1486 SourceLocation(),
1487 &ast_context->Idents.get(name),
1488 SourceLocation(),
1489 isForwardDecl,
1490 isInternal);
Greg Clayton9e409562010-07-28 02:04:09 +00001491
1492 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001493}
1494
1495bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001496ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton8cf05932010-07-22 18:30:50 +00001497{
1498 if (class_opaque_type && super_opaque_type)
1499 {
1500 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1501 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1502 clang::Type *class_type = class_qual_type.getTypePtr();
1503 clang::Type *super_type = super_qual_type.getTypePtr();
1504 if (class_type && super_type)
1505 {
1506 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1507 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1508 if (objc_class_type && objc_super_type)
1509 {
1510 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1511 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1512 if (class_interface_decl && super_interface_decl)
1513 {
1514 class_interface_decl->setSuperClass(super_interface_decl);
1515 return true;
1516 }
1517 }
1518 }
1519 }
1520 return false;
1521}
1522
1523
1524bool
1525ClangASTContext::AddObjCClassIVar
1526(
Greg Clayton1be10fc2010-09-29 01:12:09 +00001527 ASTContext *ast_context,
1528 clang_type_t class_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001529 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001530 clang_type_t ivar_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001531 AccessType access,
1532 uint32_t bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001533 bool is_synthesized
Greg Clayton8cf05932010-07-22 18:30:50 +00001534)
1535{
1536 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1537 return false;
1538
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001539 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton8cf05932010-07-22 18:30:50 +00001540
1541 assert (ast_context != NULL);
1542 assert (identifier_table != NULL);
1543
1544 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1545
1546 clang::Type *class_type = class_qual_type.getTypePtr();
1547 if (class_type)
1548 {
1549 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1550
1551 if (objc_class_type)
1552 {
1553 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1554
1555 if (class_interface_decl)
1556 {
1557 clang::Expr *bit_width = NULL;
1558 if (bitfield_bit_size != 0)
1559 {
1560 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001561 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton8cf05932010-07-22 18:30:50 +00001562 }
1563
Greg Clayton9e409562010-07-28 02:04:09 +00001564 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1565 class_interface_decl,
1566 SourceLocation(),
1567 &identifier_table->get(name), // Identifier
1568 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1569 NULL, // TypeSourceInfo *
1570 ConvertAccessTypeToObjCIvarAccessControl (access),
1571 bit_width,
Greg Clayton0fffff52010-09-24 05:15:53 +00001572 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001573
1574 if (field)
1575 {
1576 class_interface_decl->addDecl(field);
1577 return true;
1578 }
Greg Clayton8cf05932010-07-22 18:30:50 +00001579 }
1580 }
1581 }
1582 return false;
1583}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001584
Greg Clayton9e409562010-07-28 02:04:09 +00001585
1586bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001587ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9e409562010-07-28 02:04:09 +00001588{
1589 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1590
1591 clang::Type *class_type = class_qual_type.getTypePtr();
1592 if (class_type)
1593 {
1594 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1595
1596 if (objc_class_type)
1597 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1598 }
1599 return false;
1600}
1601
1602bool
1603ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1604{
1605 while (class_interface_decl)
1606 {
1607 if (class_interface_decl->ivar_size() > 0)
1608 return true;
1609
1610 if (check_superclass)
1611 class_interface_decl = class_interface_decl->getSuperClass();
1612 else
1613 break;
1614 }
1615 return false;
1616}
Greg Clayton0fffff52010-09-24 05:15:53 +00001617
Greg Clayton1be10fc2010-09-29 01:12:09 +00001618ObjCMethodDecl *
Greg Clayton0fffff52010-09-24 05:15:53 +00001619ClangASTContext::AddMethodToObjCObjectType
1620(
Greg Clayton1be10fc2010-09-29 01:12:09 +00001621 ASTContext *ast_context,
1622 clang_type_t class_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001623 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton1be10fc2010-09-29 01:12:09 +00001624 clang_type_t method_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001625 lldb::AccessType access
1626)
1627{
1628 if (class_opaque_type == NULL || method_opaque_type == NULL)
1629 return NULL;
1630
1631 IdentifierTable *identifier_table = &ast_context->Idents;
1632
1633 assert (ast_context != NULL);
1634 assert (identifier_table != NULL);
1635
1636 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1637
1638 clang::Type *class_type = class_qual_type.getTypePtr();
1639 if (class_type == NULL)
1640 return NULL;
1641
1642 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1643
1644 if (objc_class_type == NULL)
1645 return NULL;
1646
1647 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1648
1649 if (class_interface_decl == NULL)
1650 return NULL;
Greg Clayton9e409562010-07-28 02:04:09 +00001651
Greg Clayton0fffff52010-09-24 05:15:53 +00001652 const char *selector_start = ::strchr (name, ' ');
1653 if (selector_start == NULL)
1654 return NULL;
1655
1656 selector_start++;
1657 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1658 return NULL;
1659 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1660
Greg Clayton450e3f32010-10-12 02:24:53 +00001661 size_t len = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +00001662 const char *start;
Greg Clayton450e3f32010-10-12 02:24:53 +00001663 //printf ("name = '%s'\n", name);
1664
1665 unsigned num_selectors_with_args = 0;
1666 for (start = selector_start;
Greg Clayton0fffff52010-09-24 05:15:53 +00001667 start && *start != '\0' && *start != ']';
Greg Clayton450e3f32010-10-12 02:24:53 +00001668 start += len)
Greg Clayton0fffff52010-09-24 05:15:53 +00001669 {
Greg Clayton450e3f32010-10-12 02:24:53 +00001670 len = ::strcspn(start, ":]");
Greg Clayton90f90cd2010-10-27 04:01:14 +00001671 bool has_arg = (start[len] == ':');
1672 if (has_arg)
Greg Clayton450e3f32010-10-12 02:24:53 +00001673 ++num_selectors_with_args;
Greg Clayton0fffff52010-09-24 05:15:53 +00001674 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton90f90cd2010-10-27 04:01:14 +00001675 if (has_arg)
1676 len += 1;
Greg Clayton0fffff52010-09-24 05:15:53 +00001677 }
1678
1679
1680 if (selector_idents.size() == 0)
1681 return 0;
1682
Greg Clayton450e3f32010-10-12 02:24:53 +00001683 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton0fffff52010-09-24 05:15:53 +00001684 selector_idents.data());
1685
1686 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1687
1688 // Populate the method decl with parameter decls
1689 clang::Type *method_type(method_qual_type.getTypePtr());
1690
1691 if (method_type == NULL)
1692 return NULL;
1693
1694 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1695
1696 if (!method_function_prototype)
1697 return NULL;
1698
1699
1700 bool is_variadic = false;
1701 bool is_synthesized = false;
1702 bool is_defined = false;
1703 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1704
1705 const unsigned num_args = method_function_prototype->getNumArgs();
1706
1707 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1708 SourceLocation(), // beginLoc,
1709 SourceLocation(), // endLoc,
1710 method_selector,
1711 method_function_prototype->getResultType(),
1712 NULL, // TypeSourceInfo *ResultTInfo,
1713 GetDeclContextForType (class_opaque_type),
1714 name[0] == '-',
1715 is_variadic,
1716 is_synthesized,
1717 is_defined,
1718 imp_control,
1719 num_args);
1720
1721
1722 if (objc_method_decl == NULL)
1723 return NULL;
1724
1725 if (num_args > 0)
1726 {
1727 llvm::SmallVector<ParmVarDecl *, 12> params;
1728
1729 for (int param_index = 0; param_index < num_args; ++param_index)
1730 {
1731 params.push_back (ParmVarDecl::Create (*ast_context,
1732 objc_method_decl,
1733 SourceLocation(),
1734 NULL, // anonymous
1735 method_function_prototype->getArgType(param_index),
1736 NULL,
1737 SC_Auto,
1738 SC_Auto,
1739 NULL));
1740 }
1741
1742 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1743 }
1744
1745 class_interface_decl->addDecl (objc_method_decl);
1746
1747
1748 return objc_method_decl;
1749}
1750
1751
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001752uint32_t
Greg Clayton73b472d2010-10-27 03:32:59 +00001753ClangASTContext::GetTypeInfo
1754(
1755 clang_type_t clang_type,
1756 clang::ASTContext *ast_context,
1757 clang_type_t *pointee_or_element_clang_type
1758)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001759{
1760 if (clang_type == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001761 return 0;
1762
1763 if (pointee_or_element_clang_type)
1764 *pointee_or_element_clang_type = NULL;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001765
1766 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1767
1768 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1769 switch (type_class)
1770 {
Sean Callanana2424172010-10-25 00:29:48 +00001771 case clang::Type::Builtin:
1772 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1773 {
Sean Callanana2424172010-10-25 00:29:48 +00001774 case clang::BuiltinType::ObjCId:
1775 case clang::BuiltinType::ObjCClass:
Greg Clayton73b472d2010-10-27 03:32:59 +00001776 if (ast_context && pointee_or_element_clang_type)
1777 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanana2424172010-10-25 00:29:48 +00001778 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00001779
1780 default:
1781 break;
Sean Callanana2424172010-10-25 00:29:48 +00001782 }
1783 return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00001784
1785 case clang::Type::BlockPointer:
1786 if (pointee_or_element_clang_type)
1787 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1788 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1789
Greg Clayton49462ea2011-01-15 02:52:14 +00001790 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00001791
1792 case clang::Type::ConstantArray:
1793 case clang::Type::DependentSizedArray:
1794 case clang::Type::IncompleteArray:
1795 case clang::Type::VariableArray:
1796 if (pointee_or_element_clang_type)
1797 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1798 return eTypeHasChildren | eTypeIsArray;
1799
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001800 case clang::Type::DependentName: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001801 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1802 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1803 case clang::Type::Decltype: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00001804
1805 case clang::Type::Enum:
1806 if (pointee_or_element_clang_type)
1807 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1808 return eTypeIsEnumeration | eTypeHasValue;
1809
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001810 case clang::Type::Elaborated: return 0;
1811 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1812 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1813 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001814 case clang::Type::InjectedClassName: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00001815
1816 case clang::Type::LValueReference:
1817 case clang::Type::RValueReference:
1818 if (pointee_or_element_clang_type)
1819 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1820 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1821
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001822 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00001823
1824 case clang::Type::ObjCObjectPointer:
1825 if (pointee_or_element_clang_type)
1826 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1827 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1828
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001829 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1830 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Clayton73b472d2010-10-27 03:32:59 +00001831
1832 case clang::Type::Pointer:
1833 if (pointee_or_element_clang_type)
1834 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1835 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1836
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001837 case clang::Type::Record:
1838 if (qual_type->getAsCXXRecordDecl())
1839 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1840 else
1841 return eTypeHasChildren | eTypeIsStructUnion;
1842 break;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001843 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1844 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1845 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Clayton73b472d2010-10-27 03:32:59 +00001846
1847 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00001848 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Greg Clayton73b472d2010-10-27 03:32:59 +00001849 ast_context,
1850 pointee_or_element_clang_type);
1851
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001852 case clang::Type::TypeOfExpr: return 0;
1853 case clang::Type::TypeOf: return 0;
1854 case clang::Type::UnresolvedUsing: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001855 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1856 default: return 0;
1857 }
1858 return 0;
1859}
1860
Greg Clayton9e409562010-07-28 02:04:09 +00001861
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001862#pragma mark Aggregate Types
1863
1864bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001865ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001866{
1867 if (clang_type == NULL)
1868 return false;
1869
1870 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1871
Greg Clayton737b9322010-09-13 03:32:57 +00001872 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1873 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001874 {
Greg Claytone1a916a2010-07-21 22:12:05 +00001875 case clang::Type::IncompleteArray:
1876 case clang::Type::VariableArray:
1877 case clang::Type::ConstantArray:
1878 case clang::Type::ExtVector:
1879 case clang::Type::Vector:
1880 case clang::Type::Record:
Greg Clayton9e409562010-07-28 02:04:09 +00001881 case clang::Type::ObjCObject:
1882 case clang::Type::ObjCInterface:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001883 return true;
1884
Greg Claytone1a916a2010-07-21 22:12:05 +00001885 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00001886 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001887
1888 default:
1889 break;
1890 }
1891 // The clang type does have a value
1892 return false;
1893}
1894
1895uint32_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00001896ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001897{
1898 if (clang_qual_type == NULL)
1899 return 0;
1900
1901 uint32_t num_children = 0;
1902 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9e409562010-07-28 02:04:09 +00001903 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1904 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001905 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001906 case clang::Type::Builtin:
1907 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1908 {
Greg Clayton73b472d2010-10-27 03:32:59 +00001909 case clang::BuiltinType::ObjCId: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001910 case clang::BuiltinType::ObjCClass: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001911 num_children = 1;
Greg Clayton73b472d2010-10-27 03:32:59 +00001912 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001913
1914 default:
1915 break;
1916 }
1917 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00001918
Greg Clayton49462ea2011-01-15 02:52:14 +00001919 case clang::Type::Complex: return 0;
Greg Clayton54979cd2010-12-15 05:08:08 +00001920
Greg Claytone1a916a2010-07-21 22:12:05 +00001921 case clang::Type::Record:
Greg Claytona63012e2010-11-11 02:14:53 +00001922 if (ClangASTType::IsDefined (clang_qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001923 {
1924 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1925 const RecordDecl *record_decl = record_type->getDecl();
1926 assert(record_decl);
1927 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1928 if (cxx_record_decl)
1929 {
1930 if (omit_empty_base_classes)
1931 {
1932 // Check each base classes to see if it or any of its
1933 // base classes contain any fields. This can help
1934 // limit the noise in variable views by not having to
1935 // show base classes that contain no members.
1936 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1937 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1938 base_class != base_class_end;
1939 ++base_class)
1940 {
1941 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1942
1943 // Skip empty base classes
1944 if (RecordHasFields(base_class_decl) == false)
1945 continue;
1946
1947 num_children++;
1948 }
1949 }
1950 else
1951 {
1952 // Include all base classes
1953 num_children += cxx_record_decl->getNumBases();
1954 }
1955
1956 }
1957 RecordDecl::field_iterator field, field_end;
1958 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1959 ++num_children;
1960 }
1961 break;
1962
Greg Clayton9e409562010-07-28 02:04:09 +00001963 case clang::Type::ObjCObject:
1964 case clang::Type::ObjCInterface:
1965 {
1966 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1967 assert (objc_class_type);
1968 if (objc_class_type)
1969 {
1970 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1971
1972 if (class_interface_decl)
1973 {
1974
1975 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1976 if (superclass_interface_decl)
1977 {
1978 if (omit_empty_base_classes)
1979 {
1980 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1981 ++num_children;
1982 }
1983 else
1984 ++num_children;
1985 }
1986
1987 num_children += class_interface_decl->ivar_size();
1988 }
1989 }
1990 }
1991 break;
1992
1993 case clang::Type::ObjCObjectPointer:
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001994 {
1995 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1996 QualType pointee_type = pointer_type->getPointeeType();
1997 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1998 omit_empty_base_classes);
1999 // If this type points to a simple type, then it has 1 child
2000 if (num_pointee_children == 0)
2001 num_children = 1;
2002 else
2003 num_children = num_pointee_children;
2004 }
2005 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002006
Greg Claytone1a916a2010-07-21 22:12:05 +00002007 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002008 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2009 break;
2010
Greg Claytone1a916a2010-07-21 22:12:05 +00002011 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002012 {
2013 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002014 QualType pointee_type (pointer_type->getPointeeType());
Greg Clayton9e409562010-07-28 02:04:09 +00002015 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
2016 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002017 if (num_pointee_children == 0)
Greg Clayton54979cd2010-12-15 05:08:08 +00002018 {
2019 // We have a pointer to a pointee type that claims it has no children.
2020 // We will want to look at
2021 num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
2022 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002023 else
2024 num_children = num_pointee_children;
2025 }
2026 break;
2027
Greg Clayton73b472d2010-10-27 03:32:59 +00002028 case clang::Type::LValueReference:
2029 case clang::Type::RValueReference:
2030 {
2031 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2032 QualType pointee_type = reference_type->getPointeeType();
2033 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
2034 omit_empty_base_classes);
2035 // If this type points to a simple type, then it has 1 child
2036 if (num_pointee_children == 0)
2037 num_children = 1;
2038 else
2039 num_children = num_pointee_children;
2040 }
2041 break;
2042
2043
Greg Claytone1a916a2010-07-21 22:12:05 +00002044 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002045 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002046 break;
2047
2048 default:
2049 break;
2050 }
2051 return num_children;
2052}
2053
Greg Clayton54979cd2010-12-15 05:08:08 +00002054// If a pointer to a pointee type (the clang_type arg) says that it has no
2055// children, then we either need to trust it, or override it and return a
2056// different result. For example, an "int *" has one child that is an integer,
2057// but a function pointer doesn't have any children. Likewise if a Record type
2058// claims it has no children, then there really is nothing to show.
2059uint32_t
2060ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
2061{
2062 if (clang_type == NULL)
2063 return 0;
2064
2065 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2066 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2067 switch (type_class)
2068 {
Greg Clayton97a43712011-01-08 22:26:47 +00002069 case clang::Type::Builtin:
2070 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2071 {
2072 case clang::BuiltinType::Void:
2073 case clang::BuiltinType::NullPtr:
2074 return 0;
2075 case clang::BuiltinType::Bool:
2076 case clang::BuiltinType::Char_U:
2077 case clang::BuiltinType::UChar:
2078 case clang::BuiltinType::Char16:
2079 case clang::BuiltinType::Char32:
2080 case clang::BuiltinType::UShort:
2081 case clang::BuiltinType::UInt:
2082 case clang::BuiltinType::ULong:
2083 case clang::BuiltinType::ULongLong:
2084 case clang::BuiltinType::UInt128:
2085 case clang::BuiltinType::Char_S:
2086 case clang::BuiltinType::SChar:
2087 case clang::BuiltinType::WChar:
2088 case clang::BuiltinType::Short:
2089 case clang::BuiltinType::Int:
2090 case clang::BuiltinType::Long:
2091 case clang::BuiltinType::LongLong:
2092 case clang::BuiltinType::Int128:
2093 case clang::BuiltinType::Float:
2094 case clang::BuiltinType::Double:
2095 case clang::BuiltinType::LongDouble:
2096 case clang::BuiltinType::Dependent:
2097 case clang::BuiltinType::Overload:
2098 case clang::BuiltinType::UndeducedAuto:
2099 case clang::BuiltinType::ObjCId:
2100 case clang::BuiltinType::ObjCClass:
2101 case clang::BuiltinType::ObjCSel:
2102 return 1;
2103 }
2104 break;
2105
Greg Clayton49462ea2011-01-15 02:52:14 +00002106 case clang::Type::Complex: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00002107 case clang::Type::Pointer: return 1;
2108 case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
2109 case clang::Type::LValueReference: return 1;
2110 case clang::Type::RValueReference: return 1;
2111 case clang::Type::MemberPointer: return 0;
2112 case clang::Type::ConstantArray: return 0;
2113 case clang::Type::IncompleteArray: return 0;
2114 case clang::Type::VariableArray: return 0;
2115 case clang::Type::DependentSizedArray: return 0;
2116 case clang::Type::DependentSizedExtVector: return 0;
2117 case clang::Type::Vector: return 0;
2118 case clang::Type::ExtVector: return 0;
2119 case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
2120 case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
2121 case clang::Type::UnresolvedUsing: return 0;
2122 case clang::Type::Paren: return 0;
2123 case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2124 case clang::Type::TypeOfExpr: return 0;
2125 case clang::Type::TypeOf: return 0;
2126 case clang::Type::Decltype: return 0;
2127 case clang::Type::Record: return 0;
2128 case clang::Type::Enum: return 1;
2129 case clang::Type::Elaborated: return 1;
2130 case clang::Type::TemplateTypeParm: return 1;
2131 case clang::Type::SubstTemplateTypeParm: return 1;
2132 case clang::Type::TemplateSpecialization: return 1;
2133 case clang::Type::InjectedClassName: return 0;
2134 case clang::Type::DependentName: return 1;
2135 case clang::Type::DependentTemplateSpecialization: return 1;
2136 case clang::Type::ObjCObject: return 0;
2137 case clang::Type::ObjCInterface: return 0;
2138 case clang::Type::ObjCObjectPointer: return 1;
2139 default:
2140 break;
2141 }
2142 return 0;
2143}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002144
Greg Clayton1be10fc2010-09-29 01:12:09 +00002145clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002146ClangASTContext::GetChildClangTypeAtIndex
2147(
2148 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002149 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002150 uint32_t idx,
2151 bool transparent_pointers,
2152 bool omit_empty_base_classes,
2153 std::string& child_name,
2154 uint32_t &child_byte_size,
2155 int32_t &child_byte_offset,
2156 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002157 uint32_t &child_bitfield_bit_offset,
2158 bool &child_is_base_class
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002159)
2160{
2161 if (parent_clang_type)
2162
2163 return GetChildClangTypeAtIndex (getASTContext(),
2164 parent_name,
2165 parent_clang_type,
2166 idx,
2167 transparent_pointers,
2168 omit_empty_base_classes,
2169 child_name,
2170 child_byte_size,
2171 child_byte_offset,
2172 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002173 child_bitfield_bit_offset,
2174 child_is_base_class);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002175 return NULL;
2176}
2177
Greg Clayton1be10fc2010-09-29 01:12:09 +00002178clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002179ClangASTContext::GetChildClangTypeAtIndex
2180(
2181 ASTContext *ast_context,
2182 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002183 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002184 uint32_t idx,
2185 bool transparent_pointers,
2186 bool omit_empty_base_classes,
2187 std::string& child_name,
2188 uint32_t &child_byte_size,
2189 int32_t &child_byte_offset,
2190 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002191 uint32_t &child_bitfield_bit_offset,
2192 bool &child_is_base_class
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002193)
2194{
2195 if (parent_clang_type == NULL)
2196 return NULL;
2197
2198 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2199 {
2200 uint32_t bit_offset;
2201 child_bitfield_bit_size = 0;
2202 child_bitfield_bit_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002203 child_is_base_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002204 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00002205 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2206 switch (parent_type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002207 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002208 case clang::Type::Builtin:
2209 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2210 {
2211 case clang::BuiltinType::ObjCId:
2212 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00002213 child_name = "isa";
2214 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002215 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2216
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002217 default:
2218 break;
2219 }
2220 break;
2221
2222
Greg Claytone1a916a2010-07-21 22:12:05 +00002223 case clang::Type::Record:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002224 {
2225 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2226 const RecordDecl *record_decl = record_type->getDecl();
2227 assert(record_decl);
2228 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2229 uint32_t child_idx = 0;
2230
2231 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2232 if (cxx_record_decl)
2233 {
2234 // We might have base classes to print out first
2235 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2236 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2237 base_class != base_class_end;
2238 ++base_class)
2239 {
2240 const CXXRecordDecl *base_class_decl = NULL;
2241
2242 // Skip empty base classes
2243 if (omit_empty_base_classes)
2244 {
2245 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2246 if (RecordHasFields(base_class_decl) == false)
2247 continue;
2248 }
2249
2250 if (idx == child_idx)
2251 {
2252 if (base_class_decl == NULL)
2253 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2254
2255
2256 if (base_class->isVirtual())
Sean Callanan79439e82010-11-18 02:56:27 +00002257 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002258 else
Sean Callanan79439e82010-11-18 02:56:27 +00002259 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002260
2261 // Base classes should be a multiple of 8 bits in size
2262 assert (bit_offset % 8 == 0);
2263 child_byte_offset = bit_offset/8;
2264 std::string base_class_type_name(base_class->getType().getAsString());
2265
2266 child_name.assign(base_class_type_name.c_str());
2267
2268 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2269
2270 // Base classes biut sizes should be a multiple of 8 bits in size
2271 assert (clang_type_info_bit_size % 8 == 0);
2272 child_byte_size = clang_type_info_bit_size / 8;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002273 child_is_base_class = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002274 return base_class->getType().getAsOpaquePtr();
2275 }
2276 // We don't increment the child index in the for loop since we might
2277 // be skipping empty base classes
2278 ++child_idx;
2279 }
2280 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002281 // Make sure index is in range...
2282 uint32_t field_idx = 0;
2283 RecordDecl::field_iterator field, field_end;
2284 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2285 {
2286 if (idx == child_idx)
2287 {
2288 // Print the member type if requested
2289 // Print the member name and equal sign
2290 child_name.assign(field->getNameAsString().c_str());
2291
2292 // Figure out the type byte size (field_type_info.first) and
2293 // alignment (field_type_info.second) from the AST context.
2294 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Claytonc982c762010-07-09 20:39:50 +00002295 assert(field_idx < record_layout.getFieldCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002296
2297 child_byte_size = field_type_info.first / 8;
2298
2299 // Figure out the field offset within the current struct/union/class type
2300 bit_offset = record_layout.getFieldOffset (field_idx);
2301 child_byte_offset = bit_offset / 8;
2302 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2303 child_bitfield_bit_offset = bit_offset % 8;
2304
2305 return field->getType().getAsOpaquePtr();
2306 }
2307 }
2308 }
2309 break;
2310
Greg Clayton9e409562010-07-28 02:04:09 +00002311 case clang::Type::ObjCObject:
2312 case clang::Type::ObjCInterface:
2313 {
2314 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2315 assert (objc_class_type);
2316 if (objc_class_type)
2317 {
2318 uint32_t child_idx = 0;
2319 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2320
2321 if (class_interface_decl)
2322 {
2323
2324 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2325 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2326 if (superclass_interface_decl)
2327 {
2328 if (omit_empty_base_classes)
2329 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002330 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9e409562010-07-28 02:04:09 +00002331 {
2332 if (idx == 0)
2333 {
2334 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2335
2336
2337 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2338
2339 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2340
2341 child_byte_size = ivar_type_info.first / 8;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002342 child_byte_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002343 child_is_base_class = true;
Greg Clayton9e409562010-07-28 02:04:09 +00002344
2345 return ivar_qual_type.getAsOpaquePtr();
2346 }
2347
2348 ++child_idx;
2349 }
2350 }
2351 else
2352 ++child_idx;
2353 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002354
2355 const uint32_t superclass_idx = child_idx;
Greg Clayton9e409562010-07-28 02:04:09 +00002356
2357 if (idx < (child_idx + class_interface_decl->ivar_size()))
2358 {
2359 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2360
2361 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2362 {
2363 if (child_idx == idx)
2364 {
2365 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2366
2367 QualType ivar_qual_type(ivar_decl->getType());
2368
2369 child_name.assign(ivar_decl->getNameAsString().c_str());
2370
2371 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2372
2373 child_byte_size = ivar_type_info.first / 8;
2374
2375 // Figure out the field offset within the current struct/union/class type
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002376 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9e409562010-07-28 02:04:09 +00002377 child_byte_offset = bit_offset / 8;
2378
2379 return ivar_qual_type.getAsOpaquePtr();
2380 }
2381 ++child_idx;
2382 }
2383 }
2384 }
2385 }
2386 }
2387 break;
2388
2389 case clang::Type::ObjCObjectPointer:
2390 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002391 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2392 QualType pointee_type = pointer_type->getPointeeType();
2393
2394 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2395 {
2396 return GetChildClangTypeAtIndex (ast_context,
2397 parent_name,
2398 pointer_type->getPointeeType().getAsOpaquePtr(),
2399 idx,
2400 transparent_pointers,
2401 omit_empty_base_classes,
2402 child_name,
2403 child_byte_size,
2404 child_byte_offset,
2405 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002406 child_bitfield_bit_offset,
2407 child_is_base_class);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002408 }
2409 else
2410 {
2411 if (parent_name)
2412 {
2413 child_name.assign(1, '*');
2414 child_name += parent_name;
2415 }
2416
2417 // We have a pointer to an simple type
2418 if (idx == 0)
2419 {
2420 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2421 assert(clang_type_info.first % 8 == 0);
2422 child_byte_size = clang_type_info.first / 8;
2423 child_byte_offset = 0;
2424 return pointee_type.getAsOpaquePtr();
2425 }
2426 }
Greg Clayton9e409562010-07-28 02:04:09 +00002427 }
2428 break;
2429
Greg Claytone1a916a2010-07-21 22:12:05 +00002430 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002431 {
2432 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2433 const uint64_t element_count = array->getSize().getLimitedValue();
2434
2435 if (idx < element_count)
2436 {
2437 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2438
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002439 char element_name[64];
2440 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002441
2442 child_name.assign(element_name);
2443 assert(field_type_info.first % 8 == 0);
2444 child_byte_size = field_type_info.first / 8;
2445 child_byte_offset = idx * child_byte_size;
2446 return array->getElementType().getAsOpaquePtr();
2447 }
2448 }
2449 break;
2450
Greg Claytone1a916a2010-07-21 22:12:05 +00002451 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002452 {
2453 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2454 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton97a43712011-01-08 22:26:47 +00002455
2456 // Don't dereference "void *" pointers
2457 if (pointee_type->isVoidType())
2458 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002459
2460 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2461 {
2462 return GetChildClangTypeAtIndex (ast_context,
2463 parent_name,
2464 pointer_type->getPointeeType().getAsOpaquePtr(),
2465 idx,
2466 transparent_pointers,
2467 omit_empty_base_classes,
2468 child_name,
2469 child_byte_size,
2470 child_byte_offset,
2471 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002472 child_bitfield_bit_offset,
2473 child_is_base_class);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002474 }
2475 else
2476 {
2477 if (parent_name)
2478 {
2479 child_name.assign(1, '*');
2480 child_name += parent_name;
2481 }
2482
2483 // We have a pointer to an simple type
2484 if (idx == 0)
2485 {
2486 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2487 assert(clang_type_info.first % 8 == 0);
2488 child_byte_size = clang_type_info.first / 8;
2489 child_byte_offset = 0;
2490 return pointee_type.getAsOpaquePtr();
2491 }
2492 }
2493 }
2494 break;
2495
Greg Clayton73b472d2010-10-27 03:32:59 +00002496 case clang::Type::LValueReference:
2497 case clang::Type::RValueReference:
2498 {
2499 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2500 QualType pointee_type(reference_type->getPointeeType());
2501 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2502 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2503 {
2504 return GetChildClangTypeAtIndex (ast_context,
2505 parent_name,
2506 pointee_clang_type,
2507 idx,
2508 transparent_pointers,
2509 omit_empty_base_classes,
2510 child_name,
2511 child_byte_size,
2512 child_byte_offset,
2513 child_bitfield_bit_size,
2514 child_bitfield_bit_offset,
2515 child_is_base_class);
2516 }
2517 else
2518 {
2519 if (parent_name)
2520 {
2521 child_name.assign(1, '&');
2522 child_name += parent_name;
2523 }
2524
2525 // We have a pointer to an simple type
2526 if (idx == 0)
2527 {
2528 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2529 assert(clang_type_info.first % 8 == 0);
2530 child_byte_size = clang_type_info.first / 8;
2531 child_byte_offset = 0;
2532 return pointee_type.getAsOpaquePtr();
2533 }
2534 }
2535 }
2536 break;
2537
Greg Claytone1a916a2010-07-21 22:12:05 +00002538 case clang::Type::Typedef:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002539 return GetChildClangTypeAtIndex (ast_context,
2540 parent_name,
Sean Callanan48114472010-12-13 01:26:27 +00002541 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002542 idx,
2543 transparent_pointers,
2544 omit_empty_base_classes,
2545 child_name,
2546 child_byte_size,
2547 child_byte_offset,
2548 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002549 child_bitfield_bit_offset,
2550 child_is_base_class);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002551 break;
2552
2553 default:
2554 break;
2555 }
2556 }
Greg Clayton19503a22010-07-23 15:37:46 +00002557 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002558}
2559
2560static inline bool
2561BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2562{
2563 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2564}
2565
2566static uint32_t
2567GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2568{
2569 uint32_t num_bases = 0;
2570 if (cxx_record_decl)
2571 {
2572 if (omit_empty_base_classes)
2573 {
2574 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2575 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2576 base_class != base_class_end;
2577 ++base_class)
2578 {
2579 // Skip empty base classes
2580 if (omit_empty_base_classes)
2581 {
2582 if (BaseSpecifierIsEmpty (base_class))
2583 continue;
2584 }
2585 ++num_bases;
2586 }
2587 }
2588 else
2589 num_bases = cxx_record_decl->getNumBases();
2590 }
2591 return num_bases;
2592}
2593
2594
2595static uint32_t
2596GetIndexForRecordBase
2597(
2598 const RecordDecl *record_decl,
2599 const CXXBaseSpecifier *base_spec,
2600 bool omit_empty_base_classes
2601)
2602{
2603 uint32_t child_idx = 0;
2604
2605 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2606
2607// const char *super_name = record_decl->getNameAsCString();
2608// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2609// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2610//
2611 if (cxx_record_decl)
2612 {
2613 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2614 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2615 base_class != base_class_end;
2616 ++base_class)
2617 {
2618 if (omit_empty_base_classes)
2619 {
2620 if (BaseSpecifierIsEmpty (base_class))
2621 continue;
2622 }
2623
2624// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2625// child_idx,
2626// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2627//
2628//
2629 if (base_class == base_spec)
2630 return child_idx;
2631 ++child_idx;
2632 }
2633 }
2634
2635 return UINT32_MAX;
2636}
2637
2638
2639static uint32_t
2640GetIndexForRecordChild
2641(
2642 const RecordDecl *record_decl,
2643 NamedDecl *canonical_decl,
2644 bool omit_empty_base_classes
2645)
2646{
2647 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2648
2649// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2650//
2651//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2652// if (cxx_record_decl)
2653// {
2654// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2655// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2656// base_class != base_class_end;
2657// ++base_class)
2658// {
2659// if (omit_empty_base_classes)
2660// {
2661// if (BaseSpecifierIsEmpty (base_class))
2662// continue;
2663// }
2664//
2665//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2666//// record_decl->getNameAsCString(),
2667//// canonical_decl->getNameAsCString(),
2668//// child_idx,
2669//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2670//
2671//
2672// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2673// if (curr_base_class_decl == canonical_decl)
2674// {
2675// return child_idx;
2676// }
2677// ++child_idx;
2678// }
2679// }
2680//
2681// const uint32_t num_bases = child_idx;
2682 RecordDecl::field_iterator field, field_end;
2683 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2684 field != field_end;
2685 ++field, ++child_idx)
2686 {
2687// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2688// record_decl->getNameAsCString(),
2689// canonical_decl->getNameAsCString(),
2690// child_idx - num_bases,
2691// field->getNameAsCString());
2692
2693 if (field->getCanonicalDecl() == canonical_decl)
2694 return child_idx;
2695 }
2696
2697 return UINT32_MAX;
2698}
2699
2700// Look for a child member (doesn't include base classes, but it does include
2701// their members) in the type hierarchy. Returns an index path into "clang_type"
2702// on how to reach the appropriate member.
2703//
2704// class A
2705// {
2706// public:
2707// int m_a;
2708// int m_b;
2709// };
2710//
2711// class B
2712// {
2713// };
2714//
2715// class C :
2716// public B,
2717// public A
2718// {
2719// };
2720//
2721// If we have a clang type that describes "class C", and we wanted to looked
2722// "m_b" in it:
2723//
2724// With omit_empty_base_classes == false we would get an integer array back with:
2725// { 1, 1 }
2726// The first index 1 is the child index for "class A" within class C
2727// The second index 1 is the child index for "m_b" within class A
2728//
2729// With omit_empty_base_classes == true we would get an integer array back with:
2730// { 0, 1 }
2731// 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)
2732// The second index 1 is the child index for "m_b" within class A
2733
2734size_t
2735ClangASTContext::GetIndexOfChildMemberWithName
2736(
2737 ASTContext *ast_context,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002738 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002739 const char *name,
2740 bool omit_empty_base_classes,
2741 std::vector<uint32_t>& child_indexes
2742)
2743{
2744 if (clang_type && name && name[0])
2745 {
2746 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00002747 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2748 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002749 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002750 case clang::Type::Record:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002751 {
2752 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2753 const RecordDecl *record_decl = record_type->getDecl();
2754
2755 assert(record_decl);
2756 uint32_t child_idx = 0;
2757
2758 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2759
2760 // Try and find a field that matches NAME
2761 RecordDecl::field_iterator field, field_end;
2762 StringRef name_sref(name);
2763 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2764 field != field_end;
2765 ++field, ++child_idx)
2766 {
2767 if (field->getName().equals (name_sref))
2768 {
2769 // We have to add on the number of base classes to this index!
2770 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2771 return child_indexes.size();
2772 }
2773 }
2774
2775 if (cxx_record_decl)
2776 {
2777 const RecordDecl *parent_record_decl = cxx_record_decl;
2778
2779 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2780
2781 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2782 // Didn't find things easily, lets let clang do its thang...
2783 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2784 DeclarationName decl_name(&ident_ref);
2785
2786 CXXBasePaths paths;
2787 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2788 decl_name.getAsOpaquePtr(),
2789 paths))
2790 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002791 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2792 for (path = paths.begin(); path != path_end; ++path)
2793 {
2794 const size_t num_path_elements = path->size();
2795 for (size_t e=0; e<num_path_elements; ++e)
2796 {
2797 CXXBasePathElement elem = (*path)[e];
2798
2799 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2800 if (child_idx == UINT32_MAX)
2801 {
2802 child_indexes.clear();
2803 return 0;
2804 }
2805 else
2806 {
2807 child_indexes.push_back (child_idx);
2808 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2809 }
2810 }
2811 DeclContext::lookup_iterator named_decl_pos;
2812 for (named_decl_pos = path->Decls.first;
2813 named_decl_pos != path->Decls.second && parent_record_decl;
2814 ++named_decl_pos)
2815 {
2816 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2817
2818 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2819 if (child_idx == UINT32_MAX)
2820 {
2821 child_indexes.clear();
2822 return 0;
2823 }
2824 else
2825 {
2826 child_indexes.push_back (child_idx);
2827 }
2828 }
2829 }
2830 return child_indexes.size();
2831 }
2832 }
2833
2834 }
2835 break;
2836
Greg Clayton9e409562010-07-28 02:04:09 +00002837 case clang::Type::ObjCObject:
2838 case clang::Type::ObjCInterface:
2839 {
2840 StringRef name_sref(name);
2841 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2842 assert (objc_class_type);
2843 if (objc_class_type)
2844 {
2845 uint32_t child_idx = 0;
2846 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2847
2848 if (class_interface_decl)
2849 {
2850 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2851 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2852
Greg Clayton6ba78152010-09-18 02:11:07 +00002853 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9e409562010-07-28 02:04:09 +00002854 {
2855 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2856
2857 if (ivar_decl->getName().equals (name_sref))
2858 {
2859 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2860 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2861 ++child_idx;
2862
2863 child_indexes.push_back (child_idx);
2864 return child_indexes.size();
2865 }
2866 }
2867
2868 if (superclass_interface_decl)
2869 {
2870 // The super class index is always zero for ObjC classes,
2871 // so we push it onto the child indexes in case we find
2872 // an ivar in our superclass...
2873 child_indexes.push_back (0);
2874
2875 if (GetIndexOfChildMemberWithName (ast_context,
2876 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2877 name,
2878 omit_empty_base_classes,
2879 child_indexes))
2880 {
2881 // We did find an ivar in a superclass so just
2882 // return the results!
2883 return child_indexes.size();
2884 }
2885
2886 // We didn't find an ivar matching "name" in our
2887 // superclass, pop the superclass zero index that
2888 // we pushed on above.
2889 child_indexes.pop_back();
2890 }
2891 }
2892 }
2893 }
2894 break;
2895
2896 case clang::Type::ObjCObjectPointer:
2897 {
2898 return GetIndexOfChildMemberWithName (ast_context,
2899 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2900 name,
2901 omit_empty_base_classes,
2902 child_indexes);
2903 }
2904 break;
2905
2906
Greg Claytone1a916a2010-07-21 22:12:05 +00002907 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002908 {
2909// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2910// const uint64_t element_count = array->getSize().getLimitedValue();
2911//
2912// if (idx < element_count)
2913// {
2914// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2915//
2916// char element_name[32];
2917// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2918//
2919// child_name.assign(element_name);
2920// assert(field_type_info.first % 8 == 0);
2921// child_byte_size = field_type_info.first / 8;
2922// child_byte_offset = idx * child_byte_size;
2923// return array->getElementType().getAsOpaquePtr();
2924// }
2925 }
2926 break;
2927
Greg Claytone1a916a2010-07-21 22:12:05 +00002928// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002929// {
2930// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2931// QualType pointee_type = mem_ptr_type->getPointeeType();
2932//
2933// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2934// {
2935// return GetIndexOfChildWithName (ast_context,
2936// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2937// name);
2938// }
2939// }
2940// break;
2941//
Greg Claytone1a916a2010-07-21 22:12:05 +00002942 case clang::Type::LValueReference:
2943 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002944 {
2945 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2946 QualType pointee_type = reference_type->getPointeeType();
2947
2948 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2949 {
2950 return GetIndexOfChildMemberWithName (ast_context,
2951 reference_type->getPointeeType().getAsOpaquePtr(),
2952 name,
2953 omit_empty_base_classes,
2954 child_indexes);
2955 }
2956 }
2957 break;
2958
Greg Claytone1a916a2010-07-21 22:12:05 +00002959 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002960 {
2961 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2962 QualType pointee_type = pointer_type->getPointeeType();
2963
2964 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2965 {
2966 return GetIndexOfChildMemberWithName (ast_context,
2967 pointer_type->getPointeeType().getAsOpaquePtr(),
2968 name,
2969 omit_empty_base_classes,
2970 child_indexes);
2971 }
2972 else
2973 {
2974// if (parent_name)
2975// {
2976// child_name.assign(1, '*');
2977// child_name += parent_name;
2978// }
2979//
2980// // We have a pointer to an simple type
2981// if (idx == 0)
2982// {
2983// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2984// assert(clang_type_info.first % 8 == 0);
2985// child_byte_size = clang_type_info.first / 8;
2986// child_byte_offset = 0;
2987// return pointee_type.getAsOpaquePtr();
2988// }
2989 }
2990 }
2991 break;
2992
Greg Claytone1a916a2010-07-21 22:12:05 +00002993 case clang::Type::Typedef:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002994 return GetIndexOfChildMemberWithName (ast_context,
Sean Callanan48114472010-12-13 01:26:27 +00002995 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002996 name,
2997 omit_empty_base_classes,
2998 child_indexes);
2999
3000 default:
3001 break;
3002 }
3003 }
3004 return 0;
3005}
3006
3007
3008// Get the index of the child of "clang_type" whose name matches. This function
3009// doesn't descend into the children, but only looks one level deep and name
3010// matches can include base class names.
3011
3012uint32_t
3013ClangASTContext::GetIndexOfChildWithName
3014(
3015 ASTContext *ast_context,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003016 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003017 const char *name,
3018 bool omit_empty_base_classes
3019)
3020{
3021 if (clang_type && name && name[0])
3022 {
3023 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00003024
Greg Clayton737b9322010-09-13 03:32:57 +00003025 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9e409562010-07-28 02:04:09 +00003026
Greg Clayton737b9322010-09-13 03:32:57 +00003027 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003028 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003029 case clang::Type::Record:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003030 {
3031 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3032 const RecordDecl *record_decl = record_type->getDecl();
3033
3034 assert(record_decl);
3035 uint32_t child_idx = 0;
3036
3037 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3038
3039 if (cxx_record_decl)
3040 {
3041 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3042 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3043 base_class != base_class_end;
3044 ++base_class)
3045 {
3046 // Skip empty base classes
3047 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3048 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3049 continue;
3050
3051 if (base_class->getType().getAsString().compare (name) == 0)
3052 return child_idx;
3053 ++child_idx;
3054 }
3055 }
3056
3057 // Try and find a field that matches NAME
3058 RecordDecl::field_iterator field, field_end;
3059 StringRef name_sref(name);
3060 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3061 field != field_end;
3062 ++field, ++child_idx)
3063 {
3064 if (field->getName().equals (name_sref))
3065 return child_idx;
3066 }
3067
3068 }
3069 break;
3070
Greg Clayton9e409562010-07-28 02:04:09 +00003071 case clang::Type::ObjCObject:
3072 case clang::Type::ObjCInterface:
3073 {
3074 StringRef name_sref(name);
3075 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
3076 assert (objc_class_type);
3077 if (objc_class_type)
3078 {
3079 uint32_t child_idx = 0;
3080 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3081
3082 if (class_interface_decl)
3083 {
3084 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3085 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3086
3087 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3088 {
3089 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3090
3091 if (ivar_decl->getName().equals (name_sref))
3092 {
3093 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3094 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3095 ++child_idx;
3096
3097 return child_idx;
3098 }
3099 }
3100
3101 if (superclass_interface_decl)
3102 {
3103 if (superclass_interface_decl->getName().equals (name_sref))
3104 return 0;
3105 }
3106 }
3107 }
3108 }
3109 break;
3110
3111 case clang::Type::ObjCObjectPointer:
3112 {
3113 return GetIndexOfChildWithName (ast_context,
3114 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3115 name,
3116 omit_empty_base_classes);
3117 }
3118 break;
3119
Greg Claytone1a916a2010-07-21 22:12:05 +00003120 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003121 {
3122// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3123// const uint64_t element_count = array->getSize().getLimitedValue();
3124//
3125// if (idx < element_count)
3126// {
3127// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
3128//
3129// char element_name[32];
3130// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3131//
3132// child_name.assign(element_name);
3133// assert(field_type_info.first % 8 == 0);
3134// child_byte_size = field_type_info.first / 8;
3135// child_byte_offset = idx * child_byte_size;
3136// return array->getElementType().getAsOpaquePtr();
3137// }
3138 }
3139 break;
3140
Greg Claytone1a916a2010-07-21 22:12:05 +00003141// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003142// {
3143// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3144// QualType pointee_type = mem_ptr_type->getPointeeType();
3145//
3146// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3147// {
3148// return GetIndexOfChildWithName (ast_context,
3149// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3150// name);
3151// }
3152// }
3153// break;
3154//
Greg Claytone1a916a2010-07-21 22:12:05 +00003155 case clang::Type::LValueReference:
3156 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003157 {
3158 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3159 QualType pointee_type = reference_type->getPointeeType();
3160
3161 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3162 {
3163 return GetIndexOfChildWithName (ast_context,
3164 reference_type->getPointeeType().getAsOpaquePtr(),
3165 name,
3166 omit_empty_base_classes);
3167 }
3168 }
3169 break;
3170
Greg Claytone1a916a2010-07-21 22:12:05 +00003171 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003172 {
3173 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3174 QualType pointee_type = pointer_type->getPointeeType();
3175
3176 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3177 {
3178 return GetIndexOfChildWithName (ast_context,
3179 pointer_type->getPointeeType().getAsOpaquePtr(),
3180 name,
3181 omit_empty_base_classes);
3182 }
3183 else
3184 {
3185// if (parent_name)
3186// {
3187// child_name.assign(1, '*');
3188// child_name += parent_name;
3189// }
3190//
3191// // We have a pointer to an simple type
3192// if (idx == 0)
3193// {
3194// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3195// assert(clang_type_info.first % 8 == 0);
3196// child_byte_size = clang_type_info.first / 8;
3197// child_byte_offset = 0;
3198// return pointee_type.getAsOpaquePtr();
3199// }
3200 }
3201 }
3202 break;
3203
Greg Claytone1a916a2010-07-21 22:12:05 +00003204 case clang::Type::Typedef:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003205 return GetIndexOfChildWithName (ast_context,
Sean Callanan48114472010-12-13 01:26:27 +00003206 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003207 name,
3208 omit_empty_base_classes);
3209
3210 default:
3211 break;
3212 }
3213 }
3214 return UINT32_MAX;
3215}
3216
3217#pragma mark TagType
3218
3219bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003220ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003221{
3222 if (tag_clang_type)
3223 {
3224 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Claytone1a916a2010-07-21 22:12:05 +00003225 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003226 if (clang_type)
3227 {
3228 TagType *tag_type = dyn_cast<TagType>(clang_type);
3229 if (tag_type)
3230 {
3231 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3232 if (tag_decl)
3233 {
3234 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3235 return true;
3236 }
3237 }
3238 }
3239 }
3240 return false;
3241}
3242
3243
3244#pragma mark DeclContext Functions
3245
3246DeclContext *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003247ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003248{
3249 if (clang_type == NULL)
3250 return NULL;
3251
3252 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003253 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3254 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003255 {
Greg Clayton9e409562010-07-28 02:04:09 +00003256 case clang::Type::FunctionNoProto: break;
3257 case clang::Type::FunctionProto: break;
3258 case clang::Type::IncompleteArray: break;
3259 case clang::Type::VariableArray: break;
3260 case clang::Type::ConstantArray: break;
3261 case clang::Type::ExtVector: break;
3262 case clang::Type::Vector: break;
3263 case clang::Type::Builtin: break;
3264 case clang::Type::BlockPointer: break;
3265 case clang::Type::Pointer: break;
3266 case clang::Type::LValueReference: break;
3267 case clang::Type::RValueReference: break;
3268 case clang::Type::MemberPointer: break;
3269 case clang::Type::Complex: break;
3270 case clang::Type::ObjCObject: break;
3271 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3272 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3273 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3274 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
Sean Callanan48114472010-12-13 01:26:27 +00003275 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003276
Greg Clayton9e409562010-07-28 02:04:09 +00003277 case clang::Type::TypeOfExpr: break;
3278 case clang::Type::TypeOf: break;
3279 case clang::Type::Decltype: break;
3280 //case clang::Type::QualifiedName: break;
3281 case clang::Type::TemplateSpecialization: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003282 }
3283 // No DeclContext in this type...
3284 return NULL;
3285}
3286
3287#pragma mark Namespace Declarations
3288
3289NamespaceDecl *
3290ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3291{
3292 // TODO: Do something intelligent with the Declaration object passed in
3293 // like maybe filling in the SourceLocation with it...
3294 if (name)
3295 {
3296 ASTContext *ast_context = getASTContext();
3297 if (decl_ctx == NULL)
3298 decl_ctx = ast_context->getTranslationUnitDecl();
3299 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3300 }
3301 return NULL;
3302}
3303
3304
3305#pragma mark Function Types
3306
3307FunctionDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003308ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003309{
3310 if (name)
3311 {
3312 ASTContext *ast_context = getASTContext();
3313 assert (ast_context != NULL);
3314
3315 if (name && name[0])
3316 {
3317 return FunctionDecl::Create(*ast_context,
3318 ast_context->getTranslationUnitDecl(),
3319 SourceLocation(),
3320 DeclarationName (&ast_context->Idents.get(name)),
3321 QualType::getFromOpaquePtr(function_clang_type),
3322 NULL,
3323 (FunctionDecl::StorageClass)storage,
3324 (FunctionDecl::StorageClass)storage,
3325 is_inline);
3326 }
3327 else
3328 {
3329 return FunctionDecl::Create(*ast_context,
3330 ast_context->getTranslationUnitDecl(),
3331 SourceLocation(),
3332 DeclarationName (),
3333 QualType::getFromOpaquePtr(function_clang_type),
3334 NULL,
3335 (FunctionDecl::StorageClass)storage,
3336 (FunctionDecl::StorageClass)storage,
3337 is_inline);
3338 }
3339 }
3340 return NULL;
3341}
3342
Greg Clayton1be10fc2010-09-29 01:12:09 +00003343clang_type_t
3344ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3345 clang_type_t result_type,
3346 clang_type_t *args,
Sean Callananc81256a2010-09-16 20:40:25 +00003347 unsigned num_args,
3348 bool is_variadic,
3349 unsigned type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003350{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003351 assert (ast_context != NULL);
3352 std::vector<QualType> qual_type_args;
3353 for (unsigned i=0; i<num_args; ++i)
3354 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3355
3356 // TODO: Detect calling convention in DWARF?
3357 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton471b31c2010-07-20 22:52:08 +00003358 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003359 qual_type_args.size(),
Sean Callananc81256a2010-09-16 20:40:25 +00003360 is_variadic,
3361 type_quals,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003362 false, // hasExceptionSpec
3363 false, // hasAnyExceptionSpec,
3364 0, // NumExs
3365 0, // const QualType *ExArray
3366 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3367}
3368
3369ParmVarDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003370ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003371{
3372 ASTContext *ast_context = getASTContext();
3373 assert (ast_context != NULL);
3374 return ParmVarDecl::Create(*ast_context,
3375 ast_context->getTranslationUnitDecl(),
3376 SourceLocation(),
3377 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callananc81256a2010-09-16 20:40:25 +00003378 QualType::getFromOpaquePtr(param_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003379 NULL,
3380 (VarDecl::StorageClass)storage,
3381 (VarDecl::StorageClass)storage,
3382 0);
3383}
3384
3385void
3386ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3387{
3388 if (function_decl)
3389 function_decl->setParams (params, num_params);
3390}
3391
3392
3393#pragma mark Array Types
3394
Greg Clayton1be10fc2010-09-29 01:12:09 +00003395clang_type_t
3396ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003397{
3398 if (element_type)
3399 {
3400 ASTContext *ast_context = getASTContext();
3401 assert (ast_context != NULL);
3402 llvm::APInt ap_element_count (64, element_count);
3403 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3404 ap_element_count,
3405 ArrayType::Normal,
3406 0).getAsOpaquePtr(); // ElemQuals
3407 }
3408 return NULL;
3409}
3410
3411
3412#pragma mark TagDecl
3413
3414bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003415ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003416{
3417 if (clang_type)
3418 {
3419 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Claytone1a916a2010-07-21 22:12:05 +00003420 clang::Type *t = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003421 if (t)
3422 {
3423 TagType *tag_type = dyn_cast<TagType>(t);
3424 if (tag_type)
3425 {
3426 TagDecl *tag_decl = tag_type->getDecl();
3427 if (tag_decl)
3428 {
3429 tag_decl->startDefinition();
3430 return true;
3431 }
3432 }
3433 }
3434 }
3435 return false;
3436}
3437
3438bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003439ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003440{
3441 if (clang_type)
3442 {
3443 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton14372242010-09-29 03:44:17 +00003444
3445 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3446
3447 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003448 {
Greg Clayton14372242010-09-29 03:44:17 +00003449 cxx_record_decl->completeDefinition();
3450
3451 return true;
3452 }
3453
Sean Callanana2424172010-10-25 00:29:48 +00003454 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3455
3456 if (objc_class_type)
3457 {
3458 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3459
3460 class_interface_decl->setForwardDecl(false);
3461 }
3462
Greg Clayton14372242010-09-29 03:44:17 +00003463 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3464
3465 if (enum_type)
3466 {
3467 EnumDecl *enum_decl = enum_type->getDecl();
3468
3469 if (enum_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003470 {
Greg Clayton14372242010-09-29 03:44:17 +00003471 /// TODO This really needs to be fixed.
3472
3473 unsigned NumPositiveBits = 1;
3474 unsigned NumNegativeBits = 0;
3475
Greg Claytone02b8502010-10-12 04:29:14 +00003476 ASTContext *ast_context = getASTContext();
3477
3478 QualType promotion_qual_type;
3479 // If the enum integer type is less than an integer in bit width,
3480 // then we must promote it to an integer size.
3481 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3482 {
3483 if (enum_decl->getIntegerType()->isSignedIntegerType())
3484 promotion_qual_type = ast_context->IntTy;
3485 else
3486 promotion_qual_type = ast_context->UnsignedIntTy;
3487 }
3488 else
3489 promotion_qual_type = enum_decl->getIntegerType();
3490
3491 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton14372242010-09-29 03:44:17 +00003492 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003493 }
3494 }
3495 }
3496 return false;
3497}
3498
3499
3500#pragma mark Enumeration Types
3501
Greg Clayton1be10fc2010-09-29 01:12:09 +00003502clang_type_t
Greg Claytonca512b32011-01-14 04:54:56 +00003503ClangASTContext::CreateEnumerationType
3504(
3505 const char *name,
3506 DeclContext *decl_ctx,
3507 const Declaration &decl,
3508 clang_type_t integer_qual_type
3509)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003510{
3511 // TODO: Do something intelligent with the Declaration object passed in
3512 // like maybe filling in the SourceLocation with it...
3513 ASTContext *ast_context = getASTContext();
3514 assert (ast_context != NULL);
Greg Claytone02b8502010-10-12 04:29:14 +00003515
3516 // TODO: ask about these...
3517// const bool IsScoped = false;
3518// const bool IsFixed = false;
3519
3520 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
Greg Claytonca512b32011-01-14 04:54:56 +00003521 decl_ctx,
Greg Claytone02b8502010-10-12 04:29:14 +00003522 SourceLocation(),
3523 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3524 SourceLocation(),
Sean Callanan48114472010-12-13 01:26:27 +00003525 NULL,
3526 false, // IsScoped
3527 false, // IsScopedUsingClassTag
3528 false); // IsFixed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003529 if (enum_decl)
Greg Clayton83ff3892010-09-12 23:17:56 +00003530 {
3531 // TODO: check if we should be setting the promotion type too?
3532 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003533 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Clayton83ff3892010-09-12 23:17:56 +00003534 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003535 return NULL;
3536}
3537
Greg Clayton1be10fc2010-09-29 01:12:09 +00003538clang_type_t
3539ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3540{
3541 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3542
3543 clang::Type *clang_type = enum_qual_type.getTypePtr();
3544 if (clang_type)
3545 {
3546 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3547 if (enum_type)
3548 {
3549 EnumDecl *enum_decl = enum_type->getDecl();
3550 if (enum_decl)
3551 return enum_decl->getIntegerType().getAsOpaquePtr();
3552 }
3553 }
3554 return NULL;
3555}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003556bool
3557ClangASTContext::AddEnumerationValueToEnumerationType
3558(
Greg Clayton1be10fc2010-09-29 01:12:09 +00003559 clang_type_t enum_clang_type,
3560 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003561 const Declaration &decl,
3562 const char *name,
3563 int64_t enum_value,
3564 uint32_t enum_value_bit_size
3565)
3566{
3567 if (enum_clang_type && enumerator_clang_type && name)
3568 {
3569 // TODO: Do something intelligent with the Declaration object passed in
3570 // like maybe filling in the SourceLocation with it...
3571 ASTContext *ast_context = getASTContext();
3572 IdentifierTable *identifier_table = getIdentifierTable();
3573
3574 assert (ast_context != NULL);
3575 assert (identifier_table != NULL);
3576 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3577
Greg Claytone1a916a2010-07-21 22:12:05 +00003578 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003579 if (clang_type)
3580 {
3581 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3582
3583 if (enum_type)
3584 {
3585 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3586 enum_llvm_apsint = enum_value;
3587 EnumConstantDecl *enumerator_decl =
3588 EnumConstantDecl::Create(*ast_context,
3589 enum_type->getDecl(),
3590 SourceLocation(),
3591 name ? &identifier_table->get(name) : NULL, // Identifier
3592 QualType::getFromOpaquePtr(enumerator_clang_type),
3593 NULL,
3594 enum_llvm_apsint);
3595
3596 if (enumerator_decl)
3597 {
3598 enum_type->getDecl()->addDecl(enumerator_decl);
3599 return true;
3600 }
3601 }
3602 }
3603 }
3604 return false;
3605}
3606
3607#pragma mark Pointers & References
3608
Greg Clayton1be10fc2010-09-29 01:12:09 +00003609clang_type_t
3610ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003611{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003612 return CreatePointerType (getASTContext(), clang_type);
3613}
3614
3615clang_type_t
3616ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
3617{
3618 if (ast && clang_type)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003619 {
3620 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3621
Greg Clayton737b9322010-09-13 03:32:57 +00003622 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3623 switch (type_class)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003624 {
3625 case clang::Type::ObjCObject:
3626 case clang::Type::ObjCInterface:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003627 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003628
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003629 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003630 return ast->getPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003631 }
3632 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003633 return NULL;
3634}
3635
Greg Clayton1be10fc2010-09-29 01:12:09 +00003636clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003637ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
3638 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003639{
3640 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003641 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003642 return NULL;
3643}
3644
Greg Clayton1be10fc2010-09-29 01:12:09 +00003645clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003646ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
3647 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003648{
3649 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003650 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003651 return NULL;
3652}
3653
Greg Clayton1be10fc2010-09-29 01:12:09 +00003654clang_type_t
3655ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Clayton9b81a312010-06-12 01:20:30 +00003656{
3657 if (clang_pointee_type && clang_pointee_type)
3658 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3659 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3660 return NULL;
3661}
3662
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003663size_t
3664ClangASTContext::GetPointerBitSize ()
3665{
3666 ASTContext *ast_context = getASTContext();
3667 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3668}
3669
3670bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003671ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003672{
3673 if (clang_type == NULL)
3674 return false;
3675
3676 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003677 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3678 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003679 {
Sean Callanana2424172010-10-25 00:29:48 +00003680 case clang::Type::Builtin:
3681 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3682 {
3683 default:
3684 break;
3685 case clang::BuiltinType::ObjCId:
3686 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00003687 return true;
3688 }
3689 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00003690 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003691 if (target_type)
3692 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3693 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003694 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003695 if (target_type)
3696 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3697 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003698 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003699 if (target_type)
3700 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3701 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003702 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003703 if (target_type)
3704 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3705 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003706 case clang::Type::LValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003707 if (target_type)
3708 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3709 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003710 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003711 if (target_type)
3712 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3713 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003714 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00003715 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003716 default:
3717 break;
3718 }
3719 return false;
3720}
3721
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003722bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003723ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003724{
3725 if (!clang_type)
3726 return false;
3727
3728 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3729 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3730
3731 if (builtin_type)
3732 {
3733 if (builtin_type->isInteger())
3734 is_signed = builtin_type->isSignedInteger();
3735
3736 return true;
3737 }
3738
3739 return false;
3740}
3741
3742bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003743ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003744{
3745 if (clang_type)
3746 {
3747 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003748 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3749 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003750 {
Sean Callanana2424172010-10-25 00:29:48 +00003751 case clang::Type::Builtin:
3752 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3753 {
3754 default:
3755 break;
3756 case clang::BuiltinType::ObjCId:
3757 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00003758 return true;
3759 }
3760 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00003761 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003762 if (target_type)
3763 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3764 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003765 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003766 if (target_type)
3767 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3768 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003769 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003770 if (target_type)
3771 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3772 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003773 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003774 if (target_type)
3775 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3776 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003777 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00003778 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003779 default:
3780 break;
3781 }
3782 }
3783 return false;
3784}
3785
3786bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003787ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003788{
3789 if (clang_type)
3790 {
3791 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3792
3793 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3794 {
3795 clang::BuiltinType::Kind kind = BT->getKind();
3796 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3797 {
3798 count = 1;
3799 is_complex = false;
3800 return true;
3801 }
3802 }
3803 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3804 {
3805 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3806 {
3807 count = 2;
3808 is_complex = true;
3809 return true;
3810 }
3811 }
3812 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3813 {
3814 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3815 {
3816 count = VT->getNumElements();
3817 is_complex = false;
3818 return true;
3819 }
3820 }
3821 }
3822 return false;
3823}
3824
Greg Clayton8f92f0a2010-10-14 22:52:14 +00003825
3826bool
3827ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3828{
3829 if (clang_type)
3830 {
3831 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3832
3833 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3834 if (cxx_record_decl)
3835 {
3836 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3837 return true;
3838 }
3839 }
3840 class_name.clear();
3841 return false;
3842}
3843
3844
Greg Clayton0fffff52010-09-24 05:15:53 +00003845bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003846ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00003847{
3848 if (clang_type)
3849 {
3850 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3851 if (qual_type->getAsCXXRecordDecl() != NULL)
3852 return true;
3853 }
3854 return false;
3855}
3856
3857bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003858ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00003859{
3860 if (clang_type)
3861 {
3862 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3863 if (qual_type->isObjCObjectOrInterfaceType())
3864 return true;
3865 }
3866 return false;
3867}
3868
3869
Greg Clayton73b472d2010-10-27 03:32:59 +00003870bool
3871ClangASTContext::IsCharType (clang_type_t clang_type)
3872{
3873 if (clang_type)
3874 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3875 return false;
3876}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003877
3878bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003879ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003880{
Greg Clayton73b472d2010-10-27 03:32:59 +00003881 clang_type_t pointee_or_element_clang_type = NULL;
3882 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3883
3884 if (pointee_or_element_clang_type == NULL)
3885 return false;
3886
3887 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003888 {
Greg Clayton73b472d2010-10-27 03:32:59 +00003889 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3890
3891 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003892 {
Greg Clayton73b472d2010-10-27 03:32:59 +00003893 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3894 if (type_flags.Test (eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003895 {
Greg Clayton73b472d2010-10-27 03:32:59 +00003896 // We know the size of the array and it could be a C string
3897 // since it is an array of characters
3898 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3899 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003900 }
Greg Clayton73b472d2010-10-27 03:32:59 +00003901 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003902 {
Greg Clayton73b472d2010-10-27 03:32:59 +00003903 length = 0;
3904 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003905 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003906
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003907 }
3908 }
3909 return false;
3910}
3911
3912bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003913ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton737b9322010-09-13 03:32:57 +00003914{
3915 if (clang_type)
3916 {
3917 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3918
3919 if (qual_type->isFunctionPointerType())
3920 return true;
3921
3922 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3923 switch (type_class)
3924 {
3925 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00003926 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00003927
3928 case clang::Type::LValueReference:
3929 case clang::Type::RValueReference:
3930 {
3931 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3932 if (reference_type)
3933 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3934 }
3935 break;
3936 }
3937 }
3938 return false;
3939}
3940
Greg Clayton73b472d2010-10-27 03:32:59 +00003941size_t
3942ClangASTContext::GetArraySize (clang_type_t clang_type)
3943{
3944 if (clang_type)
3945 {
3946 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3947 if (array)
3948 return array->getSize().getLimitedValue();
3949 }
3950 return 0;
3951}
Greg Clayton737b9322010-09-13 03:32:57 +00003952
3953bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003954ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003955{
3956 if (!clang_type)
3957 return false;
3958
3959 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3960
Greg Clayton737b9322010-09-13 03:32:57 +00003961 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3962 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003963 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003964 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003965 if (member_type)
3966 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3967 if (size)
3968 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3969 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003970 case clang::Type::IncompleteArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003971 if (member_type)
3972 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3973 if (size)
3974 *size = 0;
3975 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003976 case clang::Type::VariableArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003977 if (member_type)
3978 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3979 if (size)
3980 *size = 0;
Greg Claytone1a916a2010-07-21 22:12:05 +00003981 case clang::Type::DependentSizedArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003982 if (member_type)
3983 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3984 if (size)
3985 *size = 0;
3986 return true;
3987 }
3988 return false;
3989}
3990
3991
3992#pragma mark Typedefs
3993
Greg Clayton1be10fc2010-09-29 01:12:09 +00003994clang_type_t
3995ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003996{
3997 if (clang_type)
3998 {
3999 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4000 ASTContext *ast_context = getASTContext();
4001 IdentifierTable *identifier_table = getIdentifierTable();
4002 assert (ast_context != NULL);
4003 assert (identifier_table != NULL);
4004 if (decl_ctx == NULL)
4005 decl_ctx = ast_context->getTranslationUnitDecl();
4006 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
4007 decl_ctx,
4008 SourceLocation(),
4009 name ? &identifier_table->get(name) : NULL, // Identifier
4010 ast_context->CreateTypeSourceInfo(qual_type));
4011
4012 // Get a uniqued QualType for the typedef decl type
4013 return ast_context->getTypedefType (decl).getAsOpaquePtr();
4014 }
4015 return NULL;
4016}
4017
4018
4019std::string
Greg Clayton1be10fc2010-09-29 01:12:09 +00004020ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004021{
4022 std::string return_name;
4023
Greg Clayton1be10fc2010-09-29 01:12:09 +00004024 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004025
Greg Clayton1be10fc2010-09-29 01:12:09 +00004026 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004027 if (typedef_type)
4028 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00004029 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004030 return_name = typedef_decl->getQualifiedNameAsString();
4031 }
4032 else
4033 {
4034 return_name = qual_type.getAsString();
4035 }
4036
4037 return return_name;
4038}
4039
4040// Disable this for now since I can't seem to get a nicely formatted float
4041// out of the APFloat class without just getting the float, double or quad
4042// and then using a formatted print on it which defeats the purpose. We ideally
4043// would like to get perfect string values for any kind of float semantics
4044// so we can support remote targets. The code below also requires a patch to
4045// llvm::APInt.
4046//bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004047//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 Lattner30fdc8d2010-06-08 16:52:24 +00004048//{
4049// uint32_t count = 0;
4050// bool is_complex = false;
4051// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4052// {
4053// unsigned num_bytes_per_float = byte_size / count;
4054// unsigned num_bits_per_float = num_bytes_per_float * 8;
4055//
4056// float_str.clear();
4057// uint32_t i;
4058// for (i=0; i<count; i++)
4059// {
4060// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
4061// bool is_ieee = false;
4062// APFloat ap_float(ap_int, is_ieee);
4063// char s[1024];
4064// unsigned int hex_digits = 0;
4065// bool upper_case = false;
4066//
4067// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
4068// {
4069// if (i > 0)
4070// float_str.append(", ");
4071// float_str.append(s);
4072// if (i == 1 && is_complex)
4073// float_str.append(1, 'i');
4074// }
4075// }
4076// return !float_str.empty();
4077// }
4078// return false;
4079//}
4080
4081size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00004082ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004083{
4084 if (clang_type)
4085 {
4086 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4087 uint32_t count = 0;
4088 bool is_complex = false;
4089 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4090 {
4091 // TODO: handle complex and vector types
4092 if (count != 1)
4093 return false;
4094
4095 StringRef s_sref(s);
4096 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
4097
4098 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
4099 const uint64_t byte_size = bit_size / 8;
4100 if (dst_size >= byte_size)
4101 {
4102 if (bit_size == sizeof(float)*8)
4103 {
4104 float float32 = ap_float.convertToFloat();
4105 ::memcpy (dst, &float32, byte_size);
4106 return byte_size;
4107 }
4108 else if (bit_size >= 64)
4109 {
4110 llvm::APInt ap_int(ap_float.bitcastToAPInt());
4111 ::memcpy (dst, ap_int.getRawData(), byte_size);
4112 return byte_size;
4113 }
4114 }
4115 }
4116 }
4117 return 0;
4118}
Sean Callanan6fe64b52010-09-17 02:24:29 +00004119
4120unsigned
Greg Clayton1be10fc2010-09-29 01:12:09 +00004121ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanan6fe64b52010-09-17 02:24:29 +00004122{
4123 assert (clang_type);
4124
4125 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4126
4127 return qual_type.getQualifiers().getCVRQualifiers();
4128}