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