CXType.cpp revision 1eb60825f0b858a4568c1a9497cc61b0d90c9b3a
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(Vector);
89    default:
90      return CXType_Unexposed;
91  }
92#undef TKCASE
93}
94
95
96CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
97  CXTypeKind TK = CXType_Invalid;
98
99  if (TU && !T.isNull()) {
100    ASTContext &Ctx = static_cast<ASTUnit *>(TU->TUData)->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
118using cxtype::MakeCXType;
119
120static inline QualType GetQualType(CXType CT) {
121  return QualType::getFromOpaquePtr(CT.data[0]);
122}
123
124static inline CXTranslationUnit GetTU(CXType CT) {
125  return static_cast<CXTranslationUnit>(CT.data[1]);
126}
127
128extern "C" {
129
130CXType clang_getCursorType(CXCursor C) {
131  using namespace cxcursor;
132
133  CXTranslationUnit TU = cxcursor::getCursorTU(C);
134  ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
135  if (clang_isExpression(C.kind)) {
136    QualType T = cxcursor::getCursorExpr(C)->getType();
137    return MakeCXType(T, TU);
138  }
139
140  if (clang_isDeclaration(C.kind)) {
141    Decl *D = cxcursor::getCursorDecl(C);
142    if (!D)
143      return MakeCXType(QualType(), TU);
144
145    if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
146      return MakeCXType(Context.getTypeDeclType(TD), TU);
147    if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
148      return MakeCXType(Context.getObjCInterfaceType(ID), TU);
149    if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
150      return MakeCXType(VD->getType(), TU);
151    if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
152      return MakeCXType(PD->getType(), TU);
153    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
154      return MakeCXType(FD->getType(), TU);
155    return MakeCXType(QualType(), TU);
156  }
157
158  if (clang_isReference(C.kind)) {
159    switch (C.kind) {
160    case CXCursor_ObjCSuperClassRef: {
161      QualType T
162        = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
163      return MakeCXType(T, TU);
164    }
165
166    case CXCursor_ObjCClassRef: {
167      QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
168      return MakeCXType(T, TU);
169    }
170
171    case CXCursor_TypeRef: {
172      QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
173      return MakeCXType(T, TU);
174
175    }
176
177    case CXCursor_CXXBaseSpecifier:
178      return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
179
180    case CXCursor_MemberRef:
181      return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
182
183    case CXCursor_VariableRef:
184      return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
185
186    case CXCursor_ObjCProtocolRef:
187    case CXCursor_TemplateRef:
188    case CXCursor_NamespaceRef:
189    case CXCursor_OverloadedDeclRef:
190    default:
191      break;
192    }
193
194    return MakeCXType(QualType(), TU);
195  }
196
197  return MakeCXType(QualType(), TU);
198}
199
200CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
201  using namespace cxcursor;
202  CXTranslationUnit TU = cxcursor::getCursorTU(C);
203
204  if (clang_isDeclaration(C.kind)) {
205    Decl *D = cxcursor::getCursorDecl(C);
206
207    if (TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
208      QualType T = TD->getUnderlyingType();
209      return MakeCXType(T, TU);
210    }
211
212    return MakeCXType(QualType(), TU);
213  }
214
215  return MakeCXType(QualType(), TU);
216}
217
218CXType clang_getEnumDeclIntegerType(CXCursor C) {
219  using namespace cxcursor;
220  CXTranslationUnit TU = cxcursor::getCursorTU(C);
221
222  if (clang_isDeclaration(C.kind)) {
223    Decl *D = cxcursor::getCursorDecl(C);
224
225    if (EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
226      QualType T = TD->getIntegerType();
227      return MakeCXType(T, TU);
228    }
229
230    return MakeCXType(QualType(), TU);
231  }
232
233  return MakeCXType(QualType(), TU);
234}
235
236long long clang_getEnumConstantDeclValue(CXCursor C) {
237  using namespace cxcursor;
238
239  if (clang_isDeclaration(C.kind)) {
240    Decl *D = cxcursor::getCursorDecl(C);
241
242    if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
243      return TD->getInitVal().getSExtValue();
244    }
245
246    return LLONG_MIN;
247  }
248
249  return LLONG_MIN;
250}
251
252unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
253  using namespace cxcursor;
254
255  if (clang_isDeclaration(C.kind)) {
256    Decl *D = cxcursor::getCursorDecl(C);
257
258    if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
259      return TD->getInitVal().getZExtValue();
260    }
261
262    return ULLONG_MAX;
263  }
264
265  return ULLONG_MAX;
266}
267
268int clang_getFieldDeclBitWidth(CXCursor C) {
269  using namespace cxcursor;
270
271  if (clang_isDeclaration(C.kind)) {
272    Decl *D = getCursorDecl(C);
273
274    if (FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
275      if (FD->isBitField())
276        return FD->getBitWidthValue(getCursorContext(C));
277    }
278  }
279
280  return -1;
281}
282
283CXType clang_getCanonicalType(CXType CT) {
284  if (CT.kind == CXType_Invalid)
285    return CT;
286
287  QualType T = GetQualType(CT);
288  CXTranslationUnit TU = GetTU(CT);
289
290  if (T.isNull())
291    return MakeCXType(QualType(), GetTU(CT));
292
293  ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
294  return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
295}
296
297unsigned clang_isConstQualifiedType(CXType CT) {
298  QualType T = GetQualType(CT);
299  return T.isLocalConstQualified();
300}
301
302unsigned clang_isVolatileQualifiedType(CXType CT) {
303  QualType T = GetQualType(CT);
304  return T.isLocalVolatileQualified();
305}
306
307unsigned clang_isRestrictQualifiedType(CXType CT) {
308  QualType T = GetQualType(CT);
309  return T.isLocalRestrictQualified();
310}
311
312CXType clang_getPointeeType(CXType CT) {
313  QualType T = GetQualType(CT);
314  const Type *TP = T.getTypePtrOrNull();
315
316  if (!TP)
317    return MakeCXType(QualType(), GetTU(CT));
318
319  switch (TP->getTypeClass()) {
320    case Type::Pointer:
321      T = cast<PointerType>(TP)->getPointeeType();
322      break;
323    case Type::BlockPointer:
324      T = cast<BlockPointerType>(TP)->getPointeeType();
325      break;
326    case Type::LValueReference:
327    case Type::RValueReference:
328      T = cast<ReferenceType>(TP)->getPointeeType();
329      break;
330    case Type::ObjCObjectPointer:
331      T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
332      break;
333    default:
334      T = QualType();
335      break;
336  }
337  return MakeCXType(T, GetTU(CT));
338}
339
340CXCursor clang_getTypeDeclaration(CXType CT) {
341  if (CT.kind == CXType_Invalid)
342    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
343
344  QualType T = GetQualType(CT);
345  const Type *TP = T.getTypePtrOrNull();
346
347  if (!TP)
348    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
349
350  Decl *D = 0;
351
352try_again:
353  switch (TP->getTypeClass()) {
354  case Type::Typedef:
355    D = cast<TypedefType>(TP)->getDecl();
356    break;
357  case Type::ObjCObject:
358    D = cast<ObjCObjectType>(TP)->getInterface();
359    break;
360  case Type::ObjCInterface:
361    D = cast<ObjCInterfaceType>(TP)->getDecl();
362    break;
363  case Type::Record:
364  case Type::Enum:
365    D = cast<TagType>(TP)->getDecl();
366    break;
367  case Type::TemplateSpecialization:
368    if (const RecordType *Record = TP->getAs<RecordType>())
369      D = Record->getDecl();
370    else
371      D = cast<TemplateSpecializationType>(TP)->getTemplateName()
372                                                         .getAsTemplateDecl();
373    break;
374
375  case Type::InjectedClassName:
376    D = cast<InjectedClassNameType>(TP)->getDecl();
377    break;
378
379  // FIXME: Template type parameters!
380
381  case Type::Elaborated:
382    TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
383    goto try_again;
384
385  default:
386    break;
387  }
388
389  if (!D)
390    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
391
392  return cxcursor::MakeCXCursor(D, GetTU(CT));
393}
394
395CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
396  const char *s = 0;
397#define TKIND(X) case CXType_##X: s = ""  #X  ""; break
398  switch (K) {
399    TKIND(Invalid);
400    TKIND(Unexposed);
401    TKIND(Void);
402    TKIND(Bool);
403    TKIND(Char_U);
404    TKIND(UChar);
405    TKIND(Char16);
406    TKIND(Char32);
407    TKIND(UShort);
408    TKIND(UInt);
409    TKIND(ULong);
410    TKIND(ULongLong);
411    TKIND(UInt128);
412    TKIND(Char_S);
413    TKIND(SChar);
414    case CXType_WChar: s = "WChar"; break;
415    TKIND(Short);
416    TKIND(Int);
417    TKIND(Long);
418    TKIND(LongLong);
419    TKIND(Int128);
420    TKIND(Float);
421    TKIND(Double);
422    TKIND(LongDouble);
423    TKIND(NullPtr);
424    TKIND(Overload);
425    TKIND(Dependent);
426    TKIND(ObjCId);
427    TKIND(ObjCClass);
428    TKIND(ObjCSel);
429    TKIND(Complex);
430    TKIND(Pointer);
431    TKIND(BlockPointer);
432    TKIND(LValueReference);
433    TKIND(RValueReference);
434    TKIND(Record);
435    TKIND(Enum);
436    TKIND(Typedef);
437    TKIND(ObjCInterface);
438    TKIND(ObjCObjectPointer);
439    TKIND(FunctionNoProto);
440    TKIND(FunctionProto);
441    TKIND(ConstantArray);
442    TKIND(Vector);
443  }
444#undef TKIND
445  return cxstring::createCXString(s);
446}
447
448unsigned clang_equalTypes(CXType A, CXType B) {
449  return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
450}
451
452unsigned clang_isFunctionTypeVariadic(CXType X) {
453  QualType T = GetQualType(X);
454  if (T.isNull())
455    return 0;
456
457  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
458    return (unsigned)FD->isVariadic();
459
460  if (T->getAs<FunctionNoProtoType>())
461    return 1;
462
463  return 0;
464}
465
466CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
467  QualType T = GetQualType(X);
468  if (T.isNull())
469    return CXCallingConv_Invalid;
470
471  if (const FunctionType *FD = T->getAs<FunctionType>()) {
472#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
473    switch (FD->getCallConv()) {
474      TCALLINGCONV(Default);
475      TCALLINGCONV(C);
476      TCALLINGCONV(X86StdCall);
477      TCALLINGCONV(X86FastCall);
478      TCALLINGCONV(X86ThisCall);
479      TCALLINGCONV(X86Pascal);
480      TCALLINGCONV(AAPCS);
481      TCALLINGCONV(AAPCS_VFP);
482      TCALLINGCONV(PnaclCall);
483    }
484#undef TCALLINGCONV
485  }
486
487  return CXCallingConv_Invalid;
488}
489
490int clang_getNumArgTypes(CXType X) {
491  QualType T = GetQualType(X);
492  if (T.isNull())
493    return -1;
494
495  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
496    return FD->getNumArgs();
497  }
498
499  if (T->getAs<FunctionNoProtoType>()) {
500    return 0;
501  }
502
503  return -1;
504}
505
506CXType clang_getArgType(CXType X, unsigned i) {
507  QualType T = GetQualType(X);
508  if (T.isNull())
509    return MakeCXType(QualType(), GetTU(X));
510
511  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
512    unsigned numArgs = FD->getNumArgs();
513    if (i >= numArgs)
514      return MakeCXType(QualType(), GetTU(X));
515
516    return MakeCXType(FD->getArgType(i), GetTU(X));
517  }
518
519  return MakeCXType(QualType(), GetTU(X));
520}
521
522CXType clang_getResultType(CXType X) {
523  QualType T = GetQualType(X);
524  if (T.isNull())
525    return MakeCXType(QualType(), GetTU(X));
526
527  if (const FunctionType *FD = T->getAs<FunctionType>())
528    return MakeCXType(FD->getResultType(), GetTU(X));
529
530  return MakeCXType(QualType(), GetTU(X));
531}
532
533CXType clang_getCursorResultType(CXCursor C) {
534  if (clang_isDeclaration(C.kind)) {
535    Decl *D = cxcursor::getCursorDecl(C);
536    if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
537      return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
538
539    return clang_getResultType(clang_getCursorType(C));
540  }
541
542  return MakeCXType(QualType(), cxcursor::getCursorTU(C));
543}
544
545unsigned clang_isPODType(CXType X) {
546  QualType T = GetQualType(X);
547  if (T.isNull())
548    return 0;
549
550  CXTranslationUnit TU = GetTU(X);
551  ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
552
553  return T.isPODType(AU->getASTContext()) ? 1 : 0;
554}
555
556CXType clang_getElementType(CXType CT) {
557  QualType ET = QualType();
558  QualType T = GetQualType(CT);
559  const Type *TP = T.getTypePtrOrNull();
560
561  if (TP) {
562    switch (TP->getTypeClass()) {
563    case Type::ConstantArray:
564      ET = cast<ConstantArrayType> (TP)->getElementType();
565      break;
566    case Type::Vector:
567      ET = cast<VectorType> (TP)->getElementType();
568      break;
569    case Type::Complex:
570      ET = cast<ComplexType> (TP)->getElementType();
571      break;
572    default:
573      break;
574    }
575  }
576  return MakeCXType(ET, GetTU(CT));
577}
578
579long long clang_getNumElements(CXType CT) {
580  long long result = -1;
581  QualType T = GetQualType(CT);
582  const Type *TP = T.getTypePtrOrNull();
583
584  if (TP) {
585    switch (TP->getTypeClass()) {
586    case Type::ConstantArray:
587      result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
588      break;
589    case Type::Vector:
590      result = cast<VectorType> (TP)->getNumElements();
591      break;
592    default:
593      break;
594    }
595  }
596  return result;
597}
598
599CXType clang_getArrayElementType(CXType CT) {
600  QualType ET = QualType();
601  QualType T = GetQualType(CT);
602  const Type *TP = T.getTypePtrOrNull();
603
604  if (TP) {
605    switch (TP->getTypeClass()) {
606    case Type::ConstantArray:
607      ET = cast<ConstantArrayType> (TP)->getElementType();
608      break;
609    default:
610      break;
611    }
612  }
613  return MakeCXType(ET, GetTU(CT));
614}
615
616long long clang_getArraySize(CXType CT) {
617  long long result = -1;
618  QualType T = GetQualType(CT);
619  const Type *TP = T.getTypePtrOrNull();
620
621  if (TP) {
622    switch (TP->getTypeClass()) {
623    case Type::ConstantArray:
624      result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
625      break;
626    default:
627      break;
628    }
629  }
630  return result;
631}
632
633CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
634  if (!clang_isDeclaration(C.kind))
635    return cxstring::createCXString("");
636
637  Decl *D = static_cast<Decl*>(C.data[0]);
638  CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
639  ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
640  ASTContext &Ctx = AU->getASTContext();
641  std::string encoding;
642
643  if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))  {
644    if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
645      return cxstring::createCXString("?");
646  } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
647    Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
648  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
649    Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
650  else {
651    QualType Ty;
652    if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
653      Ty = Ctx.getTypeDeclType(TD);
654    if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
655      Ty = VD->getType();
656    else return cxstring::createCXString("?");
657    Ctx.getObjCEncodingForType(Ty, encoding);
658  }
659
660  return cxstring::createCXString(encoding);
661}
662
663} // end: extern "C"
664