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