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