1 //===- CXType.cpp - Implements 'CXTypes' aspect of libclang ---------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===--------------------------------------------------------------------===// 8 // 9 // This file implements the 'CXTypes' API hooks in the Clang-C library. 10 // 11 //===--------------------------------------------------------------------===// 12 13 #include "CIndexer.h" 14 #include "CXCursor.h" 15 #include "CXString.h" 16 #include "CXTranslationUnit.h" 17 #include "CXType.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclObjC.h" 20 #include "clang/AST/DeclTemplate.h" 21 #include "clang/AST/Expr.h" 22 #include "clang/AST/Type.h" 23 #include "clang/Basic/AddressSpaces.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(Half); 52 BTCASE(Float); 53 BTCASE(Double); 54 BTCASE(LongDouble); 55 BTCASE(ShortAccum); 56 BTCASE(Accum); 57 BTCASE(LongAccum); 58 BTCASE(UShortAccum); 59 BTCASE(UAccum); 60 BTCASE(ULongAccum); 61 BTCASE(Float16); 62 BTCASE(Float128); 63 BTCASE(NullPtr); 64 BTCASE(Overload); 65 BTCASE(Dependent); 66 BTCASE(ObjCId); 67 BTCASE(ObjCClass); 68 BTCASE(ObjCSel); 69 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id); 70 #include "clang/Basic/OpenCLImageTypes.def" 71 #undef IMAGE_TYPE 72 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id); 73 #include "clang/Basic/OpenCLExtensionTypes.def" 74 BTCASE(OCLSampler); 75 BTCASE(OCLEvent); 76 BTCASE(OCLQueue); 77 BTCASE(OCLReserveID); 78 default: 79 return CXType_Unexposed; 80 } 81 #undef BTCASE 82 } 83 84 static CXTypeKind GetTypeKind(QualType T) { 85 const Type *TP = T.getTypePtrOrNull(); 86 if (!TP) 87 return CXType_Invalid; 88 89 #define TKCASE(K) case Type::K: return CXType_##K 90 switch (TP->getTypeClass()) { 91 case Type::Builtin: 92 return GetBuiltinTypeKind(cast<BuiltinType>(TP)); 93 TKCASE(Complex); 94 TKCASE(Pointer); 95 TKCASE(BlockPointer); 96 TKCASE(LValueReference); 97 TKCASE(RValueReference); 98 TKCASE(Record); 99 TKCASE(Enum); 100 TKCASE(Typedef); 101 TKCASE(ObjCInterface); 102 TKCASE(ObjCObject); 103 TKCASE(ObjCObjectPointer); 104 TKCASE(ObjCTypeParam); 105 TKCASE(FunctionNoProto); 106 TKCASE(FunctionProto); 107 TKCASE(ConstantArray); 108 TKCASE(IncompleteArray); 109 TKCASE(VariableArray); 110 TKCASE(DependentSizedArray); 111 TKCASE(Vector); 112 TKCASE(ExtVector); 113 TKCASE(MemberPointer); 114 TKCASE(Auto); 115 TKCASE(Elaborated); 116 TKCASE(Pipe); 117 TKCASE(Attributed); 118 default: 119 return CXType_Unexposed; 120 } 121 #undef TKCASE 122 } 123 124 125 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { 126 CXTypeKind TK = CXType_Invalid; 127 128 if (TU && !T.isNull()) { 129 // Handle attributed types as the original type 130 if (auto *ATT = T->getAs<AttributedType>()) { 131 if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes)) { 132 // Return the equivalent type which represents the canonically 133 // equivalent type. 134 return MakeCXType(ATT->getEquivalentType(), TU); 135 } 136 } 137 // Handle paren types as the original type 138 if (auto *PTT = T->getAs<ParenType>()) { 139 return MakeCXType(PTT->getInnerType(), TU); 140 } 141 142 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext(); 143 if (Ctx.getLangOpts().ObjC) { 144 QualType UnqualT = T.getUnqualifiedType(); 145 if (Ctx.isObjCIdType(UnqualT)) 146 TK = CXType_ObjCId; 147 else if (Ctx.isObjCClassType(UnqualT)) 148 TK = CXType_ObjCClass; 149 else if (Ctx.isObjCSelType(UnqualT)) 150 TK = CXType_ObjCSel; 151 } 152 153 /* Handle decayed types as the original type */ 154 if (const DecayedType *DT = T->getAs<DecayedType>()) { 155 return MakeCXType(DT->getOriginalType(), TU); 156 } 157 } 158 if (TK == CXType_Invalid) 159 TK = GetTypeKind(T); 160 161 CXType CT = { TK, { TK == CXType_Invalid ? nullptr 162 : T.getAsOpaquePtr(), TU } }; 163 return CT; 164 } 165 166 using cxtype::MakeCXType; 167 168 static inline QualType GetQualType(CXType CT) { 169 return QualType::getFromOpaquePtr(CT.data[0]); 170 } 171 172 static inline CXTranslationUnit GetTU(CXType CT) { 173 return static_cast<CXTranslationUnit>(CT.data[1]); 174 } 175 176 static Optional<ArrayRef<TemplateArgument>> 177 GetTemplateArguments(QualType Type) { 178 assert(!Type.isNull()); 179 if (const auto *Specialization = Type->getAs<TemplateSpecializationType>()) 180 return Specialization->template_arguments(); 181 182 if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) { 183 const auto *TemplateDecl = 184 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl); 185 if (TemplateDecl) 186 return TemplateDecl->getTemplateArgs().asArray(); 187 } 188 189 return None; 190 } 191 192 static Optional<QualType> TemplateArgumentToQualType(const TemplateArgument &A) { 193 if (A.getKind() == TemplateArgument::Type) 194 return A.getAsType(); 195 return None; 196 } 197 198 static Optional<QualType> 199 FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) { 200 unsigned current = 0; 201 for (const auto &A : TA) { 202 if (A.getKind() == TemplateArgument::Pack) { 203 if (index < current + A.pack_size()) 204 return TemplateArgumentToQualType(A.getPackAsArray()[index - current]); 205 current += A.pack_size(); 206 continue; 207 } 208 if (current == index) 209 return TemplateArgumentToQualType(A); 210 current++; 211 } 212 return None; 213 } 214 215 CXType clang_getCursorType(CXCursor C) { 216 using namespace cxcursor; 217 218 CXTranslationUnit TU = cxcursor::getCursorTU(C); 219 if (!TU) 220 return MakeCXType(QualType(), TU); 221 222 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext(); 223 if (clang_isExpression(C.kind)) { 224 QualType T = cxcursor::getCursorExpr(C)->getType(); 225 return MakeCXType(T, TU); 226 } 227 228 if (clang_isDeclaration(C.kind)) { 229 const Decl *D = cxcursor::getCursorDecl(C); 230 if (!D) 231 return MakeCXType(QualType(), TU); 232 233 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 234 return MakeCXType(Context.getTypeDeclType(TD), TU); 235 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) 236 return MakeCXType(Context.getObjCInterfaceType(ID), TU); 237 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) 238 return MakeCXType(DD->getType(), TU); 239 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 240 return MakeCXType(VD->getType(), TU); 241 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 242 return MakeCXType(PD->getType(), TU); 243 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) 244 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU); 245 return MakeCXType(QualType(), TU); 246 } 247 248 if (clang_isReference(C.kind)) { 249 switch (C.kind) { 250 case CXCursor_ObjCSuperClassRef: { 251 QualType T 252 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first); 253 return MakeCXType(T, TU); 254 } 255 256 case CXCursor_ObjCClassRef: { 257 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first); 258 return MakeCXType(T, TU); 259 } 260 261 case CXCursor_TypeRef: { 262 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first); 263 return MakeCXType(T, TU); 264 265 } 266 267 case CXCursor_CXXBaseSpecifier: 268 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU); 269 270 case CXCursor_MemberRef: 271 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU); 272 273 case CXCursor_VariableRef: 274 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU); 275 276 case CXCursor_ObjCProtocolRef: 277 case CXCursor_TemplateRef: 278 case CXCursor_NamespaceRef: 279 case CXCursor_OverloadedDeclRef: 280 default: 281 break; 282 } 283 284 return MakeCXType(QualType(), TU); 285 } 286 287 return MakeCXType(QualType(), TU); 288 } 289 290 CXString clang_getTypeSpelling(CXType CT) { 291 QualType T = GetQualType(CT); 292 if (T.isNull()) 293 return cxstring::createEmpty(); 294 295 CXTranslationUnit TU = GetTU(CT); 296 SmallString<64> Str; 297 llvm::raw_svector_ostream OS(Str); 298 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts()); 299 300 T.print(OS, PP); 301 302 return cxstring::createDup(OS.str()); 303 } 304 305 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) { 306 using namespace cxcursor; 307 CXTranslationUnit TU = cxcursor::getCursorTU(C); 308 309 if (clang_isDeclaration(C.kind)) { 310 const Decl *D = cxcursor::getCursorDecl(C); 311 312 if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) { 313 QualType T = TD->getUnderlyingType(); 314 return MakeCXType(T, TU); 315 } 316 317 return MakeCXType(QualType(), TU); 318 } 319 320 return MakeCXType(QualType(), TU); 321 } 322 323 CXType clang_getEnumDeclIntegerType(CXCursor C) { 324 using namespace cxcursor; 325 CXTranslationUnit TU = cxcursor::getCursorTU(C); 326 327 if (clang_isDeclaration(C.kind)) { 328 const Decl *D = cxcursor::getCursorDecl(C); 329 330 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) { 331 QualType T = TD->getIntegerType(); 332 return MakeCXType(T, TU); 333 } 334 335 return MakeCXType(QualType(), TU); 336 } 337 338 return MakeCXType(QualType(), TU); 339 } 340 341 long long clang_getEnumConstantDeclValue(CXCursor C) { 342 using namespace cxcursor; 343 344 if (clang_isDeclaration(C.kind)) { 345 const Decl *D = cxcursor::getCursorDecl(C); 346 347 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) { 348 return TD->getInitVal().getSExtValue(); 349 } 350 351 return LLONG_MIN; 352 } 353 354 return LLONG_MIN; 355 } 356 357 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) { 358 using namespace cxcursor; 359 360 if (clang_isDeclaration(C.kind)) { 361 const Decl *D = cxcursor::getCursorDecl(C); 362 363 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) { 364 return TD->getInitVal().getZExtValue(); 365 } 366 367 return ULLONG_MAX; 368 } 369 370 return ULLONG_MAX; 371 } 372 373 int clang_getFieldDeclBitWidth(CXCursor C) { 374 using namespace cxcursor; 375 376 if (clang_isDeclaration(C.kind)) { 377 const Decl *D = getCursorDecl(C); 378 379 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) { 380 if (FD->isBitField()) 381 return FD->getBitWidthValue(getCursorContext(C)); 382 } 383 } 384 385 return -1; 386 } 387 388 CXType clang_getCanonicalType(CXType CT) { 389 if (CT.kind == CXType_Invalid) 390 return CT; 391 392 QualType T = GetQualType(CT); 393 CXTranslationUnit TU = GetTU(CT); 394 395 if (T.isNull()) 396 return MakeCXType(QualType(), GetTU(CT)); 397 398 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext() 399 .getCanonicalType(T), 400 TU); 401 } 402 403 unsigned clang_isConstQualifiedType(CXType CT) { 404 QualType T = GetQualType(CT); 405 return T.isLocalConstQualified(); 406 } 407 408 unsigned clang_isVolatileQualifiedType(CXType CT) { 409 QualType T = GetQualType(CT); 410 return T.isLocalVolatileQualified(); 411 } 412 413 unsigned clang_isRestrictQualifiedType(CXType CT) { 414 QualType T = GetQualType(CT); 415 return T.isLocalRestrictQualified(); 416 } 417 418 unsigned clang_getAddressSpace(CXType CT) { 419 QualType T = GetQualType(CT); 420 421 // For non language-specific address space, use separate helper function. 422 if (T.getAddressSpace() >= LangAS::FirstTargetAddressSpace) { 423 return T.getQualifiers().getAddressSpaceAttributePrintValue(); 424 } 425 // FIXME: this function returns either a LangAS or a target AS 426 // Those values can overlap which makes this function rather unpredictable 427 // for any caller 428 return (unsigned)T.getAddressSpace(); 429 } 430 431 CXString clang_getTypedefName(CXType CT) { 432 QualType T = GetQualType(CT); 433 const TypedefType *TT = T->getAs<TypedefType>(); 434 if (TT) { 435 TypedefNameDecl *TD = TT->getDecl(); 436 if (TD) 437 return cxstring::createDup(TD->getNameAsString().c_str()); 438 } 439 return cxstring::createEmpty(); 440 } 441 442 CXType clang_getPointeeType(CXType CT) { 443 QualType T = GetQualType(CT); 444 const Type *TP = T.getTypePtrOrNull(); 445 446 if (!TP) 447 return MakeCXType(QualType(), GetTU(CT)); 448 449 try_again: 450 switch (TP->getTypeClass()) { 451 case Type::Pointer: 452 T = cast<PointerType>(TP)->getPointeeType(); 453 break; 454 case Type::BlockPointer: 455 T = cast<BlockPointerType>(TP)->getPointeeType(); 456 break; 457 case Type::LValueReference: 458 case Type::RValueReference: 459 T = cast<ReferenceType>(TP)->getPointeeType(); 460 break; 461 case Type::ObjCObjectPointer: 462 T = cast<ObjCObjectPointerType>(TP)->getPointeeType(); 463 break; 464 case Type::MemberPointer: 465 T = cast<MemberPointerType>(TP)->getPointeeType(); 466 break; 467 case Type::Auto: 468 case Type::DeducedTemplateSpecialization: 469 TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull(); 470 if (TP) 471 goto try_again; 472 break; 473 default: 474 T = QualType(); 475 break; 476 } 477 return MakeCXType(T, GetTU(CT)); 478 } 479 480 CXCursor clang_getTypeDeclaration(CXType CT) { 481 if (CT.kind == CXType_Invalid) 482 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 483 484 QualType T = GetQualType(CT); 485 const Type *TP = T.getTypePtrOrNull(); 486 487 if (!TP) 488 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 489 490 Decl *D = nullptr; 491 492 try_again: 493 switch (TP->getTypeClass()) { 494 case Type::Typedef: 495 D = cast<TypedefType>(TP)->getDecl(); 496 break; 497 case Type::ObjCObject: 498 D = cast<ObjCObjectType>(TP)->getInterface(); 499 break; 500 case Type::ObjCInterface: 501 D = cast<ObjCInterfaceType>(TP)->getDecl(); 502 break; 503 case Type::Record: 504 case Type::Enum: 505 D = cast<TagType>(TP)->getDecl(); 506 break; 507 case Type::TemplateSpecialization: 508 if (const RecordType *Record = TP->getAs<RecordType>()) 509 D = Record->getDecl(); 510 else 511 D = cast<TemplateSpecializationType>(TP)->getTemplateName() 512 .getAsTemplateDecl(); 513 break; 514 515 case Type::Auto: 516 case Type::DeducedTemplateSpecialization: 517 TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull(); 518 if (TP) 519 goto try_again; 520 break; 521 522 case Type::InjectedClassName: 523 D = cast<InjectedClassNameType>(TP)->getDecl(); 524 break; 525 526 // FIXME: Template type parameters! 527 528 case Type::Elaborated: 529 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull(); 530 goto try_again; 531 532 default: 533 break; 534 } 535 536 if (!D) 537 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 538 539 return cxcursor::MakeCXCursor(D, GetTU(CT)); 540 } 541 542 CXString clang_getTypeKindSpelling(enum CXTypeKind K) { 543 const char *s = nullptr; 544 #define TKIND(X) case CXType_##X: s = "" #X ""; break 545 switch (K) { 546 TKIND(Invalid); 547 TKIND(Unexposed); 548 TKIND(Void); 549 TKIND(Bool); 550 TKIND(Char_U); 551 TKIND(UChar); 552 TKIND(Char16); 553 TKIND(Char32); 554 TKIND(UShort); 555 TKIND(UInt); 556 TKIND(ULong); 557 TKIND(ULongLong); 558 TKIND(UInt128); 559 TKIND(Char_S); 560 TKIND(SChar); 561 case CXType_WChar: s = "WChar"; break; 562 TKIND(Short); 563 TKIND(Int); 564 TKIND(Long); 565 TKIND(LongLong); 566 TKIND(Int128); 567 TKIND(Half); 568 TKIND(Float); 569 TKIND(Double); 570 TKIND(LongDouble); 571 TKIND(ShortAccum); 572 TKIND(Accum); 573 TKIND(LongAccum); 574 TKIND(UShortAccum); 575 TKIND(UAccum); 576 TKIND(ULongAccum); 577 TKIND(Float16); 578 TKIND(Float128); 579 TKIND(NullPtr); 580 TKIND(Overload); 581 TKIND(Dependent); 582 TKIND(ObjCId); 583 TKIND(ObjCClass); 584 TKIND(ObjCSel); 585 TKIND(Complex); 586 TKIND(Pointer); 587 TKIND(BlockPointer); 588 TKIND(LValueReference); 589 TKIND(RValueReference); 590 TKIND(Record); 591 TKIND(Enum); 592 TKIND(Typedef); 593 TKIND(ObjCInterface); 594 TKIND(ObjCObject); 595 TKIND(ObjCObjectPointer); 596 TKIND(ObjCTypeParam); 597 TKIND(FunctionNoProto); 598 TKIND(FunctionProto); 599 TKIND(ConstantArray); 600 TKIND(IncompleteArray); 601 TKIND(VariableArray); 602 TKIND(DependentSizedArray); 603 TKIND(Vector); 604 TKIND(ExtVector); 605 TKIND(MemberPointer); 606 TKIND(Auto); 607 TKIND(Elaborated); 608 TKIND(Pipe); 609 TKIND(Attributed); 610 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id); 611 #include "clang/Basic/OpenCLImageTypes.def" 612 #undef IMAGE_TYPE 613 #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id); 614 #include "clang/Basic/OpenCLExtensionTypes.def" 615 TKIND(OCLSampler); 616 TKIND(OCLEvent); 617 TKIND(OCLQueue); 618 TKIND(OCLReserveID); 619 } 620 #undef TKIND 621 return cxstring::createRef(s); 622 } 623 624 unsigned clang_equalTypes(CXType A, CXType B) { 625 return A.data[0] == B.data[0] && A.data[1] == B.data[1]; 626 } 627 628 unsigned clang_isFunctionTypeVariadic(CXType X) { 629 QualType T = GetQualType(X); 630 if (T.isNull()) 631 return 0; 632 633 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) 634 return (unsigned)FD->isVariadic(); 635 636 if (T->getAs<FunctionNoProtoType>()) 637 return 1; 638 639 return 0; 640 } 641 642 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) { 643 QualType T = GetQualType(X); 644 if (T.isNull()) 645 return CXCallingConv_Invalid; 646 647 if (const FunctionType *FD = T->getAs<FunctionType>()) { 648 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X 649 switch (FD->getCallConv()) { 650 TCALLINGCONV(C); 651 TCALLINGCONV(X86StdCall); 652 TCALLINGCONV(X86FastCall); 653 TCALLINGCONV(X86ThisCall); 654 TCALLINGCONV(X86Pascal); 655 TCALLINGCONV(X86RegCall); 656 TCALLINGCONV(X86VectorCall); 657 TCALLINGCONV(AArch64VectorCall); 658 TCALLINGCONV(Win64); 659 TCALLINGCONV(X86_64SysV); 660 TCALLINGCONV(AAPCS); 661 TCALLINGCONV(AAPCS_VFP); 662 TCALLINGCONV(IntelOclBicc); 663 TCALLINGCONV(Swift); 664 TCALLINGCONV(PreserveMost); 665 TCALLINGCONV(PreserveAll); 666 case CC_SpirFunction: return CXCallingConv_Unexposed; 667 case CC_OpenCLKernel: return CXCallingConv_Unexposed; 668 break; 669 } 670 #undef TCALLINGCONV 671 } 672 673 return CXCallingConv_Invalid; 674 } 675 676 int clang_getNumArgTypes(CXType X) { 677 QualType T = GetQualType(X); 678 if (T.isNull()) 679 return -1; 680 681 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 682 return FD->getNumParams(); 683 } 684 685 if (T->getAs<FunctionNoProtoType>()) { 686 return 0; 687 } 688 689 return -1; 690 } 691 692 CXType clang_getArgType(CXType X, unsigned i) { 693 QualType T = GetQualType(X); 694 if (T.isNull()) 695 return MakeCXType(QualType(), GetTU(X)); 696 697 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 698 unsigned numParams = FD->getNumParams(); 699 if (i >= numParams) 700 return MakeCXType(QualType(), GetTU(X)); 701 702 return MakeCXType(FD->getParamType(i), GetTU(X)); 703 } 704 705 return MakeCXType(QualType(), GetTU(X)); 706 } 707 708 CXType clang_getResultType(CXType X) { 709 QualType T = GetQualType(X); 710 if (T.isNull()) 711 return MakeCXType(QualType(), GetTU(X)); 712 713 if (const FunctionType *FD = T->getAs<FunctionType>()) 714 return MakeCXType(FD->getReturnType(), GetTU(X)); 715 716 return MakeCXType(QualType(), GetTU(X)); 717 } 718 719 CXType clang_getCursorResultType(CXCursor C) { 720 if (clang_isDeclaration(C.kind)) { 721 const Decl *D = cxcursor::getCursorDecl(C); 722 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 723 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C)); 724 725 return clang_getResultType(clang_getCursorType(C)); 726 } 727 728 return MakeCXType(QualType(), cxcursor::getCursorTU(C)); 729 } 730 731 // FIXME: We should expose the canThrow(...) result instead of the EST. 732 static CXCursor_ExceptionSpecificationKind 733 getExternalExceptionSpecificationKind(ExceptionSpecificationType EST) { 734 switch (EST) { 735 case EST_None: 736 return CXCursor_ExceptionSpecificationKind_None; 737 case EST_DynamicNone: 738 return CXCursor_ExceptionSpecificationKind_DynamicNone; 739 case EST_Dynamic: 740 return CXCursor_ExceptionSpecificationKind_Dynamic; 741 case EST_MSAny: 742 return CXCursor_ExceptionSpecificationKind_MSAny; 743 case EST_BasicNoexcept: 744 return CXCursor_ExceptionSpecificationKind_BasicNoexcept; 745 case EST_NoThrow: 746 return CXCursor_ExceptionSpecificationKind_NoThrow; 747 case EST_NoexceptFalse: 748 case EST_NoexceptTrue: 749 case EST_DependentNoexcept: 750 return CXCursor_ExceptionSpecificationKind_ComputedNoexcept; 751 case EST_Unevaluated: 752 return CXCursor_ExceptionSpecificationKind_Unevaluated; 753 case EST_Uninstantiated: 754 return CXCursor_ExceptionSpecificationKind_Uninstantiated; 755 case EST_Unparsed: 756 return CXCursor_ExceptionSpecificationKind_Unparsed; 757 } 758 llvm_unreachable("invalid EST value"); 759 } 760 761 int clang_getExceptionSpecificationType(CXType X) { 762 QualType T = GetQualType(X); 763 if (T.isNull()) 764 return -1; 765 766 if (const auto *FD = T->getAs<FunctionProtoType>()) 767 return getExternalExceptionSpecificationKind(FD->getExceptionSpecType()); 768 769 return -1; 770 } 771 772 int clang_getCursorExceptionSpecificationType(CXCursor C) { 773 if (clang_isDeclaration(C.kind)) 774 return clang_getExceptionSpecificationType(clang_getCursorType(C)); 775 776 return -1; 777 } 778 779 unsigned clang_isPODType(CXType X) { 780 QualType T = GetQualType(X); 781 if (T.isNull()) 782 return 0; 783 784 CXTranslationUnit TU = GetTU(X); 785 786 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0; 787 } 788 789 CXType clang_getElementType(CXType CT) { 790 QualType ET = QualType(); 791 QualType T = GetQualType(CT); 792 const Type *TP = T.getTypePtrOrNull(); 793 794 if (TP) { 795 switch (TP->getTypeClass()) { 796 case Type::ConstantArray: 797 ET = cast<ConstantArrayType> (TP)->getElementType(); 798 break; 799 case Type::IncompleteArray: 800 ET = cast<IncompleteArrayType> (TP)->getElementType(); 801 break; 802 case Type::VariableArray: 803 ET = cast<VariableArrayType> (TP)->getElementType(); 804 break; 805 case Type::DependentSizedArray: 806 ET = cast<DependentSizedArrayType> (TP)->getElementType(); 807 break; 808 case Type::Vector: 809 ET = cast<VectorType> (TP)->getElementType(); 810 break; 811 case Type::ExtVector: 812 ET = cast<ExtVectorType>(TP)->getElementType(); 813 break; 814 case Type::Complex: 815 ET = cast<ComplexType> (TP)->getElementType(); 816 break; 817 default: 818 break; 819 } 820 } 821 return MakeCXType(ET, GetTU(CT)); 822 } 823 824 long long clang_getNumElements(CXType CT) { 825 long long result = -1; 826 QualType T = GetQualType(CT); 827 const Type *TP = T.getTypePtrOrNull(); 828 829 if (TP) { 830 switch (TP->getTypeClass()) { 831 case Type::ConstantArray: 832 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 833 break; 834 case Type::Vector: 835 result = cast<VectorType> (TP)->getNumElements(); 836 break; 837 case Type::ExtVector: 838 result = cast<ExtVectorType>(TP)->getNumElements(); 839 break; 840 default: 841 break; 842 } 843 } 844 return result; 845 } 846 847 CXType clang_getArrayElementType(CXType CT) { 848 QualType ET = QualType(); 849 QualType T = GetQualType(CT); 850 const Type *TP = T.getTypePtrOrNull(); 851 852 if (TP) { 853 switch (TP->getTypeClass()) { 854 case Type::ConstantArray: 855 ET = cast<ConstantArrayType> (TP)->getElementType(); 856 break; 857 case Type::IncompleteArray: 858 ET = cast<IncompleteArrayType> (TP)->getElementType(); 859 break; 860 case Type::VariableArray: 861 ET = cast<VariableArrayType> (TP)->getElementType(); 862 break; 863 case Type::DependentSizedArray: 864 ET = cast<DependentSizedArrayType> (TP)->getElementType(); 865 break; 866 default: 867 break; 868 } 869 } 870 return MakeCXType(ET, GetTU(CT)); 871 } 872 873 long long clang_getArraySize(CXType CT) { 874 long long result = -1; 875 QualType T = GetQualType(CT); 876 const Type *TP = T.getTypePtrOrNull(); 877 878 if (TP) { 879 switch (TP->getTypeClass()) { 880 case Type::ConstantArray: 881 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 882 break; 883 default: 884 break; 885 } 886 } 887 return result; 888 } 889 890 static bool isIncompleteTypeWithAlignment(QualType QT) { 891 return QT->isIncompleteArrayType() || !QT->isIncompleteType(); 892 } 893 894 long long clang_Type_getAlignOf(CXType T) { 895 if (T.kind == CXType_Invalid) 896 return CXTypeLayoutError_Invalid; 897 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext(); 898 QualType QT = GetQualType(T); 899 // [expr.alignof] p1: return size_t value for complete object type, reference 900 // or array. 901 // [expr.alignof] p3: if reference type, return size of referenced type 902 if (QT->isReferenceType()) 903 QT = QT.getNonReferenceType(); 904 if (!isIncompleteTypeWithAlignment(QT)) 905 return CXTypeLayoutError_Incomplete; 906 if (QT->isDependentType()) 907 return CXTypeLayoutError_Dependent; 908 if (const auto *Deduced = dyn_cast<DeducedType>(QT)) 909 if (Deduced->getDeducedType().isNull()) 910 return CXTypeLayoutError_Undeduced; 911 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl 912 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1 913 // if (QT->isVoidType()) return 1; 914 return Ctx.getTypeAlignInChars(QT).getQuantity(); 915 } 916 917 CXType clang_Type_getClassType(CXType CT) { 918 QualType ET = QualType(); 919 QualType T = GetQualType(CT); 920 const Type *TP = T.getTypePtrOrNull(); 921 922 if (TP && TP->getTypeClass() == Type::MemberPointer) { 923 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0); 924 } 925 return MakeCXType(ET, GetTU(CT)); 926 } 927 928 long long clang_Type_getSizeOf(CXType T) { 929 if (T.kind == CXType_Invalid) 930 return CXTypeLayoutError_Invalid; 931 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext(); 932 QualType QT = GetQualType(T); 933 // [expr.sizeof] p2: if reference type, return size of referenced type 934 if (QT->isReferenceType()) 935 QT = QT.getNonReferenceType(); 936 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete 937 // enumeration 938 // Note: We get the cxtype, not the cxcursor, so we can't call 939 // FieldDecl->isBitField() 940 // [expr.sizeof] p3: pointer ok, function not ok. 941 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error 942 if (QT->isIncompleteType()) 943 return CXTypeLayoutError_Incomplete; 944 if (QT->isDependentType()) 945 return CXTypeLayoutError_Dependent; 946 if (!QT->isConstantSizeType()) 947 return CXTypeLayoutError_NotConstantSize; 948 if (const auto *Deduced = dyn_cast<DeducedType>(QT)) 949 if (Deduced->getDeducedType().isNull()) 950 return CXTypeLayoutError_Undeduced; 951 // [gcc extension] lib/AST/ExprConstant.cpp:1372 952 // HandleSizeof : {voidtype,functype} == 1 953 // not handled by ASTContext.cpp:1313 getTypeInfoImpl 954 if (QT->isVoidType() || QT->isFunctionType()) 955 return 1; 956 return Ctx.getTypeSizeInChars(QT).getQuantity(); 957 } 958 959 static bool isTypeIncompleteForLayout(QualType QT) { 960 return QT->isIncompleteType() && !QT->isIncompleteArrayType(); 961 } 962 963 static long long visitRecordForValidation(const RecordDecl *RD) { 964 for (const auto *I : RD->fields()){ 965 QualType FQT = I->getType(); 966 if (isTypeIncompleteForLayout(FQT)) 967 return CXTypeLayoutError_Incomplete; 968 if (FQT->isDependentType()) 969 return CXTypeLayoutError_Dependent; 970 // recurse 971 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) { 972 if (const RecordDecl *Child = ChildType->getDecl()) { 973 long long ret = visitRecordForValidation(Child); 974 if (ret < 0) 975 return ret; 976 } 977 } 978 // else try next field 979 } 980 return 0; 981 } 982 983 static long long validateFieldParentType(CXCursor PC, CXType PT){ 984 if (clang_isInvalid(PC.kind)) 985 return CXTypeLayoutError_Invalid; 986 const RecordDecl *RD = 987 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC)); 988 // validate parent declaration 989 if (!RD || RD->isInvalidDecl()) 990 return CXTypeLayoutError_Invalid; 991 RD = RD->getDefinition(); 992 if (!RD) 993 return CXTypeLayoutError_Incomplete; 994 if (RD->isInvalidDecl()) 995 return CXTypeLayoutError_Invalid; 996 // validate parent type 997 QualType RT = GetQualType(PT); 998 if (RT->isIncompleteType()) 999 return CXTypeLayoutError_Incomplete; 1000 if (RT->isDependentType()) 1001 return CXTypeLayoutError_Dependent; 1002 // We recurse into all record fields to detect incomplete and dependent types. 1003 long long Error = visitRecordForValidation(RD); 1004 if (Error < 0) 1005 return Error; 1006 return 0; 1007 } 1008 1009 long long clang_Type_getOffsetOf(CXType PT, const char *S) { 1010 // check that PT is not incomplete/dependent 1011 CXCursor PC = clang_getTypeDeclaration(PT); 1012 long long Error = validateFieldParentType(PC,PT); 1013 if (Error < 0) 1014 return Error; 1015 if (!S) 1016 return CXTypeLayoutError_InvalidFieldName; 1017 // lookup field 1018 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext(); 1019 IdentifierInfo *II = &Ctx.Idents.get(S); 1020 DeclarationName FieldName(II); 1021 const RecordDecl *RD = 1022 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC)); 1023 // verified in validateFieldParentType 1024 RD = RD->getDefinition(); 1025 RecordDecl::lookup_result Res = RD->lookup(FieldName); 1026 // If a field of the parent record is incomplete, lookup will fail. 1027 // and we would return InvalidFieldName instead of Incomplete. 1028 // But this erroneous results does protects again a hidden assertion failure 1029 // in the RecordLayoutBuilder 1030 if (Res.size() != 1) 1031 return CXTypeLayoutError_InvalidFieldName; 1032 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front())) 1033 return Ctx.getFieldOffset(FD); 1034 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front())) 1035 return Ctx.getFieldOffset(IFD); 1036 // we don't want any other Decl Type. 1037 return CXTypeLayoutError_InvalidFieldName; 1038 } 1039 1040 CXType clang_Type_getModifiedType(CXType CT) { 1041 QualType T = GetQualType(CT); 1042 if (T.isNull()) 1043 return MakeCXType(QualType(), GetTU(CT)); 1044 1045 if (auto *ATT = T->getAs<AttributedType>()) 1046 return MakeCXType(ATT->getModifiedType(), GetTU(CT)); 1047 1048 return MakeCXType(QualType(), GetTU(CT)); 1049 } 1050 1051 long long clang_Cursor_getOffsetOfField(CXCursor C) { 1052 if (clang_isDeclaration(C.kind)) { 1053 // we need to validate the parent type 1054 CXCursor PC = clang_getCursorSemanticParent(C); 1055 CXType PT = clang_getCursorType(PC); 1056 long long Error = validateFieldParentType(PC,PT); 1057 if (Error < 0) 1058 return Error; 1059 // proceed with the offset calculation 1060 const Decl *D = cxcursor::getCursorDecl(C); 1061 ASTContext &Ctx = cxcursor::getCursorContext(C); 1062 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) 1063 return Ctx.getFieldOffset(FD); 1064 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D)) 1065 return Ctx.getFieldOffset(IFD); 1066 } 1067 return -1; 1068 } 1069 1070 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) { 1071 QualType QT = GetQualType(T); 1072 if (QT.isNull()) 1073 return CXRefQualifier_None; 1074 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>(); 1075 if (!FD) 1076 return CXRefQualifier_None; 1077 switch (FD->getRefQualifier()) { 1078 case RQ_None: 1079 return CXRefQualifier_None; 1080 case RQ_LValue: 1081 return CXRefQualifier_LValue; 1082 case RQ_RValue: 1083 return CXRefQualifier_RValue; 1084 } 1085 return CXRefQualifier_None; 1086 } 1087 1088 unsigned clang_Cursor_isBitField(CXCursor C) { 1089 if (!clang_isDeclaration(C.kind)) 1090 return 0; 1091 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C)); 1092 if (!FD) 1093 return 0; 1094 return FD->isBitField(); 1095 } 1096 1097 CXString clang_getDeclObjCTypeEncoding(CXCursor C) { 1098 if (!clang_isDeclaration(C.kind)) 1099 return cxstring::createEmpty(); 1100 1101 const Decl *D = cxcursor::getCursorDecl(C); 1102 ASTContext &Ctx = cxcursor::getCursorContext(C); 1103 std::string encoding; 1104 1105 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) { 1106 encoding = Ctx.getObjCEncodingForMethodDecl(OMD); 1107 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 1108 encoding = Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr); 1109 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 1110 encoding = Ctx.getObjCEncodingForFunctionDecl(FD); 1111 else { 1112 QualType Ty; 1113 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 1114 Ty = Ctx.getTypeDeclType(TD); 1115 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1116 Ty = VD->getType(); 1117 else return cxstring::createRef("?"); 1118 Ctx.getObjCEncodingForType(Ty, encoding); 1119 } 1120 1121 return cxstring::createDup(encoding); 1122 } 1123 1124 static unsigned GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA) { 1125 unsigned size = TA.size(); 1126 for (const auto &Arg : TA) 1127 if (Arg.getKind() == TemplateArgument::Pack) 1128 size += Arg.pack_size() - 1; 1129 return size; 1130 } 1131 1132 int clang_Type_getNumTemplateArguments(CXType CT) { 1133 QualType T = GetQualType(CT); 1134 if (T.isNull()) 1135 return -1; 1136 1137 auto TA = GetTemplateArguments(T); 1138 if (!TA) 1139 return -1; 1140 1141 return GetTemplateArgumentArraySize(TA.getValue()); 1142 } 1143 1144 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) { 1145 QualType T = GetQualType(CT); 1146 if (T.isNull()) 1147 return MakeCXType(QualType(), GetTU(CT)); 1148 1149 auto TA = GetTemplateArguments(T); 1150 if (!TA) 1151 return MakeCXType(QualType(), GetTU(CT)); 1152 1153 Optional<QualType> QT = FindTemplateArgumentTypeAt(TA.getValue(), index); 1154 return MakeCXType(QT.getValueOr(QualType()), GetTU(CT)); 1155 } 1156 1157 CXType clang_Type_getObjCObjectBaseType(CXType CT) { 1158 QualType T = GetQualType(CT); 1159 if (T.isNull()) 1160 return MakeCXType(QualType(), GetTU(CT)); 1161 1162 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); 1163 if (!OT) 1164 return MakeCXType(QualType(), GetTU(CT)); 1165 1166 return MakeCXType(OT->getBaseType(), GetTU(CT)); 1167 } 1168 1169 unsigned clang_Type_getNumObjCProtocolRefs(CXType CT) { 1170 QualType T = GetQualType(CT); 1171 if (T.isNull()) 1172 return 0; 1173 1174 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); 1175 if (!OT) 1176 return 0; 1177 1178 return OT->getNumProtocols(); 1179 } 1180 1181 CXCursor clang_Type_getObjCProtocolDecl(CXType CT, unsigned i) { 1182 QualType T = GetQualType(CT); 1183 if (T.isNull()) 1184 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 1185 1186 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); 1187 if (!OT) 1188 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 1189 1190 const ObjCProtocolDecl *PD = OT->getProtocol(i); 1191 if (!PD) 1192 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 1193 1194 return cxcursor::MakeCXCursor(PD, GetTU(CT)); 1195 } 1196 1197 unsigned clang_Type_getNumObjCTypeArgs(CXType CT) { 1198 QualType T = GetQualType(CT); 1199 if (T.isNull()) 1200 return 0; 1201 1202 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); 1203 if (!OT) 1204 return 0; 1205 1206 return OT->getTypeArgs().size(); 1207 } 1208 1209 CXType clang_Type_getObjCTypeArg(CXType CT, unsigned i) { 1210 QualType T = GetQualType(CT); 1211 if (T.isNull()) 1212 return MakeCXType(QualType(), GetTU(CT)); 1213 1214 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); 1215 if (!OT) 1216 return MakeCXType(QualType(), GetTU(CT)); 1217 1218 const ArrayRef<QualType> TA = OT->getTypeArgs(); 1219 if ((size_t)i >= TA.size()) 1220 return MakeCXType(QualType(), GetTU(CT)); 1221 1222 return MakeCXType(TA[i], GetTU(CT)); 1223 } 1224 1225 unsigned clang_Type_visitFields(CXType PT, 1226 CXFieldVisitor visitor, 1227 CXClientData client_data){ 1228 CXCursor PC = clang_getTypeDeclaration(PT); 1229 if (clang_isInvalid(PC.kind)) 1230 return false; 1231 const RecordDecl *RD = 1232 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC)); 1233 if (!RD || RD->isInvalidDecl()) 1234 return false; 1235 RD = RD->getDefinition(); 1236 if (!RD || RD->isInvalidDecl()) 1237 return false; 1238 1239 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 1240 I != E; ++I){ 1241 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I)); 1242 // Callback to the client. 1243 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){ 1244 case CXVisit_Break: 1245 return true; 1246 case CXVisit_Continue: 1247 break; 1248 } 1249 } 1250 return true; 1251 } 1252 1253 unsigned clang_Cursor_isAnonymous(CXCursor C){ 1254 if (!clang_isDeclaration(C.kind)) 1255 return 0; 1256 const Decl *D = cxcursor::getCursorDecl(C); 1257 if (const NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(D)) { 1258 return ND->isAnonymousNamespace(); 1259 } else if (const TagDecl *TD = dyn_cast_or_null<TagDecl>(D)) { 1260 return TD->getTypedefNameForAnonDecl() == nullptr && 1261 TD->getIdentifier() == nullptr; 1262 } 1263 1264 return 0; 1265 } 1266 1267 unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C){ 1268 if (!clang_isDeclaration(C.kind)) 1269 return 0; 1270 const Decl *D = cxcursor::getCursorDecl(C); 1271 if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D)) 1272 return FD->isAnonymousStructOrUnion(); 1273 return 0; 1274 } 1275 1276 unsigned clang_Cursor_isInlineNamespace(CXCursor C) { 1277 if (!clang_isDeclaration(C.kind)) 1278 return 0; 1279 const Decl *D = cxcursor::getCursorDecl(C); 1280 const NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(D); 1281 return ND ? ND->isInline() : 0; 1282 } 1283 1284 CXType clang_Type_getNamedType(CXType CT){ 1285 QualType T = GetQualType(CT); 1286 const Type *TP = T.getTypePtrOrNull(); 1287 1288 if (TP && TP->getTypeClass() == Type::Elaborated) 1289 return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT)); 1290 1291 return MakeCXType(QualType(), GetTU(CT)); 1292 } 1293 1294 unsigned clang_Type_isTransparentTagTypedef(CXType TT){ 1295 QualType T = GetQualType(TT); 1296 if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) { 1297 if (auto *D = TT->getDecl()) 1298 return D->isTransparentTag(); 1299 } 1300 return false; 1301 } 1302 1303 enum CXTypeNullabilityKind clang_Type_getNullability(CXType CT) { 1304 QualType T = GetQualType(CT); 1305 if (T.isNull()) 1306 return CXTypeNullability_Invalid; 1307 1308 ASTContext &Ctx = cxtu::getASTUnit(GetTU(CT))->getASTContext(); 1309 if (auto nullability = T->getNullability(Ctx)) { 1310 switch (*nullability) { 1311 case NullabilityKind::NonNull: 1312 return CXTypeNullability_NonNull; 1313 case NullabilityKind::Nullable: 1314 return CXTypeNullability_Nullable; 1315 case NullabilityKind::Unspecified: 1316 return CXTypeNullability_Unspecified; 1317 } 1318 } 1319 return CXTypeNullability_Invalid; 1320 } 1321