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