]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/libclang/CXType.cpp
Vendor import of clang release_30 branch r142614:
[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     default:
89       return CXType_Unexposed;
90   }
91 #undef TKCASE
92 }
93
94
95 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
96   CXTypeKind TK = GetTypeKind(T);
97   CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
98   return CT;
99 }
100
101 using cxtype::MakeCXType;
102
103 static inline QualType GetQualType(CXType CT) {
104   return QualType::getFromOpaquePtr(CT.data[0]);
105 }
106
107 static inline CXTranslationUnit GetTU(CXType CT) {
108   return static_cast<CXTranslationUnit>(CT.data[1]);
109 }
110
111 extern "C" {
112
113 CXType clang_getCursorType(CXCursor C) {
114   using namespace cxcursor;
115   
116   CXTranslationUnit TU = cxcursor::getCursorTU(C);
117   ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
118   if (clang_isExpression(C.kind)) {
119     QualType T = cxcursor::getCursorExpr(C)->getType();
120     return MakeCXType(T, TU);
121   }
122
123   if (clang_isDeclaration(C.kind)) {
124     Decl *D = cxcursor::getCursorDecl(C);
125
126     if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
127       return MakeCXType(Context.getTypeDeclType(TD), TU);
128     if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
129       return MakeCXType(Context.getObjCInterfaceType(ID), TU);
130     if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
131       return MakeCXType(VD->getType(), TU);
132     if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
133       return MakeCXType(PD->getType(), TU);
134     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
135       return MakeCXType(FD->getType(), TU);
136     return MakeCXType(QualType(), TU);
137   }
138   
139   if (clang_isReference(C.kind)) {
140     switch (C.kind) {
141     case CXCursor_ObjCSuperClassRef: {
142       QualType T
143         = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
144       return MakeCXType(T, TU);
145     }
146         
147     case CXCursor_ObjCClassRef: {
148       QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
149       return MakeCXType(T, TU);
150     }
151         
152     case CXCursor_TypeRef: {
153       QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
154       return MakeCXType(T, TU);
155
156     }
157       
158     case CXCursor_CXXBaseSpecifier:
159       return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
160       
161     case CXCursor_ObjCProtocolRef:        
162     case CXCursor_TemplateRef:
163     case CXCursor_NamespaceRef:
164     case CXCursor_MemberRef:
165     case CXCursor_OverloadedDeclRef:      
166     default:
167       break;
168     }
169     
170     return MakeCXType(QualType(), TU);
171   }
172
173   return MakeCXType(QualType(), TU);
174 }
175
176 CXType clang_getCanonicalType(CXType CT) {
177   if (CT.kind == CXType_Invalid)
178     return CT;
179
180   QualType T = GetQualType(CT);
181   CXTranslationUnit TU = GetTU(CT);
182
183   if (T.isNull())
184     return MakeCXType(QualType(), GetTU(CT));
185
186   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
187   return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
188 }
189
190 unsigned clang_isConstQualifiedType(CXType CT) {
191   QualType T = GetQualType(CT);
192   return T.isLocalConstQualified();
193 }
194
195 unsigned clang_isVolatileQualifiedType(CXType CT) {
196   QualType T = GetQualType(CT);
197   return T.isLocalVolatileQualified();
198 }
199
200 unsigned clang_isRestrictQualifiedType(CXType CT) {
201   QualType T = GetQualType(CT);
202   return T.isLocalRestrictQualified();
203 }
204
205 CXType clang_getPointeeType(CXType CT) {
206   QualType T = GetQualType(CT);
207   const Type *TP = T.getTypePtrOrNull();
208   
209   if (!TP)
210     return MakeCXType(QualType(), GetTU(CT));
211   
212   switch (TP->getTypeClass()) {
213     case Type::Pointer:
214       T = cast<PointerType>(TP)->getPointeeType();
215       break;
216     case Type::BlockPointer:
217       T = cast<BlockPointerType>(TP)->getPointeeType();
218       break;
219     case Type::LValueReference:
220     case Type::RValueReference:
221       T = cast<ReferenceType>(TP)->getPointeeType();
222       break;
223     case Type::ObjCObjectPointer:
224       T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
225       break;
226     default:
227       T = QualType();
228       break;
229   }
230   return MakeCXType(T, GetTU(CT));
231 }
232
233 CXCursor clang_getTypeDeclaration(CXType CT) {
234   if (CT.kind == CXType_Invalid)
235     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
236
237   QualType T = GetQualType(CT);
238   const Type *TP = T.getTypePtrOrNull();
239
240   if (!TP)
241     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
242
243   Decl *D = 0;
244
245 try_again:
246   switch (TP->getTypeClass()) {
247   case Type::Typedef:
248     D = cast<TypedefType>(TP)->getDecl();
249     break;
250   case Type::ObjCObject:
251     D = cast<ObjCObjectType>(TP)->getInterface();
252     break;
253   case Type::ObjCInterface:
254     D = cast<ObjCInterfaceType>(TP)->getDecl();
255     break;
256   case Type::Record:
257   case Type::Enum:
258     D = cast<TagType>(TP)->getDecl();
259     break;
260   case Type::TemplateSpecialization:
261     if (const RecordType *Record = TP->getAs<RecordType>())
262       D = Record->getDecl();
263     else
264       D = cast<TemplateSpecializationType>(TP)->getTemplateName()
265                                                          .getAsTemplateDecl();
266     break;
267       
268   case Type::InjectedClassName:
269     D = cast<InjectedClassNameType>(TP)->getDecl();
270     break;
271
272   // FIXME: Template type parameters!      
273
274   case Type::Elaborated:
275     TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
276     goto try_again;
277     
278   default:
279     break;
280   }
281
282   if (!D)
283     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
284
285   return cxcursor::MakeCXCursor(D, GetTU(CT));
286 }
287
288 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
289   const char *s = 0;
290 #define TKIND(X) case CXType_##X: s = ""  #X  ""; break
291   switch (K) {
292     TKIND(Invalid);
293     TKIND(Unexposed);
294     TKIND(Void);
295     TKIND(Bool);
296     TKIND(Char_U);
297     TKIND(UChar);
298     TKIND(Char16);
299     TKIND(Char32);  
300     TKIND(UShort);
301     TKIND(UInt);
302     TKIND(ULong);
303     TKIND(ULongLong);
304     TKIND(UInt128);
305     TKIND(Char_S);
306     TKIND(SChar);
307     case CXType_WChar: s = "WChar"; break;
308     TKIND(Short);
309     TKIND(Int);
310     TKIND(Long);
311     TKIND(LongLong);
312     TKIND(Int128);
313     TKIND(Float);
314     TKIND(Double);
315     TKIND(LongDouble);
316     TKIND(NullPtr);
317     TKIND(Overload);
318     TKIND(Dependent);
319     TKIND(ObjCId);
320     TKIND(ObjCClass);
321     TKIND(ObjCSel);
322     TKIND(Complex);
323     TKIND(Pointer);
324     TKIND(BlockPointer);
325     TKIND(LValueReference);
326     TKIND(RValueReference);
327     TKIND(Record);
328     TKIND(Enum);
329     TKIND(Typedef);
330     TKIND(ObjCInterface);
331     TKIND(ObjCObjectPointer);
332     TKIND(FunctionNoProto);
333     TKIND(FunctionProto);
334     TKIND(ConstantArray);
335   }
336 #undef TKIND
337   return cxstring::createCXString(s);
338 }
339
340 unsigned clang_equalTypes(CXType A, CXType B) {
341   return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
342 }
343
344 CXType clang_getResultType(CXType X) {
345   QualType T = GetQualType(X);
346   if (!T.getTypePtrOrNull())
347     return MakeCXType(QualType(), GetTU(X));
348   
349   if (const FunctionType *FD = T->getAs<FunctionType>())
350     return MakeCXType(FD->getResultType(), GetTU(X));
351   
352   return MakeCXType(QualType(), GetTU(X));
353 }
354
355 CXType clang_getCursorResultType(CXCursor C) {
356   if (clang_isDeclaration(C.kind)) {
357     Decl *D = cxcursor::getCursorDecl(C);
358     if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
359       return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
360
361     return clang_getResultType(clang_getCursorType(C));
362   }
363
364   return MakeCXType(QualType(), cxcursor::getCursorTU(C));
365 }
366
367 unsigned clang_isPODType(CXType X) {
368   QualType T = GetQualType(X);
369   if (!T.getTypePtrOrNull())
370     return 0;
371   
372   CXTranslationUnit TU = GetTU(X);
373   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
374
375   return T.isPODType(AU->getASTContext()) ? 1 : 0;
376 }
377
378 CXType clang_getArrayElementType(CXType CT) {
379   QualType ET = QualType();
380   QualType T = GetQualType(CT);
381   const Type *TP = T.getTypePtrOrNull();
382
383   if (TP) {
384     switch (TP->getTypeClass()) {
385     case Type::ConstantArray:
386       ET = cast<ConstantArrayType> (TP)->getElementType();
387       break;
388     default:
389       break;
390     }
391   }
392   return MakeCXType(ET, GetTU(CT));
393 }
394
395 long long clang_getArraySize(CXType CT) {
396   long long result = -1;
397   QualType T = GetQualType(CT);
398   const Type *TP = T.getTypePtrOrNull();
399
400   if (TP) {
401     switch (TP->getTypeClass()) {
402     case Type::ConstantArray:
403       result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
404       break;
405     default:
406       break;
407     }
408   }
409   return result;
410 }
411
412 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
413   if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl))
414     return cxstring::createCXString("");
415
416   Decl *D = static_cast<Decl*>(C.data[0]);
417   CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
418   ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
419   ASTContext &Ctx = AU->getASTContext();
420   std::string encoding;
421
422   if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))  {
423     if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
424       return cxstring::createCXString("?");
425   } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 
426     Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
427   else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
428     Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
429   else {
430     QualType Ty;
431     if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
432       Ty = Ctx.getTypeDeclType(TD);
433     if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
434       Ty = VD->getType();
435     else return cxstring::createCXString("?");
436     Ctx.getObjCEncodingForType(Ty, encoding);
437   }
438
439   return cxstring::createCXString(encoding);
440 }
441
442 } // end: extern "C"