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