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