CXType.cpp revision 659837e0ce0f73c7fdd5941854be3500db2f4013
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(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 100CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { 101 CXTypeKind TK = CXType_Invalid; 102 103 if (TU && !T.isNull()) { 104 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext(); 105 if (Ctx.getLangOpts().ObjC1) { 106 QualType UnqualT = T.getUnqualifiedType(); 107 if (Ctx.isObjCIdType(UnqualT)) 108 TK = CXType_ObjCId; 109 else if (Ctx.isObjCClassType(UnqualT)) 110 TK = CXType_ObjCClass; 111 else if (Ctx.isObjCSelType(UnqualT)) 112 TK = CXType_ObjCSel; 113 } 114 115 /* Handle decayed types as the original type */ 116 if (const DecayedType *DT = T->getAs<DecayedType>()) { 117 return MakeCXType(DT->getOriginalType(), TU); 118 } 119 } 120 if (TK == CXType_Invalid) 121 TK = GetTypeKind(T); 122 123 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }}; 124 return CT; 125} 126 127using cxtype::MakeCXType; 128 129static inline QualType GetQualType(CXType CT) { 130 return QualType::getFromOpaquePtr(CT.data[0]); 131} 132 133static inline CXTranslationUnit GetTU(CXType CT) { 134 return static_cast<CXTranslationUnit>(CT.data[1]); 135} 136 137extern "C" { 138 139CXType clang_getCursorType(CXCursor C) { 140 using namespace cxcursor; 141 142 CXTranslationUnit TU = cxcursor::getCursorTU(C); 143 if (!TU) 144 return MakeCXType(QualType(), TU); 145 146 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext(); 147 if (clang_isExpression(C.kind)) { 148 QualType T = cxcursor::getCursorExpr(C)->getType(); 149 return MakeCXType(T, TU); 150 } 151 152 if (clang_isDeclaration(C.kind)) { 153 const Decl *D = cxcursor::getCursorDecl(C); 154 if (!D) 155 return MakeCXType(QualType(), TU); 156 157 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 158 return MakeCXType(Context.getTypeDeclType(TD), TU); 159 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) 160 return MakeCXType(Context.getObjCInterfaceType(ID), TU); 161 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { 162 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo()) 163 return MakeCXType(TSInfo->getType(), TU); 164 return MakeCXType(DD->getType(), TU); 165 } 166 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 167 return MakeCXType(VD->getType(), TU); 168 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 169 return MakeCXType(PD->getType(), TU); 170 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) { 171 if (TypeSourceInfo *TSInfo = FTD->getTemplatedDecl()->getTypeSourceInfo()) 172 return MakeCXType(TSInfo->getType(), TU); 173 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU); 174 } 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 220CXString 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 235CXType 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 253CXType 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 271long 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 287unsigned 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 303int 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 318CXType 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 333unsigned clang_isConstQualifiedType(CXType CT) { 334 QualType T = GetQualType(CT); 335 return T.isLocalConstQualified(); 336} 337 338unsigned clang_isVolatileQualifiedType(CXType CT) { 339 QualType T = GetQualType(CT); 340 return T.isLocalVolatileQualified(); 341} 342 343unsigned clang_isRestrictQualifiedType(CXType CT) { 344 QualType T = GetQualType(CT); 345 return T.isLocalRestrictQualified(); 346} 347 348CXType 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 379CXCursor 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 = 0; 390 391try_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 434CXString clang_getTypeKindSpelling(enum CXTypeKind K) { 435 const char *s = 0; 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 491unsigned clang_equalTypes(CXType A, CXType B) { 492 return A.data[0] == B.data[0] && A.data[1] == B.data[1];; 493} 494 495unsigned 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 509CXCallingConv 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(X86_64Win64); 523 TCALLINGCONV(X86_64SysV); 524 TCALLINGCONV(AAPCS); 525 TCALLINGCONV(AAPCS_VFP); 526 TCALLINGCONV(PnaclCall); 527 TCALLINGCONV(IntelOclBicc); 528 } 529#undef TCALLINGCONV 530 } 531 532 return CXCallingConv_Invalid; 533} 534 535int clang_getNumArgTypes(CXType X) { 536 QualType T = GetQualType(X); 537 if (T.isNull()) 538 return -1; 539 540 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 541 return FD->getNumArgs(); 542 } 543 544 if (T->getAs<FunctionNoProtoType>()) { 545 return 0; 546 } 547 548 return -1; 549} 550 551CXType clang_getArgType(CXType X, unsigned i) { 552 QualType T = GetQualType(X); 553 if (T.isNull()) 554 return MakeCXType(QualType(), GetTU(X)); 555 556 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { 557 unsigned numArgs = FD->getNumArgs(); 558 if (i >= numArgs) 559 return MakeCXType(QualType(), GetTU(X)); 560 561 return MakeCXType(FD->getArgType(i), GetTU(X)); 562 } 563 564 return MakeCXType(QualType(), GetTU(X)); 565} 566 567CXType clang_getResultType(CXType X) { 568 QualType T = GetQualType(X); 569 if (T.isNull()) 570 return MakeCXType(QualType(), GetTU(X)); 571 572 if (const FunctionType *FD = T->getAs<FunctionType>()) 573 return MakeCXType(FD->getResultType(), GetTU(X)); 574 575 return MakeCXType(QualType(), GetTU(X)); 576} 577 578CXType clang_getCursorResultType(CXCursor C) { 579 if (clang_isDeclaration(C.kind)) { 580 const Decl *D = cxcursor::getCursorDecl(C); 581 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 582 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C)); 583 584 return clang_getResultType(clang_getCursorType(C)); 585 } 586 587 return MakeCXType(QualType(), cxcursor::getCursorTU(C)); 588} 589 590unsigned clang_isPODType(CXType X) { 591 QualType T = GetQualType(X); 592 if (T.isNull()) 593 return 0; 594 595 CXTranslationUnit TU = GetTU(X); 596 597 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0; 598} 599 600CXType clang_getElementType(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 case Type::IncompleteArray: 611 ET = cast<IncompleteArrayType> (TP)->getElementType(); 612 break; 613 case Type::VariableArray: 614 ET = cast<VariableArrayType> (TP)->getElementType(); 615 break; 616 case Type::DependentSizedArray: 617 ET = cast<DependentSizedArrayType> (TP)->getElementType(); 618 break; 619 case Type::Vector: 620 ET = cast<VectorType> (TP)->getElementType(); 621 break; 622 case Type::Complex: 623 ET = cast<ComplexType> (TP)->getElementType(); 624 break; 625 default: 626 break; 627 } 628 } 629 return MakeCXType(ET, GetTU(CT)); 630} 631 632long long clang_getNumElements(CXType CT) { 633 long long result = -1; 634 QualType T = GetQualType(CT); 635 const Type *TP = T.getTypePtrOrNull(); 636 637 if (TP) { 638 switch (TP->getTypeClass()) { 639 case Type::ConstantArray: 640 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 641 break; 642 case Type::Vector: 643 result = cast<VectorType> (TP)->getNumElements(); 644 break; 645 default: 646 break; 647 } 648 } 649 return result; 650} 651 652CXType clang_getArrayElementType(CXType CT) { 653 QualType ET = QualType(); 654 QualType T = GetQualType(CT); 655 const Type *TP = T.getTypePtrOrNull(); 656 657 if (TP) { 658 switch (TP->getTypeClass()) { 659 case Type::ConstantArray: 660 ET = cast<ConstantArrayType> (TP)->getElementType(); 661 break; 662 case Type::IncompleteArray: 663 ET = cast<IncompleteArrayType> (TP)->getElementType(); 664 break; 665 case Type::VariableArray: 666 ET = cast<VariableArrayType> (TP)->getElementType(); 667 break; 668 case Type::DependentSizedArray: 669 ET = cast<DependentSizedArrayType> (TP)->getElementType(); 670 break; 671 default: 672 break; 673 } 674 } 675 return MakeCXType(ET, GetTU(CT)); 676} 677 678long long clang_getArraySize(CXType CT) { 679 long long result = -1; 680 QualType T = GetQualType(CT); 681 const Type *TP = T.getTypePtrOrNull(); 682 683 if (TP) { 684 switch (TP->getTypeClass()) { 685 case Type::ConstantArray: 686 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue(); 687 break; 688 default: 689 break; 690 } 691 } 692 return result; 693} 694 695long long clang_Type_getAlignOf(CXType T) { 696 if (T.kind == CXType_Invalid) 697 return CXTypeLayoutError_Invalid; 698 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext(); 699 QualType QT = GetQualType(T); 700 // [expr.alignof] p1: return size_t value for complete object type, reference 701 // or array. 702 // [expr.alignof] p3: if reference type, return size of referenced type 703 if (QT->isReferenceType()) 704 QT = QT.getNonReferenceType(); 705 if (QT->isIncompleteType()) 706 return CXTypeLayoutError_Incomplete; 707 if (QT->isDependentType()) 708 return CXTypeLayoutError_Dependent; 709 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl 710 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1 711 // if (QT->isVoidType()) return 1; 712 return Ctx.getTypeAlignInChars(QT).getQuantity(); 713} 714 715CXType clang_Type_getClassType(CXType CT) { 716 QualType ET = QualType(); 717 QualType T = GetQualType(CT); 718 const Type *TP = T.getTypePtrOrNull(); 719 720 if (TP && TP->getTypeClass() == Type::MemberPointer) { 721 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0); 722 } 723 return MakeCXType(ET, GetTU(CT)); 724} 725 726long long clang_Type_getSizeOf(CXType T) { 727 if (T.kind == CXType_Invalid) 728 return CXTypeLayoutError_Invalid; 729 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext(); 730 QualType QT = GetQualType(T); 731 // [expr.sizeof] p2: if reference type, return size of referenced type 732 if (QT->isReferenceType()) 733 QT = QT.getNonReferenceType(); 734 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete 735 // enumeration 736 // Note: We get the cxtype, not the cxcursor, so we can't call 737 // FieldDecl->isBitField() 738 // [expr.sizeof] p3: pointer ok, function not ok. 739 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error 740 if (QT->isIncompleteType()) 741 return CXTypeLayoutError_Incomplete; 742 if (QT->isDependentType()) 743 return CXTypeLayoutError_Dependent; 744 if (!QT->isConstantSizeType()) 745 return CXTypeLayoutError_NotConstantSize; 746 // [gcc extension] lib/AST/ExprConstant.cpp:1372 747 // HandleSizeof : {voidtype,functype} == 1 748 // not handled by ASTContext.cpp:1313 getTypeInfoImpl 749 if (QT->isVoidType() || QT->isFunctionType()) 750 return 1; 751 return Ctx.getTypeSizeInChars(QT).getQuantity(); 752} 753 754static long long visitRecordForValidation(const RecordDecl *RD) { 755 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 756 I != E; ++I){ 757 QualType FQT = (*I)->getType(); 758 if (FQT->isIncompleteType()) 759 return CXTypeLayoutError_Incomplete; 760 if (FQT->isDependentType()) 761 return CXTypeLayoutError_Dependent; 762 // recurse 763 if (const RecordType *ChildType = (*I)->getType()->getAs<RecordType>()) { 764 if (const RecordDecl *Child = ChildType->getDecl()) { 765 long long ret = visitRecordForValidation(Child); 766 if (ret < 0) 767 return ret; 768 } 769 } 770 // else try next field 771 } 772 return 0; 773} 774 775long long clang_Type_getOffsetOf(CXType PT, const char *S) { 776 // check that PT is not incomplete/dependent 777 CXCursor PC = clang_getTypeDeclaration(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 if (!RD || RD->isInvalidDecl()) 783 return CXTypeLayoutError_Invalid; 784 RD = RD->getDefinition(); 785 if (!RD) 786 return CXTypeLayoutError_Incomplete; 787 if (RD->isInvalidDecl()) 788 return CXTypeLayoutError_Invalid; 789 QualType RT = GetQualType(PT); 790 if (RT->isIncompleteType()) 791 return CXTypeLayoutError_Incomplete; 792 if (RT->isDependentType()) 793 return CXTypeLayoutError_Dependent; 794 // We recurse into all record fields to detect incomplete and dependent types. 795 long long Error = visitRecordForValidation(RD); 796 if (Error < 0) 797 return Error; 798 if (!S) 799 return CXTypeLayoutError_InvalidFieldName; 800 // lookup field 801 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext(); 802 IdentifierInfo *II = &Ctx.Idents.get(S); 803 DeclarationName FieldName(II); 804 RecordDecl::lookup_const_result Res = RD->lookup(FieldName); 805 // If a field of the parent record is incomplete, lookup will fail. 806 // and we would return InvalidFieldName instead of Incomplete. 807 // But this erroneous results does protects again a hidden assertion failure 808 // in the RecordLayoutBuilder 809 if (Res.size() != 1) 810 return CXTypeLayoutError_InvalidFieldName; 811 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front())) 812 return Ctx.getFieldOffset(FD); 813 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front())) 814 return Ctx.getFieldOffset(IFD); 815 // we don't want any other Decl Type. 816 return CXTypeLayoutError_InvalidFieldName; 817} 818 819enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) { 820 QualType QT = GetQualType(T); 821 if (QT.isNull()) 822 return CXRefQualifier_None; 823 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>(); 824 if (!FD) 825 return CXRefQualifier_None; 826 switch (FD->getRefQualifier()) { 827 case RQ_None: 828 return CXRefQualifier_None; 829 case RQ_LValue: 830 return CXRefQualifier_LValue; 831 case RQ_RValue: 832 return CXRefQualifier_RValue; 833 } 834 return CXRefQualifier_None; 835} 836 837unsigned clang_Cursor_isBitField(CXCursor C) { 838 if (!clang_isDeclaration(C.kind)) 839 return 0; 840 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C)); 841 if (!FD) 842 return 0; 843 return FD->isBitField(); 844} 845 846CXString clang_getDeclObjCTypeEncoding(CXCursor C) { 847 if (!clang_isDeclaration(C.kind)) 848 return cxstring::createEmpty(); 849 850 const Decl *D = cxcursor::getCursorDecl(C); 851 ASTContext &Ctx = cxcursor::getCursorContext(C); 852 std::string encoding; 853 854 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) { 855 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding)) 856 return cxstring::createRef("?"); 857 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D)) 858 Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding); 859 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 860 Ctx.getObjCEncodingForFunctionDecl(FD, encoding); 861 else { 862 QualType Ty; 863 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 864 Ty = Ctx.getTypeDeclType(TD); 865 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 866 Ty = VD->getType(); 867 else return cxstring::createRef("?"); 868 Ctx.getObjCEncodingForType(Ty, encoding); 869 } 870 871 return cxstring::createDup(encoding); 872} 873 874} // end: extern "C" 875