blob: 229045b197bf424e68c2b382e3e1c76eafc051ff [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedman932197d2010-06-13 19:06:42 +000010#include "lldb/Symbol/ClangASTContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
Greg Clayton6beaaa62011-01-17 03:46:26 +000017
18// Clang headers like to use NDEBUG inside of them to enable/disable debug
19// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing
20// or another. This is bad because it means that if clang was built in release
21// mode, it assumes that you are building in release mode which is not always
22// the case. You can end up with functions that are defined as empty in header
23// files when NDEBUG is not defined, and this can cause link errors with the
24// clang .a files that you have since you might be missing functions in the .a
25// file. So we have to define NDEBUG when including clang headers to avoid any
26// mismatches. This is covered by rdar://problem/8691220
27
28#ifndef NDEBUG
29#define LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000030#define NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000031// Need to include assert.h so it is as clang would expect it to be (disabled)
32#include <assert.h>
33#endif
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "clang/AST/ASTContext.h"
36#include "clang/AST/ASTImporter.h"
37#include "clang/AST/CXXInheritance.h"
Greg Clayton8cf05932010-07-22 18:30:50 +000038#include "clang/AST/DeclObjC.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "clang/AST/RecordLayout.h"
40#include "clang/AST/Type.h"
41#include "clang/Basic/Builtins.h"
42#include "clang/Basic/FileManager.h"
Sean Callanan79439e82010-11-18 02:56:27 +000043#include "clang/Basic/FileSystemOptions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044#include "clang/Basic/SourceManager.h"
45#include "clang/Basic/TargetInfo.h"
46#include "clang/Basic/TargetOptions.h"
47#include "clang/Frontend/FrontendOptions.h"
48#include "clang/Frontend/LangStandard.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000049
50#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
Sean Callanan246549c2010-07-08 18:16:16 +000051#undef NDEBUG
Greg Clayton6beaaa62011-01-17 03:46:26 +000052#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
53// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
54#include <assert.h>
55#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057#include "lldb/Core/dwarf.h"
Greg Clayton73b472d2010-10-27 03:32:59 +000058#include "lldb/Core/Flags.h"
Sean Callananfb8b7092010-10-28 18:19:36 +000059#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060
Eli Friedman932197d2010-06-13 19:06:42 +000061#include <stdio.h>
62
Greg Claytonc86103d2010-08-05 01:57:25 +000063using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064using namespace lldb_private;
65using namespace llvm;
66using namespace clang;
67
Greg Clayton6beaaa62011-01-17 03:46:26 +000068
69static bool
70GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
71{
72 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
73 switch (type_class)
74 {
75 case clang::Type::Record:
76 case clang::Type::Enum:
77 {
Sean Callanan78e37602011-01-27 04:42:51 +000078 const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +000079 if (tag_type)
80 {
81 clang::TagDecl *tag_decl = tag_type->getDecl();
82 if (tag_decl)
83 {
84 if (tag_decl->getDefinition())
85 return true;
86
87 if (tag_decl->hasExternalLexicalStorage())
88 {
89 ExternalASTSource *external_ast_source = ast->getExternalSource();
90 if (external_ast_source)
91 {
92 external_ast_source->CompleteType(tag_decl);
93 return !tag_type->isIncompleteType();
94 }
95 }
96 return false;
97 }
98 }
99
100 }
101 break;
102
103 case clang::Type::ObjCObject:
104 case clang::Type::ObjCInterface:
105 {
Sean Callanan78e37602011-01-27 04:42:51 +0000106 const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000107 if (objc_class_type)
108 {
109 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
110 // We currently can't complete objective C types through the newly added ASTContext
111 // because it only supports TagDecl objects right now...
112 bool is_forward_decl = class_interface_decl->isForwardDecl();
113 if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
114 {
115 ExternalASTSource *external_ast_source = ast->getExternalSource();
116 if (external_ast_source)
117 {
118 external_ast_source->CompleteType (class_interface_decl);
119 is_forward_decl = class_interface_decl->isForwardDecl();
120 }
Greg Claytonc432c192011-01-20 04:18:48 +0000121 return is_forward_decl == false;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000122 }
Greg Claytonc432c192011-01-20 04:18:48 +0000123 return true;
Greg Clayton6beaaa62011-01-17 03:46:26 +0000124 }
125 }
126 break;
127
128 case clang::Type::Typedef:
129 return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType());
130
131 default:
132 break;
133 }
134
135 return true;
136}
137
138
Greg Clayton8cf05932010-07-22 18:30:50 +0000139static AccessSpecifier
Greg Claytonc86103d2010-08-05 01:57:25 +0000140ConvertAccessTypeToAccessSpecifier (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000141{
142 switch (access)
143 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000144 default: break;
145 case eAccessNone: return AS_none;
146 case eAccessPublic: return AS_public;
147 case eAccessPrivate: return AS_private;
148 case eAccessProtected: return AS_protected;
Greg Clayton8cf05932010-07-22 18:30:50 +0000149 }
150 return AS_none;
151}
152
153static ObjCIvarDecl::AccessControl
Greg Claytonc86103d2010-08-05 01:57:25 +0000154ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
Greg Clayton8cf05932010-07-22 18:30:50 +0000155{
156 switch (access)
157 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000158 default: break;
159 case eAccessNone: return ObjCIvarDecl::None;
160 case eAccessPublic: return ObjCIvarDecl::Public;
161 case eAccessPrivate: return ObjCIvarDecl::Private;
162 case eAccessProtected: return ObjCIvarDecl::Protected;
163 case eAccessPackage: return ObjCIvarDecl::Package;
Greg Clayton8cf05932010-07-22 18:30:50 +0000164 }
165 return ObjCIvarDecl::None;
166}
167
168
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169static void
170ParseLangArgs
171(
172 LangOptions &Opts,
Greg Clayton94e5d782010-06-13 17:34:29 +0000173 InputKind IK
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174)
175{
176 // FIXME: Cleanup per-file based stuff.
177
178 // Set some properties which depend soley on the input kind; it would be nice
179 // to move these to the language standard, and have the driver resolve the
180 // input kind + language standard.
Greg Clayton94e5d782010-06-13 17:34:29 +0000181 if (IK == IK_Asm) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182 Opts.AsmPreprocessor = 1;
Greg Clayton94e5d782010-06-13 17:34:29 +0000183 } else if (IK == IK_ObjC ||
184 IK == IK_ObjCXX ||
185 IK == IK_PreprocessedObjC ||
186 IK == IK_PreprocessedObjCXX) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187 Opts.ObjC1 = Opts.ObjC2 = 1;
188 }
189
190 LangStandard::Kind LangStd = LangStandard::lang_unspecified;
191
192 if (LangStd == LangStandard::lang_unspecified) {
193 // Based on the base language, pick one.
194 switch (IK) {
Greg Clayton94e5d782010-06-13 17:34:29 +0000195 case IK_None:
196 case IK_AST:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000197 assert (!"Invalid input kind!");
Greg Clayton94e5d782010-06-13 17:34:29 +0000198 case IK_OpenCL:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199 LangStd = LangStandard::lang_opencl;
200 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000201 case IK_Asm:
202 case IK_C:
203 case IK_PreprocessedC:
204 case IK_ObjC:
205 case IK_PreprocessedObjC:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206 LangStd = LangStandard::lang_gnu99;
207 break;
Greg Clayton94e5d782010-06-13 17:34:29 +0000208 case IK_CXX:
209 case IK_PreprocessedCXX:
210 case IK_ObjCXX:
211 case IK_PreprocessedObjCXX:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000212 LangStd = LangStandard::lang_gnucxx98;
213 break;
214 }
215 }
216
217 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
218 Opts.BCPLComment = Std.hasBCPLComments();
219 Opts.C99 = Std.isC99();
220 Opts.CPlusPlus = Std.isCPlusPlus();
221 Opts.CPlusPlus0x = Std.isCPlusPlus0x();
222 Opts.Digraphs = Std.hasDigraphs();
223 Opts.GNUMode = Std.isGNUMode();
224 Opts.GNUInline = !Std.isC99();
225 Opts.HexFloats = Std.hasHexFloats();
226 Opts.ImplicitInt = Std.hasImplicitInt();
227
228 // OpenCL has some additional defaults.
229 if (LangStd == LangStandard::lang_opencl) {
230 Opts.OpenCL = 1;
231 Opts.AltiVec = 1;
232 Opts.CXXOperatorNames = 1;
233 Opts.LaxVectorConversions = 1;
234 }
235
236 // OpenCL and C++ both have bool, true, false keywords.
237 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
238
239// if (Opts.CPlusPlus)
240// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
241//
242// if (Args.hasArg(OPT_fobjc_gc_only))
243// Opts.setGCMode(LangOptions::GCOnly);
244// else if (Args.hasArg(OPT_fobjc_gc))
245// Opts.setGCMode(LangOptions::HybridGC);
246//
247// if (Args.hasArg(OPT_print_ivar_layout))
248// Opts.ObjCGCBitmapPrint = 1;
249//
250// if (Args.hasArg(OPT_faltivec))
251// Opts.AltiVec = 1;
252//
253// if (Args.hasArg(OPT_pthread))
254// Opts.POSIXThreads = 1;
255//
256// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
257// "default");
258// if (Vis == "default")
Sean Callanan31e851c2010-10-29 18:38:40 +0000259 Opts.setVisibilityMode(DefaultVisibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260// else if (Vis == "hidden")
261// Opts.setVisibilityMode(LangOptions::Hidden);
262// else if (Vis == "protected")
263// Opts.setVisibilityMode(LangOptions::Protected);
264// else
265// Diags.Report(diag::err_drv_invalid_value)
266// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
267
268// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
269
270 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
271 // is specified, or -std is set to a conforming mode.
272 Opts.Trigraphs = !Opts.GNUMode;
273// if (Args.hasArg(OPT_trigraphs))
274// Opts.Trigraphs = 1;
275//
276// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
277// OPT_fno_dollars_in_identifiers,
278// !Opts.AsmPreprocessor);
279// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
280// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
281// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
282// if (Args.hasArg(OPT_fno_lax_vector_conversions))
283// Opts.LaxVectorConversions = 0;
284// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
285// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
286// Opts.Blocks = Args.hasArg(OPT_fblocks);
287// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
288// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
289// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
290// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
291// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
292// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
293// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
294// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
295// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
296// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
297// Diags);
298// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
299// Opts.ObjCConstantStringClass = getLastArgValue(Args,
300// OPT_fconstant_string_class);
301// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
302// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
303// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
304// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
305// Opts.Static = Args.hasArg(OPT_static_define);
306 Opts.OptimizeSize = 0;
307
308 // FIXME: Eliminate this dependency.
309// unsigned Opt =
310// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
311// Opts.Optimize = Opt != 0;
312 unsigned Opt = 0;
313
314 // This is the __NO_INLINE__ define, which just depends on things like the
315 // optimization level and -fno-inline, not actually whether the backend has
316 // inlining enabled.
317 //
318 // FIXME: This is affected by other options (-fno-inline).
319 Opts.NoInline = !Opt;
320
321// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
322// switch (SSP) {
323// default:
324// Diags.Report(diag::err_drv_invalid_value)
325// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
326// break;
327// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
328// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
329// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
330// }
331}
332
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333
Greg Clayton6beaaa62011-01-17 03:46:26 +0000334ClangASTContext::ClangASTContext (const char *target_triple) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000335 m_target_triple(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000336 m_ast_ap(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 m_language_options_ap(),
338 m_source_manager_ap(),
339 m_diagnostic_ap(),
340 m_target_options_ap(),
341 m_target_info_ap(),
342 m_identifier_table_ap(),
343 m_selector_table_ap(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000344 m_builtins_ap(),
345 m_callback_tag_decl (NULL),
346 m_callback_objc_decl (NULL),
347 m_callback_baton (NULL)
348
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349{
350 if (target_triple && target_triple[0])
351 m_target_triple.assign (target_triple);
352}
353
354//----------------------------------------------------------------------
355// Destructor
356//----------------------------------------------------------------------
357ClangASTContext::~ClangASTContext()
358{
359 m_builtins_ap.reset();
360 m_selector_table_ap.reset();
361 m_identifier_table_ap.reset();
362 m_target_info_ap.reset();
363 m_target_options_ap.reset();
364 m_diagnostic_ap.reset();
365 m_source_manager_ap.reset();
366 m_language_options_ap.reset();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000367 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368}
369
370
371void
372ClangASTContext::Clear()
373{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000374 m_ast_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375 m_language_options_ap.reset();
376 m_source_manager_ap.reset();
377 m_diagnostic_ap.reset();
378 m_target_options_ap.reset();
379 m_target_info_ap.reset();
380 m_identifier_table_ap.reset();
381 m_selector_table_ap.reset();
382 m_builtins_ap.reset();
383}
384
385const char *
386ClangASTContext::GetTargetTriple ()
387{
388 return m_target_triple.c_str();
389}
390
391void
392ClangASTContext::SetTargetTriple (const char *target_triple)
393{
394 Clear();
395 m_target_triple.assign(target_triple);
396}
397
Greg Clayton6beaaa62011-01-17 03:46:26 +0000398bool
399ClangASTContext::HasExternalSource ()
400{
401 ASTContext *ast = getASTContext();
402 if (ast)
403 return ast->getExternalSource () != NULL;
404 return false;
405}
406
407void
408ClangASTContext::SetExternalSource (llvm::OwningPtr<ExternalASTSource> &ast_source_ap)
409{
410 ASTContext *ast = getASTContext();
411 if (ast)
412 {
413 ast->setExternalSource (ast_source_ap);
414 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
415 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
416 }
417}
418
419void
420ClangASTContext::RemoveExternalSource ()
421{
422 ASTContext *ast = getASTContext();
423
424 if (ast)
425 {
426 llvm::OwningPtr<ExternalASTSource> empty_ast_source_ap;
427 ast->setExternalSource (empty_ast_source_ap);
428 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
429 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
430 }
431}
432
433
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000434
435ASTContext *
436ClangASTContext::getASTContext()
437{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000438 if (m_ast_ap.get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000440 m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
441 *getSourceManager(),
442 *getTargetInfo(),
443 *getIdentifierTable(),
444 *getSelectorTable(),
445 *getBuiltinContext(),
446 0));
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000447
Greg Clayton6beaaa62011-01-17 03:46:26 +0000448 if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton)
449 {
450 m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
451 //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
452 }
453
454 m_ast_ap->getDiagnostics().setClient(getDiagnosticClient(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000456 return m_ast_ap.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457}
458
459Builtin::Context *
460ClangASTContext::getBuiltinContext()
461{
462 if (m_builtins_ap.get() == NULL)
463 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo()));
464 return m_builtins_ap.get();
465}
466
467IdentifierTable *
468ClangASTContext::getIdentifierTable()
469{
470 if (m_identifier_table_ap.get() == NULL)
471 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
472 return m_identifier_table_ap.get();
473}
474
475LangOptions *
476ClangASTContext::getLanguageOptions()
477{
478 if (m_language_options_ap.get() == NULL)
479 {
480 m_language_options_ap.reset(new LangOptions());
Greg Clayton94e5d782010-06-13 17:34:29 +0000481 ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
482// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000483 }
484 return m_language_options_ap.get();
485}
486
487SelectorTable *
488ClangASTContext::getSelectorTable()
489{
490 if (m_selector_table_ap.get() == NULL)
491 m_selector_table_ap.reset (new SelectorTable());
492 return m_selector_table_ap.get();
493}
494
Sean Callanan79439e82010-11-18 02:56:27 +0000495clang::FileManager *
496ClangASTContext::getFileManager()
497{
498 if (m_file_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000499 {
500 clang::FileSystemOptions file_system_options;
501 m_file_manager_ap.reset(new clang::FileManager(file_system_options));
502 }
Sean Callanan79439e82010-11-18 02:56:27 +0000503 return m_file_manager_ap.get();
504}
505
Greg Claytone1a916a2010-07-21 22:12:05 +0000506clang::SourceManager *
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000507ClangASTContext::getSourceManager()
508{
509 if (m_source_manager_ap.get() == NULL)
Greg Clayton38a61402010-12-02 23:20:03 +0000510 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511 return m_source_manager_ap.get();
512}
513
514Diagnostic *
515ClangASTContext::getDiagnostic()
516{
517 if (m_diagnostic_ap.get() == NULL)
Greg Claytona651b532010-11-19 21:46:54 +0000518 {
519 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
520 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp));
521 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000522 return m_diagnostic_ap.get();
523}
524
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000525class NullDiagnosticClient : public DiagnosticClient
526{
527public:
528 NullDiagnosticClient ()
529 {
530 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
531 }
532
533 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info)
534 {
535 if (m_log)
536 {
537 llvm::SmallVectorImpl<char> diag_str(10);
538 info.FormatDiagnostic(diag_str);
539 diag_str.push_back('\0');
540 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
541 }
542 }
543private:
544 LogSP m_log;
545};
546
547DiagnosticClient *
548ClangASTContext::getDiagnosticClient()
549{
550 if (m_diagnostic_client_ap.get() == NULL)
551 m_diagnostic_client_ap.reset(new NullDiagnosticClient);
552
553 return m_diagnostic_client_ap.get();
554}
555
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556TargetOptions *
557ClangASTContext::getTargetOptions()
558{
559 if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
560 {
561 m_target_options_ap.reset (new TargetOptions());
562 if (m_target_options_ap.get())
563 m_target_options_ap->Triple = m_target_triple;
564 }
565 return m_target_options_ap.get();
566}
567
568
569TargetInfo *
570ClangASTContext::getTargetInfo()
571{
572 // target_triple should be something like "x86_64-apple-darwin10"
573 if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
574 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions()));
575 return m_target_info_ap.get();
576}
577
578#pragma mark Basic Types
579
580static inline bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000581QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000583 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584 if (qual_type_bit_size == bit_size)
585 return true;
586 return false;
587}
588
Greg Clayton1be10fc2010-09-29 01:12:09 +0000589clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +0000590ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000591{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000592 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000593
Greg Clayton6beaaa62011-01-17 03:46:26 +0000594 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000595
Greg Clayton6beaaa62011-01-17 03:46:26 +0000596 return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000597}
598
Greg Clayton1be10fc2010-09-29 01:12:09 +0000599clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000600ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000601{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000602 if (!ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000603 return NULL;
604
605 switch (encoding)
606 {
Greg Claytonc86103d2010-08-05 01:57:25 +0000607 case eEncodingInvalid:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000608 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
609 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610 break;
611
Greg Claytonc86103d2010-08-05 01:57:25 +0000612 case eEncodingUint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000613 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
614 return ast->UnsignedCharTy.getAsOpaquePtr();
615 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
616 return ast->UnsignedShortTy.getAsOpaquePtr();
617 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
618 return ast->UnsignedIntTy.getAsOpaquePtr();
619 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
620 return ast->UnsignedLongTy.getAsOpaquePtr();
621 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
622 return ast->UnsignedLongLongTy.getAsOpaquePtr();
623 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
624 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000625 break;
626
Greg Claytonc86103d2010-08-05 01:57:25 +0000627 case eEncodingSint:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000628 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
629 return ast->CharTy.getAsOpaquePtr();
630 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
631 return ast->ShortTy.getAsOpaquePtr();
632 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
633 return ast->IntTy.getAsOpaquePtr();
634 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
635 return ast->LongTy.getAsOpaquePtr();
636 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
637 return ast->LongLongTy.getAsOpaquePtr();
638 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
639 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000640 break;
641
Greg Claytonc86103d2010-08-05 01:57:25 +0000642 case eEncodingIEEE754:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000643 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
644 return ast->FloatTy.getAsOpaquePtr();
645 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
646 return ast->DoubleTy.getAsOpaquePtr();
647 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
648 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649 break;
650
Greg Claytonc86103d2010-08-05 01:57:25 +0000651 case eEncodingVector:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652 default:
653 break;
654 }
655
656 return NULL;
657}
658
Greg Clayton1be10fc2010-09-29 01:12:09 +0000659clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000660ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
661{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000662 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000663
664 #define streq(a,b) strcmp(a,b) == 0
Greg Clayton6beaaa62011-01-17 03:46:26 +0000665 assert (ast != NULL);
666 if (ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000667 {
668 switch (dw_ate)
669 {
670 default:
671 break;
672
673 case DW_ATE_address:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000674 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
675 return ast->VoidPtrTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000676 break;
677
678 case DW_ATE_boolean:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000679 if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
680 return ast->BoolTy.getAsOpaquePtr();
681 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
682 return ast->UnsignedCharTy.getAsOpaquePtr();
683 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
684 return ast->UnsignedShortTy.getAsOpaquePtr();
685 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
686 return ast->UnsignedIntTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000687 break;
688
Greg Clayton49462ea2011-01-15 02:52:14 +0000689 case DW_ATE_lo_user:
690 // This has been seen to mean DW_AT_complex_integer
Greg Clayton5732f242011-01-27 09:15:11 +0000691 if (::strstr(type_name, "complex"))
Greg Clayton49462ea2011-01-15 02:52:14 +0000692 {
693 clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000694 return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000695 }
696 break;
697
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000698 case DW_ATE_complex_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000699 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
700 return ast->FloatComplexTy.getAsOpaquePtr();
701 else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
702 return ast->DoubleComplexTy.getAsOpaquePtr();
703 else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
704 return ast->LongDoubleComplexTy.getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000705 else
706 {
707 clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000708 return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
Greg Clayton49462ea2011-01-15 02:52:14 +0000709 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000710 break;
711
712 case DW_ATE_float:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000713 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
714 return ast->FloatTy.getAsOpaquePtr();
715 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
716 return ast->DoubleTy.getAsOpaquePtr();
717 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
718 return ast->LongDoubleTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000719 break;
720
721 case DW_ATE_signed:
722 if (type_name)
723 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000724 if (strstr(type_name, "long long"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000726 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
727 return ast->LongLongTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000728 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000729 else if (strstr(type_name, "long"))
730 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000731 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
732 return ast->LongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000733 }
734 else if (strstr(type_name, "short"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000735 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000736 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
737 return ast->ShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000738 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000739 else if (strstr(type_name, "char"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000740 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000741 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
742 return ast->CharTy.getAsOpaquePtr();
743 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
744 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000745 }
Greg Clayton19de37f2010-11-02 03:48:39 +0000746 else if (strstr(type_name, "int"))
747 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000748 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
749 return ast->IntTy.getAsOpaquePtr();
750 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
751 return ast->Int128Ty.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000752 }
753 else if (streq(type_name, "wchar_t"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000755 if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
756 return ast->WCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757 }
Greg Clayton7bd65b92011-02-09 23:39:34 +0000758 else if (streq(type_name, "void"))
759 {
760 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
761 return ast->VoidTy.getAsOpaquePtr();
762 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000763 }
764 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000765 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
766 return ast->CharTy.getAsOpaquePtr();
767 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
768 return ast->ShortTy.getAsOpaquePtr();
769 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
770 return ast->IntTy.getAsOpaquePtr();
771 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
772 return ast->LongTy.getAsOpaquePtr();
773 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
774 return ast->LongLongTy.getAsOpaquePtr();
775 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
776 return ast->Int128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000777 break;
778
779 case DW_ATE_signed_char:
780 if (type_name)
781 {
782 if (streq(type_name, "signed char"))
783 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000784 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
785 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000786 }
787 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000788 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
789 return ast->CharTy.getAsOpaquePtr();
790 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
791 return ast->SignedCharTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000792 break;
793
794 case DW_ATE_unsigned:
795 if (type_name)
796 {
Greg Clayton19de37f2010-11-02 03:48:39 +0000797 if (strstr(type_name, "long long"))
798 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000799 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
800 return ast->UnsignedLongLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000801 }
802 else if (strstr(type_name, "long"))
803 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000804 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
805 return ast->UnsignedLongTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000806 }
807 else if (strstr(type_name, "short"))
808 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000809 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
810 return ast->UnsignedShortTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000811 }
812 else if (strstr(type_name, "char"))
813 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000814 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
815 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton19de37f2010-11-02 03:48:39 +0000816 }
817 else if (strstr(type_name, "int"))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000818 {
Greg Clayton6beaaa62011-01-17 03:46:26 +0000819 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
820 return ast->UnsignedIntTy.getAsOpaquePtr();
821 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
822 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000823 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000824 }
825 // We weren't able to match up a type name, just search by size
Greg Clayton6beaaa62011-01-17 03:46:26 +0000826 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
827 return ast->UnsignedCharTy.getAsOpaquePtr();
828 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
829 return ast->UnsignedShortTy.getAsOpaquePtr();
830 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
831 return ast->UnsignedIntTy.getAsOpaquePtr();
832 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
833 return ast->UnsignedLongTy.getAsOpaquePtr();
834 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
835 return ast->UnsignedLongLongTy.getAsOpaquePtr();
836 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
837 return ast->UnsignedInt128Ty.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000838 break;
839
840 case DW_ATE_unsigned_char:
Greg Clayton6beaaa62011-01-17 03:46:26 +0000841 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
842 return ast->UnsignedCharTy.getAsOpaquePtr();
Greg Clayton7bd65b92011-02-09 23:39:34 +0000843 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
844 return ast->UnsignedShortTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000845 break;
846
847 case DW_ATE_imaginary_float:
848 break;
849 }
850 }
851 // This assert should fire for anything that we don't catch above so we know
852 // to fix any issues we run into.
853 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!");
854 return NULL;
855}
856
Greg Clayton1be10fc2010-09-29 01:12:09 +0000857clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000858ClangASTContext::GetBuiltInType_void(ASTContext *ast)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000859{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000860 return ast->VoidTy.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000861}
862
Greg Clayton1be10fc2010-09-29 01:12:09 +0000863clang_type_t
Sean Callananf7c3e272010-11-19 02:52:21 +0000864ClangASTContext::GetBuiltInType_bool()
865{
866 return getASTContext()->BoolTy.getAsOpaquePtr();
867}
868
869clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000870ClangASTContext::GetBuiltInType_objc_id()
871{
Sean Callananf6c73082010-12-06 23:53:20 +0000872 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000873}
874
Greg Clayton1be10fc2010-09-29 01:12:09 +0000875clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000876ClangASTContext::GetBuiltInType_objc_Class()
877{
Sean Callanana2424172010-10-25 00:29:48 +0000878 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000879}
880
Greg Clayton1be10fc2010-09-29 01:12:09 +0000881clang_type_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000882ClangASTContext::GetBuiltInType_objc_selector()
883{
Sean Callananf6c73082010-12-06 23:53:20 +0000884 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000885}
886
Greg Clayton1be10fc2010-09-29 01:12:09 +0000887clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000888ClangASTContext::GetCStringType (bool is_const)
889{
890 QualType char_type(getASTContext()->CharTy);
891
892 if (is_const)
893 char_type.addConst();
894
895 return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
896}
897
Greg Clayton1be10fc2010-09-29 01:12:09 +0000898clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000899ClangASTContext::GetVoidPtrType (bool is_const)
900{
901 return GetVoidPtrType(getASTContext(), is_const);
902}
903
Greg Clayton1be10fc2010-09-29 01:12:09 +0000904clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +0000905ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000906{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000907 QualType void_ptr_type(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000908
909 if (is_const)
910 void_ptr_type.addConst();
911
912 return void_ptr_type.getAsOpaquePtr();
913}
914
Greg Clayton1be10fc2010-09-29 01:12:09 +0000915clang_type_t
Greg Clayton38a61402010-12-02 23:20:03 +0000916ClangASTContext::CopyType (ASTContext *dst_ast,
917 ASTContext *src_ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000918 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000919{
Sean Callanan79439e82010-11-18 02:56:27 +0000920 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000921 FileManager file_manager (file_system_options);
922 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000923 *src_ast, file_manager,
924 false);
Sean Callanan0617fcb2010-11-09 22:37:10 +0000925
Greg Clayton38a61402010-12-02 23:20:03 +0000926 QualType src (QualType::getFromOpaquePtr(clang_type));
927 QualType dst (importer.Import(src));
Sean Callanan0617fcb2010-11-09 22:37:10 +0000928
929 return dst.getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000930}
931
Greg Clayton526e5af2010-11-13 03:52:47 +0000932
933clang::Decl *
Greg Clayton38a61402010-12-02 23:20:03 +0000934ClangASTContext::CopyDecl (ASTContext *dst_ast,
935 ASTContext *src_ast,
Greg Clayton526e5af2010-11-13 03:52:47 +0000936 clang::Decl *source_decl)
Sean Callanan7fddd4c2010-12-11 00:08:56 +0000937{
Sean Callanan79439e82010-11-18 02:56:27 +0000938 FileSystemOptions file_system_options;
Greg Clayton38a61402010-12-02 23:20:03 +0000939 FileManager file_manager (file_system_options);
940 ASTImporter importer(*dst_ast, file_manager,
Sean Callanan2c777c42011-01-18 23:32:05 +0000941 *src_ast, file_manager,
942 false);
Greg Clayton526e5af2010-11-13 03:52:47 +0000943
944 return importer.Import(source_decl);
945}
946
Sean Callanan23a30272010-07-16 00:00:27 +0000947bool
Greg Clayton6beaaa62011-01-17 03:46:26 +0000948ClangASTContext::AreTypesSame(ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +0000949 clang_type_t type1,
950 clang_type_t type2)
Sean Callanan4dcca2622010-07-15 22:30:52 +0000951{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000952 return ast->hasSameType(QualType::getFromOpaquePtr(type1),
Sean Callanan4dcca2622010-07-15 22:30:52 +0000953 QualType::getFromOpaquePtr(type2));
954}
955
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000956#pragma mark CVR modifiers
957
Greg Clayton1be10fc2010-09-29 01:12:09 +0000958clang_type_t
959ClangASTContext::AddConstModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000960{
961 if (clang_type)
962 {
963 QualType result(QualType::getFromOpaquePtr(clang_type));
964 result.addConst();
965 return result.getAsOpaquePtr();
966 }
967 return NULL;
968}
969
Greg Clayton1be10fc2010-09-29 01:12:09 +0000970clang_type_t
971ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000972{
973 if (clang_type)
974 {
975 QualType result(QualType::getFromOpaquePtr(clang_type));
976 result.getQualifiers().setRestrict (true);
977 return result.getAsOpaquePtr();
978 }
979 return NULL;
980}
981
Greg Clayton1be10fc2010-09-29 01:12:09 +0000982clang_type_t
983ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000984{
985 if (clang_type)
986 {
987 QualType result(QualType::getFromOpaquePtr(clang_type));
988 result.getQualifiers().setVolatile (true);
989 return result.getAsOpaquePtr();
990 }
991 return NULL;
992}
993
Greg Clayton6beaaa62011-01-17 03:46:26 +0000994
995clang_type_t
996ClangASTContext::GetTypeForDecl (TagDecl *decl)
997{
998 // No need to call the getASTContext() accessor (which can create the AST
999 // if it isn't created yet, because we can't have created a decl in this
1000 // AST if our AST didn't already exist...
1001 if (m_ast_ap.get())
1002 return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
1003 return NULL;
1004}
1005
1006clang_type_t
1007ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
1008{
1009 // No need to call the getASTContext() accessor (which can create the AST
1010 // if it isn't created yet, because we can't have created a decl in this
1011 // AST if our AST didn't already exist...
1012 if (m_ast_ap.get())
1013 return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
1014 return NULL;
1015}
1016
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017#pragma mark Structure, Unions, Classes
1018
Greg Clayton1be10fc2010-09-29 01:12:09 +00001019clang_type_t
Greg Claytonc86103d2010-08-05 01:57:25 +00001020ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001021{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001022 ASTContext *ast = getASTContext();
1023 assert (ast != NULL);
Sean Callanana2424172010-10-25 00:29:48 +00001024
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001025 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001026 decl_ctx = ast->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001027
Greg Clayton9e409562010-07-28 02:04:09 +00001028
Greg Claytonc86103d2010-08-05 01:57:25 +00001029 if (language == eLanguageTypeObjC)
Greg Clayton9e409562010-07-28 02:04:09 +00001030 {
Greg Claytonaaf99e02010-10-11 02:25:34 +00001031 bool isForwardDecl = true;
Greg Clayton9e409562010-07-28 02:04:09 +00001032 bool isInternal = false;
1033 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
1034 }
1035
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001036 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1037 // we will need to update this code. I was told to currently always use
1038 // the CXXRecordDecl class since we often don't know from debug information
1039 // if something is struct or a class, so we default to always use the more
1040 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001041 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042 (TagDecl::TagKind)kind,
1043 decl_ctx,
1044 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001045 name && name[0] ? &ast->Idents.get(name) : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046
Greg Clayton6beaaa62011-01-17 03:46:26 +00001047 return ast->getTagDeclType(decl).getAsOpaquePtr();
1048}
1049
1050bool
1051ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
1052{
1053 if (clang_type == NULL)
1054 return false;
1055
1056 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1057
1058 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1059 switch (type_class)
1060 {
1061 case clang::Type::Record:
1062 {
1063 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
1064 if (cxx_record_decl)
1065 {
1066 cxx_record_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001067 cxx_record_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001068 return true;
1069 }
1070 }
1071 break;
1072
1073 case clang::Type::Enum:
1074 {
1075 EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
1076 if (enum_decl)
1077 {
1078 enum_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001079 enum_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001080 return true;
1081 }
1082 }
1083 break;
1084
1085 case clang::Type::ObjCObject:
1086 case clang::Type::ObjCInterface:
1087 {
Sean Callanan78e37602011-01-27 04:42:51 +00001088 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001089 assert (objc_class_type);
1090 if (objc_class_type)
1091 {
1092 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1093
1094 if (class_interface_decl)
1095 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001096 class_interface_decl->setHasExternalLexicalStorage (has_extern);
Greg Claytonc432c192011-01-20 04:18:48 +00001097 class_interface_decl->setHasExternalVisibleStorage (has_extern);
Greg Clayton6beaaa62011-01-17 03:46:26 +00001098 return true;
1099 }
1100 }
1101 }
1102 break;
1103
1104 case clang::Type::Typedef:
1105 return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
1106
1107 default:
1108 break;
1109 }
1110 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001111}
1112
Greg Claytona3c444a2010-10-01 23:13:49 +00001113static bool
1114IsOperator (const char *name, OverloadedOperatorKind &op_kind)
1115{
1116 if (name == NULL || name[0] == '\0')
1117 return false;
1118
Sean Callanana43f20d2010-12-10 19:51:54 +00001119#define OPERATOR_PREFIX "operator"
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001120#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
Sean Callananbfeff8c2010-12-10 02:15:55 +00001121
1122 const char *post_op_name = NULL;
1123
Sean Callanana43f20d2010-12-10 19:51:54 +00001124 bool no_space = true;
Sean Callananbfeff8c2010-12-10 02:15:55 +00001125
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001126 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
Greg Claytona3c444a2010-10-01 23:13:49 +00001127 return false;
1128
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001129 post_op_name = name + OPERATOR_PREFIX_LENGTH;
1130
Sean Callanana43f20d2010-12-10 19:51:54 +00001131 if (post_op_name[0] == ' ')
1132 {
1133 post_op_name++;
1134 no_space = false;
1135 }
1136
1137#undef OPERATOR_PREFIX
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001138#undef OPERATOR_PREFIX_LENGTH
Sean Callanana43f20d2010-12-10 19:51:54 +00001139
Greg Claytona3c444a2010-10-01 23:13:49 +00001140 // This is an operator, set the overloaded operator kind to invalid
1141 // in case this is a conversion operator...
1142 op_kind = NUM_OVERLOADED_OPERATORS;
1143
1144 switch (post_op_name[0])
1145 {
Sean Callananbfeff8c2010-12-10 02:15:55 +00001146 default:
1147 if (no_space)
1148 return false;
1149 break;
Greg Claytona3c444a2010-10-01 23:13:49 +00001150 case 'n':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001151 if (no_space)
1152 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001153 if (strcmp (post_op_name, "new") == 0)
1154 op_kind = OO_New;
1155 else if (strcmp (post_op_name, "new[]") == 0)
1156 op_kind = OO_Array_New;
1157 break;
1158
1159 case 'd':
Sean Callananbfeff8c2010-12-10 02:15:55 +00001160 if (no_space)
1161 return false;
Greg Claytona3c444a2010-10-01 23:13:49 +00001162 if (strcmp (post_op_name, "delete") == 0)
1163 op_kind = OO_Delete;
1164 else if (strcmp (post_op_name, "delete[]") == 0)
1165 op_kind = OO_Array_Delete;
1166 break;
1167
1168 case '+':
1169 if (post_op_name[1] == '\0')
1170 op_kind = OO_Plus;
1171 else if (post_op_name[2] == '\0')
1172 {
1173 if (post_op_name[1] == '=')
1174 op_kind = OO_PlusEqual;
1175 else if (post_op_name[1] == '+')
1176 op_kind = OO_PlusPlus;
1177 }
1178 break;
1179
1180 case '-':
1181 if (post_op_name[1] == '\0')
1182 op_kind = OO_Minus;
1183 else if (post_op_name[2] == '\0')
1184 {
1185 switch (post_op_name[1])
1186 {
1187 case '=': op_kind = OO_MinusEqual; break;
1188 case '-': op_kind = OO_MinusMinus; break;
1189 case '>': op_kind = OO_Arrow; break;
1190 }
1191 }
1192 else if (post_op_name[3] == '\0')
1193 {
1194 if (post_op_name[2] == '*')
1195 op_kind = OO_ArrowStar; break;
1196 }
1197 break;
1198
1199 case '*':
1200 if (post_op_name[1] == '\0')
1201 op_kind = OO_Star;
1202 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1203 op_kind = OO_StarEqual;
1204 break;
1205
1206 case '/':
1207 if (post_op_name[1] == '\0')
1208 op_kind = OO_Slash;
1209 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1210 op_kind = OO_SlashEqual;
1211 break;
1212
1213 case '%':
1214 if (post_op_name[1] == '\0')
1215 op_kind = OO_Percent;
1216 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1217 op_kind = OO_PercentEqual;
1218 break;
1219
1220
1221 case '^':
1222 if (post_op_name[1] == '\0')
1223 op_kind = OO_Caret;
1224 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1225 op_kind = OO_CaretEqual;
1226 break;
1227
1228 case '&':
1229 if (post_op_name[1] == '\0')
1230 op_kind = OO_Amp;
1231 else if (post_op_name[2] == '\0')
1232 {
1233 switch (post_op_name[1])
1234 {
1235 case '=': op_kind = OO_AmpEqual; break;
1236 case '&': op_kind = OO_AmpAmp; break;
1237 }
1238 }
1239 break;
1240
1241 case '|':
1242 if (post_op_name[1] == '\0')
1243 op_kind = OO_Pipe;
1244 else if (post_op_name[2] == '\0')
1245 {
1246 switch (post_op_name[1])
1247 {
1248 case '=': op_kind = OO_PipeEqual; break;
1249 case '|': op_kind = OO_PipePipe; break;
1250 }
1251 }
1252 break;
1253
1254 case '~':
1255 if (post_op_name[1] == '\0')
1256 op_kind = OO_Tilde;
1257 break;
1258
1259 case '!':
1260 if (post_op_name[1] == '\0')
1261 op_kind = OO_Exclaim;
1262 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1263 op_kind = OO_ExclaimEqual;
1264 break;
1265
1266 case '=':
1267 if (post_op_name[1] == '\0')
1268 op_kind = OO_Equal;
1269 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
1270 op_kind = OO_EqualEqual;
1271 break;
1272
1273 case '<':
1274 if (post_op_name[1] == '\0')
1275 op_kind = OO_Less;
1276 else if (post_op_name[2] == '\0')
1277 {
1278 switch (post_op_name[1])
1279 {
1280 case '<': op_kind = OO_LessLess; break;
1281 case '=': op_kind = OO_LessEqual; break;
1282 }
1283 }
1284 else if (post_op_name[3] == '\0')
1285 {
1286 if (post_op_name[2] == '=')
1287 op_kind = OO_LessLessEqual;
1288 }
1289 break;
1290
1291 case '>':
1292 if (post_op_name[1] == '\0')
1293 op_kind = OO_Greater;
1294 else if (post_op_name[2] == '\0')
1295 {
1296 switch (post_op_name[1])
1297 {
1298 case '>': op_kind = OO_GreaterGreater; break;
1299 case '=': op_kind = OO_GreaterEqual; break;
1300 }
1301 }
1302 else if (post_op_name[1] == '>' &&
1303 post_op_name[2] == '=' &&
1304 post_op_name[3] == '\0')
1305 {
1306 op_kind = OO_GreaterGreaterEqual;
1307 }
1308 break;
1309
1310 case ',':
1311 if (post_op_name[1] == '\0')
1312 op_kind = OO_Comma;
1313 break;
1314
1315 case '(':
1316 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
1317 op_kind = OO_Call;
1318 break;
1319
1320 case '[':
1321 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
1322 op_kind = OO_Subscript;
1323 break;
1324 }
1325
1326 return true;
1327}
Greg Clayton6beaaa62011-01-17 03:46:26 +00001328
Greg Claytona51ed9b2010-09-23 01:09:21 +00001329CXXMethodDecl *
Sean Callanan61da09b2010-09-17 02:58:26 +00001330ClangASTContext::AddMethodToCXXRecordType
1331(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001332 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001333 clang_type_t record_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001334 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001335 clang_type_t method_opaque_type,
Greg Claytona51ed9b2010-09-23 01:09:21 +00001336 lldb::AccessType access,
Greg Clayton0fffff52010-09-24 05:15:53 +00001337 bool is_virtual,
1338 bool is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00001339 bool is_inline,
1340 bool is_explicit
Greg Claytona51ed9b2010-09-23 01:09:21 +00001341)
Sean Callanan61da09b2010-09-17 02:58:26 +00001342{
Sean Callananfc55f5d2010-09-21 00:44:12 +00001343 if (!record_opaque_type || !method_opaque_type || !name)
Johnny Chend440bcc2010-09-28 16:10:54 +00001344 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001345
Greg Clayton6beaaa62011-01-17 03:46:26 +00001346 assert(ast);
Sean Callanan61da09b2010-09-17 02:58:26 +00001347
Greg Clayton6beaaa62011-01-17 03:46:26 +00001348 IdentifierTable *identifier_table = &ast->Idents;
Sean Callanan61da09b2010-09-17 02:58:26 +00001349
1350 assert(identifier_table);
1351
Sean Callananfc55f5d2010-09-21 00:44:12 +00001352 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001353
Greg Clayton6beaaa62011-01-17 03:46:26 +00001354 CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
Sean Callanan61da09b2010-09-17 02:58:26 +00001355
Greg Clayton0fffff52010-09-24 05:15:53 +00001356 if (cxx_record_decl == NULL)
Greg Claytona51ed9b2010-09-23 01:09:21 +00001357 return NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001358
Greg Clayton0fffff52010-09-24 05:15:53 +00001359 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
Sean Callananfc55f5d2010-09-21 00:44:12 +00001360
Greg Claytonf51de672010-10-01 02:31:07 +00001361 CXXMethodDecl *cxx_method_decl = NULL;
Sean Callanan61da09b2010-09-17 02:58:26 +00001362
Greg Claytonf51de672010-10-01 02:31:07 +00001363 DeclarationName decl_name (&identifier_table->get(name));
Greg Clayton878eaf12010-10-01 03:45:20 +00001364
Greg Clayton878eaf12010-10-01 03:45:20 +00001365 const bool is_implicitly_declared = false;
Greg Claytonf51de672010-10-01 02:31:07 +00001366
Sean Callanan78e37602011-01-27 04:42:51 +00001367 const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
Greg Clayton878eaf12010-10-01 03:45:20 +00001368
Greg Clayton90a2acd2010-10-02 01:40:05 +00001369 if (function_Type == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001370 return NULL;
1371
Sean Callanan78e37602011-01-27 04:42:51 +00001372 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
Greg Clayton878eaf12010-10-01 03:45:20 +00001373
1374 if (!method_function_prototype)
1375 return NULL;
1376
1377 unsigned int num_params = method_function_prototype->getNumArgs();
1378
1379 if (name[0] == '~')
Greg Claytonf51de672010-10-01 02:31:07 +00001380 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001381 cxx_method_decl = CXXDestructorDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001382 cxx_record_decl,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001383 DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001384 method_qual_type,
Sean Callanan31e851c2010-10-29 18:38:40 +00001385 NULL,
Greg Clayton878eaf12010-10-01 03:45:20 +00001386 is_inline,
1387 is_implicitly_declared);
1388 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001389 else if (decl_name == cxx_record_decl->getDeclName())
Greg Clayton878eaf12010-10-01 03:45:20 +00001390 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001391 cxx_method_decl = CXXConstructorDecl::Create (*ast,
Greg Claytonf51de672010-10-01 02:31:07 +00001392 cxx_record_decl,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001393 DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
Greg Claytonf51de672010-10-01 02:31:07 +00001394 method_qual_type,
1395 NULL, // TypeSourceInfo *
1396 is_explicit,
1397 is_inline,
1398 is_implicitly_declared);
1399 }
1400 else
Greg Clayton878eaf12010-10-01 03:45:20 +00001401 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001402
1403 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
1404 if (IsOperator (name, op_kind))
Greg Clayton878eaf12010-10-01 03:45:20 +00001405 {
Greg Claytona3c444a2010-10-01 23:13:49 +00001406 if (op_kind != NUM_OVERLOADED_OPERATORS)
1407 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001408 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001409 cxx_record_decl,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001410 DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001411 method_qual_type,
1412 NULL, // TypeSourceInfo *
Greg Claytona3c444a2010-10-01 23:13:49 +00001413 is_static,
1414 SC_None,
1415 is_inline);
1416 }
1417 else if (num_params == 0)
1418 {
1419 // Conversion operators don't take params...
Greg Clayton6beaaa62011-01-17 03:46:26 +00001420 cxx_method_decl = CXXConversionDecl::Create (*ast,
Greg Claytona3c444a2010-10-01 23:13:49 +00001421 cxx_record_decl,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001422 DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
Greg Claytona3c444a2010-10-01 23:13:49 +00001423 method_qual_type,
1424 NULL, // TypeSourceInfo *
1425 is_inline,
1426 is_explicit);
1427 }
Greg Clayton878eaf12010-10-01 03:45:20 +00001428 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001429
1430 if (cxx_method_decl == NULL)
Greg Clayton878eaf12010-10-01 03:45:20 +00001431 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001432 cxx_method_decl = CXXMethodDecl::Create (*ast,
Greg Clayton878eaf12010-10-01 03:45:20 +00001433 cxx_record_decl,
Greg Claytona3c444a2010-10-01 23:13:49 +00001434 DeclarationNameInfo (decl_name, SourceLocation()),
Greg Clayton878eaf12010-10-01 03:45:20 +00001435 method_qual_type,
1436 NULL, // TypeSourceInfo *
1437 is_static,
1438 SC_None,
1439 is_inline);
1440 }
Greg Claytonf51de672010-10-01 02:31:07 +00001441 }
Greg Claytona3c444a2010-10-01 23:13:49 +00001442
Greg Clayton1be10fc2010-09-29 01:12:09 +00001443 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
Greg Clayton0fffff52010-09-24 05:15:53 +00001444
1445 cxx_method_decl->setAccess (access_specifier);
1446 cxx_method_decl->setVirtualAsWritten (is_virtual);
Sean Callanane2ef6e32010-09-23 03:01:22 +00001447
Sean Callananfc55f5d2010-09-21 00:44:12 +00001448 // Populate the method decl with parameter decls
Sean Callananfc55f5d2010-09-21 00:44:12 +00001449
1450 ParmVarDecl *params[num_params];
1451
1452 for (int param_index = 0;
1453 param_index < num_params;
1454 ++param_index)
1455 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001456 params[param_index] = ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001457 cxx_method_decl,
1458 SourceLocation(),
1459 NULL, // anonymous
1460 method_function_prototype->getArgType(param_index),
1461 NULL,
1462 SC_None,
1463 SC_None,
1464 NULL);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001465 }
1466
Greg Clayton0fffff52010-09-24 05:15:53 +00001467 cxx_method_decl->setParams (params, num_params);
Sean Callananfc55f5d2010-09-21 00:44:12 +00001468
Greg Clayton0fffff52010-09-24 05:15:53 +00001469 cxx_record_decl->addDecl (cxx_method_decl);
Greg Claytonc432c192011-01-20 04:18:48 +00001470
1471// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic());
1472// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate());
1473// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD());
1474// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty());
1475// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract());
1476// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor());
1477// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
1478// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
1479// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor());
Greg Claytona51ed9b2010-09-23 01:09:21 +00001480 return cxx_method_decl;
Sean Callanan61da09b2010-09-17 02:58:26 +00001481}
1482
1483bool
Greg Clayton8cf05932010-07-22 18:30:50 +00001484ClangASTContext::AddFieldToRecordType
1485(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001486 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001487 clang_type_t record_clang_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001488 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001489 clang_type_t field_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001490 AccessType access,
1491 uint32_t bitfield_bit_size
1492)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001493{
1494 if (record_clang_type == NULL || field_type == NULL)
1495 return false;
1496
Greg Clayton6beaaa62011-01-17 03:46:26 +00001497 IdentifierTable *identifier_table = &ast->Idents;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001498
Greg Clayton6beaaa62011-01-17 03:46:26 +00001499 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001500 assert (identifier_table != NULL);
1501
1502 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
1503
Sean Callanan78e37602011-01-27 04:42:51 +00001504 const clang::Type *clang_type = record_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001505 if (clang_type)
1506 {
1507 const RecordType *record_type = dyn_cast<RecordType>(clang_type);
1508
1509 if (record_type)
1510 {
1511 RecordDecl *record_decl = record_type->getDecl();
1512
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001513 clang::Expr *bit_width = NULL;
1514 if (bitfield_bit_size != 0)
1515 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001516 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1517 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001518 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001519 FieldDecl *field = FieldDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001520 record_decl,
1521 SourceLocation(),
1522 name ? &identifier_table->get(name) : NULL, // Identifier
1523 QualType::getFromOpaquePtr(field_type), // Field type
1524 NULL, // DeclaratorInfo *
1525 bit_width, // BitWidth
1526 false); // Mutable
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001527
Greg Clayton8cf05932010-07-22 18:30:50 +00001528 field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001529
1530 if (field)
1531 {
1532 record_decl->addDecl(field);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001533 }
1534 }
Greg Clayton9e409562010-07-28 02:04:09 +00001535 else
1536 {
Sean Callanan78e37602011-01-27 04:42:51 +00001537 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001538 if (objc_class_type)
1539 {
Greg Clayton0fffff52010-09-24 05:15:53 +00001540 bool is_synthesized = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001541 ClangASTContext::AddObjCClassIVar (ast,
Sean Callanan6e6a7c72010-09-16 20:01:08 +00001542 record_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001543 name,
1544 field_type,
1545 access,
1546 bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001547 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001548 }
1549 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001550 }
1551 return false;
1552}
1553
1554bool
1555ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
1556{
1557 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
1558}
1559
1560bool
1561ClangASTContext::FieldIsBitfield
1562(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001563 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001564 FieldDecl* field,
1565 uint32_t& bitfield_bit_size
1566)
1567{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001568 if (ast == NULL || field == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001569 return false;
1570
1571 if (field->isBitField())
1572 {
1573 Expr* bit_width_expr = field->getBitWidth();
1574 if (bit_width_expr)
1575 {
1576 llvm::APSInt bit_width_apsint;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001577 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001578 {
1579 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
1580 return true;
1581 }
1582 }
1583 }
1584 return false;
1585}
1586
1587bool
1588ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
1589{
1590 if (record_decl == NULL)
1591 return false;
1592
1593 if (!record_decl->field_empty())
1594 return true;
1595
1596 // No fields, lets check this is a CXX record and check the base classes
1597 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
1598 if (cxx_record_decl)
1599 {
1600 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
1601 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
1602 base_class != base_class_end;
1603 ++base_class)
1604 {
1605 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
1606 if (RecordHasFields(base_class_decl))
1607 return true;
1608 }
1609 }
1610 return false;
1611}
1612
1613void
Greg Clayton6beaaa62011-01-17 03:46:26 +00001614ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001615{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001616 if (clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001617 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001618 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
1619
Sean Callanan78e37602011-01-27 04:42:51 +00001620 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001621 if (record_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001622 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001623 RecordDecl *record_decl = record_type->getDecl();
1624 if (record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001625 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001626 uint32_t field_idx;
1627 RecordDecl::field_iterator field, field_end;
1628 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
1629 field != field_end;
1630 ++field, ++field_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001631 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001632 // If no accessibility was assigned, assign the correct one
1633 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
1634 field->setAccess ((AccessSpecifier)default_accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001635 }
1636 }
1637 }
1638 }
1639}
1640
1641#pragma mark C++ Base Classes
1642
1643CXXBaseSpecifier *
Greg Clayton1be10fc2010-09-29 01:12:09 +00001644ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001645{
1646 if (base_class_type)
Greg Claytone6371122010-07-30 20:30:44 +00001647 return new CXXBaseSpecifier (SourceRange(),
1648 is_virtual,
1649 base_of_class,
1650 ConvertAccessTypeToAccessSpecifier (access),
Sean Callanan2c777c42011-01-18 23:32:05 +00001651 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
1652 SourceLocation());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001653 return NULL;
1654}
1655
Greg Clayton0b42ac32010-07-02 01:29:13 +00001656void
1657ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
1658{
1659 for (unsigned i=0; i<num_base_classes; ++i)
1660 {
1661 delete base_classes[i];
1662 base_classes[i] = NULL;
1663 }
1664}
1665
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001666bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001667ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001668{
1669 if (class_clang_type)
1670 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001671 CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
1672 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001673 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001674 cxx_record_decl->setBases(base_classes, num_base_classes);
1675 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001676 }
1677 }
1678 return false;
1679}
Greg Clayton8cf05932010-07-22 18:30:50 +00001680#pragma mark Objective C Classes
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001681
Greg Clayton1be10fc2010-09-29 01:12:09 +00001682clang_type_t
Greg Clayton8cf05932010-07-22 18:30:50 +00001683ClangASTContext::CreateObjCClass
1684(
1685 const char *name,
1686 DeclContext *decl_ctx,
1687 bool isForwardDecl,
1688 bool isInternal
1689)
1690{
Greg Clayton6beaaa62011-01-17 03:46:26 +00001691 ASTContext *ast = getASTContext();
1692 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001693 assert (name && name[0]);
1694 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00001695 decl_ctx = ast->getTranslationUnitDecl();
Greg Clayton8cf05932010-07-22 18:30:50 +00001696
1697 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
1698 // we will need to update this code. I was told to currently always use
1699 // the CXXRecordDecl class since we often don't know from debug information
1700 // if something is struct or a class, so we default to always use the more
1701 // complete definition just in case.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001702 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
Greg Clayton8cf05932010-07-22 18:30:50 +00001703 decl_ctx,
1704 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00001705 &ast->Idents.get(name),
Greg Clayton8cf05932010-07-22 18:30:50 +00001706 SourceLocation(),
1707 isForwardDecl,
1708 isInternal);
Greg Clayton9e409562010-07-28 02:04:09 +00001709
Greg Clayton6beaaa62011-01-17 03:46:26 +00001710 return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001711}
1712
1713bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001714ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
Greg Clayton8cf05932010-07-22 18:30:50 +00001715{
1716 if (class_opaque_type && super_opaque_type)
1717 {
1718 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1719 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
Sean Callanan78e37602011-01-27 04:42:51 +00001720 const clang::Type *class_type = class_qual_type.getTypePtr();
1721 const clang::Type *super_type = super_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001722 if (class_type && super_type)
1723 {
Sean Callanan78e37602011-01-27 04:42:51 +00001724 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
1725 const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001726 if (objc_class_type && objc_super_type)
1727 {
1728 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1729 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
1730 if (class_interface_decl && super_interface_decl)
1731 {
1732 class_interface_decl->setSuperClass(super_interface_decl);
1733 return true;
1734 }
1735 }
1736 }
1737 }
1738 return false;
1739}
1740
1741
1742bool
1743ClangASTContext::AddObjCClassIVar
1744(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001745 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001746 clang_type_t class_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001747 const char *name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001748 clang_type_t ivar_opaque_type,
Greg Clayton8cf05932010-07-22 18:30:50 +00001749 AccessType access,
1750 uint32_t bitfield_bit_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00001751 bool is_synthesized
Greg Clayton8cf05932010-07-22 18:30:50 +00001752)
1753{
1754 if (class_opaque_type == NULL || ivar_opaque_type == NULL)
1755 return false;
1756
Greg Clayton6beaaa62011-01-17 03:46:26 +00001757 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton8cf05932010-07-22 18:30:50 +00001758
Greg Clayton6beaaa62011-01-17 03:46:26 +00001759 assert (ast != NULL);
Greg Clayton8cf05932010-07-22 18:30:50 +00001760 assert (identifier_table != NULL);
1761
1762 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1763
Sean Callanan78e37602011-01-27 04:42:51 +00001764 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton8cf05932010-07-22 18:30:50 +00001765 if (class_type)
1766 {
Sean Callanan78e37602011-01-27 04:42:51 +00001767 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton8cf05932010-07-22 18:30:50 +00001768
1769 if (objc_class_type)
1770 {
1771 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1772
1773 if (class_interface_decl)
1774 {
1775 clang::Expr *bit_width = NULL;
1776 if (bitfield_bit_size != 0)
1777 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001778 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
1779 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
Greg Clayton8cf05932010-07-22 18:30:50 +00001780 }
1781
Greg Clayton6beaaa62011-01-17 03:46:26 +00001782 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast,
Greg Clayton9e409562010-07-28 02:04:09 +00001783 class_interface_decl,
1784 SourceLocation(),
1785 &identifier_table->get(name), // Identifier
1786 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
1787 NULL, // TypeSourceInfo *
1788 ConvertAccessTypeToObjCIvarAccessControl (access),
1789 bit_width,
Greg Clayton0fffff52010-09-24 05:15:53 +00001790 is_synthesized);
Greg Clayton9e409562010-07-28 02:04:09 +00001791
1792 if (field)
1793 {
1794 class_interface_decl->addDecl(field);
1795 return true;
1796 }
Greg Clayton8cf05932010-07-22 18:30:50 +00001797 }
1798 }
1799 }
1800 return false;
1801}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001802
Greg Clayton9e409562010-07-28 02:04:09 +00001803
1804bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00001805ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
Greg Clayton9e409562010-07-28 02:04:09 +00001806{
1807 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1808
Sean Callanan78e37602011-01-27 04:42:51 +00001809 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton9e409562010-07-28 02:04:09 +00001810 if (class_type)
1811 {
Sean Callanan78e37602011-01-27 04:42:51 +00001812 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001813
1814 if (objc_class_type)
1815 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
1816 }
1817 return false;
1818}
1819
1820bool
1821ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
1822{
1823 while (class_interface_decl)
1824 {
1825 if (class_interface_decl->ivar_size() > 0)
1826 return true;
1827
1828 if (check_superclass)
1829 class_interface_decl = class_interface_decl->getSuperClass();
1830 else
1831 break;
1832 }
1833 return false;
1834}
Greg Clayton0fffff52010-09-24 05:15:53 +00001835
Greg Clayton1be10fc2010-09-29 01:12:09 +00001836ObjCMethodDecl *
Greg Clayton0fffff52010-09-24 05:15:53 +00001837ClangASTContext::AddMethodToObjCObjectType
1838(
Greg Clayton6beaaa62011-01-17 03:46:26 +00001839 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001840 clang_type_t class_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001841 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
Greg Clayton1be10fc2010-09-29 01:12:09 +00001842 clang_type_t method_opaque_type,
Greg Clayton0fffff52010-09-24 05:15:53 +00001843 lldb::AccessType access
1844)
1845{
1846 if (class_opaque_type == NULL || method_opaque_type == NULL)
1847 return NULL;
1848
Greg Clayton6beaaa62011-01-17 03:46:26 +00001849 IdentifierTable *identifier_table = &ast->Idents;
Greg Clayton0fffff52010-09-24 05:15:53 +00001850
Greg Clayton6beaaa62011-01-17 03:46:26 +00001851 assert (ast != NULL);
Greg Clayton0fffff52010-09-24 05:15:53 +00001852 assert (identifier_table != NULL);
1853
1854 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
1855
Sean Callanan78e37602011-01-27 04:42:51 +00001856 const clang::Type *class_type = class_qual_type.getTypePtr();
Greg Clayton0fffff52010-09-24 05:15:53 +00001857 if (class_type == NULL)
1858 return NULL;
1859
Sean Callanan78e37602011-01-27 04:42:51 +00001860 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
Greg Clayton0fffff52010-09-24 05:15:53 +00001861
1862 if (objc_class_type == NULL)
1863 return NULL;
1864
1865 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1866
1867 if (class_interface_decl == NULL)
1868 return NULL;
Greg Clayton9e409562010-07-28 02:04:09 +00001869
Greg Clayton0fffff52010-09-24 05:15:53 +00001870 const char *selector_start = ::strchr (name, ' ');
1871 if (selector_start == NULL)
1872 return NULL;
1873
1874 selector_start++;
1875 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
1876 return NULL;
1877 llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
1878
Greg Clayton450e3f32010-10-12 02:24:53 +00001879 size_t len = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +00001880 const char *start;
Greg Clayton450e3f32010-10-12 02:24:53 +00001881 //printf ("name = '%s'\n", name);
1882
1883 unsigned num_selectors_with_args = 0;
1884 for (start = selector_start;
Greg Clayton0fffff52010-09-24 05:15:53 +00001885 start && *start != '\0' && *start != ']';
Greg Clayton450e3f32010-10-12 02:24:53 +00001886 start += len)
Greg Clayton0fffff52010-09-24 05:15:53 +00001887 {
Greg Clayton450e3f32010-10-12 02:24:53 +00001888 len = ::strcspn(start, ":]");
Greg Clayton90f90cd2010-10-27 04:01:14 +00001889 bool has_arg = (start[len] == ':');
1890 if (has_arg)
Greg Clayton450e3f32010-10-12 02:24:53 +00001891 ++num_selectors_with_args;
Greg Clayton0fffff52010-09-24 05:15:53 +00001892 selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
Greg Clayton90f90cd2010-10-27 04:01:14 +00001893 if (has_arg)
1894 len += 1;
Greg Clayton0fffff52010-09-24 05:15:53 +00001895 }
1896
1897
1898 if (selector_idents.size() == 0)
1899 return 0;
1900
Greg Clayton6beaaa62011-01-17 03:46:26 +00001901 clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
Greg Clayton0fffff52010-09-24 05:15:53 +00001902 selector_idents.data());
1903
1904 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
1905
1906 // Populate the method decl with parameter decls
Sean Callanan78e37602011-01-27 04:42:51 +00001907 const clang::Type *method_type(method_qual_type.getTypePtr());
Greg Clayton0fffff52010-09-24 05:15:53 +00001908
1909 if (method_type == NULL)
1910 return NULL;
1911
Sean Callanan78e37602011-01-27 04:42:51 +00001912 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
Greg Clayton0fffff52010-09-24 05:15:53 +00001913
1914 if (!method_function_prototype)
1915 return NULL;
1916
1917
1918 bool is_variadic = false;
1919 bool is_synthesized = false;
1920 bool is_defined = false;
1921 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
1922
1923 const unsigned num_args = method_function_prototype->getNumArgs();
1924
Greg Clayton6beaaa62011-01-17 03:46:26 +00001925 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001926 SourceLocation(), // beginLoc,
1927 SourceLocation(), // endLoc,
1928 method_selector,
1929 method_function_prototype->getResultType(),
1930 NULL, // TypeSourceInfo *ResultTInfo,
1931 GetDeclContextForType (class_opaque_type),
1932 name[0] == '-',
1933 is_variadic,
1934 is_synthesized,
1935 is_defined,
1936 imp_control,
1937 num_args);
1938
1939
1940 if (objc_method_decl == NULL)
1941 return NULL;
1942
1943 if (num_args > 0)
1944 {
1945 llvm::SmallVector<ParmVarDecl *, 12> params;
1946
1947 for (int param_index = 0; param_index < num_args; ++param_index)
1948 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001949 params.push_back (ParmVarDecl::Create (*ast,
Greg Clayton0fffff52010-09-24 05:15:53 +00001950 objc_method_decl,
1951 SourceLocation(),
1952 NULL, // anonymous
1953 method_function_prototype->getArgType(param_index),
1954 NULL,
1955 SC_Auto,
1956 SC_Auto,
1957 NULL));
1958 }
1959
Greg Clayton6beaaa62011-01-17 03:46:26 +00001960 objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args);
Greg Clayton0fffff52010-09-24 05:15:53 +00001961 }
1962
1963 class_interface_decl->addDecl (objc_method_decl);
1964
1965
1966 return objc_method_decl;
1967}
1968
1969
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001970uint32_t
Greg Clayton73b472d2010-10-27 03:32:59 +00001971ClangASTContext::GetTypeInfo
1972(
1973 clang_type_t clang_type,
Greg Clayton6beaaa62011-01-17 03:46:26 +00001974 clang::ASTContext *ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00001975 clang_type_t *pointee_or_element_clang_type
1976)
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001977{
1978 if (clang_type == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001979 return 0;
1980
1981 if (pointee_or_element_clang_type)
1982 *pointee_or_element_clang_type = NULL;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00001983
1984 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
1985
1986 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1987 switch (type_class)
1988 {
Sean Callanana2424172010-10-25 00:29:48 +00001989 case clang::Type::Builtin:
1990 switch (cast<clang::BuiltinType>(qual_type)->getKind())
1991 {
Sean Callanana2424172010-10-25 00:29:48 +00001992 case clang::BuiltinType::ObjCId:
1993 case clang::BuiltinType::ObjCClass:
Greg Clayton6beaaa62011-01-17 03:46:26 +00001994 if (ast && pointee_or_element_clang_type)
1995 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Sean Callanana2424172010-10-25 00:29:48 +00001996 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00001997
1998 default:
1999 break;
Sean Callanana2424172010-10-25 00:29:48 +00002000 }
2001 return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002002
2003 case clang::Type::BlockPointer:
2004 if (pointee_or_element_clang_type)
2005 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2006 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
2007
Greg Clayton49462ea2011-01-15 02:52:14 +00002008 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002009
2010 case clang::Type::ConstantArray:
2011 case clang::Type::DependentSizedArray:
2012 case clang::Type::IncompleteArray:
2013 case clang::Type::VariableArray:
2014 if (pointee_or_element_clang_type)
2015 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
2016 return eTypeHasChildren | eTypeIsArray;
2017
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002018 case clang::Type::DependentName: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002019 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
2020 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
2021 case clang::Type::Decltype: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002022
2023 case clang::Type::Enum:
2024 if (pointee_or_element_clang_type)
2025 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
2026 return eTypeIsEnumeration | eTypeHasValue;
2027
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002028 case clang::Type::Elaborated: return 0;
2029 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector;
2030 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
2031 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002032 case clang::Type::InjectedClassName: return 0;
Greg Clayton73b472d2010-10-27 03:32:59 +00002033
2034 case clang::Type::LValueReference:
2035 case clang::Type::RValueReference:
2036 if (pointee_or_element_clang_type)
2037 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
2038 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
2039
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002040 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
Greg Clayton73b472d2010-10-27 03:32:59 +00002041
2042 case clang::Type::ObjCObjectPointer:
2043 if (pointee_or_element_clang_type)
2044 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2045 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
2046
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002047 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
2048 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
Greg Clayton73b472d2010-10-27 03:32:59 +00002049
2050 case clang::Type::Pointer:
2051 if (pointee_or_element_clang_type)
2052 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
2053 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
2054
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002055 case clang::Type::Record:
2056 if (qual_type->getAsCXXRecordDecl())
2057 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
2058 else
2059 return eTypeHasChildren | eTypeIsStructUnion;
2060 break;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002061 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
2062 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
2063 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
Greg Clayton73b472d2010-10-27 03:32:59 +00002064
2065 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002066 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00002067 ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002068 pointee_or_element_clang_type);
2069
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002070 case clang::Type::TypeOfExpr: return 0;
2071 case clang::Type::TypeOf: return 0;
2072 case clang::Type::UnresolvedUsing: return 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002073 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector;
2074 default: return 0;
2075 }
2076 return 0;
2077}
2078
Greg Clayton9e409562010-07-28 02:04:09 +00002079
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002080#pragma mark Aggregate Types
2081
2082bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00002083ClangASTContext::IsAggregateType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002084{
2085 if (clang_type == NULL)
2086 return false;
2087
2088 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
2089
Greg Clayton737b9322010-09-13 03:32:57 +00002090 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2091 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002092 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002093 case clang::Type::IncompleteArray:
2094 case clang::Type::VariableArray:
2095 case clang::Type::ConstantArray:
2096 case clang::Type::ExtVector:
2097 case clang::Type::Vector:
2098 case clang::Type::Record:
Greg Clayton9e409562010-07-28 02:04:09 +00002099 case clang::Type::ObjCObject:
2100 case clang::Type::ObjCInterface:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002101 return true;
2102
Greg Claytone1a916a2010-07-21 22:12:05 +00002103 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00002104 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002105
2106 default:
2107 break;
2108 }
2109 // The clang type does have a value
2110 return false;
2111}
2112
2113uint32_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00002114ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002115{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002116 if (clang_type == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002117 return 0;
2118
2119 uint32_t num_children = 0;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002120 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00002121 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2122 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002123 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002124 case clang::Type::Builtin:
2125 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2126 {
Greg Clayton73b472d2010-10-27 03:32:59 +00002127 case clang::BuiltinType::ObjCId: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002128 case clang::BuiltinType::ObjCClass: // child is Class
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002129 num_children = 1;
Greg Clayton73b472d2010-10-27 03:32:59 +00002130 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002131
2132 default:
2133 break;
2134 }
2135 break;
Greg Clayton54979cd2010-12-15 05:08:08 +00002136
Greg Clayton49462ea2011-01-15 02:52:14 +00002137 case clang::Type::Complex: return 0;
Greg Clayton54979cd2010-12-15 05:08:08 +00002138
Greg Claytone1a916a2010-07-21 22:12:05 +00002139 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002140 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002141 {
2142 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2143 const RecordDecl *record_decl = record_type->getDecl();
2144 assert(record_decl);
2145 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2146 if (cxx_record_decl)
2147 {
2148 if (omit_empty_base_classes)
2149 {
2150 // Check each base classes to see if it or any of its
2151 // base classes contain any fields. This can help
2152 // limit the noise in variable views by not having to
2153 // show base classes that contain no members.
2154 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2155 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2156 base_class != base_class_end;
2157 ++base_class)
2158 {
2159 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2160
2161 // Skip empty base classes
2162 if (RecordHasFields(base_class_decl) == false)
2163 continue;
2164
2165 num_children++;
2166 }
2167 }
2168 else
2169 {
2170 // Include all base classes
2171 num_children += cxx_record_decl->getNumBases();
2172 }
2173
2174 }
2175 RecordDecl::field_iterator field, field_end;
2176 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2177 ++num_children;
2178 }
2179 break;
2180
Greg Clayton9e409562010-07-28 02:04:09 +00002181 case clang::Type::ObjCObject:
2182 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002183 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002184 {
Sean Callanan78e37602011-01-27 04:42:51 +00002185 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002186 assert (objc_class_type);
2187 if (objc_class_type)
2188 {
2189 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2190
2191 if (class_interface_decl)
2192 {
2193
2194 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2195 if (superclass_interface_decl)
2196 {
2197 if (omit_empty_base_classes)
2198 {
2199 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
2200 ++num_children;
2201 }
2202 else
2203 ++num_children;
2204 }
2205
2206 num_children += class_interface_decl->ivar_size();
2207 }
2208 }
2209 }
2210 break;
2211
2212 case clang::Type::ObjCObjectPointer:
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002213 {
Sean Callanan78e37602011-01-27 04:42:51 +00002214 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002215 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002216 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2217 pointee_type.getAsOpaquePtr(),
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002218 omit_empty_base_classes);
2219 // If this type points to a simple type, then it has 1 child
2220 if (num_pointee_children == 0)
2221 num_children = 1;
2222 else
2223 num_children = num_pointee_children;
2224 }
2225 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002226
Greg Claytone1a916a2010-07-21 22:12:05 +00002227 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002228 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2229 break;
2230
Greg Claytone1a916a2010-07-21 22:12:05 +00002231 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002232 {
Sean Callanan78e37602011-01-27 04:42:51 +00002233 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Greg Clayton54979cd2010-12-15 05:08:08 +00002234 QualType pointee_type (pointer_type->getPointeeType());
Greg Clayton6beaaa62011-01-17 03:46:26 +00002235 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2236 pointee_type.getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00002237 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002238 if (num_pointee_children == 0)
Greg Clayton54979cd2010-12-15 05:08:08 +00002239 {
2240 // We have a pointer to a pointee type that claims it has no children.
2241 // We will want to look at
2242 num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
2243 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002244 else
2245 num_children = num_pointee_children;
2246 }
2247 break;
2248
Greg Clayton73b472d2010-10-27 03:32:59 +00002249 case clang::Type::LValueReference:
2250 case clang::Type::RValueReference:
2251 {
Sean Callanan78e37602011-01-27 04:42:51 +00002252 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002253 QualType pointee_type = reference_type->getPointeeType();
Greg Clayton6beaaa62011-01-17 03:46:26 +00002254 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
2255 pointee_type.getAsOpaquePtr(),
Greg Clayton73b472d2010-10-27 03:32:59 +00002256 omit_empty_base_classes);
2257 // If this type points to a simple type, then it has 1 child
2258 if (num_pointee_children == 0)
2259 num_children = 1;
2260 else
2261 num_children = num_pointee_children;
2262 }
2263 break;
2264
2265
Greg Claytone1a916a2010-07-21 22:12:05 +00002266 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002267 num_children = ClangASTContext::GetNumChildren (ast,
2268 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
2269 omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002270 break;
2271
2272 default:
2273 break;
2274 }
2275 return num_children;
2276}
2277
Greg Clayton54979cd2010-12-15 05:08:08 +00002278// If a pointer to a pointee type (the clang_type arg) says that it has no
2279// children, then we either need to trust it, or override it and return a
2280// different result. For example, an "int *" has one child that is an integer,
2281// but a function pointer doesn't have any children. Likewise if a Record type
2282// claims it has no children, then there really is nothing to show.
2283uint32_t
2284ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
2285{
2286 if (clang_type == NULL)
2287 return 0;
2288
2289 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
2290 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2291 switch (type_class)
2292 {
Greg Clayton97a43712011-01-08 22:26:47 +00002293 case clang::Type::Builtin:
2294 switch (cast<clang::BuiltinType>(qual_type)->getKind())
2295 {
2296 case clang::BuiltinType::Void:
2297 case clang::BuiltinType::NullPtr:
2298 return 0;
2299 case clang::BuiltinType::Bool:
2300 case clang::BuiltinType::Char_U:
2301 case clang::BuiltinType::UChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002302 case clang::BuiltinType::WChar_U:
Greg Clayton97a43712011-01-08 22:26:47 +00002303 case clang::BuiltinType::Char16:
2304 case clang::BuiltinType::Char32:
2305 case clang::BuiltinType::UShort:
2306 case clang::BuiltinType::UInt:
2307 case clang::BuiltinType::ULong:
2308 case clang::BuiltinType::ULongLong:
2309 case clang::BuiltinType::UInt128:
2310 case clang::BuiltinType::Char_S:
2311 case clang::BuiltinType::SChar:
Sean Callanan2c777c42011-01-18 23:32:05 +00002312 case clang::BuiltinType::WChar_S:
Greg Clayton97a43712011-01-08 22:26:47 +00002313 case clang::BuiltinType::Short:
2314 case clang::BuiltinType::Int:
2315 case clang::BuiltinType::Long:
2316 case clang::BuiltinType::LongLong:
2317 case clang::BuiltinType::Int128:
2318 case clang::BuiltinType::Float:
2319 case clang::BuiltinType::Double:
2320 case clang::BuiltinType::LongDouble:
2321 case clang::BuiltinType::Dependent:
2322 case clang::BuiltinType::Overload:
2323 case clang::BuiltinType::UndeducedAuto:
2324 case clang::BuiltinType::ObjCId:
2325 case clang::BuiltinType::ObjCClass:
2326 case clang::BuiltinType::ObjCSel:
2327 return 1;
2328 }
2329 break;
2330
Greg Clayton49462ea2011-01-15 02:52:14 +00002331 case clang::Type::Complex: return 1;
Greg Clayton54979cd2010-12-15 05:08:08 +00002332 case clang::Type::Pointer: return 1;
2333 case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
2334 case clang::Type::LValueReference: return 1;
2335 case clang::Type::RValueReference: return 1;
2336 case clang::Type::MemberPointer: return 0;
2337 case clang::Type::ConstantArray: return 0;
2338 case clang::Type::IncompleteArray: return 0;
2339 case clang::Type::VariableArray: return 0;
2340 case clang::Type::DependentSizedArray: return 0;
2341 case clang::Type::DependentSizedExtVector: return 0;
2342 case clang::Type::Vector: return 0;
2343 case clang::Type::ExtVector: return 0;
2344 case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
2345 case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
2346 case clang::Type::UnresolvedUsing: return 0;
2347 case clang::Type::Paren: return 0;
2348 case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
2349 case clang::Type::TypeOfExpr: return 0;
2350 case clang::Type::TypeOf: return 0;
2351 case clang::Type::Decltype: return 0;
2352 case clang::Type::Record: return 0;
2353 case clang::Type::Enum: return 1;
2354 case clang::Type::Elaborated: return 1;
2355 case clang::Type::TemplateTypeParm: return 1;
2356 case clang::Type::SubstTemplateTypeParm: return 1;
2357 case clang::Type::TemplateSpecialization: return 1;
2358 case clang::Type::InjectedClassName: return 0;
2359 case clang::Type::DependentName: return 1;
2360 case clang::Type::DependentTemplateSpecialization: return 1;
2361 case clang::Type::ObjCObject: return 0;
2362 case clang::Type::ObjCInterface: return 0;
2363 case clang::Type::ObjCObjectPointer: return 1;
2364 default:
2365 break;
2366 }
2367 return 0;
2368}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002369
Greg Clayton1be10fc2010-09-29 01:12:09 +00002370clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002371ClangASTContext::GetChildClangTypeAtIndex
2372(
2373 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002374 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002375 uint32_t idx,
2376 bool transparent_pointers,
2377 bool omit_empty_base_classes,
2378 std::string& child_name,
2379 uint32_t &child_byte_size,
2380 int32_t &child_byte_offset,
2381 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002382 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002383 bool &child_is_base_class,
2384 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002385)
2386{
2387 if (parent_clang_type)
2388
2389 return GetChildClangTypeAtIndex (getASTContext(),
2390 parent_name,
2391 parent_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,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002399 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002400 child_is_base_class,
2401 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002402 return NULL;
2403}
2404
Greg Clayton1be10fc2010-09-29 01:12:09 +00002405clang_type_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002406ClangASTContext::GetChildClangTypeAtIndex
2407(
Greg Clayton6beaaa62011-01-17 03:46:26 +00002408 ASTContext *ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002409 const char *parent_name,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002410 clang_type_t parent_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002411 uint32_t idx,
2412 bool transparent_pointers,
2413 bool omit_empty_base_classes,
2414 std::string& child_name,
2415 uint32_t &child_byte_size,
2416 int32_t &child_byte_offset,
2417 uint32_t &child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002418 uint32_t &child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002419 bool &child_is_base_class,
2420 bool &child_is_deref_of_parent
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002421)
2422{
2423 if (parent_clang_type == NULL)
2424 return NULL;
2425
Greg Clayton6beaaa62011-01-17 03:46:26 +00002426 if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002427 {
2428 uint32_t bit_offset;
2429 child_bitfield_bit_size = 0;
2430 child_bitfield_bit_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002431 child_is_base_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002432 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00002433 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
2434 switch (parent_type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002435 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002436 case clang::Type::Builtin:
2437 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
2438 {
2439 case clang::BuiltinType::ObjCId:
2440 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00002441 child_name = "isa";
Greg Clayton6beaaa62011-01-17 03:46:26 +00002442 child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
2443 return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002444
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002445 default:
2446 break;
2447 }
2448 break;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002449
Greg Claytone1a916a2010-07-21 22:12:05 +00002450 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002451 if (GetCompleteQualType (ast, parent_qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002452 {
2453 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
2454 const RecordDecl *record_decl = record_type->getDecl();
2455 assert(record_decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00002456 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002457 uint32_t child_idx = 0;
2458
2459 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2460 if (cxx_record_decl)
2461 {
2462 // We might have base classes to print out first
2463 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2464 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2465 base_class != base_class_end;
2466 ++base_class)
2467 {
2468 const CXXRecordDecl *base_class_decl = NULL;
2469
2470 // Skip empty base classes
2471 if (omit_empty_base_classes)
2472 {
2473 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2474 if (RecordHasFields(base_class_decl) == false)
2475 continue;
2476 }
2477
2478 if (idx == child_idx)
2479 {
2480 if (base_class_decl == NULL)
2481 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2482
2483
2484 if (base_class->isVirtual())
Greg Clayton6ed95942011-01-22 07:12:45 +00002485 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002486 else
Greg Clayton6ed95942011-01-22 07:12:45 +00002487 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002488
2489 // Base classes should be a multiple of 8 bits in size
2490 assert (bit_offset % 8 == 0);
2491 child_byte_offset = bit_offset/8;
2492 std::string base_class_type_name(base_class->getType().getAsString());
2493
2494 child_name.assign(base_class_type_name.c_str());
2495
Greg Clayton6beaaa62011-01-17 03:46:26 +00002496 uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002497
2498 // Base classes biut sizes should be a multiple of 8 bits in size
2499 assert (clang_type_info_bit_size % 8 == 0);
2500 child_byte_size = clang_type_info_bit_size / 8;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002501 child_is_base_class = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002502 return base_class->getType().getAsOpaquePtr();
2503 }
2504 // We don't increment the child index in the for loop since we might
2505 // be skipping empty base classes
2506 ++child_idx;
2507 }
2508 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002509 // Make sure index is in range...
2510 uint32_t field_idx = 0;
2511 RecordDecl::field_iterator field, field_end;
2512 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
2513 {
2514 if (idx == child_idx)
2515 {
2516 // Print the member type if requested
2517 // Print the member name and equal sign
2518 child_name.assign(field->getNameAsString().c_str());
2519
2520 // Figure out the type byte size (field_type_info.first) and
2521 // alignment (field_type_info.second) from the AST context.
Greg Clayton6beaaa62011-01-17 03:46:26 +00002522 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
Greg Claytonc982c762010-07-09 20:39:50 +00002523 assert(field_idx < record_layout.getFieldCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002524
2525 child_byte_size = field_type_info.first / 8;
2526
2527 // Figure out the field offset within the current struct/union/class type
2528 bit_offset = record_layout.getFieldOffset (field_idx);
2529 child_byte_offset = bit_offset / 8;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002530 if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002531 child_bitfield_bit_offset = bit_offset % 8;
2532
2533 return field->getType().getAsOpaquePtr();
2534 }
2535 }
2536 }
2537 break;
2538
Greg Clayton9e409562010-07-28 02:04:09 +00002539 case clang::Type::ObjCObject:
2540 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00002541 if (GetCompleteQualType (ast, parent_qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00002542 {
Sean Callanan78e37602011-01-27 04:42:51 +00002543 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002544 assert (objc_class_type);
2545 if (objc_class_type)
2546 {
2547 uint32_t child_idx = 0;
2548 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2549
2550 if (class_interface_decl)
2551 {
2552
Greg Clayton6beaaa62011-01-17 03:46:26 +00002553 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
Greg Clayton9e409562010-07-28 02:04:09 +00002554 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2555 if (superclass_interface_decl)
2556 {
2557 if (omit_empty_base_classes)
2558 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002559 if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
Greg Clayton9e409562010-07-28 02:04:09 +00002560 {
2561 if (idx == 0)
2562 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002563 QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
Greg Clayton9e409562010-07-28 02:04:09 +00002564
2565
2566 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
2567
Greg Clayton6beaaa62011-01-17 03:46:26 +00002568 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002569
2570 child_byte_size = ivar_type_info.first / 8;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002571 child_byte_offset = 0;
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002572 child_is_base_class = true;
Greg Clayton9e409562010-07-28 02:04:09 +00002573
2574 return ivar_qual_type.getAsOpaquePtr();
2575 }
2576
2577 ++child_idx;
2578 }
2579 }
2580 else
2581 ++child_idx;
2582 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002583
2584 const uint32_t superclass_idx = child_idx;
Greg Clayton9e409562010-07-28 02:04:09 +00002585
2586 if (idx < (child_idx + class_interface_decl->ivar_size()))
2587 {
2588 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
2589
2590 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
2591 {
2592 if (child_idx == idx)
2593 {
2594 const ObjCIvarDecl* ivar_decl = *ivar_pos;
2595
2596 QualType ivar_qual_type(ivar_decl->getType());
2597
2598 child_name.assign(ivar_decl->getNameAsString().c_str());
2599
Greg Clayton6beaaa62011-01-17 03:46:26 +00002600 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00002601
2602 child_byte_size = ivar_type_info.first / 8;
2603
2604 // Figure out the field offset within the current struct/union/class type
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002605 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
Greg Clayton9e409562010-07-28 02:04:09 +00002606 child_byte_offset = bit_offset / 8;
2607
2608 return ivar_qual_type.getAsOpaquePtr();
2609 }
2610 ++child_idx;
2611 }
2612 }
2613 }
2614 }
2615 }
2616 break;
2617
2618 case clang::Type::ObjCObjectPointer:
2619 {
Sean Callanan78e37602011-01-27 04:42:51 +00002620 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002621 QualType pointee_type = pointer_type->getPointeeType();
2622
2623 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2624 {
Greg Claytone221f822011-01-21 01:59:00 +00002625 child_is_deref_of_parent = false;
2626 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002627 return GetChildClangTypeAtIndex (ast,
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002628 parent_name,
2629 pointer_type->getPointeeType().getAsOpaquePtr(),
2630 idx,
2631 transparent_pointers,
2632 omit_empty_base_classes,
2633 child_name,
2634 child_byte_size,
2635 child_byte_offset,
2636 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002637 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002638 child_is_base_class,
2639 tmp_child_is_deref_of_parent);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002640 }
2641 else
2642 {
Greg Claytone221f822011-01-21 01:59:00 +00002643 child_is_deref_of_parent = true;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002644 if (parent_name)
2645 {
2646 child_name.assign(1, '*');
2647 child_name += parent_name;
2648 }
2649
2650 // We have a pointer to an simple type
2651 if (idx == 0)
2652 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002653 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002654 assert(clang_type_info.first % 8 == 0);
2655 child_byte_size = clang_type_info.first / 8;
2656 child_byte_offset = 0;
2657 return pointee_type.getAsOpaquePtr();
2658 }
2659 }
Greg Clayton9e409562010-07-28 02:04:09 +00002660 }
2661 break;
2662
Greg Claytone1a916a2010-07-21 22:12:05 +00002663 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002664 {
2665 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
2666 const uint64_t element_count = array->getSize().getLimitedValue();
2667
2668 if (idx < element_count)
2669 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002670 if (GetCompleteQualType (ast, array->getElementType()))
2671 {
2672 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002673
Greg Clayton6beaaa62011-01-17 03:46:26 +00002674 char element_name[64];
2675 ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002676
Greg Clayton6beaaa62011-01-17 03:46:26 +00002677 child_name.assign(element_name);
2678 assert(field_type_info.first % 8 == 0);
2679 child_byte_size = field_type_info.first / 8;
2680 child_byte_offset = idx * child_byte_size;
2681 return array->getElementType().getAsOpaquePtr();
2682 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002683 }
2684 }
2685 break;
2686
Greg Claytone1a916a2010-07-21 22:12:05 +00002687 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002688 {
Sean Callanan78e37602011-01-27 04:42:51 +00002689 const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002690 QualType pointee_type = pointer_type->getPointeeType();
Greg Clayton97a43712011-01-08 22:26:47 +00002691
2692 // Don't dereference "void *" pointers
2693 if (pointee_type->isVoidType())
2694 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002695
2696 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
2697 {
Greg Claytone221f822011-01-21 01:59:00 +00002698 child_is_deref_of_parent = false;
2699 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002700 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002701 parent_name,
2702 pointer_type->getPointeeType().getAsOpaquePtr(),
2703 idx,
2704 transparent_pointers,
2705 omit_empty_base_classes,
2706 child_name,
2707 child_byte_size,
2708 child_byte_offset,
2709 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002710 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002711 child_is_base_class,
2712 tmp_child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002713 }
2714 else
2715 {
Greg Claytone221f822011-01-21 01:59:00 +00002716 child_is_deref_of_parent = true;
2717
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002718 if (parent_name)
2719 {
2720 child_name.assign(1, '*');
2721 child_name += parent_name;
2722 }
2723
2724 // We have a pointer to an simple type
2725 if (idx == 0)
2726 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002727 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002728 assert(clang_type_info.first % 8 == 0);
2729 child_byte_size = clang_type_info.first / 8;
2730 child_byte_offset = 0;
2731 return pointee_type.getAsOpaquePtr();
2732 }
2733 }
2734 }
2735 break;
2736
Greg Clayton73b472d2010-10-27 03:32:59 +00002737 case clang::Type::LValueReference:
2738 case clang::Type::RValueReference:
2739 {
Sean Callanan78e37602011-01-27 04:42:51 +00002740 const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00002741 QualType pointee_type(reference_type->getPointeeType());
2742 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
2743 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
2744 {
Greg Claytone221f822011-01-21 01:59:00 +00002745 child_is_deref_of_parent = false;
2746 bool tmp_child_is_deref_of_parent = false;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002747 return GetChildClangTypeAtIndex (ast,
Greg Clayton73b472d2010-10-27 03:32:59 +00002748 parent_name,
2749 pointee_clang_type,
2750 idx,
2751 transparent_pointers,
2752 omit_empty_base_classes,
2753 child_name,
2754 child_byte_size,
2755 child_byte_offset,
2756 child_bitfield_bit_size,
2757 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002758 child_is_base_class,
2759 tmp_child_is_deref_of_parent);
Greg Clayton73b472d2010-10-27 03:32:59 +00002760 }
2761 else
2762 {
2763 if (parent_name)
2764 {
2765 child_name.assign(1, '&');
2766 child_name += parent_name;
2767 }
2768
2769 // We have a pointer to an simple type
2770 if (idx == 0)
2771 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00002772 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Greg Clayton73b472d2010-10-27 03:32:59 +00002773 assert(clang_type_info.first % 8 == 0);
2774 child_byte_size = clang_type_info.first / 8;
2775 child_byte_offset = 0;
2776 return pointee_type.getAsOpaquePtr();
2777 }
2778 }
2779 }
2780 break;
2781
Greg Claytone1a916a2010-07-21 22:12:05 +00002782 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00002783 return GetChildClangTypeAtIndex (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002784 parent_name,
Sean Callanan48114472010-12-13 01:26:27 +00002785 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002786 idx,
2787 transparent_pointers,
2788 omit_empty_base_classes,
2789 child_name,
2790 child_byte_size,
2791 child_byte_offset,
2792 child_bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +00002793 child_bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +00002794 child_is_base_class,
2795 child_is_deref_of_parent);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002796 break;
2797
2798 default:
2799 break;
2800 }
2801 }
Greg Clayton19503a22010-07-23 15:37:46 +00002802 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002803}
2804
2805static inline bool
2806BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
2807{
Greg Clayton6beaaa62011-01-17 03:46:26 +00002808 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002809}
2810
2811static uint32_t
2812GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
2813{
2814 uint32_t num_bases = 0;
2815 if (cxx_record_decl)
2816 {
2817 if (omit_empty_base_classes)
2818 {
2819 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2820 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2821 base_class != base_class_end;
2822 ++base_class)
2823 {
2824 // Skip empty base classes
2825 if (omit_empty_base_classes)
2826 {
2827 if (BaseSpecifierIsEmpty (base_class))
2828 continue;
2829 }
2830 ++num_bases;
2831 }
2832 }
2833 else
2834 num_bases = cxx_record_decl->getNumBases();
2835 }
2836 return num_bases;
2837}
2838
2839
2840static uint32_t
2841GetIndexForRecordBase
2842(
2843 const RecordDecl *record_decl,
2844 const CXXBaseSpecifier *base_spec,
2845 bool omit_empty_base_classes
2846)
2847{
2848 uint32_t child_idx = 0;
2849
2850 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2851
2852// const char *super_name = record_decl->getNameAsCString();
2853// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
2854// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
2855//
2856 if (cxx_record_decl)
2857 {
2858 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2859 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2860 base_class != base_class_end;
2861 ++base_class)
2862 {
2863 if (omit_empty_base_classes)
2864 {
2865 if (BaseSpecifierIsEmpty (base_class))
2866 continue;
2867 }
2868
2869// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
2870// child_idx,
2871// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2872//
2873//
2874 if (base_class == base_spec)
2875 return child_idx;
2876 ++child_idx;
2877 }
2878 }
2879
2880 return UINT32_MAX;
2881}
2882
2883
2884static uint32_t
2885GetIndexForRecordChild
2886(
2887 const RecordDecl *record_decl,
2888 NamedDecl *canonical_decl,
2889 bool omit_empty_base_classes
2890)
2891{
2892 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
2893
2894// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
2895//
2896//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
2897// if (cxx_record_decl)
2898// {
2899// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2900// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2901// base_class != base_class_end;
2902// ++base_class)
2903// {
2904// if (omit_empty_base_classes)
2905// {
2906// if (BaseSpecifierIsEmpty (base_class))
2907// continue;
2908// }
2909//
2910//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
2911//// record_decl->getNameAsCString(),
2912//// canonical_decl->getNameAsCString(),
2913//// child_idx,
2914//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
2915//
2916//
2917// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
2918// if (curr_base_class_decl == canonical_decl)
2919// {
2920// return child_idx;
2921// }
2922// ++child_idx;
2923// }
2924// }
2925//
2926// const uint32_t num_bases = child_idx;
2927 RecordDecl::field_iterator field, field_end;
2928 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
2929 field != field_end;
2930 ++field, ++child_idx)
2931 {
2932// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
2933// record_decl->getNameAsCString(),
2934// canonical_decl->getNameAsCString(),
2935// child_idx - num_bases,
2936// field->getNameAsCString());
2937
2938 if (field->getCanonicalDecl() == canonical_decl)
2939 return child_idx;
2940 }
2941
2942 return UINT32_MAX;
2943}
2944
2945// Look for a child member (doesn't include base classes, but it does include
2946// their members) in the type hierarchy. Returns an index path into "clang_type"
2947// on how to reach the appropriate member.
2948//
2949// class A
2950// {
2951// public:
2952// int m_a;
2953// int m_b;
2954// };
2955//
2956// class B
2957// {
2958// };
2959//
2960// class C :
2961// public B,
2962// public A
2963// {
2964// };
2965//
2966// If we have a clang type that describes "class C", and we wanted to looked
2967// "m_b" in it:
2968//
2969// With omit_empty_base_classes == false we would get an integer array back with:
2970// { 1, 1 }
2971// The first index 1 is the child index for "class A" within class C
2972// The second index 1 is the child index for "m_b" within class A
2973//
2974// With omit_empty_base_classes == true we would get an integer array back with:
2975// { 0, 1 }
2976// 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)
2977// The second index 1 is the child index for "m_b" within class A
2978
2979size_t
2980ClangASTContext::GetIndexOfChildMemberWithName
2981(
Greg Clayton6beaaa62011-01-17 03:46:26 +00002982 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002983 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002984 const char *name,
2985 bool omit_empty_base_classes,
2986 std::vector<uint32_t>& child_indexes
2987)
2988{
2989 if (clang_type && name && name[0])
2990 {
2991 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00002992 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2993 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002994 {
Greg Claytone1a916a2010-07-21 22:12:05 +00002995 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00002996 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002997 {
2998 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
2999 const RecordDecl *record_decl = record_type->getDecl();
3000
3001 assert(record_decl);
3002 uint32_t child_idx = 0;
3003
3004 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3005
3006 // Try and find a field that matches NAME
3007 RecordDecl::field_iterator field, field_end;
3008 StringRef name_sref(name);
3009 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3010 field != field_end;
3011 ++field, ++child_idx)
3012 {
3013 if (field->getName().equals (name_sref))
3014 {
3015 // We have to add on the number of base classes to this index!
3016 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
3017 return child_indexes.size();
3018 }
3019 }
3020
3021 if (cxx_record_decl)
3022 {
3023 const RecordDecl *parent_record_decl = cxx_record_decl;
3024
3025 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
3026
3027 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
3028 // Didn't find things easily, lets let clang do its thang...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003029 IdentifierInfo & ident_ref = ast->Idents.get(name, name + strlen (name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003030 DeclarationName decl_name(&ident_ref);
3031
3032 CXXBasePaths paths;
3033 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
3034 decl_name.getAsOpaquePtr(),
3035 paths))
3036 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003037 CXXBasePaths::const_paths_iterator path, path_end = paths.end();
3038 for (path = paths.begin(); path != path_end; ++path)
3039 {
3040 const size_t num_path_elements = path->size();
3041 for (size_t e=0; e<num_path_elements; ++e)
3042 {
3043 CXXBasePathElement elem = (*path)[e];
3044
3045 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
3046 if (child_idx == UINT32_MAX)
3047 {
3048 child_indexes.clear();
3049 return 0;
3050 }
3051 else
3052 {
3053 child_indexes.push_back (child_idx);
3054 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
3055 }
3056 }
3057 DeclContext::lookup_iterator named_decl_pos;
3058 for (named_decl_pos = path->Decls.first;
3059 named_decl_pos != path->Decls.second && parent_record_decl;
3060 ++named_decl_pos)
3061 {
3062 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString());
3063
3064 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
3065 if (child_idx == UINT32_MAX)
3066 {
3067 child_indexes.clear();
3068 return 0;
3069 }
3070 else
3071 {
3072 child_indexes.push_back (child_idx);
3073 }
3074 }
3075 }
3076 return child_indexes.size();
3077 }
3078 }
3079
3080 }
3081 break;
3082
Greg Clayton9e409562010-07-28 02:04:09 +00003083 case clang::Type::ObjCObject:
3084 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003085 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003086 {
3087 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003088 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003089 assert (objc_class_type);
3090 if (objc_class_type)
3091 {
3092 uint32_t child_idx = 0;
3093 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3094
3095 if (class_interface_decl)
3096 {
3097 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3098 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3099
Greg Clayton6ba78152010-09-18 02:11:07 +00003100 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
Greg Clayton9e409562010-07-28 02:04:09 +00003101 {
3102 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3103
3104 if (ivar_decl->getName().equals (name_sref))
3105 {
3106 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3107 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3108 ++child_idx;
3109
3110 child_indexes.push_back (child_idx);
3111 return child_indexes.size();
3112 }
3113 }
3114
3115 if (superclass_interface_decl)
3116 {
3117 // The super class index is always zero for ObjC classes,
3118 // so we push it onto the child indexes in case we find
3119 // an ivar in our superclass...
3120 child_indexes.push_back (0);
3121
Greg Clayton6beaaa62011-01-17 03:46:26 +00003122 if (GetIndexOfChildMemberWithName (ast,
3123 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
Greg Clayton9e409562010-07-28 02:04:09 +00003124 name,
3125 omit_empty_base_classes,
3126 child_indexes))
3127 {
3128 // We did find an ivar in a superclass so just
3129 // return the results!
3130 return child_indexes.size();
3131 }
3132
3133 // We didn't find an ivar matching "name" in our
3134 // superclass, pop the superclass zero index that
3135 // we pushed on above.
3136 child_indexes.pop_back();
3137 }
3138 }
3139 }
3140 }
3141 break;
3142
3143 case clang::Type::ObjCObjectPointer:
3144 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003145 return GetIndexOfChildMemberWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003146 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3147 name,
3148 omit_empty_base_classes,
3149 child_indexes);
3150 }
3151 break;
3152
3153
Greg Claytone1a916a2010-07-21 22:12:05 +00003154 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003155 {
3156// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3157// const uint64_t element_count = array->getSize().getLimitedValue();
3158//
3159// if (idx < element_count)
3160// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003161// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003162//
3163// char element_name[32];
3164// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3165//
3166// child_name.assign(element_name);
3167// assert(field_type_info.first % 8 == 0);
3168// child_byte_size = field_type_info.first / 8;
3169// child_byte_offset = idx * child_byte_size;
3170// return array->getElementType().getAsOpaquePtr();
3171// }
3172 }
3173 break;
3174
Greg Claytone1a916a2010-07-21 22:12:05 +00003175// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003176// {
3177// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3178// QualType pointee_type = mem_ptr_type->getPointeeType();
3179//
3180// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3181// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003182// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003183// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3184// name);
3185// }
3186// }
3187// break;
3188//
Greg Claytone1a916a2010-07-21 22:12:05 +00003189 case clang::Type::LValueReference:
3190 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003191 {
Sean Callanan78e37602011-01-27 04:42:51 +00003192 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003193 QualType pointee_type = reference_type->getPointeeType();
3194
3195 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3196 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003197 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003198 reference_type->getPointeeType().getAsOpaquePtr(),
3199 name,
3200 omit_empty_base_classes,
3201 child_indexes);
3202 }
3203 }
3204 break;
3205
Greg Claytone1a916a2010-07-21 22:12:05 +00003206 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003207 {
Sean Callanan78e37602011-01-27 04:42:51 +00003208 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003209 QualType pointee_type = pointer_type->getPointeeType();
3210
3211 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3212 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003213 return GetIndexOfChildMemberWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003214 pointer_type->getPointeeType().getAsOpaquePtr(),
3215 name,
3216 omit_empty_base_classes,
3217 child_indexes);
3218 }
3219 else
3220 {
3221// if (parent_name)
3222// {
3223// child_name.assign(1, '*');
3224// child_name += parent_name;
3225// }
3226//
3227// // We have a pointer to an simple type
3228// if (idx == 0)
3229// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003230// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003231// assert(clang_type_info.first % 8 == 0);
3232// child_byte_size = clang_type_info.first / 8;
3233// child_byte_offset = 0;
3234// return pointee_type.getAsOpaquePtr();
3235// }
3236 }
3237 }
3238 break;
3239
Greg Claytone1a916a2010-07-21 22:12:05 +00003240 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003241 return GetIndexOfChildMemberWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003242 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003243 name,
3244 omit_empty_base_classes,
3245 child_indexes);
3246
3247 default:
3248 break;
3249 }
3250 }
3251 return 0;
3252}
3253
3254
3255// Get the index of the child of "clang_type" whose name matches. This function
3256// doesn't descend into the children, but only looks one level deep and name
3257// matches can include base class names.
3258
3259uint32_t
3260ClangASTContext::GetIndexOfChildWithName
3261(
Greg Clayton6beaaa62011-01-17 03:46:26 +00003262 ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003263 clang_type_t clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003264 const char *name,
3265 bool omit_empty_base_classes
3266)
3267{
3268 if (clang_type && name && name[0])
3269 {
3270 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton9e409562010-07-28 02:04:09 +00003271
Greg Clayton737b9322010-09-13 03:32:57 +00003272 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Greg Clayton9e409562010-07-28 02:04:09 +00003273
Greg Clayton737b9322010-09-13 03:32:57 +00003274 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003275 {
Greg Claytone1a916a2010-07-21 22:12:05 +00003276 case clang::Type::Record:
Greg Claytonc432c192011-01-20 04:18:48 +00003277 if (GetCompleteQualType (ast, qual_type))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003278 {
3279 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
3280 const RecordDecl *record_decl = record_type->getDecl();
3281
3282 assert(record_decl);
3283 uint32_t child_idx = 0;
3284
3285 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
3286
3287 if (cxx_record_decl)
3288 {
3289 CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3290 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3291 base_class != base_class_end;
3292 ++base_class)
3293 {
3294 // Skip empty base classes
3295 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
3296 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
3297 continue;
3298
3299 if (base_class->getType().getAsString().compare (name) == 0)
3300 return child_idx;
3301 ++child_idx;
3302 }
3303 }
3304
3305 // Try and find a field that matches NAME
3306 RecordDecl::field_iterator field, field_end;
3307 StringRef name_sref(name);
3308 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3309 field != field_end;
3310 ++field, ++child_idx)
3311 {
3312 if (field->getName().equals (name_sref))
3313 return child_idx;
3314 }
3315
3316 }
3317 break;
3318
Greg Clayton9e409562010-07-28 02:04:09 +00003319 case clang::Type::ObjCObject:
3320 case clang::Type::ObjCInterface:
Greg Claytonc432c192011-01-20 04:18:48 +00003321 if (GetCompleteQualType (ast, qual_type))
Greg Clayton9e409562010-07-28 02:04:09 +00003322 {
3323 StringRef name_sref(name);
Sean Callanan78e37602011-01-27 04:42:51 +00003324 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
Greg Clayton9e409562010-07-28 02:04:09 +00003325 assert (objc_class_type);
3326 if (objc_class_type)
3327 {
3328 uint32_t child_idx = 0;
3329 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3330
3331 if (class_interface_decl)
3332 {
3333 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3334 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3335
3336 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3337 {
3338 const ObjCIvarDecl* ivar_decl = *ivar_pos;
3339
3340 if (ivar_decl->getName().equals (name_sref))
3341 {
3342 if ((!omit_empty_base_classes && superclass_interface_decl) ||
3343 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
3344 ++child_idx;
3345
3346 return child_idx;
3347 }
3348 }
3349
3350 if (superclass_interface_decl)
3351 {
3352 if (superclass_interface_decl->getName().equals (name_sref))
3353 return 0;
3354 }
3355 }
3356 }
3357 }
3358 break;
3359
3360 case clang::Type::ObjCObjectPointer:
3361 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003362 return GetIndexOfChildWithName (ast,
Greg Clayton9e409562010-07-28 02:04:09 +00003363 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
3364 name,
3365 omit_empty_base_classes);
3366 }
3367 break;
3368
Greg Claytone1a916a2010-07-21 22:12:05 +00003369 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003370 {
3371// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
3372// const uint64_t element_count = array->getSize().getLimitedValue();
3373//
3374// if (idx < element_count)
3375// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003376// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003377//
3378// char element_name[32];
3379// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
3380//
3381// child_name.assign(element_name);
3382// assert(field_type_info.first % 8 == 0);
3383// child_byte_size = field_type_info.first / 8;
3384// child_byte_offset = idx * child_byte_size;
3385// return array->getElementType().getAsOpaquePtr();
3386// }
3387 }
3388 break;
3389
Greg Claytone1a916a2010-07-21 22:12:05 +00003390// case clang::Type::MemberPointerType:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003391// {
3392// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
3393// QualType pointee_type = mem_ptr_type->getPointeeType();
3394//
3395// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3396// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003397// return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003398// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
3399// name);
3400// }
3401// }
3402// break;
3403//
Greg Claytone1a916a2010-07-21 22:12:05 +00003404 case clang::Type::LValueReference:
3405 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003406 {
Sean Callanan78e37602011-01-27 04:42:51 +00003407 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003408 QualType pointee_type = reference_type->getPointeeType();
3409
3410 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3411 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003412 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003413 reference_type->getPointeeType().getAsOpaquePtr(),
3414 name,
3415 omit_empty_base_classes);
3416 }
3417 }
3418 break;
3419
Greg Claytone1a916a2010-07-21 22:12:05 +00003420 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003421 {
Sean Callanan78e37602011-01-27 04:42:51 +00003422 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003423 QualType pointee_type = pointer_type->getPointeeType();
3424
3425 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
3426 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003427 return GetIndexOfChildWithName (ast,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003428 pointer_type->getPointeeType().getAsOpaquePtr(),
3429 name,
3430 omit_empty_base_classes);
3431 }
3432 else
3433 {
3434// if (parent_name)
3435// {
3436// child_name.assign(1, '*');
3437// child_name += parent_name;
3438// }
3439//
3440// // We have a pointer to an simple type
3441// if (idx == 0)
3442// {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003443// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003444// assert(clang_type_info.first % 8 == 0);
3445// child_byte_size = clang_type_info.first / 8;
3446// child_byte_offset = 0;
3447// return pointee_type.getAsOpaquePtr();
3448// }
3449 }
3450 }
3451 break;
3452
Greg Claytone1a916a2010-07-21 22:12:05 +00003453 case clang::Type::Typedef:
Greg Clayton6beaaa62011-01-17 03:46:26 +00003454 return GetIndexOfChildWithName (ast,
Sean Callanan48114472010-12-13 01:26:27 +00003455 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003456 name,
3457 omit_empty_base_classes);
3458
3459 default:
3460 break;
3461 }
3462 }
3463 return UINT32_MAX;
3464}
3465
3466#pragma mark TagType
3467
3468bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003469ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003470{
3471 if (tag_clang_type)
3472 {
3473 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00003474 const clang::Type *clang_type = tag_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003475 if (clang_type)
3476 {
Sean Callanan78e37602011-01-27 04:42:51 +00003477 const TagType *tag_type = dyn_cast<TagType>(clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003478 if (tag_type)
3479 {
3480 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
3481 if (tag_decl)
3482 {
3483 tag_decl->setTagKind ((TagDecl::TagKind)kind);
3484 return true;
3485 }
3486 }
3487 }
3488 }
3489 return false;
3490}
3491
3492
3493#pragma mark DeclContext Functions
3494
3495DeclContext *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003496ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003497{
3498 if (clang_type == NULL)
3499 return NULL;
3500
3501 QualType qual_type(QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003502 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3503 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003504 {
Greg Clayton9e409562010-07-28 02:04:09 +00003505 case clang::Type::FunctionNoProto: break;
3506 case clang::Type::FunctionProto: break;
3507 case clang::Type::IncompleteArray: break;
3508 case clang::Type::VariableArray: break;
3509 case clang::Type::ConstantArray: break;
3510 case clang::Type::ExtVector: break;
3511 case clang::Type::Vector: break;
3512 case clang::Type::Builtin: break;
3513 case clang::Type::BlockPointer: break;
3514 case clang::Type::Pointer: break;
3515 case clang::Type::LValueReference: break;
3516 case clang::Type::RValueReference: break;
3517 case clang::Type::MemberPointer: break;
3518 case clang::Type::Complex: break;
3519 case clang::Type::ObjCObject: break;
3520 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
3521 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
3522 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
3523 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
Sean Callanan48114472010-12-13 01:26:27 +00003524 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003525
Greg Clayton9e409562010-07-28 02:04:09 +00003526 case clang::Type::TypeOfExpr: break;
3527 case clang::Type::TypeOf: break;
3528 case clang::Type::Decltype: break;
3529 //case clang::Type::QualifiedName: break;
3530 case clang::Type::TemplateSpecialization: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003531 }
3532 // No DeclContext in this type...
3533 return NULL;
3534}
3535
3536#pragma mark Namespace Declarations
3537
3538NamespaceDecl *
3539ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx)
3540{
3541 // TODO: Do something intelligent with the Declaration object passed in
3542 // like maybe filling in the SourceLocation with it...
3543 if (name)
3544 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003545 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003546 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00003547 decl_ctx = ast->getTranslationUnitDecl();
3548 return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), &ast->Idents.get(name));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003549 }
3550 return NULL;
3551}
3552
3553
3554#pragma mark Function Types
3555
3556FunctionDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003557ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003558{
3559 if (name)
3560 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003561 ASTContext *ast = getASTContext();
3562 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003563
3564 if (name && name[0])
3565 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003566 return FunctionDecl::Create(*ast,
3567 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003568 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003569 DeclarationName (&ast->Idents.get(name)),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003570 QualType::getFromOpaquePtr(function_clang_type),
3571 NULL,
3572 (FunctionDecl::StorageClass)storage,
3573 (FunctionDecl::StorageClass)storage,
3574 is_inline);
3575 }
3576 else
3577 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003578 return FunctionDecl::Create(*ast,
3579 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003580 SourceLocation(),
3581 DeclarationName (),
3582 QualType::getFromOpaquePtr(function_clang_type),
3583 NULL,
3584 (FunctionDecl::StorageClass)storage,
3585 (FunctionDecl::StorageClass)storage,
3586 is_inline);
3587 }
3588 }
3589 return NULL;
3590}
3591
Greg Clayton1be10fc2010-09-29 01:12:09 +00003592clang_type_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00003593ClangASTContext::CreateFunctionType (ASTContext *ast,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003594 clang_type_t result_type,
3595 clang_type_t *args,
Sean Callananc81256a2010-09-16 20:40:25 +00003596 unsigned num_args,
3597 bool is_variadic,
3598 unsigned type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003599{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003600 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003601 std::vector<QualType> qual_type_args;
3602 for (unsigned i=0; i<num_args; ++i)
3603 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
3604
3605 // TODO: Detect calling convention in DWARF?
Sean Callanan2c777c42011-01-18 23:32:05 +00003606 FunctionProtoType::ExtProtoInfo proto_info;
3607 proto_info.Variadic = is_variadic;
3608 proto_info.HasExceptionSpec = false;
3609 proto_info.HasAnyExceptionSpec = false;
3610 proto_info.TypeQuals = type_quals;
3611 proto_info.NumExceptions = 0;
3612 proto_info.Exceptions = NULL;
3613
Greg Clayton6beaaa62011-01-17 03:46:26 +00003614 return ast->getFunctionType(QualType::getFromOpaquePtr(result_type),
Greg Clayton471b31c2010-07-20 22:52:08 +00003615 qual_type_args.empty() ? NULL : &qual_type_args.front(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003616 qual_type_args.size(),
Sean Callanan2c777c42011-01-18 23:32:05 +00003617 proto_info).getAsOpaquePtr(); // NoReturn);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003618}
3619
3620ParmVarDecl *
Greg Clayton1be10fc2010-09-29 01:12:09 +00003621ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003622{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003623 ASTContext *ast = getASTContext();
3624 assert (ast != NULL);
3625 return ParmVarDecl::Create(*ast,
3626 ast->getTranslationUnitDecl(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003627 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003628 name && name[0] ? &ast->Idents.get(name) : NULL,
Sean Callananc81256a2010-09-16 20:40:25 +00003629 QualType::getFromOpaquePtr(param_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003630 NULL,
3631 (VarDecl::StorageClass)storage,
3632 (VarDecl::StorageClass)storage,
3633 0);
3634}
3635
3636void
3637ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
3638{
3639 if (function_decl)
3640 function_decl->setParams (params, num_params);
3641}
3642
3643
3644#pragma mark Array Types
3645
Greg Clayton1be10fc2010-09-29 01:12:09 +00003646clang_type_t
3647ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003648{
3649 if (element_type)
3650 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00003651 ASTContext *ast = getASTContext();
3652 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003653 llvm::APInt ap_element_count (64, element_count);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003654 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003655 ap_element_count,
3656 ArrayType::Normal,
3657 0).getAsOpaquePtr(); // ElemQuals
3658 }
3659 return NULL;
3660}
3661
3662
3663#pragma mark TagDecl
3664
3665bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003666ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003667{
3668 if (clang_type)
3669 {
3670 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Sean Callanan78e37602011-01-27 04:42:51 +00003671 const clang::Type *t = qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003672 if (t)
3673 {
Sean Callanan78e37602011-01-27 04:42:51 +00003674 const TagType *tag_type = dyn_cast<TagType>(t);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003675 if (tag_type)
3676 {
3677 TagDecl *tag_decl = tag_type->getDecl();
3678 if (tag_decl)
3679 {
3680 tag_decl->startDefinition();
3681 return true;
3682 }
3683 }
3684 }
3685 }
3686 return false;
3687}
3688
3689bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003690ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003691{
3692 if (clang_type)
3693 {
3694 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton14372242010-09-29 03:44:17 +00003695
3696 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3697
3698 if (cxx_record_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003699 {
Greg Clayton14372242010-09-29 03:44:17 +00003700 cxx_record_decl->completeDefinition();
3701
3702 return true;
3703 }
3704
Sean Callanan78e37602011-01-27 04:42:51 +00003705 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
Sean Callanana2424172010-10-25 00:29:48 +00003706
3707 if (objc_class_type)
3708 {
3709 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3710
3711 class_interface_decl->setForwardDecl(false);
3712 }
3713
Greg Clayton14372242010-09-29 03:44:17 +00003714 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
3715
3716 if (enum_type)
3717 {
3718 EnumDecl *enum_decl = enum_type->getDecl();
3719
3720 if (enum_decl)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003721 {
Greg Clayton14372242010-09-29 03:44:17 +00003722 /// TODO This really needs to be fixed.
3723
3724 unsigned NumPositiveBits = 1;
3725 unsigned NumNegativeBits = 0;
3726
Greg Clayton6beaaa62011-01-17 03:46:26 +00003727 ASTContext *ast = getASTContext();
Greg Claytone02b8502010-10-12 04:29:14 +00003728
3729 QualType promotion_qual_type;
3730 // If the enum integer type is less than an integer in bit width,
3731 // then we must promote it to an integer size.
Greg Clayton6beaaa62011-01-17 03:46:26 +00003732 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
Greg Claytone02b8502010-10-12 04:29:14 +00003733 {
3734 if (enum_decl->getIntegerType()->isSignedIntegerType())
Greg Clayton6beaaa62011-01-17 03:46:26 +00003735 promotion_qual_type = ast->IntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003736 else
Greg Clayton6beaaa62011-01-17 03:46:26 +00003737 promotion_qual_type = ast->UnsignedIntTy;
Greg Claytone02b8502010-10-12 04:29:14 +00003738 }
3739 else
3740 promotion_qual_type = enum_decl->getIntegerType();
3741
3742 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
Greg Clayton14372242010-09-29 03:44:17 +00003743 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003744 }
3745 }
3746 }
3747 return false;
3748}
3749
3750
3751#pragma mark Enumeration Types
3752
Greg Clayton1be10fc2010-09-29 01:12:09 +00003753clang_type_t
Greg Claytonca512b32011-01-14 04:54:56 +00003754ClangASTContext::CreateEnumerationType
3755(
3756 const char *name,
3757 DeclContext *decl_ctx,
3758 const Declaration &decl,
3759 clang_type_t integer_qual_type
3760)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003761{
3762 // TODO: Do something intelligent with the Declaration object passed in
3763 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003764 ASTContext *ast = getASTContext();
3765 assert (ast != NULL);
Greg Claytone02b8502010-10-12 04:29:14 +00003766
3767 // TODO: ask about these...
3768// const bool IsScoped = false;
3769// const bool IsFixed = false;
3770
Greg Clayton6beaaa62011-01-17 03:46:26 +00003771 EnumDecl *enum_decl = EnumDecl::Create (*ast,
Greg Claytonca512b32011-01-14 04:54:56 +00003772 decl_ctx,
Greg Claytone02b8502010-10-12 04:29:14 +00003773 SourceLocation(),
Greg Clayton6beaaa62011-01-17 03:46:26 +00003774 name && name[0] ? &ast->Idents.get(name) : NULL,
Greg Claytone02b8502010-10-12 04:29:14 +00003775 SourceLocation(),
Sean Callanan48114472010-12-13 01:26:27 +00003776 NULL,
3777 false, // IsScoped
3778 false, // IsScopedUsingClassTag
3779 false); // IsFixed
Sean Callanan2652ad22011-01-18 01:03:44 +00003780
3781
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003782 if (enum_decl)
Greg Clayton83ff3892010-09-12 23:17:56 +00003783 {
3784 // TODO: check if we should be setting the promotion type too?
3785 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00003786
3787 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
3788
Greg Clayton6beaaa62011-01-17 03:46:26 +00003789 return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
Greg Clayton83ff3892010-09-12 23:17:56 +00003790 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003791 return NULL;
3792}
3793
Greg Clayton1be10fc2010-09-29 01:12:09 +00003794clang_type_t
3795ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
3796{
3797 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3798
Sean Callanan78e37602011-01-27 04:42:51 +00003799 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003800 if (clang_type)
3801 {
3802 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3803 if (enum_type)
3804 {
3805 EnumDecl *enum_decl = enum_type->getDecl();
3806 if (enum_decl)
3807 return enum_decl->getIntegerType().getAsOpaquePtr();
3808 }
3809 }
3810 return NULL;
3811}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003812bool
3813ClangASTContext::AddEnumerationValueToEnumerationType
3814(
Greg Clayton1be10fc2010-09-29 01:12:09 +00003815 clang_type_t enum_clang_type,
3816 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003817 const Declaration &decl,
3818 const char *name,
3819 int64_t enum_value,
3820 uint32_t enum_value_bit_size
3821)
3822{
3823 if (enum_clang_type && enumerator_clang_type && name)
3824 {
3825 // TODO: Do something intelligent with the Declaration object passed in
3826 // like maybe filling in the SourceLocation with it...
Greg Clayton6beaaa62011-01-17 03:46:26 +00003827 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003828 IdentifierTable *identifier_table = getIdentifierTable();
3829
Greg Clayton6beaaa62011-01-17 03:46:26 +00003830 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003831 assert (identifier_table != NULL);
3832 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
3833
Sean Callanan78e37602011-01-27 04:42:51 +00003834 const clang::Type *clang_type = enum_qual_type.getTypePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003835 if (clang_type)
3836 {
3837 const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
3838
3839 if (enum_type)
3840 {
3841 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
3842 enum_llvm_apsint = enum_value;
3843 EnumConstantDecl *enumerator_decl =
Greg Clayton6beaaa62011-01-17 03:46:26 +00003844 EnumConstantDecl::Create (*ast,
3845 enum_type->getDecl(),
3846 SourceLocation(),
3847 name ? &identifier_table->get(name) : NULL, // Identifier
3848 QualType::getFromOpaquePtr(enumerator_clang_type),
3849 NULL,
3850 enum_llvm_apsint);
3851
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003852 if (enumerator_decl)
3853 {
3854 enum_type->getDecl()->addDecl(enumerator_decl);
3855 return true;
3856 }
3857 }
3858 }
3859 }
3860 return false;
3861}
3862
3863#pragma mark Pointers & References
3864
Greg Clayton1be10fc2010-09-29 01:12:09 +00003865clang_type_t
3866ClangASTContext::CreatePointerType (clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003867{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003868 return CreatePointerType (getASTContext(), clang_type);
3869}
3870
3871clang_type_t
3872ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
3873{
3874 if (ast && clang_type)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003875 {
3876 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3877
Greg Clayton737b9322010-09-13 03:32:57 +00003878 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3879 switch (type_class)
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003880 {
3881 case clang::Type::ObjCObject:
3882 case clang::Type::ObjCInterface:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003883 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003884
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003885 default:
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00003886 return ast->getPointerType(qual_type).getAsOpaquePtr();
Greg Clayton5fb47cd2010-07-29 20:06:32 +00003887 }
3888 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003889 return NULL;
3890}
3891
Greg Clayton1be10fc2010-09-29 01:12:09 +00003892clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003893ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
3894 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003895{
3896 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003897 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003898 return NULL;
3899}
3900
Greg Clayton1be10fc2010-09-29 01:12:09 +00003901clang_type_t
Sean Callanan92adcac2011-01-13 08:53:35 +00003902ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
3903 clang_type_t clang_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003904{
3905 if (clang_type)
Sean Callanan92adcac2011-01-13 08:53:35 +00003906 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003907 return NULL;
3908}
3909
Greg Clayton1be10fc2010-09-29 01:12:09 +00003910clang_type_t
3911ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
Greg Clayton9b81a312010-06-12 01:20:30 +00003912{
3913 if (clang_pointee_type && clang_pointee_type)
3914 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
3915 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
3916 return NULL;
3917}
3918
Greg Clayton1a65ae12011-01-25 23:55:37 +00003919uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003920ClangASTContext::GetPointerBitSize ()
3921{
Greg Clayton6beaaa62011-01-17 03:46:26 +00003922 ASTContext *ast = getASTContext();
3923 return ast->getTypeSize(ast->VoidPtrTy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003924}
3925
3926bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003927ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003928{
3929 if (clang_type == NULL)
3930 return false;
3931
3932 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00003933 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3934 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003935 {
Sean Callanana2424172010-10-25 00:29:48 +00003936 case clang::Type::Builtin:
3937 switch (cast<clang::BuiltinType>(qual_type)->getKind())
3938 {
3939 default:
3940 break;
3941 case clang::BuiltinType::ObjCId:
3942 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00003943 return true;
3944 }
3945 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00003946 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003947 if (target_type)
3948 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3949 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003950 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003951 if (target_type)
3952 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3953 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003954 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003955 if (target_type)
3956 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3957 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003958 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003959 if (target_type)
3960 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
3961 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003962 case clang::Type::LValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003963 if (target_type)
3964 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3965 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003966 case clang::Type::RValueReference:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003967 if (target_type)
3968 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
3969 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00003970 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00003971 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003972 default:
3973 break;
3974 }
3975 return false;
3976}
3977
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003978bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003979ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003980{
3981 if (!clang_type)
3982 return false;
3983
3984 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
3985 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
3986
3987 if (builtin_type)
3988 {
3989 if (builtin_type->isInteger())
3990 is_signed = builtin_type->isSignedInteger();
3991
3992 return true;
3993 }
3994
3995 return false;
3996}
3997
3998bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00003999ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004000{
4001 if (clang_type)
4002 {
4003 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton737b9322010-09-13 03:32:57 +00004004 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4005 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004006 {
Sean Callanana2424172010-10-25 00:29:48 +00004007 case clang::Type::Builtin:
4008 switch (cast<clang::BuiltinType>(qual_type)->getKind())
4009 {
4010 default:
4011 break;
4012 case clang::BuiltinType::ObjCId:
4013 case clang::BuiltinType::ObjCClass:
Sean Callanana2424172010-10-25 00:29:48 +00004014 return true;
4015 }
4016 return false;
Greg Claytone1a916a2010-07-21 22:12:05 +00004017 case clang::Type::ObjCObjectPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004018 if (target_type)
4019 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4020 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004021 case clang::Type::BlockPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004022 if (target_type)
4023 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4024 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004025 case clang::Type::Pointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004026 if (target_type)
4027 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4028 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004029 case clang::Type::MemberPointer:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004030 if (target_type)
4031 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
4032 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004033 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004034 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004035 default:
4036 break;
4037 }
4038 }
4039 return false;
4040}
4041
4042bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004043ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004044{
4045 if (clang_type)
4046 {
4047 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4048
4049 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
4050 {
4051 clang::BuiltinType::Kind kind = BT->getKind();
4052 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
4053 {
4054 count = 1;
4055 is_complex = false;
4056 return true;
4057 }
4058 }
4059 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
4060 {
4061 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
4062 {
4063 count = 2;
4064 is_complex = true;
4065 return true;
4066 }
4067 }
4068 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
4069 {
4070 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
4071 {
4072 count = VT->getNumElements();
4073 is_complex = false;
4074 return true;
4075 }
4076 }
4077 }
4078 return false;
4079}
4080
Greg Clayton8f92f0a2010-10-14 22:52:14 +00004081
4082bool
4083ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
4084{
4085 if (clang_type)
4086 {
4087 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4088
4089 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4090 if (cxx_record_decl)
4091 {
4092 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
4093 return true;
4094 }
4095 }
4096 class_name.clear();
4097 return false;
4098}
4099
4100
Greg Clayton0fffff52010-09-24 05:15:53 +00004101bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004102ClangASTContext::IsCXXClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004103{
4104 if (clang_type)
4105 {
4106 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4107 if (qual_type->getAsCXXRecordDecl() != NULL)
4108 return true;
4109 }
4110 return false;
4111}
4112
4113bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004114ClangASTContext::IsObjCClassType (clang_type_t clang_type)
Greg Clayton0fffff52010-09-24 05:15:53 +00004115{
4116 if (clang_type)
4117 {
4118 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4119 if (qual_type->isObjCObjectOrInterfaceType())
4120 return true;
4121 }
4122 return false;
4123}
4124
4125
Greg Clayton73b472d2010-10-27 03:32:59 +00004126bool
4127ClangASTContext::IsCharType (clang_type_t clang_type)
4128{
4129 if (clang_type)
4130 return QualType::getFromOpaquePtr(clang_type)->isCharType();
4131 return false;
4132}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004133
4134bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004135ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004136{
Greg Clayton73b472d2010-10-27 03:32:59 +00004137 clang_type_t pointee_or_element_clang_type = NULL;
4138 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
4139
4140 if (pointee_or_element_clang_type == NULL)
4141 return false;
4142
4143 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004144 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004145 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
4146
4147 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004148 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004149 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4150 if (type_flags.Test (eTypeIsArray))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004151 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004152 // We know the size of the array and it could be a C string
4153 // since it is an array of characters
4154 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
4155 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004156 }
Greg Clayton73b472d2010-10-27 03:32:59 +00004157 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004158 {
Greg Clayton73b472d2010-10-27 03:32:59 +00004159 length = 0;
4160 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004161 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004162
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004163 }
4164 }
4165 return false;
4166}
4167
4168bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004169ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
Greg Clayton737b9322010-09-13 03:32:57 +00004170{
4171 if (clang_type)
4172 {
4173 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4174
4175 if (qual_type->isFunctionPointerType())
4176 return true;
4177
4178 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4179 switch (type_class)
4180 {
4181 case clang::Type::Typedef:
Sean Callanan48114472010-12-13 01:26:27 +00004182 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004183
4184 case clang::Type::LValueReference:
4185 case clang::Type::RValueReference:
4186 {
Sean Callanan78e37602011-01-27 04:42:51 +00004187 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
Greg Clayton737b9322010-09-13 03:32:57 +00004188 if (reference_type)
4189 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
4190 }
4191 break;
4192 }
4193 }
4194 return false;
4195}
4196
Greg Clayton73b472d2010-10-27 03:32:59 +00004197size_t
4198ClangASTContext::GetArraySize (clang_type_t clang_type)
4199{
4200 if (clang_type)
4201 {
Sean Callanan78e37602011-01-27 04:42:51 +00004202 const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
Greg Clayton73b472d2010-10-27 03:32:59 +00004203 if (array)
4204 return array->getSize().getLimitedValue();
4205 }
4206 return 0;
4207}
Greg Clayton737b9322010-09-13 03:32:57 +00004208
4209bool
Greg Clayton1be10fc2010-09-29 01:12:09 +00004210ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004211{
4212 if (!clang_type)
4213 return false;
4214
4215 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4216
Greg Clayton737b9322010-09-13 03:32:57 +00004217 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4218 switch (type_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004219 {
Greg Claytone1a916a2010-07-21 22:12:05 +00004220 case clang::Type::ConstantArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004221 if (member_type)
4222 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4223 if (size)
4224 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX);
4225 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004226 case clang::Type::IncompleteArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004227 if (member_type)
4228 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4229 if (size)
4230 *size = 0;
4231 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004232 case clang::Type::VariableArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004233 if (member_type)
4234 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4235 if (size)
4236 *size = 0;
Greg Clayton03dbf2e2011-02-02 00:52:14 +00004237 return true;
Greg Claytone1a916a2010-07-21 22:12:05 +00004238 case clang::Type::DependentSizedArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004239 if (member_type)
4240 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
4241 if (size)
4242 *size = 0;
4243 return true;
4244 }
4245 return false;
4246}
4247
4248
4249#pragma mark Typedefs
4250
Greg Clayton1be10fc2010-09-29 01:12:09 +00004251clang_type_t
4252ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004253{
4254 if (clang_type)
4255 {
4256 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004257 ASTContext *ast = getASTContext();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004258 IdentifierTable *identifier_table = getIdentifierTable();
Greg Clayton6beaaa62011-01-17 03:46:26 +00004259 assert (ast != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004260 assert (identifier_table != NULL);
4261 if (decl_ctx == NULL)
Greg Clayton6beaaa62011-01-17 03:46:26 +00004262 decl_ctx = ast->getTranslationUnitDecl();
4263 TypedefDecl *decl = TypedefDecl::Create (*ast,
4264 decl_ctx,
4265 SourceLocation(),
4266 name ? &identifier_table->get(name) : NULL, // Identifier
4267 ast->CreateTypeSourceInfo(qual_type));
Sean Callanan2652ad22011-01-18 01:03:44 +00004268
4269 decl->setAccess(AS_public); // TODO respect proper access specifier
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004270
4271 // Get a uniqued QualType for the typedef decl type
Greg Clayton6beaaa62011-01-17 03:46:26 +00004272 return ast->getTypedefType (decl).getAsOpaquePtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004273 }
4274 return NULL;
4275}
4276
4277
4278std::string
Greg Clayton1be10fc2010-09-29 01:12:09 +00004279ClangASTContext::GetTypeName (clang_type_t opaque_qual_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004280{
4281 std::string return_name;
4282
Greg Clayton1be10fc2010-09-29 01:12:09 +00004283 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004284
Greg Clayton1be10fc2010-09-29 01:12:09 +00004285 const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004286 if (typedef_type)
4287 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00004288 const TypedefDecl *typedef_decl = typedef_type->getDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004289 return_name = typedef_decl->getQualifiedNameAsString();
4290 }
4291 else
4292 {
4293 return_name = qual_type.getAsString();
4294 }
4295
4296 return return_name;
4297}
4298
4299// Disable this for now since I can't seem to get a nicely formatted float
4300// out of the APFloat class without just getting the float, double or quad
4301// and then using a formatted print on it which defeats the purpose. We ideally
4302// would like to get perfect string values for any kind of float semantics
4303// so we can support remote targets. The code below also requires a patch to
4304// llvm::APInt.
4305//bool
Greg Clayton6beaaa62011-01-17 03:46:26 +00004306//ClangASTContext::ConvertFloatValueToString (ASTContext *ast, clang_type_t clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004307//{
4308// uint32_t count = 0;
4309// bool is_complex = false;
4310// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4311// {
4312// unsigned num_bytes_per_float = byte_size / count;
4313// unsigned num_bits_per_float = num_bytes_per_float * 8;
4314//
4315// float_str.clear();
4316// uint32_t i;
4317// for (i=0; i<count; i++)
4318// {
4319// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
4320// bool is_ieee = false;
4321// APFloat ap_float(ap_int, is_ieee);
4322// char s[1024];
4323// unsigned int hex_digits = 0;
4324// bool upper_case = false;
4325//
4326// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
4327// {
4328// if (i > 0)
4329// float_str.append(", ");
4330// float_str.append(s);
4331// if (i == 1 && is_complex)
4332// float_str.append(1, 'i');
4333// }
4334// }
4335// return !float_str.empty();
4336// }
4337// return false;
4338//}
4339
4340size_t
Greg Clayton6beaaa62011-01-17 03:46:26 +00004341ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004342{
4343 if (clang_type)
4344 {
4345 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4346 uint32_t count = 0;
4347 bool is_complex = false;
4348 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
4349 {
4350 // TODO: handle complex and vector types
4351 if (count != 1)
4352 return false;
4353
4354 StringRef s_sref(s);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004355 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004356
Greg Clayton6beaaa62011-01-17 03:46:26 +00004357 const uint64_t bit_size = ast->getTypeSize (qual_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004358 const uint64_t byte_size = bit_size / 8;
4359 if (dst_size >= byte_size)
4360 {
4361 if (bit_size == sizeof(float)*8)
4362 {
4363 float float32 = ap_float.convertToFloat();
4364 ::memcpy (dst, &float32, byte_size);
4365 return byte_size;
4366 }
4367 else if (bit_size >= 64)
4368 {
4369 llvm::APInt ap_int(ap_float.bitcastToAPInt());
4370 ::memcpy (dst, ap_int.getRawData(), byte_size);
4371 return byte_size;
4372 }
4373 }
4374 }
4375 }
4376 return 0;
4377}
Sean Callanan6fe64b52010-09-17 02:24:29 +00004378
4379unsigned
Greg Clayton1be10fc2010-09-29 01:12:09 +00004380ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
Sean Callanan6fe64b52010-09-17 02:24:29 +00004381{
4382 assert (clang_type);
4383
4384 QualType qual_type (QualType::getFromOpaquePtr(clang_type));
4385
4386 return qual_type.getQualifiers().getCVRQualifiers();
4387}
Greg Clayton6beaaa62011-01-17 03:46:26 +00004388
4389bool
4390ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
4391{
4392 if (clang_type == NULL)
4393 return false;
4394
Greg Claytonc432c192011-01-20 04:18:48 +00004395 return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
Greg Clayton6beaaa62011-01-17 03:46:26 +00004396}
4397
4398
4399bool
4400ClangASTContext::GetCompleteType (clang_type_t clang_type)
4401{
4402 return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
4403}
4404