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