blob: 28dc12a344face3c0af271534d7a7eccf4c2de86 [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);
119
120 return MakeCXType(QualType(), AU);
121 }
122
123 return MakeCXType(QualType(), AU);
124}
125
126CXType clang_getCanonicalType(CXType CT) {
127 if (CT.kind == CXType_Invalid)
128 return CT;
129
130 QualType T = GetQualType(CT);
131
132 if (T.isNull())
133 return MakeCXType(QualType(), GetASTU(CT));
134
135 ASTUnit *AU = GetASTU(CT);
136 return MakeCXType(AU->getASTContext().getCanonicalType(T), AU);
137}
138
139CXType clang_getPointeeType(CXType CT) {
140 QualType T = GetQualType(CT);
141 Type *TP = T.getTypePtr();
142
143 if (!TP)
144 return MakeCXType(QualType(), GetASTU(CT));
145
146 switch (TP->getTypeClass()) {
147 case Type::Pointer:
148 T = cast<PointerType>(TP)->getPointeeType();
149 break;
150 case Type::BlockPointer:
151 T = cast<BlockPointerType>(TP)->getPointeeType();
152 break;
153 case Type::LValueReference:
154 case Type::RValueReference:
155 T = cast<ReferenceType>(TP)->getPointeeType();
156 break;
157 case Type::ObjCObjectPointer:
158 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
159 break;
160 default:
161 T = QualType();
162 break;
163 }
164 return MakeCXType(T, GetASTU(CT));
165}
166
167CXCursor clang_getTypeDeclaration(CXType CT) {
168 QualType T = GetQualType(CT);
169 Type *TP = T.getTypePtr();
170 Decl *D = 0;
171
172 switch (TP->getTypeClass()) {
173 case Type::Typedef:
174 D = cast<TypedefType>(TP)->getDecl();
175 break;
176 case Type::ObjCInterface:
177 D = cast<ObjCInterfaceType>(TP)->getDecl();
178 break;
179 case Type::Record:
180 case Type::Enum:
181 D = cast<TagType>(TP)->getDecl();
182 break;
183 default:
184 break;
185 }
186
187 if (!D)
188 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
189
190 return cxcursor::MakeCXCursor(D, GetASTU(CT));
191}
192
193CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
194 const char *s = 0;
195#define TKIND(X) case CXType_##X: s = "" #X ""; break
196 switch (K) {
197 TKIND(Invalid);
198 TKIND(Unexposed);
199 TKIND(Void);
200 TKIND(Bool);
201 TKIND(Char_U);
202 TKIND(UChar);
203 TKIND(Char16);
204 TKIND(Char32);
205 TKIND(UShort);
206 TKIND(UInt);
207 TKIND(ULong);
208 TKIND(ULongLong);
209 TKIND(UInt128);
210 TKIND(Char_S);
211 TKIND(SChar);
212 TKIND(WChar);
213 TKIND(Short);
214 TKIND(Int);
215 TKIND(Long);
216 TKIND(LongLong);
217 TKIND(Int128);
218 TKIND(Float);
219 TKIND(Double);
220 TKIND(LongDouble);
221 TKIND(NullPtr);
222 TKIND(Overload);
223 TKIND(Dependent);
224 TKIND(ObjCId);
225 TKIND(ObjCClass);
226 TKIND(ObjCSel);
227 TKIND(Complex);
228 TKIND(Pointer);
229 TKIND(BlockPointer);
230 TKIND(LValueReference);
231 TKIND(RValueReference);
232 TKIND(Record);
233 TKIND(Enum);
234 TKIND(Typedef);
235 TKIND(ObjCInterface);
236 TKIND(ObjCObjectPointer);
237 }
238#undef TKIND
239 return cxstring::createCXString(s);
240}
241
242unsigned clang_equalTypes(CXType A, CXType B) {
243 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
244}
245
246} // end: extern "C"