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