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