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 TKCASE(Vector); 89 default: 90 return CXType_Unexposed; 91 } 92 #undef TKCASE 93 } 94 95 96 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { 97 CXTypeKind TK = GetTypeKind(T); 98 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }}; 99 return CT; 100 } 101 102 using cxtype::MakeCXType; 103 104 static inline QualType GetQualType(CXType CT) { 105 return QualType::getFromOpaquePtr(CT.data[0]); 106 } 107 108 static inline CXTranslationUnit GetTU(CXType CT) { 109 return static_cast<CXTranslationUnit>(CT.data[1]); 110 } 111 112 extern "C" { 113 114 CXType clang_getCursorType(CXCursor C) { 115 using namespace cxcursor; 116 117 CXTranslationUnit TU = cxcursor::getCursorTU(C); 118 ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext(); 119 if (clang_isExpression(C.kind)) { 120 QualType T = cxcursor::getCursorExpr(C)->getType(); 121 return MakeCXType(T, TU); 122 } 123 124 if (clang_isDeclaration(C.kind)) { 125 Decl *D = cxcursor::getCursorDecl(C); 126 if (!D) 127 return MakeCXType(QualType(), TU); 128 129 if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) 130 return MakeCXType(Context.getTypeDeclType(TD), TU); 131 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) 132 return MakeCXType(Context.getObjCInterfaceType(ID), TU); 133 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 134 return MakeCXType(VD->getType(), TU); 135 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 136 return MakeCXType(PD->getType(), TU); 137 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 138 return MakeCXType(FD->getType(), TU); 139 return MakeCXType(QualType(), TU); 140 } 141 142 if (clang_isReference(C.kind)) { 143 switch (C.kind) { 144 case CXCursor_ObjCSuperClassRef: { 145 QualType T 146 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first); 147 return MakeCXType(T, TU); 148 } 149 150 case CXCursor_ObjCClassRef: { 151 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first); 152 return MakeCXType(T, TU); 153 } 154 155 case CXCursor_TypeRef: { 156 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first); 157 return MakeCXType(T, TU); 158 159 } 160 161 case CXCursor_CXXBaseSpecifier: 162 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU); 163 164 case CXCursor_MemberRef: 165 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU); 166 167 case CXCursor_VariableRef: 168 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU); 169 170 case CXCursor_ObjCProtocolRef: 171 case CXCursor_TemplateRef: 172 case CXCursor_NamespaceRef: 173 case CXCursor_OverloadedDeclRef: 174 default: 175 break; 176 } 177 178 return MakeCXType(QualType(), TU); 179 } 180 181 return MakeCXType(QualType(), TU); 182 } 183 184 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) { 185 using namespace cxcursor; 186 CXTranslationUnit TU = cxcursor::getCursorTU(C); 187 188 if (clang_isDeclaration(C.kind)) { 189 Decl *D = cxcursor::getCursorDecl(C); 190 191 if (TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) { 192 QualType T = TD->getUnderlyingType(); 193 return MakeCXType(T, TU); 194 } 195 196 return MakeCXType(QualType(), TU); 197 } 198 199 return MakeCXType(QualType(), TU); 200 } 201 202 CXType clang_getEnumDeclIntegerType(CXCursor C) { 203 using namespace cxcursor; 204 CXTranslationUnit TU = cxcursor::getCursorTU(C); 205 206 if (clang_isDeclaration(C.kind)) { 207 Decl *D = cxcursor::getCursorDecl(C); 208 209 if (EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) { 210 QualType T = TD->getIntegerType(); 211 return MakeCXType(T, TU); 212 } 213 214 return MakeCXType(QualType(), TU); 215 } 216 217 return MakeCXType(QualType(), TU); 218 } 219 220 long long clang_getEnumConstantDeclValue(CXCursor C) { 221 using namespace cxcursor; 222 223 if (clang_isDeclaration(C.kind)) { 224 Decl *D = cxcursor::getCursorDecl(C); 225 226 if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) { 227 return TD->getInitVal().getSExtValue(); 228 } 229 230 return LLONG_MIN; 231 } 232 233 return LLONG_MIN; 234 } 235 236 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) { 237 using namespace cxcursor; 238 239 if (clang_isDeclaration(C.kind)) { 240 Decl *D = cxcursor::getCursorDecl(C); 241 242 if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) { 243 return TD->getInitVal().getZExtValue(); 244 } 245 246 return ULLONG_MAX; 247 } 248 249 return ULLONG_MAX; 250 } 251 252 CXType clang_getCanonicalType(CXType CT) { 253 if (CT.kind == CXType_Invalid) 254 return CT; 255 256 QualType T = GetQualType(CT); 257 CXTranslationUnit TU = GetTU(CT); 258 259 if (T.isNull()) 260 return MakeCXType(QualType(), GetTU(CT)); 261 262 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData); 263 return MakeCXType(AU->getASTContext().getCanonicalType(T), TU); 264 } 265 266 unsigned clang_isConstQualifiedType(CXType CT) { 267 QualType T = GetQualType(CT); 268 return T.isLocalConstQualified(); 269 } 270 271 unsigned clang_isVolatileQualifiedType(CXType CT) { 272 QualType T = GetQualType(CT); 273 return T.isLocalVolatileQualified(); 274 } 275 276 unsigned clang_isRestrictQualifiedType(CXType CT) { 277 QualType T = GetQualType(CT); 278 return T.isLocalRestrictQualified(); 279 } 280 281 CXType clang_getPointeeType(CXType CT) { 282 QualType T = GetQualType(CT); 283 const Type *TP = T.getTypePtrOrNull(); 284 285 if (!TP) 286 return MakeCXType(QualType(), GetTU(CT)); 287 288 switch (TP->getTypeClass()) { 289 case Type::Pointer: 290 T = cast<PointerType>(TP)->getPointeeType(); 291 break; 292 case Type::BlockPointer: 293 T = cast<BlockPointerType>(TP)->getPointeeType(); 294 break; 295 case Type::LValueReference: 296 case Type::RValueReference: 297 T = cast<ReferenceType>(TP)->getPointeeType(); 298 break; 299 case Type::ObjCObjectPointer: 300 T = cast<ObjCObjectPointerType>(TP)->getPointeeType(); 301 break; 302 default: 303 T = QualType(); 304 break; 305 } 306 return MakeCXType(T, GetTU(CT)); 307 } 308 309 CXCursor clang_getTypeDeclaration(CXType CT) { 310 if (CT.kind == CXType_Invalid) 311 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 312 313 QualType T = GetQualType(CT); 314 const Type *TP = T.getTypePtrOrNull(); 315 316 if (!TP) 317 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 318 319 Decl *D = 0; 320 321 try_again: 322 switch (TP->getTypeClass()) { 323 case Type::Typedef: 324 D = cast<TypedefType>(TP)->getDecl(); 325 break; 326 case Type::ObjCObject: 327 D = cast<ObjCObjectType>(TP)->getInterface(); 328 break; 329 case Type::ObjCInterface: 330 D = cast<ObjCInterfaceType>(TP)->getDecl(); 331 break; 332 case Type::Record: 333 case Type::Enum: 334 D = cast<TagType>(TP)->getDecl(); 335 break; 336 case Type::TemplateSpecialization: 337 if (const RecordType *Record = TP->getAs<RecordType>()) 338 D = Record->getDecl(); 339 else 340 D = cast<TemplateSpecializationType>(TP)->getTemplateName() 341 .getAsTemplateDecl(); 342 break; 343 344 case Type::InjectedClassName: 345 D = cast<InjectedClassNameType>(TP)->getDecl(); 346 break; 347 348 // FIXME: Template type parameters! 349 350 case Type::Elaborated: 351 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull(); 352 goto try_again; 353 354 default: 355 break; 356 } 357 358 if (!D) 359 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 360 361 return cxcursor::MakeCXCursor(D, GetTU(CT)); 362 } 363 364 CXString clang_getTypeKindSpelling(enum CXTypeKind K) { 365 const char *s = 0; 366 #define TKIND(X) case CXType_##X: s = "" #X ""; break 367 switch (K) { 368 TKIND(Invalid); 369 TKIND(Unexposed); 370 TKIND(Void); 371 TKIND(Bool); 372 TKIND(Char_U); 373 TKIND(UChar); 374 TKIND(Char16); 375 TKIND(Char32); 376 TKIND(UShort); 377 TKIND(UInt); 378 TKIND(ULong); 379 TKIND(ULongLong); 380 TKIND(UInt128); 381 TKIND(Char_S); 382 TKIND(SChar); 383 case CXType_WChar: s = "WChar"; break; 384 TKIND(Short); 385 TKIND(Int); 386 TKIND(Long); 387 TKIND(LongLong); 388 TKIND(Int128); 389 TKIND(Float); 390 TKIND(Double); 391 TKIND(LongDouble); 392 TKIND(NullPtr); 393 TKIND(Overload); 394 TKIND(Dependent); 395 TKIND(ObjCId); 396 TKIND(ObjCClass); 397 TKIND(ObjCSel); 398 TKIND(Complex); 399 TKIND(Pointer); 400 TKIND(BlockPointer); 401 TKIND(LValueReference); 402 TKIND(RValueReference); 403 TKIND(Record); 404 TKIND(Enum); 405 TKIND(Typedef); 406 TKIND(ObjCInterface); 407 TKIND(ObjCObjectPointer); 408 TKIND(FunctionNoProto); 409 TKIND(FunctionProto); 410 TKIND(ConstantArray); 411 TKIND(Vector); 412 } 413 #undef TKIND 414 return cxstring::createCXString(s); 415 } 416 417 unsigned clang_equalTypes(CXType A, CXType B) { 418 return A.data[0] == B.data[0] && A.data[1] == B.data[1];; 419 } 420 421 unsigned clang_isFunctionTypeVariadic(CXType X) { 422 QualType T = GetQualType(X); 423 if (T.isNull()) 424 return 0; 425 426 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) 427 return (unsigned)FD->isVariadic(); 428 429 if (T->getAs<FunctionNoProtoType>()) 430 return 1; 431 432 return 0; 433 } 434 435 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) { 436 QualType T = GetQualType(X); 437 if (T.isNull()) 438 return CXCallingConv_Invalid; 439 440 if (const FunctionType *FD = T->getAs<FunctionType>()) { 441 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X 442 switch (FD->getCallConv()) { 443 TCALLINGCONV(Default); 444 TCALLINGCONV(C); 445 TCALLINGCONV(X86StdCall); 446 TCALLINGCONV(X86FastCall); 447 TCALLINGCONV(X86ThisCall); 448 TCALLINGCONV(X86Pascal); 449 TCALLINGCONV(AAPCS); 450 TCALLINGCONV(AAPCS_VFP); 451 } 452 #undef TCALLINGCONV 453 } 454 455 return CXCallingConv_Invalid; 456 } 457 458 int clang_getNumArgTypes(CXType X) { 459 QualType T = GetQualType(X); 460 if (T.isNull()) 461 return -1; 462 463 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 464 return FD->getNumArgs(); 465 } 466 467 if (T->getAs<FunctionNoProtoType>()) { 468 return 0; 469 } 470 471 return -1; 472 } 473 474 CXType clang_getArgType(CXType X, unsigned i) { 475 QualType T = GetQualType(X); 476 if (T.isNull()) 477 return MakeCXType(QualType(), GetTU(X)); 478 479 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 480 unsigned numArgs = FD->getNumArgs(); 481 if (i >= numArgs) 482 return MakeCXType(QualType(), GetTU(X)); 483 484 return MakeCXType(FD->getArgType(i), GetTU(X)); 485 } 486 487 return MakeCXType(QualType(), GetTU(X)); 488 } 489 490 CXType clang_getResultType(CXType X) { 491 QualType T = GetQualType(X); 492 if (T.isNull()) 493 return MakeCXType(QualType(), GetTU(X)); 494 495 if (const FunctionType *FD = T->getAs<FunctionType>()) 496 return MakeCXType(FD->getResultType(), GetTU(X)); 497 498 return MakeCXType(QualType(), GetTU(X)); 499 } 500 501 CXType clang_getCursorResultType(CXCursor C) { 502 if (clang_isDeclaration(C.kind)) { 503 Decl *D = cxcursor::getCursorDecl(C); 504 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 505 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C)); 506 507 return clang_getResultType(clang_getCursorType(C)); 508 } 509 510 return MakeCXType(QualType(), cxcursor::getCursorTU(C)); 511 } 512 513 unsigned clang_isPODType(CXType X) { 514 QualType T = GetQualType(X); 515 if (T.isNull()) 516 return 0; 517 518 CXTranslationUnit TU = GetTU(X); 519 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData); 520 521 return T.isPODType(AU->getASTContext()) ? 1 : 0; 522 } 523 524 CXType clang_getElementType(CXType CT) { 525 QualType ET = QualType(); 526 QualType T = GetQualType(CT); 527 const Type *TP = T.getTypePtrOrNull(); 528 529 if (TP) { 530 switch (TP->getTypeClass()) { 531 case Type::ConstantArray: 532 ET = cast<ConstantArrayType> (TP)->getElementType(); 533 break; 534 case Type::Vector: 535 ET = cast<VectorType> (TP)->getElementType(); 536 break; 537 case Type::Complex: 538 ET = cast<ComplexType> (TP)->getElementType(); 539 break; 540 default: 541 break; 542 } 543 } 544 return MakeCXType(ET, GetTU(CT)); 545 } 546 547 long long clang_getNumElements(CXType CT) { 548 long long result = -1; 549 QualType T = GetQualType(CT); 550 const Type *TP = T.getTypePtrOrNull(); 551 552 if (TP) { 553 switch (TP->getTypeClass()) { 554 case Type::ConstantArray: 555 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 556 break; 557 case Type::Vector: 558 result = cast<VectorType> (TP)->getNumElements(); 559 break; 560 default: 561 break; 562 } 563 } 564 return result; 565 } 566 567 CXType clang_getArrayElementType(CXType CT) { 568 QualType ET = QualType(); 569 QualType T = GetQualType(CT); 570 const Type *TP = T.getTypePtrOrNull(); 571 572 if (TP) { 573 switch (TP->getTypeClass()) { 574 case Type::ConstantArray: 575 ET = cast<ConstantArrayType> (TP)->getElementType(); 576 break; 577 default: 578 break; 579 } 580 } 581 return MakeCXType(ET, GetTU(CT)); 582 } 583 584 long long clang_getArraySize(CXType CT) { 585 long long result = -1; 586 QualType T = GetQualType(CT); 587 const Type *TP = T.getTypePtrOrNull(); 588 589 if (TP) { 590 switch (TP->getTypeClass()) { 591 case Type::ConstantArray: 592 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 593 break; 594 default: 595 break; 596 } 597 } 598 return result; 599 } 600 601 CXString clang_getDeclObjCTypeEncoding(CXCursor C) { 602 if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl)) 603 return cxstring::createCXString(""); 604 605 Decl *D = static_cast<Decl*>(C.data[0]); 606 CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]); 607 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData); 608 ASTContext &Ctx = AU->getASTContext(); 609 std::string encoding; 610 611 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) { 612 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding)) 613 return cxstring::createCXString("?"); 614 } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 615 Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding); 616 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 617 Ctx.getObjCEncodingForFunctionDecl(FD, encoding); 618 else { 619 QualType Ty; 620 if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) 621 Ty = Ctx.getTypeDeclType(TD); 622 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 623 Ty = VD->getType(); 624 else return cxstring::createCXString("?"); 625 Ctx.getObjCEncodingForType(Ty, encoding); 626 } 627 628 return cxstring::createCXString(encoding); 629 } 630 631 } // end: extern "C" 632