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