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