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