blob: c8ad302a309c94fcb9701c7080e60b57cae3f2b9 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedmanf05633b2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Sean Callananbc4f0f52010-07-08 18:16:16 +000017#define NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "clang/AST/ASTContext.h"
19#include "clang/AST/ASTImporter.h"
20#include "clang/AST/CXXInheritance.h"
Greg Clayton84f80752010-07-22 18:30:50 +000021#include "clang/AST/DeclObjC.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "clang/AST/RecordLayout.h"
23#include "clang/AST/Type.h"
24#include "clang/Basic/Builtins.h"
25#include "clang/Basic/FileManager.h"
Sean Callanan8a3b0a82010-11-18 02:56:27 +000026#include "clang/Basic/FileSystemOptions.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "clang/Basic/SourceManager.h"
28#include "clang/Basic/TargetInfo.h"
29#include "clang/Basic/TargetOptions.h"
30#include "clang/Frontend/FrontendOptions.h"
31#include "clang/Frontend/LangStandard.h"
Sean Callananbc4f0f52010-07-08 18:16:16 +000032#undef NDEBUG
Chris Lattner24943d22010-06-08 16:52:24 +000033
Chris Lattner24943d22010-06-08 16:52:24 +000034#include "lldb/Core/dwarf.h"
Greg Claytonf3d0b0c2010-10-27 03:32:59 +000035#include "lldb/Core/Flags.h"
Sean Callanan839fde42010-10-28 18:19:36 +000036#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037
Eli Friedmanf05633b2010-06-13 19:06:42 +000038#include <stdio.h>
39
Greg Clayton585660c2010-08-05 01:57:25 +000040using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000041using namespace lldb_private;
42using namespace llvm;
43using namespace clang;
44
Greg Clayton84f80752010-07-22 18:30:50 +000045static AccessSpecifier
Greg Clayton585660c2010-08-05 01:57:25 +000046ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000047{
48 switch (access)
49 {
Greg Clayton585660c2010-08-05 01:57:25 +000050 default: break;
51 case eAccessNone: return AS_none;
52 case eAccessPublic: return AS_public;
53 case eAccessPrivate: return AS_private;
54 case eAccessProtected: return AS_protected;
Greg Clayton84f80752010-07-22 18:30:50 +000055 }
56 return AS_none;
57}
58
59static ObjCIvarDecl::AccessControl
Greg Clayton585660c2010-08-05 01:57:25 +000060ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton84f80752010-07-22 18:30:50 +000061{
62 switch (access)
63 {
Greg Clayton585660c2010-08-05 01:57:25 +000064 default: break;
65 case eAccessNone: return ObjCIvarDecl::None;
66 case eAccessPublic: return ObjCIvarDecl::Public;
67 case eAccessPrivate: return ObjCIvarDecl::Private;
68 case eAccessProtected: return ObjCIvarDecl::Protected;
69 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton84f80752010-07-22 18:30:50 +000070 }
71 return ObjCIvarDecl::None;
72}
73
74
Chris Lattner24943d22010-06-08 16:52:24 +000075static void
76ParseLangArgs
77(
78 LangOptions &Opts,
Greg Claytone41c4b22010-06-13 17:34:29 +000079 InputKind IK
Chris Lattner24943d22010-06-08 16:52:24 +000080)
81{
82 // FIXME: Cleanup per-file based stuff.
83
84 // Set some properties which depend soley on the input kind; it would be nice
85 // to move these to the language standard, and have the driver resolve the
86 // input kind + language standard.
Greg Claytone41c4b22010-06-13 17:34:29 +000087 if (IK == IK_Asm) {
Chris Lattner24943d22010-06-08 16:52:24 +000088 Opts.AsmPreprocessor = 1;
Greg Claytone41c4b22010-06-13 17:34:29 +000089 } else if (IK == IK_ObjC ||
90 IK == IK_ObjCXX ||
91 IK == IK_PreprocessedObjC ||
92 IK == IK_PreprocessedObjCXX) {
Chris Lattner24943d22010-06-08 16:52:24 +000093 Opts.ObjC1 = Opts.ObjC2 = 1;
94 }
95
96 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
97
98 if (LangStd == LangStandard::lang_unspecified) {
99 // Based on the base language, pick one.
100 switch (IK) {
Greg Claytone41c4b22010-06-13 17:34:29 +0000101 case IK_None:
102 case IK_AST:
Chris Lattner24943d22010-06-08 16:52:24 +0000103 assert(0 && "Invalid input kind!");
Greg Claytone41c4b22010-06-13 17:34:29 +0000104 case IK_OpenCL:
Chris Lattner24943d22010-06-08 16:52:24 +0000105 LangStd = LangStandard::lang_opencl;
106 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000107 case IK_Asm:
108 case IK_C:
109 case IK_PreprocessedC:
110 case IK_ObjC:
111 case IK_PreprocessedObjC:
Chris Lattner24943d22010-06-08 16:52:24 +0000112 LangStd = LangStandard::lang_gnu99;
113 break;
Greg Claytone41c4b22010-06-13 17:34:29 +0000114 case IK_CXX:
115 case IK_PreprocessedCXX:
116 case IK_ObjCXX:
117 case IK_PreprocessedObjCXX:
Chris Lattner24943d22010-06-08 16:52:24 +0000118 LangStd = LangStandard::lang_gnucxx98;
119 break;
120 }
121 }
122
123 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
124 Opts.BCPLComment = Std.hasBCPLComments();
125 Opts.C99 = Std.isC99();
126 Opts.CPlusPlus = Std.isCPlusPlus();
127 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
128 Opts.Digraphs = Std.hasDigraphs();
129 Opts.GNUMode = Std.isGNUMode();
130 Opts.GNUInline = !Std.isC99();
131 Opts.HexFloats = Std.hasHexFloats();
132 Opts.ImplicitInt = Std.hasImplicitInt();
133
134 // OpenCL has some additional defaults.
135 if (LangStd == LangStandard::lang_opencl) {
136 Opts.OpenCL = 1;
137 Opts.AltiVec = 1;
138 Opts.CXXOperatorNames = 1;
139 Opts.LaxVectorConversions = 1;
140 }
141
142 // OpenCL and C++ both have bool, true, false keywords.
143 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
144
145// if (Opts.CPlusPlus)
146// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
147//
148// if (Args.hasArg(OPT_fobjc_gc_only))
149// Opts.setGCMode(LangOptions::GCOnly);
150// else if (Args.hasArg(OPT_fobjc_gc))
151// Opts.setGCMode(LangOptions::HybridGC);
152//
153// if (Args.hasArg(OPT_print_ivar_layout))
154// Opts.ObjCGCBitmapPrint = 1;
155//
156// if (Args.hasArg(OPT_faltivec))
157// Opts.AltiVec = 1;
158//
159// if (Args.hasArg(OPT_pthread))
160// Opts.POSIXThreads = 1;
161//
162// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
163// "default");
164// if (Vis == "default")
Sean Callanan8950c9a2010-10-29 18:38:40 +0000165 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner24943d22010-06-08 16:52:24 +0000166// else if (Vis == "hidden")
167// Opts.setVisibilityMode(LangOptions::Hidden);
168// else if (Vis == "protected")
169// Opts.setVisibilityMode(LangOptions::Protected);
170// else
171// Diags.Report(diag::err_drv_invalid_value)
172// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
173
174// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
175
176 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
177 // is specified, or -std is set to a conforming mode.
178 Opts.Trigraphs = !Opts.GNUMode;
179// if (Args.hasArg(OPT_trigraphs))
180// Opts.Trigraphs = 1;
181//
182// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
183// OPT_fno_dollars_in_identifiers,
184// !Opts.AsmPreprocessor);
185// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
186// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
187// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
188// if (Args.hasArg(OPT_fno_lax_vector_conversions))
189// Opts.LaxVectorConversions = 0;
190// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
191// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
192// Opts.Blocks = Args.hasArg(OPT_fblocks);
193// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
194// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
195// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
196// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
197// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
198// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
199// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
200// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
201// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
202// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
203// Diags);
204// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
205// Opts.ObjCConstantStringClass = getLastArgValue(Args,
206// OPT_fconstant_string_class);
207// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
208// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
209// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
210// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
211// Opts.Static = Args.hasArg(OPT_static_define);
212 Opts.OptimizeSize = 0;
213
214 // FIXME: Eliminate this dependency.
215// unsigned Opt =
216// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
217// Opts.Optimize = Opt != 0;
218 unsigned Opt = 0;
219
220 // This is the __NO_INLINE__ define, which just depends on things like the
221 // optimization level and -fno-inline, not actually whether the backend has
222 // inlining enabled.
223 //
224 // FIXME: This is affected by other options (-fno-inline).
225 Opts.NoInline = !Opt;
226
227// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
228// switch (SSP) {
229// default:
230// Diags.Report(diag::err_drv_invalid_value)
231// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
232// break;
233// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
234// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
235// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
236// }
237}
238
Chris Lattner24943d22010-06-08 16:52:24 +0000239
Chris Lattner24943d22010-06-08 16:52:24 +0000240ClangASTContext::ClangASTContext(const char *target_triple) :
241 m_target_triple(),
242 m_ast_context_ap(),
243 m_language_options_ap(),
244 m_source_manager_ap(),
245 m_diagnostic_ap(),
246 m_target_options_ap(),
247 m_target_info_ap(),
248 m_identifier_table_ap(),
249 m_selector_table_ap(),
250 m_builtins_ap()
251{
252 if (target_triple && target_triple[0])
253 m_target_triple.assign (target_triple);
254}
255
256//----------------------------------------------------------------------
257// Destructor
258//----------------------------------------------------------------------
259ClangASTContext::~ClangASTContext()
260{
261 m_builtins_ap.reset();
262 m_selector_table_ap.reset();
263 m_identifier_table_ap.reset();
264 m_target_info_ap.reset();
265 m_target_options_ap.reset();
266 m_diagnostic_ap.reset();
267 m_source_manager_ap.reset();
268 m_language_options_ap.reset();
269 m_ast_context_ap.reset();
270}
271
272
273void
274ClangASTContext::Clear()
275{
276 m_ast_context_ap.reset();
277 m_language_options_ap.reset();
278 m_source_manager_ap.reset();
279 m_diagnostic_ap.reset();
280 m_target_options_ap.reset();
281 m_target_info_ap.reset();
282 m_identifier_table_ap.reset();
283 m_selector_table_ap.reset();
284 m_builtins_ap.reset();
285}
286
287const char *
288ClangASTContext::GetTargetTriple ()
289{
290 return m_target_triple.c_str();
291}
292
293void
294ClangASTContext::SetTargetTriple (const char *target_triple)
295{
296 Clear();
297 m_target_triple.assign(target_triple);
298}
299
300
301ASTContext *
302ClangASTContext::getASTContext()
303{
304 if (m_ast_context_ap.get() == NULL)
305 {
306 m_ast_context_ap.reset(
307 new ASTContext(
308 *getLanguageOptions(),
309 *getSourceManager(),
310 *getTargetInfo(),
311 *getIdentifierTable(),
312 *getSelectorTable(),
Greg Clayton6e713402010-07-30 20:30:44 +0000313 *getBuiltinContext(),
314 0));
Sean Callanan887d2512010-12-11 00:08:56 +0000315
316 m_ast_context_ap->getDiagnostics().setClient(getDiagnosticClient(), false);
Chris Lattner24943d22010-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 Claytone41c4b22010-06-13 17:34:29 +0000343 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
344// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner24943d22010-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 Callanan8a3b0a82010-11-18 02:56:27 +0000357clang::FileManager *
358ClangASTContext::getFileManager()
359{
360 if (m_file_manager_ap.get() == NULL)
Greg Clayton22defe82010-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 Callanan8a3b0a82010-11-18 02:56:27 +0000365 return m_file_manager_ap.get();
366}
367
Greg Clayton1674b122010-07-21 22:12:05 +0000368clang::SourceManager *
Chris Lattner24943d22010-06-08 16:52:24 +0000369ClangASTContext::getSourceManager()
370{
371 if (m_source_manager_ap.get() == NULL)
Greg Clayton22defe82010-12-02 23:20:03 +0000372 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
Chris Lattner24943d22010-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 Claytoneae91242010-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 Lattner24943d22010-06-08 16:52:24 +0000384 return m_diagnostic_ap.get();
385}
386
Sean Callanan887d2512010-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 Lattner24943d22010-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 Clayton462d4142010-09-29 01:12:09 +0000451clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000452ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-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 Clayton462d4142010-09-29 01:12:09 +0000461clang_type_t
462ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size)
Chris Lattner24943d22010-06-08 16:52:24 +0000463{
464 if (!ast_context)
465 return NULL;
466
467 switch (encoding)
468 {
Greg Clayton585660c2010-08-05 01:57:25 +0000469 case eEncodingInvalid:
Chris Lattner24943d22010-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 Clayton585660c2010-08-05 01:57:25 +0000474 case eEncodingUint:
Chris Lattner24943d22010-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 Clayton585660c2010-08-05 01:57:25 +0000489 case eEncodingSint:
Chris Lattner24943d22010-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 Clayton585660c2010-08-05 01:57:25 +0000504 case eEncodingIEEE754:
Chris Lattner24943d22010-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 Clayton585660c2010-08-05 01:57:25 +0000513 case eEncodingVector:
Chris Lattner24943d22010-06-08 16:52:24 +0000514 default:
515 break;
516 }
517
518 return NULL;
519}
520
Greg Clayton462d4142010-09-29 01:12:09 +0000521clang_type_t
Chris Lattner24943d22010-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
551 case DW_ATE_complex_float:
552 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy))
553 return ast_context->FloatComplexTy.getAsOpaquePtr();
554 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy))
555 return ast_context->DoubleComplexTy.getAsOpaquePtr();
556 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy))
557 return ast_context->LongDoubleComplexTy.getAsOpaquePtr();
558 break;
559
560 case DW_ATE_float:
561 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy))
562 return ast_context->FloatTy.getAsOpaquePtr();
563 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy))
564 return ast_context->DoubleTy.getAsOpaquePtr();
565 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy))
566 return ast_context->LongDoubleTy.getAsOpaquePtr();
567 break;
568
569 case DW_ATE_signed:
570 if (type_name)
571 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000572 if (strstr(type_name, "long long"))
Chris Lattner24943d22010-06-08 16:52:24 +0000573 {
Chris Lattner24943d22010-06-08 16:52:24 +0000574 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
575 return ast_context->LongLongTy.getAsOpaquePtr();
576 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000577 else if (strstr(type_name, "long"))
578 {
579 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
580 return ast_context->LongTy.getAsOpaquePtr();
581 }
582 else if (strstr(type_name, "short"))
Chris Lattner24943d22010-06-08 16:52:24 +0000583 {
584 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
585 return ast_context->ShortTy.getAsOpaquePtr();
586 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000587 else if (strstr(type_name, "char"))
Chris Lattner24943d22010-06-08 16:52:24 +0000588 {
589 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
590 return ast_context->CharTy.getAsOpaquePtr();
591 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
592 return ast_context->SignedCharTy.getAsOpaquePtr();
593 }
Greg Clayton8ff5d552010-11-02 03:48:39 +0000594 else if (strstr(type_name, "int"))
595 {
596 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
597 return ast_context->IntTy.getAsOpaquePtr();
598 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
599 return ast_context->Int128Ty.getAsOpaquePtr();
600 }
601 else if (streq(type_name, "wchar_t"))
Chris Lattner24943d22010-06-08 16:52:24 +0000602 {
603 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy))
604 return ast_context->WCharTy.getAsOpaquePtr();
605 }
Chris Lattner24943d22010-06-08 16:52:24 +0000606 }
607 // We weren't able to match up a type name, just search by size
608 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
609 return ast_context->CharTy.getAsOpaquePtr();
610 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy))
611 return ast_context->ShortTy.getAsOpaquePtr();
612 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy))
613 return ast_context->IntTy.getAsOpaquePtr();
614 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy))
615 return ast_context->LongTy.getAsOpaquePtr();
616 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy))
617 return ast_context->LongLongTy.getAsOpaquePtr();
618 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty))
619 return ast_context->Int128Ty.getAsOpaquePtr();
620 break;
621
622 case DW_ATE_signed_char:
623 if (type_name)
624 {
625 if (streq(type_name, "signed char"))
626 {
627 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
628 return ast_context->SignedCharTy.getAsOpaquePtr();
629 }
630 }
631 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy))
632 return ast_context->CharTy.getAsOpaquePtr();
633 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy))
634 return ast_context->SignedCharTy.getAsOpaquePtr();
635 break;
636
637 case DW_ATE_unsigned:
638 if (type_name)
639 {
Greg Clayton8ff5d552010-11-02 03:48:39 +0000640 if (strstr(type_name, "long long"))
641 {
642 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
643 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
644 }
645 else if (strstr(type_name, "long"))
646 {
647 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
648 return ast_context->UnsignedLongTy.getAsOpaquePtr();
649 }
650 else if (strstr(type_name, "short"))
651 {
652 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
653 return ast_context->UnsignedShortTy.getAsOpaquePtr();
654 }
655 else if (strstr(type_name, "char"))
656 {
657 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
658 return ast_context->UnsignedCharTy.getAsOpaquePtr();
659 }
660 else if (strstr(type_name, "int"))
Chris Lattner24943d22010-06-08 16:52:24 +0000661 {
662 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
663 return ast_context->UnsignedIntTy.getAsOpaquePtr();
664 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
665 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
666 }
Chris Lattner24943d22010-06-08 16:52:24 +0000667 }
668 // We weren't able to match up a type name, just search by size
669 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
670 return ast_context->UnsignedCharTy.getAsOpaquePtr();
671 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy))
672 return ast_context->UnsignedShortTy.getAsOpaquePtr();
673 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy))
674 return ast_context->UnsignedIntTy.getAsOpaquePtr();
675 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy))
676 return ast_context->UnsignedLongTy.getAsOpaquePtr();
677 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy))
678 return ast_context->UnsignedLongLongTy.getAsOpaquePtr();
679 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty))
680 return ast_context->UnsignedInt128Ty.getAsOpaquePtr();
681 break;
682
683 case DW_ATE_unsigned_char:
684 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy))
685 return ast_context->UnsignedCharTy.getAsOpaquePtr();
686 break;
687
688 case DW_ATE_imaginary_float:
689 break;
690 }
691 }
692 // This assert should fire for anything that we don't catch above so we know
693 // to fix any issues we run into.
694 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
695 return NULL;
696}
697
Greg Clayton462d4142010-09-29 01:12:09 +0000698clang_type_t
699ClangASTContext::GetBuiltInType_void(ASTContext *ast_context)
Chris Lattner24943d22010-06-08 16:52:24 +0000700{
Sean Callanana751f7b2010-09-17 02:24:29 +0000701 return ast_context->VoidTy.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000702}
703
Greg Clayton462d4142010-09-29 01:12:09 +0000704clang_type_t
Sean Callanana91dd992010-11-19 02:52:21 +0000705ClangASTContext::GetBuiltInType_bool()
706{
707 return getASTContext()->BoolTy.getAsOpaquePtr();
708}
709
710clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000711ClangASTContext::GetBuiltInType_objc_id()
712{
Sean Callananc4217a62010-12-06 23:53:20 +0000713 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000714}
715
Greg Clayton462d4142010-09-29 01:12:09 +0000716clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000717ClangASTContext::GetBuiltInType_objc_Class()
718{
Sean Callanan04325062010-10-25 00:29:48 +0000719 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000720}
721
Greg Clayton462d4142010-09-29 01:12:09 +0000722clang_type_t
Greg Clayton960d6a42010-08-03 00:35:52 +0000723ClangASTContext::GetBuiltInType_objc_selector()
724{
Sean Callananc4217a62010-12-06 23:53:20 +0000725 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Clayton960d6a42010-08-03 00:35:52 +0000726}
727
Greg Clayton462d4142010-09-29 01:12:09 +0000728clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000729ClangASTContext::GetCStringType (bool is_const)
730{
731 QualType char_type(getASTContext()->CharTy);
732
733 if (is_const)
734 char_type.addConst();
735
736 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
737}
738
Greg Clayton462d4142010-09-29 01:12:09 +0000739clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +0000740ClangASTContext::GetVoidPtrType (bool is_const)
741{
742 return GetVoidPtrType(getASTContext(), is_const);
743}
744
Greg Clayton462d4142010-09-29 01:12:09 +0000745clang_type_t
746ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const)
Chris Lattner24943d22010-06-08 16:52:24 +0000747{
748 QualType void_ptr_type(ast_context->VoidPtrTy);
749
750 if (is_const)
751 void_ptr_type.addConst();
752
753 return void_ptr_type.getAsOpaquePtr();
754}
755
Greg Clayton462d4142010-09-29 01:12:09 +0000756clang_type_t
Greg Clayton22defe82010-12-02 23:20:03 +0000757ClangASTContext::CopyType (ASTContext *dst_ast,
758 ASTContext *src_ast,
Greg Clayton462d4142010-09-29 01:12:09 +0000759 clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000760{
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000761 FileSystemOptions file_system_options;
Greg Clayton22defe82010-12-02 23:20:03 +0000762 FileManager file_manager (file_system_options);
763 ASTImporter importer(*dst_ast, file_manager,
764 *src_ast, file_manager);
Sean Callanancf18faa2010-11-09 22:37:10 +0000765
Greg Clayton22defe82010-12-02 23:20:03 +0000766 QualType src (QualType::getFromOpaquePtr(clang_type));
767 QualType dst (importer.Import(src));
Sean Callanancf18faa2010-11-09 22:37:10 +0000768
769 return dst.getAsOpaquePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000770}
771
Greg Clayton6916e352010-11-13 03:52:47 +0000772
773clang::Decl *
Greg Clayton22defe82010-12-02 23:20:03 +0000774ClangASTContext::CopyDecl (ASTContext *dst_ast,
775 ASTContext *src_ast,
Greg Clayton6916e352010-11-13 03:52:47 +0000776 clang::Decl *source_decl)
Sean Callanan887d2512010-12-11 00:08:56 +0000777{
Sean Callanan8a3b0a82010-11-18 02:56:27 +0000778 FileSystemOptions file_system_options;
Greg Clayton22defe82010-12-02 23:20:03 +0000779 FileManager file_manager (file_system_options);
780 ASTImporter importer(*dst_ast, file_manager,
781 *src_ast, file_manager);
Greg Clayton6916e352010-11-13 03:52:47 +0000782
783 return importer.Import(source_decl);
784}
785
Sean Callanan8d825062010-07-16 00:00:27 +0000786bool
Greg Clayton462d4142010-09-29 01:12:09 +0000787ClangASTContext::AreTypesSame(ASTContext *ast_context,
788 clang_type_t type1,
789 clang_type_t type2)
Sean Callanan5510ddd2010-07-15 22:30:52 +0000790{
791 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1),
792 QualType::getFromOpaquePtr(type2));
793}
794
Chris Lattner24943d22010-06-08 16:52:24 +0000795#pragma mark CVR modifiers
796
Greg Clayton462d4142010-09-29 01:12:09 +0000797clang_type_t
798ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000799{
800 if (clang_type)
801 {
802 QualType result(QualType::getFromOpaquePtr(clang_type));
803 result.addConst();
804 return result.getAsOpaquePtr();
805 }
806 return NULL;
807}
808
Greg Clayton462d4142010-09-29 01:12:09 +0000809clang_type_t
810ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000811{
812 if (clang_type)
813 {
814 QualType result(QualType::getFromOpaquePtr(clang_type));
815 result.getQualifiers().setRestrict (true);
816 return result.getAsOpaquePtr();
817 }
818 return NULL;
819}
820
Greg Clayton462d4142010-09-29 01:12:09 +0000821clang_type_t
822ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000823{
824 if (clang_type)
825 {
826 QualType result(QualType::getFromOpaquePtr(clang_type));
827 result.getQualifiers().setVolatile (true);
828 return result.getAsOpaquePtr();
829 }
830 return NULL;
831}
832
833#pragma mark Structure, Unions, Classes
834
Greg Clayton462d4142010-09-29 01:12:09 +0000835clang_type_t
Greg Clayton585660c2010-08-05 01:57:25 +0000836ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner24943d22010-06-08 16:52:24 +0000837{
838 ASTContext *ast_context = getASTContext();
839 assert (ast_context != NULL);
Sean Callanan04325062010-10-25 00:29:48 +0000840
Chris Lattner24943d22010-06-08 16:52:24 +0000841 if (decl_ctx == NULL)
842 decl_ctx = ast_context->getTranslationUnitDecl();
843
Greg Clayton9488b742010-07-28 02:04:09 +0000844
Greg Clayton585660c2010-08-05 01:57:25 +0000845 if (language == eLanguageTypeObjC)
Greg Clayton9488b742010-07-28 02:04:09 +0000846 {
Greg Clayton306edca2010-10-11 02:25:34 +0000847 bool isForwardDecl = true;
Greg Clayton9488b742010-07-28 02:04:09 +0000848 bool isInternal = false;
849 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
850 }
851
Chris Lattner24943d22010-06-08 16:52:24 +0000852 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
853 // we will need to update this code. I was told to currently always use
854 // the CXXRecordDecl class since we often don't know from debug information
855 // if something is struct or a class, so we default to always use the more
856 // complete definition just in case.
857 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context,
858 (TagDecl::TagKind)kind,
859 decl_ctx,
860 SourceLocation(),
861 name && name[0] ? &ast_context->Idents.get(name) : NULL);
862
863 return ast_context->getTagDeclType(decl).getAsOpaquePtr();
864}
865
Greg Claytondbf26152010-10-01 23:13:49 +0000866static bool
867IsOperator (const char *name, OverloadedOperatorKind &op_kind)
868{
869 if (name == NULL || name[0] == '\0')
870 return false;
871
Sean Callanan494735d2010-12-10 19:51:54 +0000872#define OPERATOR_PREFIX "operator"
Sean Callananc2c9a142010-12-10 02:15:55 +0000873
874 const char *post_op_name = NULL;
875
Sean Callanan494735d2010-12-10 19:51:54 +0000876 bool no_space = true;
Sean Callananc2c9a142010-12-10 02:15:55 +0000877
Sean Callanan494735d2010-12-10 19:51:54 +0000878 if (!::strncmp(name, OPERATOR_PREFIX, sizeof(OPERATOR_PREFIX) - 1))
879 post_op_name = name + sizeof(OPERATOR_PREFIX) - 1;
880 else
Greg Claytondbf26152010-10-01 23:13:49 +0000881 return false;
882
Sean Callanan494735d2010-12-10 19:51:54 +0000883 if (post_op_name[0] == ' ')
884 {
885 post_op_name++;
886 no_space = false;
887 }
888
889#undef OPERATOR_PREFIX
890
Greg Claytondbf26152010-10-01 23:13:49 +0000891 // This is an operator, set the overloaded operator kind to invalid
892 // in case this is a conversion operator...
893 op_kind = NUM_OVERLOADED_OPERATORS;
894
895 switch (post_op_name[0])
896 {
Sean Callananc2c9a142010-12-10 02:15:55 +0000897 default:
898 if (no_space)
899 return false;
900 break;
Greg Claytondbf26152010-10-01 23:13:49 +0000901 case 'n':
Sean Callananc2c9a142010-12-10 02:15:55 +0000902 if (no_space)
903 return false;
Greg Claytondbf26152010-10-01 23:13:49 +0000904 if (strcmp (post_op_name, "new") == 0)
905 op_kind = OO_New;
906 else if (strcmp (post_op_name, "new[]") == 0)
907 op_kind = OO_Array_New;
908 break;
909
910 case 'd':
Sean Callananc2c9a142010-12-10 02:15:55 +0000911 if (no_space)
912 return false;
Greg Claytondbf26152010-10-01 23:13:49 +0000913 if (strcmp (post_op_name, "delete") == 0)
914 op_kind = OO_Delete;
915 else if (strcmp (post_op_name, "delete[]") == 0)
916 op_kind = OO_Array_Delete;
917 break;
918
919 case '+':
920 if (post_op_name[1] == '\0')
921 op_kind = OO_Plus;
922 else if (post_op_name[2] == '\0')
923 {
924 if (post_op_name[1] == '=')
925 op_kind = OO_PlusEqual;
926 else if (post_op_name[1] == '+')
927 op_kind = OO_PlusPlus;
928 }
929 break;
930
931 case '-':
932 if (post_op_name[1] == '\0')
933 op_kind = OO_Minus;
934 else if (post_op_name[2] == '\0')
935 {
936 switch (post_op_name[1])
937 {
938 case '=': op_kind = OO_MinusEqual; break;
939 case '-': op_kind = OO_MinusMinus; break;
940 case '>': op_kind = OO_Arrow; break;
941 }
942 }
943 else if (post_op_name[3] == '\0')
944 {
945 if (post_op_name[2] == '*')
946 op_kind = OO_ArrowStar; break;
947 }
948 break;
949
950 case '*':
951 if (post_op_name[1] == '\0')
952 op_kind = OO_Star;
953 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
954 op_kind = OO_StarEqual;
955 break;
956
957 case '/':
958 if (post_op_name[1] == '\0')
959 op_kind = OO_Slash;
960 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
961 op_kind = OO_SlashEqual;
962 break;
963
964 case '%':
965 if (post_op_name[1] == '\0')
966 op_kind = OO_Percent;
967 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
968 op_kind = OO_PercentEqual;
969 break;
970
971
972 case '^':
973 if (post_op_name[1] == '\0')
974 op_kind = OO_Caret;
975 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
976 op_kind = OO_CaretEqual;
977 break;
978
979 case '&':
980 if (post_op_name[1] == '\0')
981 op_kind = OO_Amp;
982 else if (post_op_name[2] == '\0')
983 {
984 switch (post_op_name[1])
985 {
986 case '=': op_kind = OO_AmpEqual; break;
987 case '&': op_kind = OO_AmpAmp; break;
988 }
989 }
990 break;
991
992 case '|':
993 if (post_op_name[1] == '\0')
994 op_kind = OO_Pipe;
995 else if (post_op_name[2] == '\0')
996 {
997 switch (post_op_name[1])
998 {
999 case '=': op_kind = OO_PipeEqual; break;
1000 case '|': op_kind = OO_PipePipe; break;
1001 }
1002 }
1003 break;
1004
1005 case '~':
1006 if (post_op_name[1] == '\0')
1007 op_kind = OO_Tilde;
1008 break;
1009
1010 case '!':
1011 if (post_op_name[1] == '\0')
1012 op_kind = OO_Exclaim;
1013 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1014 op_kind = OO_ExclaimEqual;
1015 break;
1016
1017 case '=':
1018 if (post_op_name[1] == '\0')
1019 op_kind = OO_Equal;
1020 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1021 op_kind = OO_EqualEqual;
1022 break;
1023
1024 case '<':
1025 if (post_op_name[1] == '\0')
1026 op_kind = OO_Less;
1027 else if (post_op_name[2] == '\0')
1028 {
1029 switch (post_op_name[1])
1030 {
1031 case '<': op_kind = OO_LessLess; break;
1032 case '=': op_kind = OO_LessEqual; break;
1033 }
1034 }
1035 else if (post_op_name[3] == '\0')
1036 {
1037 if (post_op_name[2] == '=')
1038 op_kind = OO_LessLessEqual;
1039 }
1040 break;
1041
1042 case '>':
1043 if (post_op_name[1] == '\0')
1044 op_kind = OO_Greater;
1045 else if (post_op_name[2] == '\0')
1046 {
1047 switch (post_op_name[1])
1048 {
1049 case '>': op_kind = OO_GreaterGreater; break;
1050 case '=': op_kind = OO_GreaterEqual; break;
1051 }
1052 }
1053 else if (post_op_name[1] == '>' &&
1054 post_op_name[2] == '=' &&
1055 post_op_name[3] == '\0')
1056 {
1057 op_kind = OO_GreaterGreaterEqual;
1058 }
1059 break;
1060
1061 case ',':
1062 if (post_op_name[1] == '\0')
1063 op_kind = OO_Comma;
1064 break;
1065
1066 case '(':
1067 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1068 op_kind = OO_Call;
1069 break;
1070
1071 case '[':
1072 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1073 op_kind = OO_Subscript;
1074 break;
1075 }
1076
1077 return true;
1078}
Greg Clayton412440a2010-09-23 01:09:21 +00001079CXXMethodDecl *
Sean Callanan79523002010-09-17 02:58:26 +00001080ClangASTContext::AddMethodToCXXRecordType
1081(
Greg Clayton462d4142010-09-29 01:12:09 +00001082 ASTContext *ast_context,
1083 clang_type_t record_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001084 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001085 clang_type_t method_opaque_type,
Greg Clayton412440a2010-09-23 01:09:21 +00001086 lldb::AccessType access,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001087 bool is_virtual,
1088 bool is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001089 bool is_inline,
1090 bool is_explicit
Greg Clayton412440a2010-09-23 01:09:21 +00001091)
Sean Callanan79523002010-09-17 02:58:26 +00001092{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001093 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chen974fddb2010-09-28 16:10:54 +00001094 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001095
1096 assert(ast_context);
1097
1098 IdentifierTable *identifier_table = &ast_context->Idents;
1099
1100 assert(identifier_table);
1101
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001102 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton1d8173f2010-09-24 05:15:53 +00001103
1104 clang::Type *clang_type(record_qual_type.getTypePtr());
Sean Callanan79523002010-09-17 02:58:26 +00001105
Greg Clayton1d8173f2010-09-24 05:15:53 +00001106 if (clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001107 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001108
Greg Clayton1d8173f2010-09-24 05:15:53 +00001109 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
Sean Callanan79523002010-09-17 02:58:26 +00001110
Greg Clayton1d8173f2010-09-24 05:15:53 +00001111 if (record_clang_type == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001112 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001113
Greg Clayton1d8173f2010-09-24 05:15:53 +00001114 RecordDecl *record_decl = record_clang_type->getDecl();
Sean Callanan79523002010-09-17 02:58:26 +00001115
Greg Clayton1d8173f2010-09-24 05:15:53 +00001116 if (record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001117 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001118
1119 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1120
Greg Clayton1d8173f2010-09-24 05:15:53 +00001121 if (cxx_record_decl == NULL)
Greg Clayton412440a2010-09-23 01:09:21 +00001122 return NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001123
Greg Clayton1d8173f2010-09-24 05:15:53 +00001124 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001125
Greg Clayton30449d52010-10-01 02:31:07 +00001126 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan79523002010-09-17 02:58:26 +00001127
Greg Clayton30449d52010-10-01 02:31:07 +00001128 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton90e325d2010-10-01 03:45:20 +00001129
Greg Clayton90e325d2010-10-01 03:45:20 +00001130 const bool is_implicitly_declared = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001131
Greg Clayton5325a362010-10-02 01:40:05 +00001132 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton90e325d2010-10-01 03:45:20 +00001133
Greg Clayton5325a362010-10-02 01:40:05 +00001134 if (function_Type == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001135 return NULL;
1136
Greg Clayton5325a362010-10-02 01:40:05 +00001137 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton90e325d2010-10-01 03:45:20 +00001138
1139 if (!method_function_prototype)
1140 return NULL;
1141
1142 unsigned int num_params = method_function_prototype->getNumArgs();
1143
1144 if (name[0] == '~')
Greg Clayton30449d52010-10-01 02:31:07 +00001145 {
Greg Clayton90e325d2010-10-01 03:45:20 +00001146 cxx_method_decl = CXXDestructorDecl::Create (*ast_context,
1147 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001148 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001149 method_qual_type,
Sean Callanan8950c9a2010-10-29 18:38:40 +00001150 NULL,
Greg Clayton90e325d2010-10-01 03:45:20 +00001151 is_inline,
1152 is_implicitly_declared);
1153 }
1154 else if (decl_name == record_decl->getDeclName())
1155 {
Greg Clayton30449d52010-10-01 02:31:07 +00001156 cxx_method_decl = CXXConstructorDecl::Create (*ast_context,
1157 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001158 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton30449d52010-10-01 02:31:07 +00001159 method_qual_type,
1160 NULL, // TypeSourceInfo *
1161 is_explicit,
1162 is_inline,
1163 is_implicitly_declared);
1164 }
1165 else
Greg Clayton90e325d2010-10-01 03:45:20 +00001166 {
Greg Claytondbf26152010-10-01 23:13:49 +00001167
1168 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1169 if (IsOperator (name, op_kind))
Greg Clayton90e325d2010-10-01 03:45:20 +00001170 {
Greg Claytondbf26152010-10-01 23:13:49 +00001171 if (op_kind != NUM_OVERLOADED_OPERATORS)
1172 {
1173 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
Greg Clayton90e325d2010-10-01 03:45:20 +00001174 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001175 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001176 method_qual_type,
1177 NULL, // TypeSourceInfo *
Greg Claytondbf26152010-10-01 23:13:49 +00001178 is_static,
1179 SC_None,
1180 is_inline);
1181 }
1182 else if (num_params == 0)
1183 {
1184 // Conversion operators don't take params...
1185 cxx_method_decl = CXXConversionDecl::Create (*ast_context,
1186 cxx_record_decl,
Greg Clayton5325a362010-10-02 01:40:05 +00001187 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytondbf26152010-10-01 23:13:49 +00001188 method_qual_type,
1189 NULL, // TypeSourceInfo *
1190 is_inline,
1191 is_explicit);
1192 }
Greg Clayton90e325d2010-10-01 03:45:20 +00001193 }
Greg Claytondbf26152010-10-01 23:13:49 +00001194
1195 if (cxx_method_decl == NULL)
Greg Clayton90e325d2010-10-01 03:45:20 +00001196 {
1197 cxx_method_decl = CXXMethodDecl::Create (*ast_context,
1198 cxx_record_decl,
Greg Claytondbf26152010-10-01 23:13:49 +00001199 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton90e325d2010-10-01 03:45:20 +00001200 method_qual_type,
1201 NULL, // TypeSourceInfo *
1202 is_static,
1203 SC_None,
1204 is_inline);
1205 }
Greg Clayton30449d52010-10-01 02:31:07 +00001206 }
Greg Claytondbf26152010-10-01 23:13:49 +00001207
Greg Clayton462d4142010-09-29 01:12:09 +00001208 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton1d8173f2010-09-24 05:15:53 +00001209
1210 cxx_method_decl->setAccess (access_specifier);
1211 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001212
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001213 // Populate the method decl with parameter decls
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001214
1215 ParmVarDecl *params[num_params];
1216
1217 for (int param_index = 0;
1218 param_index < num_params;
1219 ++param_index)
1220 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001221 params[param_index] = ParmVarDecl::Create (*ast_context,
1222 cxx_method_decl,
1223 SourceLocation(),
1224 NULL, // anonymous
1225 method_function_prototype->getArgType(param_index),
1226 NULL,
1227 SC_None,
1228 SC_None,
1229 NULL);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001230 }
1231
Greg Clayton1d8173f2010-09-24 05:15:53 +00001232 cxx_method_decl->setParams (params, num_params);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001233
Greg Clayton1d8173f2010-09-24 05:15:53 +00001234 cxx_record_decl->addDecl (cxx_method_decl);
Sean Callanan79523002010-09-17 02:58:26 +00001235
Greg Clayton412440a2010-09-23 01:09:21 +00001236 return cxx_method_decl;
Sean Callanan79523002010-09-17 02:58:26 +00001237}
1238
1239bool
Greg Clayton84f80752010-07-22 18:30:50 +00001240ClangASTContext::AddFieldToRecordType
1241(
Greg Clayton462d4142010-09-29 01:12:09 +00001242 ASTContext *ast_context,
1243 clang_type_t record_clang_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001244 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001245 clang_type_t field_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001246 AccessType access,
1247 uint32_t bitfield_bit_size
1248)
Chris Lattner24943d22010-06-08 16:52:24 +00001249{
1250 if (record_clang_type == NULL || field_type == NULL)
1251 return false;
1252
Sean Callanan60a0ced2010-09-16 20:01:08 +00001253 IdentifierTable *identifier_table = &ast_context->Idents;
Chris Lattner24943d22010-06-08 16:52:24 +00001254
1255 assert (ast_context != NULL);
1256 assert (identifier_table != NULL);
1257
1258 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1259
Greg Clayton1674b122010-07-21 22:12:05 +00001260 clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001261 if (clang_type)
1262 {
1263 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1264
1265 if (record_type)
1266 {
1267 RecordDecl *record_decl = record_type->getDecl();
1268
Chris Lattner24943d22010-06-08 16:52:24 +00001269 clang::Expr *bit_width = NULL;
1270 if (bitfield_bit_size != 0)
1271 {
1272 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001273 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Chris Lattner24943d22010-06-08 16:52:24 +00001274 }
Greg Clayton84f80752010-07-22 18:30:50 +00001275 FieldDecl *field = FieldDecl::Create (*ast_context,
1276 record_decl,
1277 SourceLocation(),
1278 name ? &identifier_table->get(name) : NULL, // Identifier
1279 QualType::getFromOpaquePtr(field_type), // Field type
1280 NULL, // DeclaratorInfo *
1281 bit_width, // BitWidth
1282 false); // Mutable
Chris Lattner24943d22010-06-08 16:52:24 +00001283
Greg Clayton84f80752010-07-22 18:30:50 +00001284 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner24943d22010-06-08 16:52:24 +00001285
1286 if (field)
1287 {
1288 record_decl->addDecl(field);
Chris Lattner24943d22010-06-08 16:52:24 +00001289 }
1290 }
Greg Clayton9488b742010-07-28 02:04:09 +00001291 else
1292 {
1293 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
1294 if (objc_class_type)
1295 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00001296 bool is_synthesized = false;
Sean Callanan60a0ced2010-09-16 20:01:08 +00001297 ClangASTContext::AddObjCClassIVar (ast_context,
1298 record_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001299 name,
1300 field_type,
1301 access,
1302 bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001303 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001304 }
1305 }
Chris Lattner24943d22010-06-08 16:52:24 +00001306 }
1307 return false;
1308}
1309
1310bool
1311ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1312{
1313 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1314}
1315
1316bool
1317ClangASTContext::FieldIsBitfield
1318(
1319 ASTContext *ast_context,
1320 FieldDecl* field,
1321 uint32_t& bitfield_bit_size
1322)
1323{
1324 if (ast_context == NULL || field == NULL)
1325 return false;
1326
1327 if (field->isBitField())
1328 {
1329 Expr* bit_width_expr = field->getBitWidth();
1330 if (bit_width_expr)
1331 {
1332 llvm::APSInt bit_width_apsint;
1333 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context))
1334 {
1335 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1336 return true;
1337 }
1338 }
1339 }
1340 return false;
1341}
1342
1343bool
1344ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1345{
1346 if (record_decl == NULL)
1347 return false;
1348
1349 if (!record_decl->field_empty())
1350 return true;
1351
1352 // No fields, lets check this is a CXX record and check the base classes
1353 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1354 if (cxx_record_decl)
1355 {
1356 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1357 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1358 base_class != base_class_end;
1359 ++base_class)
1360 {
1361 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1362 if (RecordHasFields(base_class_decl))
1363 return true;
1364 }
1365 }
1366 return false;
1367}
1368
1369void
Greg Clayton462d4142010-09-29 01:12:09 +00001370ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner24943d22010-06-08 16:52:24 +00001371{
1372 if (clang_qual_type)
1373 {
1374 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton1674b122010-07-21 22:12:05 +00001375 clang::Type *clang_type = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001376 if (clang_type)
1377 {
1378 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1379 if (record_type)
1380 {
1381 RecordDecl *record_decl = record_type->getDecl();
1382 if (record_decl)
1383 {
1384 uint32_t field_idx;
1385 RecordDecl::field_iterator field, field_end;
1386 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1387 field != field_end;
1388 ++field, ++field_idx)
1389 {
1390 // If no accessibility was assigned, assign the correct one
1391 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1392 field->setAccess ((AccessSpecifier)default_accessibility);
1393 }
1394 }
1395 }
1396 }
1397 }
1398}
1399
1400#pragma mark C++ Base Classes
1401
1402CXXBaseSpecifier *
Greg Clayton462d4142010-09-29 01:12:09 +00001403ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001404{
1405 if (base_class_type)
Greg Clayton6e713402010-07-30 20:30:44 +00001406 return new CXXBaseSpecifier (SourceRange(),
1407 is_virtual,
1408 base_of_class,
1409 ConvertAccessTypeToAccessSpecifier (access),
1410 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)));
Chris Lattner24943d22010-06-08 16:52:24 +00001411 return NULL;
1412}
1413
Greg Claytone9d0df42010-07-02 01:29:13 +00001414void
1415ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1416{
1417 for (unsigned i=0; i<num_base_classes; ++i)
1418 {
1419 delete base_classes[i];
1420 base_classes[i] = NULL;
1421 }
1422}
1423
Chris Lattner24943d22010-06-08 16:52:24 +00001424bool
Greg Clayton462d4142010-09-29 01:12:09 +00001425ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001426{
1427 if (class_clang_type)
1428 {
Greg Clayton1674b122010-07-21 22:12:05 +00001429 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001430 if (clang_type)
1431 {
1432 RecordType *record_type = dyn_cast<RecordType>(clang_type);
1433 if (record_type)
1434 {
1435 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl());
1436 if (cxx_record_decl)
1437 {
Chris Lattner24943d22010-06-08 16:52:24 +00001438 cxx_record_decl->setBases(base_classes, num_base_classes);
1439 return true;
1440 }
1441 }
1442 }
1443 }
1444 return false;
1445}
Greg Clayton84f80752010-07-22 18:30:50 +00001446#pragma mark Objective C Classes
Chris Lattner24943d22010-06-08 16:52:24 +00001447
Greg Clayton462d4142010-09-29 01:12:09 +00001448clang_type_t
Greg Clayton84f80752010-07-22 18:30:50 +00001449ClangASTContext::CreateObjCClass
1450(
1451 const char *name,
1452 DeclContext *decl_ctx,
1453 bool isForwardDecl,
1454 bool isInternal
1455)
1456{
1457 ASTContext *ast_context = getASTContext();
1458 assert (ast_context != NULL);
1459 assert (name && name[0]);
1460 if (decl_ctx == NULL)
1461 decl_ctx = ast_context->getTranslationUnitDecl();
1462
1463 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1464 // we will need to update this code. I was told to currently always use
1465 // the CXXRecordDecl class since we often don't know from debug information
1466 // if something is struct or a class, so we default to always use the more
1467 // complete definition just in case.
1468 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context,
1469 decl_ctx,
1470 SourceLocation(),
1471 &ast_context->Idents.get(name),
1472 SourceLocation(),
1473 isForwardDecl,
1474 isInternal);
Greg Clayton9488b742010-07-28 02:04:09 +00001475
1476 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton84f80752010-07-22 18:30:50 +00001477}
1478
1479bool
Greg Clayton462d4142010-09-29 01:12:09 +00001480ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton84f80752010-07-22 18:30:50 +00001481{
1482 if (class_opaque_type && super_opaque_type)
1483 {
1484 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1485 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
1486 clang::Type *class_type = class_qual_type.getTypePtr();
1487 clang::Type *super_type = super_qual_type.getTypePtr();
1488 if (class_type && super_type)
1489 {
1490 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1491 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
1492 if (objc_class_type && objc_super_type)
1493 {
1494 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1495 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1496 if (class_interface_decl && super_interface_decl)
1497 {
1498 class_interface_decl->setSuperClass(super_interface_decl);
1499 return true;
1500 }
1501 }
1502 }
1503 }
1504 return false;
1505}
1506
1507
1508bool
1509ClangASTContext::AddObjCClassIVar
1510(
Greg Clayton462d4142010-09-29 01:12:09 +00001511 ASTContext *ast_context,
1512 clang_type_t class_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001513 const char *name,
Greg Clayton462d4142010-09-29 01:12:09 +00001514 clang_type_t ivar_opaque_type,
Greg Clayton84f80752010-07-22 18:30:50 +00001515 AccessType access,
1516 uint32_t bitfield_bit_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001517 bool is_synthesized
Greg Clayton84f80752010-07-22 18:30:50 +00001518)
1519{
1520 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1521 return false;
1522
Sean Callanan60a0ced2010-09-16 20:01:08 +00001523 IdentifierTable *identifier_table = &ast_context->Idents;
Greg Clayton84f80752010-07-22 18:30:50 +00001524
1525 assert (ast_context != NULL);
1526 assert (identifier_table != NULL);
1527
1528 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1529
1530 clang::Type *class_type = class_qual_type.getTypePtr();
1531 if (class_type)
1532 {
1533 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1534
1535 if (objc_class_type)
1536 {
1537 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1538
1539 if (class_interface_decl)
1540 {
1541 clang::Expr *bit_width = NULL;
1542 if (bitfield_bit_size != 0)
1543 {
1544 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size);
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001545 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
Greg Clayton84f80752010-07-22 18:30:50 +00001546 }
1547
Greg Clayton9488b742010-07-28 02:04:09 +00001548 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
1549 class_interface_decl,
1550 SourceLocation(),
1551 &identifier_table->get(name), // Identifier
1552 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1553 NULL, // TypeSourceInfo *
1554 ConvertAccessTypeToObjCIvarAccessControl (access),
1555 bit_width,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001556 is_synthesized);
Greg Clayton9488b742010-07-28 02:04:09 +00001557
1558 if (field)
1559 {
1560 class_interface_decl->addDecl(field);
1561 return true;
1562 }
Greg Clayton84f80752010-07-22 18:30:50 +00001563 }
1564 }
1565 }
1566 return false;
1567}
Chris Lattner24943d22010-06-08 16:52:24 +00001568
Greg Clayton9488b742010-07-28 02:04:09 +00001569
1570bool
Greg Clayton462d4142010-09-29 01:12:09 +00001571ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9488b742010-07-28 02:04:09 +00001572{
1573 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1574
1575 clang::Type *class_type = class_qual_type.getTypePtr();
1576 if (class_type)
1577 {
1578 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1579
1580 if (objc_class_type)
1581 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1582 }
1583 return false;
1584}
1585
1586bool
1587ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1588{
1589 while (class_interface_decl)
1590 {
1591 if (class_interface_decl->ivar_size() > 0)
1592 return true;
1593
1594 if (check_superclass)
1595 class_interface_decl = class_interface_decl->getSuperClass();
1596 else
1597 break;
1598 }
1599 return false;
1600}
Greg Clayton1d8173f2010-09-24 05:15:53 +00001601
Greg Clayton462d4142010-09-29 01:12:09 +00001602ObjCMethodDecl *
Greg Clayton1d8173f2010-09-24 05:15:53 +00001603ClangASTContext::AddMethodToObjCObjectType
1604(
Greg Clayton462d4142010-09-29 01:12:09 +00001605 ASTContext *ast_context,
1606 clang_type_t class_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001607 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton462d4142010-09-29 01:12:09 +00001608 clang_type_t method_opaque_type,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001609 lldb::AccessType access
1610)
1611{
1612 if (class_opaque_type == NULL || method_opaque_type == NULL)
1613 return NULL;
1614
1615 IdentifierTable *identifier_table = &ast_context->Idents;
1616
1617 assert (ast_context != NULL);
1618 assert (identifier_table != NULL);
1619
1620 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1621
1622 clang::Type *class_type = class_qual_type.getTypePtr();
1623 if (class_type == NULL)
1624 return NULL;
1625
1626 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1627
1628 if (objc_class_type == NULL)
1629 return NULL;
1630
1631 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1632
1633 if (class_interface_decl == NULL)
1634 return NULL;
Greg Clayton9488b742010-07-28 02:04:09 +00001635
Greg Clayton1d8173f2010-09-24 05:15:53 +00001636 const char *selector_start = ::strchr (name, ' ');
1637 if (selector_start == NULL)
1638 return NULL;
1639
1640 selector_start++;
1641 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1642 return NULL;
1643 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1644
Greg Claytonad60bf42010-10-12 02:24:53 +00001645 size_t len = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001646 const char *start;
Greg Claytonad60bf42010-10-12 02:24:53 +00001647 //printf ("name = '%s'\n", name);
1648
1649 unsigned num_selectors_with_args = 0;
1650 for (start = selector_start;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001651 start && *start != '\0' && *start != ']';
Greg Claytonad60bf42010-10-12 02:24:53 +00001652 start += len)
Greg Clayton1d8173f2010-09-24 05:15:53 +00001653 {
Greg Claytonad60bf42010-10-12 02:24:53 +00001654 len = ::strcspn(start, ":]");
Greg Clayton6bc44a42010-10-27 04:01:14 +00001655 bool has_arg = (start[len] == ':');
1656 if (has_arg)
Greg Claytonad60bf42010-10-12 02:24:53 +00001657 ++num_selectors_with_args;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001658 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton6bc44a42010-10-27 04:01:14 +00001659 if (has_arg)
1660 len += 1;
Greg Clayton1d8173f2010-09-24 05:15:53 +00001661 }
1662
1663
1664 if (selector_idents.size() == 0)
1665 return 0;
1666
Greg Claytonad60bf42010-10-12 02:24:53 +00001667 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001668 selector_idents.data());
1669
1670 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1671
1672 // Populate the method decl with parameter decls
1673 clang::Type *method_type(method_qual_type.getTypePtr());
1674
1675 if (method_type == NULL)
1676 return NULL;
1677
1678 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
1679
1680 if (!method_function_prototype)
1681 return NULL;
1682
1683
1684 bool is_variadic = false;
1685 bool is_synthesized = false;
1686 bool is_defined = false;
1687 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1688
1689 const unsigned num_args = method_function_prototype->getNumArgs();
1690
1691 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
1692 SourceLocation(), // beginLoc,
1693 SourceLocation(), // endLoc,
1694 method_selector,
1695 method_function_prototype->getResultType(),
1696 NULL, // TypeSourceInfo *ResultTInfo,
1697 GetDeclContextForType (class_opaque_type),
1698 name[0] == '-',
1699 is_variadic,
1700 is_synthesized,
1701 is_defined,
1702 imp_control,
1703 num_args);
1704
1705
1706 if (objc_method_decl == NULL)
1707 return NULL;
1708
1709 if (num_args > 0)
1710 {
1711 llvm::SmallVector<ParmVarDecl *, 12> params;
1712
1713 for (int param_index = 0; param_index < num_args; ++param_index)
1714 {
1715 params.push_back (ParmVarDecl::Create (*ast_context,
1716 objc_method_decl,
1717 SourceLocation(),
1718 NULL, // anonymous
1719 method_function_prototype->getArgType(param_index),
1720 NULL,
1721 SC_Auto,
1722 SC_Auto,
1723 NULL));
1724 }
1725
1726 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
1727 }
1728
1729 class_interface_decl->addDecl (objc_method_decl);
1730
1731
1732 return objc_method_decl;
1733}
1734
1735
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001736uint32_t
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001737ClangASTContext::GetTypeInfo
1738(
1739 clang_type_t clang_type,
1740 clang::ASTContext *ast_context,
1741 clang_type_t *pointee_or_element_clang_type
1742)
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001743{
1744 if (clang_type == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001745 return 0;
1746
1747 if (pointee_or_element_clang_type)
1748 *pointee_or_element_clang_type = NULL;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001749
1750 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1751
1752 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1753 switch (type_class)
1754 {
Sean Callanan04325062010-10-25 00:29:48 +00001755 case clang::Type::Builtin:
1756 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1757 {
Sean Callanan04325062010-10-25 00:29:48 +00001758 case clang::BuiltinType::ObjCId:
1759 case clang::BuiltinType::ObjCClass:
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001760 if (ast_context && pointee_or_element_clang_type)
1761 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanan04325062010-10-25 00:29:48 +00001762 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001763
1764 default:
1765 break;
Sean Callanan04325062010-10-25 00:29:48 +00001766 }
1767 return eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001768
1769 case clang::Type::BlockPointer:
1770 if (pointee_or_element_clang_type)
1771 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1772 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1773
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001774 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001775
1776 case clang::Type::ConstantArray:
1777 case clang::Type::DependentSizedArray:
1778 case clang::Type::IncompleteArray:
1779 case clang::Type::VariableArray:
1780 if (pointee_or_element_clang_type)
1781 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
1782 return eTypeHasChildren | eTypeIsArray;
1783
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001784 case clang::Type::DependentName: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001785 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1786 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1787 case clang::Type::Decltype: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001788
1789 case clang::Type::Enum:
1790 if (pointee_or_element_clang_type)
1791 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
1792 return eTypeIsEnumeration | eTypeHasValue;
1793
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001794 case clang::Type::Elaborated: return 0;
1795 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
1796 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1797 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001798 case clang::Type::InjectedClassName: return 0;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001799
1800 case clang::Type::LValueReference:
1801 case clang::Type::RValueReference:
1802 if (pointee_or_element_clang_type)
1803 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
1804 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1805
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001806 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001807
1808 case clang::Type::ObjCObjectPointer:
1809 if (pointee_or_element_clang_type)
1810 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1811 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1812
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001813 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1814 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001815
1816 case clang::Type::Pointer:
1817 if (pointee_or_element_clang_type)
1818 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
1819 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1820
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001821 case clang::Type::Record:
1822 if (qual_type->getAsCXXRecordDecl())
1823 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1824 else
1825 return eTypeHasChildren | eTypeIsStructUnion;
1826 break;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001827 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1828 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1829 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001830
1831 case clang::Type::Typedef:
Sean Callanan9e7958e2010-12-13 01:26:27 +00001832 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001833 ast_context,
1834 pointee_or_element_clang_type);
1835
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001836 case clang::Type::TypeOfExpr: return 0;
1837 case clang::Type::TypeOf: return 0;
1838 case clang::Type::UnresolvedUsing: return 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001839 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
1840 default: return 0;
1841 }
1842 return 0;
1843}
1844
Greg Clayton9488b742010-07-28 02:04:09 +00001845
Chris Lattner24943d22010-06-08 16:52:24 +00001846#pragma mark Aggregate Types
1847
1848bool
Greg Clayton462d4142010-09-29 01:12:09 +00001849ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001850{
1851 if (clang_type == NULL)
1852 return false;
1853
1854 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1855
Greg Clayton03e0f972010-09-13 03:32:57 +00001856 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1857 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001858 {
Greg Clayton1674b122010-07-21 22:12:05 +00001859 case clang::Type::IncompleteArray:
1860 case clang::Type::VariableArray:
1861 case clang::Type::ConstantArray:
1862 case clang::Type::ExtVector:
1863 case clang::Type::Vector:
1864 case clang::Type::Record:
Greg Clayton9488b742010-07-28 02:04:09 +00001865 case clang::Type::ObjCObject:
1866 case clang::Type::ObjCInterface:
Chris Lattner24943d22010-06-08 16:52:24 +00001867 return true;
1868
Greg Clayton1674b122010-07-21 22:12:05 +00001869 case clang::Type::Typedef:
Sean Callanan9e7958e2010-12-13 01:26:27 +00001870 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00001871
1872 default:
1873 break;
1874 }
1875 // The clang type does have a value
1876 return false;
1877}
1878
1879uint32_t
Greg Clayton462d4142010-09-29 01:12:09 +00001880ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes)
Chris Lattner24943d22010-06-08 16:52:24 +00001881{
1882 if (clang_qual_type == NULL)
1883 return 0;
1884
1885 uint32_t num_children = 0;
1886 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
Greg Clayton9488b742010-07-28 02:04:09 +00001887 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1888 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00001889 {
Greg Clayton960d6a42010-08-03 00:35:52 +00001890 case clang::Type::Builtin:
1891 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1892 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001893 case clang::BuiltinType::ObjCId: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001894 case clang::BuiltinType::ObjCClass: // child is Class
Greg Clayton960d6a42010-08-03 00:35:52 +00001895 num_children = 1;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001896 break;
Greg Clayton960d6a42010-08-03 00:35:52 +00001897
1898 default:
1899 break;
1900 }
1901 break;
1902
Greg Clayton1674b122010-07-21 22:12:05 +00001903 case clang::Type::Record:
Greg Clayton53d287b2010-11-11 02:14:53 +00001904 if (ClangASTType::IsDefined (clang_qual_type))
Chris Lattner24943d22010-06-08 16:52:24 +00001905 {
1906 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
1907 const RecordDecl *record_decl = record_type->getDecl();
1908 assert(record_decl);
1909 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1910 if (cxx_record_decl)
1911 {
1912 if (omit_empty_base_classes)
1913 {
1914 // Check each base classes to see if it or any of its
1915 // base classes contain any fields. This can help
1916 // limit the noise in variable views by not having to
1917 // show base classes that contain no members.
1918 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1919 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1920 base_class != base_class_end;
1921 ++base_class)
1922 {
1923 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1924
1925 // Skip empty base classes
1926 if (RecordHasFields(base_class_decl) == false)
1927 continue;
1928
1929 num_children++;
1930 }
1931 }
1932 else
1933 {
1934 // Include all base classes
1935 num_children += cxx_record_decl->getNumBases();
1936 }
1937
1938 }
1939 RecordDecl::field_iterator field, field_end;
1940 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
1941 ++num_children;
1942 }
1943 break;
1944
Greg Clayton9488b742010-07-28 02:04:09 +00001945 case clang::Type::ObjCObject:
1946 case clang::Type::ObjCInterface:
1947 {
1948 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
1949 assert (objc_class_type);
1950 if (objc_class_type)
1951 {
1952 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1953
1954 if (class_interface_decl)
1955 {
1956
1957 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
1958 if (superclass_interface_decl)
1959 {
1960 if (omit_empty_base_classes)
1961 {
1962 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
1963 ++num_children;
1964 }
1965 else
1966 ++num_children;
1967 }
1968
1969 num_children += class_interface_decl->ivar_size();
1970 }
1971 }
1972 }
1973 break;
1974
1975 case clang::Type::ObjCObjectPointer:
Greg Clayton960d6a42010-08-03 00:35:52 +00001976 {
1977 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
1978 QualType pointee_type = pointer_type->getPointeeType();
1979 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1980 omit_empty_base_classes);
1981 // If this type points to a simple type, then it has 1 child
1982 if (num_pointee_children == 0)
1983 num_children = 1;
1984 else
1985 num_children = num_pointee_children;
1986 }
1987 break;
Greg Clayton9488b742010-07-28 02:04:09 +00001988
Greg Clayton1674b122010-07-21 22:12:05 +00001989 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001990 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
1991 break;
1992
Greg Clayton1674b122010-07-21 22:12:05 +00001993 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00001994 {
1995 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
1996 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton9488b742010-07-28 02:04:09 +00001997 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
1998 omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00001999 // 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;
2006
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002007 case clang::Type::LValueReference:
2008 case clang::Type::RValueReference:
2009 {
2010 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2011 QualType pointee_type = reference_type->getPointeeType();
2012 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
2013 omit_empty_base_classes);
2014 // If this type points to a simple type, then it has 1 child
2015 if (num_pointee_children == 0)
2016 num_children = 1;
2017 else
2018 num_children = num_pointee_children;
2019 }
2020 break;
2021
2022
Greg Clayton1674b122010-07-21 22:12:05 +00002023 case clang::Type::Typedef:
Sean Callanan9e7958e2010-12-13 01:26:27 +00002024 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), omit_empty_base_classes);
Chris Lattner24943d22010-06-08 16:52:24 +00002025 break;
2026
2027 default:
2028 break;
2029 }
2030 return num_children;
2031}
2032
2033
Greg Clayton462d4142010-09-29 01:12:09 +00002034clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002035ClangASTContext::GetChildClangTypeAtIndex
2036(
2037 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002038 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002039 uint32_t idx,
2040 bool transparent_pointers,
2041 bool omit_empty_base_classes,
2042 std::string& child_name,
2043 uint32_t &child_byte_size,
2044 int32_t &child_byte_offset,
2045 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002046 uint32_t &child_bitfield_bit_offset,
2047 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002048)
2049{
2050 if (parent_clang_type)
2051
2052 return GetChildClangTypeAtIndex (getASTContext(),
2053 parent_name,
2054 parent_clang_type,
2055 idx,
2056 transparent_pointers,
2057 omit_empty_base_classes,
2058 child_name,
2059 child_byte_size,
2060 child_byte_offset,
2061 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002062 child_bitfield_bit_offset,
2063 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002064 return NULL;
2065}
2066
Greg Clayton462d4142010-09-29 01:12:09 +00002067clang_type_t
Chris Lattner24943d22010-06-08 16:52:24 +00002068ClangASTContext::GetChildClangTypeAtIndex
2069(
2070 ASTContext *ast_context,
2071 const char *parent_name,
Greg Clayton462d4142010-09-29 01:12:09 +00002072 clang_type_t parent_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002073 uint32_t idx,
2074 bool transparent_pointers,
2075 bool omit_empty_base_classes,
2076 std::string& child_name,
2077 uint32_t &child_byte_size,
2078 int32_t &child_byte_offset,
2079 uint32_t &child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002080 uint32_t &child_bitfield_bit_offset,
2081 bool &child_is_base_class
Chris Lattner24943d22010-06-08 16:52:24 +00002082)
2083{
2084 if (parent_clang_type == NULL)
2085 return NULL;
2086
2087 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes))
2088 {
2089 uint32_t bit_offset;
2090 child_bitfield_bit_size = 0;
2091 child_bitfield_bit_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002092 child_is_base_class = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002093 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002094 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2095 switch (parent_type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002096 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002097 case clang::Type::Builtin:
2098 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2099 {
2100 case clang::BuiltinType::ObjCId:
2101 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00002102 child_name = "isa";
2103 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT;
Greg Clayton960d6a42010-08-03 00:35:52 +00002104 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr();
2105
Greg Clayton960d6a42010-08-03 00:35:52 +00002106 default:
2107 break;
2108 }
2109 break;
2110
2111
Greg Clayton1674b122010-07-21 22:12:05 +00002112 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002113 {
2114 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2115 const RecordDecl *record_decl = record_type->getDecl();
2116 assert(record_decl);
2117 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
2118 uint32_t child_idx = 0;
2119
2120 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2121 if (cxx_record_decl)
2122 {
2123 // We might have base classes to print out first
2124 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2125 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2126 base_class != base_class_end;
2127 ++base_class)
2128 {
2129 const CXXRecordDecl *base_class_decl = NULL;
2130
2131 // Skip empty base classes
2132 if (omit_empty_base_classes)
2133 {
2134 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2135 if (RecordHasFields(base_class_decl) == false)
2136 continue;
2137 }
2138
2139 if (idx == child_idx)
2140 {
2141 if (base_class_decl == NULL)
2142 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2143
2144
2145 if (base_class->isVirtual())
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002146 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002147 else
Sean Callanan8a3b0a82010-11-18 02:56:27 +00002148 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
Chris Lattner24943d22010-06-08 16:52:24 +00002149
2150 // Base classes should be a multiple of 8 bits in size
2151 assert (bit_offset % 8 == 0);
2152 child_byte_offset = bit_offset/8;
2153 std::string base_class_type_name(base_class->getType().getAsString());
2154
2155 child_name.assign(base_class_type_name.c_str());
2156
2157 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType());
2158
2159 // Base classes biut sizes should be a multiple of 8 bits in size
2160 assert (clang_type_info_bit_size % 8 == 0);
2161 child_byte_size = clang_type_info_bit_size / 8;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002162 child_is_base_class = true;
Chris Lattner24943d22010-06-08 16:52:24 +00002163 return base_class->getType().getAsOpaquePtr();
2164 }
2165 // We don't increment the child index in the for loop since we might
2166 // be skipping empty base classes
2167 ++child_idx;
2168 }
2169 }
Chris Lattner24943d22010-06-08 16:52:24 +00002170 // Make sure index is in range...
2171 uint32_t field_idx = 0;
2172 RecordDecl::field_iterator field, field_end;
2173 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2174 {
2175 if (idx == child_idx)
2176 {
2177 // Print the member type if requested
2178 // Print the member name and equal sign
2179 child_name.assign(field->getNameAsString().c_str());
2180
2181 // Figure out the type byte size (field_type_info.first) and
2182 // alignment (field_type_info.second) from the AST context.
2183 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType());
Greg Clayton54e7afa2010-07-09 20:39:50 +00002184 assert(field_idx < record_layout.getFieldCount());
Chris Lattner24943d22010-06-08 16:52:24 +00002185
2186 child_byte_size = field_type_info.first / 8;
2187
2188 // Figure out the field offset within the current struct/union/class type
2189 bit_offset = record_layout.getFieldOffset (field_idx);
2190 child_byte_offset = bit_offset / 8;
2191 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size))
2192 child_bitfield_bit_offset = bit_offset % 8;
2193
2194 return field->getType().getAsOpaquePtr();
2195 }
2196 }
2197 }
2198 break;
2199
Greg Clayton9488b742010-07-28 02:04:09 +00002200 case clang::Type::ObjCObject:
2201 case clang::Type::ObjCInterface:
2202 {
2203 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
2204 assert (objc_class_type);
2205 if (objc_class_type)
2206 {
2207 uint32_t child_idx = 0;
2208 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2209
2210 if (class_interface_decl)
2211 {
2212
2213 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
2214 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2215 if (superclass_interface_decl)
2216 {
2217 if (omit_empty_base_classes)
2218 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002219 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9488b742010-07-28 02:04:09 +00002220 {
2221 if (idx == 0)
2222 {
2223 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
2224
2225
2226 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2227
2228 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2229
2230 child_byte_size = ivar_type_info.first / 8;
Greg Clayton960d6a42010-08-03 00:35:52 +00002231 child_byte_offset = 0;
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002232 child_is_base_class = true;
Greg Clayton9488b742010-07-28 02:04:09 +00002233
2234 return ivar_qual_type.getAsOpaquePtr();
2235 }
2236
2237 ++child_idx;
2238 }
2239 }
2240 else
2241 ++child_idx;
2242 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002243
2244 const uint32_t superclass_idx = child_idx;
Greg Clayton9488b742010-07-28 02:04:09 +00002245
2246 if (idx < (child_idx + class_interface_decl->ivar_size()))
2247 {
2248 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2249
2250 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2251 {
2252 if (child_idx == idx)
2253 {
2254 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2255
2256 QualType ivar_qual_type(ivar_decl->getType());
2257
2258 child_name.assign(ivar_decl->getNameAsString().c_str());
2259
2260 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
2261
2262 child_byte_size = ivar_type_info.first / 8;
2263
2264 // Figure out the field offset within the current struct/union/class type
Greg Clayton960d6a42010-08-03 00:35:52 +00002265 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9488b742010-07-28 02:04:09 +00002266 child_byte_offset = bit_offset / 8;
2267
2268 return ivar_qual_type.getAsOpaquePtr();
2269 }
2270 ++child_idx;
2271 }
2272 }
2273 }
2274 }
2275 }
2276 break;
2277
2278 case clang::Type::ObjCObjectPointer:
2279 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002280 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
2281 QualType pointee_type = pointer_type->getPointeeType();
2282
2283 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2284 {
2285 return GetChildClangTypeAtIndex (ast_context,
2286 parent_name,
2287 pointer_type->getPointeeType().getAsOpaquePtr(),
2288 idx,
2289 transparent_pointers,
2290 omit_empty_base_classes,
2291 child_name,
2292 child_byte_size,
2293 child_byte_offset,
2294 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002295 child_bitfield_bit_offset,
2296 child_is_base_class);
Greg Clayton960d6a42010-08-03 00:35:52 +00002297 }
2298 else
2299 {
2300 if (parent_name)
2301 {
2302 child_name.assign(1, '*');
2303 child_name += parent_name;
2304 }
2305
2306 // We have a pointer to an simple type
2307 if (idx == 0)
2308 {
2309 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2310 assert(clang_type_info.first % 8 == 0);
2311 child_byte_size = clang_type_info.first / 8;
2312 child_byte_offset = 0;
2313 return pointee_type.getAsOpaquePtr();
2314 }
2315 }
Greg Clayton9488b742010-07-28 02:04:09 +00002316 }
2317 break;
2318
Greg Clayton1674b122010-07-21 22:12:05 +00002319 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002320 {
2321 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2322 const uint64_t element_count = array->getSize().getLimitedValue();
2323
2324 if (idx < element_count)
2325 {
2326 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2327
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002328 char element_name[64];
2329 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002330
2331 child_name.assign(element_name);
2332 assert(field_type_info.first % 8 == 0);
2333 child_byte_size = field_type_info.first / 8;
2334 child_byte_offset = idx * child_byte_size;
2335 return array->getElementType().getAsOpaquePtr();
2336 }
2337 }
2338 break;
2339
Greg Clayton1674b122010-07-21 22:12:05 +00002340 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002341 {
2342 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
2343 QualType pointee_type = pointer_type->getPointeeType();
2344
2345 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2346 {
2347 return GetChildClangTypeAtIndex (ast_context,
2348 parent_name,
2349 pointer_type->getPointeeType().getAsOpaquePtr(),
2350 idx,
2351 transparent_pointers,
2352 omit_empty_base_classes,
2353 child_name,
2354 child_byte_size,
2355 child_byte_offset,
2356 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002357 child_bitfield_bit_offset,
2358 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002359 }
2360 else
2361 {
2362 if (parent_name)
2363 {
2364 child_name.assign(1, '*');
2365 child_name += parent_name;
2366 }
2367
2368 // We have a pointer to an simple type
2369 if (idx == 0)
2370 {
2371 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2372 assert(clang_type_info.first % 8 == 0);
2373 child_byte_size = clang_type_info.first / 8;
2374 child_byte_offset = 0;
2375 return pointee_type.getAsOpaquePtr();
2376 }
2377 }
2378 }
2379 break;
2380
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00002381 case clang::Type::LValueReference:
2382 case clang::Type::RValueReference:
2383 {
2384 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
2385 QualType pointee_type(reference_type->getPointeeType());
2386 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2387 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2388 {
2389 return GetChildClangTypeAtIndex (ast_context,
2390 parent_name,
2391 pointee_clang_type,
2392 idx,
2393 transparent_pointers,
2394 omit_empty_base_classes,
2395 child_name,
2396 child_byte_size,
2397 child_byte_offset,
2398 child_bitfield_bit_size,
2399 child_bitfield_bit_offset,
2400 child_is_base_class);
2401 }
2402 else
2403 {
2404 if (parent_name)
2405 {
2406 child_name.assign(1, '&');
2407 child_name += parent_name;
2408 }
2409
2410 // We have a pointer to an simple type
2411 if (idx == 0)
2412 {
2413 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2414 assert(clang_type_info.first % 8 == 0);
2415 child_byte_size = clang_type_info.first / 8;
2416 child_byte_offset = 0;
2417 return pointee_type.getAsOpaquePtr();
2418 }
2419 }
2420 }
2421 break;
2422
Greg Clayton1674b122010-07-21 22:12:05 +00002423 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002424 return GetChildClangTypeAtIndex (ast_context,
2425 parent_name,
Sean Callanan9e7958e2010-12-13 01:26:27 +00002426 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner24943d22010-06-08 16:52:24 +00002427 idx,
2428 transparent_pointers,
2429 omit_empty_base_classes,
2430 child_name,
2431 child_byte_size,
2432 child_byte_offset,
2433 child_bitfield_bit_size,
Greg Claytonbf8e42b2010-10-14 22:52:14 +00002434 child_bitfield_bit_offset,
2435 child_is_base_class);
Chris Lattner24943d22010-06-08 16:52:24 +00002436 break;
2437
2438 default:
2439 break;
2440 }
2441 }
Greg Claytonf8e98a62010-07-23 15:37:46 +00002442 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00002443}
2444
2445static inline bool
2446BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2447{
2448 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false;
2449}
2450
2451static uint32_t
2452GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2453{
2454 uint32_t num_bases = 0;
2455 if (cxx_record_decl)
2456 {
2457 if (omit_empty_base_classes)
2458 {
2459 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2460 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2461 base_class != base_class_end;
2462 ++base_class)
2463 {
2464 // Skip empty base classes
2465 if (omit_empty_base_classes)
2466 {
2467 if (BaseSpecifierIsEmpty (base_class))
2468 continue;
2469 }
2470 ++num_bases;
2471 }
2472 }
2473 else
2474 num_bases = cxx_record_decl->getNumBases();
2475 }
2476 return num_bases;
2477}
2478
2479
2480static uint32_t
2481GetIndexForRecordBase
2482(
2483 const RecordDecl *record_decl,
2484 const CXXBaseSpecifier *base_spec,
2485 bool omit_empty_base_classes
2486)
2487{
2488 uint32_t child_idx = 0;
2489
2490 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2491
2492// const char *super_name = record_decl->getNameAsCString();
2493// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2494// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2495//
2496 if (cxx_record_decl)
2497 {
2498 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2499 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2500 base_class != base_class_end;
2501 ++base_class)
2502 {
2503 if (omit_empty_base_classes)
2504 {
2505 if (BaseSpecifierIsEmpty (base_class))
2506 continue;
2507 }
2508
2509// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2510// child_idx,
2511// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2512//
2513//
2514 if (base_class == base_spec)
2515 return child_idx;
2516 ++child_idx;
2517 }
2518 }
2519
2520 return UINT32_MAX;
2521}
2522
2523
2524static uint32_t
2525GetIndexForRecordChild
2526(
2527 const RecordDecl *record_decl,
2528 NamedDecl *canonical_decl,
2529 bool omit_empty_base_classes
2530)
2531{
2532 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2533
2534// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2535//
2536//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2537// if (cxx_record_decl)
2538// {
2539// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2540// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2541// base_class != base_class_end;
2542// ++base_class)
2543// {
2544// if (omit_empty_base_classes)
2545// {
2546// if (BaseSpecifierIsEmpty (base_class))
2547// continue;
2548// }
2549//
2550//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2551//// record_decl->getNameAsCString(),
2552//// canonical_decl->getNameAsCString(),
2553//// child_idx,
2554//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2555//
2556//
2557// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2558// if (curr_base_class_decl == canonical_decl)
2559// {
2560// return child_idx;
2561// }
2562// ++child_idx;
2563// }
2564// }
2565//
2566// const uint32_t num_bases = child_idx;
2567 RecordDecl::field_iterator field, field_end;
2568 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2569 field != field_end;
2570 ++field, ++child_idx)
2571 {
2572// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2573// record_decl->getNameAsCString(),
2574// canonical_decl->getNameAsCString(),
2575// child_idx - num_bases,
2576// field->getNameAsCString());
2577
2578 if (field->getCanonicalDecl() == canonical_decl)
2579 return child_idx;
2580 }
2581
2582 return UINT32_MAX;
2583}
2584
2585// Look for a child member (doesn't include base classes, but it does include
2586// their members) in the type hierarchy. Returns an index path into "clang_type"
2587// on how to reach the appropriate member.
2588//
2589// class A
2590// {
2591// public:
2592// int m_a;
2593// int m_b;
2594// };
2595//
2596// class B
2597// {
2598// };
2599//
2600// class C :
2601// public B,
2602// public A
2603// {
2604// };
2605//
2606// If we have a clang type that describes "class C", and we wanted to looked
2607// "m_b" in it:
2608//
2609// With omit_empty_base_classes == false we would get an integer array back with:
2610// { 1, 1 }
2611// The first index 1 is the child index for "class A" within class C
2612// The second index 1 is the child index for "m_b" within class A
2613//
2614// With omit_empty_base_classes == true we would get an integer array back with:
2615// { 0, 1 }
2616// 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)
2617// The second index 1 is the child index for "m_b" within class A
2618
2619size_t
2620ClangASTContext::GetIndexOfChildMemberWithName
2621(
2622 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002623 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002624 const char *name,
2625 bool omit_empty_base_classes,
2626 std::vector<uint32_t>& child_indexes
2627)
2628{
2629 if (clang_type && name && name[0])
2630 {
2631 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00002632 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2633 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002634 {
Greg Clayton1674b122010-07-21 22:12:05 +00002635 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002636 {
2637 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2638 const RecordDecl *record_decl = record_type->getDecl();
2639
2640 assert(record_decl);
2641 uint32_t child_idx = 0;
2642
2643 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2644
2645 // Try and find a field that matches NAME
2646 RecordDecl::field_iterator field, field_end;
2647 StringRef name_sref(name);
2648 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2649 field != field_end;
2650 ++field, ++child_idx)
2651 {
2652 if (field->getName().equals (name_sref))
2653 {
2654 // We have to add on the number of base classes to this index!
2655 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
2656 return child_indexes.size();
2657 }
2658 }
2659
2660 if (cxx_record_decl)
2661 {
2662 const RecordDecl *parent_record_decl = cxx_record_decl;
2663
2664 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
2665
2666 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
2667 // Didn't find things easily, lets let clang do its thang...
2668 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name));
2669 DeclarationName decl_name(&ident_ref);
2670
2671 CXXBasePaths paths;
2672 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
2673 decl_name.getAsOpaquePtr(),
2674 paths))
2675 {
Chris Lattner24943d22010-06-08 16:52:24 +00002676 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
2677 for (path = paths.begin(); path != path_end; ++path)
2678 {
2679 const size_t num_path_elements = path->size();
2680 for (size_t e=0; e<num_path_elements; ++e)
2681 {
2682 CXXBasePathElement elem = (*path)[e];
2683
2684 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
2685 if (child_idx == UINT32_MAX)
2686 {
2687 child_indexes.clear();
2688 return 0;
2689 }
2690 else
2691 {
2692 child_indexes.push_back (child_idx);
2693 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
2694 }
2695 }
2696 DeclContext::lookup_iterator named_decl_pos;
2697 for (named_decl_pos = path->Decls.first;
2698 named_decl_pos != path->Decls.second && parent_record_decl;
2699 ++named_decl_pos)
2700 {
2701 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
2702
2703 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
2704 if (child_idx == UINT32_MAX)
2705 {
2706 child_indexes.clear();
2707 return 0;
2708 }
2709 else
2710 {
2711 child_indexes.push_back (child_idx);
2712 }
2713 }
2714 }
2715 return child_indexes.size();
2716 }
2717 }
2718
2719 }
2720 break;
2721
Greg Clayton9488b742010-07-28 02:04:09 +00002722 case clang::Type::ObjCObject:
2723 case clang::Type::ObjCInterface:
2724 {
2725 StringRef name_sref(name);
2726 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2727 assert (objc_class_type);
2728 if (objc_class_type)
2729 {
2730 uint32_t child_idx = 0;
2731 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2732
2733 if (class_interface_decl)
2734 {
2735 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2736 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2737
Greg Clayton823533e2010-09-18 02:11:07 +00002738 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9488b742010-07-28 02:04:09 +00002739 {
2740 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2741
2742 if (ivar_decl->getName().equals (name_sref))
2743 {
2744 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2745 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2746 ++child_idx;
2747
2748 child_indexes.push_back (child_idx);
2749 return child_indexes.size();
2750 }
2751 }
2752
2753 if (superclass_interface_decl)
2754 {
2755 // The super class index is always zero for ObjC classes,
2756 // so we push it onto the child indexes in case we find
2757 // an ivar in our superclass...
2758 child_indexes.push_back (0);
2759
2760 if (GetIndexOfChildMemberWithName (ast_context,
2761 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
2762 name,
2763 omit_empty_base_classes,
2764 child_indexes))
2765 {
2766 // We did find an ivar in a superclass so just
2767 // return the results!
2768 return child_indexes.size();
2769 }
2770
2771 // We didn't find an ivar matching "name" in our
2772 // superclass, pop the superclass zero index that
2773 // we pushed on above.
2774 child_indexes.pop_back();
2775 }
2776 }
2777 }
2778 }
2779 break;
2780
2781 case clang::Type::ObjCObjectPointer:
2782 {
2783 return GetIndexOfChildMemberWithName (ast_context,
2784 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
2785 name,
2786 omit_empty_base_classes,
2787 child_indexes);
2788 }
2789 break;
2790
2791
Greg Clayton1674b122010-07-21 22:12:05 +00002792 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00002793 {
2794// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2795// const uint64_t element_count = array->getSize().getLimitedValue();
2796//
2797// if (idx < element_count)
2798// {
2799// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
2800//
2801// char element_name[32];
2802// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
2803//
2804// child_name.assign(element_name);
2805// assert(field_type_info.first % 8 == 0);
2806// child_byte_size = field_type_info.first / 8;
2807// child_byte_offset = idx * child_byte_size;
2808// return array->getElementType().getAsOpaquePtr();
2809// }
2810 }
2811 break;
2812
Greg Clayton1674b122010-07-21 22:12:05 +00002813// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00002814// {
2815// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
2816// QualType pointee_type = mem_ptr_type->getPointeeType();
2817//
2818// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2819// {
2820// return GetIndexOfChildWithName (ast_context,
2821// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
2822// name);
2823// }
2824// }
2825// break;
2826//
Greg Clayton1674b122010-07-21 22:12:05 +00002827 case clang::Type::LValueReference:
2828 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00002829 {
2830 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
2831 QualType pointee_type = reference_type->getPointeeType();
2832
2833 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2834 {
2835 return GetIndexOfChildMemberWithName (ast_context,
2836 reference_type->getPointeeType().getAsOpaquePtr(),
2837 name,
2838 omit_empty_base_classes,
2839 child_indexes);
2840 }
2841 }
2842 break;
2843
Greg Clayton1674b122010-07-21 22:12:05 +00002844 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00002845 {
2846 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
2847 QualType pointee_type = pointer_type->getPointeeType();
2848
2849 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2850 {
2851 return GetIndexOfChildMemberWithName (ast_context,
2852 pointer_type->getPointeeType().getAsOpaquePtr(),
2853 name,
2854 omit_empty_base_classes,
2855 child_indexes);
2856 }
2857 else
2858 {
2859// if (parent_name)
2860// {
2861// child_name.assign(1, '*');
2862// child_name += parent_name;
2863// }
2864//
2865// // We have a pointer to an simple type
2866// if (idx == 0)
2867// {
2868// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
2869// assert(clang_type_info.first % 8 == 0);
2870// child_byte_size = clang_type_info.first / 8;
2871// child_byte_offset = 0;
2872// return pointee_type.getAsOpaquePtr();
2873// }
2874 }
2875 }
2876 break;
2877
Greg Clayton1674b122010-07-21 22:12:05 +00002878 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00002879 return GetIndexOfChildMemberWithName (ast_context,
Sean Callanan9e7958e2010-12-13 01:26:27 +00002880 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner24943d22010-06-08 16:52:24 +00002881 name,
2882 omit_empty_base_classes,
2883 child_indexes);
2884
2885 default:
2886 break;
2887 }
2888 }
2889 return 0;
2890}
2891
2892
2893// Get the index of the child of "clang_type" whose name matches. This function
2894// doesn't descend into the children, but only looks one level deep and name
2895// matches can include base class names.
2896
2897uint32_t
2898ClangASTContext::GetIndexOfChildWithName
2899(
2900 ASTContext *ast_context,
Greg Clayton462d4142010-09-29 01:12:09 +00002901 clang_type_t clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002902 const char *name,
2903 bool omit_empty_base_classes
2904)
2905{
2906 if (clang_type && name && name[0])
2907 {
2908 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9488b742010-07-28 02:04:09 +00002909
Greg Clayton03e0f972010-09-13 03:32:57 +00002910 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9488b742010-07-28 02:04:09 +00002911
Greg Clayton03e0f972010-09-13 03:32:57 +00002912 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00002913 {
Greg Clayton1674b122010-07-21 22:12:05 +00002914 case clang::Type::Record:
Chris Lattner24943d22010-06-08 16:52:24 +00002915 {
2916 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2917 const RecordDecl *record_decl = record_type->getDecl();
2918
2919 assert(record_decl);
2920 uint32_t child_idx = 0;
2921
2922 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2923
2924 if (cxx_record_decl)
2925 {
2926 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2927 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2928 base_class != base_class_end;
2929 ++base_class)
2930 {
2931 // Skip empty base classes
2932 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2933 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
2934 continue;
2935
2936 if (base_class->getType().getAsString().compare (name) == 0)
2937 return child_idx;
2938 ++child_idx;
2939 }
2940 }
2941
2942 // Try and find a field that matches NAME
2943 RecordDecl::field_iterator field, field_end;
2944 StringRef name_sref(name);
2945 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2946 field != field_end;
2947 ++field, ++child_idx)
2948 {
2949 if (field->getName().equals (name_sref))
2950 return child_idx;
2951 }
2952
2953 }
2954 break;
2955
Greg Clayton9488b742010-07-28 02:04:09 +00002956 case clang::Type::ObjCObject:
2957 case clang::Type::ObjCInterface:
2958 {
2959 StringRef name_sref(name);
2960 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
2961 assert (objc_class_type);
2962 if (objc_class_type)
2963 {
2964 uint32_t child_idx = 0;
2965 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2966
2967 if (class_interface_decl)
2968 {
2969 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2970 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2971
2972 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2973 {
2974 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2975
2976 if (ivar_decl->getName().equals (name_sref))
2977 {
2978 if ((!omit_empty_base_classes && superclass_interface_decl) ||
2979 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
2980 ++child_idx;
2981
2982 return child_idx;
2983 }
2984 }
2985
2986 if (superclass_interface_decl)
2987 {
2988 if (superclass_interface_decl->getName().equals (name_sref))
2989 return 0;
2990 }
2991 }
2992 }
2993 }
2994 break;
2995
2996 case clang::Type::ObjCObjectPointer:
2997 {
2998 return GetIndexOfChildWithName (ast_context,
2999 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3000 name,
3001 omit_empty_base_classes);
3002 }
3003 break;
3004
Greg Clayton1674b122010-07-21 22:12:05 +00003005 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003006 {
3007// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3008// const uint64_t element_count = array->getSize().getLimitedValue();
3009//
3010// if (idx < element_count)
3011// {
3012// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType());
3013//
3014// char element_name[32];
3015// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3016//
3017// child_name.assign(element_name);
3018// assert(field_type_info.first % 8 == 0);
3019// child_byte_size = field_type_info.first / 8;
3020// child_byte_offset = idx * child_byte_size;
3021// return array->getElementType().getAsOpaquePtr();
3022// }
3023 }
3024 break;
3025
Greg Clayton1674b122010-07-21 22:12:05 +00003026// case clang::Type::MemberPointerType:
Chris Lattner24943d22010-06-08 16:52:24 +00003027// {
3028// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3029// QualType pointee_type = mem_ptr_type->getPointeeType();
3030//
3031// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3032// {
3033// return GetIndexOfChildWithName (ast_context,
3034// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3035// name);
3036// }
3037// }
3038// break;
3039//
Greg Clayton1674b122010-07-21 22:12:05 +00003040 case clang::Type::LValueReference:
3041 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003042 {
3043 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3044 QualType pointee_type = reference_type->getPointeeType();
3045
3046 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3047 {
3048 return GetIndexOfChildWithName (ast_context,
3049 reference_type->getPointeeType().getAsOpaquePtr(),
3050 name,
3051 omit_empty_base_classes);
3052 }
3053 }
3054 break;
3055
Greg Clayton1674b122010-07-21 22:12:05 +00003056 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003057 {
3058 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
3059 QualType pointee_type = pointer_type->getPointeeType();
3060
3061 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3062 {
3063 return GetIndexOfChildWithName (ast_context,
3064 pointer_type->getPointeeType().getAsOpaquePtr(),
3065 name,
3066 omit_empty_base_classes);
3067 }
3068 else
3069 {
3070// if (parent_name)
3071// {
3072// child_name.assign(1, '*');
3073// child_name += parent_name;
3074// }
3075//
3076// // We have a pointer to an simple type
3077// if (idx == 0)
3078// {
3079// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type);
3080// assert(clang_type_info.first % 8 == 0);
3081// child_byte_size = clang_type_info.first / 8;
3082// child_byte_offset = 0;
3083// return pointee_type.getAsOpaquePtr();
3084// }
3085 }
3086 }
3087 break;
3088
Greg Clayton1674b122010-07-21 22:12:05 +00003089 case clang::Type::Typedef:
Chris Lattner24943d22010-06-08 16:52:24 +00003090 return GetIndexOfChildWithName (ast_context,
Sean Callanan9e7958e2010-12-13 01:26:27 +00003091 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner24943d22010-06-08 16:52:24 +00003092 name,
3093 omit_empty_base_classes);
3094
3095 default:
3096 break;
3097 }
3098 }
3099 return UINT32_MAX;
3100}
3101
3102#pragma mark TagType
3103
3104bool
Greg Clayton462d4142010-09-29 01:12:09 +00003105ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner24943d22010-06-08 16:52:24 +00003106{
3107 if (tag_clang_type)
3108 {
3109 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003110 clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003111 if (clang_type)
3112 {
3113 TagType *tag_type = dyn_cast<TagType>(clang_type);
3114 if (tag_type)
3115 {
3116 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3117 if (tag_decl)
3118 {
3119 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3120 return true;
3121 }
3122 }
3123 }
3124 }
3125 return false;
3126}
3127
3128
3129#pragma mark DeclContext Functions
3130
3131DeclContext *
Greg Clayton462d4142010-09-29 01:12:09 +00003132ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003133{
3134 if (clang_type == NULL)
3135 return NULL;
3136
3137 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003138 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3139 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003140 {
Greg Clayton9488b742010-07-28 02:04:09 +00003141 case clang::Type::FunctionNoProto: break;
3142 case clang::Type::FunctionProto: break;
3143 case clang::Type::IncompleteArray: break;
3144 case clang::Type::VariableArray: break;
3145 case clang::Type::ConstantArray: break;
3146 case clang::Type::ExtVector: break;
3147 case clang::Type::Vector: break;
3148 case clang::Type::Builtin: break;
3149 case clang::Type::BlockPointer: break;
3150 case clang::Type::Pointer: break;
3151 case clang::Type::LValueReference: break;
3152 case clang::Type::RValueReference: break;
3153 case clang::Type::MemberPointer: break;
3154 case clang::Type::Complex: break;
3155 case clang::Type::ObjCObject: break;
3156 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3157 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3158 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3159 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
Sean Callanan9e7958e2010-12-13 01:26:27 +00003160 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003161
Greg Clayton9488b742010-07-28 02:04:09 +00003162 case clang::Type::TypeOfExpr: break;
3163 case clang::Type::TypeOf: break;
3164 case clang::Type::Decltype: break;
3165 //case clang::Type::QualifiedName: break;
3166 case clang::Type::TemplateSpecialization: break;
Chris Lattner24943d22010-06-08 16:52:24 +00003167 }
3168 // No DeclContext in this type...
3169 return NULL;
3170}
3171
3172#pragma mark Namespace Declarations
3173
3174NamespaceDecl *
3175ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3176{
3177 // TODO: Do something intelligent with the Declaration object passed in
3178 // like maybe filling in the SourceLocation with it...
3179 if (name)
3180 {
3181 ASTContext *ast_context = getASTContext();
3182 if (decl_ctx == NULL)
3183 decl_ctx = ast_context->getTranslationUnitDecl();
3184 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name));
3185 }
3186 return NULL;
3187}
3188
3189
3190#pragma mark Function Types
3191
3192FunctionDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003193ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner24943d22010-06-08 16:52:24 +00003194{
3195 if (name)
3196 {
3197 ASTContext *ast_context = getASTContext();
3198 assert (ast_context != NULL);
3199
3200 if (name && name[0])
3201 {
3202 return FunctionDecl::Create(*ast_context,
3203 ast_context->getTranslationUnitDecl(),
3204 SourceLocation(),
3205 DeclarationName (&ast_context->Idents.get(name)),
3206 QualType::getFromOpaquePtr(function_clang_type),
3207 NULL,
3208 (FunctionDecl::StorageClass)storage,
3209 (FunctionDecl::StorageClass)storage,
3210 is_inline);
3211 }
3212 else
3213 {
3214 return FunctionDecl::Create(*ast_context,
3215 ast_context->getTranslationUnitDecl(),
3216 SourceLocation(),
3217 DeclarationName (),
3218 QualType::getFromOpaquePtr(function_clang_type),
3219 NULL,
3220 (FunctionDecl::StorageClass)storage,
3221 (FunctionDecl::StorageClass)storage,
3222 is_inline);
3223 }
3224 }
3225 return NULL;
3226}
3227
Greg Clayton462d4142010-09-29 01:12:09 +00003228clang_type_t
3229ClangASTContext::CreateFunctionType (ASTContext *ast_context,
3230 clang_type_t result_type,
3231 clang_type_t *args,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003232 unsigned num_args,
3233 bool is_variadic,
3234 unsigned type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00003235{
Chris Lattner24943d22010-06-08 16:52:24 +00003236 assert (ast_context != NULL);
3237 std::vector<QualType> qual_type_args;
3238 for (unsigned i=0; i<num_args; ++i)
3239 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3240
3241 // TODO: Detect calling convention in DWARF?
3242 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton53d68e72010-07-20 22:52:08 +00003243 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner24943d22010-06-08 16:52:24 +00003244 qual_type_args.size(),
Sean Callanan2ea8f272010-09-16 20:40:25 +00003245 is_variadic,
3246 type_quals,
Chris Lattner24943d22010-06-08 16:52:24 +00003247 false, // hasExceptionSpec
3248 false, // hasAnyExceptionSpec,
3249 0, // NumExs
3250 0, // const QualType *ExArray
3251 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn);
3252}
3253
3254ParmVarDecl *
Greg Clayton462d4142010-09-29 01:12:09 +00003255ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner24943d22010-06-08 16:52:24 +00003256{
3257 ASTContext *ast_context = getASTContext();
3258 assert (ast_context != NULL);
3259 return ParmVarDecl::Create(*ast_context,
3260 ast_context->getTranslationUnitDecl(),
3261 SourceLocation(),
3262 name && name[0] ? &ast_context->Idents.get(name) : NULL,
Sean Callanan2ea8f272010-09-16 20:40:25 +00003263 QualType::getFromOpaquePtr(param_type),
Chris Lattner24943d22010-06-08 16:52:24 +00003264 NULL,
3265 (VarDecl::StorageClass)storage,
3266 (VarDecl::StorageClass)storage,
3267 0);
3268}
3269
3270void
3271ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3272{
3273 if (function_decl)
3274 function_decl->setParams (params, num_params);
3275}
3276
3277
3278#pragma mark Array Types
3279
Greg Clayton462d4142010-09-29 01:12:09 +00003280clang_type_t
3281ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner24943d22010-06-08 16:52:24 +00003282{
3283 if (element_type)
3284 {
3285 ASTContext *ast_context = getASTContext();
3286 assert (ast_context != NULL);
3287 llvm::APInt ap_element_count (64, element_count);
3288 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
3289 ap_element_count,
3290 ArrayType::Normal,
3291 0).getAsOpaquePtr(); // ElemQuals
3292 }
3293 return NULL;
3294}
3295
3296
3297#pragma mark TagDecl
3298
3299bool
Greg Clayton462d4142010-09-29 01:12:09 +00003300ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003301{
3302 if (clang_type)
3303 {
3304 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton1674b122010-07-21 22:12:05 +00003305 clang::Type *t = qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003306 if (t)
3307 {
3308 TagType *tag_type = dyn_cast<TagType>(t);
3309 if (tag_type)
3310 {
3311 TagDecl *tag_decl = tag_type->getDecl();
3312 if (tag_decl)
3313 {
3314 tag_decl->startDefinition();
3315 return true;
3316 }
3317 }
3318 }
3319 }
3320 return false;
3321}
3322
3323bool
Greg Clayton462d4142010-09-29 01:12:09 +00003324ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003325{
3326 if (clang_type)
3327 {
3328 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton55b6c532010-09-29 03:44:17 +00003329
3330 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3331
3332 if (cxx_record_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003333 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003334 cxx_record_decl->completeDefinition();
3335
3336 return true;
3337 }
3338
Sean Callanan04325062010-10-25 00:29:48 +00003339 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
3340
3341 if (objc_class_type)
3342 {
3343 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3344
3345 class_interface_decl->setForwardDecl(false);
3346 }
3347
Greg Clayton55b6c532010-09-29 03:44:17 +00003348 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3349
3350 if (enum_type)
3351 {
3352 EnumDecl *enum_decl = enum_type->getDecl();
3353
3354 if (enum_decl)
Chris Lattner24943d22010-06-08 16:52:24 +00003355 {
Greg Clayton55b6c532010-09-29 03:44:17 +00003356 /// TODO This really needs to be fixed.
3357
3358 unsigned NumPositiveBits = 1;
3359 unsigned NumNegativeBits = 0;
3360
Greg Clayton48fbdf72010-10-12 04:29:14 +00003361 ASTContext *ast_context = getASTContext();
3362
3363 QualType promotion_qual_type;
3364 // If the enum integer type is less than an integer in bit width,
3365 // then we must promote it to an integer size.
3366 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
3367 {
3368 if (enum_decl->getIntegerType()->isSignedIntegerType())
3369 promotion_qual_type = ast_context->IntTy;
3370 else
3371 promotion_qual_type = ast_context->UnsignedIntTy;
3372 }
3373 else
3374 promotion_qual_type = enum_decl->getIntegerType();
3375
3376 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton55b6c532010-09-29 03:44:17 +00003377 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003378 }
3379 }
3380 }
3381 return false;
3382}
3383
3384
3385#pragma mark Enumeration Types
3386
Greg Clayton462d4142010-09-29 01:12:09 +00003387clang_type_t
3388ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003389{
3390 // TODO: Do something intelligent with the Declaration object passed in
3391 // like maybe filling in the SourceLocation with it...
3392 ASTContext *ast_context = getASTContext();
3393 assert (ast_context != NULL);
Greg Clayton48fbdf72010-10-12 04:29:14 +00003394
3395 // TODO: ask about these...
3396// const bool IsScoped = false;
3397// const bool IsFixed = false;
3398
3399 EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
3400 ast_context->getTranslationUnitDecl(),
3401 SourceLocation(),
3402 name && name[0] ? &ast_context->Idents.get(name) : NULL,
3403 SourceLocation(),
Sean Callanan9e7958e2010-12-13 01:26:27 +00003404 NULL,
3405 false, // IsScoped
3406 false, // IsScopedUsingClassTag
3407 false); // IsFixed
Chris Lattner24943d22010-06-08 16:52:24 +00003408 if (enum_decl)
Greg Claytone37f23c2010-09-12 23:17:56 +00003409 {
3410 // TODO: check if we should be setting the promotion type too?
3411 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003412 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Claytone37f23c2010-09-12 23:17:56 +00003413 }
Chris Lattner24943d22010-06-08 16:52:24 +00003414 return NULL;
3415}
3416
Greg Clayton462d4142010-09-29 01:12:09 +00003417clang_type_t
3418ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3419{
3420 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3421
3422 clang::Type *clang_type = enum_qual_type.getTypePtr();
3423 if (clang_type)
3424 {
3425 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3426 if (enum_type)
3427 {
3428 EnumDecl *enum_decl = enum_type->getDecl();
3429 if (enum_decl)
3430 return enum_decl->getIntegerType().getAsOpaquePtr();
3431 }
3432 }
3433 return NULL;
3434}
Chris Lattner24943d22010-06-08 16:52:24 +00003435bool
3436ClangASTContext::AddEnumerationValueToEnumerationType
3437(
Greg Clayton462d4142010-09-29 01:12:09 +00003438 clang_type_t enum_clang_type,
3439 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00003440 const Declaration &decl,
3441 const char *name,
3442 int64_t enum_value,
3443 uint32_t enum_value_bit_size
3444)
3445{
3446 if (enum_clang_type && enumerator_clang_type && name)
3447 {
3448 // TODO: Do something intelligent with the Declaration object passed in
3449 // like maybe filling in the SourceLocation with it...
3450 ASTContext *ast_context = getASTContext();
3451 IdentifierTable *identifier_table = getIdentifierTable();
3452
3453 assert (ast_context != NULL);
3454 assert (identifier_table != NULL);
3455 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3456
Greg Clayton1674b122010-07-21 22:12:05 +00003457 clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner24943d22010-06-08 16:52:24 +00003458 if (clang_type)
3459 {
3460 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3461
3462 if (enum_type)
3463 {
3464 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3465 enum_llvm_apsint = enum_value;
3466 EnumConstantDecl *enumerator_decl =
3467 EnumConstantDecl::Create(*ast_context,
3468 enum_type->getDecl(),
3469 SourceLocation(),
3470 name ? &identifier_table->get(name) : NULL, // Identifier
3471 QualType::getFromOpaquePtr(enumerator_clang_type),
3472 NULL,
3473 enum_llvm_apsint);
3474
3475 if (enumerator_decl)
3476 {
3477 enum_type->getDecl()->addDecl(enumerator_decl);
3478 return true;
3479 }
3480 }
3481 }
3482 }
3483 return false;
3484}
3485
3486#pragma mark Pointers & References
3487
Greg Clayton462d4142010-09-29 01:12:09 +00003488clang_type_t
3489ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003490{
3491 if (clang_type)
Greg Clayton7b541032010-07-29 20:06:32 +00003492 {
3493 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3494
Greg Clayton03e0f972010-09-13 03:32:57 +00003495 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3496 switch (type_class)
Greg Clayton7b541032010-07-29 20:06:32 +00003497 {
3498 case clang::Type::ObjCObject:
3499 case clang::Type::ObjCInterface:
Greg Clayton7b541032010-07-29 20:06:32 +00003500 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
3501
Greg Clayton7b541032010-07-29 20:06:32 +00003502 default:
3503 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr();
3504 }
3505 }
Chris Lattner24943d22010-06-08 16:52:24 +00003506 return NULL;
3507}
3508
Greg Clayton462d4142010-09-29 01:12:09 +00003509clang_type_t
3510ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003511{
3512 if (clang_type)
3513 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3514 return NULL;
3515}
3516
Greg Clayton462d4142010-09-29 01:12:09 +00003517clang_type_t
3518ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003519{
3520 if (clang_type)
3521 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
3522 return NULL;
3523}
3524
Greg Clayton462d4142010-09-29 01:12:09 +00003525clang_type_t
3526ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Claytonfa970692010-06-12 01:20:30 +00003527{
3528 if (clang_pointee_type && clang_pointee_type)
3529 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3530 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3531 return NULL;
3532}
3533
Chris Lattner24943d22010-06-08 16:52:24 +00003534size_t
3535ClangASTContext::GetPointerBitSize ()
3536{
3537 ASTContext *ast_context = getASTContext();
3538 return ast_context->getTypeSize(ast_context->VoidPtrTy);
3539}
3540
3541bool
Greg Clayton462d4142010-09-29 01:12:09 +00003542ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003543{
3544 if (clang_type == NULL)
3545 return false;
3546
3547 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003548 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3549 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003550 {
Sean Callanan04325062010-10-25 00:29:48 +00003551 case clang::Type::Builtin:
3552 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3553 {
3554 default:
3555 break;
3556 case clang::BuiltinType::ObjCId:
3557 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003558 return true;
3559 }
3560 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003561 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003562 if (target_type)
3563 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3564 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003565 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003566 if (target_type)
3567 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3568 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003569 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003570 if (target_type)
3571 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3572 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003573 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003574 if (target_type)
3575 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3576 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003577 case clang::Type::LValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003578 if (target_type)
3579 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3580 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003581 case clang::Type::RValueReference:
Chris Lattner24943d22010-06-08 16:52:24 +00003582 if (target_type)
3583 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3584 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003585 case clang::Type::Typedef:
Sean Callanan9e7958e2010-12-13 01:26:27 +00003586 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner24943d22010-06-08 16:52:24 +00003587 default:
3588 break;
3589 }
3590 return false;
3591}
3592
Chris Lattner24943d22010-06-08 16:52:24 +00003593bool
Greg Clayton462d4142010-09-29 01:12:09 +00003594ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner24943d22010-06-08 16:52:24 +00003595{
3596 if (!clang_type)
3597 return false;
3598
3599 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3600 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3601
3602 if (builtin_type)
3603 {
3604 if (builtin_type->isInteger())
3605 is_signed = builtin_type->isSignedInteger();
3606
3607 return true;
3608 }
3609
3610 return false;
3611}
3612
3613bool
Greg Clayton462d4142010-09-29 01:12:09 +00003614ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003615{
3616 if (clang_type)
3617 {
3618 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton03e0f972010-09-13 03:32:57 +00003619 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3620 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003621 {
Sean Callanan04325062010-10-25 00:29:48 +00003622 case clang::Type::Builtin:
3623 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3624 {
3625 default:
3626 break;
3627 case clang::BuiltinType::ObjCId:
3628 case clang::BuiltinType::ObjCClass:
Sean Callanan04325062010-10-25 00:29:48 +00003629 return true;
3630 }
3631 return false;
Greg Clayton1674b122010-07-21 22:12:05 +00003632 case clang::Type::ObjCObjectPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003633 if (target_type)
3634 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3635 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003636 case clang::Type::BlockPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003637 if (target_type)
3638 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3639 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003640 case clang::Type::Pointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003641 if (target_type)
3642 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3643 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003644 case clang::Type::MemberPointer:
Chris Lattner24943d22010-06-08 16:52:24 +00003645 if (target_type)
3646 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3647 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003648 case clang::Type::Typedef:
Sean Callanan9e7958e2010-12-13 01:26:27 +00003649 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Chris Lattner24943d22010-06-08 16:52:24 +00003650 default:
3651 break;
3652 }
3653 }
3654 return false;
3655}
3656
3657bool
Greg Clayton462d4142010-09-29 01:12:09 +00003658ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner24943d22010-06-08 16:52:24 +00003659{
3660 if (clang_type)
3661 {
3662 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3663
3664 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
3665 {
3666 clang::BuiltinType::Kind kind = BT->getKind();
3667 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
3668 {
3669 count = 1;
3670 is_complex = false;
3671 return true;
3672 }
3673 }
3674 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
3675 {
3676 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
3677 {
3678 count = 2;
3679 is_complex = true;
3680 return true;
3681 }
3682 }
3683 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
3684 {
3685 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
3686 {
3687 count = VT->getNumElements();
3688 is_complex = false;
3689 return true;
3690 }
3691 }
3692 }
3693 return false;
3694}
3695
Greg Claytonbf8e42b2010-10-14 22:52:14 +00003696
3697bool
3698ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
3699{
3700 if (clang_type)
3701 {
3702 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3703
3704 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3705 if (cxx_record_decl)
3706 {
3707 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
3708 return true;
3709 }
3710 }
3711 class_name.clear();
3712 return false;
3713}
3714
3715
Greg Clayton1d8173f2010-09-24 05:15:53 +00003716bool
Greg Clayton462d4142010-09-29 01:12:09 +00003717ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003718{
3719 if (clang_type)
3720 {
3721 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3722 if (qual_type->getAsCXXRecordDecl() != NULL)
3723 return true;
3724 }
3725 return false;
3726}
3727
3728bool
Greg Clayton462d4142010-09-29 01:12:09 +00003729ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003730{
3731 if (clang_type)
3732 {
3733 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3734 if (qual_type->isObjCObjectOrInterfaceType())
3735 return true;
3736 }
3737 return false;
3738}
3739
3740
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003741bool
3742ClangASTContext::IsCharType (clang_type_t clang_type)
3743{
3744 if (clang_type)
3745 return QualType::getFromOpaquePtr(clang_type)->isCharType();
3746 return false;
3747}
Chris Lattner24943d22010-06-08 16:52:24 +00003748
3749bool
Greg Clayton462d4142010-09-29 01:12:09 +00003750ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner24943d22010-06-08 16:52:24 +00003751{
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003752 clang_type_t pointee_or_element_clang_type = NULL;
3753 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
3754
3755 if (pointee_or_element_clang_type == NULL)
3756 return false;
3757
3758 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner24943d22010-06-08 16:52:24 +00003759 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003760 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
3761
3762 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner24943d22010-06-08 16:52:24 +00003763 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003764 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3765 if (type_flags.Test (eTypeIsArray))
Chris Lattner24943d22010-06-08 16:52:24 +00003766 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003767 // We know the size of the array and it could be a C string
3768 // since it is an array of characters
3769 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
3770 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003771 }
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003772 else
Chris Lattner24943d22010-06-08 16:52:24 +00003773 {
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003774 length = 0;
3775 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00003776 }
Chris Lattner24943d22010-06-08 16:52:24 +00003777
Chris Lattner24943d22010-06-08 16:52:24 +00003778 }
3779 }
3780 return false;
3781}
3782
3783bool
Greg Clayton462d4142010-09-29 01:12:09 +00003784ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton03e0f972010-09-13 03:32:57 +00003785{
3786 if (clang_type)
3787 {
3788 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3789
3790 if (qual_type->isFunctionPointerType())
3791 return true;
3792
3793 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3794 switch (type_class)
3795 {
3796 case clang::Type::Typedef:
Sean Callanan9e7958e2010-12-13 01:26:27 +00003797 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Greg Clayton03e0f972010-09-13 03:32:57 +00003798
3799 case clang::Type::LValueReference:
3800 case clang::Type::RValueReference:
3801 {
3802 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
3803 if (reference_type)
3804 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
3805 }
3806 break;
3807 }
3808 }
3809 return false;
3810}
3811
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00003812size_t
3813ClangASTContext::GetArraySize (clang_type_t clang_type)
3814{
3815 if (clang_type)
3816 {
3817 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
3818 if (array)
3819 return array->getSize().getLimitedValue();
3820 }
3821 return 0;
3822}
Greg Clayton03e0f972010-09-13 03:32:57 +00003823
3824bool
Greg Clayton462d4142010-09-29 01:12:09 +00003825ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner24943d22010-06-08 16:52:24 +00003826{
3827 if (!clang_type)
3828 return false;
3829
3830 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3831
Greg Clayton03e0f972010-09-13 03:32:57 +00003832 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3833 switch (type_class)
Chris Lattner24943d22010-06-08 16:52:24 +00003834 {
Greg Clayton1674b122010-07-21 22:12:05 +00003835 case clang::Type::ConstantArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003836 if (member_type)
3837 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3838 if (size)
3839 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
3840 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003841 case clang::Type::IncompleteArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003842 if (member_type)
3843 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3844 if (size)
3845 *size = 0;
3846 return true;
Greg Clayton1674b122010-07-21 22:12:05 +00003847 case clang::Type::VariableArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003848 if (member_type)
3849 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3850 if (size)
3851 *size = 0;
Greg Clayton1674b122010-07-21 22:12:05 +00003852 case clang::Type::DependentSizedArray:
Chris Lattner24943d22010-06-08 16:52:24 +00003853 if (member_type)
3854 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
3855 if (size)
3856 *size = 0;
3857 return true;
3858 }
3859 return false;
3860}
3861
3862
3863#pragma mark Typedefs
3864
Greg Clayton462d4142010-09-29 01:12:09 +00003865clang_type_t
3866ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00003867{
3868 if (clang_type)
3869 {
3870 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3871 ASTContext *ast_context = getASTContext();
3872 IdentifierTable *identifier_table = getIdentifierTable();
3873 assert (ast_context != NULL);
3874 assert (identifier_table != NULL);
3875 if (decl_ctx == NULL)
3876 decl_ctx = ast_context->getTranslationUnitDecl();
3877 TypedefDecl *decl = TypedefDecl::Create(*ast_context,
3878 decl_ctx,
3879 SourceLocation(),
3880 name ? &identifier_table->get(name) : NULL, // Identifier
3881 ast_context->CreateTypeSourceInfo(qual_type));
3882
3883 // Get a uniqued QualType for the typedef decl type
3884 return ast_context->getTypedefType (decl).getAsOpaquePtr();
3885 }
3886 return NULL;
3887}
3888
3889
3890std::string
Greg Clayton462d4142010-09-29 01:12:09 +00003891ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner24943d22010-06-08 16:52:24 +00003892{
3893 std::string return_name;
3894
Greg Clayton462d4142010-09-29 01:12:09 +00003895 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner24943d22010-06-08 16:52:24 +00003896
Greg Clayton462d4142010-09-29 01:12:09 +00003897 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner24943d22010-06-08 16:52:24 +00003898 if (typedef_type)
3899 {
Greg Clayton462d4142010-09-29 01:12:09 +00003900 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00003901 return_name = typedef_decl->getQualifiedNameAsString();
3902 }
3903 else
3904 {
3905 return_name = qual_type.getAsString();
3906 }
3907
3908 return return_name;
3909}
3910
3911// Disable this for now since I can't seem to get a nicely formatted float
3912// out of the APFloat class without just getting the float, double or quad
3913// and then using a formatted print on it which defeats the purpose. We ideally
3914// would like to get perfect string values for any kind of float semantics
3915// so we can support remote targets. The code below also requires a patch to
3916// llvm::APInt.
3917//bool
Greg Clayton462d4142010-09-29 01:12:09 +00003918//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, clang_type_t clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
Chris Lattner24943d22010-06-08 16:52:24 +00003919//{
3920// uint32_t count = 0;
3921// bool is_complex = false;
3922// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3923// {
3924// unsigned num_bytes_per_float = byte_size / count;
3925// unsigned num_bits_per_float = num_bytes_per_float * 8;
3926//
3927// float_str.clear();
3928// uint32_t i;
3929// for (i=0; i<count; i++)
3930// {
3931// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
3932// bool is_ieee = false;
3933// APFloat ap_float(ap_int, is_ieee);
3934// char s[1024];
3935// unsigned int hex_digits = 0;
3936// bool upper_case = false;
3937//
3938// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
3939// {
3940// if (i > 0)
3941// float_str.append(", ");
3942// float_str.append(s);
3943// if (i == 1 && is_complex)
3944// float_str.append(1, 'i');
3945// }
3946// }
3947// return !float_str.empty();
3948// }
3949// return false;
3950//}
3951
3952size_t
Greg Clayton462d4142010-09-29 01:12:09 +00003953ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
Chris Lattner24943d22010-06-08 16:52:24 +00003954{
3955 if (clang_type)
3956 {
3957 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3958 uint32_t count = 0;
3959 bool is_complex = false;
3960 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
3961 {
3962 // TODO: handle complex and vector types
3963 if (count != 1)
3964 return false;
3965
3966 StringRef s_sref(s);
3967 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref);
3968
3969 const uint64_t bit_size = ast_context->getTypeSize (qual_type);
3970 const uint64_t byte_size = bit_size / 8;
3971 if (dst_size >= byte_size)
3972 {
3973 if (bit_size == sizeof(float)*8)
3974 {
3975 float float32 = ap_float.convertToFloat();
3976 ::memcpy (dst, &float32, byte_size);
3977 return byte_size;
3978 }
3979 else if (bit_size >= 64)
3980 {
3981 llvm::APInt ap_int(ap_float.bitcastToAPInt());
3982 ::memcpy (dst, ap_int.getRawData(), byte_size);
3983 return byte_size;
3984 }
3985 }
3986 }
3987 }
3988 return 0;
3989}
Sean Callanana751f7b2010-09-17 02:24:29 +00003990
3991unsigned
Greg Clayton462d4142010-09-29 01:12:09 +00003992ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanana751f7b2010-09-17 02:24:29 +00003993{
3994 assert (clang_type);
3995
3996 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3997
3998 return qual_type.getQualifiers().getCVRQualifiers();
3999}