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 TKIND(BFloat16); 612 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id); 613 #include "clang/Basic/OpenCLImageTypes.def" 614 #undef IMAGE_TYPE 615 #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id); 616 #include "clang/Basic/OpenCLExtensionTypes.def" 617 TKIND(OCLSampler); 618 TKIND(OCLEvent); 619 TKIND(OCLQueue); 620 TKIND(OCLReserveID); 621 TKIND(Atomic); 622 } 623 #undef TKIND 624 return cxstring::createRef(s); 625 } 626 627 unsigned clang_equalTypes(CXType A, CXType B) { 628 return A.data[0] == B.data[0] && A.data[1] == B.data[1]; 629 } 630 631 unsigned clang_isFunctionTypeVariadic(CXType X) { 632 QualType T = GetQualType(X); 633 if (T.isNull()) 634 return 0; 635 636 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) 637 return (unsigned)FD->isVariadic(); 638 639 if (T->getAs<FunctionNoProtoType>()) 640 return 1; 641 642 return 0; 643 } 644 645 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) { 646 QualType T = GetQualType(X); 647 if (T.isNull()) 648 return CXCallingConv_Invalid; 649 650 if (const FunctionType *FD = T->getAs<FunctionType>()) { 651 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X 652 switch (FD->getCallConv()) { 653 TCALLINGCONV(C); 654 TCALLINGCONV(X86StdCall); 655 TCALLINGCONV(X86FastCall); 656 TCALLINGCONV(X86ThisCall); 657 TCALLINGCONV(X86Pascal); 658 TCALLINGCONV(X86RegCall); 659 TCALLINGCONV(X86VectorCall); 660 TCALLINGCONV(AArch64VectorCall); 661 TCALLINGCONV(Win64); 662 TCALLINGCONV(X86_64SysV); 663 TCALLINGCONV(AAPCS); 664 TCALLINGCONV(AAPCS_VFP); 665 TCALLINGCONV(IntelOclBicc); 666 TCALLINGCONV(Swift); 667 TCALLINGCONV(SwiftAsync); 668 TCALLINGCONV(PreserveMost); 669 TCALLINGCONV(PreserveAll); 670 case CC_SpirFunction: return CXCallingConv_Unexposed; 671 case CC_OpenCLKernel: return CXCallingConv_Unexposed; 672 break; 673 } 674 #undef TCALLINGCONV 675 } 676 677 return CXCallingConv_Invalid; 678 } 679 680 int clang_getNumArgTypes(CXType X) { 681 QualType T = GetQualType(X); 682 if (T.isNull()) 683 return -1; 684 685 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 686 return FD->getNumParams(); 687 } 688 689 if (T->getAs<FunctionNoProtoType>()) { 690 return 0; 691 } 692 693 return -1; 694 } 695 696 CXType clang_getArgType(CXType X, unsigned i) { 697 QualType T = GetQualType(X); 698 if (T.isNull()) 699 return MakeCXType(QualType(), GetTU(X)); 700 701 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 702 unsigned numParams = FD->getNumParams(); 703 if (i >= numParams) 704 return MakeCXType(QualType(), GetTU(X)); 705 706 return MakeCXType(FD->getParamType(i), GetTU(X)); 707 } 708 709 return MakeCXType(QualType(), GetTU(X)); 710 } 711 712 CXType clang_getResultType(CXType X) { 713 QualType T = GetQualType(X); 714 if (T.isNull()) 715 return MakeCXType(QualType(), GetTU(X)); 716 717 if (const FunctionType *FD = T->getAs<FunctionType>()) 718 return MakeCXType(FD->getReturnType(), GetTU(X)); 719 720 return MakeCXType(QualType(), GetTU(X)); 721 } 722 723 CXType clang_getCursorResultType(CXCursor C) { 724 if (clang_isDeclaration(C.kind)) { 725 const Decl *D = cxcursor::getCursorDecl(C); 726 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 727 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C)); 728 729 return clang_getResultType(clang_getCursorType(C)); 730 } 731 732 return MakeCXType(QualType(), cxcursor::getCursorTU(C)); 733 } 734 735 // FIXME: We should expose the canThrow(...) result instead of the EST. 736 static CXCursor_ExceptionSpecificationKind 737 getExternalExceptionSpecificationKind(ExceptionSpecificationType EST) { 738 switch (EST) { 739 case EST_None: 740 return CXCursor_ExceptionSpecificationKind_None; 741 case EST_DynamicNone: 742 return CXCursor_ExceptionSpecificationKind_DynamicNone; 743 case EST_Dynamic: 744 return CXCursor_ExceptionSpecificationKind_Dynamic; 745 case EST_MSAny: 746 return CXCursor_ExceptionSpecificationKind_MSAny; 747 case EST_BasicNoexcept: 748 return CXCursor_ExceptionSpecificationKind_BasicNoexcept; 749 case EST_NoThrow: 750 return CXCursor_ExceptionSpecificationKind_NoThrow; 751 case EST_NoexceptFalse: 752 case EST_NoexceptTrue: 753 case EST_DependentNoexcept: 754 return CXCursor_ExceptionSpecificationKind_ComputedNoexcept; 755 case EST_Unevaluated: 756 return CXCursor_ExceptionSpecificationKind_Unevaluated; 757 case EST_Uninstantiated: 758 return CXCursor_ExceptionSpecificationKind_Uninstantiated; 759 case EST_Unparsed: 760 return CXCursor_ExceptionSpecificationKind_Unparsed; 761 } 762 llvm_unreachable("invalid EST value"); 763 } 764 765 int clang_getExceptionSpecificationType(CXType X) { 766 QualType T = GetQualType(X); 767 if (T.isNull()) 768 return -1; 769 770 if (const auto *FD = T->getAs<FunctionProtoType>()) 771 return getExternalExceptionSpecificationKind(FD->getExceptionSpecType()); 772 773 return -1; 774 } 775 776 int clang_getCursorExceptionSpecificationType(CXCursor C) { 777 if (clang_isDeclaration(C.kind)) 778 return clang_getExceptionSpecificationType(clang_getCursorType(C)); 779 780 return -1; 781 } 782 783 unsigned clang_isPODType(CXType X) { 784 QualType T = GetQualType(X); 785 if (T.isNull()) 786 return 0; 787 788 CXTranslationUnit TU = GetTU(X); 789 790 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0; 791 } 792 793 CXType clang_getElementType(CXType CT) { 794 QualType ET = QualType(); 795 QualType T = GetQualType(CT); 796 const Type *TP = T.getTypePtrOrNull(); 797 798 if (TP) { 799 switch (TP->getTypeClass()) { 800 case Type::ConstantArray: 801 ET = cast<ConstantArrayType> (TP)->getElementType(); 802 break; 803 case Type::IncompleteArray: 804 ET = cast<IncompleteArrayType> (TP)->getElementType(); 805 break; 806 case Type::VariableArray: 807 ET = cast<VariableArrayType> (TP)->getElementType(); 808 break; 809 case Type::DependentSizedArray: 810 ET = cast<DependentSizedArrayType> (TP)->getElementType(); 811 break; 812 case Type::Vector: 813 ET = cast<VectorType> (TP)->getElementType(); 814 break; 815 case Type::ExtVector: 816 ET = cast<ExtVectorType>(TP)->getElementType(); 817 break; 818 case Type::Complex: 819 ET = cast<ComplexType> (TP)->getElementType(); 820 break; 821 default: 822 break; 823 } 824 } 825 return MakeCXType(ET, GetTU(CT)); 826 } 827 828 long long clang_getNumElements(CXType CT) { 829 long long result = -1; 830 QualType T = GetQualType(CT); 831 const Type *TP = T.getTypePtrOrNull(); 832 833 if (TP) { 834 switch (TP->getTypeClass()) { 835 case Type::ConstantArray: 836 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 837 break; 838 case Type::Vector: 839 result = cast<VectorType> (TP)->getNumElements(); 840 break; 841 case Type::ExtVector: 842 result = cast<ExtVectorType>(TP)->getNumElements(); 843 break; 844 default: 845 break; 846 } 847 } 848 return result; 849 } 850 851 CXType clang_getArrayElementType(CXType CT) { 852 QualType ET = QualType(); 853 QualType T = GetQualType(CT); 854 const Type *TP = T.getTypePtrOrNull(); 855 856 if (TP) { 857 switch (TP->getTypeClass()) { 858 case Type::ConstantArray: 859 ET = cast<ConstantArrayType> (TP)->getElementType(); 860 break; 861 case Type::IncompleteArray: 862 ET = cast<IncompleteArrayType> (TP)->getElementType(); 863 break; 864 case Type::VariableArray: 865 ET = cast<VariableArrayType> (TP)->getElementType(); 866 break; 867 case Type::DependentSizedArray: 868 ET = cast<DependentSizedArrayType> (TP)->getElementType(); 869 break; 870 default: 871 break; 872 } 873 } 874 return MakeCXType(ET, GetTU(CT)); 875 } 876 877 long long clang_getArraySize(CXType CT) { 878 long long result = -1; 879 QualType T = GetQualType(CT); 880 const Type *TP = T.getTypePtrOrNull(); 881 882 if (TP) { 883 switch (TP->getTypeClass()) { 884 case Type::ConstantArray: 885 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 886 break; 887 default: 888 break; 889 } 890 } 891 return result; 892 } 893 894 static bool isIncompleteTypeWithAlignment(QualType QT) { 895 return QT->isIncompleteArrayType() || !QT->isIncompleteType(); 896 } 897 898 long long clang_Type_getAlignOf(CXType T) { 899 if (T.kind == CXType_Invalid) 900 return CXTypeLayoutError_Invalid; 901 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext(); 902 QualType QT = GetQualType(T); 903 // [expr.alignof] p1: return size_t value for complete object type, reference 904 // or array. 905 // [expr.alignof] p3: if reference type, return size of referenced type 906 if (QT->isReferenceType()) 907 QT = QT.getNonReferenceType(); 908 if (!isIncompleteTypeWithAlignment(QT)) 909 return CXTypeLayoutError_Incomplete; 910 if (QT->isDependentType()) 911 return CXTypeLayoutError_Dependent; 912 if (const auto *Deduced = dyn_cast<DeducedType>(QT)) 913 if (Deduced->getDeducedType().isNull()) 914 return CXTypeLayoutError_Undeduced; 915 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl 916 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1 917 // if (QT->isVoidType()) return 1; 918 return Ctx.getTypeAlignInChars(QT).getQuantity(); 919 } 920 921 CXType clang_Type_getClassType(CXType CT) { 922 QualType ET = QualType(); 923 QualType T = GetQualType(CT); 924 const Type *TP = T.getTypePtrOrNull(); 925 926 if (TP && TP->getTypeClass() == Type::MemberPointer) { 927 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0); 928 } 929 return MakeCXType(ET, GetTU(CT)); 930 } 931 932 long long clang_Type_getSizeOf(CXType T) { 933 if (T.kind == CXType_Invalid) 934 return CXTypeLayoutError_Invalid; 935 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext(); 936 QualType QT = GetQualType(T); 937 // [expr.sizeof] p2: if reference type, return size of referenced type 938 if (QT->isReferenceType()) 939 QT = QT.getNonReferenceType(); 940 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete 941 // enumeration 942 // Note: We get the cxtype, not the cxcursor, so we can't call 943 // FieldDecl->isBitField() 944 // [expr.sizeof] p3: pointer ok, function not ok. 945 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error 946 if (QT->isIncompleteType()) 947 return CXTypeLayoutError_Incomplete; 948 if (QT->isDependentType()) 949 return CXTypeLayoutError_Dependent; 950 if (!QT->isConstantSizeType()) 951 return CXTypeLayoutError_NotConstantSize; 952 if (const auto *Deduced = dyn_cast<DeducedType>(QT)) 953 if (Deduced->getDeducedType().isNull()) 954 return CXTypeLayoutError_Undeduced; 955 // [gcc extension] lib/AST/ExprConstant.cpp:1372 956 // HandleSizeof : {voidtype,functype} == 1 957 // not handled by ASTContext.cpp:1313 getTypeInfoImpl 958 if (QT->isVoidType() || QT->isFunctionType()) 959 return 1; 960 return Ctx.getTypeSizeInChars(QT).getQuantity(); 961 } 962 963 static bool isTypeIncompleteForLayout(QualType QT) { 964 return QT->isIncompleteType() && !QT->isIncompleteArrayType(); 965 } 966 967 static long long visitRecordForValidation(const RecordDecl *RD) { 968 for (const auto *I : RD->fields()){ 969 QualType FQT = I->getType(); 970 if (isTypeIncompleteForLayout(FQT)) 971 return CXTypeLayoutError_Incomplete; 972 if (FQT->isDependentType()) 973 return CXTypeLayoutError_Dependent; 974 // recurse 975 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) { 976 if (const RecordDecl *Child = ChildType->getDecl()) { 977 long long ret = visitRecordForValidation(Child); 978 if (ret < 0) 979 return ret; 980 } 981 } 982 // else try next field 983 } 984 return 0; 985 } 986 987 static long long validateFieldParentType(CXCursor PC, CXType PT){ 988 if (clang_isInvalid(PC.kind)) 989 return CXTypeLayoutError_Invalid; 990 const RecordDecl *RD = 991 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC)); 992 // validate parent declaration 993 if (!RD || RD->isInvalidDecl()) 994 return CXTypeLayoutError_Invalid; 995 RD = RD->getDefinition(); 996 if (!RD) 997 return CXTypeLayoutError_Incomplete; 998 if (RD->isInvalidDecl()) 999 return CXTypeLayoutError_Invalid; 1000 // validate parent type 1001 QualType RT = GetQualType(PT); 1002 if (RT->isIncompleteType()) 1003 return CXTypeLayoutError_Incomplete; 1004 if (RT->isDependentType()) 1005 return CXTypeLayoutError_Dependent; 1006 // We recurse into all record fields to detect incomplete and dependent types. 1007 long long Error = visitRecordForValidation(RD); 1008 if (Error < 0) 1009 return Error; 1010 return 0; 1011 } 1012 1013 long long clang_Type_getOffsetOf(CXType PT, const char *S) { 1014 // check that PT is not incomplete/dependent 1015 CXCursor PC = clang_getTypeDeclaration(PT); 1016 long long Error = validateFieldParentType(PC,PT); 1017 if (Error < 0) 1018 return Error; 1019 if (!S) 1020 return CXTypeLayoutError_InvalidFieldName; 1021 // lookup field 1022 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext(); 1023 IdentifierInfo *II = &Ctx.Idents.get(S); 1024 DeclarationName FieldName(II); 1025 const RecordDecl *RD = 1026 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC)); 1027 // verified in validateFieldParentType 1028 RD = RD->getDefinition(); 1029 RecordDecl::lookup_result Res = RD->lookup(FieldName); 1030 // If a field of the parent record is incomplete, lookup will fail. 1031 // and we would return InvalidFieldName instead of Incomplete. 1032 // But this erroneous results does protects again a hidden assertion failure 1033 // in the RecordLayoutBuilder 1034 if (!Res.isSingleResult()) 1035 return CXTypeLayoutError_InvalidFieldName; 1036 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front())) 1037 return Ctx.getFieldOffset(FD); 1038 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front())) 1039 return Ctx.getFieldOffset(IFD); 1040 // we don't want any other Decl Type. 1041 return CXTypeLayoutError_InvalidFieldName; 1042 } 1043 1044 CXType clang_Type_getModifiedType(CXType CT) { 1045 QualType T = GetQualType(CT); 1046 if (T.isNull()) 1047 return MakeCXType(QualType(), GetTU(CT)); 1048 1049 if (auto *ATT = T->getAs<AttributedType>()) 1050 return MakeCXType(ATT->getModifiedType(), GetTU(CT)); 1051 1052 return MakeCXType(QualType(), GetTU(CT)); 1053 } 1054 1055 long long clang_Cursor_getOffsetOfField(CXCursor C) { 1056 if (clang_isDeclaration(C.kind)) { 1057 // we need to validate the parent type 1058 CXCursor PC = clang_getCursorSemanticParent(C); 1059 CXType PT = clang_getCursorType(PC); 1060 long long Error = validateFieldParentType(PC,PT); 1061 if (Error < 0) 1062 return Error; 1063 // proceed with the offset calculation 1064 const Decl *D = cxcursor::getCursorDecl(C); 1065 ASTContext &Ctx = cxcursor::getCursorContext(C); 1066 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) 1067 return Ctx.getFieldOffset(FD); 1068 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D)) 1069 return Ctx.getFieldOffset(IFD); 1070 } 1071 return -1; 1072 } 1073 1074 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) { 1075 QualType QT = GetQualType(T); 1076 if (QT.isNull()) 1077 return CXRefQualifier_None; 1078 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>(); 1079 if (!FD) 1080 return CXRefQualifier_None; 1081 switch (FD->getRefQualifier()) { 1082 case RQ_None: 1083 return CXRefQualifier_None; 1084 case RQ_LValue: 1085 return CXRefQualifier_LValue; 1086 case RQ_RValue: 1087 return CXRefQualifier_RValue; 1088 } 1089 return CXRefQualifier_None; 1090 } 1091 1092 unsigned clang_Cursor_isBitField(CXCursor C) { 1093 if (!clang_isDeclaration(C.kind)) 1094 return 0; 1095 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C)); 1096 if (!FD) 1097 return 0; 1098 return FD->isBitField(); 1099 } 1100 1101 CXString clang_getDeclObjCTypeEncoding(CXCursor C) { 1102 if (!clang_isDeclaration(C.kind)) 1103 return cxstring::createEmpty(); 1104 1105 const Decl *D = cxcursor::getCursorDecl(C); 1106 ASTContext &Ctx = cxcursor::getCursorContext(C); 1107 std::string encoding; 1108 1109 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) { 1110 encoding = Ctx.getObjCEncodingForMethodDecl(OMD); 1111 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 1112 encoding = Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr); 1113 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 1114 encoding = Ctx.getObjCEncodingForFunctionDecl(FD); 1115 else { 1116 QualType Ty; 1117 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 1118 Ty = Ctx.getTypeDeclType(TD); 1119 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1120 Ty = VD->getType(); 1121 else return cxstring::createRef("?"); 1122 Ctx.getObjCEncodingForType(Ty, encoding); 1123 } 1124 1125 return cxstring::createDup(encoding); 1126 } 1127 1128 static unsigned GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA) { 1129 unsigned size = TA.size(); 1130 for (const auto &Arg : TA) 1131 if (Arg.getKind() == TemplateArgument::Pack) 1132 size += Arg.pack_size() - 1; 1133 return size; 1134 } 1135 1136 int clang_Type_getNumTemplateArguments(CXType CT) { 1137 QualType T = GetQualType(CT); 1138 if (T.isNull()) 1139 return -1; 1140 1141 auto TA = GetTemplateArguments(T); 1142 if (!TA) 1143 return -1; 1144 1145 return GetTemplateArgumentArraySize(TA.getValue()); 1146 } 1147 1148 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) { 1149 QualType T = GetQualType(CT); 1150 if (T.isNull()) 1151 return MakeCXType(QualType(), GetTU(CT)); 1152 1153 auto TA = GetTemplateArguments(T); 1154 if (!TA) 1155 return MakeCXType(QualType(), GetTU(CT)); 1156 1157 Optional<QualType> QT = FindTemplateArgumentTypeAt(TA.getValue(), index); 1158 return MakeCXType(QT.getValueOr(QualType()), GetTU(CT)); 1159 } 1160 1161 CXType clang_Type_getObjCObjectBaseType(CXType CT) { 1162 QualType T = GetQualType(CT); 1163 if (T.isNull()) 1164 return MakeCXType(QualType(), GetTU(CT)); 1165 1166 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); 1167 if (!OT) 1168 return MakeCXType(QualType(), GetTU(CT)); 1169 1170 return MakeCXType(OT->getBaseType(), GetTU(CT)); 1171 } 1172 1173 unsigned clang_Type_getNumObjCProtocolRefs(CXType CT) { 1174 QualType T = GetQualType(CT); 1175 if (T.isNull()) 1176 return 0; 1177 1178 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); 1179 if (!OT) 1180 return 0; 1181 1182 return OT->getNumProtocols(); 1183 } 1184 1185 CXCursor clang_Type_getObjCProtocolDecl(CXType CT, unsigned i) { 1186 QualType T = GetQualType(CT); 1187 if (T.isNull()) 1188 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 1189 1190 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); 1191 if (!OT) 1192 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 1193 1194 const ObjCProtocolDecl *PD = OT->getProtocol(i); 1195 if (!PD) 1196 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 1197 1198 return cxcursor::MakeCXCursor(PD, GetTU(CT)); 1199 } 1200 1201 unsigned clang_Type_getNumObjCTypeArgs(CXType CT) { 1202 QualType T = GetQualType(CT); 1203 if (T.isNull()) 1204 return 0; 1205 1206 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); 1207 if (!OT) 1208 return 0; 1209 1210 return OT->getTypeArgs().size(); 1211 } 1212 1213 CXType clang_Type_getObjCTypeArg(CXType CT, unsigned i) { 1214 QualType T = GetQualType(CT); 1215 if (T.isNull()) 1216 return MakeCXType(QualType(), GetTU(CT)); 1217 1218 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); 1219 if (!OT) 1220 return MakeCXType(QualType(), GetTU(CT)); 1221 1222 const ArrayRef<QualType> TA = OT->getTypeArgs(); 1223 if ((size_t)i >= TA.size()) 1224 return MakeCXType(QualType(), GetTU(CT)); 1225 1226 return MakeCXType(TA[i], GetTU(CT)); 1227 } 1228 1229 unsigned clang_Type_visitFields(CXType PT, 1230 CXFieldVisitor visitor, 1231 CXClientData client_data){ 1232 CXCursor PC = clang_getTypeDeclaration(PT); 1233 if (clang_isInvalid(PC.kind)) 1234 return false; 1235 const RecordDecl *RD = 1236 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC)); 1237 if (!RD || RD->isInvalidDecl()) 1238 return false; 1239 RD = RD->getDefinition(); 1240 if (!RD || RD->isInvalidDecl()) 1241 return false; 1242 1243 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 1244 I != E; ++I){ 1245 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I)); 1246 // Callback to the client. 1247 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){ 1248 case CXVisit_Break: 1249 return true; 1250 case CXVisit_Continue: 1251 break; 1252 } 1253 } 1254 return true; 1255 } 1256 1257 unsigned clang_Cursor_isAnonymous(CXCursor C){ 1258 if (!clang_isDeclaration(C.kind)) 1259 return 0; 1260 const Decl *D = cxcursor::getCursorDecl(C); 1261 if (const NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(D)) { 1262 return ND->isAnonymousNamespace(); 1263 } else if (const TagDecl *TD = dyn_cast_or_null<TagDecl>(D)) { 1264 return TD->getTypedefNameForAnonDecl() == nullptr && 1265 TD->getIdentifier() == nullptr; 1266 } 1267 1268 return 0; 1269 } 1270 1271 unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C){ 1272 if (!clang_isDeclaration(C.kind)) 1273 return 0; 1274 const Decl *D = cxcursor::getCursorDecl(C); 1275 if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D)) 1276 return FD->isAnonymousStructOrUnion(); 1277 return 0; 1278 } 1279 1280 unsigned clang_Cursor_isInlineNamespace(CXCursor C) { 1281 if (!clang_isDeclaration(C.kind)) 1282 return 0; 1283 const Decl *D = cxcursor::getCursorDecl(C); 1284 const NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(D); 1285 return ND ? ND->isInline() : 0; 1286 } 1287 1288 CXType clang_Type_getNamedType(CXType CT){ 1289 QualType T = GetQualType(CT); 1290 const Type *TP = T.getTypePtrOrNull(); 1291 1292 if (TP && TP->getTypeClass() == Type::Elaborated) 1293 return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT)); 1294 1295 return MakeCXType(QualType(), GetTU(CT)); 1296 } 1297 1298 unsigned clang_Type_isTransparentTagTypedef(CXType TT){ 1299 QualType T = GetQualType(TT); 1300 if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) { 1301 if (auto *D = TT->getDecl()) 1302 return D->isTransparentTag(); 1303 } 1304 return false; 1305 } 1306 1307 enum CXTypeNullabilityKind clang_Type_getNullability(CXType CT) { 1308 QualType T = GetQualType(CT); 1309 if (T.isNull()) 1310 return CXTypeNullability_Invalid; 1311 1312 ASTContext &Ctx = cxtu::getASTUnit(GetTU(CT))->getASTContext(); 1313 if (auto nullability = T->getNullability(Ctx)) { 1314 switch (*nullability) { 1315 case NullabilityKind::NonNull: 1316 return CXTypeNullability_NonNull; 1317 case NullabilityKind::Nullable: 1318 return CXTypeNullability_Nullable; 1319 case NullabilityKind::NullableResult: 1320 return CXTypeNullability_NullableResult; 1321 case NullabilityKind::Unspecified: 1322 return CXTypeNullability_Unspecified; 1323 } 1324 } 1325 return CXTypeNullability_Invalid; 1326 } 1327 1328 CXType clang_Type_getValueType(CXType CT) { 1329 QualType T = GetQualType(CT); 1330 1331 if (T.isNull() || !T->isAtomicType()) 1332 return MakeCXType(QualType(), GetTU(CT)); 1333 1334 const auto *AT = T->castAs<AtomicType>(); 1335 return MakeCXType(AT->getValueType(), GetTU(CT)); 1336 } 1337