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