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