ClangASTContext.cpp revision cf18faaf72090a68480145ca206955d792633559
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 737 QualType src = QualType::getFromOpaquePtr(clang_type); 738 QualType dst = importer.Import(src); 739 740 return dst.getAsOpaquePtr(); 741} 742 743bool 744ClangASTContext::AreTypesSame(ASTContext *ast_context, 745 clang_type_t type1, 746 clang_type_t type2) 747{ 748 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1), 749 QualType::getFromOpaquePtr(type2)); 750} 751 752#pragma mark CVR modifiers 753 754clang_type_t 755ClangASTContext::AddConstModifier (clang_type_t clang_type) 756{ 757 if (clang_type) 758 { 759 QualType result(QualType::getFromOpaquePtr(clang_type)); 760 result.addConst(); 761 return result.getAsOpaquePtr(); 762 } 763 return NULL; 764} 765 766clang_type_t 767ClangASTContext::AddRestrictModifier (clang_type_t clang_type) 768{ 769 if (clang_type) 770 { 771 QualType result(QualType::getFromOpaquePtr(clang_type)); 772 result.getQualifiers().setRestrict (true); 773 return result.getAsOpaquePtr(); 774 } 775 return NULL; 776} 777 778clang_type_t 779ClangASTContext::AddVolatileModifier (clang_type_t clang_type) 780{ 781 if (clang_type) 782 { 783 QualType result(QualType::getFromOpaquePtr(clang_type)); 784 result.getQualifiers().setVolatile (true); 785 return result.getAsOpaquePtr(); 786 } 787 return NULL; 788} 789 790#pragma mark Structure, Unions, Classes 791 792clang_type_t 793ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language) 794{ 795 ASTContext *ast_context = getASTContext(); 796 assert (ast_context != NULL); 797 798 if (decl_ctx == NULL) 799 decl_ctx = ast_context->getTranslationUnitDecl(); 800 801 802 if (language == eLanguageTypeObjC) 803 { 804 bool isForwardDecl = true; 805 bool isInternal = false; 806 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal); 807 } 808 809 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and 810 // we will need to update this code. I was told to currently always use 811 // the CXXRecordDecl class since we often don't know from debug information 812 // if something is struct or a class, so we default to always use the more 813 // complete definition just in case. 814 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context, 815 (TagDecl::TagKind)kind, 816 decl_ctx, 817 SourceLocation(), 818 name && name[0] ? &ast_context->Idents.get(name) : NULL); 819 820 return ast_context->getTagDeclType(decl).getAsOpaquePtr(); 821} 822 823static bool 824IsOperator (const char *name, OverloadedOperatorKind &op_kind) 825{ 826 if (name == NULL || name[0] == '\0') 827 return false; 828 829 if (::strstr(name, "operator ") != name) 830 return false; 831 832 const char *post_op_name = name + 9; 833 834 // This is an operator, set the overloaded operator kind to invalid 835 // in case this is a conversion operator... 836 op_kind = NUM_OVERLOADED_OPERATORS; 837 838 switch (post_op_name[0]) 839 { 840 case 'n': 841 if (strcmp (post_op_name, "new") == 0) 842 op_kind = OO_New; 843 else if (strcmp (post_op_name, "new[]") == 0) 844 op_kind = OO_Array_New; 845 break; 846 847 case 'd': 848 if (strcmp (post_op_name, "delete") == 0) 849 op_kind = OO_Delete; 850 else if (strcmp (post_op_name, "delete[]") == 0) 851 op_kind = OO_Array_Delete; 852 break; 853 854 case '+': 855 if (post_op_name[1] == '\0') 856 op_kind = OO_Plus; 857 else if (post_op_name[2] == '\0') 858 { 859 if (post_op_name[1] == '=') 860 op_kind = OO_PlusEqual; 861 else if (post_op_name[1] == '+') 862 op_kind = OO_PlusPlus; 863 } 864 break; 865 866 case '-': 867 if (post_op_name[1] == '\0') 868 op_kind = OO_Minus; 869 else if (post_op_name[2] == '\0') 870 { 871 switch (post_op_name[1]) 872 { 873 case '=': op_kind = OO_MinusEqual; break; 874 case '-': op_kind = OO_MinusMinus; break; 875 case '>': op_kind = OO_Arrow; break; 876 } 877 } 878 else if (post_op_name[3] == '\0') 879 { 880 if (post_op_name[2] == '*') 881 op_kind = OO_ArrowStar; break; 882 } 883 break; 884 885 case '*': 886 if (post_op_name[1] == '\0') 887 op_kind = OO_Star; 888 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 889 op_kind = OO_StarEqual; 890 break; 891 892 case '/': 893 if (post_op_name[1] == '\0') 894 op_kind = OO_Slash; 895 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 896 op_kind = OO_SlashEqual; 897 break; 898 899 case '%': 900 if (post_op_name[1] == '\0') 901 op_kind = OO_Percent; 902 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 903 op_kind = OO_PercentEqual; 904 break; 905 906 907 case '^': 908 if (post_op_name[1] == '\0') 909 op_kind = OO_Caret; 910 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 911 op_kind = OO_CaretEqual; 912 break; 913 914 case '&': 915 if (post_op_name[1] == '\0') 916 op_kind = OO_Amp; 917 else if (post_op_name[2] == '\0') 918 { 919 switch (post_op_name[1]) 920 { 921 case '=': op_kind = OO_AmpEqual; break; 922 case '&': op_kind = OO_AmpAmp; break; 923 } 924 } 925 break; 926 927 case '|': 928 if (post_op_name[1] == '\0') 929 op_kind = OO_Pipe; 930 else if (post_op_name[2] == '\0') 931 { 932 switch (post_op_name[1]) 933 { 934 case '=': op_kind = OO_PipeEqual; break; 935 case '|': op_kind = OO_PipePipe; break; 936 } 937 } 938 break; 939 940 case '~': 941 if (post_op_name[1] == '\0') 942 op_kind = OO_Tilde; 943 break; 944 945 case '!': 946 if (post_op_name[1] == '\0') 947 op_kind = OO_Exclaim; 948 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 949 op_kind = OO_ExclaimEqual; 950 break; 951 952 case '=': 953 if (post_op_name[1] == '\0') 954 op_kind = OO_Equal; 955 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 956 op_kind = OO_EqualEqual; 957 break; 958 959 case '<': 960 if (post_op_name[1] == '\0') 961 op_kind = OO_Less; 962 else if (post_op_name[2] == '\0') 963 { 964 switch (post_op_name[1]) 965 { 966 case '<': op_kind = OO_LessLess; break; 967 case '=': op_kind = OO_LessEqual; break; 968 } 969 } 970 else if (post_op_name[3] == '\0') 971 { 972 if (post_op_name[2] == '=') 973 op_kind = OO_LessLessEqual; 974 } 975 break; 976 977 case '>': 978 if (post_op_name[1] == '\0') 979 op_kind = OO_Greater; 980 else if (post_op_name[2] == '\0') 981 { 982 switch (post_op_name[1]) 983 { 984 case '>': op_kind = OO_GreaterGreater; break; 985 case '=': op_kind = OO_GreaterEqual; break; 986 } 987 } 988 else if (post_op_name[1] == '>' && 989 post_op_name[2] == '=' && 990 post_op_name[3] == '\0') 991 { 992 op_kind = OO_GreaterGreaterEqual; 993 } 994 break; 995 996 case ',': 997 if (post_op_name[1] == '\0') 998 op_kind = OO_Comma; 999 break; 1000 1001 case '(': 1002 if (post_op_name[1] == ')' && post_op_name[2] == '\0') 1003 op_kind = OO_Call; 1004 break; 1005 1006 case '[': 1007 if (post_op_name[1] == ']' && post_op_name[2] == '\0') 1008 op_kind = OO_Subscript; 1009 break; 1010 } 1011 1012 return true; 1013} 1014CXXMethodDecl * 1015ClangASTContext::AddMethodToCXXRecordType 1016( 1017 ASTContext *ast_context, 1018 clang_type_t record_opaque_type, 1019 const char *name, 1020 clang_type_t method_opaque_type, 1021 lldb::AccessType access, 1022 bool is_virtual, 1023 bool is_static, 1024 bool is_inline, 1025 bool is_explicit 1026) 1027{ 1028 if (!record_opaque_type || !method_opaque_type || !name) 1029 return NULL; 1030 1031 assert(ast_context); 1032 1033 IdentifierTable *identifier_table = &ast_context->Idents; 1034 1035 assert(identifier_table); 1036 1037 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type)); 1038 1039 clang::Type *clang_type(record_qual_type.getTypePtr()); 1040 1041 if (clang_type == NULL) 1042 return NULL; 1043 1044 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type)); 1045 1046 if (record_clang_type == NULL) 1047 return NULL; 1048 1049 RecordDecl *record_decl = record_clang_type->getDecl(); 1050 1051 if (record_decl == NULL) 1052 return NULL; 1053 1054 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1055 1056 if (cxx_record_decl == NULL) 1057 return NULL; 1058 1059 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); 1060 1061 CXXMethodDecl *cxx_method_decl = NULL; 1062 1063 DeclarationName decl_name (&identifier_table->get(name)); 1064 1065 const bool is_implicitly_declared = false; 1066 1067 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr()); 1068 1069 if (function_Type == NULL) 1070 return NULL; 1071 1072 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type)); 1073 1074 if (!method_function_prototype) 1075 return NULL; 1076 1077 unsigned int num_params = method_function_prototype->getNumArgs(); 1078 1079 if (name[0] == '~') 1080 { 1081 cxx_method_decl = CXXDestructorDecl::Create (*ast_context, 1082 cxx_record_decl, 1083 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()), 1084 method_qual_type, 1085 NULL, 1086 is_inline, 1087 is_implicitly_declared); 1088 } 1089 else if (decl_name == record_decl->getDeclName()) 1090 { 1091 cxx_method_decl = CXXConstructorDecl::Create (*ast_context, 1092 cxx_record_decl, 1093 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()), 1094 method_qual_type, 1095 NULL, // TypeSourceInfo * 1096 is_explicit, 1097 is_inline, 1098 is_implicitly_declared); 1099 } 1100 else 1101 { 1102 1103 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS; 1104 if (IsOperator (name, op_kind)) 1105 { 1106 if (op_kind != NUM_OVERLOADED_OPERATORS) 1107 { 1108 cxx_method_decl = CXXMethodDecl::Create (*ast_context, 1109 cxx_record_decl, 1110 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()), 1111 method_qual_type, 1112 NULL, // TypeSourceInfo * 1113 is_static, 1114 SC_None, 1115 is_inline); 1116 } 1117 else if (num_params == 0) 1118 { 1119 // Conversion operators don't take params... 1120 cxx_method_decl = CXXConversionDecl::Create (*ast_context, 1121 cxx_record_decl, 1122 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()), 1123 method_qual_type, 1124 NULL, // TypeSourceInfo * 1125 is_inline, 1126 is_explicit); 1127 } 1128 } 1129 1130 if (cxx_method_decl == NULL) 1131 { 1132 cxx_method_decl = CXXMethodDecl::Create (*ast_context, 1133 cxx_record_decl, 1134 DeclarationNameInfo (decl_name, SourceLocation()), 1135 method_qual_type, 1136 NULL, // TypeSourceInfo * 1137 is_static, 1138 SC_None, 1139 is_inline); 1140 } 1141 } 1142 1143 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access); 1144 1145 cxx_method_decl->setAccess (access_specifier); 1146 cxx_method_decl->setVirtualAsWritten (is_virtual); 1147 1148 // Populate the method decl with parameter decls 1149 1150 ParmVarDecl *params[num_params]; 1151 1152 for (int param_index = 0; 1153 param_index < num_params; 1154 ++param_index) 1155 { 1156 params[param_index] = ParmVarDecl::Create (*ast_context, 1157 cxx_method_decl, 1158 SourceLocation(), 1159 NULL, // anonymous 1160 method_function_prototype->getArgType(param_index), 1161 NULL, 1162 SC_None, 1163 SC_None, 1164 NULL); 1165 } 1166 1167 cxx_method_decl->setParams (params, num_params); 1168 1169 cxx_record_decl->addDecl (cxx_method_decl); 1170 1171 return cxx_method_decl; 1172} 1173 1174bool 1175ClangASTContext::AddFieldToRecordType 1176( 1177 ASTContext *ast_context, 1178 clang_type_t record_clang_type, 1179 const char *name, 1180 clang_type_t field_type, 1181 AccessType access, 1182 uint32_t bitfield_bit_size 1183) 1184{ 1185 if (record_clang_type == NULL || field_type == NULL) 1186 return false; 1187 1188 IdentifierTable *identifier_table = &ast_context->Idents; 1189 1190 assert (ast_context != NULL); 1191 assert (identifier_table != NULL); 1192 1193 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type)); 1194 1195 clang::Type *clang_type = record_qual_type.getTypePtr(); 1196 if (clang_type) 1197 { 1198 const RecordType *record_type = dyn_cast<RecordType>(clang_type); 1199 1200 if (record_type) 1201 { 1202 RecordDecl *record_decl = record_type->getDecl(); 1203 1204 clang::Expr *bit_width = NULL; 1205 if (bitfield_bit_size != 0) 1206 { 1207 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size); 1208 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation()); 1209 } 1210 FieldDecl *field = FieldDecl::Create (*ast_context, 1211 record_decl, 1212 SourceLocation(), 1213 name ? &identifier_table->get(name) : NULL, // Identifier 1214 QualType::getFromOpaquePtr(field_type), // Field type 1215 NULL, // DeclaratorInfo * 1216 bit_width, // BitWidth 1217 false); // Mutable 1218 1219 field->setAccess (ConvertAccessTypeToAccessSpecifier (access)); 1220 1221 if (field) 1222 { 1223 record_decl->addDecl(field); 1224 } 1225 } 1226 else 1227 { 1228 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type); 1229 if (objc_class_type) 1230 { 1231 bool is_synthesized = false; 1232 ClangASTContext::AddObjCClassIVar (ast_context, 1233 record_clang_type, 1234 name, 1235 field_type, 1236 access, 1237 bitfield_bit_size, 1238 is_synthesized); 1239 } 1240 } 1241 } 1242 return false; 1243} 1244 1245bool 1246ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size) 1247{ 1248 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size); 1249} 1250 1251bool 1252ClangASTContext::FieldIsBitfield 1253( 1254 ASTContext *ast_context, 1255 FieldDecl* field, 1256 uint32_t& bitfield_bit_size 1257) 1258{ 1259 if (ast_context == NULL || field == NULL) 1260 return false; 1261 1262 if (field->isBitField()) 1263 { 1264 Expr* bit_width_expr = field->getBitWidth(); 1265 if (bit_width_expr) 1266 { 1267 llvm::APSInt bit_width_apsint; 1268 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context)) 1269 { 1270 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX); 1271 return true; 1272 } 1273 } 1274 } 1275 return false; 1276} 1277 1278bool 1279ClangASTContext::RecordHasFields (const RecordDecl *record_decl) 1280{ 1281 if (record_decl == NULL) 1282 return false; 1283 1284 if (!record_decl->field_empty()) 1285 return true; 1286 1287 // No fields, lets check this is a CXX record and check the base classes 1288 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1289 if (cxx_record_decl) 1290 { 1291 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1292 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1293 base_class != base_class_end; 1294 ++base_class) 1295 { 1296 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1297 if (RecordHasFields(base_class_decl)) 1298 return true; 1299 } 1300 } 1301 return false; 1302} 1303 1304void 1305ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities) 1306{ 1307 if (clang_qual_type) 1308 { 1309 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type)); 1310 clang::Type *clang_type = qual_type.getTypePtr(); 1311 if (clang_type) 1312 { 1313 RecordType *record_type = dyn_cast<RecordType>(clang_type); 1314 if (record_type) 1315 { 1316 RecordDecl *record_decl = record_type->getDecl(); 1317 if (record_decl) 1318 { 1319 uint32_t field_idx; 1320 RecordDecl::field_iterator field, field_end; 1321 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0; 1322 field != field_end; 1323 ++field, ++field_idx) 1324 { 1325 // If no accessibility was assigned, assign the correct one 1326 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none) 1327 field->setAccess ((AccessSpecifier)default_accessibility); 1328 } 1329 } 1330 } 1331 } 1332 } 1333} 1334 1335#pragma mark C++ Base Classes 1336 1337CXXBaseSpecifier * 1338ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class) 1339{ 1340 if (base_class_type) 1341 return new CXXBaseSpecifier (SourceRange(), 1342 is_virtual, 1343 base_of_class, 1344 ConvertAccessTypeToAccessSpecifier (access), 1345 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type))); 1346 return NULL; 1347} 1348 1349void 1350ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes) 1351{ 1352 for (unsigned i=0; i<num_base_classes; ++i) 1353 { 1354 delete base_classes[i]; 1355 base_classes[i] = NULL; 1356 } 1357} 1358 1359bool 1360ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes) 1361{ 1362 if (class_clang_type) 1363 { 1364 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr(); 1365 if (clang_type) 1366 { 1367 RecordType *record_type = dyn_cast<RecordType>(clang_type); 1368 if (record_type) 1369 { 1370 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl()); 1371 if (cxx_record_decl) 1372 { 1373 cxx_record_decl->setBases(base_classes, num_base_classes); 1374 return true; 1375 } 1376 } 1377 } 1378 } 1379 return false; 1380} 1381#pragma mark Objective C Classes 1382 1383clang_type_t 1384ClangASTContext::CreateObjCClass 1385( 1386 const char *name, 1387 DeclContext *decl_ctx, 1388 bool isForwardDecl, 1389 bool isInternal 1390) 1391{ 1392 ASTContext *ast_context = getASTContext(); 1393 assert (ast_context != NULL); 1394 assert (name && name[0]); 1395 if (decl_ctx == NULL) 1396 decl_ctx = ast_context->getTranslationUnitDecl(); 1397 1398 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and 1399 // we will need to update this code. I was told to currently always use 1400 // the CXXRecordDecl class since we often don't know from debug information 1401 // if something is struct or a class, so we default to always use the more 1402 // complete definition just in case. 1403 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context, 1404 decl_ctx, 1405 SourceLocation(), 1406 &ast_context->Idents.get(name), 1407 SourceLocation(), 1408 isForwardDecl, 1409 isInternal); 1410 1411 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr(); 1412} 1413 1414bool 1415ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type) 1416{ 1417 if (class_opaque_type && super_opaque_type) 1418 { 1419 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1420 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type)); 1421 clang::Type *class_type = class_qual_type.getTypePtr(); 1422 clang::Type *super_type = super_qual_type.getTypePtr(); 1423 if (class_type && super_type) 1424 { 1425 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1426 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type); 1427 if (objc_class_type && objc_super_type) 1428 { 1429 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1430 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface(); 1431 if (class_interface_decl && super_interface_decl) 1432 { 1433 class_interface_decl->setSuperClass(super_interface_decl); 1434 return true; 1435 } 1436 } 1437 } 1438 } 1439 return false; 1440} 1441 1442 1443bool 1444ClangASTContext::AddObjCClassIVar 1445( 1446 ASTContext *ast_context, 1447 clang_type_t class_opaque_type, 1448 const char *name, 1449 clang_type_t ivar_opaque_type, 1450 AccessType access, 1451 uint32_t bitfield_bit_size, 1452 bool is_synthesized 1453) 1454{ 1455 if (class_opaque_type == NULL || ivar_opaque_type == NULL) 1456 return false; 1457 1458 IdentifierTable *identifier_table = &ast_context->Idents; 1459 1460 assert (ast_context != NULL); 1461 assert (identifier_table != NULL); 1462 1463 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1464 1465 clang::Type *class_type = class_qual_type.getTypePtr(); 1466 if (class_type) 1467 { 1468 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1469 1470 if (objc_class_type) 1471 { 1472 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1473 1474 if (class_interface_decl) 1475 { 1476 clang::Expr *bit_width = NULL; 1477 if (bitfield_bit_size != 0) 1478 { 1479 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size); 1480 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation()); 1481 } 1482 1483 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context, 1484 class_interface_decl, 1485 SourceLocation(), 1486 &identifier_table->get(name), // Identifier 1487 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type 1488 NULL, // TypeSourceInfo * 1489 ConvertAccessTypeToObjCIvarAccessControl (access), 1490 bit_width, 1491 is_synthesized); 1492 1493 if (field) 1494 { 1495 class_interface_decl->addDecl(field); 1496 return true; 1497 } 1498 } 1499 } 1500 } 1501 return false; 1502} 1503 1504 1505bool 1506ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass) 1507{ 1508 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1509 1510 clang::Type *class_type = class_qual_type.getTypePtr(); 1511 if (class_type) 1512 { 1513 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1514 1515 if (objc_class_type) 1516 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass); 1517 } 1518 return false; 1519} 1520 1521bool 1522ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass) 1523{ 1524 while (class_interface_decl) 1525 { 1526 if (class_interface_decl->ivar_size() > 0) 1527 return true; 1528 1529 if (check_superclass) 1530 class_interface_decl = class_interface_decl->getSuperClass(); 1531 else 1532 break; 1533 } 1534 return false; 1535} 1536 1537ObjCMethodDecl * 1538ClangASTContext::AddMethodToObjCObjectType 1539( 1540 ASTContext *ast_context, 1541 clang_type_t class_opaque_type, 1542 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") 1543 clang_type_t method_opaque_type, 1544 lldb::AccessType access 1545) 1546{ 1547 if (class_opaque_type == NULL || method_opaque_type == NULL) 1548 return NULL; 1549 1550 IdentifierTable *identifier_table = &ast_context->Idents; 1551 1552 assert (ast_context != NULL); 1553 assert (identifier_table != NULL); 1554 1555 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1556 1557 clang::Type *class_type = class_qual_type.getTypePtr(); 1558 if (class_type == NULL) 1559 return NULL; 1560 1561 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1562 1563 if (objc_class_type == NULL) 1564 return NULL; 1565 1566 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1567 1568 if (class_interface_decl == NULL) 1569 return NULL; 1570 1571 const char *selector_start = ::strchr (name, ' '); 1572 if (selector_start == NULL) 1573 return NULL; 1574 1575 selector_start++; 1576 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_')) 1577 return NULL; 1578 llvm::SmallVector<IdentifierInfo *, 12> selector_idents; 1579 1580 size_t len = 0; 1581 const char *start; 1582 //printf ("name = '%s'\n", name); 1583 1584 unsigned num_selectors_with_args = 0; 1585 for (start = selector_start; 1586 start && *start != '\0' && *start != ']'; 1587 start += len) 1588 { 1589 len = ::strcspn(start, ":]"); 1590 bool has_arg = (start[len] == ':'); 1591 if (has_arg) 1592 ++num_selectors_with_args; 1593 selector_idents.push_back (&identifier_table->get (StringRef (start, len))); 1594 if (has_arg) 1595 len += 1; 1596 } 1597 1598 1599 if (selector_idents.size() == 0) 1600 return 0; 1601 1602 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, 1603 selector_idents.data()); 1604 1605 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); 1606 1607 // Populate the method decl with parameter decls 1608 clang::Type *method_type(method_qual_type.getTypePtr()); 1609 1610 if (method_type == NULL) 1611 return NULL; 1612 1613 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type)); 1614 1615 if (!method_function_prototype) 1616 return NULL; 1617 1618 1619 bool is_variadic = false; 1620 bool is_synthesized = false; 1621 bool is_defined = false; 1622 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None; 1623 1624 const unsigned num_args = method_function_prototype->getNumArgs(); 1625 1626 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context, 1627 SourceLocation(), // beginLoc, 1628 SourceLocation(), // endLoc, 1629 method_selector, 1630 method_function_prototype->getResultType(), 1631 NULL, // TypeSourceInfo *ResultTInfo, 1632 GetDeclContextForType (class_opaque_type), 1633 name[0] == '-', 1634 is_variadic, 1635 is_synthesized, 1636 is_defined, 1637 imp_control, 1638 num_args); 1639 1640 1641 if (objc_method_decl == NULL) 1642 return NULL; 1643 1644 if (num_args > 0) 1645 { 1646 llvm::SmallVector<ParmVarDecl *, 12> params; 1647 1648 for (int param_index = 0; param_index < num_args; ++param_index) 1649 { 1650 params.push_back (ParmVarDecl::Create (*ast_context, 1651 objc_method_decl, 1652 SourceLocation(), 1653 NULL, // anonymous 1654 method_function_prototype->getArgType(param_index), 1655 NULL, 1656 SC_Auto, 1657 SC_Auto, 1658 NULL)); 1659 } 1660 1661 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args); 1662 } 1663 1664 class_interface_decl->addDecl (objc_method_decl); 1665 1666 1667 return objc_method_decl; 1668} 1669 1670 1671uint32_t 1672ClangASTContext::GetTypeInfo 1673( 1674 clang_type_t clang_type, 1675 clang::ASTContext *ast_context, 1676 clang_type_t *pointee_or_element_clang_type 1677) 1678{ 1679 if (clang_type == NULL) 1680 return 0; 1681 1682 if (pointee_or_element_clang_type) 1683 *pointee_or_element_clang_type = NULL; 1684 1685 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 1686 1687 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 1688 switch (type_class) 1689 { 1690 case clang::Type::Builtin: 1691 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 1692 { 1693 case clang::BuiltinType::ObjCId: 1694 case clang::BuiltinType::ObjCClass: 1695 if (ast_context && pointee_or_element_clang_type) 1696 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr(); 1697 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue; 1698 1699 default: 1700 break; 1701 } 1702 return eTypeIsBuiltIn | eTypeHasValue; 1703 1704 case clang::Type::BlockPointer: 1705 if (pointee_or_element_clang_type) 1706 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); 1707 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock; 1708 1709 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue; 1710 1711 case clang::Type::ConstantArray: 1712 case clang::Type::DependentSizedArray: 1713 case clang::Type::IncompleteArray: 1714 case clang::Type::VariableArray: 1715 if (pointee_or_element_clang_type) 1716 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr(); 1717 return eTypeHasChildren | eTypeIsArray; 1718 1719 case clang::Type::DependentName: return 0; 1720 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector; 1721 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate; 1722 case clang::Type::Decltype: return 0; 1723 1724 case clang::Type::Enum: 1725 if (pointee_or_element_clang_type) 1726 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr(); 1727 return eTypeIsEnumeration | eTypeHasValue; 1728 1729 case clang::Type::Elaborated: return 0; 1730 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector; 1731 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue; 1732 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue; 1733 case clang::Type::InjectedClassName: return 0; 1734 1735 case clang::Type::LValueReference: 1736 case clang::Type::RValueReference: 1737 if (pointee_or_element_clang_type) 1738 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(); 1739 return eTypeHasChildren | eTypeIsReference | eTypeHasValue; 1740 1741 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue; 1742 1743 case clang::Type::ObjCObjectPointer: 1744 if (pointee_or_element_clang_type) 1745 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); 1746 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue; 1747 1748 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; 1749 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; 1750 1751 case clang::Type::Pointer: 1752 if (pointee_or_element_clang_type) 1753 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); 1754 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue; 1755 1756 case clang::Type::Record: 1757 if (qual_type->getAsCXXRecordDecl()) 1758 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus; 1759 else 1760 return eTypeHasChildren | eTypeIsStructUnion; 1761 break; 1762 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate; 1763 case clang::Type::TemplateTypeParm: return eTypeIsTemplate; 1764 case clang::Type::TemplateSpecialization: return eTypeIsTemplate; 1765 1766 case clang::Type::Typedef: 1767 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 1768 ast_context, 1769 pointee_or_element_clang_type); 1770 1771 case clang::Type::TypeOfExpr: return 0; 1772 case clang::Type::TypeOf: return 0; 1773 case clang::Type::UnresolvedUsing: return 0; 1774 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector; 1775 default: return 0; 1776 } 1777 return 0; 1778} 1779 1780 1781#pragma mark Aggregate Types 1782 1783bool 1784ClangASTContext::IsAggregateType (clang_type_t clang_type) 1785{ 1786 if (clang_type == NULL) 1787 return false; 1788 1789 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 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