blob: 7b603c0f93294b1836e3f8f199f21e802dc510dd [file] [log] [blame]
Ted Kremenek8e0ac172010-05-14 21:29:26 +00001//===- 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"
Ted Kremenek0a90d322010-11-17 23:24:11 +000015#include "CXTranslationUnit.h"
Ted Kremenek8e0ac172010-05-14 21:29:26 +000016#include "CXCursor.h"
Ted Kremeneked122732010-11-16 01:56:27 +000017#include "CXString.h"
Ted Kremenek95f33552010-08-26 01:42:22 +000018#include "CXType.h"
Ted Kremenek8e0ac172010-05-14 21:29:26 +000019#include "clang/AST/Expr.h"
20#include "clang/AST/Type.h"
21#include "clang/AST/Decl.h"
22#include "clang/AST/DeclObjC.h"
Douglas Gregor3f0fee32010-10-02 21:57:58 +000023#include "clang/AST/DeclTemplate.h"
Ted Kremenek8e0ac172010-05-14 21:29:26 +000024#include "clang/Frontend/ASTUnit.h"
25
26using namespace clang;
27
28static 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);
Chris Lattner3f59c972010-12-25 23:25:43 +000044 case BuiltinType::WChar_S: return CXType_WChar;
45 case BuiltinType::WChar_U: return CXType_WChar;
Ted Kremenek8e0ac172010-05-14 21:29:26 +000046 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
66static CXTypeKind GetTypeKind(QualType T) {
John McCallf4c73712011-01-19 06:33:43 +000067 const Type *TP = T.getTypePtrOrNull();
Ted Kremenek8e0ac172010-05-14 21:29:26 +000068 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);
Ted Kremenek04c3cf32010-06-21 20:15:39 +000085 TKCASE(FunctionNoProto);
86 TKCASE(FunctionProto);
Ted Kremenek8e0ac172010-05-14 21:29:26 +000087 default:
88 return CXType_Unexposed;
89 }
90#undef TKCASE
91}
92
Ted Kremenek95f33552010-08-26 01:42:22 +000093
Ted Kremeneka60ed472010-11-16 08:15:36 +000094CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
Ted Kremenek8e0ac172010-05-14 21:29:26 +000095 CXTypeKind TK = GetTypeKind(T);
96 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
97 return CT;
98}
99
Ted Kremenek95f33552010-08-26 01:42:22 +0000100using cxtype::MakeCXType;
101
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000102static inline QualType GetQualType(CXType CT) {
103 return QualType::getFromOpaquePtr(CT.data[0]);
104}
105
Ted Kremeneka60ed472010-11-16 08:15:36 +0000106static inline CXTranslationUnit GetTU(CXType CT) {
107 return static_cast<CXTranslationUnit>(CT.data[1]);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000108}
109
110extern "C" {
111
112CXType clang_getCursorType(CXCursor C) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000113 using namespace cxcursor;
114
Ted Kremeneka60ed472010-11-16 08:15:36 +0000115 CXTranslationUnit TU = cxcursor::getCursorTU(C);
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000116 ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000117 if (clang_isExpression(C.kind)) {
118 QualType T = cxcursor::getCursorExpr(C)->getType();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000119 return MakeCXType(T, TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000120 }
121
122 if (clang_isDeclaration(C.kind)) {
123 Decl *D = cxcursor::getCursorDecl(C);
124
125 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000126 return MakeCXType(Context.getTypeDeclType(TD), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000127 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000128 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000129 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000130 return MakeCXType(VD->getType(), TU);
Ted Kremenek0d32a682010-06-21 19:41:40 +0000131 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000132 return MakeCXType(PD->getType(), TU);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000133 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000134 return MakeCXType(FD->getType(), TU);
135 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000136 }
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000137
138 if (clang_isReference(C.kind)) {
139 switch (C.kind) {
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000140 case CXCursor_ObjCSuperClassRef: {
141 QualType T
142 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
143 return MakeCXType(T, TU);
144 }
145
146 case CXCursor_ObjCClassRef: {
147 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
148 return MakeCXType(T, TU);
149 }
150
151 case CXCursor_TypeRef: {
152 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
153 return MakeCXType(T, TU);
154
155 }
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000156
157 case CXCursor_CXXBaseSpecifier:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000158 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000159
160 case CXCursor_ObjCProtocolRef:
161 case CXCursor_TemplateRef:
162 case CXCursor_NamespaceRef:
163 case CXCursor_MemberRef:
164 case CXCursor_OverloadedDeclRef:
165 default:
166 break;
167 }
168
Ted Kremeneka60ed472010-11-16 08:15:36 +0000169 return MakeCXType(QualType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000170 }
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000171
Ted Kremeneka60ed472010-11-16 08:15:36 +0000172 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000173}
174
175CXType clang_getCanonicalType(CXType CT) {
176 if (CT.kind == CXType_Invalid)
177 return CT;
178
179 QualType T = GetQualType(CT);
Ted Kremeneka60ed472010-11-16 08:15:36 +0000180 CXTranslationUnit TU = GetTU(CT);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000181
182 if (T.isNull())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000183 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000184
Ted Kremeneka60ed472010-11-16 08:15:36 +0000185 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
186 return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000187}
188
189CXType clang_getPointeeType(CXType CT) {
190 QualType T = GetQualType(CT);
John McCallf4c73712011-01-19 06:33:43 +0000191 const Type *TP = T.getTypePtrOrNull();
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000192
193 if (!TP)
Ted Kremeneka60ed472010-11-16 08:15:36 +0000194 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000195
196 switch (TP->getTypeClass()) {
197 case Type::Pointer:
198 T = cast<PointerType>(TP)->getPointeeType();
199 break;
200 case Type::BlockPointer:
201 T = cast<BlockPointerType>(TP)->getPointeeType();
202 break;
203 case Type::LValueReference:
204 case Type::RValueReference:
205 T = cast<ReferenceType>(TP)->getPointeeType();
206 break;
207 case Type::ObjCObjectPointer:
208 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
209 break;
210 default:
211 T = QualType();
212 break;
213 }
Ted Kremeneka60ed472010-11-16 08:15:36 +0000214 return MakeCXType(T, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000215}
216
217CXCursor clang_getTypeDeclaration(CXType CT) {
Ted Kremenekb3da5392010-05-29 20:01:52 +0000218 if (CT.kind == CXType_Invalid)
219 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
220
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000221 QualType T = GetQualType(CT);
John McCallf4c73712011-01-19 06:33:43 +0000222 const Type *TP = T.getTypePtrOrNull();
Ted Kremenekb3da5392010-05-29 20:01:52 +0000223
224 if (!TP)
225 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
226
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000227 Decl *D = 0;
228
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000229try_again:
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000230 switch (TP->getTypeClass()) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000231 case Type::Typedef:
232 D = cast<TypedefType>(TP)->getDecl();
233 break;
234 case Type::ObjCObject:
235 D = cast<ObjCObjectType>(TP)->getInterface();
236 break;
237 case Type::ObjCInterface:
238 D = cast<ObjCInterfaceType>(TP)->getDecl();
239 break;
240 case Type::Record:
241 case Type::Enum:
242 D = cast<TagType>(TP)->getDecl();
243 break;
244 case Type::TemplateSpecialization:
245 if (const RecordType *Record = TP->getAs<RecordType>())
246 D = Record->getDecl();
247 else
248 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
249 .getAsTemplateDecl();
250 break;
251
252 case Type::InjectedClassName:
253 D = cast<InjectedClassNameType>(TP)->getDecl();
254 break;
255
256 // FIXME: Template type parameters!
257
258 case Type::Elaborated:
Douglas Gregor1ab55e92010-12-10 17:03:06 +0000259 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000260 goto try_again;
261
262 default:
263 break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000264 }
265
266 if (!D)
267 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
268
Ted Kremeneka60ed472010-11-16 08:15:36 +0000269 return cxcursor::MakeCXCursor(D, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000270}
271
272CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
273 const char *s = 0;
274#define TKIND(X) case CXType_##X: s = "" #X ""; break
275 switch (K) {
276 TKIND(Invalid);
277 TKIND(Unexposed);
278 TKIND(Void);
279 TKIND(Bool);
280 TKIND(Char_U);
281 TKIND(UChar);
282 TKIND(Char16);
283 TKIND(Char32);
284 TKIND(UShort);
285 TKIND(UInt);
286 TKIND(ULong);
287 TKIND(ULongLong);
288 TKIND(UInt128);
289 TKIND(Char_S);
290 TKIND(SChar);
Chris Lattner3f59c972010-12-25 23:25:43 +0000291 case CXType_WChar: s = "WChar"; break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000292 TKIND(Short);
293 TKIND(Int);
294 TKIND(Long);
295 TKIND(LongLong);
296 TKIND(Int128);
297 TKIND(Float);
298 TKIND(Double);
299 TKIND(LongDouble);
300 TKIND(NullPtr);
301 TKIND(Overload);
302 TKIND(Dependent);
303 TKIND(ObjCId);
304 TKIND(ObjCClass);
305 TKIND(ObjCSel);
306 TKIND(Complex);
307 TKIND(Pointer);
308 TKIND(BlockPointer);
309 TKIND(LValueReference);
310 TKIND(RValueReference);
311 TKIND(Record);
312 TKIND(Enum);
313 TKIND(Typedef);
314 TKIND(ObjCInterface);
315 TKIND(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000316 TKIND(FunctionNoProto);
317 TKIND(FunctionProto);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000318 }
319#undef TKIND
320 return cxstring::createCXString(s);
321}
322
323unsigned clang_equalTypes(CXType A, CXType B) {
324 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
325}
326
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000327CXType clang_getResultType(CXType X) {
328 QualType T = GetQualType(X);
Douglas Gregor1ab55e92010-12-10 17:03:06 +0000329 if (!T.getTypePtrOrNull())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000330 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000331
332 if (const FunctionType *FD = T->getAs<FunctionType>())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000333 return MakeCXType(FD->getResultType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000334
Ted Kremeneka60ed472010-11-16 08:15:36 +0000335 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000336}
337
Ted Kremenek9a140842010-06-21 20:48:56 +0000338CXType clang_getCursorResultType(CXCursor C) {
339 if (clang_isDeclaration(C.kind)) {
340 Decl *D = cxcursor::getCursorDecl(C);
341 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000342 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000343
344 return clang_getResultType(clang_getCursorType(C));
345 }
346
Ted Kremeneka60ed472010-11-16 08:15:36 +0000347 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000348}
349
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000350unsigned clang_isPODType(CXType X) {
351 QualType T = GetQualType(X);
Douglas Gregor1ab55e92010-12-10 17:03:06 +0000352 if (!T.getTypePtrOrNull())
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000353 return 0;
354 return T->isPODType() ? 1 : 0;
355}
356
David Chisnall5389f482010-12-30 14:05:53 +0000357CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
358 if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl))
359 return cxstring::createCXString("");
360
361 Decl *D = static_cast<Decl*>(C.data[0]);
362 CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
363 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
364 ASTContext &Ctx = AU->getASTContext();
365 std::string encoding;
366
367 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
368 Ctx.getObjCEncodingForMethodDecl(OMD, encoding);
369 else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
370 Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
371 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
372 Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
373 else {
374 QualType Ty;
375 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000376 Ty = Ctx.getTypeDeclType(TD);
David Chisnall5389f482010-12-30 14:05:53 +0000377 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
378 Ty = VD->getType();
379 else return cxstring::createCXString("?");
380 Ctx.getObjCEncodingForType(Ty, encoding);
381 }
382
383 return cxstring::createCXString(encoding);
384}
385
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000386} // end: extern "C"