blob: ae756c7a1eea2bf68a4ab30b2f2c8d551bd0e808 [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);
80 default:
81 return CXType_Unexposed;
82 }
83#undef TKCASE
84}
85
86static CXType MakeCXType(QualType T, ASTUnit *TU) {
87 CXTypeKind TK = GetTypeKind(T);
88 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
89 return CT;
90}
91
92static inline QualType GetQualType(CXType CT) {
93 return QualType::getFromOpaquePtr(CT.data[0]);
94}
95
96static inline ASTUnit* GetASTU(CXType CT) {
97 return static_cast<ASTUnit*>(CT.data[1]);
98}
99
100extern "C" {
101
102CXType clang_getCursorType(CXCursor C) {
103 ASTUnit *AU = cxcursor::getCursorASTUnit(C);
104
105 if (clang_isExpression(C.kind)) {
106 QualType T = cxcursor::getCursorExpr(C)->getType();
107 return MakeCXType(T, AU);
108 }
109
110 if (clang_isDeclaration(C.kind)) {
111 Decl *D = cxcursor::getCursorDecl(C);
112
113 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
114 return MakeCXType(QualType(TD->getTypeForDecl(), 0), AU);
115 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
116 return MakeCXType(QualType(ID->getTypeForDecl(), 0), AU);
117 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
118 return MakeCXType(VD->getType(), AU);
Ted Kremenek0d32a682010-06-21 19:41:40 +0000119 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
120 return MakeCXType(PD->getType(), AU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000121
122 return MakeCXType(QualType(), AU);
123 }
124
125 return MakeCXType(QualType(), AU);
126}
127
128CXType clang_getCanonicalType(CXType CT) {
129 if (CT.kind == CXType_Invalid)
130 return CT;
131
132 QualType T = GetQualType(CT);
133
134 if (T.isNull())
135 return MakeCXType(QualType(), GetASTU(CT));
136
137 ASTUnit *AU = GetASTU(CT);
138 return MakeCXType(AU->getASTContext().getCanonicalType(T), AU);
139}
140
141CXType clang_getPointeeType(CXType CT) {
142 QualType T = GetQualType(CT);
143 Type *TP = T.getTypePtr();
144
145 if (!TP)
146 return MakeCXType(QualType(), GetASTU(CT));
147
148 switch (TP->getTypeClass()) {
149 case Type::Pointer:
150 T = cast<PointerType>(TP)->getPointeeType();
151 break;
152 case Type::BlockPointer:
153 T = cast<BlockPointerType>(TP)->getPointeeType();
154 break;
155 case Type::LValueReference:
156 case Type::RValueReference:
157 T = cast<ReferenceType>(TP)->getPointeeType();
158 break;
159 case Type::ObjCObjectPointer:
160 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
161 break;
162 default:
163 T = QualType();
164 break;
165 }
166 return MakeCXType(T, GetASTU(CT));
167}
168
169CXCursor clang_getTypeDeclaration(CXType CT) {
Ted Kremenekb3da5392010-05-29 20:01:52 +0000170 if (CT.kind == CXType_Invalid)
171 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
172
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000173 QualType T = GetQualType(CT);
174 Type *TP = T.getTypePtr();
Ted Kremenekb3da5392010-05-29 20:01:52 +0000175
176 if (!TP)
177 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
178
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000179 Decl *D = 0;
180
181 switch (TP->getTypeClass()) {
182 case Type::Typedef:
183 D = cast<TypedefType>(TP)->getDecl();
184 break;
John McCallc12c5bb2010-05-15 11:32:37 +0000185 case Type::ObjCObject:
186 D = cast<ObjCObjectType>(TP)->getInterface();
187 break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000188 case Type::ObjCInterface:
189 D = cast<ObjCInterfaceType>(TP)->getDecl();
190 break;
191 case Type::Record:
192 case Type::Enum:
193 D = cast<TagType>(TP)->getDecl();
194 break;
195 default:
196 break;
197 }
198
199 if (!D)
200 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
201
202 return cxcursor::MakeCXCursor(D, GetASTU(CT));
203}
204
205CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
206 const char *s = 0;
207#define TKIND(X) case CXType_##X: s = "" #X ""; break
208 switch (K) {
209 TKIND(Invalid);
210 TKIND(Unexposed);
211 TKIND(Void);
212 TKIND(Bool);
213 TKIND(Char_U);
214 TKIND(UChar);
215 TKIND(Char16);
216 TKIND(Char32);
217 TKIND(UShort);
218 TKIND(UInt);
219 TKIND(ULong);
220 TKIND(ULongLong);
221 TKIND(UInt128);
222 TKIND(Char_S);
223 TKIND(SChar);
224 TKIND(WChar);
225 TKIND(Short);
226 TKIND(Int);
227 TKIND(Long);
228 TKIND(LongLong);
229 TKIND(Int128);
230 TKIND(Float);
231 TKIND(Double);
232 TKIND(LongDouble);
233 TKIND(NullPtr);
234 TKIND(Overload);
235 TKIND(Dependent);
236 TKIND(ObjCId);
237 TKIND(ObjCClass);
238 TKIND(ObjCSel);
239 TKIND(Complex);
240 TKIND(Pointer);
241 TKIND(BlockPointer);
242 TKIND(LValueReference);
243 TKIND(RValueReference);
244 TKIND(Record);
245 TKIND(Enum);
246 TKIND(Typedef);
247 TKIND(ObjCInterface);
248 TKIND(ObjCObjectPointer);
249 }
250#undef TKIND
251 return cxstring::createCXString(s);
252}
253
254unsigned clang_equalTypes(CXType A, CXType B) {
255 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
256}
257
258} // end: extern "C"