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