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