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