CXType.cpp revision 1a554f72f2cf3615e5625e0922afc6b2a02a8a94
1//===- CXTypes.cpp - Implements 'CXTypes' aspect of libclang ------------===// 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// This file implements the 'CXTypes' API hooks in the Clang-C library. 11// 12//===--------------------------------------------------------------------===// 13 14#include "CIndexer.h" 15#include "CXCursor.h" 16#include "CXString.h" 17#include "CXTranslationUnit.h" 18#include "CXType.h" 19#include "clang/AST/Decl.h" 20#include "clang/AST/DeclObjC.h" 21#include "clang/AST/DeclTemplate.h" 22#include "clang/AST/Expr.h" 23#include "clang/AST/Type.h" 24#include "clang/Frontend/ASTUnit.h" 25 26using namespace clang; 27 28static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { 29#define BTCASE(K) case BuiltinType::K: return CXType_##K 30 switch (BT->getKind()) { 31 BTCASE(Void); 32 BTCASE(Bool); 33 BTCASE(Char_U); 34 BTCASE(UChar); 35 BTCASE(Char16); 36 BTCASE(Char32); 37 BTCASE(UShort); 38 BTCASE(UInt); 39 BTCASE(ULong); 40 BTCASE(ULongLong); 41 BTCASE(UInt128); 42 BTCASE(Char_S); 43 BTCASE(SChar); 44 case BuiltinType::WChar_S: return CXType_WChar; 45 case BuiltinType::WChar_U: return CXType_WChar; 46 BTCASE(Short); 47 BTCASE(Int); 48 BTCASE(Long); 49 BTCASE(LongLong); 50 BTCASE(Int128); 51 BTCASE(Float); 52 BTCASE(Double); 53 BTCASE(LongDouble); 54 BTCASE(NullPtr); 55 BTCASE(Overload); 56 BTCASE(Dependent); 57 BTCASE(ObjCId); 58 BTCASE(ObjCClass); 59 BTCASE(ObjCSel); 60 default: 61 return CXType_Unexposed; 62 } 63#undef BTCASE 64} 65 66static CXTypeKind GetTypeKind(QualType T) { 67 const Type *TP = T.getTypePtrOrNull(); 68 if (!TP) 69 return CXType_Invalid; 70 71#define TKCASE(K) case Type::K: return CXType_##K 72 switch (TP->getTypeClass()) { 73 case Type::Builtin: 74 return GetBuiltinTypeKind(cast<BuiltinType>(TP)); 75 TKCASE(Complex); 76 TKCASE(Pointer); 77 TKCASE(BlockPointer); 78 TKCASE(LValueReference); 79 TKCASE(RValueReference); 80 TKCASE(Record); 81 TKCASE(Enum); 82 TKCASE(Typedef); 83 TKCASE(ObjCInterface); 84 TKCASE(ObjCObjectPointer); 85 TKCASE(FunctionNoProto); 86 TKCASE(FunctionProto); 87 TKCASE(ConstantArray); 88 TKCASE(Vector); 89 default: 90 return CXType_Unexposed; 91 } 92#undef TKCASE 93} 94 95 96CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { 97 CXTypeKind TK = CXType_Invalid; 98 99 if (TU && !T.isNull()) { 100 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext(); 101 if (Ctx.getLangOpts().ObjC1) { 102 QualType UnqualT = T.getUnqualifiedType(); 103 if (Ctx.isObjCIdType(UnqualT)) 104 TK = CXType_ObjCId; 105 else if (Ctx.isObjCClassType(UnqualT)) 106 TK = CXType_ObjCClass; 107 else if (Ctx.isObjCSelType(UnqualT)) 108 TK = CXType_ObjCSel; 109 } 110 } 111 if (TK == CXType_Invalid) 112 TK = GetTypeKind(T); 113 114 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }}; 115 return CT; 116} 117 118using cxtype::MakeCXType; 119 120static inline QualType GetQualType(CXType CT) { 121 return QualType::getFromOpaquePtr(CT.data[0]); 122} 123 124static inline CXTranslationUnit GetTU(CXType CT) { 125 return static_cast<CXTranslationUnit>(CT.data[1]); 126} 127 128extern "C" { 129 130CXType clang_getCursorType(CXCursor C) { 131 using namespace cxcursor; 132 133 CXTranslationUnit TU = cxcursor::getCursorTU(C); 134 if (!TU) 135 return MakeCXType(QualType(), TU); 136 137 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext(); 138 if (clang_isExpression(C.kind)) { 139 QualType T = cxcursor::getCursorExpr(C)->getType(); 140 return MakeCXType(T, TU); 141 } 142 143 if (clang_isDeclaration(C.kind)) { 144 const Decl *D = cxcursor::getCursorDecl(C); 145 if (!D) 146 return MakeCXType(QualType(), TU); 147 148 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 149 return MakeCXType(Context.getTypeDeclType(TD), TU); 150 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) 151 return MakeCXType(Context.getObjCInterfaceType(ID), TU); 152 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { 153 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo()) 154 return MakeCXType(TSInfo->getType(), TU); 155 return MakeCXType(DD->getType(), TU); 156 } 157 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 158 return MakeCXType(VD->getType(), TU); 159 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 160 return MakeCXType(PD->getType(), TU); 161 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) { 162 if (TypeSourceInfo *TSInfo = FTD->getTemplatedDecl()->getTypeSourceInfo()) 163 return MakeCXType(TSInfo->getType(), TU); 164 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU); 165 } 166 return MakeCXType(QualType(), TU); 167 } 168 169 if (clang_isReference(C.kind)) { 170 switch (C.kind) { 171 case CXCursor_ObjCSuperClassRef: { 172 QualType T 173 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first); 174 return MakeCXType(T, TU); 175 } 176 177 case CXCursor_ObjCClassRef: { 178 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first); 179 return MakeCXType(T, TU); 180 } 181 182 case CXCursor_TypeRef: { 183 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first); 184 return MakeCXType(T, TU); 185 186 } 187 188 case CXCursor_CXXBaseSpecifier: 189 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU); 190 191 case CXCursor_MemberRef: 192 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU); 193 194 case CXCursor_VariableRef: 195 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU); 196 197 case CXCursor_ObjCProtocolRef: 198 case CXCursor_TemplateRef: 199 case CXCursor_NamespaceRef: 200 case CXCursor_OverloadedDeclRef: 201 default: 202 break; 203 } 204 205 return MakeCXType(QualType(), TU); 206 } 207 208 return MakeCXType(QualType(), TU); 209} 210 211CXString clang_getTypeSpelling(CXType CT) { 212 QualType T = GetQualType(CT); 213 if (T.isNull()) 214 return cxstring::createEmpty(); 215 216 CXTranslationUnit TU = GetTU(CT); 217 SmallString<64> Str; 218 llvm::raw_svector_ostream OS(Str); 219 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts()); 220 221 T.print(OS, PP); 222 223 return cxstring::createDup(OS.str()); 224} 225 226CXType clang_getTypedefDeclUnderlyingType(CXCursor C) { 227 using namespace cxcursor; 228 CXTranslationUnit TU = cxcursor::getCursorTU(C); 229 230 if (clang_isDeclaration(C.kind)) { 231 const Decl *D = cxcursor::getCursorDecl(C); 232 233 if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) { 234 QualType T = TD->getUnderlyingType(); 235 return MakeCXType(T, TU); 236 } 237 238 return MakeCXType(QualType(), TU); 239 } 240 241 return MakeCXType(QualType(), TU); 242} 243 244CXType clang_getEnumDeclIntegerType(CXCursor C) { 245 using namespace cxcursor; 246 CXTranslationUnit TU = cxcursor::getCursorTU(C); 247 248 if (clang_isDeclaration(C.kind)) { 249 const Decl *D = cxcursor::getCursorDecl(C); 250 251 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) { 252 QualType T = TD->getIntegerType(); 253 return MakeCXType(T, TU); 254 } 255 256 return MakeCXType(QualType(), TU); 257 } 258 259 return MakeCXType(QualType(), TU); 260} 261 262long long clang_getEnumConstantDeclValue(CXCursor C) { 263 using namespace cxcursor; 264 265 if (clang_isDeclaration(C.kind)) { 266 const Decl *D = cxcursor::getCursorDecl(C); 267 268 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) { 269 return TD->getInitVal().getSExtValue(); 270 } 271 272 return LLONG_MIN; 273 } 274 275 return LLONG_MIN; 276} 277 278unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) { 279 using namespace cxcursor; 280 281 if (clang_isDeclaration(C.kind)) { 282 const Decl *D = cxcursor::getCursorDecl(C); 283 284 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) { 285 return TD->getInitVal().getZExtValue(); 286 } 287 288 return ULLONG_MAX; 289 } 290 291 return ULLONG_MAX; 292} 293 294int clang_getFieldDeclBitWidth(CXCursor C) { 295 using namespace cxcursor; 296 297 if (clang_isDeclaration(C.kind)) { 298 const Decl *D = getCursorDecl(C); 299 300 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) { 301 if (FD->isBitField()) 302 return FD->getBitWidthValue(getCursorContext(C)); 303 } 304 } 305 306 return -1; 307} 308 309CXType clang_getCanonicalType(CXType CT) { 310 if (CT.kind == CXType_Invalid) 311 return CT; 312 313 QualType T = GetQualType(CT); 314 CXTranslationUnit TU = GetTU(CT); 315 316 if (T.isNull()) 317 return MakeCXType(QualType(), GetTU(CT)); 318 319 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext() 320 .getCanonicalType(T), 321 TU); 322} 323 324unsigned clang_isConstQualifiedType(CXType CT) { 325 QualType T = GetQualType(CT); 326 return T.isLocalConstQualified(); 327} 328 329unsigned clang_isVolatileQualifiedType(CXType CT) { 330 QualType T = GetQualType(CT); 331 return T.isLocalVolatileQualified(); 332} 333 334unsigned clang_isRestrictQualifiedType(CXType CT) { 335 QualType T = GetQualType(CT); 336 return T.isLocalRestrictQualified(); 337} 338 339CXType clang_getPointeeType(CXType CT) { 340 QualType T = GetQualType(CT); 341 const Type *TP = T.getTypePtrOrNull(); 342 343 if (!TP) 344 return MakeCXType(QualType(), GetTU(CT)); 345 346 switch (TP->getTypeClass()) { 347 case Type::Pointer: 348 T = cast<PointerType>(TP)->getPointeeType(); 349 break; 350 case Type::BlockPointer: 351 T = cast<BlockPointerType>(TP)->getPointeeType(); 352 break; 353 case Type::LValueReference: 354 case Type::RValueReference: 355 T = cast<ReferenceType>(TP)->getPointeeType(); 356 break; 357 case Type::ObjCObjectPointer: 358 T = cast<ObjCObjectPointerType>(TP)->getPointeeType(); 359 break; 360 default: 361 T = QualType(); 362 break; 363 } 364 return MakeCXType(T, GetTU(CT)); 365} 366 367CXCursor clang_getTypeDeclaration(CXType CT) { 368 if (CT.kind == CXType_Invalid) 369 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 370 371 QualType T = GetQualType(CT); 372 const Type *TP = T.getTypePtrOrNull(); 373 374 if (!TP) 375 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 376 377 Decl *D = 0; 378 379try_again: 380 switch (TP->getTypeClass()) { 381 case Type::Typedef: 382 D = cast<TypedefType>(TP)->getDecl(); 383 break; 384 case Type::ObjCObject: 385 D = cast<ObjCObjectType>(TP)->getInterface(); 386 break; 387 case Type::ObjCInterface: 388 D = cast<ObjCInterfaceType>(TP)->getDecl(); 389 break; 390 case Type::Record: 391 case Type::Enum: 392 D = cast<TagType>(TP)->getDecl(); 393 break; 394 case Type::TemplateSpecialization: 395 if (const RecordType *Record = TP->getAs<RecordType>()) 396 D = Record->getDecl(); 397 else 398 D = cast<TemplateSpecializationType>(TP)->getTemplateName() 399 .getAsTemplateDecl(); 400 break; 401 402 case Type::InjectedClassName: 403 D = cast<InjectedClassNameType>(TP)->getDecl(); 404 break; 405 406 // FIXME: Template type parameters! 407 408 case Type::Elaborated: 409 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull(); 410 goto try_again; 411 412 default: 413 break; 414 } 415 416 if (!D) 417 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 418 419 return cxcursor::MakeCXCursor(D, GetTU(CT)); 420} 421 422CXString clang_getTypeKindSpelling(enum CXTypeKind K) { 423 const char *s = 0; 424#define TKIND(X) case CXType_##X: s = "" #X ""; break 425 switch (K) { 426 TKIND(Invalid); 427 TKIND(Unexposed); 428 TKIND(Void); 429 TKIND(Bool); 430 TKIND(Char_U); 431 TKIND(UChar); 432 TKIND(Char16); 433 TKIND(Char32); 434 TKIND(UShort); 435 TKIND(UInt); 436 TKIND(ULong); 437 TKIND(ULongLong); 438 TKIND(UInt128); 439 TKIND(Char_S); 440 TKIND(SChar); 441 case CXType_WChar: s = "WChar"; break; 442 TKIND(Short); 443 TKIND(Int); 444 TKIND(Long); 445 TKIND(LongLong); 446 TKIND(Int128); 447 TKIND(Float); 448 TKIND(Double); 449 TKIND(LongDouble); 450 TKIND(NullPtr); 451 TKIND(Overload); 452 TKIND(Dependent); 453 TKIND(ObjCId); 454 TKIND(ObjCClass); 455 TKIND(ObjCSel); 456 TKIND(Complex); 457 TKIND(Pointer); 458 TKIND(BlockPointer); 459 TKIND(LValueReference); 460 TKIND(RValueReference); 461 TKIND(Record); 462 TKIND(Enum); 463 TKIND(Typedef); 464 TKIND(ObjCInterface); 465 TKIND(ObjCObjectPointer); 466 TKIND(FunctionNoProto); 467 TKIND(FunctionProto); 468 TKIND(ConstantArray); 469 TKIND(Vector); 470 } 471#undef TKIND 472 return cxstring::createRef(s); 473} 474 475unsigned clang_equalTypes(CXType A, CXType B) { 476 return A.data[0] == B.data[0] && A.data[1] == B.data[1];; 477} 478 479unsigned clang_isFunctionTypeVariadic(CXType X) { 480 QualType T = GetQualType(X); 481 if (T.isNull()) 482 return 0; 483 484 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) 485 return (unsigned)FD->isVariadic(); 486 487 if (T->getAs<FunctionNoProtoType>()) 488 return 1; 489 490 return 0; 491} 492 493CXCallingConv clang_getFunctionTypeCallingConv(CXType X) { 494 QualType T = GetQualType(X); 495 if (T.isNull()) 496 return CXCallingConv_Invalid; 497 498 if (const FunctionType *FD = T->getAs<FunctionType>()) { 499#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X 500 switch (FD->getCallConv()) { 501 TCALLINGCONV(Default); 502 TCALLINGCONV(C); 503 TCALLINGCONV(X86StdCall); 504 TCALLINGCONV(X86FastCall); 505 TCALLINGCONV(X86ThisCall); 506 TCALLINGCONV(X86Pascal); 507 TCALLINGCONV(AAPCS); 508 TCALLINGCONV(AAPCS_VFP); 509 TCALLINGCONV(PnaclCall); 510 TCALLINGCONV(IntelOclBicc); 511 } 512#undef TCALLINGCONV 513 } 514 515 return CXCallingConv_Invalid; 516} 517 518int clang_getNumArgTypes(CXType X) { 519 QualType T = GetQualType(X); 520 if (T.isNull()) 521 return -1; 522 523 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 524 return FD->getNumArgs(); 525 } 526 527 if (T->getAs<FunctionNoProtoType>()) { 528 return 0; 529 } 530 531 return -1; 532} 533 534CXType clang_getArgType(CXType X, unsigned i) { 535 QualType T = GetQualType(X); 536 if (T.isNull()) 537 return MakeCXType(QualType(), GetTU(X)); 538 539 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 540 unsigned numArgs = FD->getNumArgs(); 541 if (i >= numArgs) 542 return MakeCXType(QualType(), GetTU(X)); 543 544 return MakeCXType(FD->getArgType(i), GetTU(X)); 545 } 546 547 return MakeCXType(QualType(), GetTU(X)); 548} 549 550CXType clang_getResultType(CXType X) { 551 QualType T = GetQualType(X); 552 if (T.isNull()) 553 return MakeCXType(QualType(), GetTU(X)); 554 555 if (const FunctionType *FD = T->getAs<FunctionType>()) 556 return MakeCXType(FD->getResultType(), GetTU(X)); 557 558 return MakeCXType(QualType(), GetTU(X)); 559} 560 561CXType clang_getCursorResultType(CXCursor C) { 562 if (clang_isDeclaration(C.kind)) { 563 const Decl *D = cxcursor::getCursorDecl(C); 564 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 565 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C)); 566 567 return clang_getResultType(clang_getCursorType(C)); 568 } 569 570 return MakeCXType(QualType(), cxcursor::getCursorTU(C)); 571} 572 573unsigned clang_isPODType(CXType X) { 574 QualType T = GetQualType(X); 575 if (T.isNull()) 576 return 0; 577 578 CXTranslationUnit TU = GetTU(X); 579 580 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0; 581} 582 583CXType clang_getElementType(CXType CT) { 584 QualType ET = QualType(); 585 QualType T = GetQualType(CT); 586 const Type *TP = T.getTypePtrOrNull(); 587 588 if (TP) { 589 switch (TP->getTypeClass()) { 590 case Type::ConstantArray: 591 ET = cast<ConstantArrayType> (TP)->getElementType(); 592 break; 593 case Type::Vector: 594 ET = cast<VectorType> (TP)->getElementType(); 595 break; 596 case Type::Complex: 597 ET = cast<ComplexType> (TP)->getElementType(); 598 break; 599 default: 600 break; 601 } 602 } 603 return MakeCXType(ET, GetTU(CT)); 604} 605 606long long clang_getNumElements(CXType CT) { 607 long long result = -1; 608 QualType T = GetQualType(CT); 609 const Type *TP = T.getTypePtrOrNull(); 610 611 if (TP) { 612 switch (TP->getTypeClass()) { 613 case Type::ConstantArray: 614 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 615 break; 616 case Type::Vector: 617 result = cast<VectorType> (TP)->getNumElements(); 618 break; 619 default: 620 break; 621 } 622 } 623 return result; 624} 625 626CXType clang_getArrayElementType(CXType CT) { 627 QualType ET = QualType(); 628 QualType T = GetQualType(CT); 629 const Type *TP = T.getTypePtrOrNull(); 630 631 if (TP) { 632 switch (TP->getTypeClass()) { 633 case Type::ConstantArray: 634 ET = cast<ConstantArrayType> (TP)->getElementType(); 635 break; 636 default: 637 break; 638 } 639 } 640 return MakeCXType(ET, GetTU(CT)); 641} 642 643long long clang_getArraySize(CXType CT) { 644 long long result = -1; 645 QualType T = GetQualType(CT); 646 const Type *TP = T.getTypePtrOrNull(); 647 648 if (TP) { 649 switch (TP->getTypeClass()) { 650 case Type::ConstantArray: 651 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 652 break; 653 default: 654 break; 655 } 656 } 657 return result; 658} 659 660long long clang_Type_getAlignOf(CXType T) { 661 if (T.kind == CXType_Invalid) 662 return CXTypeLayoutError_Invalid; 663 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext(); 664 QualType QT = GetQualType(T); 665 // [expr.alignof] p1: return size_t value for complete object type, reference 666 // or array. 667 // [expr.alignof] p3: if reference type, return size of referenced type 668 if (QT->isReferenceType()) 669 QT = QT.getNonReferenceType(); 670 if (QT->isIncompleteType()) 671 return CXTypeLayoutError_Incomplete; 672 if (QT->isDependentType()) 673 return CXTypeLayoutError_Dependent; 674 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl 675 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1 676 // if (QT->isVoidType()) return 1; 677 return Ctx.getTypeAlignInChars(QT).getQuantity(); 678} 679 680long long clang_Type_getSizeOf(CXType T) { 681 if (T.kind == CXType_Invalid) 682 return CXTypeLayoutError_Invalid; 683 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext(); 684 QualType QT = GetQualType(T); 685 // [expr.sizeof] p2: if reference type, return size of referenced type 686 if (QT->isReferenceType()) 687 QT = QT.getNonReferenceType(); 688 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete 689 // enumeration 690 // Note: We get the cxtype, not the cxcursor, so we can't call 691 // FieldDecl->isBitField() 692 // [expr.sizeof] p3: pointer ok, function not ok. 693 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error 694 if (QT->isIncompleteType()) 695 return CXTypeLayoutError_Incomplete; 696 if (QT->isDependentType()) 697 return CXTypeLayoutError_Dependent; 698 if (!QT->isConstantSizeType()) 699 return CXTypeLayoutError_NotConstantSize; 700 // [gcc extension] lib/AST/ExprConstant.cpp:1372 701 // HandleSizeof : {voidtype,functype} == 1 702 // not handled by ASTContext.cpp:1313 getTypeInfoImpl 703 if (QT->isVoidType() || QT->isFunctionType()) 704 return 1; 705 return Ctx.getTypeSizeInChars(QT).getQuantity(); 706} 707 708static long long visitRecordForValidation(const RecordDecl *RD) { 709 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 710 I != E; ++I){ 711 QualType FQT = (*I)->getType(); 712 if (FQT->isIncompleteType()) 713 return CXTypeLayoutError_Incomplete; 714 if (FQT->isDependentType()) 715 return CXTypeLayoutError_Dependent; 716 // recurse 717 if (const RecordType *ChildType = (*I)->getType()->getAs<RecordType>()) { 718 if (const RecordDecl *Child = ChildType->getDecl()) { 719 long long ret = visitRecordForValidation(Child); 720 if (ret < 0) 721 return ret; 722 } 723 } 724 // else try next field 725 } 726 return 0; 727} 728 729long long clang_Type_getOffsetOf(CXType PT, const char *S) { 730 // check that PT is not incomplete/dependent 731 CXCursor PC = clang_getTypeDeclaration(PT); 732 if (clang_isInvalid(PC.kind)) 733 return CXTypeLayoutError_Invalid; 734 const RecordDecl *RD = 735 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC)); 736 if (!RD || RD->isInvalidDecl()) 737 return CXTypeLayoutError_Invalid; 738 RD = RD->getDefinition(); 739 if (!RD) 740 return CXTypeLayoutError_Incomplete; 741 if (RD->isInvalidDecl()) 742 return CXTypeLayoutError_Invalid; 743 QualType RT = GetQualType(PT); 744 if (RT->isIncompleteType()) 745 return CXTypeLayoutError_Incomplete; 746 if (RT->isDependentType()) 747 return CXTypeLayoutError_Dependent; 748 // We recurse into all record fields to detect incomplete and dependent types. 749 long long Error = visitRecordForValidation(RD); 750 if (Error < 0) 751 return Error; 752 if (!S) 753 return CXTypeLayoutError_InvalidFieldName; 754 // lookup field 755 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext(); 756 IdentifierInfo *II = &Ctx.Idents.get(S); 757 DeclarationName FieldName(II); 758 RecordDecl::lookup_const_result Res = RD->lookup(FieldName); 759 // If a field of the parent record is incomplete, lookup will fail. 760 // and we would return InvalidFieldName instead of Incomplete. 761 // But this erroneous results does protects again a hidden assertion failure 762 // in the RecordLayoutBuilder 763 if (Res.size() != 1) 764 return CXTypeLayoutError_InvalidFieldName; 765 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front())) 766 return Ctx.getFieldOffset(FD); 767 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front())) 768 return Ctx.getFieldOffset(IFD); 769 // we don't want any other Decl Type. 770 return CXTypeLayoutError_InvalidFieldName; 771} 772 773unsigned clang_Cursor_isBitField(CXCursor C) { 774 if (!clang_isDeclaration(C.kind)) 775 return 0; 776 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C)); 777 if (!FD) 778 return 0; 779 return FD->isBitField(); 780} 781 782CXString clang_getDeclObjCTypeEncoding(CXCursor C) { 783 if (!clang_isDeclaration(C.kind)) 784 return cxstring::createEmpty(); 785 786 const Decl *D = cxcursor::getCursorDecl(C); 787 ASTContext &Ctx = cxcursor::getCursorContext(C); 788 std::string encoding; 789 790 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) { 791 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding)) 792 return cxstring::createRef("?"); 793 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 794 Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding); 795 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 796 Ctx.getObjCEncodingForFunctionDecl(FD, encoding); 797 else { 798 QualType Ty; 799 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 800 Ty = Ctx.getTypeDeclType(TD); 801 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 802 Ty = VD->getType(); 803 else return cxstring::createRef("?"); 804 Ctx.getObjCEncodingForType(Ty, encoding); 805 } 806 807 return cxstring::createDup(encoding); 808} 809 810} // end: extern "C" 811