]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/libclang/CXType.cpp
Vendor import of clang trunk r161861:
[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 = 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
118 using cxtype::MakeCXType;
119
120 static inline QualType GetQualType(CXType CT) {
121   return QualType::getFromOpaquePtr(CT.data[0]);
122 }
123
124 static inline CXTranslationUnit GetTU(CXType CT) {
125   return static_cast<CXTranslationUnit>(CT.data[1]);
126 }
127
128 extern "C" {
129
130 CXType 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
200 CXType 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
218 CXType 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
236 long 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
252 unsigned 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
268 CXType clang_getCanonicalType(CXType CT) {
269   if (CT.kind == CXType_Invalid)
270     return CT;
271
272   QualType T = GetQualType(CT);
273   CXTranslationUnit TU = GetTU(CT);
274
275   if (T.isNull())
276     return MakeCXType(QualType(), GetTU(CT));
277
278   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
279   return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
280 }
281
282 unsigned clang_isConstQualifiedType(CXType CT) {
283   QualType T = GetQualType(CT);
284   return T.isLocalConstQualified();
285 }
286
287 unsigned clang_isVolatileQualifiedType(CXType CT) {
288   QualType T = GetQualType(CT);
289   return T.isLocalVolatileQualified();
290 }
291
292 unsigned clang_isRestrictQualifiedType(CXType CT) {
293   QualType T = GetQualType(CT);
294   return T.isLocalRestrictQualified();
295 }
296
297 CXType clang_getPointeeType(CXType CT) {
298   QualType T = GetQualType(CT);
299   const Type *TP = T.getTypePtrOrNull();
300   
301   if (!TP)
302     return MakeCXType(QualType(), GetTU(CT));
303   
304   switch (TP->getTypeClass()) {
305     case Type::Pointer:
306       T = cast<PointerType>(TP)->getPointeeType();
307       break;
308     case Type::BlockPointer:
309       T = cast<BlockPointerType>(TP)->getPointeeType();
310       break;
311     case Type::LValueReference:
312     case Type::RValueReference:
313       T = cast<ReferenceType>(TP)->getPointeeType();
314       break;
315     case Type::ObjCObjectPointer:
316       T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
317       break;
318     default:
319       T = QualType();
320       break;
321   }
322   return MakeCXType(T, GetTU(CT));
323 }
324
325 CXCursor clang_getTypeDeclaration(CXType CT) {
326   if (CT.kind == CXType_Invalid)
327     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
328
329   QualType T = GetQualType(CT);
330   const Type *TP = T.getTypePtrOrNull();
331
332   if (!TP)
333     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
334
335   Decl *D = 0;
336
337 try_again:
338   switch (TP->getTypeClass()) {
339   case Type::Typedef:
340     D = cast<TypedefType>(TP)->getDecl();
341     break;
342   case Type::ObjCObject:
343     D = cast<ObjCObjectType>(TP)->getInterface();
344     break;
345   case Type::ObjCInterface:
346     D = cast<ObjCInterfaceType>(TP)->getDecl();
347     break;
348   case Type::Record:
349   case Type::Enum:
350     D = cast<TagType>(TP)->getDecl();
351     break;
352   case Type::TemplateSpecialization:
353     if (const RecordType *Record = TP->getAs<RecordType>())
354       D = Record->getDecl();
355     else
356       D = cast<TemplateSpecializationType>(TP)->getTemplateName()
357                                                          .getAsTemplateDecl();
358     break;
359       
360   case Type::InjectedClassName:
361     D = cast<InjectedClassNameType>(TP)->getDecl();
362     break;
363
364   // FIXME: Template type parameters!      
365
366   case Type::Elaborated:
367     TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
368     goto try_again;
369     
370   default:
371     break;
372   }
373
374   if (!D)
375     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
376
377   return cxcursor::MakeCXCursor(D, GetTU(CT));
378 }
379
380 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
381   const char *s = 0;
382 #define TKIND(X) case CXType_##X: s = ""  #X  ""; break
383   switch (K) {
384     TKIND(Invalid);
385     TKIND(Unexposed);
386     TKIND(Void);
387     TKIND(Bool);
388     TKIND(Char_U);
389     TKIND(UChar);
390     TKIND(Char16);
391     TKIND(Char32);  
392     TKIND(UShort);
393     TKIND(UInt);
394     TKIND(ULong);
395     TKIND(ULongLong);
396     TKIND(UInt128);
397     TKIND(Char_S);
398     TKIND(SChar);
399     case CXType_WChar: s = "WChar"; break;
400     TKIND(Short);
401     TKIND(Int);
402     TKIND(Long);
403     TKIND(LongLong);
404     TKIND(Int128);
405     TKIND(Float);
406     TKIND(Double);
407     TKIND(LongDouble);
408     TKIND(NullPtr);
409     TKIND(Overload);
410     TKIND(Dependent);
411     TKIND(ObjCId);
412     TKIND(ObjCClass);
413     TKIND(ObjCSel);
414     TKIND(Complex);
415     TKIND(Pointer);
416     TKIND(BlockPointer);
417     TKIND(LValueReference);
418     TKIND(RValueReference);
419     TKIND(Record);
420     TKIND(Enum);
421     TKIND(Typedef);
422     TKIND(ObjCInterface);
423     TKIND(ObjCObjectPointer);
424     TKIND(FunctionNoProto);
425     TKIND(FunctionProto);
426     TKIND(ConstantArray);
427     TKIND(Vector);
428   }
429 #undef TKIND
430   return cxstring::createCXString(s);
431 }
432
433 unsigned clang_equalTypes(CXType A, CXType B) {
434   return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
435 }
436
437 unsigned clang_isFunctionTypeVariadic(CXType X) {
438   QualType T = GetQualType(X);
439   if (T.isNull())
440     return 0;
441
442   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
443     return (unsigned)FD->isVariadic();
444
445   if (T->getAs<FunctionNoProtoType>())
446     return 1;
447   
448   return 0;
449 }
450
451 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
452   QualType T = GetQualType(X);
453   if (T.isNull())
454     return CXCallingConv_Invalid;
455   
456   if (const FunctionType *FD = T->getAs<FunctionType>()) {
457 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
458     switch (FD->getCallConv()) {
459       TCALLINGCONV(Default);
460       TCALLINGCONV(C);
461       TCALLINGCONV(X86StdCall);
462       TCALLINGCONV(X86FastCall);
463       TCALLINGCONV(X86ThisCall);
464       TCALLINGCONV(X86Pascal);
465       TCALLINGCONV(AAPCS);
466       TCALLINGCONV(AAPCS_VFP);
467     }
468 #undef TCALLINGCONV
469   }
470   
471   return CXCallingConv_Invalid;
472 }
473
474 int clang_getNumArgTypes(CXType X) {
475   QualType T = GetQualType(X);
476   if (T.isNull())
477     return -1;
478   
479   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
480     return FD->getNumArgs();
481   }
482   
483   if (T->getAs<FunctionNoProtoType>()) {
484     return 0;
485   }
486   
487   return -1;
488 }
489
490 CXType clang_getArgType(CXType X, unsigned i) {
491   QualType T = GetQualType(X);
492   if (T.isNull())
493     return MakeCXType(QualType(), GetTU(X));
494
495   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
496     unsigned numArgs = FD->getNumArgs();
497     if (i >= numArgs)
498       return MakeCXType(QualType(), GetTU(X));
499     
500     return MakeCXType(FD->getArgType(i), GetTU(X));
501   }
502   
503   return MakeCXType(QualType(), GetTU(X));
504 }
505
506 CXType clang_getResultType(CXType X) {
507   QualType T = GetQualType(X);
508   if (T.isNull())
509     return MakeCXType(QualType(), GetTU(X));
510   
511   if (const FunctionType *FD = T->getAs<FunctionType>())
512     return MakeCXType(FD->getResultType(), GetTU(X));
513   
514   return MakeCXType(QualType(), GetTU(X));
515 }
516
517 CXType clang_getCursorResultType(CXCursor C) {
518   if (clang_isDeclaration(C.kind)) {
519     Decl *D = cxcursor::getCursorDecl(C);
520     if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
521       return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
522
523     return clang_getResultType(clang_getCursorType(C));
524   }
525
526   return MakeCXType(QualType(), cxcursor::getCursorTU(C));
527 }
528
529 unsigned clang_isPODType(CXType X) {
530   QualType T = GetQualType(X);
531   if (T.isNull())
532     return 0;
533   
534   CXTranslationUnit TU = GetTU(X);
535   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
536
537   return T.isPODType(AU->getASTContext()) ? 1 : 0;
538 }
539
540 CXType clang_getElementType(CXType CT) {
541   QualType ET = QualType();
542   QualType T = GetQualType(CT);
543   const Type *TP = T.getTypePtrOrNull();
544
545   if (TP) {
546     switch (TP->getTypeClass()) {
547     case Type::ConstantArray:
548       ET = cast<ConstantArrayType> (TP)->getElementType();
549       break;
550     case Type::Vector:
551       ET = cast<VectorType> (TP)->getElementType();
552       break;
553     case Type::Complex:
554       ET = cast<ComplexType> (TP)->getElementType();
555       break;
556     default:
557       break;
558     }
559   }
560   return MakeCXType(ET, GetTU(CT));
561 }
562
563 long long clang_getNumElements(CXType CT) {
564   long long result = -1;
565   QualType T = GetQualType(CT);
566   const Type *TP = T.getTypePtrOrNull();
567
568   if (TP) {
569     switch (TP->getTypeClass()) {
570     case Type::ConstantArray:
571       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
572       break;
573     case Type::Vector:
574       result = cast<VectorType> (TP)->getNumElements();
575       break;
576     default:
577       break;
578     }
579   }
580   return result;
581 }
582
583 CXType clang_getArrayElementType(CXType CT) {
584   QualType ET = QualType();
585   QualType T = GetQualType(CT);
586   const Type *TP = T.getTypePtrOrNull();
587
588   if (TP) {
589     switch (TP->getTypeClass()) {
590     case Type::ConstantArray:
591       ET = cast<ConstantArrayType> (TP)->getElementType();
592       break;
593     default:
594       break;
595     }
596   }
597   return MakeCXType(ET, GetTU(CT));
598 }
599
600 long long clang_getArraySize(CXType CT) {
601   long long result = -1;
602   QualType T = GetQualType(CT);
603   const Type *TP = T.getTypePtrOrNull();
604
605   if (TP) {
606     switch (TP->getTypeClass()) {
607     case Type::ConstantArray:
608       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
609       break;
610     default:
611       break;
612     }
613   }
614   return result;
615 }
616
617 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
618   if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl))
619     return cxstring::createCXString("");
620
621   Decl *D = static_cast<Decl*>(C.data[0]);
622   CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
623   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
624   ASTContext &Ctx = AU->getASTContext();
625   std::string encoding;
626
627   if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))  {
628     if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
629       return cxstring::createCXString("?");
630   } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 
631     Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
632   else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
633     Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
634   else {
635     QualType Ty;
636     if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
637       Ty = Ctx.getTypeDeclType(TD);
638     if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
639       Ty = VD->getType();
640     else return cxstring::createCXString("?");
641     Ctx.getObjCEncodingForType(Ty, encoding);
642   }
643
644   return cxstring::createCXString(encoding);
645 }
646
647 } // end: extern "C"