ClangASTContext.cpp revision 462d4147f3bb9141bf62d904f58a623db00669df
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 = false; 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 806CXXMethodDecl * 807ClangASTContext::AddMethodToCXXRecordType 808( 809 ASTContext *ast_context, 810 clang_type_t record_opaque_type, 811 const char *name, 812 clang_type_t method_opaque_type, 813 lldb::AccessType access, 814 bool is_virtual, 815 bool is_static, 816 bool is_inline 817) 818{ 819 if (!record_opaque_type || !method_opaque_type || !name) 820 return NULL; 821 822 assert(ast_context); 823 824 IdentifierTable *identifier_table = &ast_context->Idents; 825 826 assert(identifier_table); 827 828 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type)); 829 830 clang::Type *clang_type(record_qual_type.getTypePtr()); 831 832 if (clang_type == NULL) 833 return NULL; 834 835 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type)); 836 837 if (record_clang_type == NULL) 838 return NULL; 839 840 RecordDecl *record_decl = record_clang_type->getDecl(); 841 842 if (record_decl == NULL) 843 return NULL; 844 845 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 846 847 if (cxx_record_decl == NULL) 848 return NULL; 849 850 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); 851 852 CXXMethodDecl *cxx_method_decl = CXXMethodDecl::Create (*ast_context, 853 cxx_record_decl, 854 DeclarationNameInfo (DeclarationName (&identifier_table->get(name)), SourceLocation()), 855 method_qual_type, 856 NULL, // TypeSourceInfo * 857 is_static, 858 SC_None, 859 is_inline); 860 861 862 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access); 863 864 cxx_method_decl->setAccess (access_specifier); 865 cxx_method_decl->setVirtualAsWritten (is_virtual); 866 867 // Populate the method decl with parameter decls 868 clang::Type *method_type(method_qual_type.getTypePtr()); 869 870 if (method_type == NULL) 871 return NULL; 872 873 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type)); 874 875 if (!method_function_prototype) 876 return NULL; 877 878 unsigned int num_params = method_function_prototype->getNumArgs(); 879 880 ParmVarDecl *params[num_params]; 881 882 for (int param_index = 0; 883 param_index < num_params; 884 ++param_index) 885 { 886 params[param_index] = ParmVarDecl::Create (*ast_context, 887 cxx_method_decl, 888 SourceLocation(), 889 NULL, // anonymous 890 method_function_prototype->getArgType(param_index), 891 NULL, 892 SC_None, 893 SC_None, 894 NULL); 895 } 896 897 cxx_method_decl->setParams (params, num_params); 898 899 cxx_record_decl->addDecl (cxx_method_decl); 900 901 return cxx_method_decl; 902} 903 904bool 905ClangASTContext::AddFieldToRecordType 906( 907 ASTContext *ast_context, 908 clang_type_t record_clang_type, 909 const char *name, 910 clang_type_t field_type, 911 AccessType access, 912 uint32_t bitfield_bit_size 913) 914{ 915 if (record_clang_type == NULL || field_type == NULL) 916 return false; 917 918 IdentifierTable *identifier_table = &ast_context->Idents; 919 920 assert (ast_context != NULL); 921 assert (identifier_table != NULL); 922 923 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type)); 924 925 clang::Type *clang_type = record_qual_type.getTypePtr(); 926 if (clang_type) 927 { 928 const RecordType *record_type = dyn_cast<RecordType>(clang_type); 929 930 if (record_type) 931 { 932 RecordDecl *record_decl = record_type->getDecl(); 933 934 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 935 if (cxx_record_decl) 936 { 937 // NOTE: we currently have some fixes that should be placed 938 // into clang that will automatically set if a record is empty 939 // when each field is added (during the addDecl() method call 940 // below) so this code should be able to come out when those 941 // changes make it into llvm/clang, then we can remove this 942 // code... 943 // Currently SEMA is using the accessors manually to set 944 // whether a class is empty, is POD, is aggregate, and more. 945 // This code will be moved into CXXRecordDecl so everyone 946 // can benefit. 947 // This will currently work for everything except zero sized 948 // bitfields which we currently aren't detecting anyway from the 949 // DWARF so it should be ok for now. 950 cxx_record_decl->setEmpty (false); 951 } 952 953 clang::Expr *bit_width = NULL; 954 if (bitfield_bit_size != 0) 955 { 956 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size); 957 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation()); 958 } 959 FieldDecl *field = FieldDecl::Create (*ast_context, 960 record_decl, 961 SourceLocation(), 962 name ? &identifier_table->get(name) : NULL, // Identifier 963 QualType::getFromOpaquePtr(field_type), // Field type 964 NULL, // DeclaratorInfo * 965 bit_width, // BitWidth 966 false); // Mutable 967 968 field->setAccess (ConvertAccessTypeToAccessSpecifier (access)); 969 970 if (field) 971 { 972 record_decl->addDecl(field); 973 974 // NOTE: we currently have some fixes that should be placed 975 // into clang that will automatically set if a record is POD 976 // when each field is added (during the addDecl() method call 977 // above) so this code should be able to come out when those 978 // changes make it into llvm/clang, then we can remove this 979 // code... 980 // Currently SEMA is using the accessors manually to set 981 // whether a class is empty, is POD, is aggregate, and more. 982 // This code will be moved into CXXRecordDecl so everyone 983 // can benefit. 984 985 if (cxx_record_decl->isPOD()) 986 { 987 if (!field->getType()->isPODType()) 988 cxx_record_decl->setPOD (false); 989 return true; 990 } 991 } 992 } 993 else 994 { 995 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type); 996 if (objc_class_type) 997 { 998 bool is_synthesized = false; 999 ClangASTContext::AddObjCClassIVar (ast_context, 1000 record_clang_type, 1001 name, 1002 field_type, 1003 access, 1004 bitfield_bit_size, 1005 is_synthesized); 1006 } 1007 } 1008 } 1009 return false; 1010} 1011 1012bool 1013ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size) 1014{ 1015 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size); 1016} 1017 1018bool 1019ClangASTContext::FieldIsBitfield 1020( 1021 ASTContext *ast_context, 1022 FieldDecl* field, 1023 uint32_t& bitfield_bit_size 1024) 1025{ 1026 if (ast_context == NULL || field == NULL) 1027 return false; 1028 1029 if (field->isBitField()) 1030 { 1031 Expr* bit_width_expr = field->getBitWidth(); 1032 if (bit_width_expr) 1033 { 1034 llvm::APSInt bit_width_apsint; 1035 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context)) 1036 { 1037 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX); 1038 return true; 1039 } 1040 } 1041 } 1042 return false; 1043} 1044 1045bool 1046ClangASTContext::RecordHasFields (const RecordDecl *record_decl) 1047{ 1048 if (record_decl == NULL) 1049 return false; 1050 1051 if (!record_decl->field_empty()) 1052 return true; 1053 1054 // No fields, lets check this is a CXX record and check the base classes 1055 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1056 if (cxx_record_decl) 1057 { 1058 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1059 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1060 base_class != base_class_end; 1061 ++base_class) 1062 { 1063 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1064 if (RecordHasFields(base_class_decl)) 1065 return true; 1066 } 1067 } 1068 return false; 1069} 1070 1071void 1072ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities) 1073{ 1074 if (clang_qual_type) 1075 { 1076 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type)); 1077 clang::Type *clang_type = qual_type.getTypePtr(); 1078 if (clang_type) 1079 { 1080 RecordType *record_type = dyn_cast<RecordType>(clang_type); 1081 if (record_type) 1082 { 1083 RecordDecl *record_decl = record_type->getDecl(); 1084 if (record_decl) 1085 { 1086 uint32_t field_idx; 1087 RecordDecl::field_iterator field, field_end; 1088 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0; 1089 field != field_end; 1090 ++field, ++field_idx) 1091 { 1092 // If no accessibility was assigned, assign the correct one 1093 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none) 1094 field->setAccess ((AccessSpecifier)default_accessibility); 1095 } 1096 } 1097 } 1098 } 1099 } 1100} 1101 1102#pragma mark C++ Base Classes 1103 1104CXXBaseSpecifier * 1105ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class) 1106{ 1107 if (base_class_type) 1108 return new CXXBaseSpecifier (SourceRange(), 1109 is_virtual, 1110 base_of_class, 1111 ConvertAccessTypeToAccessSpecifier (access), 1112 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type))); 1113 return NULL; 1114} 1115 1116void 1117ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes) 1118{ 1119 for (unsigned i=0; i<num_base_classes; ++i) 1120 { 1121 delete base_classes[i]; 1122 base_classes[i] = NULL; 1123 } 1124} 1125 1126bool 1127ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes) 1128{ 1129 if (class_clang_type) 1130 { 1131 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr(); 1132 if (clang_type) 1133 { 1134 RecordType *record_type = dyn_cast<RecordType>(clang_type); 1135 if (record_type) 1136 { 1137 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl()); 1138 if (cxx_record_decl) 1139 { 1140 cxx_record_decl->setBases(base_classes, num_base_classes); 1141 1142 // NOTE: we currently have some fixes that should be placed 1143 // into clang that will automatically set these things when 1144 // they are added (during the setBases() method call above) 1145 // so this code should be able to come out when those changes 1146 // make it into llvm/clang, then we can remove this code... 1147 // Currently SEMA is using the accessors manually to set 1148 // whether a class is empty, is POD, is aggregate, and more. 1149 // This code will be moved into CXXRecordDecl so everyone 1150 // can benefit. 1151 if (cxx_record_decl->isEmpty() || cxx_record_decl->isPOD()) 1152 { 1153 // set empty to false if any bases are virtual, or not empty. 1154 1155 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1156 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1157 base_class != base_class_end; 1158 ++base_class) 1159 { 1160 if (base_class->isVirtual()) 1161 { 1162 cxx_record_decl->setEmpty (false); 1163 cxx_record_decl->setPOD (false); 1164 break; 1165 } 1166 else 1167 { 1168 QualType base_type (base_class->getType()); 1169 1170 if (!base_type->isPODType()) 1171 cxx_record_decl->setPOD (false); 1172 1173 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_type->getAs<RecordType>()->getDecl()); 1174 if (!base_class_decl->isEmpty()) 1175 { 1176 cxx_record_decl->setEmpty (false); 1177 break; 1178 } 1179 } 1180 } 1181 } 1182 return true; 1183 } 1184 } 1185 } 1186 } 1187 return false; 1188} 1189#pragma mark Objective C Classes 1190 1191clang_type_t 1192ClangASTContext::CreateObjCClass 1193( 1194 const char *name, 1195 DeclContext *decl_ctx, 1196 bool isForwardDecl, 1197 bool isInternal 1198) 1199{ 1200 ASTContext *ast_context = getASTContext(); 1201 assert (ast_context != NULL); 1202 assert (name && name[0]); 1203 if (decl_ctx == NULL) 1204 decl_ctx = ast_context->getTranslationUnitDecl(); 1205 1206 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and 1207 // we will need to update this code. I was told to currently always use 1208 // the CXXRecordDecl class since we often don't know from debug information 1209 // if something is struct or a class, so we default to always use the more 1210 // complete definition just in case. 1211 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context, 1212 decl_ctx, 1213 SourceLocation(), 1214 &ast_context->Idents.get(name), 1215 SourceLocation(), 1216 isForwardDecl, 1217 isInternal); 1218 1219 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr(); 1220} 1221 1222bool 1223ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type) 1224{ 1225 if (class_opaque_type && super_opaque_type) 1226 { 1227 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1228 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type)); 1229 clang::Type *class_type = class_qual_type.getTypePtr(); 1230 clang::Type *super_type = super_qual_type.getTypePtr(); 1231 if (class_type && super_type) 1232 { 1233 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1234 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type); 1235 if (objc_class_type && objc_super_type) 1236 { 1237 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1238 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface(); 1239 if (class_interface_decl && super_interface_decl) 1240 { 1241 class_interface_decl->setSuperClass(super_interface_decl); 1242 return true; 1243 } 1244 } 1245 } 1246 } 1247 return false; 1248} 1249 1250 1251bool 1252ClangASTContext::AddObjCClassIVar 1253( 1254 ASTContext *ast_context, 1255 clang_type_t class_opaque_type, 1256 const char *name, 1257 clang_type_t ivar_opaque_type, 1258 AccessType access, 1259 uint32_t bitfield_bit_size, 1260 bool is_synthesized 1261) 1262{ 1263 if (class_opaque_type == NULL || ivar_opaque_type == NULL) 1264 return false; 1265 1266 IdentifierTable *identifier_table = &ast_context->Idents; 1267 1268 assert (ast_context != NULL); 1269 assert (identifier_table != NULL); 1270 1271 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1272 1273 clang::Type *class_type = class_qual_type.getTypePtr(); 1274 if (class_type) 1275 { 1276 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1277 1278 if (objc_class_type) 1279 { 1280 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1281 1282 if (class_interface_decl) 1283 { 1284 clang::Expr *bit_width = NULL; 1285 if (bitfield_bit_size != 0) 1286 { 1287 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size); 1288 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation()); 1289 } 1290 1291 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context, 1292 class_interface_decl, 1293 SourceLocation(), 1294 &identifier_table->get(name), // Identifier 1295 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type 1296 NULL, // TypeSourceInfo * 1297 ConvertAccessTypeToObjCIvarAccessControl (access), 1298 bit_width, 1299 is_synthesized); 1300 1301 if (field) 1302 { 1303 class_interface_decl->addDecl(field); 1304 return true; 1305 } 1306 } 1307 } 1308 } 1309 return false; 1310} 1311 1312 1313bool 1314ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass) 1315{ 1316 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1317 1318 clang::Type *class_type = class_qual_type.getTypePtr(); 1319 if (class_type) 1320 { 1321 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1322 1323 if (objc_class_type) 1324 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass); 1325 } 1326 return false; 1327} 1328 1329bool 1330ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass) 1331{ 1332 while (class_interface_decl) 1333 { 1334 if (class_interface_decl->ivar_size() > 0) 1335 return true; 1336 1337 if (check_superclass) 1338 class_interface_decl = class_interface_decl->getSuperClass(); 1339 else 1340 break; 1341 } 1342 return false; 1343} 1344 1345ObjCMethodDecl * 1346ClangASTContext::AddMethodToObjCObjectType 1347( 1348 ASTContext *ast_context, 1349 clang_type_t class_opaque_type, 1350 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") 1351 clang_type_t method_opaque_type, 1352 lldb::AccessType access 1353) 1354{ 1355 if (class_opaque_type == NULL || method_opaque_type == NULL) 1356 return NULL; 1357 1358 IdentifierTable *identifier_table = &ast_context->Idents; 1359 1360 assert (ast_context != NULL); 1361 assert (identifier_table != NULL); 1362 1363 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1364 1365 clang::Type *class_type = class_qual_type.getTypePtr(); 1366 if (class_type == NULL) 1367 return NULL; 1368 1369 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1370 1371 if (objc_class_type == NULL) 1372 return NULL; 1373 1374 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1375 1376 if (class_interface_decl == NULL) 1377 return NULL; 1378 1379 const char *selector_start = ::strchr (name, ' '); 1380 if (selector_start == NULL) 1381 return NULL; 1382 1383 selector_start++; 1384 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_')) 1385 return NULL; 1386 llvm::SmallVector<IdentifierInfo *, 12> selector_idents; 1387 1388 size_t len; 1389 const char *start; 1390 for (start = selector_start, len = ::strcspn(start, ":]"); 1391 start && *start != '\0' && *start != ']'; 1392 start += len + 1) 1393 { 1394 selector_idents.push_back (&identifier_table->get (StringRef (start, len))); 1395 } 1396 1397 1398 if (selector_idents.size() == 0) 1399 return 0; 1400 1401 clang::Selector method_selector = ast_context->Selectors.getSelector (selector_idents.size(), 1402 selector_idents.data()); 1403 1404 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); 1405 1406 // Populate the method decl with parameter decls 1407 clang::Type *method_type(method_qual_type.getTypePtr()); 1408 1409 if (method_type == NULL) 1410 return NULL; 1411 1412 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type)); 1413 1414 if (!method_function_prototype) 1415 return NULL; 1416 1417 1418 bool is_variadic = false; 1419 bool is_synthesized = false; 1420 bool is_defined = false; 1421 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None; 1422 1423 const unsigned num_args = method_function_prototype->getNumArgs(); 1424 1425 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context, 1426 SourceLocation(), // beginLoc, 1427 SourceLocation(), // endLoc, 1428 method_selector, 1429 method_function_prototype->getResultType(), 1430 NULL, // TypeSourceInfo *ResultTInfo, 1431 GetDeclContextForType (class_opaque_type), 1432 name[0] == '-', 1433 is_variadic, 1434 is_synthesized, 1435 is_defined, 1436 imp_control, 1437 num_args); 1438 1439 1440 if (objc_method_decl == NULL) 1441 return NULL; 1442 1443 if (num_args > 0) 1444 { 1445 llvm::SmallVector<ParmVarDecl *, 12> params; 1446 1447 for (int param_index = 0; param_index < num_args; ++param_index) 1448 { 1449 params.push_back (ParmVarDecl::Create (*ast_context, 1450 objc_method_decl, 1451 SourceLocation(), 1452 NULL, // anonymous 1453 method_function_prototype->getArgType(param_index), 1454 NULL, 1455 SC_Auto, 1456 SC_Auto, 1457 NULL)); 1458 } 1459 1460 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args); 1461 } 1462 1463 class_interface_decl->addDecl (objc_method_decl); 1464 1465 1466 return objc_method_decl; 1467} 1468 1469 1470 1471#pragma mark Aggregate Types 1472 1473bool 1474ClangASTContext::IsAggregateType (clang_type_t clang_type) 1475{ 1476 if (clang_type == NULL) 1477 return false; 1478 1479 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 1480 1481 if (qual_type->isAggregateType ()) 1482 return true; 1483 1484 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 1485 switch (type_class) 1486 { 1487 case clang::Type::IncompleteArray: 1488 case clang::Type::VariableArray: 1489 case clang::Type::ConstantArray: 1490 case clang::Type::ExtVector: 1491 case clang::Type::Vector: 1492 case clang::Type::Record: 1493 case clang::Type::ObjCObject: 1494 case clang::Type::ObjCInterface: 1495 return true; 1496 1497 case clang::Type::Typedef: 1498 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 1499 1500 default: 1501 break; 1502 } 1503 // The clang type does have a value 1504 return false; 1505} 1506 1507uint32_t 1508ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes) 1509{ 1510 if (clang_qual_type == NULL) 1511 return 0; 1512 1513 uint32_t num_children = 0; 1514 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type)); 1515 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 1516 switch (type_class) 1517 { 1518 case clang::Type::Builtin: 1519 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 1520 { 1521 case clang::BuiltinType::ObjCId: // Child is Class 1522 case clang::BuiltinType::ObjCClass: // child is Class 1523 case clang::BuiltinType::ObjCSel: // child is const char * 1524 num_children = 1; 1525 1526 default: 1527 break; 1528 } 1529 break; 1530 1531 case clang::Type::Record: 1532 { 1533 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 1534 const RecordDecl *record_decl = record_type->getDecl(); 1535 assert(record_decl); 1536 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1537 if (cxx_record_decl) 1538 { 1539 if (omit_empty_base_classes) 1540 { 1541 // Check each base classes to see if it or any of its 1542 // base classes contain any fields. This can help 1543 // limit the noise in variable views by not having to 1544 // show base classes that contain no members. 1545 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1546 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1547 base_class != base_class_end; 1548 ++base_class) 1549 { 1550 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1551 1552 // Skip empty base classes 1553 if (RecordHasFields(base_class_decl) == false) 1554 continue; 1555 1556 num_children++; 1557 } 1558 } 1559 else 1560 { 1561 // Include all base classes 1562 num_children += cxx_record_decl->getNumBases(); 1563 } 1564 1565 } 1566 RecordDecl::field_iterator field, field_end; 1567 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) 1568 ++num_children; 1569 } 1570 break; 1571 1572 case clang::Type::ObjCObject: 1573 case clang::Type::ObjCInterface: 1574 { 1575 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 1576 assert (objc_class_type); 1577 if (objc_class_type) 1578 { 1579 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1580 1581 if (class_interface_decl) 1582 { 1583 1584 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 1585 if (superclass_interface_decl) 1586 { 1587 if (omit_empty_base_classes) 1588 { 1589 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true)) 1590 ++num_children; 1591 } 1592 else 1593 ++num_children; 1594 } 1595 1596 num_children += class_interface_decl->ivar_size(); 1597 } 1598 } 1599 } 1600 break; 1601 1602 case clang::Type::ObjCObjectPointer: 1603 { 1604 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr()); 1605 QualType pointee_type = pointer_type->getPointeeType(); 1606 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), 1607 omit_empty_base_classes); 1608 // If this type points to a simple type, then it has 1 child 1609 if (num_pointee_children == 0) 1610 num_children = 1; 1611 else 1612 num_children = num_pointee_children; 1613 } 1614 break; 1615 1616 case clang::Type::ConstantArray: 1617 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); 1618 break; 1619 1620 case clang::Type::Pointer: 1621 { 1622 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 1623 QualType pointee_type = pointer_type->getPointeeType(); 1624 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), 1625 omit_empty_base_classes); 1626 // If this type points to a simple type, then it has 1 child 1627 if (num_pointee_children == 0) 1628 num_children = 1; 1629 else 1630 num_children = num_pointee_children; 1631 } 1632 break; 1633 1634 case clang::Type::Typedef: 1635 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes); 1636 break; 1637 1638 default: 1639 break; 1640 } 1641 return num_children; 1642} 1643 1644 1645clang_type_t 1646ClangASTContext::GetChildClangTypeAtIndex 1647( 1648 const char *parent_name, 1649 clang_type_t parent_clang_type, 1650 uint32_t idx, 1651 bool transparent_pointers, 1652 bool omit_empty_base_classes, 1653 std::string& child_name, 1654 uint32_t &child_byte_size, 1655 int32_t &child_byte_offset, 1656 uint32_t &child_bitfield_bit_size, 1657 uint32_t &child_bitfield_bit_offset 1658) 1659{ 1660 if (parent_clang_type) 1661 1662 return GetChildClangTypeAtIndex (getASTContext(), 1663 parent_name, 1664 parent_clang_type, 1665 idx, 1666 transparent_pointers, 1667 omit_empty_base_classes, 1668 child_name, 1669 child_byte_size, 1670 child_byte_offset, 1671 child_bitfield_bit_size, 1672 child_bitfield_bit_offset); 1673 return NULL; 1674} 1675 1676clang_type_t 1677ClangASTContext::GetChildClangTypeAtIndex 1678( 1679 ASTContext *ast_context, 1680 const char *parent_name, 1681 clang_type_t parent_clang_type, 1682 uint32_t idx, 1683 bool transparent_pointers, 1684 bool omit_empty_base_classes, 1685 std::string& child_name, 1686 uint32_t &child_byte_size, 1687 int32_t &child_byte_offset, 1688 uint32_t &child_bitfield_bit_size, 1689 uint32_t &child_bitfield_bit_offset 1690) 1691{ 1692 if (parent_clang_type == NULL) 1693 return NULL; 1694 1695 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes)) 1696 { 1697 uint32_t bit_offset; 1698 child_bitfield_bit_size = 0; 1699 child_bitfield_bit_offset = 0; 1700 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type)); 1701 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass(); 1702 switch (parent_type_class) 1703 { 1704 case clang::Type::Builtin: 1705 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind()) 1706 { 1707 case clang::BuiltinType::ObjCId: 1708 case clang::BuiltinType::ObjCClass: 1709 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr(); 1710 1711 case clang::BuiltinType::ObjCSel: 1712 { 1713 QualType char_type(ast_context->CharTy); 1714 char_type.addConst(); 1715 return ast_context->getPointerType(char_type).getAsOpaquePtr(); 1716 } 1717 break; 1718 1719 default: 1720 break; 1721 } 1722 break; 1723 1724 1725 case clang::Type::Record: 1726 { 1727 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr()); 1728 const RecordDecl *record_decl = record_type->getDecl(); 1729 assert(record_decl); 1730 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl); 1731 uint32_t child_idx = 0; 1732 1733 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1734 if (cxx_record_decl) 1735 { 1736 // We might have base classes to print out first 1737 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1738 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1739 base_class != base_class_end; 1740 ++base_class) 1741 { 1742 const CXXRecordDecl *base_class_decl = NULL; 1743 1744 // Skip empty base classes 1745 if (omit_empty_base_classes) 1746 { 1747 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1748 if (RecordHasFields(base_class_decl) == false) 1749 continue; 1750 } 1751 1752 if (idx == child_idx) 1753 { 1754 if (base_class_decl == NULL) 1755 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1756 1757 1758 if (base_class->isVirtual()) 1759 bit_offset = record_layout.getVBaseClassOffset(base_class_decl); 1760 else 1761 bit_offset = record_layout.getBaseClassOffset(base_class_decl); 1762 1763 // Base classes should be a multiple of 8 bits in size 1764 assert (bit_offset % 8 == 0); 1765 child_byte_offset = bit_offset/8; 1766 std::string base_class_type_name(base_class->getType().getAsString()); 1767 1768 child_name.assign(base_class_type_name.c_str()); 1769 1770 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType()); 1771 1772 // Base classes biut sizes should be a multiple of 8 bits in size 1773 assert (clang_type_info_bit_size % 8 == 0); 1774 child_byte_size = clang_type_info_bit_size / 8; 1775 return base_class->getType().getAsOpaquePtr(); 1776 } 1777 // We don't increment the child index in the for loop since we might 1778 // be skipping empty base classes 1779 ++child_idx; 1780 } 1781 } 1782 // Make sure index is in range... 1783 uint32_t field_idx = 0; 1784 RecordDecl::field_iterator field, field_end; 1785 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx) 1786 { 1787 if (idx == child_idx) 1788 { 1789 // Print the member type if requested 1790 // Print the member name and equal sign 1791 child_name.assign(field->getNameAsString().c_str()); 1792 1793 // Figure out the type byte size (field_type_info.first) and 1794 // alignment (field_type_info.second) from the AST context. 1795 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType()); 1796 assert(field_idx < record_layout.getFieldCount()); 1797 1798 child_byte_size = field_type_info.first / 8; 1799 1800 // Figure out the field offset within the current struct/union/class type 1801 bit_offset = record_layout.getFieldOffset (field_idx); 1802 child_byte_offset = bit_offset / 8; 1803 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size)) 1804 child_bitfield_bit_offset = bit_offset % 8; 1805 1806 return field->getType().getAsOpaquePtr(); 1807 } 1808 } 1809 } 1810 break; 1811 1812 case clang::Type::ObjCObject: 1813 case clang::Type::ObjCInterface: 1814 { 1815 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr()); 1816 assert (objc_class_type); 1817 if (objc_class_type) 1818 { 1819 uint32_t child_idx = 0; 1820 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1821 1822 if (class_interface_decl) 1823 { 1824 1825 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl); 1826 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 1827 if (superclass_interface_decl) 1828 { 1829 if (omit_empty_base_classes) 1830 { 1831 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0) 1832 { 1833 if (idx == 0) 1834 { 1835 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl)); 1836 1837 1838 child_name.assign(superclass_interface_decl->getNameAsString().c_str()); 1839 1840 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr()); 1841 1842 child_byte_size = ivar_type_info.first / 8; 1843 child_byte_offset = 0; 1844 1845 return ivar_qual_type.getAsOpaquePtr(); 1846 } 1847 1848 ++child_idx; 1849 } 1850 } 1851 else 1852 ++child_idx; 1853 } 1854 1855 const uint32_t superclass_idx = child_idx; 1856 1857 if (idx < (child_idx + class_interface_decl->ivar_size())) 1858 { 1859 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 1860 1861 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) 1862 { 1863 if (child_idx == idx) 1864 { 1865 const ObjCIvarDecl* ivar_decl = *ivar_pos; 1866 1867 QualType ivar_qual_type(ivar_decl->getType()); 1868 1869 child_name.assign(ivar_decl->getNameAsString().c_str()); 1870 1871 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr()); 1872 1873 child_byte_size = ivar_type_info.first / 8; 1874 1875 // Figure out the field offset within the current struct/union/class type 1876 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); 1877 child_byte_offset = bit_offset / 8; 1878 1879 return ivar_qual_type.getAsOpaquePtr(); 1880 } 1881 ++child_idx; 1882 } 1883 } 1884 } 1885 } 1886 } 1887 break; 1888 1889 case clang::Type::ObjCObjectPointer: 1890 { 1891 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr()); 1892 QualType pointee_type = pointer_type->getPointeeType(); 1893 1894 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 1895 { 1896 return GetChildClangTypeAtIndex (ast_context, 1897 parent_name, 1898 pointer_type->getPointeeType().getAsOpaquePtr(), 1899 idx, 1900 transparent_pointers, 1901 omit_empty_base_classes, 1902 child_name, 1903 child_byte_size, 1904 child_byte_offset, 1905 child_bitfield_bit_size, 1906 child_bitfield_bit_offset); 1907 } 1908 else 1909 { 1910 if (parent_name) 1911 { 1912 child_name.assign(1, '*'); 1913 child_name += parent_name; 1914 } 1915 1916 // We have a pointer to an simple type 1917 if (idx == 0) 1918 { 1919 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 1920 assert(clang_type_info.first % 8 == 0); 1921 child_byte_size = clang_type_info.first / 8; 1922 child_byte_offset = 0; 1923 return pointee_type.getAsOpaquePtr(); 1924 } 1925 } 1926 } 1927 break; 1928 1929 case clang::Type::ConstantArray: 1930 { 1931 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 1932 const uint64_t element_count = array->getSize().getLimitedValue(); 1933 1934 if (idx < element_count) 1935 { 1936 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType()); 1937 1938 char element_name[32]; 1939 ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); 1940 1941 child_name.assign(element_name); 1942 assert(field_type_info.first % 8 == 0); 1943 child_byte_size = field_type_info.first / 8; 1944 child_byte_offset = idx * child_byte_size; 1945 return array->getElementType().getAsOpaquePtr(); 1946 } 1947 } 1948 break; 1949 1950 case clang::Type::Pointer: 1951 { 1952 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr()); 1953 QualType pointee_type = pointer_type->getPointeeType(); 1954 1955 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 1956 { 1957 return GetChildClangTypeAtIndex (ast_context, 1958 parent_name, 1959 pointer_type->getPointeeType().getAsOpaquePtr(), 1960 idx, 1961 transparent_pointers, 1962 omit_empty_base_classes, 1963 child_name, 1964 child_byte_size, 1965 child_byte_offset, 1966 child_bitfield_bit_size, 1967 child_bitfield_bit_offset); 1968 } 1969 else 1970 { 1971 if (parent_name) 1972 { 1973 child_name.assign(1, '*'); 1974 child_name += parent_name; 1975 } 1976 1977 // We have a pointer to an simple type 1978 if (idx == 0) 1979 { 1980 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 1981 assert(clang_type_info.first % 8 == 0); 1982 child_byte_size = clang_type_info.first / 8; 1983 child_byte_offset = 0; 1984 return pointee_type.getAsOpaquePtr(); 1985 } 1986 } 1987 } 1988 break; 1989 1990 case clang::Type::Typedef: 1991 return GetChildClangTypeAtIndex (ast_context, 1992 parent_name, 1993 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 1994 idx, 1995 transparent_pointers, 1996 omit_empty_base_classes, 1997 child_name, 1998 child_byte_size, 1999 child_byte_offset, 2000 child_bitfield_bit_size, 2001 child_bitfield_bit_offset); 2002 break; 2003 2004 default: 2005 break; 2006 } 2007 } 2008 return NULL; 2009} 2010 2011static inline bool 2012BaseSpecifierIsEmpty (const CXXBaseSpecifier *b) 2013{ 2014 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false; 2015} 2016 2017static uint32_t 2018GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes) 2019{ 2020 uint32_t num_bases = 0; 2021 if (cxx_record_decl) 2022 { 2023 if (omit_empty_base_classes) 2024 { 2025 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2026 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2027 base_class != base_class_end; 2028 ++base_class) 2029 { 2030 // Skip empty base classes 2031 if (omit_empty_base_classes) 2032 { 2033 if (BaseSpecifierIsEmpty (base_class)) 2034 continue; 2035 } 2036 ++num_bases; 2037 } 2038 } 2039 else 2040 num_bases = cxx_record_decl->getNumBases(); 2041 } 2042 return num_bases; 2043} 2044 2045 2046static uint32_t 2047GetIndexForRecordBase 2048( 2049 const RecordDecl *record_decl, 2050 const CXXBaseSpecifier *base_spec, 2051 bool omit_empty_base_classes 2052) 2053{ 2054 uint32_t child_idx = 0; 2055 2056 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2057 2058// const char *super_name = record_decl->getNameAsCString(); 2059// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString(); 2060// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name); 2061// 2062 if (cxx_record_decl) 2063 { 2064 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2065 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2066 base_class != base_class_end; 2067 ++base_class) 2068 { 2069 if (omit_empty_base_classes) 2070 { 2071 if (BaseSpecifierIsEmpty (base_class)) 2072 continue; 2073 } 2074 2075// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name, 2076// child_idx, 2077// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); 2078// 2079// 2080 if (base_class == base_spec) 2081 return child_idx; 2082 ++child_idx; 2083 } 2084 } 2085 2086 return UINT32_MAX; 2087} 2088 2089 2090static uint32_t 2091GetIndexForRecordChild 2092( 2093 const RecordDecl *record_decl, 2094 NamedDecl *canonical_decl, 2095 bool omit_empty_base_classes 2096) 2097{ 2098 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes); 2099 2100// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2101// 2102//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString()); 2103// if (cxx_record_decl) 2104// { 2105// CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2106// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2107// base_class != base_class_end; 2108// ++base_class) 2109// { 2110// if (omit_empty_base_classes) 2111// { 2112// if (BaseSpecifierIsEmpty (base_class)) 2113// continue; 2114// } 2115// 2116//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", 2117//// record_decl->getNameAsCString(), 2118//// canonical_decl->getNameAsCString(), 2119//// child_idx, 2120//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); 2121// 2122// 2123// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2124// if (curr_base_class_decl == canonical_decl) 2125// { 2126// return child_idx; 2127// } 2128// ++child_idx; 2129// } 2130// } 2131// 2132// const uint32_t num_bases = child_idx; 2133 RecordDecl::field_iterator field, field_end; 2134 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 2135 field != field_end; 2136 ++field, ++child_idx) 2137 { 2138// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n", 2139// record_decl->getNameAsCString(), 2140// canonical_decl->getNameAsCString(), 2141// child_idx - num_bases, 2142// field->getNameAsCString()); 2143 2144 if (field->getCanonicalDecl() == canonical_decl) 2145 return child_idx; 2146 } 2147 2148 return UINT32_MAX; 2149} 2150 2151// Look for a child member (doesn't include base classes, but it does include 2152// their members) in the type hierarchy. Returns an index path into "clang_type" 2153// on how to reach the appropriate member. 2154// 2155// class A 2156// { 2157// public: 2158// int m_a; 2159// int m_b; 2160// }; 2161// 2162// class B 2163// { 2164// }; 2165// 2166// class C : 2167// public B, 2168// public A 2169// { 2170// }; 2171// 2172// If we have a clang type that describes "class C", and we wanted to looked 2173// "m_b" in it: 2174// 2175// With omit_empty_base_classes == false we would get an integer array back with: 2176// { 1, 1 } 2177// The first index 1 is the child index for "class A" within class C 2178// The second index 1 is the child index for "m_b" within class A 2179// 2180// With omit_empty_base_classes == true we would get an integer array back with: 2181// { 0, 1 } 2182// 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) 2183// The second index 1 is the child index for "m_b" within class A 2184 2185size_t 2186ClangASTContext::GetIndexOfChildMemberWithName 2187( 2188 ASTContext *ast_context, 2189 clang_type_t clang_type, 2190 const char *name, 2191 bool omit_empty_base_classes, 2192 std::vector<uint32_t>& child_indexes 2193) 2194{ 2195 if (clang_type && name && name[0]) 2196 { 2197 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2198 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2199 switch (type_class) 2200 { 2201 case clang::Type::Record: 2202 { 2203 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 2204 const RecordDecl *record_decl = record_type->getDecl(); 2205 2206 assert(record_decl); 2207 uint32_t child_idx = 0; 2208 2209 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2210 2211 // Try and find a field that matches NAME 2212 RecordDecl::field_iterator field, field_end; 2213 StringRef name_sref(name); 2214 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 2215 field != field_end; 2216 ++field, ++child_idx) 2217 { 2218 if (field->getName().equals (name_sref)) 2219 { 2220 // We have to add on the number of base classes to this index! 2221 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes)); 2222 return child_indexes.size(); 2223 } 2224 } 2225 2226 if (cxx_record_decl) 2227 { 2228 const RecordDecl *parent_record_decl = cxx_record_decl; 2229 2230 //printf ("parent = %s\n", parent_record_decl->getNameAsCString()); 2231 2232 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl(); 2233 // Didn't find things easily, lets let clang do its thang... 2234 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name)); 2235 DeclarationName decl_name(&ident_ref); 2236 2237 CXXBasePaths paths; 2238 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember, 2239 decl_name.getAsOpaquePtr(), 2240 paths)) 2241 { 2242 CXXBasePaths::const_paths_iterator path, path_end = paths.end(); 2243 for (path = paths.begin(); path != path_end; ++path) 2244 { 2245 const size_t num_path_elements = path->size(); 2246 for (size_t e=0; e<num_path_elements; ++e) 2247 { 2248 CXXBasePathElement elem = (*path)[e]; 2249 2250 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes); 2251 if (child_idx == UINT32_MAX) 2252 { 2253 child_indexes.clear(); 2254 return 0; 2255 } 2256 else 2257 { 2258 child_indexes.push_back (child_idx); 2259 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl()); 2260 } 2261 } 2262 DeclContext::lookup_iterator named_decl_pos; 2263 for (named_decl_pos = path->Decls.first; 2264 named_decl_pos != path->Decls.second && parent_record_decl; 2265 ++named_decl_pos) 2266 { 2267 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString()); 2268 2269 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes); 2270 if (child_idx == UINT32_MAX) 2271 { 2272 child_indexes.clear(); 2273 return 0; 2274 } 2275 else 2276 { 2277 child_indexes.push_back (child_idx); 2278 } 2279 } 2280 } 2281 return child_indexes.size(); 2282 } 2283 } 2284 2285 } 2286 break; 2287 2288 case clang::Type::ObjCObject: 2289 case clang::Type::ObjCInterface: 2290 { 2291 StringRef name_sref(name); 2292 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 2293 assert (objc_class_type); 2294 if (objc_class_type) 2295 { 2296 uint32_t child_idx = 0; 2297 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 2298 2299 if (class_interface_decl) 2300 { 2301 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 2302 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 2303 2304 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) 2305 { 2306 const ObjCIvarDecl* ivar_decl = *ivar_pos; 2307 2308 if (ivar_decl->getName().equals (name_sref)) 2309 { 2310 if ((!omit_empty_base_classes && superclass_interface_decl) || 2311 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) 2312 ++child_idx; 2313 2314 child_indexes.push_back (child_idx); 2315 return child_indexes.size(); 2316 } 2317 } 2318 2319 if (superclass_interface_decl) 2320 { 2321 // The super class index is always zero for ObjC classes, 2322 // so we push it onto the child indexes in case we find 2323 // an ivar in our superclass... 2324 child_indexes.push_back (0); 2325 2326 if (GetIndexOfChildMemberWithName (ast_context, 2327 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), 2328 name, 2329 omit_empty_base_classes, 2330 child_indexes)) 2331 { 2332 // We did find an ivar in a superclass so just 2333 // return the results! 2334 return child_indexes.size(); 2335 } 2336 2337 // We didn't find an ivar matching "name" in our 2338 // superclass, pop the superclass zero index that 2339 // we pushed on above. 2340 child_indexes.pop_back(); 2341 } 2342 } 2343 } 2344 } 2345 break; 2346 2347 case clang::Type::ObjCObjectPointer: 2348 { 2349 return GetIndexOfChildMemberWithName (ast_context, 2350 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), 2351 name, 2352 omit_empty_base_classes, 2353 child_indexes); 2354 } 2355 break; 2356 2357 2358 case clang::Type::ConstantArray: 2359 { 2360// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 2361// const uint64_t element_count = array->getSize().getLimitedValue(); 2362// 2363// if (idx < element_count) 2364// { 2365// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType()); 2366// 2367// char element_name[32]; 2368// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); 2369// 2370// child_name.assign(element_name); 2371// assert(field_type_info.first % 8 == 0); 2372// child_byte_size = field_type_info.first / 8; 2373// child_byte_offset = idx * child_byte_size; 2374// return array->getElementType().getAsOpaquePtr(); 2375// } 2376 } 2377 break; 2378 2379// case clang::Type::MemberPointerType: 2380// { 2381// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); 2382// QualType pointee_type = mem_ptr_type->getPointeeType(); 2383// 2384// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2385// { 2386// return GetIndexOfChildWithName (ast_context, 2387// mem_ptr_type->getPointeeType().getAsOpaquePtr(), 2388// name); 2389// } 2390// } 2391// break; 2392// 2393 case clang::Type::LValueReference: 2394 case clang::Type::RValueReference: 2395 { 2396 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 2397 QualType pointee_type = reference_type->getPointeeType(); 2398 2399 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2400 { 2401 return GetIndexOfChildMemberWithName (ast_context, 2402 reference_type->getPointeeType().getAsOpaquePtr(), 2403 name, 2404 omit_empty_base_classes, 2405 child_indexes); 2406 } 2407 } 2408 break; 2409 2410 case clang::Type::Pointer: 2411 { 2412 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 2413 QualType pointee_type = pointer_type->getPointeeType(); 2414 2415 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2416 { 2417 return GetIndexOfChildMemberWithName (ast_context, 2418 pointer_type->getPointeeType().getAsOpaquePtr(), 2419 name, 2420 omit_empty_base_classes, 2421 child_indexes); 2422 } 2423 else 2424 { 2425// if (parent_name) 2426// { 2427// child_name.assign(1, '*'); 2428// child_name += parent_name; 2429// } 2430// 2431// // We have a pointer to an simple type 2432// if (idx == 0) 2433// { 2434// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 2435// assert(clang_type_info.first % 8 == 0); 2436// child_byte_size = clang_type_info.first / 8; 2437// child_byte_offset = 0; 2438// return pointee_type.getAsOpaquePtr(); 2439// } 2440 } 2441 } 2442 break; 2443 2444 case clang::Type::Typedef: 2445 return GetIndexOfChildMemberWithName (ast_context, 2446 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 2447 name, 2448 omit_empty_base_classes, 2449 child_indexes); 2450 2451 default: 2452 break; 2453 } 2454 } 2455 return 0; 2456} 2457 2458 2459// Get the index of the child of "clang_type" whose name matches. This function 2460// doesn't descend into the children, but only looks one level deep and name 2461// matches can include base class names. 2462 2463uint32_t 2464ClangASTContext::GetIndexOfChildWithName 2465( 2466 ASTContext *ast_context, 2467 clang_type_t clang_type, 2468 const char *name, 2469 bool omit_empty_base_classes 2470) 2471{ 2472 if (clang_type && name && name[0]) 2473 { 2474 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2475 2476 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2477 2478 switch (type_class) 2479 { 2480 case clang::Type::Record: 2481 { 2482 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 2483 const RecordDecl *record_decl = record_type->getDecl(); 2484 2485 assert(record_decl); 2486 uint32_t child_idx = 0; 2487 2488 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2489 2490 if (cxx_record_decl) 2491 { 2492 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2493 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2494 base_class != base_class_end; 2495 ++base_class) 2496 { 2497 // Skip empty base classes 2498 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2499 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false) 2500 continue; 2501 2502 if (base_class->getType().getAsString().compare (name) == 0) 2503 return child_idx; 2504 ++child_idx; 2505 } 2506 } 2507 2508 // Try and find a field that matches NAME 2509 RecordDecl::field_iterator field, field_end; 2510 StringRef name_sref(name); 2511 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 2512 field != field_end; 2513 ++field, ++child_idx) 2514 { 2515 if (field->getName().equals (name_sref)) 2516 return child_idx; 2517 } 2518 2519 } 2520 break; 2521 2522 case clang::Type::ObjCObject: 2523 case clang::Type::ObjCInterface: 2524 { 2525 StringRef name_sref(name); 2526 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 2527 assert (objc_class_type); 2528 if (objc_class_type) 2529 { 2530 uint32_t child_idx = 0; 2531 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 2532 2533 if (class_interface_decl) 2534 { 2535 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 2536 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 2537 2538 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) 2539 { 2540 const ObjCIvarDecl* ivar_decl = *ivar_pos; 2541 2542 if (ivar_decl->getName().equals (name_sref)) 2543 { 2544 if ((!omit_empty_base_classes && superclass_interface_decl) || 2545 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) 2546 ++child_idx; 2547 2548 return child_idx; 2549 } 2550 } 2551 2552 if (superclass_interface_decl) 2553 { 2554 if (superclass_interface_decl->getName().equals (name_sref)) 2555 return 0; 2556 } 2557 } 2558 } 2559 } 2560 break; 2561 2562 case clang::Type::ObjCObjectPointer: 2563 { 2564 return GetIndexOfChildWithName (ast_context, 2565 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), 2566 name, 2567 omit_empty_base_classes); 2568 } 2569 break; 2570 2571 case clang::Type::ConstantArray: 2572 { 2573// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 2574// const uint64_t element_count = array->getSize().getLimitedValue(); 2575// 2576// if (idx < element_count) 2577// { 2578// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType()); 2579// 2580// char element_name[32]; 2581// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); 2582// 2583// child_name.assign(element_name); 2584// assert(field_type_info.first % 8 == 0); 2585// child_byte_size = field_type_info.first / 8; 2586// child_byte_offset = idx * child_byte_size; 2587// return array->getElementType().getAsOpaquePtr(); 2588// } 2589 } 2590 break; 2591 2592// case clang::Type::MemberPointerType: 2593// { 2594// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); 2595// QualType pointee_type = mem_ptr_type->getPointeeType(); 2596// 2597// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2598// { 2599// return GetIndexOfChildWithName (ast_context, 2600// mem_ptr_type->getPointeeType().getAsOpaquePtr(), 2601// name); 2602// } 2603// } 2604// break; 2605// 2606 case clang::Type::LValueReference: 2607 case clang::Type::RValueReference: 2608 { 2609 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 2610 QualType pointee_type = reference_type->getPointeeType(); 2611 2612 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2613 { 2614 return GetIndexOfChildWithName (ast_context, 2615 reference_type->getPointeeType().getAsOpaquePtr(), 2616 name, 2617 omit_empty_base_classes); 2618 } 2619 } 2620 break; 2621 2622 case clang::Type::Pointer: 2623 { 2624 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 2625 QualType pointee_type = pointer_type->getPointeeType(); 2626 2627 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2628 { 2629 return GetIndexOfChildWithName (ast_context, 2630 pointer_type->getPointeeType().getAsOpaquePtr(), 2631 name, 2632 omit_empty_base_classes); 2633 } 2634 else 2635 { 2636// if (parent_name) 2637// { 2638// child_name.assign(1, '*'); 2639// child_name += parent_name; 2640// } 2641// 2642// // We have a pointer to an simple type 2643// if (idx == 0) 2644// { 2645// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 2646// assert(clang_type_info.first % 8 == 0); 2647// child_byte_size = clang_type_info.first / 8; 2648// child_byte_offset = 0; 2649// return pointee_type.getAsOpaquePtr(); 2650// } 2651 } 2652 } 2653 break; 2654 2655 case clang::Type::Typedef: 2656 return GetIndexOfChildWithName (ast_context, 2657 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 2658 name, 2659 omit_empty_base_classes); 2660 2661 default: 2662 break; 2663 } 2664 } 2665 return UINT32_MAX; 2666} 2667 2668#pragma mark TagType 2669 2670bool 2671ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind) 2672{ 2673 if (tag_clang_type) 2674 { 2675 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type)); 2676 clang::Type *clang_type = tag_qual_type.getTypePtr(); 2677 if (clang_type) 2678 { 2679 TagType *tag_type = dyn_cast<TagType>(clang_type); 2680 if (tag_type) 2681 { 2682 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl()); 2683 if (tag_decl) 2684 { 2685 tag_decl->setTagKind ((TagDecl::TagKind)kind); 2686 return true; 2687 } 2688 } 2689 } 2690 } 2691 return false; 2692} 2693 2694 2695#pragma mark DeclContext Functions 2696 2697DeclContext * 2698ClangASTContext::GetDeclContextForType (clang_type_t clang_type) 2699{ 2700 if (clang_type == NULL) 2701 return NULL; 2702 2703 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2704 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2705 switch (type_class) 2706 { 2707 case clang::Type::FunctionNoProto: break; 2708 case clang::Type::FunctionProto: break; 2709 case clang::Type::IncompleteArray: break; 2710 case clang::Type::VariableArray: break; 2711 case clang::Type::ConstantArray: break; 2712 case clang::Type::ExtVector: break; 2713 case clang::Type::Vector: break; 2714 case clang::Type::Builtin: break; 2715 case clang::Type::BlockPointer: break; 2716 case clang::Type::Pointer: break; 2717 case clang::Type::LValueReference: break; 2718 case clang::Type::RValueReference: break; 2719 case clang::Type::MemberPointer: break; 2720 case clang::Type::Complex: break; 2721 case clang::Type::ObjCObject: break; 2722 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface(); 2723 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr()); 2724 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl(); 2725 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl(); 2726 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 2727 2728 case clang::Type::TypeOfExpr: break; 2729 case clang::Type::TypeOf: break; 2730 case clang::Type::Decltype: break; 2731 //case clang::Type::QualifiedName: break; 2732 case clang::Type::TemplateSpecialization: break; 2733 } 2734 // No DeclContext in this type... 2735 return NULL; 2736} 2737 2738#pragma mark Namespace Declarations 2739 2740NamespaceDecl * 2741ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx) 2742{ 2743 // TODO: Do something intelligent with the Declaration object passed in 2744 // like maybe filling in the SourceLocation with it... 2745 if (name) 2746 { 2747 ASTContext *ast_context = getASTContext(); 2748 if (decl_ctx == NULL) 2749 decl_ctx = ast_context->getTranslationUnitDecl(); 2750 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name)); 2751 } 2752 return NULL; 2753} 2754 2755 2756#pragma mark Function Types 2757 2758FunctionDecl * 2759ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline) 2760{ 2761 if (name) 2762 { 2763 ASTContext *ast_context = getASTContext(); 2764 assert (ast_context != NULL); 2765 2766 if (name && name[0]) 2767 { 2768 return FunctionDecl::Create(*ast_context, 2769 ast_context->getTranslationUnitDecl(), 2770 SourceLocation(), 2771 DeclarationName (&ast_context->Idents.get(name)), 2772 QualType::getFromOpaquePtr(function_clang_type), 2773 NULL, 2774 (FunctionDecl::StorageClass)storage, 2775 (FunctionDecl::StorageClass)storage, 2776 is_inline); 2777 } 2778 else 2779 { 2780 return FunctionDecl::Create(*ast_context, 2781 ast_context->getTranslationUnitDecl(), 2782 SourceLocation(), 2783 DeclarationName (), 2784 QualType::getFromOpaquePtr(function_clang_type), 2785 NULL, 2786 (FunctionDecl::StorageClass)storage, 2787 (FunctionDecl::StorageClass)storage, 2788 is_inline); 2789 } 2790 } 2791 return NULL; 2792} 2793 2794clang_type_t 2795ClangASTContext::CreateFunctionType (ASTContext *ast_context, 2796 clang_type_t result_type, 2797 clang_type_t *args, 2798 unsigned num_args, 2799 bool is_variadic, 2800 unsigned type_quals) 2801{ 2802 assert (ast_context != NULL); 2803 std::vector<QualType> qual_type_args; 2804 for (unsigned i=0; i<num_args; ++i) 2805 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i])); 2806 2807 // TODO: Detect calling convention in DWARF? 2808 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type), 2809 qual_type_args.empty() ? NULL : &qual_type_args.front(), 2810 qual_type_args.size(), 2811 is_variadic, 2812 type_quals, 2813 false, // hasExceptionSpec 2814 false, // hasAnyExceptionSpec, 2815 0, // NumExs 2816 0, // const QualType *ExArray 2817 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn); 2818} 2819 2820ParmVarDecl * 2821ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage) 2822{ 2823 ASTContext *ast_context = getASTContext(); 2824 assert (ast_context != NULL); 2825 return ParmVarDecl::Create(*ast_context, 2826 ast_context->getTranslationUnitDecl(), 2827 SourceLocation(), 2828 name && name[0] ? &ast_context->Idents.get(name) : NULL, 2829 QualType::getFromOpaquePtr(param_type), 2830 NULL, 2831 (VarDecl::StorageClass)storage, 2832 (VarDecl::StorageClass)storage, 2833 0); 2834} 2835 2836void 2837ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params) 2838{ 2839 if (function_decl) 2840 function_decl->setParams (params, num_params); 2841} 2842 2843 2844#pragma mark Array Types 2845 2846clang_type_t 2847ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride) 2848{ 2849 if (element_type) 2850 { 2851 ASTContext *ast_context = getASTContext(); 2852 assert (ast_context != NULL); 2853 llvm::APInt ap_element_count (64, element_count); 2854 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type), 2855 ap_element_count, 2856 ArrayType::Normal, 2857 0).getAsOpaquePtr(); // ElemQuals 2858 } 2859 return NULL; 2860} 2861 2862 2863#pragma mark TagDecl 2864 2865bool 2866ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type) 2867{ 2868 if (clang_type) 2869 { 2870 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2871 clang::Type *t = qual_type.getTypePtr(); 2872 if (t) 2873 { 2874 TagType *tag_type = dyn_cast<TagType>(t); 2875 if (tag_type) 2876 { 2877 TagDecl *tag_decl = tag_type->getDecl(); 2878 if (tag_decl) 2879 { 2880 tag_decl->startDefinition(); 2881 return true; 2882 } 2883 } 2884 } 2885 } 2886 return false; 2887} 2888 2889bool 2890ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type) 2891{ 2892 if (clang_type) 2893 { 2894 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2895 clang::Type *t = qual_type.getTypePtr(); 2896 if (t) 2897 { 2898 TagType *tag_type = dyn_cast<TagType>(t); 2899 if (tag_type) 2900 { 2901 TagDecl *tag_decl = tag_type->getDecl(); 2902 if (tag_decl) 2903 { 2904 tag_decl->completeDefinition(); 2905 return true; 2906 } 2907 } 2908 } 2909 } 2910 return false; 2911} 2912 2913 2914#pragma mark Enumeration Types 2915 2916clang_type_t 2917ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type) 2918{ 2919 // TODO: Do something intelligent with the Declaration object passed in 2920 // like maybe filling in the SourceLocation with it... 2921 ASTContext *ast_context = getASTContext(); 2922 assert (ast_context != NULL); 2923 EnumDecl *enum_decl = EnumDecl::Create(*ast_context, 2924 ast_context->getTranslationUnitDecl(), 2925 SourceLocation(), 2926 name && name[0] ? &ast_context->Idents.get(name) : NULL, 2927 SourceLocation(), 2928 NULL); 2929 if (enum_decl) 2930 { 2931 // TODO: check if we should be setting the promotion type too? 2932 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type)); 2933 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr(); 2934 } 2935 return NULL; 2936} 2937 2938clang_type_t 2939ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type) 2940{ 2941 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); 2942 2943 clang::Type *clang_type = enum_qual_type.getTypePtr(); 2944 if (clang_type) 2945 { 2946 const EnumType *enum_type = dyn_cast<EnumType>(clang_type); 2947 if (enum_type) 2948 { 2949 EnumDecl *enum_decl = enum_type->getDecl(); 2950 if (enum_decl) 2951 return enum_decl->getIntegerType().getAsOpaquePtr(); 2952 } 2953 } 2954 return NULL; 2955} 2956bool 2957ClangASTContext::AddEnumerationValueToEnumerationType 2958( 2959 clang_type_t enum_clang_type, 2960 clang_type_t enumerator_clang_type, 2961 const Declaration &decl, 2962 const char *name, 2963 int64_t enum_value, 2964 uint32_t enum_value_bit_size 2965) 2966{ 2967 if (enum_clang_type && enumerator_clang_type && name) 2968 { 2969 // TODO: Do something intelligent with the Declaration object passed in 2970 // like maybe filling in the SourceLocation with it... 2971 ASTContext *ast_context = getASTContext(); 2972 IdentifierTable *identifier_table = getIdentifierTable(); 2973 2974 assert (ast_context != NULL); 2975 assert (identifier_table != NULL); 2976 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); 2977 2978 clang::Type *clang_type = enum_qual_type.getTypePtr(); 2979 if (clang_type) 2980 { 2981 const EnumType *enum_type = dyn_cast<EnumType>(clang_type); 2982 2983 if (enum_type) 2984 { 2985 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false); 2986 enum_llvm_apsint = enum_value; 2987 EnumConstantDecl *enumerator_decl = 2988 EnumConstantDecl::Create(*ast_context, 2989 enum_type->getDecl(), 2990 SourceLocation(), 2991 name ? &identifier_table->get(name) : NULL, // Identifier 2992 QualType::getFromOpaquePtr(enumerator_clang_type), 2993 NULL, 2994 enum_llvm_apsint); 2995 2996 if (enumerator_decl) 2997 { 2998 enum_type->getDecl()->addDecl(enumerator_decl); 2999 return true; 3000 } 3001 } 3002 } 3003 } 3004 return false; 3005} 3006 3007#pragma mark Pointers & References 3008 3009clang_type_t 3010ClangASTContext::CreatePointerType (clang_type_t clang_type) 3011{ 3012 if (clang_type) 3013 { 3014 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3015 3016 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3017 switch (type_class) 3018 { 3019 case clang::Type::ObjCObject: 3020 case clang::Type::ObjCInterface: 3021 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); 3022 3023 default: 3024 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr(); 3025 } 3026 } 3027 return NULL; 3028} 3029 3030clang_type_t 3031ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type) 3032{ 3033 if (clang_type) 3034 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); 3035 return NULL; 3036} 3037 3038clang_type_t 3039ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type) 3040{ 3041 if (clang_type) 3042 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); 3043 return NULL; 3044} 3045 3046clang_type_t 3047ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type) 3048{ 3049 if (clang_pointee_type && clang_pointee_type) 3050 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type), 3051 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr(); 3052 return NULL; 3053} 3054 3055size_t 3056ClangASTContext::GetPointerBitSize () 3057{ 3058 ASTContext *ast_context = getASTContext(); 3059 return ast_context->getTypeSize(ast_context->VoidPtrTy); 3060} 3061 3062bool 3063ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type) 3064{ 3065 if (clang_type == NULL) 3066 return false; 3067 3068 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3069 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3070 switch (type_class) 3071 { 3072 case clang::Type::ObjCObjectPointer: 3073 if (target_type) 3074 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3075 return true; 3076 case clang::Type::BlockPointer: 3077 if (target_type) 3078 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3079 return true; 3080 case clang::Type::Pointer: 3081 if (target_type) 3082 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3083 return true; 3084 case clang::Type::MemberPointer: 3085 if (target_type) 3086 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3087 return true; 3088 case clang::Type::LValueReference: 3089 if (target_type) 3090 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); 3091 return true; 3092 case clang::Type::RValueReference: 3093 if (target_type) 3094 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); 3095 return true; 3096 case clang::Type::Typedef: 3097 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 3098 default: 3099 break; 3100 } 3101 return false; 3102} 3103 3104bool 3105ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed) 3106{ 3107 if (!clang_type) 3108 return false; 3109 3110 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3111 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()); 3112 3113 if (builtin_type) 3114 { 3115 if (builtin_type->isInteger()) 3116 is_signed = builtin_type->isSignedInteger(); 3117 3118 return true; 3119 } 3120 3121 return false; 3122} 3123 3124bool 3125ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type) 3126{ 3127 if (clang_type) 3128 { 3129 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3130 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3131 switch (type_class) 3132 { 3133 case clang::Type::ObjCObjectPointer: 3134 if (target_type) 3135 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3136 return true; 3137 case clang::Type::BlockPointer: 3138 if (target_type) 3139 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3140 return true; 3141 case clang::Type::Pointer: 3142 if (target_type) 3143 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3144 return true; 3145 case clang::Type::MemberPointer: 3146 if (target_type) 3147 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3148 return true; 3149 case clang::Type::Typedef: 3150 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type); 3151 default: 3152 break; 3153 } 3154 } 3155 return false; 3156} 3157 3158bool 3159ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex) 3160{ 3161 if (clang_type) 3162 { 3163 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3164 3165 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal())) 3166 { 3167 clang::BuiltinType::Kind kind = BT->getKind(); 3168 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble) 3169 { 3170 count = 1; 3171 is_complex = false; 3172 return true; 3173 } 3174 } 3175 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal())) 3176 { 3177 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex)) 3178 { 3179 count = 2; 3180 is_complex = true; 3181 return true; 3182 } 3183 } 3184 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal())) 3185 { 3186 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex)) 3187 { 3188 count = VT->getNumElements(); 3189 is_complex = false; 3190 return true; 3191 } 3192 } 3193 } 3194 return false; 3195} 3196 3197bool 3198ClangASTContext::IsCXXClassType (clang_type_t clang_type) 3199{ 3200 if (clang_type) 3201 { 3202 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3203 if (qual_type->getAsCXXRecordDecl() != NULL) 3204 return true; 3205 } 3206 return false; 3207} 3208 3209bool 3210ClangASTContext::IsObjCClassType (clang_type_t clang_type) 3211{ 3212 if (clang_type) 3213 { 3214 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3215 if (qual_type->isObjCObjectOrInterfaceType()) 3216 return true; 3217 } 3218 return false; 3219} 3220 3221 3222 3223 3224bool 3225ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length) 3226{ 3227 if (clang_type) 3228 { 3229 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3230 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3231 switch (type_class) 3232 { 3233 case clang::Type::ConstantArray: 3234 { 3235 ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr()); 3236 QualType element_qual_type = array->getElementType(); 3237 clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr(); 3238 if (canonical_type && canonical_type->isCharType()) 3239 { 3240 // We know the size of the array and it could be a C string 3241 // since it is an array of characters 3242 length = array->getSize().getLimitedValue(); 3243 return true; 3244 } 3245 } 3246 break; 3247 3248 case clang::Type::Pointer: 3249 { 3250 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 3251 clang::Type *pointee_type_ptr = pointer_type->getPointeeType().getTypePtr(); 3252 if (pointee_type_ptr) 3253 { 3254 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr(); 3255 length = 0; // No length info, read until a NULL terminator is received 3256 if (canonical_type_ptr) 3257 return canonical_type_ptr->isCharType(); 3258 else 3259 return pointee_type_ptr->isCharType(); 3260 } 3261 } 3262 break; 3263 3264 case clang::Type::Typedef: 3265 return ClangASTContext::IsCStringType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), length); 3266 3267 case clang::Type::LValueReference: 3268 case clang::Type::RValueReference: 3269 { 3270 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 3271 clang::Type *pointee_type_ptr = reference_type->getPointeeType().getTypePtr(); 3272 if (pointee_type_ptr) 3273 { 3274 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr(); 3275 length = 0; // No length info, read until a NULL terminator is received 3276 if (canonical_type_ptr) 3277 return canonical_type_ptr->isCharType(); 3278 else 3279 return pointee_type_ptr->isCharType(); 3280 } 3281 } 3282 break; 3283 } 3284 } 3285 return false; 3286} 3287 3288bool 3289ClangASTContext::IsFunctionPointerType (clang_type_t clang_type) 3290{ 3291 if (clang_type) 3292 { 3293 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3294 3295 if (qual_type->isFunctionPointerType()) 3296 return true; 3297 3298 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3299 switch (type_class) 3300 { 3301 case clang::Type::Typedef: 3302 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 3303 3304 case clang::Type::LValueReference: 3305 case clang::Type::RValueReference: 3306 { 3307 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 3308 if (reference_type) 3309 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr()); 3310 } 3311 break; 3312 } 3313 } 3314 return false; 3315} 3316 3317 3318 3319 3320bool 3321ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size) 3322{ 3323 if (!clang_type) 3324 return false; 3325 3326 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3327 3328 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3329 switch (type_class) 3330 { 3331 case clang::Type::ConstantArray: 3332 if (member_type) 3333 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3334 if (size) 3335 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX); 3336 return true; 3337 case clang::Type::IncompleteArray: 3338 if (member_type) 3339 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3340 if (size) 3341 *size = 0; 3342 return true; 3343 case clang::Type::VariableArray: 3344 if (member_type) 3345 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3346 if (size) 3347 *size = 0; 3348 case clang::Type::DependentSizedArray: 3349 if (member_type) 3350 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3351 if (size) 3352 *size = 0; 3353 return true; 3354 } 3355 return false; 3356} 3357 3358 3359#pragma mark Typedefs 3360 3361clang_type_t 3362ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx) 3363{ 3364 if (clang_type) 3365 { 3366 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3367 ASTContext *ast_context = getASTContext(); 3368 IdentifierTable *identifier_table = getIdentifierTable(); 3369 assert (ast_context != NULL); 3370 assert (identifier_table != NULL); 3371 if (decl_ctx == NULL) 3372 decl_ctx = ast_context->getTranslationUnitDecl(); 3373 TypedefDecl *decl = TypedefDecl::Create(*ast_context, 3374 decl_ctx, 3375 SourceLocation(), 3376 name ? &identifier_table->get(name) : NULL, // Identifier 3377 ast_context->CreateTypeSourceInfo(qual_type)); 3378 3379 // Get a uniqued QualType for the typedef decl type 3380 return ast_context->getTypedefType (decl).getAsOpaquePtr(); 3381 } 3382 return NULL; 3383} 3384 3385 3386std::string 3387ClangASTContext::GetTypeName (clang_type_t opaque_qual_type) 3388{ 3389 std::string return_name; 3390 3391 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type)); 3392 3393 const TypedefType *typedef_type = qual_type->getAs<TypedefType>(); 3394 if (typedef_type) 3395 { 3396 const TypedefDecl *typedef_decl = typedef_type->getDecl(); 3397 return_name = typedef_decl->getQualifiedNameAsString(); 3398 } 3399 else 3400 { 3401 return_name = qual_type.getAsString(); 3402 } 3403 3404 return return_name; 3405} 3406 3407// Disable this for now since I can't seem to get a nicely formatted float 3408// out of the APFloat class without just getting the float, double or quad 3409// and then using a formatted print on it which defeats the purpose. We ideally 3410// would like to get perfect string values for any kind of float semantics 3411// so we can support remote targets. The code below also requires a patch to 3412// llvm::APInt. 3413//bool 3414//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) 3415//{ 3416// uint32_t count = 0; 3417// bool is_complex = false; 3418// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex)) 3419// { 3420// unsigned num_bytes_per_float = byte_size / count; 3421// unsigned num_bits_per_float = num_bytes_per_float * 8; 3422// 3423// float_str.clear(); 3424// uint32_t i; 3425// for (i=0; i<count; i++) 3426// { 3427// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order); 3428// bool is_ieee = false; 3429// APFloat ap_float(ap_int, is_ieee); 3430// char s[1024]; 3431// unsigned int hex_digits = 0; 3432// bool upper_case = false; 3433// 3434// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0) 3435// { 3436// if (i > 0) 3437// float_str.append(", "); 3438// float_str.append(s); 3439// if (i == 1 && is_complex) 3440// float_str.append(1, 'i'); 3441// } 3442// } 3443// return !float_str.empty(); 3444// } 3445// return false; 3446//} 3447 3448size_t 3449ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size) 3450{ 3451 if (clang_type) 3452 { 3453 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3454 uint32_t count = 0; 3455 bool is_complex = false; 3456 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex)) 3457 { 3458 // TODO: handle complex and vector types 3459 if (count != 1) 3460 return false; 3461 3462 StringRef s_sref(s); 3463 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref); 3464 3465 const uint64_t bit_size = ast_context->getTypeSize (qual_type); 3466 const uint64_t byte_size = bit_size / 8; 3467 if (dst_size >= byte_size) 3468 { 3469 if (bit_size == sizeof(float)*8) 3470 { 3471 float float32 = ap_float.convertToFloat(); 3472 ::memcpy (dst, &float32, byte_size); 3473 return byte_size; 3474 } 3475 else if (bit_size >= 64) 3476 { 3477 llvm::APInt ap_int(ap_float.bitcastToAPInt()); 3478 ::memcpy (dst, ap_int.getRawData(), byte_size); 3479 return byte_size; 3480 } 3481 } 3482 } 3483 } 3484 return 0; 3485} 3486 3487unsigned 3488ClangASTContext::GetTypeQualifiers(clang_type_t clang_type) 3489{ 3490 assert (clang_type); 3491 3492 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3493 3494 return qual_type.getQualifiers().getCVRQualifiers(); 3495} 3496