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