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