1 //===- 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 "CXTranslationUnit.h" 16 #include "CXCursor.h" 17 #include "CXString.h" 18 #include "CXType.h" 19 #include "clang/AST/Expr.h" 20 #include "clang/AST/Type.h" 21 #include "clang/AST/Decl.h" 22 #include "clang/AST/DeclObjC.h" 23 #include "clang/AST/DeclTemplate.h" 24 #include "clang/Frontend/ASTUnit.h" 25 26 using namespace clang; 27 28 static 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); 44 case BuiltinType::WChar_S: return CXType_WChar; 45 case BuiltinType::WChar_U: return CXType_WChar; 46 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 66 static CXTypeKind GetTypeKind(QualType T) { 67 const Type *TP = T.getTypePtrOrNull(); 68 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); 85 TKCASE(FunctionNoProto); 86 TKCASE(FunctionProto); 87 TKCASE(ConstantArray); 88 default: 89 return CXType_Unexposed; 90 } 91 #undef TKCASE 92 } 93 94 95 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { 96 CXTypeKind TK = GetTypeKind(T); 97 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }}; 98 return CT; 99 } 100 101 using cxtype::MakeCXType; 102 103 static inline QualType GetQualType(CXType CT) { 104 return QualType::getFromOpaquePtr(CT.data[0]); 105 } 106 107 static inline CXTranslationUnit GetTU(CXType CT) { 108 return static_cast<CXTranslationUnit>(CT.data[1]); 109 } 110 111 extern "C" { 112 113 CXType clang_getCursorType(CXCursor C) { 114 using namespace cxcursor; 115 116 CXTranslationUnit TU = cxcursor::getCursorTU(C); 117 ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext(); 118 if (clang_isExpression(C.kind)) { 119 QualType T = cxcursor::getCursorExpr(C)->getType(); 120 return MakeCXType(T, TU); 121 } 122 123 if (clang_isDeclaration(C.kind)) { 124 Decl *D = cxcursor::getCursorDecl(C); 125 126 if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) 127 return MakeCXType(Context.getTypeDeclType(TD), TU); 128 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) 129 return MakeCXType(Context.getObjCInterfaceType(ID), TU); 130 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 131 return MakeCXType(VD->getType(), TU); 132 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 133 return MakeCXType(PD->getType(), TU); 134 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 135 return MakeCXType(FD->getType(), TU); 136 return MakeCXType(QualType(), TU); 137 } 138 139 if (clang_isReference(C.kind)) { 140 switch (C.kind) { 141 case CXCursor_ObjCSuperClassRef: { 142 QualType T 143 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first); 144 return MakeCXType(T, TU); 145 } 146 147 case CXCursor_ObjCClassRef: { 148 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first); 149 return MakeCXType(T, TU); 150 } 151 152 case CXCursor_TypeRef: { 153 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first); 154 return MakeCXType(T, TU); 155 156 } 157 158 case CXCursor_CXXBaseSpecifier: 159 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU); 160 161 case CXCursor_ObjCProtocolRef: 162 case CXCursor_TemplateRef: 163 case CXCursor_NamespaceRef: 164 case CXCursor_MemberRef: 165 case CXCursor_OverloadedDeclRef: 166 default: 167 break; 168 } 169 170 return MakeCXType(QualType(), TU); 171 } 172 173 return MakeCXType(QualType(), TU); 174 } 175 176 CXType clang_getCanonicalType(CXType CT) { 177 if (CT.kind == CXType_Invalid) 178 return CT; 179 180 QualType T = GetQualType(CT); 181 CXTranslationUnit TU = GetTU(CT); 182 183 if (T.isNull()) 184 return MakeCXType(QualType(), GetTU(CT)); 185 186 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData); 187 return MakeCXType(AU->getASTContext().getCanonicalType(T), TU); 188 } 189 190 unsigned clang_isConstQualifiedType(CXType CT) { 191 QualType T = GetQualType(CT); 192 return T.isLocalConstQualified(); 193 } 194 195 unsigned clang_isVolatileQualifiedType(CXType CT) { 196 QualType T = GetQualType(CT); 197 return T.isLocalVolatileQualified(); 198 } 199 200 unsigned clang_isRestrictQualifiedType(CXType CT) { 201 QualType T = GetQualType(CT); 202 return T.isLocalRestrictQualified(); 203 } 204 205 CXType clang_getPointeeType(CXType CT) { 206 QualType T = GetQualType(CT); 207 const Type *TP = T.getTypePtrOrNull(); 208 209 if (!TP) 210 return MakeCXType(QualType(), GetTU(CT)); 211 212 switch (TP->getTypeClass()) { 213 case Type::Pointer: 214 T = cast<PointerType>(TP)->getPointeeType(); 215 break; 216 case Type::BlockPointer: 217 T = cast<BlockPointerType>(TP)->getPointeeType(); 218 break; 219 case Type::LValueReference: 220 case Type::RValueReference: 221 T = cast<ReferenceType>(TP)->getPointeeType(); 222 break; 223 case Type::ObjCObjectPointer: 224 T = cast<ObjCObjectPointerType>(TP)->getPointeeType(); 225 break; 226 default: 227 T = QualType(); 228 break; 229 } 230 return MakeCXType(T, GetTU(CT)); 231 } 232 233 CXCursor clang_getTypeDeclaration(CXType CT) { 234 if (CT.kind == CXType_Invalid) 235 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 236 237 QualType T = GetQualType(CT); 238 const Type *TP = T.getTypePtrOrNull(); 239 240 if (!TP) 241 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 242 243 Decl *D = 0; 244 245 try_again: 246 switch (TP->getTypeClass()) { 247 case Type::Typedef: 248 D = cast<TypedefType>(TP)->getDecl(); 249 break; 250 case Type::ObjCObject: 251 D = cast<ObjCObjectType>(TP)->getInterface(); 252 break; 253 case Type::ObjCInterface: 254 D = cast<ObjCInterfaceType>(TP)->getDecl(); 255 break; 256 case Type::Record: 257 case Type::Enum: 258 D = cast<TagType>(TP)->getDecl(); 259 break; 260 case Type::TemplateSpecialization: 261 if (const RecordType *Record = TP->getAs<RecordType>()) 262 D = Record->getDecl(); 263 else 264 D = cast<TemplateSpecializationType>(TP)->getTemplateName() 265 .getAsTemplateDecl(); 266 break; 267 268 case Type::InjectedClassName: 269 D = cast<InjectedClassNameType>(TP)->getDecl(); 270 break; 271 272 // FIXME: Template type parameters! 273 274 case Type::Elaborated: 275 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull(); 276 goto try_again; 277 278 default: 279 break; 280 } 281 282 if (!D) 283 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 284 285 return cxcursor::MakeCXCursor(D, GetTU(CT)); 286 } 287 288 CXString clang_getTypeKindSpelling(enum CXTypeKind K) { 289 const char *s = 0; 290 #define TKIND(X) case CXType_##X: s = "" #X ""; break 291 switch (K) { 292 TKIND(Invalid); 293 TKIND(Unexposed); 294 TKIND(Void); 295 TKIND(Bool); 296 TKIND(Char_U); 297 TKIND(UChar); 298 TKIND(Char16); 299 TKIND(Char32); 300 TKIND(UShort); 301 TKIND(UInt); 302 TKIND(ULong); 303 TKIND(ULongLong); 304 TKIND(UInt128); 305 TKIND(Char_S); 306 TKIND(SChar); 307 case CXType_WChar: s = "WChar"; break; 308 TKIND(Short); 309 TKIND(Int); 310 TKIND(Long); 311 TKIND(LongLong); 312 TKIND(Int128); 313 TKIND(Float); 314 TKIND(Double); 315 TKIND(LongDouble); 316 TKIND(NullPtr); 317 TKIND(Overload); 318 TKIND(Dependent); 319 TKIND(ObjCId); 320 TKIND(ObjCClass); 321 TKIND(ObjCSel); 322 TKIND(Complex); 323 TKIND(Pointer); 324 TKIND(BlockPointer); 325 TKIND(LValueReference); 326 TKIND(RValueReference); 327 TKIND(Record); 328 TKIND(Enum); 329 TKIND(Typedef); 330 TKIND(ObjCInterface); 331 TKIND(ObjCObjectPointer); 332 TKIND(FunctionNoProto); 333 TKIND(FunctionProto); 334 TKIND(ConstantArray); 335 } 336 #undef TKIND 337 return cxstring::createCXString(s); 338 } 339 340 unsigned clang_equalTypes(CXType A, CXType B) { 341 return A.data[0] == B.data[0] && A.data[1] == B.data[1];; 342 } 343 344 CXType clang_getResultType(CXType X) { 345 QualType T = GetQualType(X); 346 if (!T.getTypePtrOrNull()) 347 return MakeCXType(QualType(), GetTU(X)); 348 349 if (const FunctionType *FD = T->getAs<FunctionType>()) 350 return MakeCXType(FD->getResultType(), GetTU(X)); 351 352 return MakeCXType(QualType(), GetTU(X)); 353 } 354 355 CXType clang_getCursorResultType(CXCursor C) { 356 if (clang_isDeclaration(C.kind)) { 357 Decl *D = cxcursor::getCursorDecl(C); 358 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 359 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C)); 360 361 return clang_getResultType(clang_getCursorType(C)); 362 } 363 364 return MakeCXType(QualType(), cxcursor::getCursorTU(C)); 365 } 366 367 unsigned clang_isPODType(CXType X) { 368 QualType T = GetQualType(X); 369 if (!T.getTypePtrOrNull()) 370 return 0; 371 372 CXTranslationUnit TU = GetTU(X); 373 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData); 374 375 return T.isPODType(AU->getASTContext()) ? 1 : 0; 376 } 377 378 CXType clang_getArrayElementType(CXType CT) { 379 QualType ET = QualType(); 380 QualType T = GetQualType(CT); 381 const Type *TP = T.getTypePtrOrNull(); 382 383 if (TP) { 384 switch (TP->getTypeClass()) { 385 case Type::ConstantArray: 386 ET = cast<ConstantArrayType> (TP)->getElementType(); 387 break; 388 default: 389 break; 390 } 391 } 392 return MakeCXType(ET, GetTU(CT)); 393 } 394 395 long long clang_getArraySize(CXType CT) { 396 long long result = -1; 397 QualType T = GetQualType(CT); 398 const Type *TP = T.getTypePtrOrNull(); 399 400 if (TP) { 401 switch (TP->getTypeClass()) { 402 case Type::ConstantArray: 403 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 404 break; 405 default: 406 break; 407 } 408 } 409 return result; 410 } 411 412 CXString clang_getDeclObjCTypeEncoding(CXCursor C) { 413 if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl)) 414 return cxstring::createCXString(""); 415 416 Decl *D = static_cast<Decl*>(C.data[0]); 417 CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]); 418 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData); 419 ASTContext &Ctx = AU->getASTContext(); 420 std::string encoding; 421 422 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) { 423 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding)) 424 return cxstring::createCXString("?"); 425 } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 426 Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding); 427 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 428 Ctx.getObjCEncodingForFunctionDecl(FD, encoding); 429 else { 430 QualType Ty; 431 if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) 432 Ty = Ctx.getTypeDeclType(TD); 433 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 434 Ty = VD->getType(); 435 else return cxstring::createCXString("?"); 436 Ctx.getObjCEncodingForType(Ty, encoding); 437 } 438 439 return cxstring::createCXString(encoding); 440 } 441 442 } // end: extern "C" 443