]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/libclang/CXType.cpp
Vendor import of clang trunk r301441:
[FreeBSD/FreeBSD.git] / tools / libclang / CXType.cpp
1 //===- CXTypes.cpp - Implements 'CXTypes' aspect of libclang ------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===--------------------------------------------------------------------===//
9 //
10 // This file implements the 'CXTypes' API hooks in the Clang-C library.
11 //
12 //===--------------------------------------------------------------------===//
13
14 #include "CIndexer.h"
15 #include "CXCursor.h"
16 #include "CXString.h"
17 #include "CXTranslationUnit.h"
18 #include "CXType.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclObjC.h"
21 #include "clang/AST/DeclTemplate.h"
22 #include "clang/AST/Expr.h"
23 #include "clang/AST/Type.h"
24 #include "clang/Frontend/ASTUnit.h"
25
26 using namespace clang;
27
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(Float128);
56     BTCASE(NullPtr);
57     BTCASE(Overload);
58     BTCASE(Dependent);
59     BTCASE(ObjCId);
60     BTCASE(ObjCClass);
61     BTCASE(ObjCSel);
62   default:
63     return CXType_Unexposed;
64   }
65 #undef BTCASE
66 }
67
68 static CXTypeKind GetTypeKind(QualType T) {
69   const Type *TP = T.getTypePtrOrNull();
70   if (!TP)
71     return CXType_Invalid;
72
73 #define TKCASE(K) case Type::K: return CXType_##K
74   switch (TP->getTypeClass()) {
75     case Type::Builtin:
76       return GetBuiltinTypeKind(cast<BuiltinType>(TP));
77     TKCASE(Complex);
78     TKCASE(Pointer);
79     TKCASE(BlockPointer);
80     TKCASE(LValueReference);
81     TKCASE(RValueReference);
82     TKCASE(Record);
83     TKCASE(Enum);
84     TKCASE(Typedef);
85     TKCASE(ObjCInterface);
86     TKCASE(ObjCObjectPointer);
87     TKCASE(FunctionNoProto);
88     TKCASE(FunctionProto);
89     TKCASE(ConstantArray);
90     TKCASE(IncompleteArray);
91     TKCASE(VariableArray);
92     TKCASE(DependentSizedArray);
93     TKCASE(Vector);
94     TKCASE(MemberPointer);
95     TKCASE(Auto);
96     TKCASE(Elaborated);
97     default:
98       return CXType_Unexposed;
99   }
100 #undef TKCASE
101 }
102
103
104 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
105   CXTypeKind TK = CXType_Invalid;
106
107   if (TU && !T.isNull()) {
108     // Handle attributed types as the original type
109     if (auto *ATT = T->getAs<AttributedType>()) {
110       return MakeCXType(ATT->getModifiedType(), TU);
111     }
112
113     ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
114     if (Ctx.getLangOpts().ObjC1) {
115       QualType UnqualT = T.getUnqualifiedType();
116       if (Ctx.isObjCIdType(UnqualT))
117         TK = CXType_ObjCId;
118       else if (Ctx.isObjCClassType(UnqualT))
119         TK = CXType_ObjCClass;
120       else if (Ctx.isObjCSelType(UnqualT))
121         TK = CXType_ObjCSel;
122     }
123
124     /* Handle decayed types as the original type */
125     if (const DecayedType *DT = T->getAs<DecayedType>()) {
126       return MakeCXType(DT->getOriginalType(), TU);
127     }
128   }
129   if (TK == CXType_Invalid)
130     TK = GetTypeKind(T);
131
132   CXType CT = { TK, { TK == CXType_Invalid ? nullptr
133                                            : T.getAsOpaquePtr(), TU } };
134   return CT;
135 }
136
137 using cxtype::MakeCXType;
138
139 static inline QualType GetQualType(CXType CT) {
140   return QualType::getFromOpaquePtr(CT.data[0]);
141 }
142
143 static inline CXTranslationUnit GetTU(CXType CT) {
144   return static_cast<CXTranslationUnit>(CT.data[1]);
145 }
146
147 static Optional<ArrayRef<TemplateArgument>>
148 GetTemplateArguments(QualType Type) {
149   assert(!Type.isNull());
150   if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) {
151     const auto *TemplateDecl =
152       dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
153     if (TemplateDecl)
154       return TemplateDecl->getTemplateArgs().asArray();
155   }
156
157   if (const auto *Specialization = Type->getAs<TemplateSpecializationType>())
158     return Specialization->template_arguments();
159
160   return None;
161 }
162
163 static Optional<QualType> TemplateArgumentToQualType(const TemplateArgument &A) {
164   if (A.getKind() == TemplateArgument::Type)
165     return A.getAsType();
166   return None;
167 }
168
169 static Optional<QualType>
170 FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) {
171   unsigned current = 0;
172   for (const auto &A : TA) {
173     if (A.getKind() == TemplateArgument::Pack) {
174       if (index < current + A.pack_size())
175         return TemplateArgumentToQualType(A.getPackAsArray()[index - current]);
176       current += A.pack_size();
177       continue;
178     }
179     if (current == index)
180       return TemplateArgumentToQualType(A);
181     current++;
182   }
183   return None;
184 }
185
186 CXType clang_getCursorType(CXCursor C) {
187   using namespace cxcursor;
188
189   CXTranslationUnit TU = cxcursor::getCursorTU(C);
190   if (!TU)
191     return MakeCXType(QualType(), TU);
192
193   ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
194   if (clang_isExpression(C.kind)) {
195     QualType T = cxcursor::getCursorExpr(C)->getType();
196     return MakeCXType(T, TU);
197   }
198
199   if (clang_isDeclaration(C.kind)) {
200     const Decl *D = cxcursor::getCursorDecl(C);
201     if (!D)
202       return MakeCXType(QualType(), TU);
203
204     if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
205       return MakeCXType(Context.getTypeDeclType(TD), TU);
206     if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
207       return MakeCXType(Context.getObjCInterfaceType(ID), TU);
208     if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
209       return MakeCXType(DD->getType(), TU);
210     if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
211       return MakeCXType(VD->getType(), TU);
212     if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
213       return MakeCXType(PD->getType(), TU);
214     if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
215       return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
216     return MakeCXType(QualType(), TU);
217   }
218
219   if (clang_isReference(C.kind)) {
220     switch (C.kind) {
221     case CXCursor_ObjCSuperClassRef: {
222       QualType T
223         = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
224       return MakeCXType(T, TU);
225     }
226
227     case CXCursor_ObjCClassRef: {
228       QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
229       return MakeCXType(T, TU);
230     }
231
232     case CXCursor_TypeRef: {
233       QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
234       return MakeCXType(T, TU);
235
236     }
237
238     case CXCursor_CXXBaseSpecifier:
239       return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
240
241     case CXCursor_MemberRef:
242       return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
243
244     case CXCursor_VariableRef:
245       return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
246
247     case CXCursor_ObjCProtocolRef:
248     case CXCursor_TemplateRef:
249     case CXCursor_NamespaceRef:
250     case CXCursor_OverloadedDeclRef:
251     default:
252       break;
253     }
254
255     return MakeCXType(QualType(), TU);
256   }
257
258   return MakeCXType(QualType(), TU);
259 }
260
261 CXString clang_getTypeSpelling(CXType CT) {
262   QualType T = GetQualType(CT);
263   if (T.isNull())
264     return cxstring::createEmpty();
265
266   CXTranslationUnit TU = GetTU(CT);
267   SmallString<64> Str;
268   llvm::raw_svector_ostream OS(Str);
269   PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
270
271   T.print(OS, PP);
272
273   return cxstring::createDup(OS.str());
274 }
275
276 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
277   using namespace cxcursor;
278   CXTranslationUnit TU = cxcursor::getCursorTU(C);
279
280   if (clang_isDeclaration(C.kind)) {
281     const Decl *D = cxcursor::getCursorDecl(C);
282
283     if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
284       QualType T = TD->getUnderlyingType();
285       return MakeCXType(T, TU);
286     }
287
288     return MakeCXType(QualType(), TU);
289   }
290
291   return MakeCXType(QualType(), TU);
292 }
293
294 CXType clang_getEnumDeclIntegerType(CXCursor C) {
295   using namespace cxcursor;
296   CXTranslationUnit TU = cxcursor::getCursorTU(C);
297
298   if (clang_isDeclaration(C.kind)) {
299     const Decl *D = cxcursor::getCursorDecl(C);
300
301     if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
302       QualType T = TD->getIntegerType();
303       return MakeCXType(T, TU);
304     }
305
306     return MakeCXType(QualType(), TU);
307   }
308
309   return MakeCXType(QualType(), TU);
310 }
311
312 long long clang_getEnumConstantDeclValue(CXCursor C) {
313   using namespace cxcursor;
314
315   if (clang_isDeclaration(C.kind)) {
316     const Decl *D = cxcursor::getCursorDecl(C);
317
318     if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
319       return TD->getInitVal().getSExtValue();
320     }
321
322     return LLONG_MIN;
323   }
324
325   return LLONG_MIN;
326 }
327
328 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
329   using namespace cxcursor;
330
331   if (clang_isDeclaration(C.kind)) {
332     const Decl *D = cxcursor::getCursorDecl(C);
333
334     if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
335       return TD->getInitVal().getZExtValue();
336     }
337
338     return ULLONG_MAX;
339   }
340
341   return ULLONG_MAX;
342 }
343
344 int clang_getFieldDeclBitWidth(CXCursor C) {
345   using namespace cxcursor;
346
347   if (clang_isDeclaration(C.kind)) {
348     const Decl *D = getCursorDecl(C);
349
350     if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
351       if (FD->isBitField())
352         return FD->getBitWidthValue(getCursorContext(C));
353     }
354   }
355
356   return -1;
357 }
358
359 CXType clang_getCanonicalType(CXType CT) {
360   if (CT.kind == CXType_Invalid)
361     return CT;
362
363   QualType T = GetQualType(CT);
364   CXTranslationUnit TU = GetTU(CT);
365
366   if (T.isNull())
367     return MakeCXType(QualType(), GetTU(CT));
368
369   return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
370                         .getCanonicalType(T),
371                     TU);
372 }
373
374 unsigned clang_isConstQualifiedType(CXType CT) {
375   QualType T = GetQualType(CT);
376   return T.isLocalConstQualified();
377 }
378
379 unsigned clang_isVolatileQualifiedType(CXType CT) {
380   QualType T = GetQualType(CT);
381   return T.isLocalVolatileQualified();
382 }
383
384 unsigned clang_isRestrictQualifiedType(CXType CT) {
385   QualType T = GetQualType(CT);
386   return T.isLocalRestrictQualified();
387 }
388
389 CXType clang_getPointeeType(CXType CT) {
390   QualType T = GetQualType(CT);
391   const Type *TP = T.getTypePtrOrNull();
392
393   if (!TP)
394     return MakeCXType(QualType(), GetTU(CT));
395
396   switch (TP->getTypeClass()) {
397     case Type::Pointer:
398       T = cast<PointerType>(TP)->getPointeeType();
399       break;
400     case Type::BlockPointer:
401       T = cast<BlockPointerType>(TP)->getPointeeType();
402       break;
403     case Type::LValueReference:
404     case Type::RValueReference:
405       T = cast<ReferenceType>(TP)->getPointeeType();
406       break;
407     case Type::ObjCObjectPointer:
408       T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
409       break;
410     case Type::MemberPointer:
411       T = cast<MemberPointerType>(TP)->getPointeeType();
412       break;
413     default:
414       T = QualType();
415       break;
416   }
417   return MakeCXType(T, GetTU(CT));
418 }
419
420 CXCursor clang_getTypeDeclaration(CXType CT) {
421   if (CT.kind == CXType_Invalid)
422     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
423
424   QualType T = GetQualType(CT);
425   const Type *TP = T.getTypePtrOrNull();
426
427   if (!TP)
428     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
429
430   Decl *D = nullptr;
431
432 try_again:
433   switch (TP->getTypeClass()) {
434   case Type::Typedef:
435     D = cast<TypedefType>(TP)->getDecl();
436     break;
437   case Type::ObjCObject:
438     D = cast<ObjCObjectType>(TP)->getInterface();
439     break;
440   case Type::ObjCInterface:
441     D = cast<ObjCInterfaceType>(TP)->getDecl();
442     break;
443   case Type::Record:
444   case Type::Enum:
445     D = cast<TagType>(TP)->getDecl();
446     break;
447   case Type::TemplateSpecialization:
448     if (const RecordType *Record = TP->getAs<RecordType>())
449       D = Record->getDecl();
450     else
451       D = cast<TemplateSpecializationType>(TP)->getTemplateName()
452                                                          .getAsTemplateDecl();
453     break;
454
455   case Type::Auto:
456   case Type::DeducedTemplateSpecialization:
457     TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull();
458     if (TP)
459       goto try_again;
460     break;
461
462   case Type::InjectedClassName:
463     D = cast<InjectedClassNameType>(TP)->getDecl();
464     break;
465
466   // FIXME: Template type parameters!      
467
468   case Type::Elaborated:
469     TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
470     goto try_again;
471
472   default:
473     break;
474   }
475
476   if (!D)
477     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
478
479   return cxcursor::MakeCXCursor(D, GetTU(CT));
480 }
481
482 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
483   const char *s = nullptr;
484 #define TKIND(X) case CXType_##X: s = ""  #X  ""; break
485   switch (K) {
486     TKIND(Invalid);
487     TKIND(Unexposed);
488     TKIND(Void);
489     TKIND(Bool);
490     TKIND(Char_U);
491     TKIND(UChar);
492     TKIND(Char16);
493     TKIND(Char32);  
494     TKIND(UShort);
495     TKIND(UInt);
496     TKIND(ULong);
497     TKIND(ULongLong);
498     TKIND(UInt128);
499     TKIND(Char_S);
500     TKIND(SChar);
501     case CXType_WChar: s = "WChar"; break;
502     TKIND(Short);
503     TKIND(Int);
504     TKIND(Long);
505     TKIND(LongLong);
506     TKIND(Int128);
507     TKIND(Half);
508     TKIND(Float);
509     TKIND(Double);
510     TKIND(LongDouble);
511     TKIND(Float128);
512     TKIND(NullPtr);
513     TKIND(Overload);
514     TKIND(Dependent);
515     TKIND(ObjCId);
516     TKIND(ObjCClass);
517     TKIND(ObjCSel);
518     TKIND(Complex);
519     TKIND(Pointer);
520     TKIND(BlockPointer);
521     TKIND(LValueReference);
522     TKIND(RValueReference);
523     TKIND(Record);
524     TKIND(Enum);
525     TKIND(Typedef);
526     TKIND(ObjCInterface);
527     TKIND(ObjCObjectPointer);
528     TKIND(FunctionNoProto);
529     TKIND(FunctionProto);
530     TKIND(ConstantArray);
531     TKIND(IncompleteArray);
532     TKIND(VariableArray);
533     TKIND(DependentSizedArray);
534     TKIND(Vector);
535     TKIND(MemberPointer);
536     TKIND(Auto);
537     TKIND(Elaborated);
538   }
539 #undef TKIND
540   return cxstring::createRef(s);
541 }
542
543 unsigned clang_equalTypes(CXType A, CXType B) {
544   return A.data[0] == B.data[0] && A.data[1] == B.data[1];
545 }
546
547 unsigned clang_isFunctionTypeVariadic(CXType X) {
548   QualType T = GetQualType(X);
549   if (T.isNull())
550     return 0;
551
552   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
553     return (unsigned)FD->isVariadic();
554
555   if (T->getAs<FunctionNoProtoType>())
556     return 1;
557   
558   return 0;
559 }
560
561 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
562   QualType T = GetQualType(X);
563   if (T.isNull())
564     return CXCallingConv_Invalid;
565   
566   if (const FunctionType *FD = T->getAs<FunctionType>()) {
567 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
568     switch (FD->getCallConv()) {
569       TCALLINGCONV(C);
570       TCALLINGCONV(X86StdCall);
571       TCALLINGCONV(X86FastCall);
572       TCALLINGCONV(X86ThisCall);
573       TCALLINGCONV(X86Pascal);
574       TCALLINGCONV(X86RegCall);
575       TCALLINGCONV(X86VectorCall);
576       TCALLINGCONV(X86_64Win64);
577       TCALLINGCONV(X86_64SysV);
578       TCALLINGCONV(AAPCS);
579       TCALLINGCONV(AAPCS_VFP);
580       TCALLINGCONV(IntelOclBicc);
581       TCALLINGCONV(Swift);
582       TCALLINGCONV(PreserveMost);
583       TCALLINGCONV(PreserveAll);
584     case CC_SpirFunction: return CXCallingConv_Unexposed;
585     case CC_OpenCLKernel: return CXCallingConv_Unexposed;
586       break;
587     }
588 #undef TCALLINGCONV
589   }
590   
591   return CXCallingConv_Invalid;
592 }
593
594 int clang_getNumArgTypes(CXType X) {
595   QualType T = GetQualType(X);
596   if (T.isNull())
597     return -1;
598   
599   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
600     return FD->getNumParams();
601   }
602   
603   if (T->getAs<FunctionNoProtoType>()) {
604     return 0;
605   }
606   
607   return -1;
608 }
609
610 CXType clang_getArgType(CXType X, unsigned i) {
611   QualType T = GetQualType(X);
612   if (T.isNull())
613     return MakeCXType(QualType(), GetTU(X));
614
615   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
616     unsigned numParams = FD->getNumParams();
617     if (i >= numParams)
618       return MakeCXType(QualType(), GetTU(X));
619
620     return MakeCXType(FD->getParamType(i), GetTU(X));
621   }
622   
623   return MakeCXType(QualType(), GetTU(X));
624 }
625
626 CXType clang_getResultType(CXType X) {
627   QualType T = GetQualType(X);
628   if (T.isNull())
629     return MakeCXType(QualType(), GetTU(X));
630   
631   if (const FunctionType *FD = T->getAs<FunctionType>())
632     return MakeCXType(FD->getReturnType(), GetTU(X));
633
634   return MakeCXType(QualType(), GetTU(X));
635 }
636
637 CXType clang_getCursorResultType(CXCursor C) {
638   if (clang_isDeclaration(C.kind)) {
639     const Decl *D = cxcursor::getCursorDecl(C);
640     if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
641       return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
642
643     return clang_getResultType(clang_getCursorType(C));
644   }
645
646   return MakeCXType(QualType(), cxcursor::getCursorTU(C));
647 }
648
649 unsigned clang_isPODType(CXType X) {
650   QualType T = GetQualType(X);
651   if (T.isNull())
652     return 0;
653   
654   CXTranslationUnit TU = GetTU(X);
655
656   return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
657 }
658
659 CXType clang_getElementType(CXType CT) {
660   QualType ET = QualType();
661   QualType T = GetQualType(CT);
662   const Type *TP = T.getTypePtrOrNull();
663
664   if (TP) {
665     switch (TP->getTypeClass()) {
666     case Type::ConstantArray:
667       ET = cast<ConstantArrayType> (TP)->getElementType();
668       break;
669     case Type::IncompleteArray:
670       ET = cast<IncompleteArrayType> (TP)->getElementType();
671       break;
672     case Type::VariableArray:
673       ET = cast<VariableArrayType> (TP)->getElementType();
674       break;
675     case Type::DependentSizedArray:
676       ET = cast<DependentSizedArrayType> (TP)->getElementType();
677       break;
678     case Type::Vector:
679       ET = cast<VectorType> (TP)->getElementType();
680       break;
681     case Type::Complex:
682       ET = cast<ComplexType> (TP)->getElementType();
683       break;
684     default:
685       break;
686     }
687   }
688   return MakeCXType(ET, GetTU(CT));
689 }
690
691 long long clang_getNumElements(CXType CT) {
692   long long result = -1;
693   QualType T = GetQualType(CT);
694   const Type *TP = T.getTypePtrOrNull();
695
696   if (TP) {
697     switch (TP->getTypeClass()) {
698     case Type::ConstantArray:
699       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
700       break;
701     case Type::Vector:
702       result = cast<VectorType> (TP)->getNumElements();
703       break;
704     default:
705       break;
706     }
707   }
708   return result;
709 }
710
711 CXType clang_getArrayElementType(CXType CT) {
712   QualType ET = QualType();
713   QualType T = GetQualType(CT);
714   const Type *TP = T.getTypePtrOrNull();
715
716   if (TP) {
717     switch (TP->getTypeClass()) {
718     case Type::ConstantArray:
719       ET = cast<ConstantArrayType> (TP)->getElementType();
720       break;
721     case Type::IncompleteArray:
722       ET = cast<IncompleteArrayType> (TP)->getElementType();
723       break;
724     case Type::VariableArray:
725       ET = cast<VariableArrayType> (TP)->getElementType();
726       break;
727     case Type::DependentSizedArray:
728       ET = cast<DependentSizedArrayType> (TP)->getElementType();
729       break;
730     default:
731       break;
732     }
733   }
734   return MakeCXType(ET, GetTU(CT));
735 }
736
737 long long clang_getArraySize(CXType CT) {
738   long long result = -1;
739   QualType T = GetQualType(CT);
740   const Type *TP = T.getTypePtrOrNull();
741
742   if (TP) {
743     switch (TP->getTypeClass()) {
744     case Type::ConstantArray:
745       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
746       break;
747     default:
748       break;
749     }
750   }
751   return result;
752 }
753
754 long long clang_Type_getAlignOf(CXType T) {
755   if (T.kind == CXType_Invalid)
756     return CXTypeLayoutError_Invalid;
757   ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
758   QualType QT = GetQualType(T);
759   // [expr.alignof] p1: return size_t value for complete object type, reference
760   //                    or array.
761   // [expr.alignof] p3: if reference type, return size of referenced type
762   if (QT->isReferenceType())
763     QT = QT.getNonReferenceType();
764   if (QT->isIncompleteType())
765     return CXTypeLayoutError_Incomplete;
766   if (QT->isDependentType())
767     return CXTypeLayoutError_Dependent;
768   // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
769   // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
770   // if (QT->isVoidType()) return 1;
771   return Ctx.getTypeAlignInChars(QT).getQuantity();
772 }
773
774 CXType clang_Type_getClassType(CXType CT) {
775   QualType ET = QualType();
776   QualType T = GetQualType(CT);
777   const Type *TP = T.getTypePtrOrNull();
778
779   if (TP && TP->getTypeClass() == Type::MemberPointer) {
780     ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
781   }
782   return MakeCXType(ET, GetTU(CT));
783 }
784
785 long long clang_Type_getSizeOf(CXType T) {
786   if (T.kind == CXType_Invalid)
787     return CXTypeLayoutError_Invalid;
788   ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
789   QualType QT = GetQualType(T);
790   // [expr.sizeof] p2: if reference type, return size of referenced type
791   if (QT->isReferenceType())
792     QT = QT.getNonReferenceType();
793   // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
794   //                   enumeration
795   // Note: We get the cxtype, not the cxcursor, so we can't call
796   //       FieldDecl->isBitField()
797   // [expr.sizeof] p3: pointer ok, function not ok.
798   // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
799   if (QT->isIncompleteType())
800     return CXTypeLayoutError_Incomplete;
801   if (QT->isDependentType())
802     return CXTypeLayoutError_Dependent;
803   if (!QT->isConstantSizeType())
804     return CXTypeLayoutError_NotConstantSize;
805   // [gcc extension] lib/AST/ExprConstant.cpp:1372
806   //                 HandleSizeof : {voidtype,functype} == 1
807   // not handled by ASTContext.cpp:1313 getTypeInfoImpl
808   if (QT->isVoidType() || QT->isFunctionType())
809     return 1;
810   return Ctx.getTypeSizeInChars(QT).getQuantity();
811 }
812
813 static long long visitRecordForValidation(const RecordDecl *RD) {
814   for (const auto *I : RD->fields()){
815     QualType FQT = I->getType();
816     if (FQT->isIncompleteType())
817       return CXTypeLayoutError_Incomplete;
818     if (FQT->isDependentType())
819       return CXTypeLayoutError_Dependent;
820     // recurse
821     if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
822       if (const RecordDecl *Child = ChildType->getDecl()) {
823         long long ret = visitRecordForValidation(Child);
824         if (ret < 0)
825           return ret;
826       }
827     }
828     // else try next field
829   }
830   return 0;
831 }
832
833 static long long validateFieldParentType(CXCursor PC, CXType PT){
834   if (clang_isInvalid(PC.kind))
835     return CXTypeLayoutError_Invalid;
836   const RecordDecl *RD =
837         dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
838   // validate parent declaration
839   if (!RD || RD->isInvalidDecl())
840     return CXTypeLayoutError_Invalid;
841   RD = RD->getDefinition();
842   if (!RD)
843     return CXTypeLayoutError_Incomplete;
844   if (RD->isInvalidDecl())
845     return CXTypeLayoutError_Invalid;
846   // validate parent type
847   QualType RT = GetQualType(PT);
848   if (RT->isIncompleteType())
849     return CXTypeLayoutError_Incomplete;
850   if (RT->isDependentType())
851     return CXTypeLayoutError_Dependent;
852   // We recurse into all record fields to detect incomplete and dependent types.
853   long long Error = visitRecordForValidation(RD);
854   if (Error < 0)
855     return Error;
856   return 0;
857 }
858
859 long long clang_Type_getOffsetOf(CXType PT, const char *S) {
860   // check that PT is not incomplete/dependent
861   CXCursor PC = clang_getTypeDeclaration(PT);
862   long long Error = validateFieldParentType(PC,PT);
863   if (Error < 0)
864     return Error;
865   if (!S)
866     return CXTypeLayoutError_InvalidFieldName;
867   // lookup field
868   ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
869   IdentifierInfo *II = &Ctx.Idents.get(S);
870   DeclarationName FieldName(II);
871   const RecordDecl *RD =
872         dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
873   // verified in validateFieldParentType
874   RD = RD->getDefinition();
875   RecordDecl::lookup_result Res = RD->lookup(FieldName);
876   // If a field of the parent record is incomplete, lookup will fail.
877   // and we would return InvalidFieldName instead of Incomplete.
878   // But this erroneous results does protects again a hidden assertion failure
879   // in the RecordLayoutBuilder
880   if (Res.size() != 1)
881     return CXTypeLayoutError_InvalidFieldName;
882   if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
883     return Ctx.getFieldOffset(FD);
884   if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
885     return Ctx.getFieldOffset(IFD);
886   // we don't want any other Decl Type.
887   return CXTypeLayoutError_InvalidFieldName;
888 }
889
890 long long clang_Cursor_getOffsetOfField(CXCursor C) {
891   if (clang_isDeclaration(C.kind)) {
892     // we need to validate the parent type
893     CXCursor PC = clang_getCursorSemanticParent(C);
894     CXType PT = clang_getCursorType(PC);
895     long long Error = validateFieldParentType(PC,PT);
896     if (Error < 0)
897       return Error;
898     // proceed with the offset calculation
899     const Decl *D = cxcursor::getCursorDecl(C);
900     ASTContext &Ctx = cxcursor::getCursorContext(C);
901     if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
902       return Ctx.getFieldOffset(FD);
903     if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
904       return Ctx.getFieldOffset(IFD);
905   }
906   return -1;
907 }
908
909 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
910   QualType QT = GetQualType(T);
911   if (QT.isNull())
912     return CXRefQualifier_None;
913   const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
914   if (!FD)
915     return CXRefQualifier_None;
916   switch (FD->getRefQualifier()) {
917     case RQ_None:
918       return CXRefQualifier_None;
919     case RQ_LValue:
920       return CXRefQualifier_LValue;
921     case RQ_RValue:
922       return CXRefQualifier_RValue;
923   }
924   return CXRefQualifier_None;
925 }
926
927 unsigned clang_Cursor_isBitField(CXCursor C) {
928   if (!clang_isDeclaration(C.kind))
929     return 0;
930   const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
931   if (!FD)
932     return 0;
933   return FD->isBitField();
934 }
935
936 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
937   if (!clang_isDeclaration(C.kind))
938     return cxstring::createEmpty();
939
940   const Decl *D = cxcursor::getCursorDecl(C);
941   ASTContext &Ctx = cxcursor::getCursorContext(C);
942   std::string encoding;
943
944   if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))  {
945     encoding = Ctx.getObjCEncodingForMethodDecl(OMD);
946   } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
947     encoding = Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr);
948   else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
949     encoding = Ctx.getObjCEncodingForFunctionDecl(FD);
950   else {
951     QualType Ty;
952     if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
953       Ty = Ctx.getTypeDeclType(TD);
954     if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
955       Ty = VD->getType();
956     else return cxstring::createRef("?");
957     Ctx.getObjCEncodingForType(Ty, encoding);
958   }
959
960   return cxstring::createDup(encoding);
961 }
962
963 static unsigned GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA) {
964   unsigned size = TA.size();
965   for (const auto &Arg : TA)
966     if (Arg.getKind() == TemplateArgument::Pack)
967       size += Arg.pack_size() - 1;
968   return size;
969 }
970
971 int clang_Type_getNumTemplateArguments(CXType CT) {
972   QualType T = GetQualType(CT);
973   if (T.isNull())
974     return -1;
975
976   auto TA = GetTemplateArguments(T);
977   if (!TA)
978     return -1;
979
980   return GetTemplateArgumentArraySize(TA.getValue());
981 }
982
983 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) {
984   QualType T = GetQualType(CT);
985   if (T.isNull())
986     return MakeCXType(QualType(), GetTU(CT));
987
988   auto TA = GetTemplateArguments(T);
989   if (!TA)
990     return MakeCXType(QualType(), GetTU(CT));
991
992   Optional<QualType> QT = FindTemplateArgumentTypeAt(TA.getValue(), index);
993   return MakeCXType(QT.getValueOr(QualType()), GetTU(CT));
994 }
995
996 unsigned clang_Type_visitFields(CXType PT,
997                                 CXFieldVisitor visitor,
998                                 CXClientData client_data){
999   CXCursor PC = clang_getTypeDeclaration(PT);
1000   if (clang_isInvalid(PC.kind))
1001     return false;
1002   const RecordDecl *RD =
1003         dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
1004   if (!RD || RD->isInvalidDecl())
1005     return false;
1006   RD = RD->getDefinition();
1007   if (!RD || RD->isInvalidDecl())
1008     return false;
1009
1010   for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
1011        I != E; ++I){
1012     const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
1013     // Callback to the client.
1014     switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
1015     case CXVisit_Break:
1016       return true;
1017     case CXVisit_Continue:
1018       break;
1019     }
1020   }
1021   return true;
1022 }
1023
1024 unsigned clang_Cursor_isAnonymous(CXCursor C){
1025   if (!clang_isDeclaration(C.kind))
1026     return 0;
1027   const Decl *D = cxcursor::getCursorDecl(C);
1028   if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
1029     return FD->isAnonymousStructOrUnion();
1030   return 0;
1031 }
1032
1033 CXType clang_Type_getNamedType(CXType CT){
1034   QualType T = GetQualType(CT);
1035   const Type *TP = T.getTypePtrOrNull();
1036
1037   if (TP && TP->getTypeClass() == Type::Elaborated)
1038     return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT));
1039
1040   return MakeCXType(QualType(), GetTU(CT));
1041 }
1042
1043 unsigned clang_Type_isTransparentTagTypedef(CXType TT){
1044   QualType T = GetQualType(TT);
1045   if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) {
1046     if (auto *D = TT->getDecl())
1047       return D->isTransparentTag();
1048   }
1049   return false;
1050 }