blob: d5c9f452100b02bd3143c7fe1c78cf31e1524975 [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"
16#include "clang/AST/Expr.h"
17#include "clang/AST/Type.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/Frontend/ASTUnit.h"
21
22using namespace clang;
23
24static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
25#define BTCASE(K) case BuiltinType::K: return CXType_##K
26 switch (BT->getKind()) {
27 BTCASE(Void);
28 BTCASE(Bool);
29 BTCASE(Char_U);
30 BTCASE(UChar);
31 BTCASE(Char16);
32 BTCASE(Char32);
33 BTCASE(UShort);
34 BTCASE(UInt);
35 BTCASE(ULong);
36 BTCASE(ULongLong);
37 BTCASE(UInt128);
38 BTCASE(Char_S);
39 BTCASE(SChar);
40 BTCASE(WChar);
41 BTCASE(Short);
42 BTCASE(Int);
43 BTCASE(Long);
44 BTCASE(LongLong);
45 BTCASE(Int128);
46 BTCASE(Float);
47 BTCASE(Double);
48 BTCASE(LongDouble);
49 BTCASE(NullPtr);
50 BTCASE(Overload);
51 BTCASE(Dependent);
52 BTCASE(ObjCId);
53 BTCASE(ObjCClass);
54 BTCASE(ObjCSel);
55 default:
56 return CXType_Unexposed;
57 }
58#undef BTCASE
59}
60
61static CXTypeKind GetTypeKind(QualType T) {
62 Type *TP = T.getTypePtr();
63 if (!TP)
64 return CXType_Invalid;
65
66#define TKCASE(K) case Type::K: return CXType_##K
67 switch (TP->getTypeClass()) {
68 case Type::Builtin:
69 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
70 TKCASE(Complex);
71 TKCASE(Pointer);
72 TKCASE(BlockPointer);
73 TKCASE(LValueReference);
74 TKCASE(RValueReference);
75 TKCASE(Record);
76 TKCASE(Enum);
77 TKCASE(Typedef);
78 TKCASE(ObjCInterface);
79 TKCASE(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +000080 TKCASE(FunctionNoProto);
81 TKCASE(FunctionProto);
Ted Kremenek8e0ac172010-05-14 21:29:26 +000082 default:
83 return CXType_Unexposed;
84 }
85#undef TKCASE
86}
87
88static CXType MakeCXType(QualType T, ASTUnit *TU) {
89 CXTypeKind TK = GetTypeKind(T);
90 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
91 return CT;
92}
93
94static inline QualType GetQualType(CXType CT) {
95 return QualType::getFromOpaquePtr(CT.data[0]);
96}
97
98static inline ASTUnit* GetASTU(CXType CT) {
99 return static_cast<ASTUnit*>(CT.data[1]);
100}
101
102extern "C" {
103
104CXType clang_getCursorType(CXCursor C) {
105 ASTUnit *AU = cxcursor::getCursorASTUnit(C);
106
107 if (clang_isExpression(C.kind)) {
108 QualType T = cxcursor::getCursorExpr(C)->getType();
109 return MakeCXType(T, AU);
110 }
111
112 if (clang_isDeclaration(C.kind)) {
113 Decl *D = cxcursor::getCursorDecl(C);
114
115 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
116 return MakeCXType(QualType(TD->getTypeForDecl(), 0), AU);
117 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
118 return MakeCXType(QualType(ID->getTypeForDecl(), 0), AU);
119 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
120 return MakeCXType(VD->getType(), AU);
Ted Kremenek0d32a682010-06-21 19:41:40 +0000121 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
122 return MakeCXType(PD->getType(), AU);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000123 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
124 return MakeCXType(FD->getType(), AU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000125 return MakeCXType(QualType(), AU);
126 }
127
128 return MakeCXType(QualType(), AU);
129}
130
131CXType clang_getCanonicalType(CXType CT) {
132 if (CT.kind == CXType_Invalid)
133 return CT;
134
135 QualType T = GetQualType(CT);
136
137 if (T.isNull())
138 return MakeCXType(QualType(), GetASTU(CT));
139
140 ASTUnit *AU = GetASTU(CT);
141 return MakeCXType(AU->getASTContext().getCanonicalType(T), AU);
142}
143
144CXType clang_getPointeeType(CXType CT) {
145 QualType T = GetQualType(CT);
146 Type *TP = T.getTypePtr();
147
148 if (!TP)
149 return MakeCXType(QualType(), GetASTU(CT));
150
151 switch (TP->getTypeClass()) {
152 case Type::Pointer:
153 T = cast<PointerType>(TP)->getPointeeType();
154 break;
155 case Type::BlockPointer:
156 T = cast<BlockPointerType>(TP)->getPointeeType();
157 break;
158 case Type::LValueReference:
159 case Type::RValueReference:
160 T = cast<ReferenceType>(TP)->getPointeeType();
161 break;
162 case Type::ObjCObjectPointer:
163 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
164 break;
165 default:
166 T = QualType();
167 break;
168 }
169 return MakeCXType(T, GetASTU(CT));
170}
171
172CXCursor clang_getTypeDeclaration(CXType CT) {
Ted Kremenekb3da5392010-05-29 20:01:52 +0000173 if (CT.kind == CXType_Invalid)
174 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
175
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000176 QualType T = GetQualType(CT);
177 Type *TP = T.getTypePtr();
Ted Kremenekb3da5392010-05-29 20:01:52 +0000178
179 if (!TP)
180 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
181
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000182 Decl *D = 0;
183
184 switch (TP->getTypeClass()) {
185 case Type::Typedef:
186 D = cast<TypedefType>(TP)->getDecl();
187 break;
John McCallc12c5bb2010-05-15 11:32:37 +0000188 case Type::ObjCObject:
189 D = cast<ObjCObjectType>(TP)->getInterface();
190 break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000191 case Type::ObjCInterface:
192 D = cast<ObjCInterfaceType>(TP)->getDecl();
193 break;
194 case Type::Record:
195 case Type::Enum:
196 D = cast<TagType>(TP)->getDecl();
197 break;
198 default:
199 break;
200 }
201
202 if (!D)
203 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
204
205 return cxcursor::MakeCXCursor(D, GetASTU(CT));
206}
207
208CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
209 const char *s = 0;
210#define TKIND(X) case CXType_##X: s = "" #X ""; break
211 switch (K) {
212 TKIND(Invalid);
213 TKIND(Unexposed);
214 TKIND(Void);
215 TKIND(Bool);
216 TKIND(Char_U);
217 TKIND(UChar);
218 TKIND(Char16);
219 TKIND(Char32);
220 TKIND(UShort);
221 TKIND(UInt);
222 TKIND(ULong);
223 TKIND(ULongLong);
224 TKIND(UInt128);
225 TKIND(Char_S);
226 TKIND(SChar);
227 TKIND(WChar);
228 TKIND(Short);
229 TKIND(Int);
230 TKIND(Long);
231 TKIND(LongLong);
232 TKIND(Int128);
233 TKIND(Float);
234 TKIND(Double);
235 TKIND(LongDouble);
236 TKIND(NullPtr);
237 TKIND(Overload);
238 TKIND(Dependent);
239 TKIND(ObjCId);
240 TKIND(ObjCClass);
241 TKIND(ObjCSel);
242 TKIND(Complex);
243 TKIND(Pointer);
244 TKIND(BlockPointer);
245 TKIND(LValueReference);
246 TKIND(RValueReference);
247 TKIND(Record);
248 TKIND(Enum);
249 TKIND(Typedef);
250 TKIND(ObjCInterface);
251 TKIND(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000252 TKIND(FunctionNoProto);
253 TKIND(FunctionProto);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000254 }
255#undef TKIND
256 return cxstring::createCXString(s);
257}
258
259unsigned clang_equalTypes(CXType A, CXType B) {
260 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
261}
262
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000263CXType clang_getResultType(CXType X) {
264 QualType T = GetQualType(X);
265 if (!T.getTypePtr())
266 return MakeCXType(QualType(), GetASTU(X));
267
268 if (const FunctionType *FD = T->getAs<FunctionType>())
269 return MakeCXType(FD->getResultType(), GetASTU(X));
270
271 return MakeCXType(QualType(), GetASTU(X));
272}
273
Ted Kremenek9a140842010-06-21 20:48:56 +0000274CXType clang_getCursorResultType(CXCursor C) {
275 if (clang_isDeclaration(C.kind)) {
276 Decl *D = cxcursor::getCursorDecl(C);
277 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
278 return MakeCXType(MD->getResultType(), cxcursor::getCursorASTUnit(C));
279
280 return clang_getResultType(clang_getCursorType(C));
281 }
282
283 return MakeCXType(QualType(), cxcursor::getCursorASTUnit(C));
284}
285
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000286} // end: extern "C"