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