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