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