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 26 using namespace clang; 27 28 static 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 66 static 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(IncompleteArray); 89 TKCASE(VariableArray); 90 TKCASE(DependentSizedArray); 91 TKCASE(Vector); 92 TKCASE(MemberPointer); 93 default: 94 return CXType_Unexposed; 95 } 96 #undef TKCASE 97 } 98 99 100 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { 101 CXTypeKind TK = CXType_Invalid; 102 103 if (TU && !T.isNull()) { 104 // Handle attributed types as the original type 105 if (auto *ATT = T->getAs<AttributedType>()) { 106 return MakeCXType(ATT->getModifiedType(), TU); 107 } 108 109 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext(); 110 if (Ctx.getLangOpts().ObjC1) { 111 QualType UnqualT = T.getUnqualifiedType(); 112 if (Ctx.isObjCIdType(UnqualT)) 113 TK = CXType_ObjCId; 114 else if (Ctx.isObjCClassType(UnqualT)) 115 TK = CXType_ObjCClass; 116 else if (Ctx.isObjCSelType(UnqualT)) 117 TK = CXType_ObjCSel; 118 } 119 120 /* Handle decayed types as the original type */ 121 if (const DecayedType *DT = T->getAs<DecayedType>()) { 122 return MakeCXType(DT->getOriginalType(), TU); 123 } 124 } 125 if (TK == CXType_Invalid) 126 TK = GetTypeKind(T); 127 128 CXType CT = { TK, { TK == CXType_Invalid ? nullptr 129 : T.getAsOpaquePtr(), TU } }; 130 return CT; 131 } 132 133 using cxtype::MakeCXType; 134 135 static inline QualType GetQualType(CXType CT) { 136 return QualType::getFromOpaquePtr(CT.data[0]); 137 } 138 139 static inline CXTranslationUnit GetTU(CXType CT) { 140 return static_cast<CXTranslationUnit>(CT.data[1]); 141 } 142 143 extern "C" { 144 145 CXType clang_getCursorType(CXCursor C) { 146 using namespace cxcursor; 147 148 CXTranslationUnit TU = cxcursor::getCursorTU(C); 149 if (!TU) 150 return MakeCXType(QualType(), TU); 151 152 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext(); 153 if (clang_isExpression(C.kind)) { 154 QualType T = cxcursor::getCursorExpr(C)->getType(); 155 return MakeCXType(T, TU); 156 } 157 158 if (clang_isDeclaration(C.kind)) { 159 const Decl *D = cxcursor::getCursorDecl(C); 160 if (!D) 161 return MakeCXType(QualType(), TU); 162 163 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 164 return MakeCXType(Context.getTypeDeclType(TD), TU); 165 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) 166 return MakeCXType(Context.getObjCInterfaceType(ID), TU); 167 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) 168 return MakeCXType(DD->getType(), TU); 169 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 170 return MakeCXType(VD->getType(), TU); 171 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 172 return MakeCXType(PD->getType(), TU); 173 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) 174 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU); 175 return MakeCXType(QualType(), TU); 176 } 177 178 if (clang_isReference(C.kind)) { 179 switch (C.kind) { 180 case CXCursor_ObjCSuperClassRef: { 181 QualType T 182 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first); 183 return MakeCXType(T, TU); 184 } 185 186 case CXCursor_ObjCClassRef: { 187 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first); 188 return MakeCXType(T, TU); 189 } 190 191 case CXCursor_TypeRef: { 192 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first); 193 return MakeCXType(T, TU); 194 195 } 196 197 case CXCursor_CXXBaseSpecifier: 198 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU); 199 200 case CXCursor_MemberRef: 201 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU); 202 203 case CXCursor_VariableRef: 204 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU); 205 206 case CXCursor_ObjCProtocolRef: 207 case CXCursor_TemplateRef: 208 case CXCursor_NamespaceRef: 209 case CXCursor_OverloadedDeclRef: 210 default: 211 break; 212 } 213 214 return MakeCXType(QualType(), TU); 215 } 216 217 return MakeCXType(QualType(), TU); 218 } 219 220 CXString clang_getTypeSpelling(CXType CT) { 221 QualType T = GetQualType(CT); 222 if (T.isNull()) 223 return cxstring::createEmpty(); 224 225 CXTranslationUnit TU = GetTU(CT); 226 SmallString<64> Str; 227 llvm::raw_svector_ostream OS(Str); 228 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts()); 229 230 T.print(OS, PP); 231 232 return cxstring::createDup(OS.str()); 233 } 234 235 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) { 236 using namespace cxcursor; 237 CXTranslationUnit TU = cxcursor::getCursorTU(C); 238 239 if (clang_isDeclaration(C.kind)) { 240 const Decl *D = cxcursor::getCursorDecl(C); 241 242 if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) { 243 QualType T = TD->getUnderlyingType(); 244 return MakeCXType(T, TU); 245 } 246 247 return MakeCXType(QualType(), TU); 248 } 249 250 return MakeCXType(QualType(), TU); 251 } 252 253 CXType clang_getEnumDeclIntegerType(CXCursor C) { 254 using namespace cxcursor; 255 CXTranslationUnit TU = cxcursor::getCursorTU(C); 256 257 if (clang_isDeclaration(C.kind)) { 258 const Decl *D = cxcursor::getCursorDecl(C); 259 260 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) { 261 QualType T = TD->getIntegerType(); 262 return MakeCXType(T, TU); 263 } 264 265 return MakeCXType(QualType(), TU); 266 } 267 268 return MakeCXType(QualType(), TU); 269 } 270 271 long long clang_getEnumConstantDeclValue(CXCursor C) { 272 using namespace cxcursor; 273 274 if (clang_isDeclaration(C.kind)) { 275 const Decl *D = cxcursor::getCursorDecl(C); 276 277 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) { 278 return TD->getInitVal().getSExtValue(); 279 } 280 281 return LLONG_MIN; 282 } 283 284 return LLONG_MIN; 285 } 286 287 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) { 288 using namespace cxcursor; 289 290 if (clang_isDeclaration(C.kind)) { 291 const Decl *D = cxcursor::getCursorDecl(C); 292 293 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) { 294 return TD->getInitVal().getZExtValue(); 295 } 296 297 return ULLONG_MAX; 298 } 299 300 return ULLONG_MAX; 301 } 302 303 int clang_getFieldDeclBitWidth(CXCursor C) { 304 using namespace cxcursor; 305 306 if (clang_isDeclaration(C.kind)) { 307 const Decl *D = getCursorDecl(C); 308 309 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) { 310 if (FD->isBitField()) 311 return FD->getBitWidthValue(getCursorContext(C)); 312 } 313 } 314 315 return -1; 316 } 317 318 CXType clang_getCanonicalType(CXType CT) { 319 if (CT.kind == CXType_Invalid) 320 return CT; 321 322 QualType T = GetQualType(CT); 323 CXTranslationUnit TU = GetTU(CT); 324 325 if (T.isNull()) 326 return MakeCXType(QualType(), GetTU(CT)); 327 328 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext() 329 .getCanonicalType(T), 330 TU); 331 } 332 333 unsigned clang_isConstQualifiedType(CXType CT) { 334 QualType T = GetQualType(CT); 335 return T.isLocalConstQualified(); 336 } 337 338 unsigned clang_isVolatileQualifiedType(CXType CT) { 339 QualType T = GetQualType(CT); 340 return T.isLocalVolatileQualified(); 341 } 342 343 unsigned clang_isRestrictQualifiedType(CXType CT) { 344 QualType T = GetQualType(CT); 345 return T.isLocalRestrictQualified(); 346 } 347 348 CXType clang_getPointeeType(CXType CT) { 349 QualType T = GetQualType(CT); 350 const Type *TP = T.getTypePtrOrNull(); 351 352 if (!TP) 353 return MakeCXType(QualType(), GetTU(CT)); 354 355 switch (TP->getTypeClass()) { 356 case Type::Pointer: 357 T = cast<PointerType>(TP)->getPointeeType(); 358 break; 359 case Type::BlockPointer: 360 T = cast<BlockPointerType>(TP)->getPointeeType(); 361 break; 362 case Type::LValueReference: 363 case Type::RValueReference: 364 T = cast<ReferenceType>(TP)->getPointeeType(); 365 break; 366 case Type::ObjCObjectPointer: 367 T = cast<ObjCObjectPointerType>(TP)->getPointeeType(); 368 break; 369 case Type::MemberPointer: 370 T = cast<MemberPointerType>(TP)->getPointeeType(); 371 break; 372 default: 373 T = QualType(); 374 break; 375 } 376 return MakeCXType(T, GetTU(CT)); 377 } 378 379 CXCursor clang_getTypeDeclaration(CXType CT) { 380 if (CT.kind == CXType_Invalid) 381 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 382 383 QualType T = GetQualType(CT); 384 const Type *TP = T.getTypePtrOrNull(); 385 386 if (!TP) 387 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 388 389 Decl *D = nullptr; 390 391 try_again: 392 switch (TP->getTypeClass()) { 393 case Type::Typedef: 394 D = cast<TypedefType>(TP)->getDecl(); 395 break; 396 case Type::ObjCObject: 397 D = cast<ObjCObjectType>(TP)->getInterface(); 398 break; 399 case Type::ObjCInterface: 400 D = cast<ObjCInterfaceType>(TP)->getDecl(); 401 break; 402 case Type::Record: 403 case Type::Enum: 404 D = cast<TagType>(TP)->getDecl(); 405 break; 406 case Type::TemplateSpecialization: 407 if (const RecordType *Record = TP->getAs<RecordType>()) 408 D = Record->getDecl(); 409 else 410 D = cast<TemplateSpecializationType>(TP)->getTemplateName() 411 .getAsTemplateDecl(); 412 break; 413 414 case Type::InjectedClassName: 415 D = cast<InjectedClassNameType>(TP)->getDecl(); 416 break; 417 418 // FIXME: Template type parameters! 419 420 case Type::Elaborated: 421 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull(); 422 goto try_again; 423 424 default: 425 break; 426 } 427 428 if (!D) 429 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); 430 431 return cxcursor::MakeCXCursor(D, GetTU(CT)); 432 } 433 434 CXString clang_getTypeKindSpelling(enum CXTypeKind K) { 435 const char *s = nullptr; 436 #define TKIND(X) case CXType_##X: s = "" #X ""; break 437 switch (K) { 438 TKIND(Invalid); 439 TKIND(Unexposed); 440 TKIND(Void); 441 TKIND(Bool); 442 TKIND(Char_U); 443 TKIND(UChar); 444 TKIND(Char16); 445 TKIND(Char32); 446 TKIND(UShort); 447 TKIND(UInt); 448 TKIND(ULong); 449 TKIND(ULongLong); 450 TKIND(UInt128); 451 TKIND(Char_S); 452 TKIND(SChar); 453 case CXType_WChar: s = "WChar"; break; 454 TKIND(Short); 455 TKIND(Int); 456 TKIND(Long); 457 TKIND(LongLong); 458 TKIND(Int128); 459 TKIND(Float); 460 TKIND(Double); 461 TKIND(LongDouble); 462 TKIND(NullPtr); 463 TKIND(Overload); 464 TKIND(Dependent); 465 TKIND(ObjCId); 466 TKIND(ObjCClass); 467 TKIND(ObjCSel); 468 TKIND(Complex); 469 TKIND(Pointer); 470 TKIND(BlockPointer); 471 TKIND(LValueReference); 472 TKIND(RValueReference); 473 TKIND(Record); 474 TKIND(Enum); 475 TKIND(Typedef); 476 TKIND(ObjCInterface); 477 TKIND(ObjCObjectPointer); 478 TKIND(FunctionNoProto); 479 TKIND(FunctionProto); 480 TKIND(ConstantArray); 481 TKIND(IncompleteArray); 482 TKIND(VariableArray); 483 TKIND(DependentSizedArray); 484 TKIND(Vector); 485 TKIND(MemberPointer); 486 } 487 #undef TKIND 488 return cxstring::createRef(s); 489 } 490 491 unsigned clang_equalTypes(CXType A, CXType B) { 492 return A.data[0] == B.data[0] && A.data[1] == B.data[1]; 493 } 494 495 unsigned clang_isFunctionTypeVariadic(CXType X) { 496 QualType T = GetQualType(X); 497 if (T.isNull()) 498 return 0; 499 500 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) 501 return (unsigned)FD->isVariadic(); 502 503 if (T->getAs<FunctionNoProtoType>()) 504 return 1; 505 506 return 0; 507 } 508 509 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) { 510 QualType T = GetQualType(X); 511 if (T.isNull()) 512 return CXCallingConv_Invalid; 513 514 if (const FunctionType *FD = T->getAs<FunctionType>()) { 515 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X 516 switch (FD->getCallConv()) { 517 TCALLINGCONV(C); 518 TCALLINGCONV(X86StdCall); 519 TCALLINGCONV(X86FastCall); 520 TCALLINGCONV(X86ThisCall); 521 TCALLINGCONV(X86Pascal); 522 TCALLINGCONV(X86VectorCall); 523 TCALLINGCONV(X86_64Win64); 524 TCALLINGCONV(X86_64SysV); 525 TCALLINGCONV(AAPCS); 526 TCALLINGCONV(AAPCS_VFP); 527 TCALLINGCONV(IntelOclBicc); 528 case CC_SpirFunction: return CXCallingConv_Unexposed; 529 case CC_SpirKernel: return CXCallingConv_Unexposed; 530 break; 531 } 532 #undef TCALLINGCONV 533 } 534 535 return CXCallingConv_Invalid; 536 } 537 538 int clang_getNumArgTypes(CXType X) { 539 QualType T = GetQualType(X); 540 if (T.isNull()) 541 return -1; 542 543 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 544 return FD->getNumParams(); 545 } 546 547 if (T->getAs<FunctionNoProtoType>()) { 548 return 0; 549 } 550 551 return -1; 552 } 553 554 CXType clang_getArgType(CXType X, unsigned i) { 555 QualType T = GetQualType(X); 556 if (T.isNull()) 557 return MakeCXType(QualType(), GetTU(X)); 558 559 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 560 unsigned numParams = FD->getNumParams(); 561 if (i >= numParams) 562 return MakeCXType(QualType(), GetTU(X)); 563 564 return MakeCXType(FD->getParamType(i), GetTU(X)); 565 } 566 567 return MakeCXType(QualType(), GetTU(X)); 568 } 569 570 CXType clang_getResultType(CXType X) { 571 QualType T = GetQualType(X); 572 if (T.isNull()) 573 return MakeCXType(QualType(), GetTU(X)); 574 575 if (const FunctionType *FD = T->getAs<FunctionType>()) 576 return MakeCXType(FD->getReturnType(), GetTU(X)); 577 578 return MakeCXType(QualType(), GetTU(X)); 579 } 580 581 CXType clang_getCursorResultType(CXCursor C) { 582 if (clang_isDeclaration(C.kind)) { 583 const Decl *D = cxcursor::getCursorDecl(C); 584 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 585 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C)); 586 587 return clang_getResultType(clang_getCursorType(C)); 588 } 589 590 return MakeCXType(QualType(), cxcursor::getCursorTU(C)); 591 } 592 593 unsigned clang_isPODType(CXType X) { 594 QualType T = GetQualType(X); 595 if (T.isNull()) 596 return 0; 597 598 CXTranslationUnit TU = GetTU(X); 599 600 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0; 601 } 602 603 CXType clang_getElementType(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 case Type::IncompleteArray: 614 ET = cast<IncompleteArrayType> (TP)->getElementType(); 615 break; 616 case Type::VariableArray: 617 ET = cast<VariableArrayType> (TP)->getElementType(); 618 break; 619 case Type::DependentSizedArray: 620 ET = cast<DependentSizedArrayType> (TP)->getElementType(); 621 break; 622 case Type::Vector: 623 ET = cast<VectorType> (TP)->getElementType(); 624 break; 625 case Type::Complex: 626 ET = cast<ComplexType> (TP)->getElementType(); 627 break; 628 default: 629 break; 630 } 631 } 632 return MakeCXType(ET, GetTU(CT)); 633 } 634 635 long long clang_getNumElements(CXType CT) { 636 long long result = -1; 637 QualType T = GetQualType(CT); 638 const Type *TP = T.getTypePtrOrNull(); 639 640 if (TP) { 641 switch (TP->getTypeClass()) { 642 case Type::ConstantArray: 643 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 644 break; 645 case Type::Vector: 646 result = cast<VectorType> (TP)->getNumElements(); 647 break; 648 default: 649 break; 650 } 651 } 652 return result; 653 } 654 655 CXType clang_getArrayElementType(CXType CT) { 656 QualType ET = QualType(); 657 QualType T = GetQualType(CT); 658 const Type *TP = T.getTypePtrOrNull(); 659 660 if (TP) { 661 switch (TP->getTypeClass()) { 662 case Type::ConstantArray: 663 ET = cast<ConstantArrayType> (TP)->getElementType(); 664 break; 665 case Type::IncompleteArray: 666 ET = cast<IncompleteArrayType> (TP)->getElementType(); 667 break; 668 case Type::VariableArray: 669 ET = cast<VariableArrayType> (TP)->getElementType(); 670 break; 671 case Type::DependentSizedArray: 672 ET = cast<DependentSizedArrayType> (TP)->getElementType(); 673 break; 674 default: 675 break; 676 } 677 } 678 return MakeCXType(ET, GetTU(CT)); 679 } 680 681 long long clang_getArraySize(CXType CT) { 682 long long result = -1; 683 QualType T = GetQualType(CT); 684 const Type *TP = T.getTypePtrOrNull(); 685 686 if (TP) { 687 switch (TP->getTypeClass()) { 688 case Type::ConstantArray: 689 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 690 break; 691 default: 692 break; 693 } 694 } 695 return result; 696 } 697 698 long long clang_Type_getAlignOf(CXType T) { 699 if (T.kind == CXType_Invalid) 700 return CXTypeLayoutError_Invalid; 701 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext(); 702 QualType QT = GetQualType(T); 703 // [expr.alignof] p1: return size_t value for complete object type, reference 704 // or array. 705 // [expr.alignof] p3: if reference type, return size of referenced type 706 if (QT->isReferenceType()) 707 QT = QT.getNonReferenceType(); 708 if (QT->isIncompleteType()) 709 return CXTypeLayoutError_Incomplete; 710 if (QT->isDependentType()) 711 return CXTypeLayoutError_Dependent; 712 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl 713 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1 714 // if (QT->isVoidType()) return 1; 715 return Ctx.getTypeAlignInChars(QT).getQuantity(); 716 } 717 718 CXType clang_Type_getClassType(CXType CT) { 719 QualType ET = QualType(); 720 QualType T = GetQualType(CT); 721 const Type *TP = T.getTypePtrOrNull(); 722 723 if (TP && TP->getTypeClass() == Type::MemberPointer) { 724 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0); 725 } 726 return MakeCXType(ET, GetTU(CT)); 727 } 728 729 long long clang_Type_getSizeOf(CXType T) { 730 if (T.kind == CXType_Invalid) 731 return CXTypeLayoutError_Invalid; 732 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext(); 733 QualType QT = GetQualType(T); 734 // [expr.sizeof] p2: if reference type, return size of referenced type 735 if (QT->isReferenceType()) 736 QT = QT.getNonReferenceType(); 737 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete 738 // enumeration 739 // Note: We get the cxtype, not the cxcursor, so we can't call 740 // FieldDecl->isBitField() 741 // [expr.sizeof] p3: pointer ok, function not ok. 742 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error 743 if (QT->isIncompleteType()) 744 return CXTypeLayoutError_Incomplete; 745 if (QT->isDependentType()) 746 return CXTypeLayoutError_Dependent; 747 if (!QT->isConstantSizeType()) 748 return CXTypeLayoutError_NotConstantSize; 749 // [gcc extension] lib/AST/ExprConstant.cpp:1372 750 // HandleSizeof : {voidtype,functype} == 1 751 // not handled by ASTContext.cpp:1313 getTypeInfoImpl 752 if (QT->isVoidType() || QT->isFunctionType()) 753 return 1; 754 return Ctx.getTypeSizeInChars(QT).getQuantity(); 755 } 756 757 static long long visitRecordForValidation(const RecordDecl *RD) { 758 for (const auto *I : RD->fields()){ 759 QualType FQT = I->getType(); 760 if (FQT->isIncompleteType()) 761 return CXTypeLayoutError_Incomplete; 762 if (FQT->isDependentType()) 763 return CXTypeLayoutError_Dependent; 764 // recurse 765 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) { 766 if (const RecordDecl *Child = ChildType->getDecl()) { 767 long long ret = visitRecordForValidation(Child); 768 if (ret < 0) 769 return ret; 770 } 771 } 772 // else try next field 773 } 774 return 0; 775 } 776 777 static long long validateFieldParentType(CXCursor PC, CXType PT){ 778 if (clang_isInvalid(PC.kind)) 779 return CXTypeLayoutError_Invalid; 780 const RecordDecl *RD = 781 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC)); 782 // validate parent declaration 783 if (!RD || RD->isInvalidDecl()) 784 return CXTypeLayoutError_Invalid; 785 RD = RD->getDefinition(); 786 if (!RD) 787 return CXTypeLayoutError_Incomplete; 788 if (RD->isInvalidDecl()) 789 return CXTypeLayoutError_Invalid; 790 // validate parent type 791 QualType RT = GetQualType(PT); 792 if (RT->isIncompleteType()) 793 return CXTypeLayoutError_Incomplete; 794 if (RT->isDependentType()) 795 return CXTypeLayoutError_Dependent; 796 // We recurse into all record fields to detect incomplete and dependent types. 797 long long Error = visitRecordForValidation(RD); 798 if (Error < 0) 799 return Error; 800 return 0; 801 } 802 803 long long clang_Type_getOffsetOf(CXType PT, const char *S) { 804 // check that PT is not incomplete/dependent 805 CXCursor PC = clang_getTypeDeclaration(PT); 806 long long Error = validateFieldParentType(PC,PT); 807 if (Error < 0) 808 return Error; 809 if (!S) 810 return CXTypeLayoutError_InvalidFieldName; 811 // lookup field 812 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext(); 813 IdentifierInfo *II = &Ctx.Idents.get(S); 814 DeclarationName FieldName(II); 815 const RecordDecl *RD = 816 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC)); 817 // verified in validateFieldParentType 818 RD = RD->getDefinition(); 819 RecordDecl::lookup_result Res = RD->lookup(FieldName); 820 // If a field of the parent record is incomplete, lookup will fail. 821 // and we would return InvalidFieldName instead of Incomplete. 822 // But this erroneous results does protects again a hidden assertion failure 823 // in the RecordLayoutBuilder 824 if (Res.size() != 1) 825 return CXTypeLayoutError_InvalidFieldName; 826 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front())) 827 return Ctx.getFieldOffset(FD); 828 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front())) 829 return Ctx.getFieldOffset(IFD); 830 // we don't want any other Decl Type. 831 return CXTypeLayoutError_InvalidFieldName; 832 } 833 834 long long clang_Cursor_getOffsetOfField(CXCursor C) { 835 if (clang_isDeclaration(C.kind)) { 836 // we need to validate the parent type 837 CXCursor PC = clang_getCursorSemanticParent(C); 838 CXType PT = clang_getCursorType(PC); 839 long long Error = validateFieldParentType(PC,PT); 840 if (Error < 0) 841 return Error; 842 // proceed with the offset calculation 843 const Decl *D = cxcursor::getCursorDecl(C); 844 ASTContext &Ctx = cxcursor::getCursorContext(C); 845 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) 846 return Ctx.getFieldOffset(FD); 847 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D)) 848 return Ctx.getFieldOffset(IFD); 849 } 850 return -1; 851 } 852 853 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) { 854 QualType QT = GetQualType(T); 855 if (QT.isNull()) 856 return CXRefQualifier_None; 857 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>(); 858 if (!FD) 859 return CXRefQualifier_None; 860 switch (FD->getRefQualifier()) { 861 case RQ_None: 862 return CXRefQualifier_None; 863 case RQ_LValue: 864 return CXRefQualifier_LValue; 865 case RQ_RValue: 866 return CXRefQualifier_RValue; 867 } 868 return CXRefQualifier_None; 869 } 870 871 unsigned clang_Cursor_isBitField(CXCursor C) { 872 if (!clang_isDeclaration(C.kind)) 873 return 0; 874 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C)); 875 if (!FD) 876 return 0; 877 return FD->isBitField(); 878 } 879 880 CXString clang_getDeclObjCTypeEncoding(CXCursor C) { 881 if (!clang_isDeclaration(C.kind)) 882 return cxstring::createEmpty(); 883 884 const Decl *D = cxcursor::getCursorDecl(C); 885 ASTContext &Ctx = cxcursor::getCursorContext(C); 886 std::string encoding; 887 888 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) { 889 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding)) 890 return cxstring::createRef("?"); 891 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 892 Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr, encoding); 893 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 894 Ctx.getObjCEncodingForFunctionDecl(FD, encoding); 895 else { 896 QualType Ty; 897 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 898 Ty = Ctx.getTypeDeclType(TD); 899 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 900 Ty = VD->getType(); 901 else return cxstring::createRef("?"); 902 Ctx.getObjCEncodingForType(Ty, encoding); 903 } 904 905 return cxstring::createDup(encoding); 906 } 907 908 int clang_Type_getNumTemplateArguments(CXType CT) { 909 QualType T = GetQualType(CT); 910 if (T.isNull()) 911 return -1; 912 const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl(); 913 if (!RecordDecl) 914 return -1; 915 const ClassTemplateSpecializationDecl *TemplateDecl = 916 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl); 917 if (!TemplateDecl) 918 return -1; 919 return TemplateDecl->getTemplateArgs().size(); 920 } 921 922 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) { 923 QualType T = GetQualType(CT); 924 if (T.isNull()) 925 return MakeCXType(QualType(), GetTU(CT)); 926 const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl(); 927 if (!RecordDecl) 928 return MakeCXType(QualType(), GetTU(CT)); 929 const ClassTemplateSpecializationDecl *TemplateDecl = 930 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl); 931 if (!TemplateDecl) 932 return MakeCXType(QualType(), GetTU(CT)); 933 const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs(); 934 if (TA.size() <= i) 935 return MakeCXType(QualType(), GetTU(CT)); 936 const TemplateArgument &A = TA.get(i); 937 if (A.getKind() != TemplateArgument::Type) 938 return MakeCXType(QualType(), GetTU(CT)); 939 return MakeCXType(A.getAsType(), GetTU(CT)); 940 } 941 942 unsigned clang_Type_visitFields(CXType PT, 943 CXFieldVisitor visitor, 944 CXClientData client_data){ 945 CXCursor PC = clang_getTypeDeclaration(PT); 946 if (clang_isInvalid(PC.kind)) 947 return false; 948 const RecordDecl *RD = 949 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC)); 950 if (!RD || RD->isInvalidDecl()) 951 return false; 952 RD = RD->getDefinition(); 953 if (!RD || RD->isInvalidDecl()) 954 return false; 955 956 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 957 I != E; ++I){ 958 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I)); 959 // Callback to the client. 960 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){ 961 case CXVisit_Break: 962 return true; 963 case CXVisit_Continue: 964 break; 965 } 966 } 967 return true; 968 } 969 970 unsigned clang_Cursor_isAnonymous(CXCursor C){ 971 if (!clang_isDeclaration(C.kind)) 972 return 0; 973 const Decl *D = cxcursor::getCursorDecl(C); 974 if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D)) 975 return FD->isAnonymousStructOrUnion(); 976 return 0; 977 } 978 979 } // end: extern "C" 980