xref: /openbsd/gnu/llvm/clang/tools/libclang/CXType.cpp (revision 12c85518)
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 
27 using namespace clang;
28 
GetBuiltinTypeKind(const BuiltinType * BT)29 static 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 
GetTypeKind(QualType T)86 static 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 
MakeCXType(QualType T,CXTranslationUnit TU)129 CXType 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 
174 using cxtype::MakeCXType;
175 
GetQualType(CXType CT)176 static inline QualType GetQualType(CXType CT) {
177   return QualType::getFromOpaquePtr(CT.data[0]);
178 }
179 
GetTU(CXType CT)180 static inline CXTranslationUnit GetTU(CXType CT) {
181   return static_cast<CXTranslationUnit>(CT.data[1]);
182 }
183 
184 static std::optional<ArrayRef<TemplateArgument>>
GetTemplateArguments(QualType Type)185 GetTemplateArguments(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 
200 static std::optional<QualType>
TemplateArgumentToQualType(const TemplateArgument & A)201 TemplateArgumentToQualType(const TemplateArgument &A) {
202   if (A.getKind() == TemplateArgument::Type)
203     return A.getAsType();
204   return std::nullopt;
205 }
206 
207 static std::optional<QualType>
FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA,unsigned index)208 FindTemplateArgumentTypeAt(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 
clang_getCursorType(CXCursor C)224 CXType 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 
clang_getTypeSpelling(CXType CT)299 CXString 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 
clang_getTypedefDeclUnderlyingType(CXCursor C)314 CXType 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 
clang_getEnumDeclIntegerType(CXCursor C)332 CXType 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 
clang_getEnumConstantDeclValue(CXCursor C)350 long 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 
clang_getEnumConstantDeclUnsignedValue(CXCursor C)366 unsigned 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 
clang_getFieldDeclBitWidth(CXCursor C)382 int 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 
clang_getCanonicalType(CXType CT)397 CXType 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 
clang_isConstQualifiedType(CXType CT)412 unsigned clang_isConstQualifiedType(CXType CT) {
413   QualType T = GetQualType(CT);
414   return T.isLocalConstQualified();
415 }
416 
clang_isVolatileQualifiedType(CXType CT)417 unsigned clang_isVolatileQualifiedType(CXType CT) {
418   QualType T = GetQualType(CT);
419   return T.isLocalVolatileQualified();
420 }
421 
clang_isRestrictQualifiedType(CXType CT)422 unsigned clang_isRestrictQualifiedType(CXType CT) {
423   QualType T = GetQualType(CT);
424   return T.isLocalRestrictQualified();
425 }
426 
clang_getAddressSpace(CXType CT)427 unsigned 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 
clang_getTypedefName(CXType CT)440 CXString 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 
clang_getPointeeType(CXType CT)451 CXType 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 
458 try_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 
clang_getUnqualifiedType(CXType CT)489 CXType clang_getUnqualifiedType(CXType CT) {
490   return MakeCXType(GetQualType(CT).getUnqualifiedType(), GetTU(CT));
491 }
492 
clang_getNonReferenceType(CXType CT)493 CXType clang_getNonReferenceType(CXType CT) {
494   return MakeCXType(GetQualType(CT).getNonReferenceType(), GetTU(CT));
495 }
496 
clang_getTypeDeclaration(CXType CT)497 CXCursor 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 
509 try_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 
clang_getTypeKindSpelling(enum CXTypeKind K)559 CXString 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 
clang_equalTypes(CXType A,CXType B)645 unsigned clang_equalTypes(CXType A, CXType B) {
646   return A.data[0] == B.data[0] && A.data[1] == B.data[1];
647 }
648 
clang_isFunctionTypeVariadic(CXType X)649 unsigned 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 
clang_getFunctionTypeCallingConv(CXType X)663 CXCallingConv 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 
clang_getNumArgTypes(CXType X)700 int 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 
clang_getArgType(CXType X,unsigned i)716 CXType 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 
clang_getResultType(CXType X)732 CXType 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 
clang_getCursorResultType(CXCursor C)743 CXType 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.
756 static CXCursor_ExceptionSpecificationKind
getExternalExceptionSpecificationKind(ExceptionSpecificationType EST)757 getExternalExceptionSpecificationKind(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 
clang_getExceptionSpecificationType(CXType X)785 int 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 
clang_getCursorExceptionSpecificationType(CXCursor C)796 int clang_getCursorExceptionSpecificationType(CXCursor C) {
797   if (clang_isDeclaration(C.kind))
798     return clang_getExceptionSpecificationType(clang_getCursorType(C));
799 
800   return -1;
801 }
802 
clang_isPODType(CXType X)803 unsigned 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 
clang_getElementType(CXType CT)813 CXType 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 
clang_getNumElements(CXType CT)848 long 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 
clang_getArrayElementType(CXType CT)871 CXType 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 
clang_getArraySize(CXType CT)897 long 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 
isIncompleteTypeWithAlignment(QualType QT)914 static bool isIncompleteTypeWithAlignment(QualType QT) {
915   return QT->isIncompleteArrayType() || !QT->isIncompleteType();
916 }
917 
clang_Type_getAlignOf(CXType T)918 long 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 
clang_Type_getClassType(CXType CT)941 CXType 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 
clang_Type_getSizeOf(CXType T)952 long 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 
isTypeIncompleteForLayout(QualType QT)983 static bool isTypeIncompleteForLayout(QualType QT) {
984   return QT->isIncompleteType() && !QT->isIncompleteArrayType();
985 }
986 
visitRecordForValidation(const RecordDecl * RD)987 static 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 
validateFieldParentType(CXCursor PC,CXType PT)1007 static 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 
clang_Type_getOffsetOf(CXType PT,const char * S)1033 long 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 
clang_Type_getModifiedType(CXType CT)1064 CXType 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 
clang_Cursor_getOffsetOfField(CXCursor C)1078 long 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 
clang_Type_getCXXRefQualifier(CXType T)1097 enum 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 
clang_Cursor_isBitField(CXCursor C)1115 unsigned 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 
clang_getDeclObjCTypeEncoding(CXCursor C)1124 CXString 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 
GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA)1151 static 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 
clang_Type_getNumTemplateArguments(CXType CT)1159 int 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 
clang_Type_getTemplateArgumentAsType(CXType CT,unsigned index)1171 CXType 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 
clang_Type_getObjCObjectBaseType(CXType CT)1184 CXType 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 
clang_Type_getNumObjCProtocolRefs(CXType CT)1196 unsigned 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 
clang_Type_getObjCProtocolDecl(CXType CT,unsigned i)1208 CXCursor 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 
clang_Type_getNumObjCTypeArgs(CXType CT)1224 unsigned 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 
clang_Type_getObjCTypeArg(CXType CT,unsigned i)1236 CXType 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 
clang_Type_visitFields(CXType PT,CXFieldVisitor visitor,CXClientData client_data)1252 unsigned 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 
clang_Cursor_isAnonymous(CXCursor C)1280 unsigned 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 
clang_Cursor_isAnonymousRecordDecl(CXCursor C)1294 unsigned 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 
clang_Cursor_isInlineNamespace(CXCursor C)1303 unsigned 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 
clang_Type_getNamedType(CXType CT)1311 CXType 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 
clang_Type_isTransparentTagTypedef(CXType TT)1321 unsigned 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 
clang_Type_getNullability(CXType CT)1330 enum 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 
clang_Type_getValueType(CXType CT)1350 CXType 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