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