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(X86VectorCall);
524      TCALLINGCONV(X86_64Win64);
525      TCALLINGCONV(X86_64SysV);
526      TCALLINGCONV(AAPCS);
527      TCALLINGCONV(AAPCS_VFP);
528      TCALLINGCONV(IntelOclBicc);
529    case CC_SpirFunction: return CXCallingConv_Unexposed;
530    case CC_SpirKernel: return CXCallingConv_Unexposed;
531      break;
532    }
533#undef TCALLINGCONV
534  }
535
536  return CXCallingConv_Invalid;
537}
538
539int clang_getNumArgTypes(CXType X) {
540  QualType T = GetQualType(X);
541  if (T.isNull())
542    return -1;
543
544  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
545    return FD->getNumParams();
546  }
547
548  if (T->getAs<FunctionNoProtoType>()) {
549    return 0;
550  }
551
552  return -1;
553}
554
555CXType clang_getArgType(CXType X, unsigned i) {
556  QualType T = GetQualType(X);
557  if (T.isNull())
558    return MakeCXType(QualType(), GetTU(X));
559
560  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
561    unsigned numParams = FD->getNumParams();
562    if (i >= numParams)
563      return MakeCXType(QualType(), GetTU(X));
564
565    return MakeCXType(FD->getParamType(i), GetTU(X));
566  }
567
568  return MakeCXType(QualType(), GetTU(X));
569}
570
571CXType clang_getResultType(CXType X) {
572  QualType T = GetQualType(X);
573  if (T.isNull())
574    return MakeCXType(QualType(), GetTU(X));
575
576  if (const FunctionType *FD = T->getAs<FunctionType>())
577    return MakeCXType(FD->getReturnType(), GetTU(X));
578
579  return MakeCXType(QualType(), GetTU(X));
580}
581
582CXType clang_getCursorResultType(CXCursor C) {
583  if (clang_isDeclaration(C.kind)) {
584    const Decl *D = cxcursor::getCursorDecl(C);
585    if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
586      return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
587
588    return clang_getResultType(clang_getCursorType(C));
589  }
590
591  return MakeCXType(QualType(), cxcursor::getCursorTU(C));
592}
593
594unsigned clang_isPODType(CXType X) {
595  QualType T = GetQualType(X);
596  if (T.isNull())
597    return 0;
598
599  CXTranslationUnit TU = GetTU(X);
600
601  return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
602}
603
604CXType clang_getElementType(CXType CT) {
605  QualType ET = QualType();
606  QualType T = GetQualType(CT);
607  const Type *TP = T.getTypePtrOrNull();
608
609  if (TP) {
610    switch (TP->getTypeClass()) {
611    case Type::ConstantArray:
612      ET = cast<ConstantArrayType> (TP)->getElementType();
613      break;
614    case Type::IncompleteArray:
615      ET = cast<IncompleteArrayType> (TP)->getElementType();
616      break;
617    case Type::VariableArray:
618      ET = cast<VariableArrayType> (TP)->getElementType();
619      break;
620    case Type::DependentSizedArray:
621      ET = cast<DependentSizedArrayType> (TP)->getElementType();
622      break;
623    case Type::Vector:
624      ET = cast<VectorType> (TP)->getElementType();
625      break;
626    case Type::Complex:
627      ET = cast<ComplexType> (TP)->getElementType();
628      break;
629    default:
630      break;
631    }
632  }
633  return MakeCXType(ET, GetTU(CT));
634}
635
636long long clang_getNumElements(CXType CT) {
637  long long result = -1;
638  QualType T = GetQualType(CT);
639  const Type *TP = T.getTypePtrOrNull();
640
641  if (TP) {
642    switch (TP->getTypeClass()) {
643    case Type::ConstantArray:
644      result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
645      break;
646    case Type::Vector:
647      result = cast<VectorType> (TP)->getNumElements();
648      break;
649    default:
650      break;
651    }
652  }
653  return result;
654}
655
656CXType clang_getArrayElementType(CXType CT) {
657  QualType ET = QualType();
658  QualType T = GetQualType(CT);
659  const Type *TP = T.getTypePtrOrNull();
660
661  if (TP) {
662    switch (TP->getTypeClass()) {
663    case Type::ConstantArray:
664      ET = cast<ConstantArrayType> (TP)->getElementType();
665      break;
666    case Type::IncompleteArray:
667      ET = cast<IncompleteArrayType> (TP)->getElementType();
668      break;
669    case Type::VariableArray:
670      ET = cast<VariableArrayType> (TP)->getElementType();
671      break;
672    case Type::DependentSizedArray:
673      ET = cast<DependentSizedArrayType> (TP)->getElementType();
674      break;
675    default:
676      break;
677    }
678  }
679  return MakeCXType(ET, GetTU(CT));
680}
681
682long long clang_getArraySize(CXType CT) {
683  long long result = -1;
684  QualType T = GetQualType(CT);
685  const Type *TP = T.getTypePtrOrNull();
686
687  if (TP) {
688    switch (TP->getTypeClass()) {
689    case Type::ConstantArray:
690      result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
691      break;
692    default:
693      break;
694    }
695  }
696  return result;
697}
698
699long long clang_Type_getAlignOf(CXType T) {
700  if (T.kind == CXType_Invalid)
701    return CXTypeLayoutError_Invalid;
702  ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
703  QualType QT = GetQualType(T);
704  // [expr.alignof] p1: return size_t value for complete object type, reference
705  //                    or array.
706  // [expr.alignof] p3: if reference type, return size of referenced type
707  if (QT->isReferenceType())
708    QT = QT.getNonReferenceType();
709  if (QT->isIncompleteType())
710    return CXTypeLayoutError_Incomplete;
711  if (QT->isDependentType())
712    return CXTypeLayoutError_Dependent;
713  // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
714  // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
715  // if (QT->isVoidType()) return 1;
716  return Ctx.getTypeAlignInChars(QT).getQuantity();
717}
718
719CXType clang_Type_getClassType(CXType CT) {
720  QualType ET = QualType();
721  QualType T = GetQualType(CT);
722  const Type *TP = T.getTypePtrOrNull();
723
724  if (TP && TP->getTypeClass() == Type::MemberPointer) {
725    ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
726  }
727  return MakeCXType(ET, GetTU(CT));
728}
729
730long long clang_Type_getSizeOf(CXType T) {
731  if (T.kind == CXType_Invalid)
732    return CXTypeLayoutError_Invalid;
733  ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
734  QualType QT = GetQualType(T);
735  // [expr.sizeof] p2: if reference type, return size of referenced type
736  if (QT->isReferenceType())
737    QT = QT.getNonReferenceType();
738  // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
739  //                   enumeration
740  // Note: We get the cxtype, not the cxcursor, so we can't call
741  //       FieldDecl->isBitField()
742  // [expr.sizeof] p3: pointer ok, function not ok.
743  // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
744  if (QT->isIncompleteType())
745    return CXTypeLayoutError_Incomplete;
746  if (QT->isDependentType())
747    return CXTypeLayoutError_Dependent;
748  if (!QT->isConstantSizeType())
749    return CXTypeLayoutError_NotConstantSize;
750  // [gcc extension] lib/AST/ExprConstant.cpp:1372
751  //                 HandleSizeof : {voidtype,functype} == 1
752  // not handled by ASTContext.cpp:1313 getTypeInfoImpl
753  if (QT->isVoidType() || QT->isFunctionType())
754    return 1;
755  return Ctx.getTypeSizeInChars(QT).getQuantity();
756}
757
758static long long visitRecordForValidation(const RecordDecl *RD) {
759  for (const auto *I : RD->fields()){
760    QualType FQT = I->getType();
761    if (FQT->isIncompleteType())
762      return CXTypeLayoutError_Incomplete;
763    if (FQT->isDependentType())
764      return CXTypeLayoutError_Dependent;
765    // recurse
766    if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
767      if (const RecordDecl *Child = ChildType->getDecl()) {
768        long long ret = visitRecordForValidation(Child);
769        if (ret < 0)
770          return ret;
771      }
772    }
773    // else try next field
774  }
775  return 0;
776}
777
778static long long validateFieldParentType(CXCursor PC, CXType PT){
779  if (clang_isInvalid(PC.kind))
780    return CXTypeLayoutError_Invalid;
781  const RecordDecl *RD =
782        dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
783  // validate parent declaration
784  if (!RD || RD->isInvalidDecl())
785    return CXTypeLayoutError_Invalid;
786  RD = RD->getDefinition();
787  if (!RD)
788    return CXTypeLayoutError_Incomplete;
789  if (RD->isInvalidDecl())
790    return CXTypeLayoutError_Invalid;
791  // validate parent type
792  QualType RT = GetQualType(PT);
793  if (RT->isIncompleteType())
794    return CXTypeLayoutError_Incomplete;
795  if (RT->isDependentType())
796    return CXTypeLayoutError_Dependent;
797  // We recurse into all record fields to detect incomplete and dependent types.
798  long long Error = visitRecordForValidation(RD);
799  if (Error < 0)
800    return Error;
801  return 0;
802}
803
804long long clang_Type_getOffsetOf(CXType PT, const char *S) {
805  // check that PT is not incomplete/dependent
806  CXCursor PC = clang_getTypeDeclaration(PT);
807  long long Error = validateFieldParentType(PC,PT);
808  if (Error < 0)
809    return Error;
810  if (!S)
811    return CXTypeLayoutError_InvalidFieldName;
812  // lookup field
813  ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
814  IdentifierInfo *II = &Ctx.Idents.get(S);
815  DeclarationName FieldName(II);
816  const RecordDecl *RD =
817        dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
818  // verified in validateFieldParentType
819  RD = RD->getDefinition();
820  RecordDecl::lookup_result Res = RD->lookup(FieldName);
821  // If a field of the parent record is incomplete, lookup will fail.
822  // and we would return InvalidFieldName instead of Incomplete.
823  // But this erroneous results does protects again a hidden assertion failure
824  // in the RecordLayoutBuilder
825  if (Res.size() != 1)
826    return CXTypeLayoutError_InvalidFieldName;
827  if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
828    return Ctx.getFieldOffset(FD);
829  if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
830    return Ctx.getFieldOffset(IFD);
831  // we don't want any other Decl Type.
832  return CXTypeLayoutError_InvalidFieldName;
833}
834
835long long clang_Cursor_getOffsetOfField(CXCursor C) {
836  if (clang_isDeclaration(C.kind)) {
837    // we need to validate the parent type
838    CXCursor PC = clang_getCursorSemanticParent(C);
839    CXType PT = clang_getCursorType(PC);
840    long long Error = validateFieldParentType(PC,PT);
841    if (Error < 0)
842      return Error;
843    // proceed with the offset calculation
844    const Decl *D = cxcursor::getCursorDecl(C);
845    ASTContext &Ctx = cxcursor::getCursorContext(C);
846    if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
847      return Ctx.getFieldOffset(FD);
848    if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
849      return Ctx.getFieldOffset(IFD);
850  }
851  return -1;
852}
853
854enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
855  QualType QT = GetQualType(T);
856  if (QT.isNull())
857    return CXRefQualifier_None;
858  const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
859  if (!FD)
860    return CXRefQualifier_None;
861  switch (FD->getRefQualifier()) {
862    case RQ_None:
863      return CXRefQualifier_None;
864    case RQ_LValue:
865      return CXRefQualifier_LValue;
866    case RQ_RValue:
867      return CXRefQualifier_RValue;
868  }
869  return CXRefQualifier_None;
870}
871
872unsigned clang_Cursor_isBitField(CXCursor C) {
873  if (!clang_isDeclaration(C.kind))
874    return 0;
875  const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
876  if (!FD)
877    return 0;
878  return FD->isBitField();
879}
880
881CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
882  if (!clang_isDeclaration(C.kind))
883    return cxstring::createEmpty();
884
885  const Decl *D = cxcursor::getCursorDecl(C);
886  ASTContext &Ctx = cxcursor::getCursorContext(C);
887  std::string encoding;
888
889  if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))  {
890    if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
891      return cxstring::createRef("?");
892  } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
893    Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr, encoding);
894  else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
895    Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
896  else {
897    QualType Ty;
898    if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
899      Ty = Ctx.getTypeDeclType(TD);
900    if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
901      Ty = VD->getType();
902    else return cxstring::createRef("?");
903    Ctx.getObjCEncodingForType(Ty, encoding);
904  }
905
906  return cxstring::createDup(encoding);
907}
908
909int clang_Type_getNumTemplateArguments(CXType CT) {
910  QualType T = GetQualType(CT);
911  if (T.isNull())
912    return -1;
913  const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
914  if (!RecordDecl)
915    return -1;
916  const ClassTemplateSpecializationDecl *TemplateDecl =
917      dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
918  if (!TemplateDecl)
919    return -1;
920  return TemplateDecl->getTemplateArgs().size();
921}
922
923CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) {
924  QualType T = GetQualType(CT);
925  if (T.isNull())
926    return MakeCXType(QualType(), GetTU(CT));
927  const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
928  if (!RecordDecl)
929    return MakeCXType(QualType(), GetTU(CT));
930  const ClassTemplateSpecializationDecl *TemplateDecl =
931      dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
932  if (!TemplateDecl)
933    return MakeCXType(QualType(), GetTU(CT));
934  const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs();
935  if (TA.size() <= i)
936    return MakeCXType(QualType(), GetTU(CT));
937  const TemplateArgument &A = TA.get(i);
938  if (A.getKind() != TemplateArgument::Type)
939    return MakeCXType(QualType(), GetTU(CT));
940  return MakeCXType(A.getAsType(), GetTU(CT));
941}
942
943unsigned clang_Type_visitFields(CXType PT,
944                                CXFieldVisitor visitor,
945                                CXClientData client_data){
946  CXCursor PC = clang_getTypeDeclaration(PT);
947  if (clang_isInvalid(PC.kind))
948    return false;
949  const RecordDecl *RD =
950        dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
951  if (!RD || RD->isInvalidDecl())
952    return false;
953  RD = RD->getDefinition();
954  if (!RD || RD->isInvalidDecl())
955    return false;
956
957  for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
958       I != E; ++I){
959    const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
960    // Callback to the client.
961    switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
962    case CXVisit_Break:
963      return true;
964    case CXVisit_Continue:
965      break;
966    }
967  }
968  return true;
969}
970
971unsigned clang_Cursor_isAnonymous(CXCursor C){
972  if (!clang_isDeclaration(C.kind))
973    return 0;
974  const Decl *D = cxcursor::getCursorDecl(C);
975  if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
976    return FD->isAnonymousStructOrUnion();
977  return 0;
978}
979
980} // end: extern "C"
981