1 //===- CXTypes.cpp - Implements 'CXTypes' aspect of libclang ------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===--------------------------------------------------------------------===//
10 // This file implements the 'CXTypes' API hooks in the Clang-C library.
12 //===--------------------------------------------------------------------===//
17 #include "CXTranslationUnit.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"
26 using namespace clang;
28 static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
29 #define BTCASE(K) case BuiltinType::K: return CXType_##K
30 switch (BT->getKind()) {
44 case BuiltinType::WChar_S: return CXType_WChar;
45 case BuiltinType::WChar_U: return CXType_WChar;
61 return CXType_Unexposed;
66 static CXTypeKind GetTypeKind(QualType T) {
67 const Type *TP = T.getTypePtrOrNull();
69 return CXType_Invalid;
71 #define TKCASE(K) case Type::K: return CXType_##K
72 switch (TP->getTypeClass()) {
74 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
78 TKCASE(LValueReference);
79 TKCASE(RValueReference);
83 TKCASE(ObjCInterface);
84 TKCASE(ObjCObjectPointer);
85 TKCASE(FunctionNoProto);
86 TKCASE(FunctionProto);
87 TKCASE(ConstantArray);
88 TKCASE(IncompleteArray);
89 TKCASE(VariableArray);
90 TKCASE(DependentSizedArray);
92 TKCASE(MemberPointer);
95 return CXType_Unexposed;
101 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
102 CXTypeKind TK = CXType_Invalid;
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);
110 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
111 if (Ctx.getLangOpts().ObjC1) {
112 QualType UnqualT = T.getUnqualifiedType();
113 if (Ctx.isObjCIdType(UnqualT))
115 else if (Ctx.isObjCClassType(UnqualT))
116 TK = CXType_ObjCClass;
117 else if (Ctx.isObjCSelType(UnqualT))
121 /* Handle decayed types as the original type */
122 if (const DecayedType *DT = T->getAs<DecayedType>()) {
123 return MakeCXType(DT->getOriginalType(), TU);
126 if (TK == CXType_Invalid)
129 CXType CT = { TK, { TK == CXType_Invalid ? nullptr
130 : T.getAsOpaquePtr(), TU } };
134 using cxtype::MakeCXType;
136 static inline QualType GetQualType(CXType CT) {
137 return QualType::getFromOpaquePtr(CT.data[0]);
140 static inline CXTranslationUnit GetTU(CXType CT) {
141 return static_cast<CXTranslationUnit>(CT.data[1]);
146 CXType clang_getCursorType(CXCursor C) {
147 using namespace cxcursor;
149 CXTranslationUnit TU = cxcursor::getCursorTU(C);
151 return MakeCXType(QualType(), TU);
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);
159 if (clang_isDeclaration(C.kind)) {
160 const Decl *D = cxcursor::getCursorDecl(C);
162 return MakeCXType(QualType(), TU);
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);
179 if (clang_isReference(C.kind)) {
181 case CXCursor_ObjCSuperClassRef: {
183 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
184 return MakeCXType(T, TU);
187 case CXCursor_ObjCClassRef: {
188 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
189 return MakeCXType(T, TU);
192 case CXCursor_TypeRef: {
193 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
194 return MakeCXType(T, TU);
198 case CXCursor_CXXBaseSpecifier:
199 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
201 case CXCursor_MemberRef:
202 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
204 case CXCursor_VariableRef:
205 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
207 case CXCursor_ObjCProtocolRef:
208 case CXCursor_TemplateRef:
209 case CXCursor_NamespaceRef:
210 case CXCursor_OverloadedDeclRef:
215 return MakeCXType(QualType(), TU);
218 return MakeCXType(QualType(), TU);
221 CXString clang_getTypeSpelling(CXType CT) {
222 QualType T = GetQualType(CT);
224 return cxstring::createEmpty();
226 CXTranslationUnit TU = GetTU(CT);
228 llvm::raw_svector_ostream OS(Str);
229 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
233 return cxstring::createDup(OS.str());
236 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
237 using namespace cxcursor;
238 CXTranslationUnit TU = cxcursor::getCursorTU(C);
240 if (clang_isDeclaration(C.kind)) {
241 const Decl *D = cxcursor::getCursorDecl(C);
243 if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
244 QualType T = TD->getUnderlyingType();
245 return MakeCXType(T, TU);
248 return MakeCXType(QualType(), TU);
251 return MakeCXType(QualType(), TU);
254 CXType clang_getEnumDeclIntegerType(CXCursor C) {
255 using namespace cxcursor;
256 CXTranslationUnit TU = cxcursor::getCursorTU(C);
258 if (clang_isDeclaration(C.kind)) {
259 const Decl *D = cxcursor::getCursorDecl(C);
261 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
262 QualType T = TD->getIntegerType();
263 return MakeCXType(T, TU);
266 return MakeCXType(QualType(), TU);
269 return MakeCXType(QualType(), TU);
272 long long clang_getEnumConstantDeclValue(CXCursor C) {
273 using namespace cxcursor;
275 if (clang_isDeclaration(C.kind)) {
276 const Decl *D = cxcursor::getCursorDecl(C);
278 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
279 return TD->getInitVal().getSExtValue();
288 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
289 using namespace cxcursor;
291 if (clang_isDeclaration(C.kind)) {
292 const Decl *D = cxcursor::getCursorDecl(C);
294 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
295 return TD->getInitVal().getZExtValue();
304 int clang_getFieldDeclBitWidth(CXCursor C) {
305 using namespace cxcursor;
307 if (clang_isDeclaration(C.kind)) {
308 const Decl *D = getCursorDecl(C);
310 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
311 if (FD->isBitField())
312 return FD->getBitWidthValue(getCursorContext(C));
319 CXType clang_getCanonicalType(CXType CT) {
320 if (CT.kind == CXType_Invalid)
323 QualType T = GetQualType(CT);
324 CXTranslationUnit TU = GetTU(CT);
327 return MakeCXType(QualType(), GetTU(CT));
329 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
330 .getCanonicalType(T),
334 unsigned clang_isConstQualifiedType(CXType CT) {
335 QualType T = GetQualType(CT);
336 return T.isLocalConstQualified();
339 unsigned clang_isVolatileQualifiedType(CXType CT) {
340 QualType T = GetQualType(CT);
341 return T.isLocalVolatileQualified();
344 unsigned clang_isRestrictQualifiedType(CXType CT) {
345 QualType T = GetQualType(CT);
346 return T.isLocalRestrictQualified();
349 CXType clang_getPointeeType(CXType CT) {
350 QualType T = GetQualType(CT);
351 const Type *TP = T.getTypePtrOrNull();
354 return MakeCXType(QualType(), GetTU(CT));
356 switch (TP->getTypeClass()) {
358 T = cast<PointerType>(TP)->getPointeeType();
360 case Type::BlockPointer:
361 T = cast<BlockPointerType>(TP)->getPointeeType();
363 case Type::LValueReference:
364 case Type::RValueReference:
365 T = cast<ReferenceType>(TP)->getPointeeType();
367 case Type::ObjCObjectPointer:
368 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
370 case Type::MemberPointer:
371 T = cast<MemberPointerType>(TP)->getPointeeType();
377 return MakeCXType(T, GetTU(CT));
380 CXCursor clang_getTypeDeclaration(CXType CT) {
381 if (CT.kind == CXType_Invalid)
382 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
384 QualType T = GetQualType(CT);
385 const Type *TP = T.getTypePtrOrNull();
388 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
393 switch (TP->getTypeClass()) {
395 D = cast<TypedefType>(TP)->getDecl();
397 case Type::ObjCObject:
398 D = cast<ObjCObjectType>(TP)->getInterface();
400 case Type::ObjCInterface:
401 D = cast<ObjCInterfaceType>(TP)->getDecl();
405 D = cast<TagType>(TP)->getDecl();
407 case Type::TemplateSpecialization:
408 if (const RecordType *Record = TP->getAs<RecordType>())
409 D = Record->getDecl();
411 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
412 .getAsTemplateDecl();
416 TP = cast<AutoType>(TP)->getDeducedType().getTypePtrOrNull();
421 case Type::InjectedClassName:
422 D = cast<InjectedClassNameType>(TP)->getDecl();
425 // FIXME: Template type parameters!
427 case Type::Elaborated:
428 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
436 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
438 return cxcursor::MakeCXCursor(D, GetTU(CT));
441 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
442 const char *s = nullptr;
443 #define TKIND(X) case CXType_##X: s = "" #X ""; break
460 case CXType_WChar: s = "WChar"; break;
478 TKIND(LValueReference);
479 TKIND(RValueReference);
483 TKIND(ObjCInterface);
484 TKIND(ObjCObjectPointer);
485 TKIND(FunctionNoProto);
486 TKIND(FunctionProto);
487 TKIND(ConstantArray);
488 TKIND(IncompleteArray);
489 TKIND(VariableArray);
490 TKIND(DependentSizedArray);
492 TKIND(MemberPointer);
496 return cxstring::createRef(s);
499 unsigned clang_equalTypes(CXType A, CXType B) {
500 return A.data[0] == B.data[0] && A.data[1] == B.data[1];
503 unsigned clang_isFunctionTypeVariadic(CXType X) {
504 QualType T = GetQualType(X);
508 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
509 return (unsigned)FD->isVariadic();
511 if (T->getAs<FunctionNoProtoType>())
517 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
518 QualType T = GetQualType(X);
520 return CXCallingConv_Invalid;
522 if (const FunctionType *FD = T->getAs<FunctionType>()) {
523 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
524 switch (FD->getCallConv()) {
526 TCALLINGCONV(X86StdCall);
527 TCALLINGCONV(X86FastCall);
528 TCALLINGCONV(X86ThisCall);
529 TCALLINGCONV(X86Pascal);
530 TCALLINGCONV(X86VectorCall);
531 TCALLINGCONV(X86_64Win64);
532 TCALLINGCONV(X86_64SysV);
534 TCALLINGCONV(AAPCS_VFP);
535 TCALLINGCONV(IntelOclBicc);
536 case CC_SpirFunction: return CXCallingConv_Unexposed;
537 case CC_SpirKernel: return CXCallingConv_Unexposed;
543 return CXCallingConv_Invalid;
546 int clang_getNumArgTypes(CXType X) {
547 QualType T = GetQualType(X);
551 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
552 return FD->getNumParams();
555 if (T->getAs<FunctionNoProtoType>()) {
562 CXType clang_getArgType(CXType X, unsigned i) {
563 QualType T = GetQualType(X);
565 return MakeCXType(QualType(), GetTU(X));
567 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
568 unsigned numParams = FD->getNumParams();
570 return MakeCXType(QualType(), GetTU(X));
572 return MakeCXType(FD->getParamType(i), GetTU(X));
575 return MakeCXType(QualType(), GetTU(X));
578 CXType clang_getResultType(CXType X) {
579 QualType T = GetQualType(X);
581 return MakeCXType(QualType(), GetTU(X));
583 if (const FunctionType *FD = T->getAs<FunctionType>())
584 return MakeCXType(FD->getReturnType(), GetTU(X));
586 return MakeCXType(QualType(), GetTU(X));
589 CXType clang_getCursorResultType(CXCursor C) {
590 if (clang_isDeclaration(C.kind)) {
591 const Decl *D = cxcursor::getCursorDecl(C);
592 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
593 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
595 return clang_getResultType(clang_getCursorType(C));
598 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
601 unsigned clang_isPODType(CXType X) {
602 QualType T = GetQualType(X);
606 CXTranslationUnit TU = GetTU(X);
608 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
611 CXType clang_getElementType(CXType CT) {
612 QualType ET = QualType();
613 QualType T = GetQualType(CT);
614 const Type *TP = T.getTypePtrOrNull();
617 switch (TP->getTypeClass()) {
618 case Type::ConstantArray:
619 ET = cast<ConstantArrayType> (TP)->getElementType();
621 case Type::IncompleteArray:
622 ET = cast<IncompleteArrayType> (TP)->getElementType();
624 case Type::VariableArray:
625 ET = cast<VariableArrayType> (TP)->getElementType();
627 case Type::DependentSizedArray:
628 ET = cast<DependentSizedArrayType> (TP)->getElementType();
631 ET = cast<VectorType> (TP)->getElementType();
634 ET = cast<ComplexType> (TP)->getElementType();
640 return MakeCXType(ET, GetTU(CT));
643 long long clang_getNumElements(CXType CT) {
644 long long result = -1;
645 QualType T = GetQualType(CT);
646 const Type *TP = T.getTypePtrOrNull();
649 switch (TP->getTypeClass()) {
650 case Type::ConstantArray:
651 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
654 result = cast<VectorType> (TP)->getNumElements();
663 CXType clang_getArrayElementType(CXType CT) {
664 QualType ET = QualType();
665 QualType T = GetQualType(CT);
666 const Type *TP = T.getTypePtrOrNull();
669 switch (TP->getTypeClass()) {
670 case Type::ConstantArray:
671 ET = cast<ConstantArrayType> (TP)->getElementType();
673 case Type::IncompleteArray:
674 ET = cast<IncompleteArrayType> (TP)->getElementType();
676 case Type::VariableArray:
677 ET = cast<VariableArrayType> (TP)->getElementType();
679 case Type::DependentSizedArray:
680 ET = cast<DependentSizedArrayType> (TP)->getElementType();
686 return MakeCXType(ET, GetTU(CT));
689 long long clang_getArraySize(CXType CT) {
690 long long result = -1;
691 QualType T = GetQualType(CT);
692 const Type *TP = T.getTypePtrOrNull();
695 switch (TP->getTypeClass()) {
696 case Type::ConstantArray:
697 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
706 long long clang_Type_getAlignOf(CXType T) {
707 if (T.kind == CXType_Invalid)
708 return CXTypeLayoutError_Invalid;
709 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
710 QualType QT = GetQualType(T);
711 // [expr.alignof] p1: return size_t value for complete object type, reference
713 // [expr.alignof] p3: if reference type, return size of referenced type
714 if (QT->isReferenceType())
715 QT = QT.getNonReferenceType();
716 if (QT->isIncompleteType())
717 return CXTypeLayoutError_Incomplete;
718 if (QT->isDependentType())
719 return CXTypeLayoutError_Dependent;
720 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
721 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
722 // if (QT->isVoidType()) return 1;
723 return Ctx.getTypeAlignInChars(QT).getQuantity();
726 CXType clang_Type_getClassType(CXType CT) {
727 QualType ET = QualType();
728 QualType T = GetQualType(CT);
729 const Type *TP = T.getTypePtrOrNull();
731 if (TP && TP->getTypeClass() == Type::MemberPointer) {
732 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
734 return MakeCXType(ET, GetTU(CT));
737 long long clang_Type_getSizeOf(CXType T) {
738 if (T.kind == CXType_Invalid)
739 return CXTypeLayoutError_Invalid;
740 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
741 QualType QT = GetQualType(T);
742 // [expr.sizeof] p2: if reference type, return size of referenced type
743 if (QT->isReferenceType())
744 QT = QT.getNonReferenceType();
745 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
747 // Note: We get the cxtype, not the cxcursor, so we can't call
748 // FieldDecl->isBitField()
749 // [expr.sizeof] p3: pointer ok, function not ok.
750 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
751 if (QT->isIncompleteType())
752 return CXTypeLayoutError_Incomplete;
753 if (QT->isDependentType())
754 return CXTypeLayoutError_Dependent;
755 if (!QT->isConstantSizeType())
756 return CXTypeLayoutError_NotConstantSize;
757 // [gcc extension] lib/AST/ExprConstant.cpp:1372
758 // HandleSizeof : {voidtype,functype} == 1
759 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
760 if (QT->isVoidType() || QT->isFunctionType())
762 return Ctx.getTypeSizeInChars(QT).getQuantity();
765 static long long visitRecordForValidation(const RecordDecl *RD) {
766 for (const auto *I : RD->fields()){
767 QualType FQT = I->getType();
768 if (FQT->isIncompleteType())
769 return CXTypeLayoutError_Incomplete;
770 if (FQT->isDependentType())
771 return CXTypeLayoutError_Dependent;
773 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
774 if (const RecordDecl *Child = ChildType->getDecl()) {
775 long long ret = visitRecordForValidation(Child);
780 // else try next field
785 static long long validateFieldParentType(CXCursor PC, CXType PT){
786 if (clang_isInvalid(PC.kind))
787 return CXTypeLayoutError_Invalid;
788 const RecordDecl *RD =
789 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
790 // validate parent declaration
791 if (!RD || RD->isInvalidDecl())
792 return CXTypeLayoutError_Invalid;
793 RD = RD->getDefinition();
795 return CXTypeLayoutError_Incomplete;
796 if (RD->isInvalidDecl())
797 return CXTypeLayoutError_Invalid;
798 // validate parent type
799 QualType RT = GetQualType(PT);
800 if (RT->isIncompleteType())
801 return CXTypeLayoutError_Incomplete;
802 if (RT->isDependentType())
803 return CXTypeLayoutError_Dependent;
804 // We recurse into all record fields to detect incomplete and dependent types.
805 long long Error = visitRecordForValidation(RD);
811 long long clang_Type_getOffsetOf(CXType PT, const char *S) {
812 // check that PT is not incomplete/dependent
813 CXCursor PC = clang_getTypeDeclaration(PT);
814 long long Error = validateFieldParentType(PC,PT);
818 return CXTypeLayoutError_InvalidFieldName;
820 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
821 IdentifierInfo *II = &Ctx.Idents.get(S);
822 DeclarationName FieldName(II);
823 const RecordDecl *RD =
824 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
825 // verified in validateFieldParentType
826 RD = RD->getDefinition();
827 RecordDecl::lookup_result Res = RD->lookup(FieldName);
828 // If a field of the parent record is incomplete, lookup will fail.
829 // and we would return InvalidFieldName instead of Incomplete.
830 // But this erroneous results does protects again a hidden assertion failure
831 // in the RecordLayoutBuilder
833 return CXTypeLayoutError_InvalidFieldName;
834 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
835 return Ctx.getFieldOffset(FD);
836 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
837 return Ctx.getFieldOffset(IFD);
838 // we don't want any other Decl Type.
839 return CXTypeLayoutError_InvalidFieldName;
842 long long clang_Cursor_getOffsetOfField(CXCursor C) {
843 if (clang_isDeclaration(C.kind)) {
844 // we need to validate the parent type
845 CXCursor PC = clang_getCursorSemanticParent(C);
846 CXType PT = clang_getCursorType(PC);
847 long long Error = validateFieldParentType(PC,PT);
850 // proceed with the offset calculation
851 const Decl *D = cxcursor::getCursorDecl(C);
852 ASTContext &Ctx = cxcursor::getCursorContext(C);
853 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
854 return Ctx.getFieldOffset(FD);
855 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
856 return Ctx.getFieldOffset(IFD);
861 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
862 QualType QT = GetQualType(T);
864 return CXRefQualifier_None;
865 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
867 return CXRefQualifier_None;
868 switch (FD->getRefQualifier()) {
870 return CXRefQualifier_None;
872 return CXRefQualifier_LValue;
874 return CXRefQualifier_RValue;
876 return CXRefQualifier_None;
879 unsigned clang_Cursor_isBitField(CXCursor C) {
880 if (!clang_isDeclaration(C.kind))
882 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
885 return FD->isBitField();
888 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
889 if (!clang_isDeclaration(C.kind))
890 return cxstring::createEmpty();
892 const Decl *D = cxcursor::getCursorDecl(C);
893 ASTContext &Ctx = cxcursor::getCursorContext(C);
894 std::string encoding;
896 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
897 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
898 return cxstring::createRef("?");
899 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
900 Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr, encoding);
901 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
902 Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
905 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
906 Ty = Ctx.getTypeDeclType(TD);
907 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
909 else return cxstring::createRef("?");
910 Ctx.getObjCEncodingForType(Ty, encoding);
913 return cxstring::createDup(encoding);
916 int clang_Type_getNumTemplateArguments(CXType CT) {
917 QualType T = GetQualType(CT);
920 const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
923 const ClassTemplateSpecializationDecl *TemplateDecl =
924 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
927 return TemplateDecl->getTemplateArgs().size();
930 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) {
931 QualType T = GetQualType(CT);
933 return MakeCXType(QualType(), GetTU(CT));
934 const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
936 return MakeCXType(QualType(), GetTU(CT));
937 const ClassTemplateSpecializationDecl *TemplateDecl =
938 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
940 return MakeCXType(QualType(), GetTU(CT));
941 const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs();
943 return MakeCXType(QualType(), GetTU(CT));
944 const TemplateArgument &A = TA.get(i);
945 if (A.getKind() != TemplateArgument::Type)
946 return MakeCXType(QualType(), GetTU(CT));
947 return MakeCXType(A.getAsType(), GetTU(CT));
950 unsigned clang_Type_visitFields(CXType PT,
951 CXFieldVisitor visitor,
952 CXClientData client_data){
953 CXCursor PC = clang_getTypeDeclaration(PT);
954 if (clang_isInvalid(PC.kind))
956 const RecordDecl *RD =
957 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
958 if (!RD || RD->isInvalidDecl())
960 RD = RD->getDefinition();
961 if (!RD || RD->isInvalidDecl())
964 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
966 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
967 // Callback to the client.
968 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
971 case CXVisit_Continue:
978 unsigned clang_Cursor_isAnonymous(CXCursor C){
979 if (!clang_isDeclaration(C.kind))
981 const Decl *D = cxcursor::getCursorDecl(C);
982 if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
983 return FD->isAnonymousStructOrUnion();