CXType.cpp revision ae50a5bb0aaa9595f0969fc0cc4809ace9508d0c
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 = 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 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 = 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 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 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext() 297 .getCanonicalType(T), 298 TU); 299} 300 301unsigned clang_isConstQualifiedType(CXType CT) { 302 QualType T = GetQualType(CT); 303 return T.isLocalConstQualified(); 304} 305 306unsigned clang_isVolatileQualifiedType(CXType CT) { 307 QualType T = GetQualType(CT); 308 return T.isLocalVolatileQualified(); 309} 310 311unsigned clang_isRestrictQualifiedType(CXType CT) { 312 QualType T = GetQualType(CT); 313 return T.isLocalRestrictQualified(); 314} 315 316CXType clang_getPointeeType(CXType CT) { 317 QualType T = GetQualType(CT); 318 const Type *TP = T.getTypePtrOrNull(); 319 320 if (!TP) 321 return MakeCXType(QualType(), GetTU(CT)); 322 323 switch (TP->getTypeClass()) { 324 case Type::Pointer: 325 T = cast<PointerType>(TP)->getPointeeType(); 326 break; 327 case Type::BlockPointer: 328 T = cast<BlockPointerType>(TP)->getPointeeType(); 329 break; 330 case Type::LValueReference: 331 case Type::RValueReference: 332 T = cast<ReferenceType>(TP)->getPointeeType(); 333 break; 334 case Type::ObjCObjectPointer: 335 T = cast<ObjCObjectPointerType>(TP)->getPointeeType(); 336 break; 337 default: 338 T = QualType(); 339 break; 340 } 341 return MakeCXType(T, GetTU(CT)); 342} 343 344CXCursor clang_getTypeDeclaration(CXType CT) { 345 if (CT.kind == CXType_Invalid) 346 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 347 348 QualType T = GetQualType(CT); 349 const Type *TP = T.getTypePtrOrNull(); 350 351 if (!TP) 352 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 353 354 Decl *D = 0; 355 356try_again: 357 switch (TP->getTypeClass()) { 358 case Type::Typedef: 359 D = cast<TypedefType>(TP)->getDecl(); 360 break; 361 case Type::ObjCObject: 362 D = cast<ObjCObjectType>(TP)->getInterface(); 363 break; 364 case Type::ObjCInterface: 365 D = cast<ObjCInterfaceType>(TP)->getDecl(); 366 break; 367 case Type::Record: 368 case Type::Enum: 369 D = cast<TagType>(TP)->getDecl(); 370 break; 371 case Type::TemplateSpecialization: 372 if (const RecordType *Record = TP->getAs<RecordType>()) 373 D = Record->getDecl(); 374 else 375 D = cast<TemplateSpecializationType>(TP)->getTemplateName() 376 .getAsTemplateDecl(); 377 break; 378 379 case Type::InjectedClassName: 380 D = cast<InjectedClassNameType>(TP)->getDecl(); 381 break; 382 383 // FIXME: Template type parameters! 384 385 case Type::Elaborated: 386 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull(); 387 goto try_again; 388 389 default: 390 break; 391 } 392 393 if (!D) 394 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 395 396 return cxcursor::MakeCXCursor(D, GetTU(CT)); 397} 398 399CXString clang_getTypeKindSpelling(enum CXTypeKind K) { 400 const char *s = 0; 401#define TKIND(X) case CXType_##X: s = "" #X ""; break 402 switch (K) { 403 TKIND(Invalid); 404 TKIND(Unexposed); 405 TKIND(Void); 406 TKIND(Bool); 407 TKIND(Char_U); 408 TKIND(UChar); 409 TKIND(Char16); 410 TKIND(Char32); 411 TKIND(UShort); 412 TKIND(UInt); 413 TKIND(ULong); 414 TKIND(ULongLong); 415 TKIND(UInt128); 416 TKIND(Char_S); 417 TKIND(SChar); 418 case CXType_WChar: s = "WChar"; break; 419 TKIND(Short); 420 TKIND(Int); 421 TKIND(Long); 422 TKIND(LongLong); 423 TKIND(Int128); 424 TKIND(Float); 425 TKIND(Double); 426 TKIND(LongDouble); 427 TKIND(NullPtr); 428 TKIND(Overload); 429 TKIND(Dependent); 430 TKIND(ObjCId); 431 TKIND(ObjCClass); 432 TKIND(ObjCSel); 433 TKIND(Complex); 434 TKIND(Pointer); 435 TKIND(BlockPointer); 436 TKIND(LValueReference); 437 TKIND(RValueReference); 438 TKIND(Record); 439 TKIND(Enum); 440 TKIND(Typedef); 441 TKIND(ObjCInterface); 442 TKIND(ObjCObjectPointer); 443 TKIND(FunctionNoProto); 444 TKIND(FunctionProto); 445 TKIND(ConstantArray); 446 TKIND(Vector); 447 } 448#undef TKIND 449 return cxstring::createRef(s); 450} 451 452unsigned clang_equalTypes(CXType A, CXType B) { 453 return A.data[0] == B.data[0] && A.data[1] == B.data[1];; 454} 455 456unsigned clang_isFunctionTypeVariadic(CXType X) { 457 QualType T = GetQualType(X); 458 if (T.isNull()) 459 return 0; 460 461 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) 462 return (unsigned)FD->isVariadic(); 463 464 if (T->getAs<FunctionNoProtoType>()) 465 return 1; 466 467 return 0; 468} 469 470CXCallingConv clang_getFunctionTypeCallingConv(CXType X) { 471 QualType T = GetQualType(X); 472 if (T.isNull()) 473 return CXCallingConv_Invalid; 474 475 if (const FunctionType *FD = T->getAs<FunctionType>()) { 476#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X 477 switch (FD->getCallConv()) { 478 TCALLINGCONV(Default); 479 TCALLINGCONV(C); 480 TCALLINGCONV(X86StdCall); 481 TCALLINGCONV(X86FastCall); 482 TCALLINGCONV(X86ThisCall); 483 TCALLINGCONV(X86Pascal); 484 TCALLINGCONV(AAPCS); 485 TCALLINGCONV(AAPCS_VFP); 486 TCALLINGCONV(PnaclCall); 487 TCALLINGCONV(IntelOclBicc); 488 } 489#undef TCALLINGCONV 490 } 491 492 return CXCallingConv_Invalid; 493} 494 495int clang_getNumArgTypes(CXType X) { 496 QualType T = GetQualType(X); 497 if (T.isNull()) 498 return -1; 499 500 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 501 return FD->getNumArgs(); 502 } 503 504 if (T->getAs<FunctionNoProtoType>()) { 505 return 0; 506 } 507 508 return -1; 509} 510 511CXType clang_getArgType(CXType X, unsigned i) { 512 QualType T = GetQualType(X); 513 if (T.isNull()) 514 return MakeCXType(QualType(), GetTU(X)); 515 516 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 517 unsigned numArgs = FD->getNumArgs(); 518 if (i >= numArgs) 519 return MakeCXType(QualType(), GetTU(X)); 520 521 return MakeCXType(FD->getArgType(i), GetTU(X)); 522 } 523 524 return MakeCXType(QualType(), GetTU(X)); 525} 526 527CXType clang_getResultType(CXType X) { 528 QualType T = GetQualType(X); 529 if (T.isNull()) 530 return MakeCXType(QualType(), GetTU(X)); 531 532 if (const FunctionType *FD = T->getAs<FunctionType>()) 533 return MakeCXType(FD->getResultType(), GetTU(X)); 534 535 return MakeCXType(QualType(), GetTU(X)); 536} 537 538CXType clang_getCursorResultType(CXCursor C) { 539 if (clang_isDeclaration(C.kind)) { 540 const Decl *D = cxcursor::getCursorDecl(C); 541 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 542 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C)); 543 544 return clang_getResultType(clang_getCursorType(C)); 545 } 546 547 return MakeCXType(QualType(), cxcursor::getCursorTU(C)); 548} 549 550unsigned clang_isPODType(CXType X) { 551 QualType T = GetQualType(X); 552 if (T.isNull()) 553 return 0; 554 555 CXTranslationUnit TU = GetTU(X); 556 557 return T.isPODType(cxtu::getASTUnit(TU)->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::createEmpty(); 640 641 const Decl *D = cxcursor::getCursorDecl(C); 642 ASTContext &Ctx = cxcursor::getCursorContext(C); 643 std::string encoding; 644 645 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) { 646 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding)) 647 return cxstring::createRef("?"); 648 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 649 Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding); 650 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 651 Ctx.getObjCEncodingForFunctionDecl(FD, encoding); 652 else { 653 QualType Ty; 654 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 655 Ty = Ctx.getTypeDeclType(TD); 656 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 657 Ty = VD->getType(); 658 else return cxstring::createRef("?"); 659 Ctx.getObjCEncodingForType(Ty, encoding); 660 } 661 662 return cxstring::createDup(encoding); 663} 664 665} // end: extern "C" 666