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