ClangASTContext.cpp revision 7bb069b2216523f21fb6a3ce867f2f7278b1b07b
1//===-- 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 10#include "lldb/Symbol/ClangASTContext.h" 11 12// C Includes 13// C++ Includes 14#include <string> 15 16// Other libraries and framework includes 17 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 30#define NDEBUG 31// Need to include assert.h so it is as clang would expect it to be (disabled) 32#include <assert.h> 33#endif 34 35#include "clang/AST/ASTContext.h" 36#include "clang/AST/ASTImporter.h" 37#include "clang/AST/CXXInheritance.h" 38#include "clang/AST/DeclObjC.h" 39#include "clang/AST/RecordLayout.h" 40#include "clang/AST/Type.h" 41#include "clang/Basic/Builtins.h" 42#include "clang/Basic/FileManager.h" 43#include "clang/Basic/FileSystemOptions.h" 44#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" 49 50#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG 51#undef NDEBUG 52#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 56 57#include "lldb/Core/dwarf.h" 58#include "lldb/Core/Flags.h" 59#include "lldb/Core/Log.h" 60 61#include <stdio.h> 62 63using namespace lldb; 64using namespace lldb_private; 65using namespace llvm; 66using namespace clang; 67 68 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 { 78 const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr()); 79 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 { 106 const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type); 107 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 } 121 return is_forward_decl == false; 122 } 123 return true; 124 } 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 139static AccessSpecifier 140ConvertAccessTypeToAccessSpecifier (AccessType access) 141{ 142 switch (access) 143 { 144 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; 149 } 150 return AS_none; 151} 152 153static ObjCIvarDecl::AccessControl 154ConvertAccessTypeToObjCIvarAccessControl (AccessType access) 155{ 156 switch (access) 157 { 158 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; 164 } 165 return ObjCIvarDecl::None; 166} 167 168 169static void 170ParseLangArgs 171( 172 LangOptions &Opts, 173 InputKind IK 174) 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. 181 if (IK == IK_Asm) { 182 Opts.AsmPreprocessor = 1; 183 } else if (IK == IK_ObjC || 184 IK == IK_ObjCXX || 185 IK == IK_PreprocessedObjC || 186 IK == IK_PreprocessedObjCXX) { 187 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) { 195 case IK_None: 196 case IK_AST: 197 assert (!"Invalid input kind!"); 198 case IK_OpenCL: 199 LangStd = LangStandard::lang_opencl; 200 break; 201 case IK_Asm: 202 case IK_C: 203 case IK_PreprocessedC: 204 case IK_ObjC: 205 case IK_PreprocessedObjC: 206 LangStd = LangStandard::lang_gnu99; 207 break; 208 case IK_CXX: 209 case IK_PreprocessedCXX: 210 case IK_ObjCXX: 211 case IK_PreprocessedObjCXX: 212 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") 259 Opts.setVisibilityMode(DefaultVisibility); 260// 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 333 334ClangASTContext::ClangASTContext (const char *target_triple) : 335 m_target_triple(), 336 m_ast_ap(), 337 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(), 344 m_builtins_ap(), 345 m_callback_tag_decl (NULL), 346 m_callback_objc_decl (NULL), 347 m_callback_baton (NULL) 348 349{ 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(); 367 m_ast_ap.reset(); 368} 369 370 371void 372ClangASTContext::Clear() 373{ 374 m_ast_ap.reset(); 375 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 398bool 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 434 435ASTContext * 436ClangASTContext::getASTContext() 437{ 438 if (m_ast_ap.get() == NULL) 439 { 440 m_ast_ap.reset(new ASTContext (*getLanguageOptions(), 441 *getSourceManager(), 442 *getTargetInfo(), 443 *getIdentifierTable(), 444 *getSelectorTable(), 445 *getBuiltinContext(), 446 0)); 447 448 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); 455 } 456 return m_ast_ap.get(); 457} 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()); 481 ParseLangArgs(*m_language_options_ap, IK_ObjCXX); 482// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX); 483 } 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 495clang::FileManager * 496ClangASTContext::getFileManager() 497{ 498 if (m_file_manager_ap.get() == NULL) 499 { 500 clang::FileSystemOptions file_system_options; 501 m_file_manager_ap.reset(new clang::FileManager(file_system_options)); 502 } 503 return m_file_manager_ap.get(); 504} 505 506clang::SourceManager * 507ClangASTContext::getSourceManager() 508{ 509 if (m_source_manager_ap.get() == NULL) 510 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager())); 511 return m_source_manager_ap.get(); 512} 513 514Diagnostic * 515ClangASTContext::getDiagnostic() 516{ 517 if (m_diagnostic_ap.get() == NULL) 518 { 519 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs()); 520 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp)); 521 } 522 return m_diagnostic_ap.get(); 523} 524 525class 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 556TargetOptions * 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 581QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type) 582{ 583 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type); 584 if (qual_type_bit_size == bit_size) 585 return true; 586 return false; 587} 588 589clang_type_t 590ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size) 591{ 592 ASTContext *ast = getASTContext(); 593 594 assert (ast != NULL); 595 596 return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size); 597} 598 599clang_type_t 600ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size) 601{ 602 if (!ast) 603 return NULL; 604 605 switch (encoding) 606 { 607 case eEncodingInvalid: 608 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy)) 609 return ast->VoidPtrTy.getAsOpaquePtr(); 610 break; 611 612 case eEncodingUint: 613 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(); 625 break; 626 627 case eEncodingSint: 628 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(); 640 break; 641 642 case eEncodingIEEE754: 643 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(); 649 break; 650 651 case eEncodingVector: 652 default: 653 break; 654 } 655 656 return NULL; 657} 658 659clang_type_t 660ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size) 661{ 662 ASTContext *ast = getASTContext(); 663 664 #define streq(a,b) strcmp(a,b) == 0 665 assert (ast != NULL); 666 if (ast) 667 { 668 switch (dw_ate) 669 { 670 default: 671 break; 672 673 case DW_ATE_address: 674 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy)) 675 return ast->VoidPtrTy.getAsOpaquePtr(); 676 break; 677 678 case DW_ATE_boolean: 679 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(); 687 break; 688 689 case DW_ATE_lo_user: 690 // This has been seen to mean DW_AT_complex_integer 691 if (::strstr(type_name, "complex")) 692 { 693 clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2); 694 return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr(); 695 } 696 break; 697 698 case DW_ATE_complex_float: 699 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(); 705 else 706 { 707 clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2); 708 return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr(); 709 } 710 break; 711 712 case DW_ATE_float: 713 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(); 719 break; 720 721 case DW_ATE_signed: 722 if (type_name) 723 { 724 if (strstr(type_name, "long long")) 725 { 726 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) 727 return ast->LongLongTy.getAsOpaquePtr(); 728 } 729 else if (strstr(type_name, "long")) 730 { 731 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) 732 return ast->LongTy.getAsOpaquePtr(); 733 } 734 else if (strstr(type_name, "short")) 735 { 736 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) 737 return ast->ShortTy.getAsOpaquePtr(); 738 } 739 else if (strstr(type_name, "char")) 740 { 741 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(); 745 } 746 else if (strstr(type_name, "int")) 747 { 748 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(); 752 } 753 else if (streq(type_name, "wchar_t")) 754 { 755 if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy)) 756 return ast->WCharTy.getAsOpaquePtr(); 757 } 758 else if (streq(type_name, "void")) 759 { 760 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy)) 761 return ast->VoidTy.getAsOpaquePtr(); 762 } 763 } 764 // We weren't able to match up a type name, just search by size 765 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(); 777 break; 778 779 case DW_ATE_signed_char: 780 if (type_name) 781 { 782 if (streq(type_name, "signed char")) 783 { 784 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) 785 return ast->SignedCharTy.getAsOpaquePtr(); 786 } 787 } 788 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(); 792 break; 793 794 case DW_ATE_unsigned: 795 if (type_name) 796 { 797 if (strstr(type_name, "long long")) 798 { 799 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) 800 return ast->UnsignedLongLongTy.getAsOpaquePtr(); 801 } 802 else if (strstr(type_name, "long")) 803 { 804 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) 805 return ast->UnsignedLongTy.getAsOpaquePtr(); 806 } 807 else if (strstr(type_name, "short")) 808 { 809 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) 810 return ast->UnsignedShortTy.getAsOpaquePtr(); 811 } 812 else if (strstr(type_name, "char")) 813 { 814 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) 815 return ast->UnsignedCharTy.getAsOpaquePtr(); 816 } 817 else if (strstr(type_name, "int")) 818 { 819 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(); 823 } 824 } 825 // We weren't able to match up a type name, just search by size 826 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(); 838 break; 839 840 case DW_ATE_unsigned_char: 841 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) 842 return ast->UnsignedCharTy.getAsOpaquePtr(); 843 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) 844 return ast->UnsignedShortTy.getAsOpaquePtr(); 845 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 857clang_type_t 858ClangASTContext::GetBuiltInType_void(ASTContext *ast) 859{ 860 return ast->VoidTy.getAsOpaquePtr(); 861} 862 863clang_type_t 864ClangASTContext::GetBuiltInType_bool() 865{ 866 return getASTContext()->BoolTy.getAsOpaquePtr(); 867} 868 869clang_type_t 870ClangASTContext::GetBuiltInType_objc_id() 871{ 872 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr(); 873} 874 875clang_type_t 876ClangASTContext::GetBuiltInType_objc_Class() 877{ 878 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr(); 879} 880 881clang_type_t 882ClangASTContext::GetBuiltInType_objc_selector() 883{ 884 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr(); 885} 886 887clang_type_t 888ClangASTContext::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 898clang_type_t 899ClangASTContext::GetVoidPtrType (bool is_const) 900{ 901 return GetVoidPtrType(getASTContext(), is_const); 902} 903 904clang_type_t 905ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const) 906{ 907 QualType void_ptr_type(ast->VoidPtrTy); 908 909 if (is_const) 910 void_ptr_type.addConst(); 911 912 return void_ptr_type.getAsOpaquePtr(); 913} 914 915clang_type_t 916ClangASTContext::CopyType (ASTContext *dst_ast, 917 ASTContext *src_ast, 918 clang_type_t clang_type) 919{ 920 FileSystemOptions file_system_options; 921 FileManager file_manager (file_system_options); 922 ASTImporter importer(*dst_ast, file_manager, 923 *src_ast, file_manager, 924 false); 925 926 QualType src (QualType::getFromOpaquePtr(clang_type)); 927 QualType dst (importer.Import(src)); 928 929 return dst.getAsOpaquePtr(); 930} 931 932 933clang::Decl * 934ClangASTContext::CopyDecl (ASTContext *dst_ast, 935 ASTContext *src_ast, 936 clang::Decl *source_decl) 937{ 938 FileSystemOptions file_system_options; 939 FileManager file_manager (file_system_options); 940 ASTImporter importer(*dst_ast, file_manager, 941 *src_ast, file_manager, 942 false); 943 944 return importer.Import(source_decl); 945} 946 947bool 948ClangASTContext::AreTypesSame(ASTContext *ast, 949 clang_type_t type1, 950 clang_type_t type2) 951{ 952 return ast->hasSameType(QualType::getFromOpaquePtr(type1), 953 QualType::getFromOpaquePtr(type2)); 954} 955 956#pragma mark CVR modifiers 957 958clang_type_t 959ClangASTContext::AddConstModifier (clang_type_t clang_type) 960{ 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 970clang_type_t 971ClangASTContext::AddRestrictModifier (clang_type_t clang_type) 972{ 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 982clang_type_t 983ClangASTContext::AddVolatileModifier (clang_type_t clang_type) 984{ 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 994 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 1017#pragma mark Structure, Unions, Classes 1018 1019clang_type_t 1020ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language) 1021{ 1022 ASTContext *ast = getASTContext(); 1023 assert (ast != NULL); 1024 1025 if (decl_ctx == NULL) 1026 decl_ctx = ast->getTranslationUnitDecl(); 1027 1028 1029 if (language == eLanguageTypeObjC) 1030 { 1031 bool isForwardDecl = true; 1032 bool isInternal = false; 1033 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal); 1034 } 1035 1036 // 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. 1041 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast, 1042 (TagDecl::TagKind)kind, 1043 decl_ctx, 1044 SourceLocation(), 1045 name && name[0] ? &ast->Idents.get(name) : NULL); 1046 1047 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); 1067 cxx_record_decl->setHasExternalVisibleStorage (has_extern); 1068 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); 1079 enum_decl->setHasExternalVisibleStorage (has_extern); 1080 return true; 1081 } 1082 } 1083 break; 1084 1085 case clang::Type::ObjCObject: 1086 case clang::Type::ObjCInterface: 1087 { 1088 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 1089 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 { 1096 class_interface_decl->setHasExternalLexicalStorage (has_extern); 1097 class_interface_decl->setHasExternalVisibleStorage (has_extern); 1098 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; 1111} 1112 1113static bool 1114IsOperator (const char *name, OverloadedOperatorKind &op_kind) 1115{ 1116 if (name == NULL || name[0] == '\0') 1117 return false; 1118 1119#define OPERATOR_PREFIX "operator" 1120#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1) 1121 1122 const char *post_op_name = NULL; 1123 1124 bool no_space = true; 1125 1126 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH)) 1127 return false; 1128 1129 post_op_name = name + OPERATOR_PREFIX_LENGTH; 1130 1131 if (post_op_name[0] == ' ') 1132 { 1133 post_op_name++; 1134 no_space = false; 1135 } 1136 1137#undef OPERATOR_PREFIX 1138#undef OPERATOR_PREFIX_LENGTH 1139 1140 // 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 { 1146 default: 1147 if (no_space) 1148 return false; 1149 break; 1150 case 'n': 1151 if (no_space) 1152 return false; 1153 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': 1160 if (no_space) 1161 return false; 1162 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} 1328 1329CXXMethodDecl * 1330ClangASTContext::AddMethodToCXXRecordType 1331( 1332 ASTContext *ast, 1333 clang_type_t record_opaque_type, 1334 const char *name, 1335 clang_type_t method_opaque_type, 1336 lldb::AccessType access, 1337 bool is_virtual, 1338 bool is_static, 1339 bool is_inline, 1340 bool is_explicit 1341) 1342{ 1343 if (!record_opaque_type || !method_opaque_type || !name) 1344 return NULL; 1345 1346 assert(ast); 1347 1348 IdentifierTable *identifier_table = &ast->Idents; 1349 1350 assert(identifier_table); 1351 1352 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type)); 1353 1354 CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl(); 1355 1356 if (cxx_record_decl == NULL) 1357 return NULL; 1358 1359 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); 1360 1361 CXXMethodDecl *cxx_method_decl = NULL; 1362 1363 DeclarationName decl_name (&identifier_table->get(name)); 1364 1365 const bool is_implicitly_declared = false; 1366 1367 const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr()); 1368 1369 if (function_Type == NULL) 1370 return NULL; 1371 1372 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type)); 1373 1374 if (!method_function_prototype) 1375 return NULL; 1376 1377 unsigned int num_params = method_function_prototype->getNumArgs(); 1378 1379 if (name[0] == '~') 1380 { 1381 cxx_method_decl = CXXDestructorDecl::Create (*ast, 1382 cxx_record_decl, 1383 DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()), 1384 method_qual_type, 1385 NULL, 1386 is_inline, 1387 is_implicitly_declared); 1388 } 1389 else if (decl_name == cxx_record_decl->getDeclName()) 1390 { 1391 cxx_method_decl = CXXConstructorDecl::Create (*ast, 1392 cxx_record_decl, 1393 DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()), 1394 method_qual_type, 1395 NULL, // TypeSourceInfo * 1396 is_explicit, 1397 is_inline, 1398 is_implicitly_declared); 1399 } 1400 else 1401 { 1402 1403 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS; 1404 if (IsOperator (name, op_kind)) 1405 { 1406 if (op_kind != NUM_OVERLOADED_OPERATORS) 1407 { 1408 cxx_method_decl = CXXMethodDecl::Create (*ast, 1409 cxx_record_decl, 1410 DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()), 1411 method_qual_type, 1412 NULL, // TypeSourceInfo * 1413 is_static, 1414 SC_None, 1415 is_inline); 1416 } 1417 else if (num_params == 0) 1418 { 1419 // Conversion operators don't take params... 1420 cxx_method_decl = CXXConversionDecl::Create (*ast, 1421 cxx_record_decl, 1422 DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()), 1423 method_qual_type, 1424 NULL, // TypeSourceInfo * 1425 is_inline, 1426 is_explicit); 1427 } 1428 } 1429 1430 if (cxx_method_decl == NULL) 1431 { 1432 cxx_method_decl = CXXMethodDecl::Create (*ast, 1433 cxx_record_decl, 1434 DeclarationNameInfo (decl_name, SourceLocation()), 1435 method_qual_type, 1436 NULL, // TypeSourceInfo * 1437 is_static, 1438 SC_None, 1439 is_inline); 1440 } 1441 } 1442 1443 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access); 1444 1445 cxx_method_decl->setAccess (access_specifier); 1446 cxx_method_decl->setVirtualAsWritten (is_virtual); 1447 1448 // Populate the method decl with parameter decls 1449 1450 ParmVarDecl *params[num_params]; 1451 1452 for (int param_index = 0; 1453 param_index < num_params; 1454 ++param_index) 1455 { 1456 params[param_index] = ParmVarDecl::Create (*ast, 1457 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); 1465 } 1466 1467 cxx_method_decl->setParams (params, num_params); 1468 1469 cxx_record_decl->addDecl (cxx_method_decl); 1470 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()); 1480 return cxx_method_decl; 1481} 1482 1483bool 1484ClangASTContext::AddFieldToRecordType 1485( 1486 ASTContext *ast, 1487 clang_type_t record_clang_type, 1488 const char *name, 1489 clang_type_t field_type, 1490 AccessType access, 1491 uint32_t bitfield_bit_size 1492) 1493{ 1494 if (record_clang_type == NULL || field_type == NULL) 1495 return false; 1496 1497 IdentifierTable *identifier_table = &ast->Idents; 1498 1499 assert (ast != NULL); 1500 assert (identifier_table != NULL); 1501 1502 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type)); 1503 1504 const clang::Type *clang_type = record_qual_type.getTypePtr(); 1505 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 1513 clang::Expr *bit_width = NULL; 1514 if (bitfield_bit_size != 0) 1515 { 1516 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()); 1518 } 1519 FieldDecl *field = FieldDecl::Create (*ast, 1520 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 1527 1528 field->setAccess (ConvertAccessTypeToAccessSpecifier (access)); 1529 1530 if (field) 1531 { 1532 record_decl->addDecl(field); 1533 } 1534 } 1535 else 1536 { 1537 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type); 1538 if (objc_class_type) 1539 { 1540 bool is_synthesized = false; 1541 ClangASTContext::AddObjCClassIVar (ast, 1542 record_clang_type, 1543 name, 1544 field_type, 1545 access, 1546 bitfield_bit_size, 1547 is_synthesized); 1548 } 1549 } 1550 } 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( 1563 ASTContext *ast, 1564 FieldDecl* field, 1565 uint32_t& bitfield_bit_size 1566) 1567{ 1568 if (ast == NULL || field == NULL) 1569 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; 1577 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast)) 1578 { 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 1614ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities) 1615{ 1616 if (clang_type) 1617 { 1618 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 1619 1620 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr()); 1621 if (record_type) 1622 { 1623 RecordDecl *record_decl = record_type->getDecl(); 1624 if (record_decl) 1625 { 1626 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) 1631 { 1632 // 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); 1635 } 1636 } 1637 } 1638 } 1639} 1640 1641#pragma mark C++ Base Classes 1642 1643CXXBaseSpecifier * 1644ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class) 1645{ 1646 if (base_class_type) 1647 return new CXXBaseSpecifier (SourceRange(), 1648 is_virtual, 1649 base_of_class, 1650 ConvertAccessTypeToAccessSpecifier (access), 1651 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)), 1652 SourceLocation()); 1653 return NULL; 1654} 1655 1656void 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 1666bool 1667ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes) 1668{ 1669 if (class_clang_type) 1670 { 1671 CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl(); 1672 if (cxx_record_decl) 1673 { 1674 cxx_record_decl->setBases(base_classes, num_base_classes); 1675 return true; 1676 } 1677 } 1678 return false; 1679} 1680#pragma mark Objective C Classes 1681 1682clang_type_t 1683ClangASTContext::CreateObjCClass 1684( 1685 const char *name, 1686 DeclContext *decl_ctx, 1687 bool isForwardDecl, 1688 bool isInternal 1689) 1690{ 1691 ASTContext *ast = getASTContext(); 1692 assert (ast != NULL); 1693 assert (name && name[0]); 1694 if (decl_ctx == NULL) 1695 decl_ctx = ast->getTranslationUnitDecl(); 1696 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. 1702 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast, 1703 decl_ctx, 1704 SourceLocation(), 1705 &ast->Idents.get(name), 1706 SourceLocation(), 1707 isForwardDecl, 1708 isInternal); 1709 1710 return ast->getObjCInterfaceType(decl).getAsOpaquePtr(); 1711} 1712 1713bool 1714ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type) 1715{ 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)); 1720 const clang::Type *class_type = class_qual_type.getTypePtr(); 1721 const clang::Type *super_type = super_qual_type.getTypePtr(); 1722 if (class_type && super_type) 1723 { 1724 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1725 const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type); 1726 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( 1745 ASTContext *ast, 1746 clang_type_t class_opaque_type, 1747 const char *name, 1748 clang_type_t ivar_opaque_type, 1749 AccessType access, 1750 uint32_t bitfield_bit_size, 1751 bool is_synthesized 1752) 1753{ 1754 if (class_opaque_type == NULL || ivar_opaque_type == NULL) 1755 return false; 1756 1757 IdentifierTable *identifier_table = &ast->Idents; 1758 1759 assert (ast != NULL); 1760 assert (identifier_table != NULL); 1761 1762 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1763 1764 const clang::Type *class_type = class_qual_type.getTypePtr(); 1765 if (class_type) 1766 { 1767 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1768 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 { 1778 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()); 1780 } 1781 1782 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast, 1783 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, 1790 is_synthesized); 1791 1792 if (field) 1793 { 1794 class_interface_decl->addDecl(field); 1795 return true; 1796 } 1797 } 1798 } 1799 } 1800 return false; 1801} 1802 1803 1804bool 1805ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass) 1806{ 1807 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1808 1809 const clang::Type *class_type = class_qual_type.getTypePtr(); 1810 if (class_type) 1811 { 1812 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1813 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} 1835 1836ObjCMethodDecl * 1837ClangASTContext::AddMethodToObjCObjectType 1838( 1839 ASTContext *ast, 1840 clang_type_t class_opaque_type, 1841 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") 1842 clang_type_t method_opaque_type, 1843 lldb::AccessType access 1844) 1845{ 1846 if (class_opaque_type == NULL || method_opaque_type == NULL) 1847 return NULL; 1848 1849 IdentifierTable *identifier_table = &ast->Idents; 1850 1851 assert (ast != NULL); 1852 assert (identifier_table != NULL); 1853 1854 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1855 1856 const clang::Type *class_type = class_qual_type.getTypePtr(); 1857 if (class_type == NULL) 1858 return NULL; 1859 1860 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1861 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; 1869 1870 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 1879 size_t len = 0; 1880 const char *start; 1881 //printf ("name = '%s'\n", name); 1882 1883 unsigned num_selectors_with_args = 0; 1884 for (start = selector_start; 1885 start && *start != '\0' && *start != ']'; 1886 start += len) 1887 { 1888 len = ::strcspn(start, ":]"); 1889 bool has_arg = (start[len] == ':'); 1890 if (has_arg) 1891 ++num_selectors_with_args; 1892 selector_idents.push_back (&identifier_table->get (StringRef (start, len))); 1893 if (has_arg) 1894 len += 1; 1895 } 1896 1897 1898 if (selector_idents.size() == 0) 1899 return 0; 1900 1901 clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, 1902 selector_idents.data()); 1903 1904 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); 1905 1906 // Populate the method decl with parameter decls 1907 const clang::Type *method_type(method_qual_type.getTypePtr()); 1908 1909 if (method_type == NULL) 1910 return NULL; 1911 1912 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type)); 1913 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 1925 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast, 1926 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 { 1949 params.push_back (ParmVarDecl::Create (*ast, 1950 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 1960 objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args); 1961 } 1962 1963 class_interface_decl->addDecl (objc_method_decl); 1964 1965 1966 return objc_method_decl; 1967} 1968 1969 1970uint32_t 1971ClangASTContext::GetTypeInfo 1972( 1973 clang_type_t clang_type, 1974 clang::ASTContext *ast, 1975 clang_type_t *pointee_or_element_clang_type 1976) 1977{ 1978 if (clang_type == NULL) 1979 return 0; 1980 1981 if (pointee_or_element_clang_type) 1982 *pointee_or_element_clang_type = NULL; 1983 1984 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 1985 1986 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 1987 switch (type_class) 1988 { 1989 case clang::Type::Builtin: 1990 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 1991 { 1992 case clang::BuiltinType::ObjCId: 1993 case clang::BuiltinType::ObjCClass: 1994 if (ast && pointee_or_element_clang_type) 1995 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr(); 1996 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue; 1997 1998 default: 1999 break; 2000 } 2001 return eTypeIsBuiltIn | eTypeHasValue; 2002 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 2008 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue; 2009 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 2018 case clang::Type::DependentName: return 0; 2019 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector; 2020 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate; 2021 case clang::Type::Decltype: return 0; 2022 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 2028 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; 2032 case clang::Type::InjectedClassName: return 0; 2033 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 2040 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue; 2041 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 2047 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; 2048 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; 2049 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 2055 case clang::Type::Record: 2056 if (qual_type->getAsCXXRecordDecl()) 2057 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus; 2058 else 2059 return eTypeHasChildren | eTypeIsStructUnion; 2060 break; 2061 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate; 2062 case clang::Type::TemplateTypeParm: return eTypeIsTemplate; 2063 case clang::Type::TemplateSpecialization: return eTypeIsTemplate; 2064 2065 case clang::Type::Typedef: 2066 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 2067 ast, 2068 pointee_or_element_clang_type); 2069 2070 case clang::Type::TypeOfExpr: return 0; 2071 case clang::Type::TypeOf: return 0; 2072 case clang::Type::UnresolvedUsing: return 0; 2073 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector; 2074 default: return 0; 2075 } 2076 return 0; 2077} 2078 2079 2080#pragma mark Aggregate Types 2081 2082bool 2083ClangASTContext::IsAggregateType (clang_type_t clang_type) 2084{ 2085 if (clang_type == NULL) 2086 return false; 2087 2088 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2089 2090 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2091 switch (type_class) 2092 { 2093 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: 2099 case clang::Type::ObjCObject: 2100 case clang::Type::ObjCInterface: 2101 return true; 2102 2103 case clang::Type::Typedef: 2104 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); 2105 2106 default: 2107 break; 2108 } 2109 // The clang type does have a value 2110 return false; 2111} 2112 2113uint32_t 2114ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes) 2115{ 2116 if (clang_type == NULL) 2117 return 0; 2118 2119 uint32_t num_children = 0; 2120 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2121 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2122 switch (type_class) 2123 { 2124 case clang::Type::Builtin: 2125 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 2126 { 2127 case clang::BuiltinType::ObjCId: // child is Class 2128 case clang::BuiltinType::ObjCClass: // child is Class 2129 num_children = 1; 2130 break; 2131 2132 default: 2133 break; 2134 } 2135 break; 2136 2137 case clang::Type::Complex: return 0; 2138 2139 case clang::Type::Record: 2140 if (GetCompleteQualType (ast, qual_type)) 2141 { 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 2181 case clang::Type::ObjCObject: 2182 case clang::Type::ObjCInterface: 2183 if (GetCompleteQualType (ast, qual_type)) 2184 { 2185 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 2186 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: 2213 { 2214 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr()); 2215 QualType pointee_type = pointer_type->getPointeeType(); 2216 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, 2217 pointee_type.getAsOpaquePtr(), 2218 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; 2226 2227 case clang::Type::ConstantArray: 2228 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); 2229 break; 2230 2231 case clang::Type::Pointer: 2232 { 2233 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 2234 QualType pointee_type (pointer_type->getPointeeType()); 2235 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, 2236 pointee_type.getAsOpaquePtr(), 2237 omit_empty_base_classes); 2238 if (num_pointee_children == 0) 2239 { 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 } 2244 else 2245 num_children = num_pointee_children; 2246 } 2247 break; 2248 2249 case clang::Type::LValueReference: 2250 case clang::Type::RValueReference: 2251 { 2252 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 2253 QualType pointee_type = reference_type->getPointeeType(); 2254 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, 2255 pointee_type.getAsOpaquePtr(), 2256 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 2266 case clang::Type::Typedef: 2267 num_children = ClangASTContext::GetNumChildren (ast, 2268 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 2269 omit_empty_base_classes); 2270 break; 2271 2272 default: 2273 break; 2274 } 2275 return num_children; 2276} 2277 2278// 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 { 2293 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: 2302 case clang::BuiltinType::WChar_U: 2303 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: 2312 case clang::BuiltinType::WChar_S: 2313 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 2331 case clang::Type::Complex: return 1; 2332 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} 2369 2370clang_type_t 2371ClangASTContext::GetChildClangTypeAtIndex 2372( 2373 const char *parent_name, 2374 clang_type_t parent_clang_type, 2375 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, 2382 uint32_t &child_bitfield_bit_offset, 2383 bool &child_is_base_class, 2384 bool &child_is_deref_of_parent 2385) 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, 2399 child_bitfield_bit_offset, 2400 child_is_base_class, 2401 child_is_deref_of_parent); 2402 return NULL; 2403} 2404 2405clang_type_t 2406ClangASTContext::GetChildClangTypeAtIndex 2407( 2408 ASTContext *ast, 2409 const char *parent_name, 2410 clang_type_t parent_clang_type, 2411 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, 2418 uint32_t &child_bitfield_bit_offset, 2419 bool &child_is_base_class, 2420 bool &child_is_deref_of_parent 2421) 2422{ 2423 if (parent_clang_type == NULL) 2424 return NULL; 2425 2426 if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes)) 2427 { 2428 uint32_t bit_offset; 2429 child_bitfield_bit_size = 0; 2430 child_bitfield_bit_offset = 0; 2431 child_is_base_class = false; 2432 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type)); 2433 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass(); 2434 switch (parent_type_class) 2435 { 2436 case clang::Type::Builtin: 2437 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind()) 2438 { 2439 case clang::BuiltinType::ObjCId: 2440 case clang::BuiltinType::ObjCClass: 2441 child_name = "isa"; 2442 child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT; 2443 return ast->ObjCBuiltinClassTy.getAsOpaquePtr(); 2444 2445 default: 2446 break; 2447 } 2448 break; 2449 2450 case clang::Type::Record: 2451 if (GetCompleteQualType (ast, parent_qual_type)) 2452 { 2453 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr()); 2454 const RecordDecl *record_decl = record_type->getDecl(); 2455 assert(record_decl); 2456 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl); 2457 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()) 2485 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; 2486 else 2487 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; 2488 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 2496 uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType()); 2497 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; 2501 child_is_base_class = true; 2502 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 } 2509 // 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. 2522 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType()); 2523 assert(field_idx < record_layout.getFieldCount()); 2524 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; 2530 if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size)) 2531 child_bitfield_bit_offset = bit_offset % 8; 2532 2533 return field->getType().getAsOpaquePtr(); 2534 } 2535 } 2536 } 2537 break; 2538 2539 case clang::Type::ObjCObject: 2540 case clang::Type::ObjCInterface: 2541 if (GetCompleteQualType (ast, parent_qual_type)) 2542 { 2543 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr()); 2544 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 2553 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl); 2554 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 2555 if (superclass_interface_decl) 2556 { 2557 if (omit_empty_base_classes) 2558 { 2559 if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0) 2560 { 2561 if (idx == 0) 2562 { 2563 QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl)); 2564 2565 2566 child_name.assign(superclass_interface_decl->getNameAsString().c_str()); 2567 2568 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr()); 2569 2570 child_byte_size = ivar_type_info.first / 8; 2571 child_byte_offset = 0; 2572 child_is_base_class = true; 2573 2574 return ivar_qual_type.getAsOpaquePtr(); 2575 } 2576 2577 ++child_idx; 2578 } 2579 } 2580 else 2581 ++child_idx; 2582 } 2583 2584 const uint32_t superclass_idx = child_idx; 2585 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 2600 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr()); 2601 2602 child_byte_size = ivar_type_info.first / 8; 2603 2604 // Figure out the field offset within the current struct/union/class type 2605 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); 2606 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 { 2620 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr()); 2621 QualType pointee_type = pointer_type->getPointeeType(); 2622 2623 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2624 { 2625 child_is_deref_of_parent = false; 2626 bool tmp_child_is_deref_of_parent = false; 2627 return GetChildClangTypeAtIndex (ast, 2628 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, 2637 child_bitfield_bit_offset, 2638 child_is_base_class, 2639 tmp_child_is_deref_of_parent); 2640 } 2641 else 2642 { 2643 child_is_deref_of_parent = true; 2644 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 { 2653 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); 2654 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 } 2660 } 2661 break; 2662 2663 case clang::Type::ConstantArray: 2664 { 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 { 2670 if (GetCompleteQualType (ast, array->getElementType())) 2671 { 2672 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); 2673 2674 char element_name[64]; 2675 ::snprintf (element_name, sizeof (element_name), "[%u]", idx); 2676 2677 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 } 2683 } 2684 } 2685 break; 2686 2687 case clang::Type::Pointer: 2688 { 2689 const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr()); 2690 QualType pointee_type = pointer_type->getPointeeType(); 2691 2692 // Don't dereference "void *" pointers 2693 if (pointee_type->isVoidType()) 2694 return NULL; 2695 2696 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2697 { 2698 child_is_deref_of_parent = false; 2699 bool tmp_child_is_deref_of_parent = false; 2700 return GetChildClangTypeAtIndex (ast, 2701 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, 2710 child_bitfield_bit_offset, 2711 child_is_base_class, 2712 tmp_child_is_deref_of_parent); 2713 } 2714 else 2715 { 2716 child_is_deref_of_parent = true; 2717 2718 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 { 2727 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); 2728 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 2737 case clang::Type::LValueReference: 2738 case clang::Type::RValueReference: 2739 { 2740 const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr()); 2741 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 { 2745 child_is_deref_of_parent = false; 2746 bool tmp_child_is_deref_of_parent = false; 2747 return GetChildClangTypeAtIndex (ast, 2748 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, 2758 child_is_base_class, 2759 tmp_child_is_deref_of_parent); 2760 } 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 { 2772 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); 2773 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 2782 case clang::Type::Typedef: 2783 return GetChildClangTypeAtIndex (ast, 2784 parent_name, 2785 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 2786 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, 2793 child_bitfield_bit_offset, 2794 child_is_base_class, 2795 child_is_deref_of_parent); 2796 break; 2797 2798 default: 2799 break; 2800 } 2801 } 2802 return NULL; 2803} 2804 2805static inline bool 2806BaseSpecifierIsEmpty (const CXXBaseSpecifier *b) 2807{ 2808 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false; 2809} 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( 2982 ASTContext *ast, 2983 clang_type_t clang_type, 2984 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)); 2992 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2993 switch (type_class) 2994 { 2995 case clang::Type::Record: 2996 if (GetCompleteQualType (ast, qual_type)) 2997 { 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... 3029 IdentifierInfo & ident_ref = ast->Idents.get(name, name + strlen (name)); 3030 DeclarationName decl_name(&ident_ref); 3031 3032 CXXBasePaths paths; 3033 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember, 3034 decl_name.getAsOpaquePtr(), 3035 paths)) 3036 { 3037 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 3083 case clang::Type::ObjCObject: 3084 case clang::Type::ObjCInterface: 3085 if (GetCompleteQualType (ast, qual_type)) 3086 { 3087 StringRef name_sref(name); 3088 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 3089 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 3100 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) 3101 { 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 3122 if (GetIndexOfChildMemberWithName (ast, 3123 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), 3124 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 { 3145 return GetIndexOfChildMemberWithName (ast, 3146 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), 3147 name, 3148 omit_empty_base_classes, 3149 child_indexes); 3150 } 3151 break; 3152 3153 3154 case clang::Type::ConstantArray: 3155 { 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// { 3161// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); 3162// 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 3175// case clang::Type::MemberPointerType: 3176// { 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// { 3182// return GetIndexOfChildWithName (ast, 3183// mem_ptr_type->getPointeeType().getAsOpaquePtr(), 3184// name); 3185// } 3186// } 3187// break; 3188// 3189 case clang::Type::LValueReference: 3190 case clang::Type::RValueReference: 3191 { 3192 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 3193 QualType pointee_type = reference_type->getPointeeType(); 3194 3195 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3196 { 3197 return GetIndexOfChildMemberWithName (ast, 3198 reference_type->getPointeeType().getAsOpaquePtr(), 3199 name, 3200 omit_empty_base_classes, 3201 child_indexes); 3202 } 3203 } 3204 break; 3205 3206 case clang::Type::Pointer: 3207 { 3208 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 3209 QualType pointee_type = pointer_type->getPointeeType(); 3210 3211 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3212 { 3213 return GetIndexOfChildMemberWithName (ast, 3214 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// { 3230// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); 3231// 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 3240 case clang::Type::Typedef: 3241 return GetIndexOfChildMemberWithName (ast, 3242 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 3243 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( 3262 ASTContext *ast, 3263 clang_type_t clang_type, 3264 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)); 3271 3272 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3273 3274 switch (type_class) 3275 { 3276 case clang::Type::Record: 3277 if (GetCompleteQualType (ast, qual_type)) 3278 { 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 3319 case clang::Type::ObjCObject: 3320 case clang::Type::ObjCInterface: 3321 if (GetCompleteQualType (ast, qual_type)) 3322 { 3323 StringRef name_sref(name); 3324 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 3325 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 { 3362 return GetIndexOfChildWithName (ast, 3363 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), 3364 name, 3365 omit_empty_base_classes); 3366 } 3367 break; 3368 3369 case clang::Type::ConstantArray: 3370 { 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// { 3376// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); 3377// 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 3390// case clang::Type::MemberPointerType: 3391// { 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// { 3397// return GetIndexOfChildWithName (ast, 3398// mem_ptr_type->getPointeeType().getAsOpaquePtr(), 3399// name); 3400// } 3401// } 3402// break; 3403// 3404 case clang::Type::LValueReference: 3405 case clang::Type::RValueReference: 3406 { 3407 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 3408 QualType pointee_type = reference_type->getPointeeType(); 3409 3410 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3411 { 3412 return GetIndexOfChildWithName (ast, 3413 reference_type->getPointeeType().getAsOpaquePtr(), 3414 name, 3415 omit_empty_base_classes); 3416 } 3417 } 3418 break; 3419 3420 case clang::Type::Pointer: 3421 { 3422 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 3423 QualType pointee_type = pointer_type->getPointeeType(); 3424 3425 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3426 { 3427 return GetIndexOfChildWithName (ast, 3428 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// { 3443// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); 3444// 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 3453 case clang::Type::Typedef: 3454 return GetIndexOfChildWithName (ast, 3455 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 3456 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 3469ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind) 3470{ 3471 if (tag_clang_type) 3472 { 3473 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type)); 3474 const clang::Type *clang_type = tag_qual_type.getTypePtr(); 3475 if (clang_type) 3476 { 3477 const TagType *tag_type = dyn_cast<TagType>(clang_type); 3478 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 * 3496ClangASTContext::GetDeclContextForType (clang_type_t clang_type) 3497{ 3498 if (clang_type == NULL) 3499 return NULL; 3500 3501 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 3502 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3503 switch (type_class) 3504 { 3505 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(); 3524 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); 3525 3526 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; 3531 } 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 { 3545 ASTContext *ast = getASTContext(); 3546 if (decl_ctx == NULL) 3547 decl_ctx = ast->getTranslationUnitDecl(); 3548 return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), &ast->Idents.get(name)); 3549 } 3550 return NULL; 3551} 3552 3553 3554#pragma mark Function Types 3555 3556FunctionDecl * 3557ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline) 3558{ 3559 if (name) 3560 { 3561 ASTContext *ast = getASTContext(); 3562 assert (ast != NULL); 3563 3564 if (name && name[0]) 3565 { 3566 return FunctionDecl::Create(*ast, 3567 ast->getTranslationUnitDecl(), 3568 SourceLocation(), 3569 DeclarationName (&ast->Idents.get(name)), 3570 QualType::getFromOpaquePtr(function_clang_type), 3571 NULL, 3572 (FunctionDecl::StorageClass)storage, 3573 (FunctionDecl::StorageClass)storage, 3574 is_inline); 3575 } 3576 else 3577 { 3578 return FunctionDecl::Create(*ast, 3579 ast->getTranslationUnitDecl(), 3580 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 3592clang_type_t 3593ClangASTContext::CreateFunctionType (ASTContext *ast, 3594 clang_type_t result_type, 3595 clang_type_t *args, 3596 unsigned num_args, 3597 bool is_variadic, 3598 unsigned type_quals) 3599{ 3600 assert (ast != NULL); 3601 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? 3606 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 3614 return ast->getFunctionType(QualType::getFromOpaquePtr(result_type), 3615 qual_type_args.empty() ? NULL : &qual_type_args.front(), 3616 qual_type_args.size(), 3617 proto_info).getAsOpaquePtr(); // NoReturn); 3618} 3619 3620ParmVarDecl * 3621ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage) 3622{ 3623 ASTContext *ast = getASTContext(); 3624 assert (ast != NULL); 3625 return ParmVarDecl::Create(*ast, 3626 ast->getTranslationUnitDecl(), 3627 SourceLocation(), 3628 name && name[0] ? &ast->Idents.get(name) : NULL, 3629 QualType::getFromOpaquePtr(param_type), 3630 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 3646clang_type_t 3647ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride) 3648{ 3649 if (element_type) 3650 { 3651 ASTContext *ast = getASTContext(); 3652 assert (ast != NULL); 3653 llvm::APInt ap_element_count (64, element_count); 3654 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type), 3655 ap_element_count, 3656 ArrayType::Normal, 3657 0).getAsOpaquePtr(); // ElemQuals 3658 } 3659 return NULL; 3660} 3661 3662 3663#pragma mark TagDecl 3664 3665bool 3666ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type) 3667{ 3668 if (clang_type) 3669 { 3670 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3671 const clang::Type *t = qual_type.getTypePtr(); 3672 if (t) 3673 { 3674 const TagType *tag_type = dyn_cast<TagType>(t); 3675 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 3690ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type) 3691{ 3692 if (clang_type) 3693 { 3694 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3695 3696 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); 3697 3698 if (cxx_record_decl) 3699 { 3700 cxx_record_decl->completeDefinition(); 3701 3702 return true; 3703 } 3704 3705 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type); 3706 3707 if (objc_class_type) 3708 { 3709 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 3710 3711 class_interface_decl->setForwardDecl(false); 3712 } 3713 3714 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) 3721 { 3722 /// TODO This really needs to be fixed. 3723 3724 unsigned NumPositiveBits = 1; 3725 unsigned NumNegativeBits = 0; 3726 3727 ASTContext *ast = getASTContext(); 3728 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. 3732 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy)) 3733 { 3734 if (enum_decl->getIntegerType()->isSignedIntegerType()) 3735 promotion_qual_type = ast->IntTy; 3736 else 3737 promotion_qual_type = ast->UnsignedIntTy; 3738 } 3739 else 3740 promotion_qual_type = enum_decl->getIntegerType(); 3741 3742 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); 3743 return true; 3744 } 3745 } 3746 } 3747 return false; 3748} 3749 3750 3751#pragma mark Enumeration Types 3752 3753clang_type_t 3754ClangASTContext::CreateEnumerationType 3755( 3756 const char *name, 3757 DeclContext *decl_ctx, 3758 const Declaration &decl, 3759 clang_type_t integer_qual_type 3760) 3761{ 3762 // TODO: Do something intelligent with the Declaration object passed in 3763 // like maybe filling in the SourceLocation with it... 3764 ASTContext *ast = getASTContext(); 3765 assert (ast != NULL); 3766 3767 // TODO: ask about these... 3768// const bool IsScoped = false; 3769// const bool IsFixed = false; 3770 3771 EnumDecl *enum_decl = EnumDecl::Create (*ast, 3772 decl_ctx, 3773 SourceLocation(), 3774 name && name[0] ? &ast->Idents.get(name) : NULL, 3775 SourceLocation(), 3776 NULL, 3777 false, // IsScoped 3778 false, // IsScopedUsingClassTag 3779 false); // IsFixed 3780 3781 3782 if (enum_decl) 3783 { 3784 // TODO: check if we should be setting the promotion type too? 3785 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type)); 3786 3787 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info 3788 3789 return ast->getTagDeclType(enum_decl).getAsOpaquePtr(); 3790 } 3791 return NULL; 3792} 3793 3794clang_type_t 3795ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type) 3796{ 3797 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); 3798 3799 const clang::Type *clang_type = enum_qual_type.getTypePtr(); 3800 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} 3812bool 3813ClangASTContext::AddEnumerationValueToEnumerationType 3814( 3815 clang_type_t enum_clang_type, 3816 clang_type_t enumerator_clang_type, 3817 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... 3827 ASTContext *ast = getASTContext(); 3828 IdentifierTable *identifier_table = getIdentifierTable(); 3829 3830 assert (ast != NULL); 3831 assert (identifier_table != NULL); 3832 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); 3833 3834 const clang::Type *clang_type = enum_qual_type.getTypePtr(); 3835 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 = 3844 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 3852 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 3865clang_type_t 3866ClangASTContext::CreatePointerType (clang_type_t clang_type) 3867{ 3868 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) 3875 { 3876 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3877 3878 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3879 switch (type_class) 3880 { 3881 case clang::Type::ObjCObject: 3882 case clang::Type::ObjCInterface: 3883 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); 3884 3885 default: 3886 return ast->getPointerType(qual_type).getAsOpaquePtr(); 3887 } 3888 } 3889 return NULL; 3890} 3891 3892clang_type_t 3893ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast, 3894 clang_type_t clang_type) 3895{ 3896 if (clang_type) 3897 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); 3898 return NULL; 3899} 3900 3901clang_type_t 3902ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast, 3903 clang_type_t clang_type) 3904{ 3905 if (clang_type) 3906 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); 3907 return NULL; 3908} 3909 3910clang_type_t 3911ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type) 3912{ 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 3919uint32_t 3920ClangASTContext::GetPointerBitSize () 3921{ 3922 ASTContext *ast = getASTContext(); 3923 return ast->getTypeSize(ast->VoidPtrTy); 3924} 3925 3926bool 3927ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type) 3928{ 3929 if (clang_type == NULL) 3930 return false; 3931 3932 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3933 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3934 switch (type_class) 3935 { 3936 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: 3943 return true; 3944 } 3945 return false; 3946 case clang::Type::ObjCObjectPointer: 3947 if (target_type) 3948 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3949 return true; 3950 case clang::Type::BlockPointer: 3951 if (target_type) 3952 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3953 return true; 3954 case clang::Type::Pointer: 3955 if (target_type) 3956 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3957 return true; 3958 case clang::Type::MemberPointer: 3959 if (target_type) 3960 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3961 return true; 3962 case clang::Type::LValueReference: 3963 if (target_type) 3964 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); 3965 return true; 3966 case clang::Type::RValueReference: 3967 if (target_type) 3968 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); 3969 return true; 3970 case clang::Type::Typedef: 3971 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); 3972 default: 3973 break; 3974 } 3975 return false; 3976} 3977 3978bool 3979ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed) 3980{ 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 3999ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type) 4000{ 4001 if (clang_type) 4002 { 4003 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4004 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 4005 switch (type_class) 4006 { 4007 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: 4014 return true; 4015 } 4016 return false; 4017 case clang::Type::ObjCObjectPointer: 4018 if (target_type) 4019 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 4020 return true; 4021 case clang::Type::BlockPointer: 4022 if (target_type) 4023 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 4024 return true; 4025 case clang::Type::Pointer: 4026 if (target_type) 4027 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 4028 return true; 4029 case clang::Type::MemberPointer: 4030 if (target_type) 4031 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 4032 return true; 4033 case clang::Type::Typedef: 4034 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type); 4035 default: 4036 break; 4037 } 4038 } 4039 return false; 4040} 4041 4042bool 4043ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex) 4044{ 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 4081 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 4101bool 4102ClangASTContext::IsCXXClassType (clang_type_t clang_type) 4103{ 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 4114ClangASTContext::IsObjCClassType (clang_type_t clang_type) 4115{ 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 4126bool 4127ClangASTContext::IsCharType (clang_type_t clang_type) 4128{ 4129 if (clang_type) 4130 return QualType::getFromOpaquePtr(clang_type)->isCharType(); 4131 return false; 4132} 4133 4134bool 4135ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length) 4136{ 4137 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)) 4144 { 4145 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type)); 4146 4147 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType()) 4148 { 4149 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4150 if (type_flags.Test (eTypeIsArray)) 4151 { 4152 // 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; 4156 } 4157 else 4158 { 4159 length = 0; 4160 return true; 4161 } 4162 4163 } 4164 } 4165 return false; 4166} 4167 4168bool 4169ClangASTContext::IsFunctionPointerType (clang_type_t clang_type) 4170{ 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: 4182 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); 4183 4184 case clang::Type::LValueReference: 4185 case clang::Type::RValueReference: 4186 { 4187 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 4188 if (reference_type) 4189 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr()); 4190 } 4191 break; 4192 } 4193 } 4194 return false; 4195} 4196 4197size_t 4198ClangASTContext::GetArraySize (clang_type_t clang_type) 4199{ 4200 if (clang_type) 4201 { 4202 const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr()); 4203 if (array) 4204 return array->getSize().getLimitedValue(); 4205 } 4206 return 0; 4207} 4208 4209bool 4210ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size) 4211{ 4212 if (!clang_type) 4213 return false; 4214 4215 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4216 4217 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 4218 switch (type_class) 4219 { 4220 case clang::Type::ConstantArray: 4221 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; 4226 case clang::Type::IncompleteArray: 4227 if (member_type) 4228 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 4229 if (size) 4230 *size = 0; 4231 return true; 4232 case clang::Type::VariableArray: 4233 if (member_type) 4234 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 4235 if (size) 4236 *size = 0; 4237 return true; 4238 case clang::Type::DependentSizedArray: 4239 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 4251clang_type_t 4252ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx) 4253{ 4254 if (clang_type) 4255 { 4256 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4257 ASTContext *ast = getASTContext(); 4258 IdentifierTable *identifier_table = getIdentifierTable(); 4259 assert (ast != NULL); 4260 assert (identifier_table != NULL); 4261 if (decl_ctx == NULL) 4262 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)); 4268 4269 decl->setAccess(AS_public); // TODO respect proper access specifier 4270 4271 // Get a uniqued QualType for the typedef decl type 4272 return ast->getTypedefType (decl).getAsOpaquePtr(); 4273 } 4274 return NULL; 4275} 4276 4277 4278std::string 4279ClangASTContext::GetTypeName (clang_type_t opaque_qual_type) 4280{ 4281 std::string return_name; 4282 4283 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type)); 4284 4285 const TypedefType *typedef_type = qual_type->getAs<TypedefType>(); 4286 if (typedef_type) 4287 { 4288 const TypedefDecl *typedef_decl = typedef_type->getDecl(); 4289 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 4306//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) 4307//{ 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 4341ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size) 4342{ 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); 4355 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref); 4356 4357 const uint64_t bit_size = ast->getTypeSize (qual_type); 4358 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} 4378 4379unsigned 4380ClangASTContext::GetTypeQualifiers(clang_type_t clang_type) 4381{ 4382 assert (clang_type); 4383 4384 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4385 4386 return qual_type.getQualifiers().getCVRQualifiers(); 4387} 4388 4389bool 4390ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type) 4391{ 4392 if (clang_type == NULL) 4393 return false; 4394 4395 return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type)); 4396} 4397 4398 4399bool 4400ClangASTContext::GetCompleteType (clang_type_t clang_type) 4401{ 4402 return ClangASTContext::GetCompleteType (getASTContext(), clang_type); 4403} 4404 4405