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