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