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