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