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