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