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