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