ClangASTContext.cpp revision 412440aa3a110e4068ee99729f7883c828fb3dce
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 SourceLocation(), 852 DeclarationName(&identifier_table->get(name)), 853 method_qual_type, 854 NULL); 855 856 cxx_method_decl->setAccess (ConvertAccessTypeToAccessSpecifier (access)); 857 cxx_method_decl->setVirtualAsWritten (is_virtual); 858 859 // Populate the method decl with parameter decls 860 clang::Type *method_type(method_qual_type.getTypePtr()); 861 862 if (!method_type) 863 return NULL; 864 865 FunctionProtoType *method_funprototy(dyn_cast<FunctionProtoType>(method_type)); 866 867 if (!method_funprototy) 868 return NULL; 869 870 unsigned int num_params = method_funprototy->getNumArgs(); 871 872 ParmVarDecl *params[num_params]; 873 874 for (int param_index = 0; 875 param_index < num_params; 876 ++param_index) 877 { 878 params[param_index] = ParmVarDecl::Create(*ast_context, 879 cxx_method_decl, 880 SourceLocation(), 881 NULL, // anonymous 882 method_funprototy->getArgType(param_index), 883 NULL, 884 VarDecl::Auto, 885 VarDecl::Auto, 886 NULL); 887 } 888 889 cxx_method_decl->setParams(params, num_params); 890 891 cxx_record_decl->addDecl(cxx_method_decl); 892 893 return cxx_method_decl; 894} 895 896bool 897ClangASTContext::AddFieldToRecordType 898( 899 clang::ASTContext *ast_context, 900 void *record_clang_type, 901 const char *name, 902 void *field_type, 903 AccessType access, 904 uint32_t bitfield_bit_size 905) 906{ 907 if (record_clang_type == NULL || field_type == NULL) 908 return false; 909 910 IdentifierTable *identifier_table = &ast_context->Idents; 911 912 assert (ast_context != NULL); 913 assert (identifier_table != NULL); 914 915 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type)); 916 917 clang::Type *clang_type = record_qual_type.getTypePtr(); 918 if (clang_type) 919 { 920 const RecordType *record_type = dyn_cast<RecordType>(clang_type); 921 922 if (record_type) 923 { 924 RecordDecl *record_decl = record_type->getDecl(); 925 926 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 927 if (cxx_record_decl) 928 { 929 // NOTE: we currently have some fixes that should be placed 930 // into clang that will automatically set if a record is empty 931 // when each field is added (during the addDecl() method call 932 // below) so this code should be able to come out when those 933 // changes make it into llvm/clang, then we can remove this 934 // code... 935 // Currently SEMA is using the accessors manually to set 936 // whether a class is empty, is POD, is aggregate, and more. 937 // This code will be moved into CXXRecordDecl so everyone 938 // can benefit. 939 // This will currently work for everything except zero sized 940 // bitfields which we currently aren't detecting anyway from the 941 // DWARF so it should be ok for now. 942 cxx_record_decl->setEmpty (false); 943 } 944 945 clang::Expr *bit_width = NULL; 946 if (bitfield_bit_size != 0) 947 { 948 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size); 949 bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation()); 950 } 951 FieldDecl *field = FieldDecl::Create (*ast_context, 952 record_decl, 953 SourceLocation(), 954 name ? &identifier_table->get(name) : NULL, // Identifier 955 QualType::getFromOpaquePtr(field_type), // Field type 956 NULL, // DeclaratorInfo * 957 bit_width, // BitWidth 958 false); // Mutable 959 960 field->setAccess (ConvertAccessTypeToAccessSpecifier (access)); 961 962 if (field) 963 { 964 record_decl->addDecl(field); 965 966 // NOTE: we currently have some fixes that should be placed 967 // into clang that will automatically set if a record is POD 968 // when each field is added (during the addDecl() method call 969 // above) so this code should be able to come out when those 970 // changes make it into llvm/clang, then we can remove this 971 // code... 972 // Currently SEMA is using the accessors manually to set 973 // whether a class is empty, is POD, is aggregate, and more. 974 // This code will be moved into CXXRecordDecl so everyone 975 // can benefit. 976 977 if (cxx_record_decl->isPOD()) 978 { 979 if (!field->getType()->isPODType()) 980 cxx_record_decl->setPOD (false); 981 return true; 982 } 983 } 984 } 985 else 986 { 987 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type); 988 if (objc_class_type) 989 { 990 bool isSynthesized = false; 991 ClangASTContext::AddObjCClassIVar (ast_context, 992 record_clang_type, 993 name, 994 field_type, 995 access, 996 bitfield_bit_size, 997 isSynthesized); 998 } 999 } 1000 } 1001 return false; 1002} 1003 1004bool 1005ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size) 1006{ 1007 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size); 1008} 1009 1010bool 1011ClangASTContext::FieldIsBitfield 1012( 1013 ASTContext *ast_context, 1014 FieldDecl* field, 1015 uint32_t& bitfield_bit_size 1016) 1017{ 1018 if (ast_context == NULL || field == NULL) 1019 return false; 1020 1021 if (field->isBitField()) 1022 { 1023 Expr* bit_width_expr = field->getBitWidth(); 1024 if (bit_width_expr) 1025 { 1026 llvm::APSInt bit_width_apsint; 1027 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context)) 1028 { 1029 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX); 1030 return true; 1031 } 1032 } 1033 } 1034 return false; 1035} 1036 1037bool 1038ClangASTContext::RecordHasFields (const RecordDecl *record_decl) 1039{ 1040 if (record_decl == NULL) 1041 return false; 1042 1043 if (!record_decl->field_empty()) 1044 return true; 1045 1046 // No fields, lets check this is a CXX record and check the base classes 1047 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1048 if (cxx_record_decl) 1049 { 1050 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1051 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1052 base_class != base_class_end; 1053 ++base_class) 1054 { 1055 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1056 if (RecordHasFields(base_class_decl)) 1057 return true; 1058 } 1059 } 1060 return false; 1061} 1062 1063void 1064ClangASTContext::SetDefaultAccessForRecordFields (void *clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities) 1065{ 1066 if (clang_qual_type) 1067 { 1068 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type)); 1069 clang::Type *clang_type = qual_type.getTypePtr(); 1070 if (clang_type) 1071 { 1072 RecordType *record_type = dyn_cast<RecordType>(clang_type); 1073 if (record_type) 1074 { 1075 RecordDecl *record_decl = record_type->getDecl(); 1076 if (record_decl) 1077 { 1078 uint32_t field_idx; 1079 RecordDecl::field_iterator field, field_end; 1080 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0; 1081 field != field_end; 1082 ++field, ++field_idx) 1083 { 1084 // If no accessibility was assigned, assign the correct one 1085 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none) 1086 field->setAccess ((AccessSpecifier)default_accessibility); 1087 } 1088 } 1089 } 1090 } 1091 } 1092} 1093 1094#pragma mark C++ Base Classes 1095 1096CXXBaseSpecifier * 1097ClangASTContext::CreateBaseClassSpecifier (void *base_class_type, AccessType access, bool is_virtual, bool base_of_class) 1098{ 1099 if (base_class_type) 1100 return new CXXBaseSpecifier (SourceRange(), 1101 is_virtual, 1102 base_of_class, 1103 ConvertAccessTypeToAccessSpecifier (access), 1104 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type))); 1105 return NULL; 1106} 1107 1108void 1109ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes) 1110{ 1111 for (unsigned i=0; i<num_base_classes; ++i) 1112 { 1113 delete base_classes[i]; 1114 base_classes[i] = NULL; 1115 } 1116} 1117 1118bool 1119ClangASTContext::SetBaseClassesForClassType (void *class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes) 1120{ 1121 if (class_clang_type) 1122 { 1123 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr(); 1124 if (clang_type) 1125 { 1126 RecordType *record_type = dyn_cast<RecordType>(clang_type); 1127 if (record_type) 1128 { 1129 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl()); 1130 if (cxx_record_decl) 1131 { 1132 cxx_record_decl->setBases(base_classes, num_base_classes); 1133 1134 // NOTE: we currently have some fixes that should be placed 1135 // into clang that will automatically set these things when 1136 // they are added (during the setBases() method call above) 1137 // so this code should be able to come out when those changes 1138 // make it into llvm/clang, then we can remove this code... 1139 // Currently SEMA is using the accessors manually to set 1140 // whether a class is empty, is POD, is aggregate, and more. 1141 // This code will be moved into CXXRecordDecl so everyone 1142 // can benefit. 1143 if (cxx_record_decl->isEmpty() || cxx_record_decl->isPOD()) 1144 { 1145 // set empty to false if any bases are virtual, or not empty. 1146 1147 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1148 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1149 base_class != base_class_end; 1150 ++base_class) 1151 { 1152 if (base_class->isVirtual()) 1153 { 1154 cxx_record_decl->setEmpty (false); 1155 cxx_record_decl->setPOD (false); 1156 break; 1157 } 1158 else 1159 { 1160 QualType base_type (base_class->getType()); 1161 1162 if (!base_type->isPODType()) 1163 cxx_record_decl->setPOD (false); 1164 1165 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_type->getAs<RecordType>()->getDecl()); 1166 if (!base_class_decl->isEmpty()) 1167 { 1168 cxx_record_decl->setEmpty (false); 1169 break; 1170 } 1171 } 1172 } 1173 } 1174 return true; 1175 } 1176 } 1177 } 1178 } 1179 return false; 1180} 1181#pragma mark Objective C Classes 1182 1183void * 1184ClangASTContext::CreateObjCClass 1185( 1186 const char *name, 1187 DeclContext *decl_ctx, 1188 bool isForwardDecl, 1189 bool isInternal 1190) 1191{ 1192 ASTContext *ast_context = getASTContext(); 1193 assert (ast_context != NULL); 1194 assert (name && name[0]); 1195 if (decl_ctx == NULL) 1196 decl_ctx = ast_context->getTranslationUnitDecl(); 1197 1198 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and 1199 // we will need to update this code. I was told to currently always use 1200 // the CXXRecordDecl class since we often don't know from debug information 1201 // if something is struct or a class, so we default to always use the more 1202 // complete definition just in case. 1203 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context, 1204 decl_ctx, 1205 SourceLocation(), 1206 &ast_context->Idents.get(name), 1207 SourceLocation(), 1208 isForwardDecl, 1209 isInternal); 1210 1211 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr(); 1212} 1213 1214bool 1215ClangASTContext::SetObjCSuperClass (void *class_opaque_type, void *super_opaque_type) 1216{ 1217 if (class_opaque_type && super_opaque_type) 1218 { 1219 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1220 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type)); 1221 clang::Type *class_type = class_qual_type.getTypePtr(); 1222 clang::Type *super_type = super_qual_type.getTypePtr(); 1223 if (class_type && super_type) 1224 { 1225 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1226 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type); 1227 if (objc_class_type && objc_super_type) 1228 { 1229 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1230 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface(); 1231 if (class_interface_decl && super_interface_decl) 1232 { 1233 class_interface_decl->setSuperClass(super_interface_decl); 1234 return true; 1235 } 1236 } 1237 } 1238 } 1239 return false; 1240} 1241 1242 1243bool 1244ClangASTContext::AddObjCClassIVar 1245( 1246 clang::ASTContext *ast_context, 1247 void *class_opaque_type, 1248 const char *name, 1249 void *ivar_opaque_type, 1250 AccessType access, 1251 uint32_t bitfield_bit_size, 1252 bool isSynthesized 1253) 1254{ 1255 if (class_opaque_type == NULL || ivar_opaque_type == NULL) 1256 return false; 1257 1258 IdentifierTable *identifier_table = &ast_context->Idents; 1259 1260 assert (ast_context != NULL); 1261 assert (identifier_table != NULL); 1262 1263 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1264 1265 clang::Type *class_type = class_qual_type.getTypePtr(); 1266 if (class_type) 1267 { 1268 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1269 1270 if (objc_class_type) 1271 { 1272 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1273 1274 if (class_interface_decl) 1275 { 1276 clang::Expr *bit_width = NULL; 1277 if (bitfield_bit_size != 0) 1278 { 1279 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size); 1280 bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation()); 1281 } 1282 1283 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context, 1284 class_interface_decl, 1285 SourceLocation(), 1286 &identifier_table->get(name), // Identifier 1287 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type 1288 NULL, // TypeSourceInfo * 1289 ConvertAccessTypeToObjCIvarAccessControl (access), 1290 bit_width, 1291 isSynthesized); 1292 1293 if (field) 1294 { 1295 class_interface_decl->addDecl(field); 1296 return true; 1297 } 1298 } 1299 } 1300 } 1301 return false; 1302} 1303 1304 1305bool 1306ClangASTContext::ObjCTypeHasIVars (void *class_opaque_type, bool check_superclass) 1307{ 1308 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1309 1310 clang::Type *class_type = class_qual_type.getTypePtr(); 1311 if (class_type) 1312 { 1313 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1314 1315 if (objc_class_type) 1316 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass); 1317 } 1318 return false; 1319} 1320 1321bool 1322ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass) 1323{ 1324 while (class_interface_decl) 1325 { 1326 if (class_interface_decl->ivar_size() > 0) 1327 return true; 1328 1329 if (check_superclass) 1330 class_interface_decl = class_interface_decl->getSuperClass(); 1331 else 1332 break; 1333 } 1334 return false; 1335} 1336 1337 1338#pragma mark Aggregate Types 1339 1340bool 1341ClangASTContext::IsAggregateType (void *clang_type) 1342{ 1343 if (clang_type == NULL) 1344 return false; 1345 1346 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 1347 1348 if (qual_type->isAggregateType ()) 1349 return true; 1350 1351 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 1352 switch (type_class) 1353 { 1354 case clang::Type::IncompleteArray: 1355 case clang::Type::VariableArray: 1356 case clang::Type::ConstantArray: 1357 case clang::Type::ExtVector: 1358 case clang::Type::Vector: 1359 case clang::Type::Record: 1360 case clang::Type::ObjCObject: 1361 case clang::Type::ObjCInterface: 1362 return true; 1363 1364 case clang::Type::Typedef: 1365 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 1366 1367 default: 1368 break; 1369 } 1370 // The clang type does have a value 1371 return false; 1372} 1373 1374uint32_t 1375ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_classes) 1376{ 1377 if (clang_qual_type == NULL) 1378 return 0; 1379 1380 uint32_t num_children = 0; 1381 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type)); 1382 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 1383 switch (type_class) 1384 { 1385 case clang::Type::Builtin: 1386 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 1387 { 1388 case clang::BuiltinType::ObjCId: // Child is Class 1389 case clang::BuiltinType::ObjCClass: // child is Class 1390 case clang::BuiltinType::ObjCSel: // child is const char * 1391 num_children = 1; 1392 1393 default: 1394 break; 1395 } 1396 break; 1397 1398 case clang::Type::Record: 1399 { 1400 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 1401 const RecordDecl *record_decl = record_type->getDecl(); 1402 assert(record_decl); 1403 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1404 if (cxx_record_decl) 1405 { 1406 if (omit_empty_base_classes) 1407 { 1408 // Check each base classes to see if it or any of its 1409 // base classes contain any fields. This can help 1410 // limit the noise in variable views by not having to 1411 // show base classes that contain no members. 1412 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1413 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1414 base_class != base_class_end; 1415 ++base_class) 1416 { 1417 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1418 1419 // Skip empty base classes 1420 if (RecordHasFields(base_class_decl) == false) 1421 continue; 1422 1423 num_children++; 1424 } 1425 } 1426 else 1427 { 1428 // Include all base classes 1429 num_children += cxx_record_decl->getNumBases(); 1430 } 1431 1432 } 1433 RecordDecl::field_iterator field, field_end; 1434 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) 1435 ++num_children; 1436 } 1437 break; 1438 1439 case clang::Type::ObjCObject: 1440 case clang::Type::ObjCInterface: 1441 { 1442 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 1443 assert (objc_class_type); 1444 if (objc_class_type) 1445 { 1446 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1447 1448 if (class_interface_decl) 1449 { 1450 1451 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 1452 if (superclass_interface_decl) 1453 { 1454 if (omit_empty_base_classes) 1455 { 1456 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true)) 1457 ++num_children; 1458 } 1459 else 1460 ++num_children; 1461 } 1462 1463 num_children += class_interface_decl->ivar_size(); 1464 } 1465 } 1466 } 1467 break; 1468 1469 case clang::Type::ObjCObjectPointer: 1470 { 1471 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr()); 1472 QualType pointee_type = pointer_type->getPointeeType(); 1473 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), 1474 omit_empty_base_classes); 1475 // If this type points to a simple type, then it has 1 child 1476 if (num_pointee_children == 0) 1477 num_children = 1; 1478 else 1479 num_children = num_pointee_children; 1480 } 1481 break; 1482 1483 case clang::Type::ConstantArray: 1484 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); 1485 break; 1486 1487 case clang::Type::Pointer: 1488 { 1489 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 1490 QualType pointee_type = pointer_type->getPointeeType(); 1491 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), 1492 omit_empty_base_classes); 1493 // If this type points to a simple type, then it has 1 child 1494 if (num_pointee_children == 0) 1495 num_children = 1; 1496 else 1497 num_children = num_pointee_children; 1498 } 1499 break; 1500 1501 case clang::Type::Typedef: 1502 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes); 1503 break; 1504 1505 default: 1506 break; 1507 } 1508 return num_children; 1509} 1510 1511 1512void * 1513ClangASTContext::GetChildClangTypeAtIndex 1514( 1515 const char *parent_name, 1516 void *parent_clang_type, 1517 uint32_t idx, 1518 bool transparent_pointers, 1519 bool omit_empty_base_classes, 1520 std::string& child_name, 1521 uint32_t &child_byte_size, 1522 int32_t &child_byte_offset, 1523 uint32_t &child_bitfield_bit_size, 1524 uint32_t &child_bitfield_bit_offset 1525) 1526{ 1527 if (parent_clang_type) 1528 1529 return GetChildClangTypeAtIndex (getASTContext(), 1530 parent_name, 1531 parent_clang_type, 1532 idx, 1533 transparent_pointers, 1534 omit_empty_base_classes, 1535 child_name, 1536 child_byte_size, 1537 child_byte_offset, 1538 child_bitfield_bit_size, 1539 child_bitfield_bit_offset); 1540 return NULL; 1541} 1542 1543void * 1544ClangASTContext::GetChildClangTypeAtIndex 1545( 1546 ASTContext *ast_context, 1547 const char *parent_name, 1548 void *parent_clang_type, 1549 uint32_t idx, 1550 bool transparent_pointers, 1551 bool omit_empty_base_classes, 1552 std::string& child_name, 1553 uint32_t &child_byte_size, 1554 int32_t &child_byte_offset, 1555 uint32_t &child_bitfield_bit_size, 1556 uint32_t &child_bitfield_bit_offset 1557) 1558{ 1559 if (parent_clang_type == NULL) 1560 return NULL; 1561 1562 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes)) 1563 { 1564 uint32_t bit_offset; 1565 child_bitfield_bit_size = 0; 1566 child_bitfield_bit_offset = 0; 1567 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type)); 1568 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass(); 1569 switch (parent_type_class) 1570 { 1571 case clang::Type::Builtin: 1572 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind()) 1573 { 1574 case clang::BuiltinType::ObjCId: 1575 case clang::BuiltinType::ObjCClass: 1576 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr(); 1577 1578 case clang::BuiltinType::ObjCSel: 1579 { 1580 QualType char_type(ast_context->CharTy); 1581 char_type.addConst(); 1582 return ast_context->getPointerType(char_type).getAsOpaquePtr(); 1583 } 1584 break; 1585 1586 default: 1587 break; 1588 } 1589 break; 1590 1591 1592 case clang::Type::Record: 1593 { 1594 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr()); 1595 const RecordDecl *record_decl = record_type->getDecl(); 1596 assert(record_decl); 1597 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl); 1598 uint32_t child_idx = 0; 1599 1600 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1601 if (cxx_record_decl) 1602 { 1603 // We might have base classes to print out first 1604 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1605 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1606 base_class != base_class_end; 1607 ++base_class) 1608 { 1609 const CXXRecordDecl *base_class_decl = NULL; 1610 1611 // Skip empty base classes 1612 if (omit_empty_base_classes) 1613 { 1614 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1615 if (RecordHasFields(base_class_decl) == false) 1616 continue; 1617 } 1618 1619 if (idx == child_idx) 1620 { 1621 if (base_class_decl == NULL) 1622 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1623 1624 1625 if (base_class->isVirtual()) 1626 bit_offset = record_layout.getVBaseClassOffset(base_class_decl); 1627 else 1628 bit_offset = record_layout.getBaseClassOffset(base_class_decl); 1629 1630 // Base classes should be a multiple of 8 bits in size 1631 assert (bit_offset % 8 == 0); 1632 child_byte_offset = bit_offset/8; 1633 std::string base_class_type_name(base_class->getType().getAsString()); 1634 1635 child_name.assign(base_class_type_name.c_str()); 1636 1637 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType()); 1638 1639 // Base classes biut sizes should be a multiple of 8 bits in size 1640 assert (clang_type_info_bit_size % 8 == 0); 1641 child_byte_size = clang_type_info_bit_size / 8; 1642 return base_class->getType().getAsOpaquePtr(); 1643 } 1644 // We don't increment the child index in the for loop since we might 1645 // be skipping empty base classes 1646 ++child_idx; 1647 } 1648 } 1649 // Make sure index is in range... 1650 uint32_t field_idx = 0; 1651 RecordDecl::field_iterator field, field_end; 1652 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx) 1653 { 1654 if (idx == child_idx) 1655 { 1656 // Print the member type if requested 1657 // Print the member name and equal sign 1658 child_name.assign(field->getNameAsString().c_str()); 1659 1660 // Figure out the type byte size (field_type_info.first) and 1661 // alignment (field_type_info.second) from the AST context. 1662 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType()); 1663 assert(field_idx < record_layout.getFieldCount()); 1664 1665 child_byte_size = field_type_info.first / 8; 1666 1667 // Figure out the field offset within the current struct/union/class type 1668 bit_offset = record_layout.getFieldOffset (field_idx); 1669 child_byte_offset = bit_offset / 8; 1670 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size)) 1671 child_bitfield_bit_offset = bit_offset % 8; 1672 1673 return field->getType().getAsOpaquePtr(); 1674 } 1675 } 1676 } 1677 break; 1678 1679 case clang::Type::ObjCObject: 1680 case clang::Type::ObjCInterface: 1681 { 1682 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr()); 1683 assert (objc_class_type); 1684 if (objc_class_type) 1685 { 1686 uint32_t child_idx = 0; 1687 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1688 1689 if (class_interface_decl) 1690 { 1691 1692 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl); 1693 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 1694 if (superclass_interface_decl) 1695 { 1696 if (omit_empty_base_classes) 1697 { 1698 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0) 1699 { 1700 if (idx == 0) 1701 { 1702 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl)); 1703 1704 1705 child_name.assign(superclass_interface_decl->getNameAsString().c_str()); 1706 1707 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr()); 1708 1709 child_byte_size = ivar_type_info.first / 8; 1710 child_byte_offset = 0; 1711 1712 return ivar_qual_type.getAsOpaquePtr(); 1713 } 1714 1715 ++child_idx; 1716 } 1717 } 1718 else 1719 ++child_idx; 1720 } 1721 1722 const uint32_t superclass_idx = child_idx; 1723 1724 if (idx < (child_idx + class_interface_decl->ivar_size())) 1725 { 1726 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 1727 1728 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) 1729 { 1730 if (child_idx == idx) 1731 { 1732 const ObjCIvarDecl* ivar_decl = *ivar_pos; 1733 1734 QualType ivar_qual_type(ivar_decl->getType()); 1735 1736 child_name.assign(ivar_decl->getNameAsString().c_str()); 1737 1738 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr()); 1739 1740 child_byte_size = ivar_type_info.first / 8; 1741 1742 // Figure out the field offset within the current struct/union/class type 1743 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); 1744 child_byte_offset = bit_offset / 8; 1745 1746 return ivar_qual_type.getAsOpaquePtr(); 1747 } 1748 ++child_idx; 1749 } 1750 } 1751 } 1752 } 1753 } 1754 break; 1755 1756 case clang::Type::ObjCObjectPointer: 1757 { 1758 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr()); 1759 QualType pointee_type = pointer_type->getPointeeType(); 1760 1761 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 1762 { 1763 return GetChildClangTypeAtIndex (ast_context, 1764 parent_name, 1765 pointer_type->getPointeeType().getAsOpaquePtr(), 1766 idx, 1767 transparent_pointers, 1768 omit_empty_base_classes, 1769 child_name, 1770 child_byte_size, 1771 child_byte_offset, 1772 child_bitfield_bit_size, 1773 child_bitfield_bit_offset); 1774 } 1775 else 1776 { 1777 if (parent_name) 1778 { 1779 child_name.assign(1, '*'); 1780 child_name += parent_name; 1781 } 1782 1783 // We have a pointer to an simple type 1784 if (idx == 0) 1785 { 1786 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 1787 assert(clang_type_info.first % 8 == 0); 1788 child_byte_size = clang_type_info.first / 8; 1789 child_byte_offset = 0; 1790 return pointee_type.getAsOpaquePtr(); 1791 } 1792 } 1793 } 1794 break; 1795 1796 case clang::Type::ConstantArray: 1797 { 1798 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 1799 const uint64_t element_count = array->getSize().getLimitedValue(); 1800 1801 if (idx < element_count) 1802 { 1803 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType()); 1804 1805 char element_name[32]; 1806 ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); 1807 1808 child_name.assign(element_name); 1809 assert(field_type_info.first % 8 == 0); 1810 child_byte_size = field_type_info.first / 8; 1811 child_byte_offset = idx * child_byte_size; 1812 return array->getElementType().getAsOpaquePtr(); 1813 } 1814 } 1815 break; 1816 1817 case clang::Type::Pointer: 1818 { 1819 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr()); 1820 QualType pointee_type = pointer_type->getPointeeType(); 1821 1822 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 1823 { 1824 return GetChildClangTypeAtIndex (ast_context, 1825 parent_name, 1826 pointer_type->getPointeeType().getAsOpaquePtr(), 1827 idx, 1828 transparent_pointers, 1829 omit_empty_base_classes, 1830 child_name, 1831 child_byte_size, 1832 child_byte_offset, 1833 child_bitfield_bit_size, 1834 child_bitfield_bit_offset); 1835 } 1836 else 1837 { 1838 if (parent_name) 1839 { 1840 child_name.assign(1, '*'); 1841 child_name += parent_name; 1842 } 1843 1844 // We have a pointer to an simple type 1845 if (idx == 0) 1846 { 1847 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 1848 assert(clang_type_info.first % 8 == 0); 1849 child_byte_size = clang_type_info.first / 8; 1850 child_byte_offset = 0; 1851 return pointee_type.getAsOpaquePtr(); 1852 } 1853 } 1854 } 1855 break; 1856 1857 case clang::Type::Typedef: 1858 return GetChildClangTypeAtIndex (ast_context, 1859 parent_name, 1860 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 1861 idx, 1862 transparent_pointers, 1863 omit_empty_base_classes, 1864 child_name, 1865 child_byte_size, 1866 child_byte_offset, 1867 child_bitfield_bit_size, 1868 child_bitfield_bit_offset); 1869 break; 1870 1871 default: 1872 break; 1873 } 1874 } 1875 return NULL; 1876} 1877 1878static inline bool 1879BaseSpecifierIsEmpty (const CXXBaseSpecifier *b) 1880{ 1881 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false; 1882} 1883 1884static uint32_t 1885GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes) 1886{ 1887 uint32_t num_bases = 0; 1888 if (cxx_record_decl) 1889 { 1890 if (omit_empty_base_classes) 1891 { 1892 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1893 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1894 base_class != base_class_end; 1895 ++base_class) 1896 { 1897 // Skip empty base classes 1898 if (omit_empty_base_classes) 1899 { 1900 if (BaseSpecifierIsEmpty (base_class)) 1901 continue; 1902 } 1903 ++num_bases; 1904 } 1905 } 1906 else 1907 num_bases = cxx_record_decl->getNumBases(); 1908 } 1909 return num_bases; 1910} 1911 1912 1913static uint32_t 1914GetIndexForRecordBase 1915( 1916 const RecordDecl *record_decl, 1917 const CXXBaseSpecifier *base_spec, 1918 bool omit_empty_base_classes 1919) 1920{ 1921 uint32_t child_idx = 0; 1922 1923 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1924 1925// const char *super_name = record_decl->getNameAsCString(); 1926// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString(); 1927// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name); 1928// 1929 if (cxx_record_decl) 1930 { 1931 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1932 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1933 base_class != base_class_end; 1934 ++base_class) 1935 { 1936 if (omit_empty_base_classes) 1937 { 1938 if (BaseSpecifierIsEmpty (base_class)) 1939 continue; 1940 } 1941 1942// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name, 1943// child_idx, 1944// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); 1945// 1946// 1947 if (base_class == base_spec) 1948 return child_idx; 1949 ++child_idx; 1950 } 1951 } 1952 1953 return UINT32_MAX; 1954} 1955 1956 1957static uint32_t 1958GetIndexForRecordChild 1959( 1960 const RecordDecl *record_decl, 1961 NamedDecl *canonical_decl, 1962 bool omit_empty_base_classes 1963) 1964{ 1965 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes); 1966 1967// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1968// 1969//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString()); 1970// if (cxx_record_decl) 1971// { 1972// CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1973// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1974// base_class != base_class_end; 1975// ++base_class) 1976// { 1977// if (omit_empty_base_classes) 1978// { 1979// if (BaseSpecifierIsEmpty (base_class)) 1980// continue; 1981// } 1982// 1983//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", 1984//// record_decl->getNameAsCString(), 1985//// canonical_decl->getNameAsCString(), 1986//// child_idx, 1987//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); 1988// 1989// 1990// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1991// if (curr_base_class_decl == canonical_decl) 1992// { 1993// return child_idx; 1994// } 1995// ++child_idx; 1996// } 1997// } 1998// 1999// const uint32_t num_bases = child_idx; 2000 RecordDecl::field_iterator field, field_end; 2001 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 2002 field != field_end; 2003 ++field, ++child_idx) 2004 { 2005// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n", 2006// record_decl->getNameAsCString(), 2007// canonical_decl->getNameAsCString(), 2008// child_idx - num_bases, 2009// field->getNameAsCString()); 2010 2011 if (field->getCanonicalDecl() == canonical_decl) 2012 return child_idx; 2013 } 2014 2015 return UINT32_MAX; 2016} 2017 2018// Look for a child member (doesn't include base classes, but it does include 2019// their members) in the type hierarchy. Returns an index path into "clang_type" 2020// on how to reach the appropriate member. 2021// 2022// class A 2023// { 2024// public: 2025// int m_a; 2026// int m_b; 2027// }; 2028// 2029// class B 2030// { 2031// }; 2032// 2033// class C : 2034// public B, 2035// public A 2036// { 2037// }; 2038// 2039// If we have a clang type that describes "class C", and we wanted to looked 2040// "m_b" in it: 2041// 2042// With omit_empty_base_classes == false we would get an integer array back with: 2043// { 1, 1 } 2044// The first index 1 is the child index for "class A" within class C 2045// The second index 1 is the child index for "m_b" within class A 2046// 2047// With omit_empty_base_classes == true we would get an integer array back with: 2048// { 0, 1 } 2049// 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) 2050// The second index 1 is the child index for "m_b" within class A 2051 2052size_t 2053ClangASTContext::GetIndexOfChildMemberWithName 2054( 2055 ASTContext *ast_context, 2056 void *clang_type, 2057 const char *name, 2058 bool omit_empty_base_classes, 2059 std::vector<uint32_t>& child_indexes 2060) 2061{ 2062 if (clang_type && name && name[0]) 2063 { 2064 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2065 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2066 switch (type_class) 2067 { 2068 case clang::Type::Record: 2069 { 2070 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 2071 const RecordDecl *record_decl = record_type->getDecl(); 2072 2073 assert(record_decl); 2074 uint32_t child_idx = 0; 2075 2076 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2077 2078 // Try and find a field that matches NAME 2079 RecordDecl::field_iterator field, field_end; 2080 StringRef name_sref(name); 2081 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 2082 field != field_end; 2083 ++field, ++child_idx) 2084 { 2085 if (field->getName().equals (name_sref)) 2086 { 2087 // We have to add on the number of base classes to this index! 2088 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes)); 2089 return child_indexes.size(); 2090 } 2091 } 2092 2093 if (cxx_record_decl) 2094 { 2095 const RecordDecl *parent_record_decl = cxx_record_decl; 2096 2097 //printf ("parent = %s\n", parent_record_decl->getNameAsCString()); 2098 2099 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl(); 2100 // Didn't find things easily, lets let clang do its thang... 2101 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name)); 2102 DeclarationName decl_name(&ident_ref); 2103 2104 CXXBasePaths paths; 2105 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember, 2106 decl_name.getAsOpaquePtr(), 2107 paths)) 2108 { 2109 CXXBasePaths::const_paths_iterator path, path_end = paths.end(); 2110 for (path = paths.begin(); path != path_end; ++path) 2111 { 2112 const size_t num_path_elements = path->size(); 2113 for (size_t e=0; e<num_path_elements; ++e) 2114 { 2115 CXXBasePathElement elem = (*path)[e]; 2116 2117 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes); 2118 if (child_idx == UINT32_MAX) 2119 { 2120 child_indexes.clear(); 2121 return 0; 2122 } 2123 else 2124 { 2125 child_indexes.push_back (child_idx); 2126 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl()); 2127 } 2128 } 2129 DeclContext::lookup_iterator named_decl_pos; 2130 for (named_decl_pos = path->Decls.first; 2131 named_decl_pos != path->Decls.second && parent_record_decl; 2132 ++named_decl_pos) 2133 { 2134 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString()); 2135 2136 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes); 2137 if (child_idx == UINT32_MAX) 2138 { 2139 child_indexes.clear(); 2140 return 0; 2141 } 2142 else 2143 { 2144 child_indexes.push_back (child_idx); 2145 } 2146 } 2147 } 2148 return child_indexes.size(); 2149 } 2150 } 2151 2152 } 2153 break; 2154 2155 case clang::Type::ObjCObject: 2156 case clang::Type::ObjCInterface: 2157 { 2158 StringRef name_sref(name); 2159 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 2160 assert (objc_class_type); 2161 if (objc_class_type) 2162 { 2163 uint32_t child_idx = 0; 2164 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 2165 2166 if (class_interface_decl) 2167 { 2168 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 2169 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 2170 2171 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) 2172 { 2173 const ObjCIvarDecl* ivar_decl = *ivar_pos; 2174 2175 if (ivar_decl->getName().equals (name_sref)) 2176 { 2177 if ((!omit_empty_base_classes && superclass_interface_decl) || 2178 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) 2179 ++child_idx; 2180 2181 child_indexes.push_back (child_idx); 2182 return child_indexes.size(); 2183 } 2184 } 2185 2186 if (superclass_interface_decl) 2187 { 2188 // The super class index is always zero for ObjC classes, 2189 // so we push it onto the child indexes in case we find 2190 // an ivar in our superclass... 2191 child_indexes.push_back (0); 2192 2193 if (GetIndexOfChildMemberWithName (ast_context, 2194 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), 2195 name, 2196 omit_empty_base_classes, 2197 child_indexes)) 2198 { 2199 // We did find an ivar in a superclass so just 2200 // return the results! 2201 return child_indexes.size(); 2202 } 2203 2204 // We didn't find an ivar matching "name" in our 2205 // superclass, pop the superclass zero index that 2206 // we pushed on above. 2207 child_indexes.pop_back(); 2208 } 2209 } 2210 } 2211 } 2212 break; 2213 2214 case clang::Type::ObjCObjectPointer: 2215 { 2216 return GetIndexOfChildMemberWithName (ast_context, 2217 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), 2218 name, 2219 omit_empty_base_classes, 2220 child_indexes); 2221 } 2222 break; 2223 2224 2225 case clang::Type::ConstantArray: 2226 { 2227// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 2228// const uint64_t element_count = array->getSize().getLimitedValue(); 2229// 2230// if (idx < element_count) 2231// { 2232// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType()); 2233// 2234// char element_name[32]; 2235// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); 2236// 2237// child_name.assign(element_name); 2238// assert(field_type_info.first % 8 == 0); 2239// child_byte_size = field_type_info.first / 8; 2240// child_byte_offset = idx * child_byte_size; 2241// return array->getElementType().getAsOpaquePtr(); 2242// } 2243 } 2244 break; 2245 2246// case clang::Type::MemberPointerType: 2247// { 2248// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); 2249// QualType pointee_type = mem_ptr_type->getPointeeType(); 2250// 2251// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2252// { 2253// return GetIndexOfChildWithName (ast_context, 2254// mem_ptr_type->getPointeeType().getAsOpaquePtr(), 2255// name); 2256// } 2257// } 2258// break; 2259// 2260 case clang::Type::LValueReference: 2261 case clang::Type::RValueReference: 2262 { 2263 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 2264 QualType pointee_type = reference_type->getPointeeType(); 2265 2266 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2267 { 2268 return GetIndexOfChildMemberWithName (ast_context, 2269 reference_type->getPointeeType().getAsOpaquePtr(), 2270 name, 2271 omit_empty_base_classes, 2272 child_indexes); 2273 } 2274 } 2275 break; 2276 2277 case clang::Type::Pointer: 2278 { 2279 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 2280 QualType pointee_type = pointer_type->getPointeeType(); 2281 2282 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2283 { 2284 return GetIndexOfChildMemberWithName (ast_context, 2285 pointer_type->getPointeeType().getAsOpaquePtr(), 2286 name, 2287 omit_empty_base_classes, 2288 child_indexes); 2289 } 2290 else 2291 { 2292// if (parent_name) 2293// { 2294// child_name.assign(1, '*'); 2295// child_name += parent_name; 2296// } 2297// 2298// // We have a pointer to an simple type 2299// if (idx == 0) 2300// { 2301// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 2302// assert(clang_type_info.first % 8 == 0); 2303// child_byte_size = clang_type_info.first / 8; 2304// child_byte_offset = 0; 2305// return pointee_type.getAsOpaquePtr(); 2306// } 2307 } 2308 } 2309 break; 2310 2311 case clang::Type::Typedef: 2312 return GetIndexOfChildMemberWithName (ast_context, 2313 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 2314 name, 2315 omit_empty_base_classes, 2316 child_indexes); 2317 2318 default: 2319 break; 2320 } 2321 } 2322 return 0; 2323} 2324 2325 2326// Get the index of the child of "clang_type" whose name matches. This function 2327// doesn't descend into the children, but only looks one level deep and name 2328// matches can include base class names. 2329 2330uint32_t 2331ClangASTContext::GetIndexOfChildWithName 2332( 2333 ASTContext *ast_context, 2334 void *clang_type, 2335 const char *name, 2336 bool omit_empty_base_classes 2337) 2338{ 2339 if (clang_type && name && name[0]) 2340 { 2341 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2342 2343 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2344 2345 switch (type_class) 2346 { 2347 case clang::Type::Record: 2348 { 2349 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 2350 const RecordDecl *record_decl = record_type->getDecl(); 2351 2352 assert(record_decl); 2353 uint32_t child_idx = 0; 2354 2355 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2356 2357 if (cxx_record_decl) 2358 { 2359 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2360 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2361 base_class != base_class_end; 2362 ++base_class) 2363 { 2364 // Skip empty base classes 2365 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2366 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false) 2367 continue; 2368 2369 if (base_class->getType().getAsString().compare (name) == 0) 2370 return child_idx; 2371 ++child_idx; 2372 } 2373 } 2374 2375 // Try and find a field that matches NAME 2376 RecordDecl::field_iterator field, field_end; 2377 StringRef name_sref(name); 2378 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 2379 field != field_end; 2380 ++field, ++child_idx) 2381 { 2382 if (field->getName().equals (name_sref)) 2383 return child_idx; 2384 } 2385 2386 } 2387 break; 2388 2389 case clang::Type::ObjCObject: 2390 case clang::Type::ObjCInterface: 2391 { 2392 StringRef name_sref(name); 2393 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 2394 assert (objc_class_type); 2395 if (objc_class_type) 2396 { 2397 uint32_t child_idx = 0; 2398 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 2399 2400 if (class_interface_decl) 2401 { 2402 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 2403 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 2404 2405 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) 2406 { 2407 const ObjCIvarDecl* ivar_decl = *ivar_pos; 2408 2409 if (ivar_decl->getName().equals (name_sref)) 2410 { 2411 if ((!omit_empty_base_classes && superclass_interface_decl) || 2412 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) 2413 ++child_idx; 2414 2415 return child_idx; 2416 } 2417 } 2418 2419 if (superclass_interface_decl) 2420 { 2421 if (superclass_interface_decl->getName().equals (name_sref)) 2422 return 0; 2423 } 2424 } 2425 } 2426 } 2427 break; 2428 2429 case clang::Type::ObjCObjectPointer: 2430 { 2431 return GetIndexOfChildWithName (ast_context, 2432 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), 2433 name, 2434 omit_empty_base_classes); 2435 } 2436 break; 2437 2438 case clang::Type::ConstantArray: 2439 { 2440// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 2441// const uint64_t element_count = array->getSize().getLimitedValue(); 2442// 2443// if (idx < element_count) 2444// { 2445// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType()); 2446// 2447// char element_name[32]; 2448// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); 2449// 2450// child_name.assign(element_name); 2451// assert(field_type_info.first % 8 == 0); 2452// child_byte_size = field_type_info.first / 8; 2453// child_byte_offset = idx * child_byte_size; 2454// return array->getElementType().getAsOpaquePtr(); 2455// } 2456 } 2457 break; 2458 2459// case clang::Type::MemberPointerType: 2460// { 2461// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); 2462// QualType pointee_type = mem_ptr_type->getPointeeType(); 2463// 2464// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2465// { 2466// return GetIndexOfChildWithName (ast_context, 2467// mem_ptr_type->getPointeeType().getAsOpaquePtr(), 2468// name); 2469// } 2470// } 2471// break; 2472// 2473 case clang::Type::LValueReference: 2474 case clang::Type::RValueReference: 2475 { 2476 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 2477 QualType pointee_type = reference_type->getPointeeType(); 2478 2479 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2480 { 2481 return GetIndexOfChildWithName (ast_context, 2482 reference_type->getPointeeType().getAsOpaquePtr(), 2483 name, 2484 omit_empty_base_classes); 2485 } 2486 } 2487 break; 2488 2489 case clang::Type::Pointer: 2490 { 2491 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 2492 QualType pointee_type = pointer_type->getPointeeType(); 2493 2494 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2495 { 2496 return GetIndexOfChildWithName (ast_context, 2497 pointer_type->getPointeeType().getAsOpaquePtr(), 2498 name, 2499 omit_empty_base_classes); 2500 } 2501 else 2502 { 2503// if (parent_name) 2504// { 2505// child_name.assign(1, '*'); 2506// child_name += parent_name; 2507// } 2508// 2509// // We have a pointer to an simple type 2510// if (idx == 0) 2511// { 2512// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 2513// assert(clang_type_info.first % 8 == 0); 2514// child_byte_size = clang_type_info.first / 8; 2515// child_byte_offset = 0; 2516// return pointee_type.getAsOpaquePtr(); 2517// } 2518 } 2519 } 2520 break; 2521 2522 case clang::Type::Typedef: 2523 return GetIndexOfChildWithName (ast_context, 2524 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 2525 name, 2526 omit_empty_base_classes); 2527 2528 default: 2529 break; 2530 } 2531 } 2532 return UINT32_MAX; 2533} 2534 2535#pragma mark TagType 2536 2537bool 2538ClangASTContext::SetTagTypeKind (void *tag_clang_type, int kind) 2539{ 2540 if (tag_clang_type) 2541 { 2542 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type)); 2543 clang::Type *clang_type = tag_qual_type.getTypePtr(); 2544 if (clang_type) 2545 { 2546 TagType *tag_type = dyn_cast<TagType>(clang_type); 2547 if (tag_type) 2548 { 2549 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl()); 2550 if (tag_decl) 2551 { 2552 tag_decl->setTagKind ((TagDecl::TagKind)kind); 2553 return true; 2554 } 2555 } 2556 } 2557 } 2558 return false; 2559} 2560 2561 2562#pragma mark DeclContext Functions 2563 2564DeclContext * 2565ClangASTContext::GetDeclContextForType (void *clang_type) 2566{ 2567 if (clang_type == NULL) 2568 return NULL; 2569 2570 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2571 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2572 switch (type_class) 2573 { 2574 case clang::Type::FunctionNoProto: break; 2575 case clang::Type::FunctionProto: break; 2576 case clang::Type::IncompleteArray: break; 2577 case clang::Type::VariableArray: break; 2578 case clang::Type::ConstantArray: break; 2579 case clang::Type::ExtVector: break; 2580 case clang::Type::Vector: break; 2581 case clang::Type::Builtin: break; 2582 case clang::Type::BlockPointer: break; 2583 case clang::Type::Pointer: break; 2584 case clang::Type::LValueReference: break; 2585 case clang::Type::RValueReference: break; 2586 case clang::Type::MemberPointer: break; 2587 case clang::Type::Complex: break; 2588 case clang::Type::ObjCObject: break; 2589 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface(); 2590 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr()); 2591 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl(); 2592 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl(); 2593 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 2594 2595 case clang::Type::TypeOfExpr: break; 2596 case clang::Type::TypeOf: break; 2597 case clang::Type::Decltype: break; 2598 //case clang::Type::QualifiedName: break; 2599 case clang::Type::TemplateSpecialization: break; 2600 } 2601 // No DeclContext in this type... 2602 return NULL; 2603} 2604 2605#pragma mark Namespace Declarations 2606 2607NamespaceDecl * 2608ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx) 2609{ 2610 // TODO: Do something intelligent with the Declaration object passed in 2611 // like maybe filling in the SourceLocation with it... 2612 if (name) 2613 { 2614 ASTContext *ast_context = getASTContext(); 2615 if (decl_ctx == NULL) 2616 decl_ctx = ast_context->getTranslationUnitDecl(); 2617 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name)); 2618 } 2619 return NULL; 2620} 2621 2622 2623#pragma mark Function Types 2624 2625FunctionDecl * 2626ClangASTContext::CreateFunctionDeclaration (const char *name, void *function_clang_type, int storage, bool is_inline) 2627{ 2628 if (name) 2629 { 2630 ASTContext *ast_context = getASTContext(); 2631 assert (ast_context != NULL); 2632 2633 if (name && name[0]) 2634 { 2635 return FunctionDecl::Create(*ast_context, 2636 ast_context->getTranslationUnitDecl(), 2637 SourceLocation(), 2638 DeclarationName (&ast_context->Idents.get(name)), 2639 QualType::getFromOpaquePtr(function_clang_type), 2640 NULL, 2641 (FunctionDecl::StorageClass)storage, 2642 (FunctionDecl::StorageClass)storage, 2643 is_inline); 2644 } 2645 else 2646 { 2647 return FunctionDecl::Create(*ast_context, 2648 ast_context->getTranslationUnitDecl(), 2649 SourceLocation(), 2650 DeclarationName (), 2651 QualType::getFromOpaquePtr(function_clang_type), 2652 NULL, 2653 (FunctionDecl::StorageClass)storage, 2654 (FunctionDecl::StorageClass)storage, 2655 is_inline); 2656 } 2657 } 2658 return NULL; 2659} 2660 2661void * 2662ClangASTContext::CreateFunctionType (clang::ASTContext *ast_context, 2663 void *result_type, 2664 void **args, 2665 unsigned num_args, 2666 bool is_variadic, 2667 unsigned type_quals) 2668{ 2669 assert (ast_context != NULL); 2670 std::vector<QualType> qual_type_args; 2671 for (unsigned i=0; i<num_args; ++i) 2672 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i])); 2673 2674 // TODO: Detect calling convention in DWARF? 2675 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type), 2676 qual_type_args.empty() ? NULL : &qual_type_args.front(), 2677 qual_type_args.size(), 2678 is_variadic, 2679 type_quals, 2680 false, // hasExceptionSpec 2681 false, // hasAnyExceptionSpec, 2682 0, // NumExs 2683 0, // const QualType *ExArray 2684 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn); 2685} 2686 2687ParmVarDecl * 2688ClangASTContext::CreateParameterDeclaration (const char *name, void *param_type, int storage) 2689{ 2690 ASTContext *ast_context = getASTContext(); 2691 assert (ast_context != NULL); 2692 return ParmVarDecl::Create(*ast_context, 2693 ast_context->getTranslationUnitDecl(), 2694 SourceLocation(), 2695 name && name[0] ? &ast_context->Idents.get(name) : NULL, 2696 QualType::getFromOpaquePtr(param_type), 2697 NULL, 2698 (VarDecl::StorageClass)storage, 2699 (VarDecl::StorageClass)storage, 2700 0); 2701} 2702 2703void 2704ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params) 2705{ 2706 if (function_decl) 2707 function_decl->setParams (params, num_params); 2708} 2709 2710 2711#pragma mark Array Types 2712 2713void * 2714ClangASTContext::CreateArrayType (void *element_type, size_t element_count, uint32_t bit_stride) 2715{ 2716 if (element_type) 2717 { 2718 ASTContext *ast_context = getASTContext(); 2719 assert (ast_context != NULL); 2720 llvm::APInt ap_element_count (64, element_count); 2721 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type), 2722 ap_element_count, 2723 ArrayType::Normal, 2724 0).getAsOpaquePtr(); // ElemQuals 2725 } 2726 return NULL; 2727} 2728 2729 2730#pragma mark TagDecl 2731 2732bool 2733ClangASTContext::StartTagDeclarationDefinition (void *clang_type) 2734{ 2735 if (clang_type) 2736 { 2737 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2738 clang::Type *t = qual_type.getTypePtr(); 2739 if (t) 2740 { 2741 TagType *tag_type = dyn_cast<TagType>(t); 2742 if (tag_type) 2743 { 2744 TagDecl *tag_decl = tag_type->getDecl(); 2745 if (tag_decl) 2746 { 2747 tag_decl->startDefinition(); 2748 return true; 2749 } 2750 } 2751 } 2752 } 2753 return false; 2754} 2755 2756bool 2757ClangASTContext::CompleteTagDeclarationDefinition (void *clang_type) 2758{ 2759 if (clang_type) 2760 { 2761 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2762 clang::Type *t = qual_type.getTypePtr(); 2763 if (t) 2764 { 2765 TagType *tag_type = dyn_cast<TagType>(t); 2766 if (tag_type) 2767 { 2768 TagDecl *tag_decl = tag_type->getDecl(); 2769 if (tag_decl) 2770 { 2771 tag_decl->completeDefinition(); 2772 return true; 2773 } 2774 } 2775 } 2776 } 2777 return false; 2778} 2779 2780 2781#pragma mark Enumeration Types 2782 2783void * 2784ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, void *integer_qual_type) 2785{ 2786 // TODO: Do something intelligent with the Declaration object passed in 2787 // like maybe filling in the SourceLocation with it... 2788 ASTContext *ast_context = getASTContext(); 2789 assert (ast_context != NULL); 2790 EnumDecl *enum_decl = EnumDecl::Create(*ast_context, 2791 ast_context->getTranslationUnitDecl(), 2792 SourceLocation(), 2793 name && name[0] ? &ast_context->Idents.get(name) : NULL, 2794 SourceLocation(), 2795 NULL); 2796 if (enum_decl) 2797 { 2798 // TODO: check if we should be setting the promotion type too? 2799 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type)); 2800 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr(); 2801 } 2802 return NULL; 2803} 2804 2805bool 2806ClangASTContext::AddEnumerationValueToEnumerationType 2807( 2808 void *enum_clang_type, 2809 void *enumerator_clang_type, 2810 const Declaration &decl, 2811 const char *name, 2812 int64_t enum_value, 2813 uint32_t enum_value_bit_size 2814) 2815{ 2816 if (enum_clang_type && enumerator_clang_type && name) 2817 { 2818 // TODO: Do something intelligent with the Declaration object passed in 2819 // like maybe filling in the SourceLocation with it... 2820 ASTContext *ast_context = getASTContext(); 2821 IdentifierTable *identifier_table = getIdentifierTable(); 2822 2823 assert (ast_context != NULL); 2824 assert (identifier_table != NULL); 2825 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); 2826 2827 clang::Type *clang_type = enum_qual_type.getTypePtr(); 2828 if (clang_type) 2829 { 2830 const EnumType *enum_type = dyn_cast<EnumType>(clang_type); 2831 2832 if (enum_type) 2833 { 2834 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false); 2835 enum_llvm_apsint = enum_value; 2836 EnumConstantDecl *enumerator_decl = 2837 EnumConstantDecl::Create(*ast_context, 2838 enum_type->getDecl(), 2839 SourceLocation(), 2840 name ? &identifier_table->get(name) : NULL, // Identifier 2841 QualType::getFromOpaquePtr(enumerator_clang_type), 2842 NULL, 2843 enum_llvm_apsint); 2844 2845 if (enumerator_decl) 2846 { 2847 enum_type->getDecl()->addDecl(enumerator_decl); 2848 return true; 2849 } 2850 } 2851 } 2852 } 2853 return false; 2854} 2855 2856#pragma mark Pointers & References 2857 2858void * 2859ClangASTContext::CreatePointerType (void *clang_type) 2860{ 2861 if (clang_type) 2862 { 2863 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2864 2865 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2866 switch (type_class) 2867 { 2868 case clang::Type::ObjCObject: 2869 case clang::Type::ObjCInterface: 2870 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); 2871 2872 default: 2873 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr(); 2874 } 2875 } 2876 return NULL; 2877} 2878 2879void * 2880ClangASTContext::CreateLValueReferenceType (void *clang_type) 2881{ 2882 if (clang_type) 2883 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); 2884 return NULL; 2885} 2886 2887void * 2888ClangASTContext::CreateRValueReferenceType (void *clang_type) 2889{ 2890 if (clang_type) 2891 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); 2892 return NULL; 2893} 2894 2895void * 2896ClangASTContext::CreateMemberPointerType (void *clang_pointee_type, void *clang_class_type) 2897{ 2898 if (clang_pointee_type && clang_pointee_type) 2899 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type), 2900 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr(); 2901 return NULL; 2902} 2903 2904size_t 2905ClangASTContext::GetPointerBitSize () 2906{ 2907 ASTContext *ast_context = getASTContext(); 2908 return ast_context->getTypeSize(ast_context->VoidPtrTy); 2909} 2910 2911bool 2912ClangASTContext::IsPointerOrReferenceType (void *clang_type, void **target_type) 2913{ 2914 if (clang_type == NULL) 2915 return false; 2916 2917 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2918 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2919 switch (type_class) 2920 { 2921 case clang::Type::ObjCObjectPointer: 2922 if (target_type) 2923 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 2924 return true; 2925 case clang::Type::BlockPointer: 2926 if (target_type) 2927 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 2928 return true; 2929 case clang::Type::Pointer: 2930 if (target_type) 2931 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 2932 return true; 2933 case clang::Type::MemberPointer: 2934 if (target_type) 2935 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 2936 return true; 2937 case clang::Type::LValueReference: 2938 if (target_type) 2939 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); 2940 return true; 2941 case clang::Type::RValueReference: 2942 if (target_type) 2943 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); 2944 return true; 2945 case clang::Type::Typedef: 2946 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 2947 default: 2948 break; 2949 } 2950 return false; 2951} 2952 2953bool 2954ClangASTContext::IsIntegerType (void *clang_type, bool &is_signed) 2955{ 2956 if (!clang_type) 2957 return false; 2958 2959 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2960 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()); 2961 2962 if (builtin_type) 2963 { 2964 if (builtin_type->isInteger()) 2965 is_signed = builtin_type->isSignedInteger(); 2966 2967 return true; 2968 } 2969 2970 return false; 2971} 2972 2973bool 2974ClangASTContext::IsPointerType (void *clang_type, void **target_type) 2975{ 2976 if (clang_type) 2977 { 2978 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 2979 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2980 switch (type_class) 2981 { 2982 case clang::Type::ObjCObjectPointer: 2983 if (target_type) 2984 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 2985 return true; 2986 case clang::Type::BlockPointer: 2987 if (target_type) 2988 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 2989 return true; 2990 case clang::Type::Pointer: 2991 if (target_type) 2992 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 2993 return true; 2994 case clang::Type::MemberPointer: 2995 if (target_type) 2996 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 2997 return true; 2998 case clang::Type::Typedef: 2999 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type); 3000 default: 3001 break; 3002 } 3003 } 3004 return false; 3005} 3006 3007bool 3008ClangASTContext::IsFloatingPointType (void *clang_type, uint32_t &count, bool &is_complex) 3009{ 3010 if (clang_type) 3011 { 3012 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3013 3014 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal())) 3015 { 3016 clang::BuiltinType::Kind kind = BT->getKind(); 3017 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble) 3018 { 3019 count = 1; 3020 is_complex = false; 3021 return true; 3022 } 3023 } 3024 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal())) 3025 { 3026 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex)) 3027 { 3028 count = 2; 3029 is_complex = true; 3030 return true; 3031 } 3032 } 3033 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal())) 3034 { 3035 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex)) 3036 { 3037 count = VT->getNumElements(); 3038 is_complex = false; 3039 return true; 3040 } 3041 } 3042 } 3043 return false; 3044} 3045 3046 3047bool 3048ClangASTContext::IsCStringType (void *clang_type, uint32_t &length) 3049{ 3050 if (clang_type) 3051 { 3052 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3053 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3054 switch (type_class) 3055 { 3056 case clang::Type::ConstantArray: 3057 { 3058 ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr()); 3059 QualType element_qual_type = array->getElementType(); 3060 clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr(); 3061 if (canonical_type && canonical_type->isCharType()) 3062 { 3063 // We know the size of the array and it could be a C string 3064 // since it is an array of characters 3065 length = array->getSize().getLimitedValue(); 3066 return true; 3067 } 3068 } 3069 break; 3070 3071 case clang::Type::Pointer: 3072 { 3073 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 3074 clang::Type *pointee_type_ptr = pointer_type->getPointeeType().getTypePtr(); 3075 if (pointee_type_ptr) 3076 { 3077 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr(); 3078 length = 0; // No length info, read until a NULL terminator is received 3079 if (canonical_type_ptr) 3080 return canonical_type_ptr->isCharType(); 3081 else 3082 return pointee_type_ptr->isCharType(); 3083 } 3084 } 3085 break; 3086 3087 case clang::Type::Typedef: 3088 return ClangASTContext::IsCStringType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), length); 3089 3090 case clang::Type::LValueReference: 3091 case clang::Type::RValueReference: 3092 { 3093 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 3094 clang::Type *pointee_type_ptr = reference_type->getPointeeType().getTypePtr(); 3095 if (pointee_type_ptr) 3096 { 3097 clang::Type *canonical_type_ptr = pointee_type_ptr->getCanonicalTypeInternal().getTypePtr(); 3098 length = 0; // No length info, read until a NULL terminator is received 3099 if (canonical_type_ptr) 3100 return canonical_type_ptr->isCharType(); 3101 else 3102 return pointee_type_ptr->isCharType(); 3103 } 3104 } 3105 break; 3106 } 3107 } 3108 return false; 3109} 3110 3111bool 3112ClangASTContext::IsFunctionPointerType (void *clang_type) 3113{ 3114 if (clang_type) 3115 { 3116 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3117 3118 if (qual_type->isFunctionPointerType()) 3119 return true; 3120 3121 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3122 switch (type_class) 3123 { 3124 case clang::Type::Typedef: 3125 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 3126 3127 case clang::Type::LValueReference: 3128 case clang::Type::RValueReference: 3129 { 3130 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 3131 if (reference_type) 3132 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr()); 3133 } 3134 break; 3135 } 3136 } 3137 return false; 3138} 3139 3140 3141 3142 3143bool 3144ClangASTContext::IsArrayType (void *clang_type, void **member_type, uint64_t *size) 3145{ 3146 if (!clang_type) 3147 return false; 3148 3149 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3150 3151 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3152 switch (type_class) 3153 { 3154 case clang::Type::ConstantArray: 3155 if (member_type) 3156 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3157 if (size) 3158 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX); 3159 return true; 3160 case clang::Type::IncompleteArray: 3161 if (member_type) 3162 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3163 if (size) 3164 *size = 0; 3165 return true; 3166 case clang::Type::VariableArray: 3167 if (member_type) 3168 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3169 if (size) 3170 *size = 0; 3171 case clang::Type::DependentSizedArray: 3172 if (member_type) 3173 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3174 if (size) 3175 *size = 0; 3176 return true; 3177 } 3178 return false; 3179} 3180 3181 3182#pragma mark Typedefs 3183 3184void * 3185ClangASTContext::CreateTypedefType (const char *name, void *clang_type, DeclContext *decl_ctx) 3186{ 3187 if (clang_type) 3188 { 3189 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3190 ASTContext *ast_context = getASTContext(); 3191 IdentifierTable *identifier_table = getIdentifierTable(); 3192 assert (ast_context != NULL); 3193 assert (identifier_table != NULL); 3194 if (decl_ctx == NULL) 3195 decl_ctx = ast_context->getTranslationUnitDecl(); 3196 TypedefDecl *decl = TypedefDecl::Create(*ast_context, 3197 decl_ctx, 3198 SourceLocation(), 3199 name ? &identifier_table->get(name) : NULL, // Identifier 3200 ast_context->CreateTypeSourceInfo(qual_type)); 3201 3202 // Get a uniqued QualType for the typedef decl type 3203 return ast_context->getTypedefType (decl).getAsOpaquePtr(); 3204 } 3205 return NULL; 3206} 3207 3208 3209std::string 3210ClangASTContext::GetTypeName (void *opaque_qual_type) 3211{ 3212 std::string return_name; 3213 3214 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_qual_type)); 3215 3216 const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>(); 3217 if (typedef_type) 3218 { 3219 const clang::TypedefDecl *typedef_decl = typedef_type->getDecl(); 3220 return_name = typedef_decl->getQualifiedNameAsString(); 3221 } 3222 else 3223 { 3224 return_name = qual_type.getAsString(); 3225 } 3226 3227 return return_name; 3228} 3229 3230// Disable this for now since I can't seem to get a nicely formatted float 3231// out of the APFloat class without just getting the float, double or quad 3232// and then using a formatted print on it which defeats the purpose. We ideally 3233// would like to get perfect string values for any kind of float semantics 3234// so we can support remote targets. The code below also requires a patch to 3235// llvm::APInt. 3236//bool 3237//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, void *clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str) 3238//{ 3239// uint32_t count = 0; 3240// bool is_complex = false; 3241// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex)) 3242// { 3243// unsigned num_bytes_per_float = byte_size / count; 3244// unsigned num_bits_per_float = num_bytes_per_float * 8; 3245// 3246// float_str.clear(); 3247// uint32_t i; 3248// for (i=0; i<count; i++) 3249// { 3250// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order); 3251// bool is_ieee = false; 3252// APFloat ap_float(ap_int, is_ieee); 3253// char s[1024]; 3254// unsigned int hex_digits = 0; 3255// bool upper_case = false; 3256// 3257// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0) 3258// { 3259// if (i > 0) 3260// float_str.append(", "); 3261// float_str.append(s); 3262// if (i == 1 && is_complex) 3263// float_str.append(1, 'i'); 3264// } 3265// } 3266// return !float_str.empty(); 3267// } 3268// return false; 3269//} 3270 3271size_t 3272ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, void *clang_type, const char *s, uint8_t *dst, size_t dst_size) 3273{ 3274 if (clang_type) 3275 { 3276 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3277 uint32_t count = 0; 3278 bool is_complex = false; 3279 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex)) 3280 { 3281 // TODO: handle complex and vector types 3282 if (count != 1) 3283 return false; 3284 3285 StringRef s_sref(s); 3286 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref); 3287 3288 const uint64_t bit_size = ast_context->getTypeSize (qual_type); 3289 const uint64_t byte_size = bit_size / 8; 3290 if (dst_size >= byte_size) 3291 { 3292 if (bit_size == sizeof(float)*8) 3293 { 3294 float float32 = ap_float.convertToFloat(); 3295 ::memcpy (dst, &float32, byte_size); 3296 return byte_size; 3297 } 3298 else if (bit_size >= 64) 3299 { 3300 llvm::APInt ap_int(ap_float.bitcastToAPInt()); 3301 ::memcpy (dst, ap_int.getRawData(), byte_size); 3302 return byte_size; 3303 } 3304 } 3305 } 3306 } 3307 return 0; 3308} 3309 3310unsigned 3311ClangASTContext::GetTypeQualifiers(void *clang_type) 3312{ 3313 assert (clang_type); 3314 3315 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3316 3317 return qual_type.getQualifiers().getCVRQualifiers(); 3318} 3319