ClangASTContext.cpp revision 9994a0bcfe1790b320f6a9cf51c8d5ac9c4efdbd
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/ArchSpec.h" 58#include "lldb/Core/dwarf.h" 59#include "lldb/Core/Flags.h" 60#include "lldb/Core/Log.h" 61 62#include <stdio.h> 63 64using namespace lldb; 65using namespace lldb_private; 66using namespace llvm; 67using namespace clang; 68 69 70static bool 71GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type) 72{ 73 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 74 switch (type_class) 75 { 76 case clang::Type::Record: 77 case clang::Type::Enum: 78 { 79 const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr()); 80 if (tag_type) 81 { 82 clang::TagDecl *tag_decl = tag_type->getDecl(); 83 if (tag_decl) 84 { 85 if (tag_decl->getDefinition()) 86 return true; 87 88 if (tag_decl->hasExternalLexicalStorage()) 89 { 90 ExternalASTSource *external_ast_source = ast->getExternalSource(); 91 if (external_ast_source) 92 { 93 external_ast_source->CompleteType(tag_decl); 94 return !tag_type->isIncompleteType(); 95 } 96 } 97 return false; 98 } 99 } 100 101 } 102 break; 103 104 case clang::Type::ObjCObject: 105 case clang::Type::ObjCInterface: 106 { 107 const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type); 108 if (objc_class_type) 109 { 110 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 111 // We currently can't complete objective C types through the newly added ASTContext 112 // because it only supports TagDecl objects right now... 113 bool is_forward_decl = class_interface_decl->isForwardDecl(); 114 if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage()) 115 { 116 ExternalASTSource *external_ast_source = ast->getExternalSource(); 117 if (external_ast_source) 118 { 119 external_ast_source->CompleteType (class_interface_decl); 120 is_forward_decl = class_interface_decl->isForwardDecl(); 121 } 122 return is_forward_decl == false; 123 } 124 return true; 125 } 126 } 127 break; 128 129 case clang::Type::Typedef: 130 return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()); 131 132 default: 133 break; 134 } 135 136 return true; 137} 138 139 140static AccessSpecifier 141ConvertAccessTypeToAccessSpecifier (AccessType access) 142{ 143 switch (access) 144 { 145 default: break; 146 case eAccessNone: return AS_none; 147 case eAccessPublic: return AS_public; 148 case eAccessPrivate: return AS_private; 149 case eAccessProtected: return AS_protected; 150 } 151 return AS_none; 152} 153 154static ObjCIvarDecl::AccessControl 155ConvertAccessTypeToObjCIvarAccessControl (AccessType access) 156{ 157 switch (access) 158 { 159 default: break; 160 case eAccessNone: return ObjCIvarDecl::None; 161 case eAccessPublic: return ObjCIvarDecl::Public; 162 case eAccessPrivate: return ObjCIvarDecl::Private; 163 case eAccessProtected: return ObjCIvarDecl::Protected; 164 case eAccessPackage: return ObjCIvarDecl::Package; 165 } 166 return ObjCIvarDecl::None; 167} 168 169 170static void 171ParseLangArgs 172( 173 LangOptions &Opts, 174 InputKind IK 175) 176{ 177 // FIXME: Cleanup per-file based stuff. 178 179 // Set some properties which depend soley on the input kind; it would be nice 180 // to move these to the language standard, and have the driver resolve the 181 // input kind + language standard. 182 if (IK == IK_Asm) { 183 Opts.AsmPreprocessor = 1; 184 } else if (IK == IK_ObjC || 185 IK == IK_ObjCXX || 186 IK == IK_PreprocessedObjC || 187 IK == IK_PreprocessedObjCXX) { 188 Opts.ObjC1 = Opts.ObjC2 = 1; 189 } 190 191 LangStandard::Kind LangStd = LangStandard::lang_unspecified; 192 193 if (LangStd == LangStandard::lang_unspecified) { 194 // Based on the base language, pick one. 195 switch (IK) { 196 case IK_None: 197 case IK_AST: 198 case IK_LLVM_IR: 199 assert (!"Invalid input kind!"); 200 case IK_OpenCL: 201 LangStd = LangStandard::lang_opencl; 202 break; 203 case IK_CUDA: 204 LangStd = LangStandard::lang_cuda; 205 break; 206 case IK_Asm: 207 case IK_C: 208 case IK_PreprocessedC: 209 case IK_ObjC: 210 case IK_PreprocessedObjC: 211 LangStd = LangStandard::lang_gnu99; 212 break; 213 case IK_CXX: 214 case IK_PreprocessedCXX: 215 case IK_ObjCXX: 216 case IK_PreprocessedObjCXX: 217 LangStd = LangStandard::lang_gnucxx98; 218 break; 219 } 220 } 221 222 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); 223 Opts.BCPLComment = Std.hasBCPLComments(); 224 Opts.C99 = Std.isC99(); 225 Opts.CPlusPlus = Std.isCPlusPlus(); 226 Opts.CPlusPlus0x = Std.isCPlusPlus0x(); 227 Opts.Digraphs = Std.hasDigraphs(); 228 Opts.GNUMode = Std.isGNUMode(); 229 Opts.GNUInline = !Std.isC99(); 230 Opts.HexFloats = Std.hasHexFloats(); 231 Opts.ImplicitInt = Std.hasImplicitInt(); 232 233 // OpenCL has some additional defaults. 234 if (LangStd == LangStandard::lang_opencl) { 235 Opts.OpenCL = 1; 236 Opts.AltiVec = 1; 237 Opts.CXXOperatorNames = 1; 238 Opts.LaxVectorConversions = 1; 239 } 240 241 // OpenCL and C++ both have bool, true, false keywords. 242 Opts.Bool = Opts.OpenCL || Opts.CPlusPlus; 243 244// if (Opts.CPlusPlus) 245// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names); 246// 247// if (Args.hasArg(OPT_fobjc_gc_only)) 248// Opts.setGCMode(LangOptions::GCOnly); 249// else if (Args.hasArg(OPT_fobjc_gc)) 250// Opts.setGCMode(LangOptions::HybridGC); 251// 252// if (Args.hasArg(OPT_print_ivar_layout)) 253// Opts.ObjCGCBitmapPrint = 1; 254// 255// if (Args.hasArg(OPT_faltivec)) 256// Opts.AltiVec = 1; 257// 258// if (Args.hasArg(OPT_pthread)) 259// Opts.POSIXThreads = 1; 260// 261// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility, 262// "default"); 263// if (Vis == "default") 264 Opts.setVisibilityMode(DefaultVisibility); 265// else if (Vis == "hidden") 266// Opts.setVisibilityMode(LangOptions::Hidden); 267// else if (Vis == "protected") 268// Opts.setVisibilityMode(LangOptions::Protected); 269// else 270// Diags.Report(diag::err_drv_invalid_value) 271// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis; 272 273// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv); 274 275 // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs 276 // is specified, or -std is set to a conforming mode. 277 Opts.Trigraphs = !Opts.GNUMode; 278// if (Args.hasArg(OPT_trigraphs)) 279// Opts.Trigraphs = 1; 280// 281// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers, 282// OPT_fno_dollars_in_identifiers, 283// !Opts.AsmPreprocessor); 284// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings); 285// Opts.Microsoft = Args.hasArg(OPT_fms_extensions); 286// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings); 287// if (Args.hasArg(OPT_fno_lax_vector_conversions)) 288// Opts.LaxVectorConversions = 0; 289// Opts.Exceptions = Args.hasArg(OPT_fexceptions); 290// Opts.RTTI = !Args.hasArg(OPT_fno_rtti); 291// Opts.Blocks = Args.hasArg(OPT_fblocks); 292// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char); 293// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar); 294// Opts.Freestanding = Args.hasArg(OPT_ffreestanding); 295// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding; 296// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); 297// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions); 298// Opts.AccessControl = Args.hasArg(OPT_faccess_control); 299// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors); 300// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno); 301// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99, 302// Diags); 303// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime); 304// Opts.ObjCConstantStringClass = getLastArgValue(Args, 305// OPT_fconstant_string_class); 306// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi); 307// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior); 308// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls); 309// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags); 310// Opts.Static = Args.hasArg(OPT_static_define); 311 Opts.OptimizeSize = 0; 312 313 // FIXME: Eliminate this dependency. 314// unsigned Opt = 315// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags); 316// Opts.Optimize = Opt != 0; 317 unsigned Opt = 0; 318 319 // This is the __NO_INLINE__ define, which just depends on things like the 320 // optimization level and -fno-inline, not actually whether the backend has 321 // inlining enabled. 322 // 323 // FIXME: This is affected by other options (-fno-inline). 324 Opts.NoInline = !Opt; 325 326// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags); 327// switch (SSP) { 328// default: 329// Diags.Report(diag::err_drv_invalid_value) 330// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP; 331// break; 332// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break; 333// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break; 334// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break; 335// } 336} 337 338 339ClangASTContext::ClangASTContext (const char *target_triple) : 340 m_target_triple(), 341 m_ast_ap(), 342 m_language_options_ap(), 343 m_source_manager_ap(), 344 m_diagnostic_ap(), 345 m_target_options_ap(), 346 m_target_info_ap(), 347 m_identifier_table_ap(), 348 m_selector_table_ap(), 349 m_builtins_ap(), 350 m_callback_tag_decl (NULL), 351 m_callback_objc_decl (NULL), 352 m_callback_baton (NULL) 353 354{ 355 if (target_triple && target_triple[0]) 356 m_target_triple.assign (target_triple); 357} 358 359//---------------------------------------------------------------------- 360// Destructor 361//---------------------------------------------------------------------- 362ClangASTContext::~ClangASTContext() 363{ 364 m_builtins_ap.reset(); 365 m_selector_table_ap.reset(); 366 m_identifier_table_ap.reset(); 367 m_target_info_ap.reset(); 368 m_target_options_ap.reset(); 369 m_diagnostic_ap.reset(); 370 m_source_manager_ap.reset(); 371 m_language_options_ap.reset(); 372 m_ast_ap.reset(); 373} 374 375 376void 377ClangASTContext::Clear() 378{ 379 m_ast_ap.reset(); 380 m_language_options_ap.reset(); 381 m_source_manager_ap.reset(); 382 m_diagnostic_ap.reset(); 383 m_target_options_ap.reset(); 384 m_target_info_ap.reset(); 385 m_identifier_table_ap.reset(); 386 m_selector_table_ap.reset(); 387 m_builtins_ap.reset(); 388} 389 390const char * 391ClangASTContext::GetTargetTriple () 392{ 393 return m_target_triple.c_str(); 394} 395 396void 397ClangASTContext::SetTargetTriple (const char *target_triple) 398{ 399 Clear(); 400 m_target_triple.assign(target_triple); 401} 402 403void 404ClangASTContext::SetArchitecture (const ArchSpec &arch) 405{ 406 Clear(); 407 m_target_triple.assign(arch.GetTriple().str()); 408} 409 410bool 411ClangASTContext::HasExternalSource () 412{ 413 ASTContext *ast = getASTContext(); 414 if (ast) 415 return ast->getExternalSource () != NULL; 416 return false; 417} 418 419void 420ClangASTContext::SetExternalSource (llvm::OwningPtr<ExternalASTSource> &ast_source_ap) 421{ 422 ASTContext *ast = getASTContext(); 423 if (ast) 424 { 425 ast->setExternalSource (ast_source_ap); 426 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true); 427 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true); 428 } 429} 430 431void 432ClangASTContext::RemoveExternalSource () 433{ 434 ASTContext *ast = getASTContext(); 435 436 if (ast) 437 { 438 llvm::OwningPtr<ExternalASTSource> empty_ast_source_ap; 439 ast->setExternalSource (empty_ast_source_ap); 440 ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false); 441 //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false); 442 } 443} 444 445 446 447ASTContext * 448ClangASTContext::getASTContext() 449{ 450 if (m_ast_ap.get() == NULL) 451 { 452 m_ast_ap.reset(new ASTContext (*getLanguageOptions(), 453 *getSourceManager(), 454 *getTargetInfo(), 455 *getIdentifierTable(), 456 *getSelectorTable(), 457 *getBuiltinContext(), 458 0)); 459 460 if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) 461 { 462 m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage(); 463 //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage(); 464 } 465 466 m_ast_ap->getDiagnostics().setClient(getDiagnosticClient(), false); 467 } 468 return m_ast_ap.get(); 469} 470 471Builtin::Context * 472ClangASTContext::getBuiltinContext() 473{ 474 if (m_builtins_ap.get() == NULL) 475 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo())); 476 return m_builtins_ap.get(); 477} 478 479IdentifierTable * 480ClangASTContext::getIdentifierTable() 481{ 482 if (m_identifier_table_ap.get() == NULL) 483 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL)); 484 return m_identifier_table_ap.get(); 485} 486 487LangOptions * 488ClangASTContext::getLanguageOptions() 489{ 490 if (m_language_options_ap.get() == NULL) 491 { 492 m_language_options_ap.reset(new LangOptions()); 493 ParseLangArgs(*m_language_options_ap, IK_ObjCXX); 494// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX); 495 } 496 return m_language_options_ap.get(); 497} 498 499SelectorTable * 500ClangASTContext::getSelectorTable() 501{ 502 if (m_selector_table_ap.get() == NULL) 503 m_selector_table_ap.reset (new SelectorTable()); 504 return m_selector_table_ap.get(); 505} 506 507clang::FileManager * 508ClangASTContext::getFileManager() 509{ 510 if (m_file_manager_ap.get() == NULL) 511 { 512 clang::FileSystemOptions file_system_options; 513 m_file_manager_ap.reset(new clang::FileManager(file_system_options)); 514 } 515 return m_file_manager_ap.get(); 516} 517 518clang::SourceManager * 519ClangASTContext::getSourceManager() 520{ 521 if (m_source_manager_ap.get() == NULL) 522 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager())); 523 return m_source_manager_ap.get(); 524} 525 526Diagnostic * 527ClangASTContext::getDiagnostic() 528{ 529 if (m_diagnostic_ap.get() == NULL) 530 { 531 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs()); 532 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp)); 533 } 534 return m_diagnostic_ap.get(); 535} 536 537class NullDiagnosticClient : public DiagnosticClient 538{ 539public: 540 NullDiagnosticClient () 541 { 542 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 543 } 544 545 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info) 546 { 547 if (m_log) 548 { 549 llvm::SmallVectorImpl<char> diag_str(10); 550 info.FormatDiagnostic(diag_str); 551 diag_str.push_back('\0'); 552 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data()); 553 } 554 } 555private: 556 LogSP m_log; 557}; 558 559DiagnosticClient * 560ClangASTContext::getDiagnosticClient() 561{ 562 if (m_diagnostic_client_ap.get() == NULL) 563 m_diagnostic_client_ap.reset(new NullDiagnosticClient); 564 565 return m_diagnostic_client_ap.get(); 566} 567 568TargetOptions * 569ClangASTContext::getTargetOptions() 570{ 571 if (m_target_options_ap.get() == NULL && !m_target_triple.empty()) 572 { 573 m_target_options_ap.reset (new TargetOptions()); 574 if (m_target_options_ap.get()) 575 m_target_options_ap->Triple = m_target_triple; 576 } 577 return m_target_options_ap.get(); 578} 579 580 581TargetInfo * 582ClangASTContext::getTargetInfo() 583{ 584 // target_triple should be something like "x86_64-apple-darwin10" 585 if (m_target_info_ap.get() == NULL && !m_target_triple.empty()) 586 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions())); 587 return m_target_info_ap.get(); 588} 589 590#pragma mark Basic Types 591 592static inline bool 593QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type) 594{ 595 uint64_t qual_type_bit_size = ast->getTypeSize(qual_type); 596 if (qual_type_bit_size == bit_size) 597 return true; 598 return false; 599} 600 601clang_type_t 602ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size) 603{ 604 ASTContext *ast = getASTContext(); 605 606 assert (ast != NULL); 607 608 return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size); 609} 610 611clang_type_t 612ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size) 613{ 614 if (!ast) 615 return NULL; 616 617 switch (encoding) 618 { 619 case eEncodingInvalid: 620 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy)) 621 return ast->VoidPtrTy.getAsOpaquePtr(); 622 break; 623 624 case eEncodingUint: 625 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) 626 return ast->UnsignedCharTy.getAsOpaquePtr(); 627 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) 628 return ast->UnsignedShortTy.getAsOpaquePtr(); 629 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) 630 return ast->UnsignedIntTy.getAsOpaquePtr(); 631 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) 632 return ast->UnsignedLongTy.getAsOpaquePtr(); 633 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) 634 return ast->UnsignedLongLongTy.getAsOpaquePtr(); 635 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) 636 return ast->UnsignedInt128Ty.getAsOpaquePtr(); 637 break; 638 639 case eEncodingSint: 640 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) 641 return ast->CharTy.getAsOpaquePtr(); 642 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) 643 return ast->ShortTy.getAsOpaquePtr(); 644 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) 645 return ast->IntTy.getAsOpaquePtr(); 646 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) 647 return ast->LongTy.getAsOpaquePtr(); 648 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) 649 return ast->LongLongTy.getAsOpaquePtr(); 650 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) 651 return ast->Int128Ty.getAsOpaquePtr(); 652 break; 653 654 case eEncodingIEEE754: 655 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy)) 656 return ast->FloatTy.getAsOpaquePtr(); 657 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy)) 658 return ast->DoubleTy.getAsOpaquePtr(); 659 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy)) 660 return ast->LongDoubleTy.getAsOpaquePtr(); 661 break; 662 663 case eEncodingVector: 664 default: 665 break; 666 } 667 668 return NULL; 669} 670 671clang_type_t 672ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size) 673{ 674 ASTContext *ast = getASTContext(); 675 676 #define streq(a,b) strcmp(a,b) == 0 677 assert (ast != NULL); 678 if (ast) 679 { 680 switch (dw_ate) 681 { 682 default: 683 break; 684 685 case DW_ATE_address: 686 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy)) 687 return ast->VoidPtrTy.getAsOpaquePtr(); 688 break; 689 690 case DW_ATE_boolean: 691 if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy)) 692 return ast->BoolTy.getAsOpaquePtr(); 693 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) 694 return ast->UnsignedCharTy.getAsOpaquePtr(); 695 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) 696 return ast->UnsignedShortTy.getAsOpaquePtr(); 697 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) 698 return ast->UnsignedIntTy.getAsOpaquePtr(); 699 break; 700 701 case DW_ATE_lo_user: 702 // This has been seen to mean DW_AT_complex_integer 703 if (::strstr(type_name, "complex")) 704 { 705 clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2); 706 return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr(); 707 } 708 break; 709 710 case DW_ATE_complex_float: 711 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy)) 712 return ast->FloatComplexTy.getAsOpaquePtr(); 713 else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy)) 714 return ast->DoubleComplexTy.getAsOpaquePtr(); 715 else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy)) 716 return ast->LongDoubleComplexTy.getAsOpaquePtr(); 717 else 718 { 719 clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2); 720 return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr(); 721 } 722 break; 723 724 case DW_ATE_float: 725 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy)) 726 return ast->FloatTy.getAsOpaquePtr(); 727 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy)) 728 return ast->DoubleTy.getAsOpaquePtr(); 729 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy)) 730 return ast->LongDoubleTy.getAsOpaquePtr(); 731 break; 732 733 case DW_ATE_signed: 734 if (type_name) 735 { 736 if (strstr(type_name, "long long")) 737 { 738 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) 739 return ast->LongLongTy.getAsOpaquePtr(); 740 } 741 else if (strstr(type_name, "long")) 742 { 743 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) 744 return ast->LongTy.getAsOpaquePtr(); 745 } 746 else if (strstr(type_name, "short")) 747 { 748 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) 749 return ast->ShortTy.getAsOpaquePtr(); 750 } 751 else if (strstr(type_name, "char")) 752 { 753 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) 754 return ast->CharTy.getAsOpaquePtr(); 755 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) 756 return ast->SignedCharTy.getAsOpaquePtr(); 757 } 758 else if (strstr(type_name, "int")) 759 { 760 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) 761 return ast->IntTy.getAsOpaquePtr(); 762 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) 763 return ast->Int128Ty.getAsOpaquePtr(); 764 } 765 else if (streq(type_name, "wchar_t")) 766 { 767 if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy)) 768 return ast->WCharTy.getAsOpaquePtr(); 769 } 770 else if (streq(type_name, "void")) 771 { 772 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy)) 773 return ast->VoidTy.getAsOpaquePtr(); 774 } 775 } 776 // We weren't able to match up a type name, just search by size 777 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) 778 return ast->CharTy.getAsOpaquePtr(); 779 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) 780 return ast->ShortTy.getAsOpaquePtr(); 781 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) 782 return ast->IntTy.getAsOpaquePtr(); 783 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) 784 return ast->LongTy.getAsOpaquePtr(); 785 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) 786 return ast->LongLongTy.getAsOpaquePtr(); 787 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) 788 return ast->Int128Ty.getAsOpaquePtr(); 789 break; 790 791 case DW_ATE_signed_char: 792 if (type_name) 793 { 794 if (streq(type_name, "signed char")) 795 { 796 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) 797 return ast->SignedCharTy.getAsOpaquePtr(); 798 } 799 } 800 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) 801 return ast->CharTy.getAsOpaquePtr(); 802 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) 803 return ast->SignedCharTy.getAsOpaquePtr(); 804 break; 805 806 case DW_ATE_unsigned: 807 if (type_name) 808 { 809 if (strstr(type_name, "long long")) 810 { 811 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) 812 return ast->UnsignedLongLongTy.getAsOpaquePtr(); 813 } 814 else if (strstr(type_name, "long")) 815 { 816 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) 817 return ast->UnsignedLongTy.getAsOpaquePtr(); 818 } 819 else if (strstr(type_name, "short")) 820 { 821 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) 822 return ast->UnsignedShortTy.getAsOpaquePtr(); 823 } 824 else if (strstr(type_name, "char")) 825 { 826 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) 827 return ast->UnsignedCharTy.getAsOpaquePtr(); 828 } 829 else if (strstr(type_name, "int")) 830 { 831 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) 832 return ast->UnsignedIntTy.getAsOpaquePtr(); 833 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) 834 return ast->UnsignedInt128Ty.getAsOpaquePtr(); 835 } 836 } 837 // We weren't able to match up a type name, just search by size 838 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) 839 return ast->UnsignedCharTy.getAsOpaquePtr(); 840 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) 841 return ast->UnsignedShortTy.getAsOpaquePtr(); 842 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) 843 return ast->UnsignedIntTy.getAsOpaquePtr(); 844 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) 845 return ast->UnsignedLongTy.getAsOpaquePtr(); 846 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) 847 return ast->UnsignedLongLongTy.getAsOpaquePtr(); 848 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) 849 return ast->UnsignedInt128Ty.getAsOpaquePtr(); 850 break; 851 852 case DW_ATE_unsigned_char: 853 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) 854 return ast->UnsignedCharTy.getAsOpaquePtr(); 855 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) 856 return ast->UnsignedShortTy.getAsOpaquePtr(); 857 break; 858 859 case DW_ATE_imaginary_float: 860 break; 861 } 862 } 863 // This assert should fire for anything that we don't catch above so we know 864 // to fix any issues we run into. 865 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!"); 866 return NULL; 867} 868 869clang_type_t 870ClangASTContext::GetBuiltInType_void(ASTContext *ast) 871{ 872 return ast->VoidTy.getAsOpaquePtr(); 873} 874 875clang_type_t 876ClangASTContext::GetBuiltInType_bool() 877{ 878 return getASTContext()->BoolTy.getAsOpaquePtr(); 879} 880 881clang_type_t 882ClangASTContext::GetBuiltInType_objc_id() 883{ 884 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr(); 885} 886 887clang_type_t 888ClangASTContext::GetBuiltInType_objc_Class() 889{ 890 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr(); 891} 892 893clang_type_t 894ClangASTContext::GetBuiltInType_objc_selector() 895{ 896 return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr(); 897} 898 899clang_type_t 900ClangASTContext::GetCStringType (bool is_const) 901{ 902 QualType char_type(getASTContext()->CharTy); 903 904 if (is_const) 905 char_type.addConst(); 906 907 return getASTContext()->getPointerType(char_type).getAsOpaquePtr(); 908} 909 910clang_type_t 911ClangASTContext::GetVoidPtrType (bool is_const) 912{ 913 return GetVoidPtrType(getASTContext(), is_const); 914} 915 916clang_type_t 917ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const) 918{ 919 QualType void_ptr_type(ast->VoidPtrTy); 920 921 if (is_const) 922 void_ptr_type.addConst(); 923 924 return void_ptr_type.getAsOpaquePtr(); 925} 926 927clang_type_t 928ClangASTContext::CopyType (ASTContext *dst_ast, 929 ASTContext *src_ast, 930 clang_type_t clang_type) 931{ 932 FileSystemOptions file_system_options; 933 FileManager file_manager (file_system_options); 934 ASTImporter importer(*dst_ast, file_manager, 935 *src_ast, file_manager, 936 false); 937 938 QualType src (QualType::getFromOpaquePtr(clang_type)); 939 QualType dst (importer.Import(src)); 940 941 return dst.getAsOpaquePtr(); 942} 943 944 945clang::Decl * 946ClangASTContext::CopyDecl (ASTContext *dst_ast, 947 ASTContext *src_ast, 948 clang::Decl *source_decl) 949{ 950 FileSystemOptions file_system_options; 951 FileManager file_manager (file_system_options); 952 ASTImporter importer(*dst_ast, file_manager, 953 *src_ast, file_manager, 954 false); 955 956 return importer.Import(source_decl); 957} 958 959bool 960ClangASTContext::AreTypesSame(ASTContext *ast, 961 clang_type_t type1, 962 clang_type_t type2) 963{ 964 return ast->hasSameType (QualType::getFromOpaquePtr(type1), 965 QualType::getFromOpaquePtr(type2)); 966} 967 968#pragma mark CVR modifiers 969 970clang_type_t 971ClangASTContext::AddConstModifier (clang_type_t clang_type) 972{ 973 if (clang_type) 974 { 975 QualType result(QualType::getFromOpaquePtr(clang_type)); 976 result.addConst(); 977 return result.getAsOpaquePtr(); 978 } 979 return NULL; 980} 981 982clang_type_t 983ClangASTContext::AddRestrictModifier (clang_type_t clang_type) 984{ 985 if (clang_type) 986 { 987 QualType result(QualType::getFromOpaquePtr(clang_type)); 988 result.getQualifiers().setRestrict (true); 989 return result.getAsOpaquePtr(); 990 } 991 return NULL; 992} 993 994clang_type_t 995ClangASTContext::AddVolatileModifier (clang_type_t clang_type) 996{ 997 if (clang_type) 998 { 999 QualType result(QualType::getFromOpaquePtr(clang_type)); 1000 result.getQualifiers().setVolatile (true); 1001 return result.getAsOpaquePtr(); 1002 } 1003 return NULL; 1004} 1005 1006 1007clang_type_t 1008ClangASTContext::GetTypeForDecl (TagDecl *decl) 1009{ 1010 // No need to call the getASTContext() accessor (which can create the AST 1011 // if it isn't created yet, because we can't have created a decl in this 1012 // AST if our AST didn't already exist... 1013 if (m_ast_ap.get()) 1014 return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr(); 1015 return NULL; 1016} 1017 1018clang_type_t 1019ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl) 1020{ 1021 // No need to call the getASTContext() accessor (which can create the AST 1022 // if it isn't created yet, because we can't have created a decl in this 1023 // AST if our AST didn't already exist... 1024 if (m_ast_ap.get()) 1025 return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr(); 1026 return NULL; 1027} 1028 1029#pragma mark Structure, Unions, Classes 1030 1031clang_type_t 1032ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language) 1033{ 1034 ASTContext *ast = getASTContext(); 1035 assert (ast != NULL); 1036 1037 if (decl_ctx == NULL) 1038 decl_ctx = ast->getTranslationUnitDecl(); 1039 1040 1041 if (language == eLanguageTypeObjC) 1042 { 1043 bool isForwardDecl = true; 1044 bool isInternal = false; 1045 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal); 1046 } 1047 1048 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and 1049 // we will need to update this code. I was told to currently always use 1050 // the CXXRecordDecl class since we often don't know from debug information 1051 // if something is struct or a class, so we default to always use the more 1052 // complete definition just in case. 1053 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast, 1054 (TagDecl::TagKind)kind, 1055 decl_ctx, 1056 SourceLocation(), 1057 SourceLocation(), 1058 name && name[0] ? &ast->Idents.get(name) : NULL); 1059 1060 return ast->getTagDeclType(decl).getAsOpaquePtr(); 1061} 1062 1063bool 1064ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern) 1065{ 1066 if (clang_type == NULL) 1067 return false; 1068 1069 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 1070 1071 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 1072 switch (type_class) 1073 { 1074 case clang::Type::Record: 1075 { 1076 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); 1077 if (cxx_record_decl) 1078 { 1079 cxx_record_decl->setHasExternalLexicalStorage (has_extern); 1080 cxx_record_decl->setHasExternalVisibleStorage (has_extern); 1081 return true; 1082 } 1083 } 1084 break; 1085 1086 case clang::Type::Enum: 1087 { 1088 EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl(); 1089 if (enum_decl) 1090 { 1091 enum_decl->setHasExternalLexicalStorage (has_extern); 1092 enum_decl->setHasExternalVisibleStorage (has_extern); 1093 return true; 1094 } 1095 } 1096 break; 1097 1098 case clang::Type::ObjCObject: 1099 case clang::Type::ObjCInterface: 1100 { 1101 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 1102 assert (objc_class_type); 1103 if (objc_class_type) 1104 { 1105 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1106 1107 if (class_interface_decl) 1108 { 1109 class_interface_decl->setHasExternalLexicalStorage (has_extern); 1110 class_interface_decl->setHasExternalVisibleStorage (has_extern); 1111 return true; 1112 } 1113 } 1114 } 1115 break; 1116 1117 case clang::Type::Typedef: 1118 return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern); 1119 1120 default: 1121 break; 1122 } 1123 return false; 1124} 1125 1126static bool 1127IsOperator (const char *name, OverloadedOperatorKind &op_kind) 1128{ 1129 if (name == NULL || name[0] == '\0') 1130 return false; 1131 1132#define OPERATOR_PREFIX "operator" 1133#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1) 1134 1135 const char *post_op_name = NULL; 1136 1137 bool no_space = true; 1138 1139 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH)) 1140 return false; 1141 1142 post_op_name = name + OPERATOR_PREFIX_LENGTH; 1143 1144 if (post_op_name[0] == ' ') 1145 { 1146 post_op_name++; 1147 no_space = false; 1148 } 1149 1150#undef OPERATOR_PREFIX 1151#undef OPERATOR_PREFIX_LENGTH 1152 1153 // This is an operator, set the overloaded operator kind to invalid 1154 // in case this is a conversion operator... 1155 op_kind = NUM_OVERLOADED_OPERATORS; 1156 1157 switch (post_op_name[0]) 1158 { 1159 default: 1160 if (no_space) 1161 return false; 1162 break; 1163 case 'n': 1164 if (no_space) 1165 return false; 1166 if (strcmp (post_op_name, "new") == 0) 1167 op_kind = OO_New; 1168 else if (strcmp (post_op_name, "new[]") == 0) 1169 op_kind = OO_Array_New; 1170 break; 1171 1172 case 'd': 1173 if (no_space) 1174 return false; 1175 if (strcmp (post_op_name, "delete") == 0) 1176 op_kind = OO_Delete; 1177 else if (strcmp (post_op_name, "delete[]") == 0) 1178 op_kind = OO_Array_Delete; 1179 break; 1180 1181 case '+': 1182 if (post_op_name[1] == '\0') 1183 op_kind = OO_Plus; 1184 else if (post_op_name[2] == '\0') 1185 { 1186 if (post_op_name[1] == '=') 1187 op_kind = OO_PlusEqual; 1188 else if (post_op_name[1] == '+') 1189 op_kind = OO_PlusPlus; 1190 } 1191 break; 1192 1193 case '-': 1194 if (post_op_name[1] == '\0') 1195 op_kind = OO_Minus; 1196 else if (post_op_name[2] == '\0') 1197 { 1198 switch (post_op_name[1]) 1199 { 1200 case '=': op_kind = OO_MinusEqual; break; 1201 case '-': op_kind = OO_MinusMinus; break; 1202 case '>': op_kind = OO_Arrow; break; 1203 } 1204 } 1205 else if (post_op_name[3] == '\0') 1206 { 1207 if (post_op_name[2] == '*') 1208 op_kind = OO_ArrowStar; break; 1209 } 1210 break; 1211 1212 case '*': 1213 if (post_op_name[1] == '\0') 1214 op_kind = OO_Star; 1215 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 1216 op_kind = OO_StarEqual; 1217 break; 1218 1219 case '/': 1220 if (post_op_name[1] == '\0') 1221 op_kind = OO_Slash; 1222 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 1223 op_kind = OO_SlashEqual; 1224 break; 1225 1226 case '%': 1227 if (post_op_name[1] == '\0') 1228 op_kind = OO_Percent; 1229 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 1230 op_kind = OO_PercentEqual; 1231 break; 1232 1233 1234 case '^': 1235 if (post_op_name[1] == '\0') 1236 op_kind = OO_Caret; 1237 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 1238 op_kind = OO_CaretEqual; 1239 break; 1240 1241 case '&': 1242 if (post_op_name[1] == '\0') 1243 op_kind = OO_Amp; 1244 else if (post_op_name[2] == '\0') 1245 { 1246 switch (post_op_name[1]) 1247 { 1248 case '=': op_kind = OO_AmpEqual; break; 1249 case '&': op_kind = OO_AmpAmp; break; 1250 } 1251 } 1252 break; 1253 1254 case '|': 1255 if (post_op_name[1] == '\0') 1256 op_kind = OO_Pipe; 1257 else if (post_op_name[2] == '\0') 1258 { 1259 switch (post_op_name[1]) 1260 { 1261 case '=': op_kind = OO_PipeEqual; break; 1262 case '|': op_kind = OO_PipePipe; break; 1263 } 1264 } 1265 break; 1266 1267 case '~': 1268 if (post_op_name[1] == '\0') 1269 op_kind = OO_Tilde; 1270 break; 1271 1272 case '!': 1273 if (post_op_name[1] == '\0') 1274 op_kind = OO_Exclaim; 1275 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 1276 op_kind = OO_ExclaimEqual; 1277 break; 1278 1279 case '=': 1280 if (post_op_name[1] == '\0') 1281 op_kind = OO_Equal; 1282 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 1283 op_kind = OO_EqualEqual; 1284 break; 1285 1286 case '<': 1287 if (post_op_name[1] == '\0') 1288 op_kind = OO_Less; 1289 else if (post_op_name[2] == '\0') 1290 { 1291 switch (post_op_name[1]) 1292 { 1293 case '<': op_kind = OO_LessLess; break; 1294 case '=': op_kind = OO_LessEqual; break; 1295 } 1296 } 1297 else if (post_op_name[3] == '\0') 1298 { 1299 if (post_op_name[2] == '=') 1300 op_kind = OO_LessLessEqual; 1301 } 1302 break; 1303 1304 case '>': 1305 if (post_op_name[1] == '\0') 1306 op_kind = OO_Greater; 1307 else if (post_op_name[2] == '\0') 1308 { 1309 switch (post_op_name[1]) 1310 { 1311 case '>': op_kind = OO_GreaterGreater; break; 1312 case '=': op_kind = OO_GreaterEqual; break; 1313 } 1314 } 1315 else if (post_op_name[1] == '>' && 1316 post_op_name[2] == '=' && 1317 post_op_name[3] == '\0') 1318 { 1319 op_kind = OO_GreaterGreaterEqual; 1320 } 1321 break; 1322 1323 case ',': 1324 if (post_op_name[1] == '\0') 1325 op_kind = OO_Comma; 1326 break; 1327 1328 case '(': 1329 if (post_op_name[1] == ')' && post_op_name[2] == '\0') 1330 op_kind = OO_Call; 1331 break; 1332 1333 case '[': 1334 if (post_op_name[1] == ']' && post_op_name[2] == '\0') 1335 op_kind = OO_Subscript; 1336 break; 1337 } 1338 1339 return true; 1340} 1341 1342CXXMethodDecl * 1343ClangASTContext::AddMethodToCXXRecordType 1344( 1345 ASTContext *ast, 1346 clang_type_t record_opaque_type, 1347 const char *name, 1348 clang_type_t method_opaque_type, 1349 lldb::AccessType access, 1350 bool is_virtual, 1351 bool is_static, 1352 bool is_inline, 1353 bool is_explicit 1354) 1355{ 1356 if (!record_opaque_type || !method_opaque_type || !name) 1357 return NULL; 1358 1359 assert(ast); 1360 1361 IdentifierTable *identifier_table = &ast->Idents; 1362 1363 assert(identifier_table); 1364 1365 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type)); 1366 1367 CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl(); 1368 1369 if (cxx_record_decl == NULL) 1370 return NULL; 1371 1372 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); 1373 1374 CXXMethodDecl *cxx_method_decl = NULL; 1375 1376 DeclarationName decl_name (&identifier_table->get(name)); 1377 1378 const bool is_implicitly_declared = false; 1379 1380 const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr()); 1381 1382 if (function_Type == NULL) 1383 return NULL; 1384 1385 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type)); 1386 1387 if (!method_function_prototype) 1388 return NULL; 1389 1390 unsigned int num_params = method_function_prototype->getNumArgs(); 1391 1392 if (name[0] == '~') 1393 { 1394 cxx_method_decl = CXXDestructorDecl::Create (*ast, 1395 cxx_record_decl, 1396 SourceLocation(), 1397 DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()), 1398 method_qual_type, 1399 NULL, 1400 is_inline, 1401 is_implicitly_declared); 1402 } 1403 else if (decl_name == cxx_record_decl->getDeclName()) 1404 { 1405 cxx_method_decl = CXXConstructorDecl::Create (*ast, 1406 cxx_record_decl, 1407 SourceLocation(), 1408 DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()), 1409 method_qual_type, 1410 NULL, // TypeSourceInfo * 1411 is_explicit, 1412 is_inline, 1413 is_implicitly_declared); 1414 } 1415 else 1416 { 1417 1418 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS; 1419 if (IsOperator (name, op_kind)) 1420 { 1421 if (op_kind != NUM_OVERLOADED_OPERATORS) 1422 { 1423 cxx_method_decl = CXXMethodDecl::Create (*ast, 1424 cxx_record_decl, 1425 SourceLocation(), 1426 DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()), 1427 method_qual_type, 1428 NULL, // TypeSourceInfo * 1429 is_static, 1430 SC_None, 1431 is_inline, 1432 SourceLocation()); 1433 } 1434 else if (num_params == 0) 1435 { 1436 // Conversion operators don't take params... 1437 cxx_method_decl = CXXConversionDecl::Create (*ast, 1438 cxx_record_decl, 1439 SourceLocation(), 1440 DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()), 1441 method_qual_type, 1442 NULL, // TypeSourceInfo * 1443 is_inline, 1444 is_explicit, 1445 SourceLocation()); 1446 } 1447 } 1448 1449 if (cxx_method_decl == NULL) 1450 { 1451 cxx_method_decl = CXXMethodDecl::Create (*ast, 1452 cxx_record_decl, 1453 SourceLocation(), 1454 DeclarationNameInfo (decl_name, SourceLocation()), 1455 method_qual_type, 1456 NULL, // TypeSourceInfo * 1457 is_static, 1458 SC_None, 1459 is_inline, 1460 SourceLocation()); 1461 } 1462 } 1463 1464 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access); 1465 1466 cxx_method_decl->setAccess (access_specifier); 1467 cxx_method_decl->setVirtualAsWritten (is_virtual); 1468 1469 // Populate the method decl with parameter decls 1470 1471 ParmVarDecl *params[num_params]; 1472 1473 for (int param_index = 0; 1474 param_index < num_params; 1475 ++param_index) 1476 { 1477 params[param_index] = ParmVarDecl::Create (*ast, 1478 cxx_method_decl, 1479 SourceLocation(), 1480 SourceLocation(), 1481 NULL, // anonymous 1482 method_function_prototype->getArgType(param_index), 1483 NULL, 1484 SC_None, 1485 SC_None, 1486 NULL); 1487 } 1488 1489 cxx_method_decl->setParams (params, num_params); 1490 1491 cxx_record_decl->addDecl (cxx_method_decl); 1492 1493// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic()); 1494// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate()); 1495// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD()); 1496// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty()); 1497// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract()); 1498// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor()); 1499// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor()); 1500// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment()); 1501// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor()); 1502 return cxx_method_decl; 1503} 1504 1505bool 1506ClangASTContext::AddFieldToRecordType 1507( 1508 ASTContext *ast, 1509 clang_type_t record_clang_type, 1510 const char *name, 1511 clang_type_t field_type, 1512 AccessType access, 1513 uint32_t bitfield_bit_size 1514) 1515{ 1516 if (record_clang_type == NULL || field_type == NULL) 1517 return false; 1518 1519 IdentifierTable *identifier_table = &ast->Idents; 1520 1521 assert (ast != NULL); 1522 assert (identifier_table != NULL); 1523 1524 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type)); 1525 1526 const clang::Type *clang_type = record_qual_type.getTypePtr(); 1527 if (clang_type) 1528 { 1529 const RecordType *record_type = dyn_cast<RecordType>(clang_type); 1530 1531 if (record_type) 1532 { 1533 RecordDecl *record_decl = record_type->getDecl(); 1534 1535 clang::Expr *bit_width = NULL; 1536 if (bitfield_bit_size != 0) 1537 { 1538 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size); 1539 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation()); 1540 } 1541 FieldDecl *field = FieldDecl::Create (*ast, 1542 record_decl, 1543 SourceLocation(), 1544 SourceLocation(), 1545 name ? &identifier_table->get(name) : NULL, // Identifier 1546 QualType::getFromOpaquePtr(field_type), // Field type 1547 NULL, // DeclaratorInfo * 1548 bit_width, // BitWidth 1549 false); // Mutable 1550 1551 field->setAccess (ConvertAccessTypeToAccessSpecifier (access)); 1552 1553 if (field) 1554 { 1555 record_decl->addDecl(field); 1556 } 1557 } 1558 else 1559 { 1560 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type); 1561 if (objc_class_type) 1562 { 1563 bool is_synthesized = false; 1564 ClangASTContext::AddObjCClassIVar (ast, 1565 record_clang_type, 1566 name, 1567 field_type, 1568 access, 1569 bitfield_bit_size, 1570 is_synthesized); 1571 } 1572 } 1573 } 1574 return false; 1575} 1576 1577bool 1578ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size) 1579{ 1580 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size); 1581} 1582 1583bool 1584ClangASTContext::FieldIsBitfield 1585( 1586 ASTContext *ast, 1587 FieldDecl* field, 1588 uint32_t& bitfield_bit_size 1589) 1590{ 1591 if (ast == NULL || field == NULL) 1592 return false; 1593 1594 if (field->isBitField()) 1595 { 1596 Expr* bit_width_expr = field->getBitWidth(); 1597 if (bit_width_expr) 1598 { 1599 llvm::APSInt bit_width_apsint; 1600 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast)) 1601 { 1602 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX); 1603 return true; 1604 } 1605 } 1606 } 1607 return false; 1608} 1609 1610bool 1611ClangASTContext::RecordHasFields (const RecordDecl *record_decl) 1612{ 1613 if (record_decl == NULL) 1614 return false; 1615 1616 if (!record_decl->field_empty()) 1617 return true; 1618 1619 // No fields, lets check this is a CXX record and check the base classes 1620 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1621 if (cxx_record_decl) 1622 { 1623 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1624 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1625 base_class != base_class_end; 1626 ++base_class) 1627 { 1628 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1629 if (RecordHasFields(base_class_decl)) 1630 return true; 1631 } 1632 } 1633 return false; 1634} 1635 1636void 1637ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities) 1638{ 1639 if (clang_type) 1640 { 1641 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 1642 1643 const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr()); 1644 if (record_type) 1645 { 1646 RecordDecl *record_decl = record_type->getDecl(); 1647 if (record_decl) 1648 { 1649 uint32_t field_idx; 1650 RecordDecl::field_iterator field, field_end; 1651 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0; 1652 field != field_end; 1653 ++field, ++field_idx) 1654 { 1655 // If no accessibility was assigned, assign the correct one 1656 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none) 1657 field->setAccess ((AccessSpecifier)default_accessibility); 1658 } 1659 } 1660 } 1661 } 1662} 1663 1664#pragma mark C++ Base Classes 1665 1666CXXBaseSpecifier * 1667ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class) 1668{ 1669 if (base_class_type) 1670 return new CXXBaseSpecifier (SourceRange(), 1671 is_virtual, 1672 base_of_class, 1673 ConvertAccessTypeToAccessSpecifier (access), 1674 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)), 1675 SourceLocation()); 1676 return NULL; 1677} 1678 1679void 1680ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes) 1681{ 1682 for (unsigned i=0; i<num_base_classes; ++i) 1683 { 1684 delete base_classes[i]; 1685 base_classes[i] = NULL; 1686 } 1687} 1688 1689bool 1690ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes) 1691{ 1692 if (class_clang_type) 1693 { 1694 CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl(); 1695 if (cxx_record_decl) 1696 { 1697 cxx_record_decl->setBases(base_classes, num_base_classes); 1698 return true; 1699 } 1700 } 1701 return false; 1702} 1703#pragma mark Objective C Classes 1704 1705clang_type_t 1706ClangASTContext::CreateObjCClass 1707( 1708 const char *name, 1709 DeclContext *decl_ctx, 1710 bool isForwardDecl, 1711 bool isInternal 1712) 1713{ 1714 ASTContext *ast = getASTContext(); 1715 assert (ast != NULL); 1716 assert (name && name[0]); 1717 if (decl_ctx == NULL) 1718 decl_ctx = ast->getTranslationUnitDecl(); 1719 1720 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and 1721 // we will need to update this code. I was told to currently always use 1722 // the CXXRecordDecl class since we often don't know from debug information 1723 // if something is struct or a class, so we default to always use the more 1724 // complete definition just in case. 1725 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast, 1726 decl_ctx, 1727 SourceLocation(), 1728 &ast->Idents.get(name), 1729 SourceLocation(), 1730 isForwardDecl, 1731 isInternal); 1732 1733 return ast->getObjCInterfaceType(decl).getAsOpaquePtr(); 1734} 1735 1736bool 1737ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type) 1738{ 1739 if (class_opaque_type && super_opaque_type) 1740 { 1741 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1742 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type)); 1743 const clang::Type *class_type = class_qual_type.getTypePtr(); 1744 const clang::Type *super_type = super_qual_type.getTypePtr(); 1745 if (class_type && super_type) 1746 { 1747 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1748 const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type); 1749 if (objc_class_type && objc_super_type) 1750 { 1751 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1752 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface(); 1753 if (class_interface_decl && super_interface_decl) 1754 { 1755 class_interface_decl->setSuperClass(super_interface_decl); 1756 return true; 1757 } 1758 } 1759 } 1760 } 1761 return false; 1762} 1763 1764 1765bool 1766ClangASTContext::AddObjCClassIVar 1767( 1768 ASTContext *ast, 1769 clang_type_t class_opaque_type, 1770 const char *name, 1771 clang_type_t ivar_opaque_type, 1772 AccessType access, 1773 uint32_t bitfield_bit_size, 1774 bool is_synthesized 1775) 1776{ 1777 if (class_opaque_type == NULL || ivar_opaque_type == NULL) 1778 return false; 1779 1780 IdentifierTable *identifier_table = &ast->Idents; 1781 1782 assert (ast != NULL); 1783 assert (identifier_table != NULL); 1784 1785 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1786 1787 const clang::Type *class_type = class_qual_type.getTypePtr(); 1788 if (class_type) 1789 { 1790 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1791 1792 if (objc_class_type) 1793 { 1794 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1795 1796 if (class_interface_decl) 1797 { 1798 clang::Expr *bit_width = NULL; 1799 if (bitfield_bit_size != 0) 1800 { 1801 APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size); 1802 bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation()); 1803 } 1804 1805 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast, 1806 class_interface_decl, 1807 SourceLocation(), 1808 SourceLocation(), 1809 &identifier_table->get(name), // Identifier 1810 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type 1811 NULL, // TypeSourceInfo * 1812 ConvertAccessTypeToObjCIvarAccessControl (access), 1813 bit_width, 1814 is_synthesized); 1815 1816 if (field) 1817 { 1818 class_interface_decl->addDecl(field); 1819 return true; 1820 } 1821 } 1822 } 1823 } 1824 return false; 1825} 1826 1827 1828bool 1829ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass) 1830{ 1831 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1832 1833 const clang::Type *class_type = class_qual_type.getTypePtr(); 1834 if (class_type) 1835 { 1836 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1837 1838 if (objc_class_type) 1839 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass); 1840 } 1841 return false; 1842} 1843 1844bool 1845ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass) 1846{ 1847 while (class_interface_decl) 1848 { 1849 if (class_interface_decl->ivar_size() > 0) 1850 return true; 1851 1852 if (check_superclass) 1853 class_interface_decl = class_interface_decl->getSuperClass(); 1854 else 1855 break; 1856 } 1857 return false; 1858} 1859 1860ObjCMethodDecl * 1861ClangASTContext::AddMethodToObjCObjectType 1862( 1863 ASTContext *ast, 1864 clang_type_t class_opaque_type, 1865 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") 1866 clang_type_t method_opaque_type, 1867 lldb::AccessType access 1868) 1869{ 1870 if (class_opaque_type == NULL || method_opaque_type == NULL) 1871 return NULL; 1872 1873 IdentifierTable *identifier_table = &ast->Idents; 1874 1875 assert (ast != NULL); 1876 assert (identifier_table != NULL); 1877 1878 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1879 1880 const clang::Type *class_type = class_qual_type.getTypePtr(); 1881 if (class_type == NULL) 1882 return NULL; 1883 1884 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1885 1886 if (objc_class_type == NULL) 1887 return NULL; 1888 1889 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1890 1891 if (class_interface_decl == NULL) 1892 return NULL; 1893 1894 const char *selector_start = ::strchr (name, ' '); 1895 if (selector_start == NULL) 1896 return NULL; 1897 1898 selector_start++; 1899 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_')) 1900 return NULL; 1901 llvm::SmallVector<IdentifierInfo *, 12> selector_idents; 1902 1903 size_t len = 0; 1904 const char *start; 1905 //printf ("name = '%s'\n", name); 1906 1907 unsigned num_selectors_with_args = 0; 1908 for (start = selector_start; 1909 start && *start != '\0' && *start != ']'; 1910 start += len) 1911 { 1912 len = ::strcspn(start, ":]"); 1913 bool has_arg = (start[len] == ':'); 1914 if (has_arg) 1915 ++num_selectors_with_args; 1916 selector_idents.push_back (&identifier_table->get (StringRef (start, len))); 1917 if (has_arg) 1918 len += 1; 1919 } 1920 1921 1922 if (selector_idents.size() == 0) 1923 return 0; 1924 1925 clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, 1926 selector_idents.data()); 1927 1928 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); 1929 1930 // Populate the method decl with parameter decls 1931 const clang::Type *method_type(method_qual_type.getTypePtr()); 1932 1933 if (method_type == NULL) 1934 return NULL; 1935 1936 const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type)); 1937 1938 if (!method_function_prototype) 1939 return NULL; 1940 1941 1942 bool is_variadic = false; 1943 bool is_synthesized = false; 1944 bool is_defined = false; 1945 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None; 1946 1947 const unsigned num_args = method_function_prototype->getNumArgs(); 1948 1949 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast, 1950 SourceLocation(), // beginLoc, 1951 SourceLocation(), // endLoc, 1952 method_selector, 1953 method_function_prototype->getResultType(), 1954 NULL, // TypeSourceInfo *ResultTInfo, 1955 GetDeclContextForType (class_opaque_type), 1956 name[0] == '-', 1957 is_variadic, 1958 is_synthesized, 1959 is_defined, 1960 imp_control, 1961 num_args); 1962 1963 1964 if (objc_method_decl == NULL) 1965 return NULL; 1966 1967 if (num_args > 0) 1968 { 1969 llvm::SmallVector<ParmVarDecl *, 12> params; 1970 1971 for (int param_index = 0; param_index < num_args; ++param_index) 1972 { 1973 params.push_back (ParmVarDecl::Create (*ast, 1974 objc_method_decl, 1975 SourceLocation(), 1976 SourceLocation(), 1977 NULL, // anonymous 1978 method_function_prototype->getArgType(param_index), 1979 NULL, 1980 SC_Auto, 1981 SC_Auto, 1982 NULL)); 1983 } 1984 1985 objc_method_decl->setMethodParams(*ast, params.data(), params.size(), num_args); 1986 } 1987 1988 class_interface_decl->addDecl (objc_method_decl); 1989 1990 1991 return objc_method_decl; 1992} 1993 1994 1995uint32_t 1996ClangASTContext::GetTypeInfo 1997( 1998 clang_type_t clang_type, 1999 clang::ASTContext *ast, 2000 clang_type_t *pointee_or_element_clang_type 2001) 2002{ 2003 if (clang_type == NULL) 2004 return 0; 2005 2006 if (pointee_or_element_clang_type) 2007 *pointee_or_element_clang_type = NULL; 2008 2009 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2010 2011 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2012 switch (type_class) 2013 { 2014 case clang::Type::Builtin: 2015 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 2016 { 2017 case clang::BuiltinType::ObjCId: 2018 case clang::BuiltinType::ObjCClass: 2019 if (ast && pointee_or_element_clang_type) 2020 *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr(); 2021 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue; 2022 2023 default: 2024 break; 2025 } 2026 return eTypeIsBuiltIn | eTypeHasValue; 2027 2028 case clang::Type::BlockPointer: 2029 if (pointee_or_element_clang_type) 2030 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); 2031 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock; 2032 2033 case clang::Type::Complex: return eTypeIsBuiltIn | eTypeHasValue; 2034 2035 case clang::Type::ConstantArray: 2036 case clang::Type::DependentSizedArray: 2037 case clang::Type::IncompleteArray: 2038 case clang::Type::VariableArray: 2039 if (pointee_or_element_clang_type) 2040 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr(); 2041 return eTypeHasChildren | eTypeIsArray; 2042 2043 case clang::Type::DependentName: return 0; 2044 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector; 2045 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate; 2046 case clang::Type::Decltype: return 0; 2047 2048 case clang::Type::Enum: 2049 if (pointee_or_element_clang_type) 2050 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr(); 2051 return eTypeIsEnumeration | eTypeHasValue; 2052 2053 case clang::Type::Elaborated: return 0; 2054 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector; 2055 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue; 2056 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue; 2057 case clang::Type::InjectedClassName: return 0; 2058 2059 case clang::Type::LValueReference: 2060 case clang::Type::RValueReference: 2061 if (pointee_or_element_clang_type) 2062 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(); 2063 return eTypeHasChildren | eTypeIsReference | eTypeHasValue; 2064 2065 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue; 2066 2067 case clang::Type::ObjCObjectPointer: 2068 if (pointee_or_element_clang_type) 2069 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); 2070 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue; 2071 2072 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; 2073 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; 2074 2075 case clang::Type::Pointer: 2076 if (pointee_or_element_clang_type) 2077 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); 2078 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue; 2079 2080 case clang::Type::Record: 2081 if (qual_type->getAsCXXRecordDecl()) 2082 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus; 2083 else 2084 return eTypeHasChildren | eTypeIsStructUnion; 2085 break; 2086 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate; 2087 case clang::Type::TemplateTypeParm: return eTypeIsTemplate; 2088 case clang::Type::TemplateSpecialization: return eTypeIsTemplate; 2089 2090 case clang::Type::Typedef: 2091 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 2092 ast, 2093 pointee_or_element_clang_type); 2094 2095 case clang::Type::TypeOfExpr: return 0; 2096 case clang::Type::TypeOf: return 0; 2097 case clang::Type::UnresolvedUsing: return 0; 2098 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector; 2099 default: return 0; 2100 } 2101 return 0; 2102} 2103 2104 2105#pragma mark Aggregate Types 2106 2107bool 2108ClangASTContext::IsAggregateType (clang_type_t clang_type) 2109{ 2110 if (clang_type == NULL) 2111 return false; 2112 2113 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2114 2115 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2116 switch (type_class) 2117 { 2118 case clang::Type::IncompleteArray: 2119 case clang::Type::VariableArray: 2120 case clang::Type::ConstantArray: 2121 case clang::Type::ExtVector: 2122 case clang::Type::Vector: 2123 case clang::Type::Record: 2124 case clang::Type::ObjCObject: 2125 case clang::Type::ObjCInterface: 2126 return true; 2127 2128 case clang::Type::Typedef: 2129 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); 2130 2131 default: 2132 break; 2133 } 2134 // The clang type does have a value 2135 return false; 2136} 2137 2138uint32_t 2139ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes) 2140{ 2141 if (clang_type == NULL) 2142 return 0; 2143 2144 uint32_t num_children = 0; 2145 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2146 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2147 switch (type_class) 2148 { 2149 case clang::Type::Builtin: 2150 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 2151 { 2152 case clang::BuiltinType::ObjCId: // child is Class 2153 case clang::BuiltinType::ObjCClass: // child is Class 2154 num_children = 1; 2155 break; 2156 2157 default: 2158 break; 2159 } 2160 break; 2161 2162 case clang::Type::Complex: return 0; 2163 2164 case clang::Type::Record: 2165 if (GetCompleteQualType (ast, qual_type)) 2166 { 2167 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 2168 const RecordDecl *record_decl = record_type->getDecl(); 2169 assert(record_decl); 2170 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2171 if (cxx_record_decl) 2172 { 2173 if (omit_empty_base_classes) 2174 { 2175 // Check each base classes to see if it or any of its 2176 // base classes contain any fields. This can help 2177 // limit the noise in variable views by not having to 2178 // show base classes that contain no members. 2179 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2180 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2181 base_class != base_class_end; 2182 ++base_class) 2183 { 2184 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2185 2186 // Skip empty base classes 2187 if (RecordHasFields(base_class_decl) == false) 2188 continue; 2189 2190 num_children++; 2191 } 2192 } 2193 else 2194 { 2195 // Include all base classes 2196 num_children += cxx_record_decl->getNumBases(); 2197 } 2198 2199 } 2200 RecordDecl::field_iterator field, field_end; 2201 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) 2202 ++num_children; 2203 } 2204 break; 2205 2206 case clang::Type::ObjCObject: 2207 case clang::Type::ObjCInterface: 2208 if (GetCompleteQualType (ast, qual_type)) 2209 { 2210 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 2211 assert (objc_class_type); 2212 if (objc_class_type) 2213 { 2214 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 2215 2216 if (class_interface_decl) 2217 { 2218 2219 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 2220 if (superclass_interface_decl) 2221 { 2222 if (omit_empty_base_classes) 2223 { 2224 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true)) 2225 ++num_children; 2226 } 2227 else 2228 ++num_children; 2229 } 2230 2231 num_children += class_interface_decl->ivar_size(); 2232 } 2233 } 2234 } 2235 break; 2236 2237 case clang::Type::ObjCObjectPointer: 2238 { 2239 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr()); 2240 QualType pointee_type = pointer_type->getPointeeType(); 2241 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, 2242 pointee_type.getAsOpaquePtr(), 2243 omit_empty_base_classes); 2244 // If this type points to a simple type, then it has 1 child 2245 if (num_pointee_children == 0) 2246 num_children = 1; 2247 else 2248 num_children = num_pointee_children; 2249 } 2250 break; 2251 2252 case clang::Type::ConstantArray: 2253 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); 2254 break; 2255 2256 case clang::Type::Pointer: 2257 { 2258 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 2259 QualType pointee_type (pointer_type->getPointeeType()); 2260 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, 2261 pointee_type.getAsOpaquePtr(), 2262 omit_empty_base_classes); 2263 if (num_pointee_children == 0) 2264 { 2265 // We have a pointer to a pointee type that claims it has no children. 2266 // We will want to look at 2267 num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr()); 2268 } 2269 else 2270 num_children = num_pointee_children; 2271 } 2272 break; 2273 2274 case clang::Type::LValueReference: 2275 case clang::Type::RValueReference: 2276 { 2277 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 2278 QualType pointee_type = reference_type->getPointeeType(); 2279 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, 2280 pointee_type.getAsOpaquePtr(), 2281 omit_empty_base_classes); 2282 // If this type points to a simple type, then it has 1 child 2283 if (num_pointee_children == 0) 2284 num_children = 1; 2285 else 2286 num_children = num_pointee_children; 2287 } 2288 break; 2289 2290 2291 case clang::Type::Typedef: 2292 num_children = ClangASTContext::GetNumChildren (ast, 2293 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 2294 omit_empty_base_classes); 2295 break; 2296 2297 default: 2298 break; 2299 } 2300 return num_children; 2301} 2302 2303// If a pointer to a pointee type (the clang_type arg) says that it has no 2304// children, then we either need to trust it, or override it and return a 2305// different result. For example, an "int *" has one child that is an integer, 2306// but a function pointer doesn't have any children. Likewise if a Record type 2307// claims it has no children, then there really is nothing to show. 2308uint32_t 2309ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type) 2310{ 2311 if (clang_type == NULL) 2312 return 0; 2313 2314 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2315 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2316 switch (type_class) 2317 { 2318 case clang::Type::Builtin: 2319 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 2320 { 2321 case clang::BuiltinType::Void: 2322 case clang::BuiltinType::NullPtr: 2323 return 0; 2324 case clang::BuiltinType::Bool: 2325 case clang::BuiltinType::Char_U: 2326 case clang::BuiltinType::UChar: 2327 case clang::BuiltinType::WChar_U: 2328 case clang::BuiltinType::Char16: 2329 case clang::BuiltinType::Char32: 2330 case clang::BuiltinType::UShort: 2331 case clang::BuiltinType::UInt: 2332 case clang::BuiltinType::ULong: 2333 case clang::BuiltinType::ULongLong: 2334 case clang::BuiltinType::UInt128: 2335 case clang::BuiltinType::Char_S: 2336 case clang::BuiltinType::SChar: 2337 case clang::BuiltinType::WChar_S: 2338 case clang::BuiltinType::Short: 2339 case clang::BuiltinType::Int: 2340 case clang::BuiltinType::Long: 2341 case clang::BuiltinType::LongLong: 2342 case clang::BuiltinType::Int128: 2343 case clang::BuiltinType::Float: 2344 case clang::BuiltinType::Double: 2345 case clang::BuiltinType::LongDouble: 2346 case clang::BuiltinType::Dependent: 2347 case clang::BuiltinType::Overload: 2348 case clang::BuiltinType::ObjCId: 2349 case clang::BuiltinType::ObjCClass: 2350 case clang::BuiltinType::ObjCSel: 2351 return 1; 2352 } 2353 break; 2354 2355 case clang::Type::Complex: return 1; 2356 case clang::Type::Pointer: return 1; 2357 case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them 2358 case clang::Type::LValueReference: return 1; 2359 case clang::Type::RValueReference: return 1; 2360 case clang::Type::MemberPointer: return 0; 2361 case clang::Type::ConstantArray: return 0; 2362 case clang::Type::IncompleteArray: return 0; 2363 case clang::Type::VariableArray: return 0; 2364 case clang::Type::DependentSizedArray: return 0; 2365 case clang::Type::DependentSizedExtVector: return 0; 2366 case clang::Type::Vector: return 0; 2367 case clang::Type::ExtVector: return 0; 2368 case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children... 2369 case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children... 2370 case clang::Type::UnresolvedUsing: return 0; 2371 case clang::Type::Paren: return 0; 2372 case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); 2373 case clang::Type::TypeOfExpr: return 0; 2374 case clang::Type::TypeOf: return 0; 2375 case clang::Type::Decltype: return 0; 2376 case clang::Type::Record: return 0; 2377 case clang::Type::Enum: return 1; 2378 case clang::Type::Elaborated: return 1; 2379 case clang::Type::TemplateTypeParm: return 1; 2380 case clang::Type::SubstTemplateTypeParm: return 1; 2381 case clang::Type::TemplateSpecialization: return 1; 2382 case clang::Type::InjectedClassName: return 0; 2383 case clang::Type::DependentName: return 1; 2384 case clang::Type::DependentTemplateSpecialization: return 1; 2385 case clang::Type::ObjCObject: return 0; 2386 case clang::Type::ObjCInterface: return 0; 2387 case clang::Type::ObjCObjectPointer: return 1; 2388 default: 2389 break; 2390 } 2391 return 0; 2392} 2393 2394clang_type_t 2395ClangASTContext::GetChildClangTypeAtIndex 2396( 2397 const char *parent_name, 2398 clang_type_t parent_clang_type, 2399 uint32_t idx, 2400 bool transparent_pointers, 2401 bool omit_empty_base_classes, 2402 std::string& child_name, 2403 uint32_t &child_byte_size, 2404 int32_t &child_byte_offset, 2405 uint32_t &child_bitfield_bit_size, 2406 uint32_t &child_bitfield_bit_offset, 2407 bool &child_is_base_class, 2408 bool &child_is_deref_of_parent 2409) 2410{ 2411 if (parent_clang_type) 2412 2413 return GetChildClangTypeAtIndex (getASTContext(), 2414 parent_name, 2415 parent_clang_type, 2416 idx, 2417 transparent_pointers, 2418 omit_empty_base_classes, 2419 child_name, 2420 child_byte_size, 2421 child_byte_offset, 2422 child_bitfield_bit_size, 2423 child_bitfield_bit_offset, 2424 child_is_base_class, 2425 child_is_deref_of_parent); 2426 return NULL; 2427} 2428 2429clang_type_t 2430ClangASTContext::GetChildClangTypeAtIndex 2431( 2432 ASTContext *ast, 2433 const char *parent_name, 2434 clang_type_t parent_clang_type, 2435 uint32_t idx, 2436 bool transparent_pointers, 2437 bool omit_empty_base_classes, 2438 std::string& child_name, 2439 uint32_t &child_byte_size, 2440 int32_t &child_byte_offset, 2441 uint32_t &child_bitfield_bit_size, 2442 uint32_t &child_bitfield_bit_offset, 2443 bool &child_is_base_class, 2444 bool &child_is_deref_of_parent 2445) 2446{ 2447 if (parent_clang_type == NULL) 2448 return NULL; 2449 2450 if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes)) 2451 { 2452 uint32_t bit_offset; 2453 child_bitfield_bit_size = 0; 2454 child_bitfield_bit_offset = 0; 2455 child_is_base_class = false; 2456 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type)); 2457 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass(); 2458 switch (parent_type_class) 2459 { 2460 case clang::Type::Builtin: 2461 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind()) 2462 { 2463 case clang::BuiltinType::ObjCId: 2464 case clang::BuiltinType::ObjCClass: 2465 child_name = "isa"; 2466 child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT; 2467 return ast->ObjCBuiltinClassTy.getAsOpaquePtr(); 2468 2469 default: 2470 break; 2471 } 2472 break; 2473 2474 case clang::Type::Record: 2475 if (GetCompleteQualType (ast, parent_qual_type)) 2476 { 2477 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr()); 2478 const RecordDecl *record_decl = record_type->getDecl(); 2479 assert(record_decl); 2480 const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl); 2481 uint32_t child_idx = 0; 2482 2483 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2484 if (cxx_record_decl) 2485 { 2486 // We might have base classes to print out first 2487 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2488 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2489 base_class != base_class_end; 2490 ++base_class) 2491 { 2492 const CXXRecordDecl *base_class_decl = NULL; 2493 2494 // Skip empty base classes 2495 if (omit_empty_base_classes) 2496 { 2497 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2498 if (RecordHasFields(base_class_decl) == false) 2499 continue; 2500 } 2501 2502 if (idx == child_idx) 2503 { 2504 if (base_class_decl == NULL) 2505 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2506 2507 2508 if (base_class->isVirtual()) 2509 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; 2510 else 2511 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; 2512 2513 // Base classes should be a multiple of 8 bits in size 2514 assert (bit_offset % 8 == 0); 2515 child_byte_offset = bit_offset/8; 2516 std::string base_class_type_name(base_class->getType().getAsString()); 2517 2518 child_name.assign(base_class_type_name.c_str()); 2519 2520 uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType()); 2521 2522 // Base classes bit sizes should be a multiple of 8 bits in size 2523 assert (clang_type_info_bit_size % 8 == 0); 2524 child_byte_size = clang_type_info_bit_size / 8; 2525 child_is_base_class = true; 2526 return base_class->getType().getAsOpaquePtr(); 2527 } 2528 // We don't increment the child index in the for loop since we might 2529 // be skipping empty base classes 2530 ++child_idx; 2531 } 2532 } 2533 // Make sure index is in range... 2534 uint32_t field_idx = 0; 2535 RecordDecl::field_iterator field, field_end; 2536 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx) 2537 { 2538 if (idx == child_idx) 2539 { 2540 // Print the member type if requested 2541 // Print the member name and equal sign 2542 child_name.assign(field->getNameAsString().c_str()); 2543 2544 // Figure out the type byte size (field_type_info.first) and 2545 // alignment (field_type_info.second) from the AST context. 2546 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType()); 2547 assert(field_idx < record_layout.getFieldCount()); 2548 2549 child_byte_size = field_type_info.first / 8; 2550 2551 // Figure out the field offset within the current struct/union/class type 2552 bit_offset = record_layout.getFieldOffset (field_idx); 2553 child_byte_offset = bit_offset / 8; 2554 if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size)) 2555 child_bitfield_bit_offset = bit_offset % 8; 2556 2557 return field->getType().getAsOpaquePtr(); 2558 } 2559 } 2560 } 2561 break; 2562 2563 case clang::Type::ObjCObject: 2564 case clang::Type::ObjCInterface: 2565 if (GetCompleteQualType (ast, parent_qual_type)) 2566 { 2567 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr()); 2568 assert (objc_class_type); 2569 if (objc_class_type) 2570 { 2571 uint32_t child_idx = 0; 2572 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 2573 2574 if (class_interface_decl) 2575 { 2576 2577 const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl); 2578 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 2579 if (superclass_interface_decl) 2580 { 2581 if (omit_empty_base_classes) 2582 { 2583 if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0) 2584 { 2585 if (idx == 0) 2586 { 2587 QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl)); 2588 2589 2590 child_name.assign(superclass_interface_decl->getNameAsString().c_str()); 2591 2592 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr()); 2593 2594 child_byte_size = ivar_type_info.first / 8; 2595 child_byte_offset = 0; 2596 child_is_base_class = true; 2597 2598 return ivar_qual_type.getAsOpaquePtr(); 2599 } 2600 2601 ++child_idx; 2602 } 2603 } 2604 else 2605 ++child_idx; 2606 } 2607 2608 const uint32_t superclass_idx = child_idx; 2609 2610 if (idx < (child_idx + class_interface_decl->ivar_size())) 2611 { 2612 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 2613 2614 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) 2615 { 2616 if (child_idx == idx) 2617 { 2618 const ObjCIvarDecl* ivar_decl = *ivar_pos; 2619 2620 QualType ivar_qual_type(ivar_decl->getType()); 2621 2622 child_name.assign(ivar_decl->getNameAsString().c_str()); 2623 2624 std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr()); 2625 2626 child_byte_size = ivar_type_info.first / 8; 2627 2628 // Figure out the field offset within the current struct/union/class type 2629 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); 2630 child_byte_offset = bit_offset / 8; 2631 2632 return ivar_qual_type.getAsOpaquePtr(); 2633 } 2634 ++child_idx; 2635 } 2636 } 2637 } 2638 } 2639 } 2640 break; 2641 2642 case clang::Type::ObjCObjectPointer: 2643 { 2644 const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr()); 2645 QualType pointee_type = pointer_type->getPointeeType(); 2646 2647 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2648 { 2649 child_is_deref_of_parent = false; 2650 bool tmp_child_is_deref_of_parent = false; 2651 return GetChildClangTypeAtIndex (ast, 2652 parent_name, 2653 pointer_type->getPointeeType().getAsOpaquePtr(), 2654 idx, 2655 transparent_pointers, 2656 omit_empty_base_classes, 2657 child_name, 2658 child_byte_size, 2659 child_byte_offset, 2660 child_bitfield_bit_size, 2661 child_bitfield_bit_offset, 2662 child_is_base_class, 2663 tmp_child_is_deref_of_parent); 2664 } 2665 else 2666 { 2667 child_is_deref_of_parent = true; 2668 if (parent_name) 2669 { 2670 child_name.assign(1, '*'); 2671 child_name += parent_name; 2672 } 2673 2674 // We have a pointer to an simple type 2675 if (idx == 0) 2676 { 2677 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); 2678 assert(clang_type_info.first % 8 == 0); 2679 child_byte_size = clang_type_info.first / 8; 2680 child_byte_offset = 0; 2681 return pointee_type.getAsOpaquePtr(); 2682 } 2683 } 2684 } 2685 break; 2686 2687 case clang::Type::ConstantArray: 2688 { 2689 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 2690 const uint64_t element_count = array->getSize().getLimitedValue(); 2691 2692 if (idx < element_count) 2693 { 2694 if (GetCompleteQualType (ast, array->getElementType())) 2695 { 2696 std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); 2697 2698 char element_name[64]; 2699 ::snprintf (element_name, sizeof (element_name), "[%u]", idx); 2700 2701 child_name.assign(element_name); 2702 assert(field_type_info.first % 8 == 0); 2703 child_byte_size = field_type_info.first / 8; 2704 child_byte_offset = idx * child_byte_size; 2705 return array->getElementType().getAsOpaquePtr(); 2706 } 2707 } 2708 } 2709 break; 2710 2711 case clang::Type::Pointer: 2712 { 2713 const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr()); 2714 QualType pointee_type = pointer_type->getPointeeType(); 2715 2716 // Don't dereference "void *" pointers 2717 if (pointee_type->isVoidType()) 2718 return NULL; 2719 2720 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2721 { 2722 child_is_deref_of_parent = false; 2723 bool tmp_child_is_deref_of_parent = false; 2724 return GetChildClangTypeAtIndex (ast, 2725 parent_name, 2726 pointer_type->getPointeeType().getAsOpaquePtr(), 2727 idx, 2728 transparent_pointers, 2729 omit_empty_base_classes, 2730 child_name, 2731 child_byte_size, 2732 child_byte_offset, 2733 child_bitfield_bit_size, 2734 child_bitfield_bit_offset, 2735 child_is_base_class, 2736 tmp_child_is_deref_of_parent); 2737 } 2738 else 2739 { 2740 child_is_deref_of_parent = true; 2741 2742 if (parent_name) 2743 { 2744 child_name.assign(1, '*'); 2745 child_name += parent_name; 2746 } 2747 2748 // We have a pointer to an simple type 2749 if (idx == 0) 2750 { 2751 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); 2752 assert(clang_type_info.first % 8 == 0); 2753 child_byte_size = clang_type_info.first / 8; 2754 child_byte_offset = 0; 2755 return pointee_type.getAsOpaquePtr(); 2756 } 2757 } 2758 } 2759 break; 2760 2761 case clang::Type::LValueReference: 2762 case clang::Type::RValueReference: 2763 { 2764 const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr()); 2765 QualType pointee_type(reference_type->getPointeeType()); 2766 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr(); 2767 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type)) 2768 { 2769 child_is_deref_of_parent = false; 2770 bool tmp_child_is_deref_of_parent = false; 2771 return GetChildClangTypeAtIndex (ast, 2772 parent_name, 2773 pointee_clang_type, 2774 idx, 2775 transparent_pointers, 2776 omit_empty_base_classes, 2777 child_name, 2778 child_byte_size, 2779 child_byte_offset, 2780 child_bitfield_bit_size, 2781 child_bitfield_bit_offset, 2782 child_is_base_class, 2783 tmp_child_is_deref_of_parent); 2784 } 2785 else 2786 { 2787 if (parent_name) 2788 { 2789 child_name.assign(1, '&'); 2790 child_name += parent_name; 2791 } 2792 2793 // We have a pointer to an simple type 2794 if (idx == 0) 2795 { 2796 std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); 2797 assert(clang_type_info.first % 8 == 0); 2798 child_byte_size = clang_type_info.first / 8; 2799 child_byte_offset = 0; 2800 return pointee_type.getAsOpaquePtr(); 2801 } 2802 } 2803 } 2804 break; 2805 2806 case clang::Type::Typedef: 2807 return GetChildClangTypeAtIndex (ast, 2808 parent_name, 2809 cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 2810 idx, 2811 transparent_pointers, 2812 omit_empty_base_classes, 2813 child_name, 2814 child_byte_size, 2815 child_byte_offset, 2816 child_bitfield_bit_size, 2817 child_bitfield_bit_offset, 2818 child_is_base_class, 2819 child_is_deref_of_parent); 2820 break; 2821 2822 default: 2823 break; 2824 } 2825 } 2826 return NULL; 2827} 2828 2829static inline bool 2830BaseSpecifierIsEmpty (const CXXBaseSpecifier *b) 2831{ 2832 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false; 2833} 2834 2835static uint32_t 2836GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes) 2837{ 2838 uint32_t num_bases = 0; 2839 if (cxx_record_decl) 2840 { 2841 if (omit_empty_base_classes) 2842 { 2843 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2844 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2845 base_class != base_class_end; 2846 ++base_class) 2847 { 2848 // Skip empty base classes 2849 if (omit_empty_base_classes) 2850 { 2851 if (BaseSpecifierIsEmpty (base_class)) 2852 continue; 2853 } 2854 ++num_bases; 2855 } 2856 } 2857 else 2858 num_bases = cxx_record_decl->getNumBases(); 2859 } 2860 return num_bases; 2861} 2862 2863 2864static uint32_t 2865GetIndexForRecordBase 2866( 2867 const RecordDecl *record_decl, 2868 const CXXBaseSpecifier *base_spec, 2869 bool omit_empty_base_classes 2870) 2871{ 2872 uint32_t child_idx = 0; 2873 2874 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2875 2876// const char *super_name = record_decl->getNameAsCString(); 2877// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString(); 2878// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name); 2879// 2880 if (cxx_record_decl) 2881 { 2882 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2883 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2884 base_class != base_class_end; 2885 ++base_class) 2886 { 2887 if (omit_empty_base_classes) 2888 { 2889 if (BaseSpecifierIsEmpty (base_class)) 2890 continue; 2891 } 2892 2893// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name, 2894// child_idx, 2895// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); 2896// 2897// 2898 if (base_class == base_spec) 2899 return child_idx; 2900 ++child_idx; 2901 } 2902 } 2903 2904 return UINT32_MAX; 2905} 2906 2907 2908static uint32_t 2909GetIndexForRecordChild 2910( 2911 const RecordDecl *record_decl, 2912 NamedDecl *canonical_decl, 2913 bool omit_empty_base_classes 2914) 2915{ 2916 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes); 2917 2918// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2919// 2920//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString()); 2921// if (cxx_record_decl) 2922// { 2923// CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2924// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2925// base_class != base_class_end; 2926// ++base_class) 2927// { 2928// if (omit_empty_base_classes) 2929// { 2930// if (BaseSpecifierIsEmpty (base_class)) 2931// continue; 2932// } 2933// 2934//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", 2935//// record_decl->getNameAsCString(), 2936//// canonical_decl->getNameAsCString(), 2937//// child_idx, 2938//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); 2939// 2940// 2941// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2942// if (curr_base_class_decl == canonical_decl) 2943// { 2944// return child_idx; 2945// } 2946// ++child_idx; 2947// } 2948// } 2949// 2950// const uint32_t num_bases = child_idx; 2951 RecordDecl::field_iterator field, field_end; 2952 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 2953 field != field_end; 2954 ++field, ++child_idx) 2955 { 2956// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n", 2957// record_decl->getNameAsCString(), 2958// canonical_decl->getNameAsCString(), 2959// child_idx - num_bases, 2960// field->getNameAsCString()); 2961 2962 if (field->getCanonicalDecl() == canonical_decl) 2963 return child_idx; 2964 } 2965 2966 return UINT32_MAX; 2967} 2968 2969// Look for a child member (doesn't include base classes, but it does include 2970// their members) in the type hierarchy. Returns an index path into "clang_type" 2971// on how to reach the appropriate member. 2972// 2973// class A 2974// { 2975// public: 2976// int m_a; 2977// int m_b; 2978// }; 2979// 2980// class B 2981// { 2982// }; 2983// 2984// class C : 2985// public B, 2986// public A 2987// { 2988// }; 2989// 2990// If we have a clang type that describes "class C", and we wanted to looked 2991// "m_b" in it: 2992// 2993// With omit_empty_base_classes == false we would get an integer array back with: 2994// { 1, 1 } 2995// The first index 1 is the child index for "class A" within class C 2996// The second index 1 is the child index for "m_b" within class A 2997// 2998// With omit_empty_base_classes == true we would get an integer array back with: 2999// { 0, 1 } 3000// 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) 3001// The second index 1 is the child index for "m_b" within class A 3002 3003size_t 3004ClangASTContext::GetIndexOfChildMemberWithName 3005( 3006 ASTContext *ast, 3007 clang_type_t clang_type, 3008 const char *name, 3009 bool omit_empty_base_classes, 3010 std::vector<uint32_t>& child_indexes 3011) 3012{ 3013 if (clang_type && name && name[0]) 3014 { 3015 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 3016 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3017 switch (type_class) 3018 { 3019 case clang::Type::Record: 3020 if (GetCompleteQualType (ast, qual_type)) 3021 { 3022 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 3023 const RecordDecl *record_decl = record_type->getDecl(); 3024 3025 assert(record_decl); 3026 uint32_t child_idx = 0; 3027 3028 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 3029 3030 // Try and find a field that matches NAME 3031 RecordDecl::field_iterator field, field_end; 3032 StringRef name_sref(name); 3033 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 3034 field != field_end; 3035 ++field, ++child_idx) 3036 { 3037 if (field->getName().equals (name_sref)) 3038 { 3039 // We have to add on the number of base classes to this index! 3040 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes)); 3041 return child_indexes.size(); 3042 } 3043 } 3044 3045 if (cxx_record_decl) 3046 { 3047 const RecordDecl *parent_record_decl = cxx_record_decl; 3048 3049 //printf ("parent = %s\n", parent_record_decl->getNameAsCString()); 3050 3051 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl(); 3052 // Didn't find things easily, lets let clang do its thang... 3053 IdentifierInfo & ident_ref = ast->Idents.get(name, name + strlen (name)); 3054 DeclarationName decl_name(&ident_ref); 3055 3056 CXXBasePaths paths; 3057 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember, 3058 decl_name.getAsOpaquePtr(), 3059 paths)) 3060 { 3061 CXXBasePaths::const_paths_iterator path, path_end = paths.end(); 3062 for (path = paths.begin(); path != path_end; ++path) 3063 { 3064 const size_t num_path_elements = path->size(); 3065 for (size_t e=0; e<num_path_elements; ++e) 3066 { 3067 CXXBasePathElement elem = (*path)[e]; 3068 3069 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes); 3070 if (child_idx == UINT32_MAX) 3071 { 3072 child_indexes.clear(); 3073 return 0; 3074 } 3075 else 3076 { 3077 child_indexes.push_back (child_idx); 3078 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl()); 3079 } 3080 } 3081 DeclContext::lookup_iterator named_decl_pos; 3082 for (named_decl_pos = path->Decls.first; 3083 named_decl_pos != path->Decls.second && parent_record_decl; 3084 ++named_decl_pos) 3085 { 3086 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString()); 3087 3088 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes); 3089 if (child_idx == UINT32_MAX) 3090 { 3091 child_indexes.clear(); 3092 return 0; 3093 } 3094 else 3095 { 3096 child_indexes.push_back (child_idx); 3097 } 3098 } 3099 } 3100 return child_indexes.size(); 3101 } 3102 } 3103 3104 } 3105 break; 3106 3107 case clang::Type::ObjCObject: 3108 case clang::Type::ObjCInterface: 3109 if (GetCompleteQualType (ast, qual_type)) 3110 { 3111 StringRef name_sref(name); 3112 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 3113 assert (objc_class_type); 3114 if (objc_class_type) 3115 { 3116 uint32_t child_idx = 0; 3117 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 3118 3119 if (class_interface_decl) 3120 { 3121 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 3122 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 3123 3124 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) 3125 { 3126 const ObjCIvarDecl* ivar_decl = *ivar_pos; 3127 3128 if (ivar_decl->getName().equals (name_sref)) 3129 { 3130 if ((!omit_empty_base_classes && superclass_interface_decl) || 3131 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) 3132 ++child_idx; 3133 3134 child_indexes.push_back (child_idx); 3135 return child_indexes.size(); 3136 } 3137 } 3138 3139 if (superclass_interface_decl) 3140 { 3141 // The super class index is always zero for ObjC classes, 3142 // so we push it onto the child indexes in case we find 3143 // an ivar in our superclass... 3144 child_indexes.push_back (0); 3145 3146 if (GetIndexOfChildMemberWithName (ast, 3147 ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), 3148 name, 3149 omit_empty_base_classes, 3150 child_indexes)) 3151 { 3152 // We did find an ivar in a superclass so just 3153 // return the results! 3154 return child_indexes.size(); 3155 } 3156 3157 // We didn't find an ivar matching "name" in our 3158 // superclass, pop the superclass zero index that 3159 // we pushed on above. 3160 child_indexes.pop_back(); 3161 } 3162 } 3163 } 3164 } 3165 break; 3166 3167 case clang::Type::ObjCObjectPointer: 3168 { 3169 return GetIndexOfChildMemberWithName (ast, 3170 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), 3171 name, 3172 omit_empty_base_classes, 3173 child_indexes); 3174 } 3175 break; 3176 3177 3178 case clang::Type::ConstantArray: 3179 { 3180// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 3181// const uint64_t element_count = array->getSize().getLimitedValue(); 3182// 3183// if (idx < element_count) 3184// { 3185// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); 3186// 3187// char element_name[32]; 3188// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); 3189// 3190// child_name.assign(element_name); 3191// assert(field_type_info.first % 8 == 0); 3192// child_byte_size = field_type_info.first / 8; 3193// child_byte_offset = idx * child_byte_size; 3194// return array->getElementType().getAsOpaquePtr(); 3195// } 3196 } 3197 break; 3198 3199// case clang::Type::MemberPointerType: 3200// { 3201// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); 3202// QualType pointee_type = mem_ptr_type->getPointeeType(); 3203// 3204// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3205// { 3206// return GetIndexOfChildWithName (ast, 3207// mem_ptr_type->getPointeeType().getAsOpaquePtr(), 3208// name); 3209// } 3210// } 3211// break; 3212// 3213 case clang::Type::LValueReference: 3214 case clang::Type::RValueReference: 3215 { 3216 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 3217 QualType pointee_type = reference_type->getPointeeType(); 3218 3219 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3220 { 3221 return GetIndexOfChildMemberWithName (ast, 3222 reference_type->getPointeeType().getAsOpaquePtr(), 3223 name, 3224 omit_empty_base_classes, 3225 child_indexes); 3226 } 3227 } 3228 break; 3229 3230 case clang::Type::Pointer: 3231 { 3232 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 3233 QualType pointee_type = pointer_type->getPointeeType(); 3234 3235 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3236 { 3237 return GetIndexOfChildMemberWithName (ast, 3238 pointer_type->getPointeeType().getAsOpaquePtr(), 3239 name, 3240 omit_empty_base_classes, 3241 child_indexes); 3242 } 3243 else 3244 { 3245// if (parent_name) 3246// { 3247// child_name.assign(1, '*'); 3248// child_name += parent_name; 3249// } 3250// 3251// // We have a pointer to an simple type 3252// if (idx == 0) 3253// { 3254// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); 3255// assert(clang_type_info.first % 8 == 0); 3256// child_byte_size = clang_type_info.first / 8; 3257// child_byte_offset = 0; 3258// return pointee_type.getAsOpaquePtr(); 3259// } 3260 } 3261 } 3262 break; 3263 3264 case clang::Type::Typedef: 3265 return GetIndexOfChildMemberWithName (ast, 3266 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 3267 name, 3268 omit_empty_base_classes, 3269 child_indexes); 3270 3271 default: 3272 break; 3273 } 3274 } 3275 return 0; 3276} 3277 3278 3279// Get the index of the child of "clang_type" whose name matches. This function 3280// doesn't descend into the children, but only looks one level deep and name 3281// matches can include base class names. 3282 3283uint32_t 3284ClangASTContext::GetIndexOfChildWithName 3285( 3286 ASTContext *ast, 3287 clang_type_t clang_type, 3288 const char *name, 3289 bool omit_empty_base_classes 3290) 3291{ 3292 if (clang_type && name && name[0]) 3293 { 3294 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 3295 3296 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3297 3298 switch (type_class) 3299 { 3300 case clang::Type::Record: 3301 if (GetCompleteQualType (ast, qual_type)) 3302 { 3303 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 3304 const RecordDecl *record_decl = record_type->getDecl(); 3305 3306 assert(record_decl); 3307 uint32_t child_idx = 0; 3308 3309 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 3310 3311 if (cxx_record_decl) 3312 { 3313 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 3314 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 3315 base_class != base_class_end; 3316 ++base_class) 3317 { 3318 // Skip empty base classes 3319 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 3320 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false) 3321 continue; 3322 3323 if (base_class->getType().getAsString().compare (name) == 0) 3324 return child_idx; 3325 ++child_idx; 3326 } 3327 } 3328 3329 // Try and find a field that matches NAME 3330 RecordDecl::field_iterator field, field_end; 3331 StringRef name_sref(name); 3332 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 3333 field != field_end; 3334 ++field, ++child_idx) 3335 { 3336 if (field->getName().equals (name_sref)) 3337 return child_idx; 3338 } 3339 3340 } 3341 break; 3342 3343 case clang::Type::ObjCObject: 3344 case clang::Type::ObjCInterface: 3345 if (GetCompleteQualType (ast, qual_type)) 3346 { 3347 StringRef name_sref(name); 3348 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 3349 assert (objc_class_type); 3350 if (objc_class_type) 3351 { 3352 uint32_t child_idx = 0; 3353 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 3354 3355 if (class_interface_decl) 3356 { 3357 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 3358 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 3359 3360 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) 3361 { 3362 const ObjCIvarDecl* ivar_decl = *ivar_pos; 3363 3364 if (ivar_decl->getName().equals (name_sref)) 3365 { 3366 if ((!omit_empty_base_classes && superclass_interface_decl) || 3367 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) 3368 ++child_idx; 3369 3370 return child_idx; 3371 } 3372 } 3373 3374 if (superclass_interface_decl) 3375 { 3376 if (superclass_interface_decl->getName().equals (name_sref)) 3377 return 0; 3378 } 3379 } 3380 } 3381 } 3382 break; 3383 3384 case clang::Type::ObjCObjectPointer: 3385 { 3386 return GetIndexOfChildWithName (ast, 3387 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), 3388 name, 3389 omit_empty_base_classes); 3390 } 3391 break; 3392 3393 case clang::Type::ConstantArray: 3394 { 3395// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 3396// const uint64_t element_count = array->getSize().getLimitedValue(); 3397// 3398// if (idx < element_count) 3399// { 3400// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); 3401// 3402// char element_name[32]; 3403// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); 3404// 3405// child_name.assign(element_name); 3406// assert(field_type_info.first % 8 == 0); 3407// child_byte_size = field_type_info.first / 8; 3408// child_byte_offset = idx * child_byte_size; 3409// return array->getElementType().getAsOpaquePtr(); 3410// } 3411 } 3412 break; 3413 3414// case clang::Type::MemberPointerType: 3415// { 3416// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); 3417// QualType pointee_type = mem_ptr_type->getPointeeType(); 3418// 3419// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3420// { 3421// return GetIndexOfChildWithName (ast, 3422// mem_ptr_type->getPointeeType().getAsOpaquePtr(), 3423// name); 3424// } 3425// } 3426// break; 3427// 3428 case clang::Type::LValueReference: 3429 case clang::Type::RValueReference: 3430 { 3431 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 3432 QualType pointee_type = reference_type->getPointeeType(); 3433 3434 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3435 { 3436 return GetIndexOfChildWithName (ast, 3437 reference_type->getPointeeType().getAsOpaquePtr(), 3438 name, 3439 omit_empty_base_classes); 3440 } 3441 } 3442 break; 3443 3444 case clang::Type::Pointer: 3445 { 3446 const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 3447 QualType pointee_type = pointer_type->getPointeeType(); 3448 3449 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3450 { 3451 return GetIndexOfChildWithName (ast, 3452 pointer_type->getPointeeType().getAsOpaquePtr(), 3453 name, 3454 omit_empty_base_classes); 3455 } 3456 else 3457 { 3458// if (parent_name) 3459// { 3460// child_name.assign(1, '*'); 3461// child_name += parent_name; 3462// } 3463// 3464// // We have a pointer to an simple type 3465// if (idx == 0) 3466// { 3467// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); 3468// assert(clang_type_info.first % 8 == 0); 3469// child_byte_size = clang_type_info.first / 8; 3470// child_byte_offset = 0; 3471// return pointee_type.getAsOpaquePtr(); 3472// } 3473 } 3474 } 3475 break; 3476 3477 case clang::Type::Typedef: 3478 return GetIndexOfChildWithName (ast, 3479 cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 3480 name, 3481 omit_empty_base_classes); 3482 3483 default: 3484 break; 3485 } 3486 } 3487 return UINT32_MAX; 3488} 3489 3490#pragma mark TagType 3491 3492bool 3493ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind) 3494{ 3495 if (tag_clang_type) 3496 { 3497 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type)); 3498 const clang::Type *clang_type = tag_qual_type.getTypePtr(); 3499 if (clang_type) 3500 { 3501 const TagType *tag_type = dyn_cast<TagType>(clang_type); 3502 if (tag_type) 3503 { 3504 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl()); 3505 if (tag_decl) 3506 { 3507 tag_decl->setTagKind ((TagDecl::TagKind)kind); 3508 return true; 3509 } 3510 } 3511 } 3512 } 3513 return false; 3514} 3515 3516 3517#pragma mark DeclContext Functions 3518 3519DeclContext * 3520ClangASTContext::GetDeclContextForType (clang_type_t clang_type) 3521{ 3522 if (clang_type == NULL) 3523 return NULL; 3524 3525 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 3526 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3527 switch (type_class) 3528 { 3529 case clang::Type::FunctionNoProto: break; 3530 case clang::Type::FunctionProto: break; 3531 case clang::Type::IncompleteArray: break; 3532 case clang::Type::VariableArray: break; 3533 case clang::Type::ConstantArray: break; 3534 case clang::Type::DependentSizedArray: break; 3535 case clang::Type::ExtVector: break; 3536 case clang::Type::DependentSizedExtVector: break; 3537 case clang::Type::Vector: break; 3538 case clang::Type::Builtin: break; 3539 case clang::Type::BlockPointer: break; 3540 case clang::Type::Pointer: break; 3541 case clang::Type::LValueReference: break; 3542 case clang::Type::RValueReference: break; 3543 case clang::Type::MemberPointer: break; 3544 case clang::Type::Complex: break; 3545 case clang::Type::ObjCObject: break; 3546 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface(); 3547 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr()); 3548 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl(); 3549 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl(); 3550 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); 3551 3552 case clang::Type::TypeOfExpr: break; 3553 case clang::Type::TypeOf: break; 3554 case clang::Type::Decltype: break; 3555 //case clang::Type::QualifiedName: break; 3556 case clang::Type::TemplateSpecialization: break; 3557 case clang::Type::DependentTemplateSpecialization: break; 3558 case clang::Type::TemplateTypeParm: break; 3559 case clang::Type::SubstTemplateTypeParm: break; 3560 case clang::Type::SubstTemplateTypeParmPack:break; 3561 case clang::Type::PackExpansion: break; 3562 case clang::Type::UnresolvedUsing: break; 3563 case clang::Type::Paren: break; 3564 case clang::Type::Elaborated: break; 3565 case clang::Type::Attributed: break; 3566 case clang::Type::Auto: break; 3567 case clang::Type::InjectedClassName: break; 3568 case clang::Type::DependentName: break; 3569 } 3570 // No DeclContext in this type... 3571 return NULL; 3572} 3573 3574#pragma mark Namespace Declarations 3575 3576NamespaceDecl * 3577ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx) 3578{ 3579 // TODO: Do something intelligent with the Declaration object passed in 3580 // like maybe filling in the SourceLocation with it... 3581 if (name) 3582 { 3583 ASTContext *ast = getASTContext(); 3584 if (decl_ctx == NULL) 3585 decl_ctx = ast->getTranslationUnitDecl(); 3586 return NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &ast->Idents.get(name)); 3587 } 3588 return NULL; 3589} 3590 3591 3592#pragma mark Function Types 3593 3594FunctionDecl * 3595ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline) 3596{ 3597 if (name) 3598 { 3599 ASTContext *ast = getASTContext(); 3600 assert (ast != NULL); 3601 3602 if (name && name[0]) 3603 { 3604 return FunctionDecl::Create(*ast, 3605 ast->getTranslationUnitDecl(), 3606 SourceLocation(), 3607 SourceLocation(), 3608 DeclarationName (&ast->Idents.get(name)), 3609 QualType::getFromOpaquePtr(function_clang_type), 3610 NULL, 3611 (FunctionDecl::StorageClass)storage, 3612 (FunctionDecl::StorageClass)storage, 3613 is_inline); 3614 } 3615 else 3616 { 3617 return FunctionDecl::Create(*ast, 3618 ast->getTranslationUnitDecl(), 3619 SourceLocation(), 3620 SourceLocation(), 3621 DeclarationName (), 3622 QualType::getFromOpaquePtr(function_clang_type), 3623 NULL, 3624 (FunctionDecl::StorageClass)storage, 3625 (FunctionDecl::StorageClass)storage, 3626 is_inline); 3627 } 3628 } 3629 return NULL; 3630} 3631 3632clang_type_t 3633ClangASTContext::CreateFunctionType (ASTContext *ast, 3634 clang_type_t result_type, 3635 clang_type_t *args, 3636 unsigned num_args, 3637 bool is_variadic, 3638 unsigned type_quals) 3639{ 3640 assert (ast != NULL); 3641 std::vector<QualType> qual_type_args; 3642 for (unsigned i=0; i<num_args; ++i) 3643 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i])); 3644 3645 // TODO: Detect calling convention in DWARF? 3646 FunctionProtoType::ExtProtoInfo proto_info; 3647 proto_info.Variadic = is_variadic; 3648 proto_info.ExceptionSpecType = EST_None; 3649 proto_info.TypeQuals = type_quals; 3650 proto_info.RefQualifier = RQ_None; 3651 proto_info.NumExceptions = 0; 3652 proto_info.Exceptions = NULL; 3653 3654 return ast->getFunctionType(QualType::getFromOpaquePtr(result_type), 3655 qual_type_args.empty() ? NULL : &qual_type_args.front(), 3656 qual_type_args.size(), 3657 proto_info).getAsOpaquePtr(); // NoReturn); 3658} 3659 3660ParmVarDecl * 3661ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage) 3662{ 3663 ASTContext *ast = getASTContext(); 3664 assert (ast != NULL); 3665 return ParmVarDecl::Create(*ast, 3666 ast->getTranslationUnitDecl(), 3667 SourceLocation(), 3668 SourceLocation(), 3669 name && name[0] ? &ast->Idents.get(name) : NULL, 3670 QualType::getFromOpaquePtr(param_type), 3671 NULL, 3672 (VarDecl::StorageClass)storage, 3673 (VarDecl::StorageClass)storage, 3674 0); 3675} 3676 3677void 3678ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params) 3679{ 3680 if (function_decl) 3681 function_decl->setParams (params, num_params); 3682} 3683 3684 3685#pragma mark Array Types 3686 3687clang_type_t 3688ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride) 3689{ 3690 if (element_type) 3691 { 3692 ASTContext *ast = getASTContext(); 3693 assert (ast != NULL); 3694 llvm::APInt ap_element_count (64, element_count); 3695 return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type), 3696 ap_element_count, 3697 ArrayType::Normal, 3698 0).getAsOpaquePtr(); // ElemQuals 3699 } 3700 return NULL; 3701} 3702 3703 3704#pragma mark TagDecl 3705 3706bool 3707ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type) 3708{ 3709 if (clang_type) 3710 { 3711 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3712 const clang::Type *t = qual_type.getTypePtr(); 3713 if (t) 3714 { 3715 const TagType *tag_type = dyn_cast<TagType>(t); 3716 if (tag_type) 3717 { 3718 TagDecl *tag_decl = tag_type->getDecl(); 3719 if (tag_decl) 3720 { 3721 tag_decl->startDefinition(); 3722 return true; 3723 } 3724 } 3725 } 3726 } 3727 return false; 3728} 3729 3730bool 3731ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type) 3732{ 3733 if (clang_type) 3734 { 3735 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3736 3737 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); 3738 3739 if (cxx_record_decl) 3740 { 3741 cxx_record_decl->completeDefinition(); 3742 3743 return true; 3744 } 3745 3746 const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type); 3747 3748 if (objc_class_type) 3749 { 3750 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 3751 3752 class_interface_decl->setForwardDecl(false); 3753 } 3754 3755 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr()); 3756 3757 if (enum_type) 3758 { 3759 EnumDecl *enum_decl = enum_type->getDecl(); 3760 3761 if (enum_decl) 3762 { 3763 /// TODO This really needs to be fixed. 3764 3765 unsigned NumPositiveBits = 1; 3766 unsigned NumNegativeBits = 0; 3767 3768 ASTContext *ast = getASTContext(); 3769 3770 QualType promotion_qual_type; 3771 // If the enum integer type is less than an integer in bit width, 3772 // then we must promote it to an integer size. 3773 if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy)) 3774 { 3775 if (enum_decl->getIntegerType()->isSignedIntegerType()) 3776 promotion_qual_type = ast->IntTy; 3777 else 3778 promotion_qual_type = ast->UnsignedIntTy; 3779 } 3780 else 3781 promotion_qual_type = enum_decl->getIntegerType(); 3782 3783 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); 3784 return true; 3785 } 3786 } 3787 } 3788 return false; 3789} 3790 3791 3792#pragma mark Enumeration Types 3793 3794clang_type_t 3795ClangASTContext::CreateEnumerationType 3796( 3797 const char *name, 3798 DeclContext *decl_ctx, 3799 const Declaration &decl, 3800 clang_type_t integer_qual_type 3801) 3802{ 3803 // TODO: Do something intelligent with the Declaration object passed in 3804 // like maybe filling in the SourceLocation with it... 3805 ASTContext *ast = getASTContext(); 3806 assert (ast != NULL); 3807 3808 // TODO: ask about these... 3809// const bool IsScoped = false; 3810// const bool IsFixed = false; 3811 3812 EnumDecl *enum_decl = EnumDecl::Create (*ast, 3813 decl_ctx, 3814 SourceLocation(), 3815 SourceLocation(), 3816 name && name[0] ? &ast->Idents.get(name) : NULL, 3817 NULL, 3818 false, // IsScoped 3819 false, // IsScopedUsingClassTag 3820 false); // IsFixed 3821 3822 3823 if (enum_decl) 3824 { 3825 // TODO: check if we should be setting the promotion type too? 3826 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type)); 3827 3828 enum_decl->setAccess(AS_public); // TODO respect what's in the debug info 3829 3830 return ast->getTagDeclType(enum_decl).getAsOpaquePtr(); 3831 } 3832 return NULL; 3833} 3834 3835clang_type_t 3836ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type) 3837{ 3838 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); 3839 3840 const clang::Type *clang_type = enum_qual_type.getTypePtr(); 3841 if (clang_type) 3842 { 3843 const EnumType *enum_type = dyn_cast<EnumType>(clang_type); 3844 if (enum_type) 3845 { 3846 EnumDecl *enum_decl = enum_type->getDecl(); 3847 if (enum_decl) 3848 return enum_decl->getIntegerType().getAsOpaquePtr(); 3849 } 3850 } 3851 return NULL; 3852} 3853bool 3854ClangASTContext::AddEnumerationValueToEnumerationType 3855( 3856 clang_type_t enum_clang_type, 3857 clang_type_t enumerator_clang_type, 3858 const Declaration &decl, 3859 const char *name, 3860 int64_t enum_value, 3861 uint32_t enum_value_bit_size 3862) 3863{ 3864 if (enum_clang_type && enumerator_clang_type && name) 3865 { 3866 // TODO: Do something intelligent with the Declaration object passed in 3867 // like maybe filling in the SourceLocation with it... 3868 ASTContext *ast = getASTContext(); 3869 IdentifierTable *identifier_table = getIdentifierTable(); 3870 3871 assert (ast != NULL); 3872 assert (identifier_table != NULL); 3873 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); 3874 3875 const clang::Type *clang_type = enum_qual_type.getTypePtr(); 3876 if (clang_type) 3877 { 3878 const EnumType *enum_type = dyn_cast<EnumType>(clang_type); 3879 3880 if (enum_type) 3881 { 3882 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false); 3883 enum_llvm_apsint = enum_value; 3884 EnumConstantDecl *enumerator_decl = 3885 EnumConstantDecl::Create (*ast, 3886 enum_type->getDecl(), 3887 SourceLocation(), 3888 name ? &identifier_table->get(name) : NULL, // Identifier 3889 QualType::getFromOpaquePtr(enumerator_clang_type), 3890 NULL, 3891 enum_llvm_apsint); 3892 3893 if (enumerator_decl) 3894 { 3895 enum_type->getDecl()->addDecl(enumerator_decl); 3896 return true; 3897 } 3898 } 3899 } 3900 } 3901 return false; 3902} 3903 3904#pragma mark Pointers & References 3905 3906clang_type_t 3907ClangASTContext::CreatePointerType (clang_type_t clang_type) 3908{ 3909 return CreatePointerType (getASTContext(), clang_type); 3910} 3911 3912clang_type_t 3913ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type) 3914{ 3915 if (ast && clang_type) 3916 { 3917 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3918 3919 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3920 switch (type_class) 3921 { 3922 case clang::Type::ObjCObject: 3923 case clang::Type::ObjCInterface: 3924 return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); 3925 3926 default: 3927 return ast->getPointerType(qual_type).getAsOpaquePtr(); 3928 } 3929 } 3930 return NULL; 3931} 3932 3933clang_type_t 3934ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast, 3935 clang_type_t clang_type) 3936{ 3937 if (clang_type) 3938 return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); 3939 return NULL; 3940} 3941 3942clang_type_t 3943ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast, 3944 clang_type_t clang_type) 3945{ 3946 if (clang_type) 3947 return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); 3948 return NULL; 3949} 3950 3951clang_type_t 3952ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type) 3953{ 3954 if (clang_pointee_type && clang_pointee_type) 3955 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type), 3956 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr(); 3957 return NULL; 3958} 3959 3960uint32_t 3961ClangASTContext::GetPointerBitSize () 3962{ 3963 ASTContext *ast = getASTContext(); 3964 return ast->getTypeSize(ast->VoidPtrTy); 3965} 3966 3967bool 3968ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type) 3969{ 3970 if (clang_type == NULL) 3971 return false; 3972 3973 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3974 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3975 switch (type_class) 3976 { 3977 case clang::Type::Builtin: 3978 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 3979 { 3980 default: 3981 break; 3982 case clang::BuiltinType::ObjCId: 3983 case clang::BuiltinType::ObjCClass: 3984 return true; 3985 } 3986 return false; 3987 case clang::Type::ObjCObjectPointer: 3988 if (target_type) 3989 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3990 return true; 3991 case clang::Type::BlockPointer: 3992 if (target_type) 3993 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3994 return true; 3995 case clang::Type::Pointer: 3996 if (target_type) 3997 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3998 return true; 3999 case clang::Type::MemberPointer: 4000 if (target_type) 4001 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 4002 return true; 4003 case clang::Type::LValueReference: 4004 if (target_type) 4005 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); 4006 return true; 4007 case clang::Type::RValueReference: 4008 if (target_type) 4009 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); 4010 return true; 4011 case clang::Type::Typedef: 4012 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); 4013 default: 4014 break; 4015 } 4016 return false; 4017} 4018 4019bool 4020ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed) 4021{ 4022 if (!clang_type) 4023 return false; 4024 4025 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4026 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()); 4027 4028 if (builtin_type) 4029 { 4030 if (builtin_type->isInteger()) 4031 is_signed = builtin_type->isSignedInteger(); 4032 4033 return true; 4034 } 4035 4036 return false; 4037} 4038 4039bool 4040ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type) 4041{ 4042 if (clang_type) 4043 { 4044 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4045 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 4046 switch (type_class) 4047 { 4048 case clang::Type::Builtin: 4049 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 4050 { 4051 default: 4052 break; 4053 case clang::BuiltinType::ObjCId: 4054 case clang::BuiltinType::ObjCClass: 4055 return true; 4056 } 4057 return false; 4058 case clang::Type::ObjCObjectPointer: 4059 if (target_type) 4060 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 4061 return true; 4062 case clang::Type::BlockPointer: 4063 if (target_type) 4064 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 4065 return true; 4066 case clang::Type::Pointer: 4067 if (target_type) 4068 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 4069 return true; 4070 case clang::Type::MemberPointer: 4071 if (target_type) 4072 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 4073 return true; 4074 case clang::Type::Typedef: 4075 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type); 4076 default: 4077 break; 4078 } 4079 } 4080 return false; 4081} 4082 4083bool 4084ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex) 4085{ 4086 if (clang_type) 4087 { 4088 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4089 4090 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal())) 4091 { 4092 clang::BuiltinType::Kind kind = BT->getKind(); 4093 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble) 4094 { 4095 count = 1; 4096 is_complex = false; 4097 return true; 4098 } 4099 } 4100 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal())) 4101 { 4102 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex)) 4103 { 4104 count = 2; 4105 is_complex = true; 4106 return true; 4107 } 4108 } 4109 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal())) 4110 { 4111 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex)) 4112 { 4113 count = VT->getNumElements(); 4114 is_complex = false; 4115 return true; 4116 } 4117 } 4118 } 4119 return false; 4120} 4121 4122 4123bool 4124ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name) 4125{ 4126 if (clang_type) 4127 { 4128 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4129 4130 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); 4131 if (cxx_record_decl) 4132 { 4133 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart()); 4134 return true; 4135 } 4136 } 4137 class_name.clear(); 4138 return false; 4139} 4140 4141 4142bool 4143ClangASTContext::IsCXXClassType (clang_type_t clang_type) 4144{ 4145 if (clang_type) 4146 { 4147 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4148 if (qual_type->getAsCXXRecordDecl() != NULL) 4149 return true; 4150 } 4151 return false; 4152} 4153 4154bool 4155ClangASTContext::IsObjCClassType (clang_type_t clang_type) 4156{ 4157 if (clang_type) 4158 { 4159 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4160 if (qual_type->isObjCObjectOrInterfaceType()) 4161 return true; 4162 } 4163 return false; 4164} 4165 4166 4167bool 4168ClangASTContext::IsCharType (clang_type_t clang_type) 4169{ 4170 if (clang_type) 4171 return QualType::getFromOpaquePtr(clang_type)->isCharType(); 4172 return false; 4173} 4174 4175bool 4176ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length) 4177{ 4178 clang_type_t pointee_or_element_clang_type = NULL; 4179 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type)); 4180 4181 if (pointee_or_element_clang_type == NULL) 4182 return false; 4183 4184 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer)) 4185 { 4186 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type)); 4187 4188 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType()) 4189 { 4190 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4191 if (type_flags.Test (eTypeIsArray)) 4192 { 4193 // We know the size of the array and it could be a C string 4194 // since it is an array of characters 4195 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); 4196 return true; 4197 } 4198 else 4199 { 4200 length = 0; 4201 return true; 4202 } 4203 4204 } 4205 } 4206 return false; 4207} 4208 4209bool 4210ClangASTContext::IsFunctionPointerType (clang_type_t clang_type) 4211{ 4212 if (clang_type) 4213 { 4214 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4215 4216 if (qual_type->isFunctionPointerType()) 4217 return true; 4218 4219 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 4220 switch (type_class) 4221 { 4222 default: 4223 break; 4224 case clang::Type::Typedef: 4225 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); 4226 4227 case clang::Type::LValueReference: 4228 case clang::Type::RValueReference: 4229 { 4230 const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 4231 if (reference_type) 4232 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr()); 4233 } 4234 break; 4235 } 4236 } 4237 return false; 4238} 4239 4240size_t 4241ClangASTContext::GetArraySize (clang_type_t clang_type) 4242{ 4243 if (clang_type) 4244 { 4245 const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr()); 4246 if (array) 4247 return array->getSize().getLimitedValue(); 4248 } 4249 return 0; 4250} 4251 4252bool 4253ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size) 4254{ 4255 if (!clang_type) 4256 return false; 4257 4258 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4259 4260 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 4261 switch (type_class) 4262 { 4263 default: 4264 break; 4265 case clang::Type::ConstantArray: 4266 if (member_type) 4267 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 4268 if (size) 4269 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX); 4270 return true; 4271 case clang::Type::IncompleteArray: 4272 if (member_type) 4273 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 4274 if (size) 4275 *size = 0; 4276 return true; 4277 case clang::Type::VariableArray: 4278 if (member_type) 4279 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 4280 if (size) 4281 *size = 0; 4282 return true; 4283 case clang::Type::DependentSizedArray: 4284 if (member_type) 4285 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 4286 if (size) 4287 *size = 0; 4288 return true; 4289 } 4290 return false; 4291} 4292 4293 4294#pragma mark Typedefs 4295 4296clang_type_t 4297ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx) 4298{ 4299 if (clang_type) 4300 { 4301 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4302 ASTContext *ast = getASTContext(); 4303 IdentifierTable *identifier_table = getIdentifierTable(); 4304 assert (ast != NULL); 4305 assert (identifier_table != NULL); 4306 if (decl_ctx == NULL) 4307 decl_ctx = ast->getTranslationUnitDecl(); 4308 TypedefDecl *decl = TypedefDecl::Create (*ast, 4309 decl_ctx, 4310 SourceLocation(), 4311 SourceLocation(), 4312 name ? &identifier_table->get(name) : NULL, // Identifier 4313 ast->CreateTypeSourceInfo(qual_type)); 4314 4315 decl->setAccess(AS_public); // TODO respect proper access specifier 4316 4317 // Get a uniqued QualType for the typedef decl type 4318 return ast->getTypedefType (decl).getAsOpaquePtr(); 4319 } 4320 return NULL; 4321} 4322 4323 4324std::string 4325ClangASTContext::GetTypeName (clang_type_t opaque_qual_type) 4326{ 4327 std::string return_name; 4328 4329 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type)); 4330 4331 const TypedefType *typedef_type = qual_type->getAs<TypedefType>(); 4332 if (typedef_type) 4333 { 4334 const TypedefDecl *typedef_decl = typedef_type->getDecl(); 4335 return_name = typedef_decl->getQualifiedNameAsString(); 4336 } 4337 else 4338 { 4339 return_name = qual_type.getAsString(); 4340 } 4341 4342 return return_name; 4343} 4344 4345// Disable this for now since I can't seem to get a nicely formatted float 4346// out of the APFloat class without just getting the float, double or quad 4347// and then using a formatted print on it which defeats the purpose. We ideally 4348// would like to get perfect string values for any kind of float semantics 4349// so we can support remote targets. The code below also requires a patch to 4350// llvm::APInt. 4351//bool 4352//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) 4353//{ 4354// uint32_t count = 0; 4355// bool is_complex = false; 4356// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex)) 4357// { 4358// unsigned num_bytes_per_float = byte_size / count; 4359// unsigned num_bits_per_float = num_bytes_per_float * 8; 4360// 4361// float_str.clear(); 4362// uint32_t i; 4363// for (i=0; i<count; i++) 4364// { 4365// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order); 4366// bool is_ieee = false; 4367// APFloat ap_float(ap_int, is_ieee); 4368// char s[1024]; 4369// unsigned int hex_digits = 0; 4370// bool upper_case = false; 4371// 4372// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0) 4373// { 4374// if (i > 0) 4375// float_str.append(", "); 4376// float_str.append(s); 4377// if (i == 1 && is_complex) 4378// float_str.append(1, 'i'); 4379// } 4380// } 4381// return !float_str.empty(); 4382// } 4383// return false; 4384//} 4385 4386size_t 4387ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size) 4388{ 4389 if (clang_type) 4390 { 4391 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4392 uint32_t count = 0; 4393 bool is_complex = false; 4394 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex)) 4395 { 4396 // TODO: handle complex and vector types 4397 if (count != 1) 4398 return false; 4399 4400 StringRef s_sref(s); 4401 APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref); 4402 4403 const uint64_t bit_size = ast->getTypeSize (qual_type); 4404 const uint64_t byte_size = bit_size / 8; 4405 if (dst_size >= byte_size) 4406 { 4407 if (bit_size == sizeof(float)*8) 4408 { 4409 float float32 = ap_float.convertToFloat(); 4410 ::memcpy (dst, &float32, byte_size); 4411 return byte_size; 4412 } 4413 else if (bit_size >= 64) 4414 { 4415 llvm::APInt ap_int(ap_float.bitcastToAPInt()); 4416 ::memcpy (dst, ap_int.getRawData(), byte_size); 4417 return byte_size; 4418 } 4419 } 4420 } 4421 } 4422 return 0; 4423} 4424 4425unsigned 4426ClangASTContext::GetTypeQualifiers(clang_type_t clang_type) 4427{ 4428 assert (clang_type); 4429 4430 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 4431 4432 return qual_type.getQualifiers().getCVRQualifiers(); 4433} 4434 4435bool 4436ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type) 4437{ 4438 if (clang_type == NULL) 4439 return false; 4440 4441 return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type)); 4442} 4443 4444 4445bool 4446ClangASTContext::GetCompleteType (clang_type_t clang_type) 4447{ 4448 return ClangASTContext::GetCompleteType (getASTContext(), clang_type); 4449} 4450 4451