]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/libclang/CXType.cpp
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):
[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       TCALLINGCONV(PnaclCall);
468     }
469 #undef TCALLINGCONV
470   }
471   
472   return CXCallingConv_Invalid;
473 }
474
475 int clang_getNumArgTypes(CXType X) {
476   QualType T = GetQualType(X);
477   if (T.isNull())
478     return -1;
479   
480   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
481     return FD->getNumArgs();
482   }
483   
484   if (T->getAs<FunctionNoProtoType>()) {
485     return 0;
486   }
487   
488   return -1;
489 }
490
491 CXType clang_getArgType(CXType X, unsigned i) {
492   QualType T = GetQualType(X);
493   if (T.isNull())
494     return MakeCXType(QualType(), GetTU(X));
495
496   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
497     unsigned numArgs = FD->getNumArgs();
498     if (i >= numArgs)
499       return MakeCXType(QualType(), GetTU(X));
500     
501     return MakeCXType(FD->getArgType(i), GetTU(X));
502   }
503   
504   return MakeCXType(QualType(), GetTU(X));
505 }
506
507 CXType clang_getResultType(CXType X) {
508   QualType T = GetQualType(X);
509   if (T.isNull())
510     return MakeCXType(QualType(), GetTU(X));
511   
512   if (const FunctionType *FD = T->getAs<FunctionType>())
513     return MakeCXType(FD->getResultType(), GetTU(X));
514   
515   return MakeCXType(QualType(), GetTU(X));
516 }
517
518 CXType clang_getCursorResultType(CXCursor C) {
519   if (clang_isDeclaration(C.kind)) {
520     Decl *D = cxcursor::getCursorDecl(C);
521     if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
522       return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
523
524     return clang_getResultType(clang_getCursorType(C));
525   }
526
527   return MakeCXType(QualType(), cxcursor::getCursorTU(C));
528 }
529
530 unsigned clang_isPODType(CXType X) {
531   QualType T = GetQualType(X);
532   if (T.isNull())
533     return 0;
534   
535   CXTranslationUnit TU = GetTU(X);
536   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
537
538   return T.isPODType(AU->getASTContext()) ? 1 : 0;
539 }
540
541 CXType clang_getElementType(CXType CT) {
542   QualType ET = QualType();
543   QualType T = GetQualType(CT);
544   const Type *TP = T.getTypePtrOrNull();
545
546   if (TP) {
547     switch (TP->getTypeClass()) {
548     case Type::ConstantArray:
549       ET = cast<ConstantArrayType> (TP)->getElementType();
550       break;
551     case Type::Vector:
552       ET = cast<VectorType> (TP)->getElementType();
553       break;
554     case Type::Complex:
555       ET = cast<ComplexType> (TP)->getElementType();
556       break;
557     default:
558       break;
559     }
560   }
561   return MakeCXType(ET, GetTU(CT));
562 }
563
564 long long clang_getNumElements(CXType CT) {
565   long long result = -1;
566   QualType T = GetQualType(CT);
567   const Type *TP = T.getTypePtrOrNull();
568
569   if (TP) {
570     switch (TP->getTypeClass()) {
571     case Type::ConstantArray:
572       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
573       break;
574     case Type::Vector:
575       result = cast<VectorType> (TP)->getNumElements();
576       break;
577     default:
578       break;
579     }
580   }
581   return result;
582 }
583
584 CXType clang_getArrayElementType(CXType CT) {
585   QualType ET = QualType();
586   QualType T = GetQualType(CT);
587   const Type *TP = T.getTypePtrOrNull();
588
589   if (TP) {
590     switch (TP->getTypeClass()) {
591     case Type::ConstantArray:
592       ET = cast<ConstantArrayType> (TP)->getElementType();
593       break;
594     default:
595       break;
596     }
597   }
598   return MakeCXType(ET, GetTU(CT));
599 }
600
601 long long clang_getArraySize(CXType CT) {
602   long long result = -1;
603   QualType T = GetQualType(CT);
604   const Type *TP = T.getTypePtrOrNull();
605
606   if (TP) {
607     switch (TP->getTypeClass()) {
608     case Type::ConstantArray:
609       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
610       break;
611     default:
612       break;
613     }
614   }
615   return result;
616 }
617
618 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
619   if (!clang_isDeclaration(C.kind))
620     return cxstring::createCXString("");
621
622   Decl *D = static_cast<Decl*>(C.data[0]);
623   CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
624   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
625   ASTContext &Ctx = AU->getASTContext();
626   std::string encoding;
627
628   if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))  {
629     if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
630       return cxstring::createCXString("?");
631   } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 
632     Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
633   else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
634     Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
635   else {
636     QualType Ty;
637     if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
638       Ty = Ctx.getTypeDeclType(TD);
639     if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
640       Ty = VD->getType();
641     else return cxstring::createCXString("?");
642     Ctx.getObjCEncodingForType(Ty, encoding);
643   }
644
645   return cxstring::createCXString(encoding);
646 }
647
648 } // end: extern "C"