blob: 90c665882a970fccf078b6c286ac3cc9ab43bbde [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"
15#include "CXCursor.h"
Ted Kremeneked122732010-11-16 01:56:27 +000016#include "CXString.h"
Ted Kremenek95f33552010-08-26 01:42:22 +000017#include "CXType.h"
Ted Kremenek8e0ac172010-05-14 21:29:26 +000018#include "clang/AST/Expr.h"
19#include "clang/AST/Type.h"
20#include "clang/AST/Decl.h"
21#include "clang/AST/DeclObjC.h"
Douglas Gregor3f0fee32010-10-02 21:57:58 +000022#include "clang/AST/DeclTemplate.h"
Ted Kremenek8e0ac172010-05-14 21:29:26 +000023#include "clang/Frontend/ASTUnit.h"
24
25using namespace clang;
26
27static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
28#define BTCASE(K) case BuiltinType::K: return CXType_##K
29 switch (BT->getKind()) {
30 BTCASE(Void);
31 BTCASE(Bool);
32 BTCASE(Char_U);
33 BTCASE(UChar);
34 BTCASE(Char16);
35 BTCASE(Char32);
36 BTCASE(UShort);
37 BTCASE(UInt);
38 BTCASE(ULong);
39 BTCASE(ULongLong);
40 BTCASE(UInt128);
41 BTCASE(Char_S);
42 BTCASE(SChar);
43 BTCASE(WChar);
44 BTCASE(Short);
45 BTCASE(Int);
46 BTCASE(Long);
47 BTCASE(LongLong);
48 BTCASE(Int128);
49 BTCASE(Float);
50 BTCASE(Double);
51 BTCASE(LongDouble);
52 BTCASE(NullPtr);
53 BTCASE(Overload);
54 BTCASE(Dependent);
55 BTCASE(ObjCId);
56 BTCASE(ObjCClass);
57 BTCASE(ObjCSel);
58 default:
59 return CXType_Unexposed;
60 }
61#undef BTCASE
62}
63
64static CXTypeKind GetTypeKind(QualType T) {
65 Type *TP = T.getTypePtr();
66 if (!TP)
67 return CXType_Invalid;
68
69#define TKCASE(K) case Type::K: return CXType_##K
70 switch (TP->getTypeClass()) {
71 case Type::Builtin:
72 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
73 TKCASE(Complex);
74 TKCASE(Pointer);
75 TKCASE(BlockPointer);
76 TKCASE(LValueReference);
77 TKCASE(RValueReference);
78 TKCASE(Record);
79 TKCASE(Enum);
80 TKCASE(Typedef);
81 TKCASE(ObjCInterface);
82 TKCASE(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +000083 TKCASE(FunctionNoProto);
84 TKCASE(FunctionProto);
Ted Kremenek8e0ac172010-05-14 21:29:26 +000085 default:
86 return CXType_Unexposed;
87 }
88#undef TKCASE
89}
90
Ted Kremenek95f33552010-08-26 01:42:22 +000091
Ted Kremeneka60ed472010-11-16 08:15:36 +000092CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
Ted Kremenek8e0ac172010-05-14 21:29:26 +000093 CXTypeKind TK = GetTypeKind(T);
94 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
95 return CT;
96}
97
Ted Kremenek95f33552010-08-26 01:42:22 +000098using cxtype::MakeCXType;
99
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000100static inline QualType GetQualType(CXType CT) {
101 return QualType::getFromOpaquePtr(CT.data[0]);
102}
103
Ted Kremeneka60ed472010-11-16 08:15:36 +0000104static inline CXTranslationUnit GetTU(CXType CT) {
105 return static_cast<CXTranslationUnit>(CT.data[1]);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000106}
107
108extern "C" {
109
110CXType clang_getCursorType(CXCursor C) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000111 using namespace cxcursor;
112
Ted Kremeneka60ed472010-11-16 08:15:36 +0000113 CXTranslationUnit TU = cxcursor::getCursorTU(C);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000114 if (clang_isExpression(C.kind)) {
115 QualType T = cxcursor::getCursorExpr(C)->getType();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000116 return MakeCXType(T, TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000117 }
118
119 if (clang_isDeclaration(C.kind)) {
120 Decl *D = cxcursor::getCursorDecl(C);
121
122 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000123 return MakeCXType(QualType(TD->getTypeForDecl(), 0), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000124 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000125 return MakeCXType(QualType(ID->getTypeForDecl(), 0), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000126 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000127 return MakeCXType(VD->getType(), TU);
Ted Kremenek0d32a682010-06-21 19:41:40 +0000128 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000129 return MakeCXType(PD->getType(), TU);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000130 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000131 return MakeCXType(FD->getType(), TU);
132 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000133 }
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000134
135 if (clang_isReference(C.kind)) {
136 switch (C.kind) {
137 case CXCursor_ObjCSuperClassRef:
138 return MakeCXType(
139 QualType(getCursorObjCSuperClassRef(C).first->getTypeForDecl(),
140 0),
Ted Kremeneka60ed472010-11-16 08:15:36 +0000141 TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000142
143 case CXCursor_ObjCClassRef:
144 return MakeCXType(
145 QualType(getCursorObjCClassRef(C).first->getTypeForDecl(),
146 0),
Ted Kremeneka60ed472010-11-16 08:15:36 +0000147 TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000148
149 case CXCursor_TypeRef:
150 return MakeCXType(QualType(getCursorTypeRef(C).first->getTypeForDecl(),
151 0),
Ted Kremeneka60ed472010-11-16 08:15:36 +0000152 TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000153
154 case CXCursor_CXXBaseSpecifier:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000155 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000156
157 case CXCursor_ObjCProtocolRef:
158 case CXCursor_TemplateRef:
159 case CXCursor_NamespaceRef:
160 case CXCursor_MemberRef:
161 case CXCursor_OverloadedDeclRef:
162 default:
163 break;
164 }
165
Ted Kremeneka60ed472010-11-16 08:15:36 +0000166 return MakeCXType(QualType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000167 }
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000168
Ted Kremeneka60ed472010-11-16 08:15:36 +0000169 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000170}
171
172CXType clang_getCanonicalType(CXType CT) {
173 if (CT.kind == CXType_Invalid)
174 return CT;
175
176 QualType T = GetQualType(CT);
Ted Kremeneka60ed472010-11-16 08:15:36 +0000177 CXTranslationUnit TU = GetTU(CT);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000178
179 if (T.isNull())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000180 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000181
Ted Kremeneka60ed472010-11-16 08:15:36 +0000182 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
183 return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000184}
185
186CXType clang_getPointeeType(CXType CT) {
187 QualType T = GetQualType(CT);
188 Type *TP = T.getTypePtr();
189
190 if (!TP)
Ted Kremeneka60ed472010-11-16 08:15:36 +0000191 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000192
193 switch (TP->getTypeClass()) {
194 case Type::Pointer:
195 T = cast<PointerType>(TP)->getPointeeType();
196 break;
197 case Type::BlockPointer:
198 T = cast<BlockPointerType>(TP)->getPointeeType();
199 break;
200 case Type::LValueReference:
201 case Type::RValueReference:
202 T = cast<ReferenceType>(TP)->getPointeeType();
203 break;
204 case Type::ObjCObjectPointer:
205 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
206 break;
207 default:
208 T = QualType();
209 break;
210 }
Ted Kremeneka60ed472010-11-16 08:15:36 +0000211 return MakeCXType(T, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000212}
213
214CXCursor clang_getTypeDeclaration(CXType CT) {
Ted Kremenekb3da5392010-05-29 20:01:52 +0000215 if (CT.kind == CXType_Invalid)
216 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
217
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000218 QualType T = GetQualType(CT);
219 Type *TP = T.getTypePtr();
Ted Kremenekb3da5392010-05-29 20:01:52 +0000220
221 if (!TP)
222 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
223
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000224 Decl *D = 0;
225
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000226try_again:
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000227 switch (TP->getTypeClass()) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000228 case Type::Typedef:
229 D = cast<TypedefType>(TP)->getDecl();
230 break;
231 case Type::ObjCObject:
232 D = cast<ObjCObjectType>(TP)->getInterface();
233 break;
234 case Type::ObjCInterface:
235 D = cast<ObjCInterfaceType>(TP)->getDecl();
236 break;
237 case Type::Record:
238 case Type::Enum:
239 D = cast<TagType>(TP)->getDecl();
240 break;
241 case Type::TemplateSpecialization:
242 if (const RecordType *Record = TP->getAs<RecordType>())
243 D = Record->getDecl();
244 else
245 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
246 .getAsTemplateDecl();
247 break;
248
249 case Type::InjectedClassName:
250 D = cast<InjectedClassNameType>(TP)->getDecl();
251 break;
252
253 // FIXME: Template type parameters!
254
255 case Type::Elaborated:
256 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtr();
257 goto try_again;
258
259 default:
260 break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000261 }
262
263 if (!D)
264 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
265
Ted Kremeneka60ed472010-11-16 08:15:36 +0000266 return cxcursor::MakeCXCursor(D, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000267}
268
269CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
270 const char *s = 0;
271#define TKIND(X) case CXType_##X: s = "" #X ""; break
272 switch (K) {
273 TKIND(Invalid);
274 TKIND(Unexposed);
275 TKIND(Void);
276 TKIND(Bool);
277 TKIND(Char_U);
278 TKIND(UChar);
279 TKIND(Char16);
280 TKIND(Char32);
281 TKIND(UShort);
282 TKIND(UInt);
283 TKIND(ULong);
284 TKIND(ULongLong);
285 TKIND(UInt128);
286 TKIND(Char_S);
287 TKIND(SChar);
288 TKIND(WChar);
289 TKIND(Short);
290 TKIND(Int);
291 TKIND(Long);
292 TKIND(LongLong);
293 TKIND(Int128);
294 TKIND(Float);
295 TKIND(Double);
296 TKIND(LongDouble);
297 TKIND(NullPtr);
298 TKIND(Overload);
299 TKIND(Dependent);
300 TKIND(ObjCId);
301 TKIND(ObjCClass);
302 TKIND(ObjCSel);
303 TKIND(Complex);
304 TKIND(Pointer);
305 TKIND(BlockPointer);
306 TKIND(LValueReference);
307 TKIND(RValueReference);
308 TKIND(Record);
309 TKIND(Enum);
310 TKIND(Typedef);
311 TKIND(ObjCInterface);
312 TKIND(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000313 TKIND(FunctionNoProto);
314 TKIND(FunctionProto);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000315 }
316#undef TKIND
317 return cxstring::createCXString(s);
318}
319
320unsigned clang_equalTypes(CXType A, CXType B) {
321 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
322}
323
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000324CXType clang_getResultType(CXType X) {
325 QualType T = GetQualType(X);
326 if (!T.getTypePtr())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000327 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000328
329 if (const FunctionType *FD = T->getAs<FunctionType>())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000330 return MakeCXType(FD->getResultType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000331
Ted Kremeneka60ed472010-11-16 08:15:36 +0000332 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000333}
334
Ted Kremenek9a140842010-06-21 20:48:56 +0000335CXType clang_getCursorResultType(CXCursor C) {
336 if (clang_isDeclaration(C.kind)) {
337 Decl *D = cxcursor::getCursorDecl(C);
338 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000339 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000340
341 return clang_getResultType(clang_getCursorType(C));
342 }
343
Ted Kremeneka60ed472010-11-16 08:15:36 +0000344 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000345}
346
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000347unsigned clang_isPODType(CXType X) {
348 QualType T = GetQualType(X);
349 if (!T.getTypePtr())
350 return 0;
351 return T->isPODType() ? 1 : 0;
352}
353
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000354} // end: extern "C"