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