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