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