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