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
26using namespace clang;
27
28static 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
66static 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
100CXType 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 ? nullptr
124                                           : T.getAsOpaquePtr(), TU } };
125  return CT;
126}
127
128using cxtype::MakeCXType;
129
130static inline QualType GetQualType(CXType CT) {
131  return QualType::getFromOpaquePtr(CT.data[0]);
132}
133
134static inline CXTranslationUnit GetTU(CXType CT) {
135  return static_cast<CXTranslationUnit>(CT.data[1]);
136}
137
138extern "C" {
139
140CXType clang_getCursorType(CXCursor C) {
141  using namespace cxcursor;
142
143  CXTranslationUnit TU = cxcursor::getCursorTU(C);
144  if (!TU)
145    return MakeCXType(QualType(), TU);
146
147  ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
148  if (clang_isExpression(C.kind)) {
149    QualType T = cxcursor::getCursorExpr(C)->getType();
150    return MakeCXType(T, TU);
151  }
152
153  if (clang_isDeclaration(C.kind)) {
154    const Decl *D = cxcursor::getCursorDecl(C);
155    if (!D)
156      return MakeCXType(QualType(), TU);
157
158    if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
159      return MakeCXType(Context.getTypeDeclType(TD), TU);
160    if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
161      return MakeCXType(Context.getObjCInterfaceType(ID), TU);
162    if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
163      if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
164        return MakeCXType(TSInfo->getType(), TU);
165      return MakeCXType(DD->getType(), TU);
166    }
167    if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
168      return MakeCXType(VD->getType(), TU);
169    if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
170      return MakeCXType(PD->getType(), TU);
171    if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) {
172      if (TypeSourceInfo *TSInfo = FTD->getTemplatedDecl()->getTypeSourceInfo())
173        return MakeCXType(TSInfo->getType(), TU);
174      return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
175    }
176    return MakeCXType(QualType(), TU);
177  }
178
179  if (clang_isReference(C.kind)) {
180    switch (C.kind) {
181    case CXCursor_ObjCSuperClassRef: {
182      QualType T
183        = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
184      return MakeCXType(T, TU);
185    }
186
187    case CXCursor_ObjCClassRef: {
188      QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
189      return MakeCXType(T, TU);
190    }
191
192    case CXCursor_TypeRef: {
193      QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
194      return MakeCXType(T, TU);
195
196    }
197
198    case CXCursor_CXXBaseSpecifier:
199      return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
200
201    case CXCursor_MemberRef:
202      return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
203
204    case CXCursor_VariableRef:
205      return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
206
207    case CXCursor_ObjCProtocolRef:
208    case CXCursor_TemplateRef:
209    case CXCursor_NamespaceRef:
210    case CXCursor_OverloadedDeclRef:
211    default:
212      break;
213    }
214
215    return MakeCXType(QualType(), TU);
216  }
217
218  return MakeCXType(QualType(), TU);
219}
220
221CXString clang_getTypeSpelling(CXType CT) {
222  QualType T = GetQualType(CT);
223  if (T.isNull())
224    return cxstring::createEmpty();
225
226  CXTranslationUnit TU = GetTU(CT);
227  SmallString<64> Str;
228  llvm::raw_svector_ostream OS(Str);
229  PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
230
231  T.print(OS, PP);
232
233  return cxstring::createDup(OS.str());
234}
235
236CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
237  using namespace cxcursor;
238  CXTranslationUnit TU = cxcursor::getCursorTU(C);
239
240  if (clang_isDeclaration(C.kind)) {
241    const Decl *D = cxcursor::getCursorDecl(C);
242
243    if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
244      QualType T = TD->getUnderlyingType();
245      return MakeCXType(T, TU);
246    }
247
248    return MakeCXType(QualType(), TU);
249  }
250
251  return MakeCXType(QualType(), TU);
252}
253
254CXType clang_getEnumDeclIntegerType(CXCursor C) {
255  using namespace cxcursor;
256  CXTranslationUnit TU = cxcursor::getCursorTU(C);
257
258  if (clang_isDeclaration(C.kind)) {
259    const Decl *D = cxcursor::getCursorDecl(C);
260
261    if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
262      QualType T = TD->getIntegerType();
263      return MakeCXType(T, TU);
264    }
265
266    return MakeCXType(QualType(), TU);
267  }
268
269  return MakeCXType(QualType(), TU);
270}
271
272long long clang_getEnumConstantDeclValue(CXCursor C) {
273  using namespace cxcursor;
274
275  if (clang_isDeclaration(C.kind)) {
276    const Decl *D = cxcursor::getCursorDecl(C);
277
278    if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
279      return TD->getInitVal().getSExtValue();
280    }
281
282    return LLONG_MIN;
283  }
284
285  return LLONG_MIN;
286}
287
288unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
289  using namespace cxcursor;
290
291  if (clang_isDeclaration(C.kind)) {
292    const Decl *D = cxcursor::getCursorDecl(C);
293
294    if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
295      return TD->getInitVal().getZExtValue();
296    }
297
298    return ULLONG_MAX;
299  }
300
301  return ULLONG_MAX;
302}
303
304int clang_getFieldDeclBitWidth(CXCursor C) {
305  using namespace cxcursor;
306
307  if (clang_isDeclaration(C.kind)) {
308    const Decl *D = getCursorDecl(C);
309
310    if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
311      if (FD->isBitField())
312        return FD->getBitWidthValue(getCursorContext(C));
313    }
314  }
315
316  return -1;
317}
318
319CXType clang_getCanonicalType(CXType CT) {
320  if (CT.kind == CXType_Invalid)
321    return CT;
322
323  QualType T = GetQualType(CT);
324  CXTranslationUnit TU = GetTU(CT);
325
326  if (T.isNull())
327    return MakeCXType(QualType(), GetTU(CT));
328
329  return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
330                        .getCanonicalType(T),
331                    TU);
332}
333
334unsigned clang_isConstQualifiedType(CXType CT) {
335  QualType T = GetQualType(CT);
336  return T.isLocalConstQualified();
337}
338
339unsigned clang_isVolatileQualifiedType(CXType CT) {
340  QualType T = GetQualType(CT);
341  return T.isLocalVolatileQualified();
342}
343
344unsigned clang_isRestrictQualifiedType(CXType CT) {
345  QualType T = GetQualType(CT);
346  return T.isLocalRestrictQualified();
347}
348
349CXType clang_getPointeeType(CXType CT) {
350  QualType T = GetQualType(CT);
351  const Type *TP = T.getTypePtrOrNull();
352
353  if (!TP)
354    return MakeCXType(QualType(), GetTU(CT));
355
356  switch (TP->getTypeClass()) {
357    case Type::Pointer:
358      T = cast<PointerType>(TP)->getPointeeType();
359      break;
360    case Type::BlockPointer:
361      T = cast<BlockPointerType>(TP)->getPointeeType();
362      break;
363    case Type::LValueReference:
364    case Type::RValueReference:
365      T = cast<ReferenceType>(TP)->getPointeeType();
366      break;
367    case Type::ObjCObjectPointer:
368      T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
369      break;
370    case Type::MemberPointer:
371      T = cast<MemberPointerType>(TP)->getPointeeType();
372      break;
373    default:
374      T = QualType();
375      break;
376  }
377  return MakeCXType(T, GetTU(CT));
378}
379
380CXCursor clang_getTypeDeclaration(CXType CT) {
381  if (CT.kind == CXType_Invalid)
382    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
383
384  QualType T = GetQualType(CT);
385  const Type *TP = T.getTypePtrOrNull();
386
387  if (!TP)
388    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
389
390  Decl *D = nullptr;
391
392try_again:
393  switch (TP->getTypeClass()) {
394  case Type::Typedef:
395    D = cast<TypedefType>(TP)->getDecl();
396    break;
397  case Type::ObjCObject:
398    D = cast<ObjCObjectType>(TP)->getInterface();
399    break;
400  case Type::ObjCInterface:
401    D = cast<ObjCInterfaceType>(TP)->getDecl();
402    break;
403  case Type::Record:
404  case Type::Enum:
405    D = cast<TagType>(TP)->getDecl();
406    break;
407  case Type::TemplateSpecialization:
408    if (const RecordType *Record = TP->getAs<RecordType>())
409      D = Record->getDecl();
410    else
411      D = cast<TemplateSpecializationType>(TP)->getTemplateName()
412                                                         .getAsTemplateDecl();
413    break;
414
415  case Type::InjectedClassName:
416    D = cast<InjectedClassNameType>(TP)->getDecl();
417    break;
418
419  // FIXME: Template type parameters!
420
421  case Type::Elaborated:
422    TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
423    goto try_again;
424
425  default:
426    break;
427  }
428
429  if (!D)
430    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
431
432  return cxcursor::MakeCXCursor(D, GetTU(CT));
433}
434
435CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
436  const char *s = nullptr;
437#define TKIND(X) case CXType_##X: s = ""  #X  ""; break
438  switch (K) {
439    TKIND(Invalid);
440    TKIND(Unexposed);
441    TKIND(Void);
442    TKIND(Bool);
443    TKIND(Char_U);
444    TKIND(UChar);
445    TKIND(Char16);
446    TKIND(Char32);
447    TKIND(UShort);
448    TKIND(UInt);
449    TKIND(ULong);
450    TKIND(ULongLong);
451    TKIND(UInt128);
452    TKIND(Char_S);
453    TKIND(SChar);
454    case CXType_WChar: s = "WChar"; break;
455    TKIND(Short);
456    TKIND(Int);
457    TKIND(Long);
458    TKIND(LongLong);
459    TKIND(Int128);
460    TKIND(Float);
461    TKIND(Double);
462    TKIND(LongDouble);
463    TKIND(NullPtr);
464    TKIND(Overload);
465    TKIND(Dependent);
466    TKIND(ObjCId);
467    TKIND(ObjCClass);
468    TKIND(ObjCSel);
469    TKIND(Complex);
470    TKIND(Pointer);
471    TKIND(BlockPointer);
472    TKIND(LValueReference);
473    TKIND(RValueReference);
474    TKIND(Record);
475    TKIND(Enum);
476    TKIND(Typedef);
477    TKIND(ObjCInterface);
478    TKIND(ObjCObjectPointer);
479    TKIND(FunctionNoProto);
480    TKIND(FunctionProto);
481    TKIND(ConstantArray);
482    TKIND(IncompleteArray);
483    TKIND(VariableArray);
484    TKIND(DependentSizedArray);
485    TKIND(Vector);
486    TKIND(MemberPointer);
487  }
488#undef TKIND
489  return cxstring::createRef(s);
490}
491
492unsigned clang_equalTypes(CXType A, CXType B) {
493  return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
494}
495
496unsigned clang_isFunctionTypeVariadic(CXType X) {
497  QualType T = GetQualType(X);
498  if (T.isNull())
499    return 0;
500
501  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
502    return (unsigned)FD->isVariadic();
503
504  if (T->getAs<FunctionNoProtoType>())
505    return 1;
506
507  return 0;
508}
509
510CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
511  QualType T = GetQualType(X);
512  if (T.isNull())
513    return CXCallingConv_Invalid;
514
515  if (const FunctionType *FD = T->getAs<FunctionType>()) {
516#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
517    switch (FD->getCallConv()) {
518      TCALLINGCONV(C);
519      TCALLINGCONV(X86StdCall);
520      TCALLINGCONV(X86FastCall);
521      TCALLINGCONV(X86ThisCall);
522      TCALLINGCONV(X86Pascal);
523      TCALLINGCONV(X86_64Win64);
524      TCALLINGCONV(X86_64SysV);
525      TCALLINGCONV(AAPCS);
526      TCALLINGCONV(AAPCS_VFP);
527      TCALLINGCONV(PnaclCall);
528      TCALLINGCONV(IntelOclBicc);
529    }
530#undef TCALLINGCONV
531  }
532
533  return CXCallingConv_Invalid;
534}
535
536int clang_getNumArgTypes(CXType X) {
537  QualType T = GetQualType(X);
538  if (T.isNull())
539    return -1;
540
541  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
542    return FD->getNumParams();
543  }
544
545  if (T->getAs<FunctionNoProtoType>()) {
546    return 0;
547  }
548
549  return -1;
550}
551
552CXType clang_getArgType(CXType X, unsigned i) {
553  QualType T = GetQualType(X);
554  if (T.isNull())
555    return MakeCXType(QualType(), GetTU(X));
556
557  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
558    unsigned numParams = FD->getNumParams();
559    if (i >= numParams)
560      return MakeCXType(QualType(), GetTU(X));
561
562    return MakeCXType(FD->getParamType(i), GetTU(X));
563  }
564
565  return MakeCXType(QualType(), GetTU(X));
566}
567
568CXType clang_getResultType(CXType X) {
569  QualType T = GetQualType(X);
570  if (T.isNull())
571    return MakeCXType(QualType(), GetTU(X));
572
573  if (const FunctionType *FD = T->getAs<FunctionType>())
574    return MakeCXType(FD->getReturnType(), GetTU(X));
575
576  return MakeCXType(QualType(), GetTU(X));
577}
578
579CXType clang_getCursorResultType(CXCursor C) {
580  if (clang_isDeclaration(C.kind)) {
581    const Decl *D = cxcursor::getCursorDecl(C);
582    if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
583      return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
584
585    return clang_getResultType(clang_getCursorType(C));
586  }
587
588  return MakeCXType(QualType(), cxcursor::getCursorTU(C));
589}
590
591unsigned clang_isPODType(CXType X) {
592  QualType T = GetQualType(X);
593  if (T.isNull())
594    return 0;
595
596  CXTranslationUnit TU = GetTU(X);
597
598  return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
599}
600
601CXType clang_getElementType(CXType CT) {
602  QualType ET = QualType();
603  QualType T = GetQualType(CT);
604  const Type *TP = T.getTypePtrOrNull();
605
606  if (TP) {
607    switch (TP->getTypeClass()) {
608    case Type::ConstantArray:
609      ET = cast<ConstantArrayType> (TP)->getElementType();
610      break;
611    case Type::IncompleteArray:
612      ET = cast<IncompleteArrayType> (TP)->getElementType();
613      break;
614    case Type::VariableArray:
615      ET = cast<VariableArrayType> (TP)->getElementType();
616      break;
617    case Type::DependentSizedArray:
618      ET = cast<DependentSizedArrayType> (TP)->getElementType();
619      break;
620    case Type::Vector:
621      ET = cast<VectorType> (TP)->getElementType();
622      break;
623    case Type::Complex:
624      ET = cast<ComplexType> (TP)->getElementType();
625      break;
626    default:
627      break;
628    }
629  }
630  return MakeCXType(ET, GetTU(CT));
631}
632
633long long clang_getNumElements(CXType CT) {
634  long long result = -1;
635  QualType T = GetQualType(CT);
636  const Type *TP = T.getTypePtrOrNull();
637
638  if (TP) {
639    switch (TP->getTypeClass()) {
640    case Type::ConstantArray:
641      result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
642      break;
643    case Type::Vector:
644      result = cast<VectorType> (TP)->getNumElements();
645      break;
646    default:
647      break;
648    }
649  }
650  return result;
651}
652
653CXType clang_getArrayElementType(CXType CT) {
654  QualType ET = QualType();
655  QualType T = GetQualType(CT);
656  const Type *TP = T.getTypePtrOrNull();
657
658  if (TP) {
659    switch (TP->getTypeClass()) {
660    case Type::ConstantArray:
661      ET = cast<ConstantArrayType> (TP)->getElementType();
662      break;
663    case Type::IncompleteArray:
664      ET = cast<IncompleteArrayType> (TP)->getElementType();
665      break;
666    case Type::VariableArray:
667      ET = cast<VariableArrayType> (TP)->getElementType();
668      break;
669    case Type::DependentSizedArray:
670      ET = cast<DependentSizedArrayType> (TP)->getElementType();
671      break;
672    default:
673      break;
674    }
675  }
676  return MakeCXType(ET, GetTU(CT));
677}
678
679long long clang_getArraySize(CXType CT) {
680  long long result = -1;
681  QualType T = GetQualType(CT);
682  const Type *TP = T.getTypePtrOrNull();
683
684  if (TP) {
685    switch (TP->getTypeClass()) {
686    case Type::ConstantArray:
687      result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
688      break;
689    default:
690      break;
691    }
692  }
693  return result;
694}
695
696long long clang_Type_getAlignOf(CXType T) {
697  if (T.kind == CXType_Invalid)
698    return CXTypeLayoutError_Invalid;
699  ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
700  QualType QT = GetQualType(T);
701  // [expr.alignof] p1: return size_t value for complete object type, reference
702  //                    or array.
703  // [expr.alignof] p3: if reference type, return size of referenced type
704  if (QT->isReferenceType())
705    QT = QT.getNonReferenceType();
706  if (QT->isIncompleteType())
707    return CXTypeLayoutError_Incomplete;
708  if (QT->isDependentType())
709    return CXTypeLayoutError_Dependent;
710  // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
711  // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
712  // if (QT->isVoidType()) return 1;
713  return Ctx.getTypeAlignInChars(QT).getQuantity();
714}
715
716CXType clang_Type_getClassType(CXType CT) {
717  QualType ET = QualType();
718  QualType T = GetQualType(CT);
719  const Type *TP = T.getTypePtrOrNull();
720
721  if (TP && TP->getTypeClass() == Type::MemberPointer) {
722    ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
723  }
724  return MakeCXType(ET, GetTU(CT));
725}
726
727long long clang_Type_getSizeOf(CXType T) {
728  if (T.kind == CXType_Invalid)
729    return CXTypeLayoutError_Invalid;
730  ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
731  QualType QT = GetQualType(T);
732  // [expr.sizeof] p2: if reference type, return size of referenced type
733  if (QT->isReferenceType())
734    QT = QT.getNonReferenceType();
735  // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
736  //                   enumeration
737  // Note: We get the cxtype, not the cxcursor, so we can't call
738  //       FieldDecl->isBitField()
739  // [expr.sizeof] p3: pointer ok, function not ok.
740  // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
741  if (QT->isIncompleteType())
742    return CXTypeLayoutError_Incomplete;
743  if (QT->isDependentType())
744    return CXTypeLayoutError_Dependent;
745  if (!QT->isConstantSizeType())
746    return CXTypeLayoutError_NotConstantSize;
747  // [gcc extension] lib/AST/ExprConstant.cpp:1372
748  //                 HandleSizeof : {voidtype,functype} == 1
749  // not handled by ASTContext.cpp:1313 getTypeInfoImpl
750  if (QT->isVoidType() || QT->isFunctionType())
751    return 1;
752  return Ctx.getTypeSizeInChars(QT).getQuantity();
753}
754
755static long long visitRecordForValidation(const RecordDecl *RD) {
756  for (const auto *I : RD->fields()){
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
775long 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
819enum 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
837unsigned 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
846CXString 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, nullptr, 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
874int clang_Type_getNumTemplateArguments(CXType CT) {
875  QualType T = GetQualType(CT);
876  if (T.isNull())
877    return -1;
878  const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
879  if (!RecordDecl)
880    return -1;
881  const ClassTemplateSpecializationDecl *TemplateDecl =
882      dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
883  if (!TemplateDecl)
884    return -1;
885  return TemplateDecl->getTemplateArgs().size();
886}
887
888CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) {
889  QualType T = GetQualType(CT);
890  if (T.isNull())
891    return MakeCXType(QualType(), GetTU(CT));
892  const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
893  if (!RecordDecl)
894    return MakeCXType(QualType(), GetTU(CT));
895  const ClassTemplateSpecializationDecl *TemplateDecl =
896      dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
897  if (!TemplateDecl)
898    return MakeCXType(QualType(), GetTU(CT));
899  const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs();
900  if (TA.size() <= i)
901    return MakeCXType(QualType(), GetTU(CT));
902  const TemplateArgument &A = TA.get(i);
903  if (A.getKind() != TemplateArgument::Type)
904    return MakeCXType(QualType(), GetTU(CT));
905  return MakeCXType(A.getAsType(), GetTU(CT));
906}
907
908} // end: extern "C"
909