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