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