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;
62 return CXType_Unexposed;
67 static CXTypeKind GetTypeKind(QualType T) {
68 const Type *TP = T.getTypePtrOrNull();
70 return CXType_Invalid;
72 #define TKCASE(K) case Type::K: return CXType_##K
73 switch (TP->getTypeClass()) {
75 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
79 TKCASE(LValueReference);
80 TKCASE(RValueReference);
84 TKCASE(ObjCInterface);
85 TKCASE(ObjCObjectPointer);
86 TKCASE(FunctionNoProto);
87 TKCASE(FunctionProto);
88 TKCASE(ConstantArray);
89 TKCASE(IncompleteArray);
90 TKCASE(VariableArray);
91 TKCASE(DependentSizedArray);
93 TKCASE(MemberPointer);
97 return CXType_Unexposed;
103 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
104 CXTypeKind TK = CXType_Invalid;
106 if (TU && !T.isNull()) {
107 // Handle attributed types as the original type
108 if (auto *ATT = T->getAs<AttributedType>()) {
109 return MakeCXType(ATT->getModifiedType(), TU);
112 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
113 if (Ctx.getLangOpts().ObjC1) {
114 QualType UnqualT = T.getUnqualifiedType();
115 if (Ctx.isObjCIdType(UnqualT))
117 else if (Ctx.isObjCClassType(UnqualT))
118 TK = CXType_ObjCClass;
119 else if (Ctx.isObjCSelType(UnqualT))
123 /* Handle decayed types as the original type */
124 if (const DecayedType *DT = T->getAs<DecayedType>()) {
125 return MakeCXType(DT->getOriginalType(), TU);
128 if (TK == CXType_Invalid)
131 CXType CT = { TK, { TK == CXType_Invalid ? nullptr
132 : T.getAsOpaquePtr(), TU } };
136 using cxtype::MakeCXType;
138 static inline QualType GetQualType(CXType CT) {
139 return QualType::getFromOpaquePtr(CT.data[0]);
142 static inline CXTranslationUnit GetTU(CXType CT) {
143 return static_cast<CXTranslationUnit>(CT.data[1]);
146 static Optional<ArrayRef<TemplateArgument>>
147 GetTemplateArguments(QualType Type) {
148 assert(!Type.isNull());
149 if (const auto *Specialization = Type->getAs<TemplateSpecializationType>())
150 return Specialization->template_arguments();
152 if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) {
153 const auto *TemplateDecl =
154 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
156 return TemplateDecl->getTemplateArgs().asArray();
162 static Optional<QualType> TemplateArgumentToQualType(const TemplateArgument &A) {
163 if (A.getKind() == TemplateArgument::Type)
164 return A.getAsType();
168 static Optional<QualType>
169 FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) {
170 unsigned current = 0;
171 for (const auto &A : TA) {
172 if (A.getKind() == TemplateArgument::Pack) {
173 if (index < current + A.pack_size())
174 return TemplateArgumentToQualType(A.getPackAsArray()[index - current]);
175 current += A.pack_size();
178 if (current == index)
179 return TemplateArgumentToQualType(A);
185 CXType clang_getCursorType(CXCursor C) {
186 using namespace cxcursor;
188 CXTranslationUnit TU = cxcursor::getCursorTU(C);
190 return MakeCXType(QualType(), TU);
192 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
193 if (clang_isExpression(C.kind)) {
194 QualType T = cxcursor::getCursorExpr(C)->getType();
195 return MakeCXType(T, TU);
198 if (clang_isDeclaration(C.kind)) {
199 const Decl *D = cxcursor::getCursorDecl(C);
201 return MakeCXType(QualType(), TU);
203 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
204 return MakeCXType(Context.getTypeDeclType(TD), TU);
205 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
206 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
207 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
208 return MakeCXType(DD->getType(), TU);
209 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
210 return MakeCXType(VD->getType(), TU);
211 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
212 return MakeCXType(PD->getType(), TU);
213 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
214 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
215 return MakeCXType(QualType(), TU);
218 if (clang_isReference(C.kind)) {
220 case CXCursor_ObjCSuperClassRef: {
222 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
223 return MakeCXType(T, TU);
226 case CXCursor_ObjCClassRef: {
227 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
228 return MakeCXType(T, TU);
231 case CXCursor_TypeRef: {
232 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
233 return MakeCXType(T, TU);
237 case CXCursor_CXXBaseSpecifier:
238 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
240 case CXCursor_MemberRef:
241 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
243 case CXCursor_VariableRef:
244 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
246 case CXCursor_ObjCProtocolRef:
247 case CXCursor_TemplateRef:
248 case CXCursor_NamespaceRef:
249 case CXCursor_OverloadedDeclRef:
254 return MakeCXType(QualType(), TU);
257 return MakeCXType(QualType(), TU);
260 CXString clang_getTypeSpelling(CXType CT) {
261 QualType T = GetQualType(CT);
263 return cxstring::createEmpty();
265 CXTranslationUnit TU = GetTU(CT);
267 llvm::raw_svector_ostream OS(Str);
268 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
272 return cxstring::createDup(OS.str());
275 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
276 using namespace cxcursor;
277 CXTranslationUnit TU = cxcursor::getCursorTU(C);
279 if (clang_isDeclaration(C.kind)) {
280 const Decl *D = cxcursor::getCursorDecl(C);
282 if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
283 QualType T = TD->getUnderlyingType();
284 return MakeCXType(T, TU);
287 return MakeCXType(QualType(), TU);
290 return MakeCXType(QualType(), TU);
293 CXType clang_getEnumDeclIntegerType(CXCursor C) {
294 using namespace cxcursor;
295 CXTranslationUnit TU = cxcursor::getCursorTU(C);
297 if (clang_isDeclaration(C.kind)) {
298 const Decl *D = cxcursor::getCursorDecl(C);
300 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
301 QualType T = TD->getIntegerType();
302 return MakeCXType(T, TU);
305 return MakeCXType(QualType(), TU);
308 return MakeCXType(QualType(), TU);
311 long long clang_getEnumConstantDeclValue(CXCursor C) {
312 using namespace cxcursor;
314 if (clang_isDeclaration(C.kind)) {
315 const Decl *D = cxcursor::getCursorDecl(C);
317 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
318 return TD->getInitVal().getSExtValue();
327 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
328 using namespace cxcursor;
330 if (clang_isDeclaration(C.kind)) {
331 const Decl *D = cxcursor::getCursorDecl(C);
333 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
334 return TD->getInitVal().getZExtValue();
343 int clang_getFieldDeclBitWidth(CXCursor C) {
344 using namespace cxcursor;
346 if (clang_isDeclaration(C.kind)) {
347 const Decl *D = getCursorDecl(C);
349 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
350 if (FD->isBitField())
351 return FD->getBitWidthValue(getCursorContext(C));
358 CXType clang_getCanonicalType(CXType CT) {
359 if (CT.kind == CXType_Invalid)
362 QualType T = GetQualType(CT);
363 CXTranslationUnit TU = GetTU(CT);
366 return MakeCXType(QualType(), GetTU(CT));
368 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
369 .getCanonicalType(T),
373 unsigned clang_isConstQualifiedType(CXType CT) {
374 QualType T = GetQualType(CT);
375 return T.isLocalConstQualified();
378 unsigned clang_isVolatileQualifiedType(CXType CT) {
379 QualType T = GetQualType(CT);
380 return T.isLocalVolatileQualified();
383 unsigned clang_isRestrictQualifiedType(CXType CT) {
384 QualType T = GetQualType(CT);
385 return T.isLocalRestrictQualified();
388 CXType clang_getPointeeType(CXType CT) {
389 QualType T = GetQualType(CT);
390 const Type *TP = T.getTypePtrOrNull();
393 return MakeCXType(QualType(), GetTU(CT));
395 switch (TP->getTypeClass()) {
397 T = cast<PointerType>(TP)->getPointeeType();
399 case Type::BlockPointer:
400 T = cast<BlockPointerType>(TP)->getPointeeType();
402 case Type::LValueReference:
403 case Type::RValueReference:
404 T = cast<ReferenceType>(TP)->getPointeeType();
406 case Type::ObjCObjectPointer:
407 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
409 case Type::MemberPointer:
410 T = cast<MemberPointerType>(TP)->getPointeeType();
416 return MakeCXType(T, GetTU(CT));
419 CXCursor clang_getTypeDeclaration(CXType CT) {
420 if (CT.kind == CXType_Invalid)
421 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
423 QualType T = GetQualType(CT);
424 const Type *TP = T.getTypePtrOrNull();
427 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
432 switch (TP->getTypeClass()) {
434 D = cast<TypedefType>(TP)->getDecl();
436 case Type::ObjCObject:
437 D = cast<ObjCObjectType>(TP)->getInterface();
439 case Type::ObjCInterface:
440 D = cast<ObjCInterfaceType>(TP)->getDecl();
444 D = cast<TagType>(TP)->getDecl();
446 case Type::TemplateSpecialization:
447 if (const RecordType *Record = TP->getAs<RecordType>())
448 D = Record->getDecl();
450 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
451 .getAsTemplateDecl();
455 TP = cast<AutoType>(TP)->getDeducedType().getTypePtrOrNull();
460 case Type::InjectedClassName:
461 D = cast<InjectedClassNameType>(TP)->getDecl();
464 // FIXME: Template type parameters!
466 case Type::Elaborated:
467 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
475 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
477 return cxcursor::MakeCXCursor(D, GetTU(CT));
480 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
481 const char *s = nullptr;
482 #define TKIND(X) case CXType_##X: s = "" #X ""; break
499 case CXType_WChar: s = "WChar"; break;
518 TKIND(LValueReference);
519 TKIND(RValueReference);
523 TKIND(ObjCInterface);
524 TKIND(ObjCObjectPointer);
525 TKIND(FunctionNoProto);
526 TKIND(FunctionProto);
527 TKIND(ConstantArray);
528 TKIND(IncompleteArray);
529 TKIND(VariableArray);
530 TKIND(DependentSizedArray);
532 TKIND(MemberPointer);
537 return cxstring::createRef(s);
540 unsigned clang_equalTypes(CXType A, CXType B) {
541 return A.data[0] == B.data[0] && A.data[1] == B.data[1];
544 unsigned clang_isFunctionTypeVariadic(CXType X) {
545 QualType T = GetQualType(X);
549 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
550 return (unsigned)FD->isVariadic();
552 if (T->getAs<FunctionNoProtoType>())
558 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
559 QualType T = GetQualType(X);
561 return CXCallingConv_Invalid;
563 if (const FunctionType *FD = T->getAs<FunctionType>()) {
564 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
565 switch (FD->getCallConv()) {
567 TCALLINGCONV(X86StdCall);
568 TCALLINGCONV(X86FastCall);
569 TCALLINGCONV(X86ThisCall);
570 TCALLINGCONV(X86Pascal);
571 TCALLINGCONV(X86RegCall);
572 TCALLINGCONV(X86VectorCall);
573 TCALLINGCONV(X86_64Win64);
574 TCALLINGCONV(X86_64SysV);
576 TCALLINGCONV(AAPCS_VFP);
577 TCALLINGCONV(IntelOclBicc);
579 TCALLINGCONV(PreserveMost);
580 TCALLINGCONV(PreserveAll);
581 case CC_SpirFunction: return CXCallingConv_Unexposed;
582 case CC_OpenCLKernel: return CXCallingConv_Unexposed;
588 return CXCallingConv_Invalid;
591 int clang_getNumArgTypes(CXType X) {
592 QualType T = GetQualType(X);
596 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
597 return FD->getNumParams();
600 if (T->getAs<FunctionNoProtoType>()) {
607 CXType clang_getArgType(CXType X, unsigned i) {
608 QualType T = GetQualType(X);
610 return MakeCXType(QualType(), GetTU(X));
612 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
613 unsigned numParams = FD->getNumParams();
615 return MakeCXType(QualType(), GetTU(X));
617 return MakeCXType(FD->getParamType(i), GetTU(X));
620 return MakeCXType(QualType(), GetTU(X));
623 CXType clang_getResultType(CXType X) {
624 QualType T = GetQualType(X);
626 return MakeCXType(QualType(), GetTU(X));
628 if (const FunctionType *FD = T->getAs<FunctionType>())
629 return MakeCXType(FD->getReturnType(), GetTU(X));
631 return MakeCXType(QualType(), GetTU(X));
634 CXType clang_getCursorResultType(CXCursor C) {
635 if (clang_isDeclaration(C.kind)) {
636 const Decl *D = cxcursor::getCursorDecl(C);
637 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
638 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
640 return clang_getResultType(clang_getCursorType(C));
643 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
646 unsigned clang_isPODType(CXType X) {
647 QualType T = GetQualType(X);
651 CXTranslationUnit TU = GetTU(X);
653 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
656 CXType clang_getElementType(CXType CT) {
657 QualType ET = QualType();
658 QualType T = GetQualType(CT);
659 const Type *TP = T.getTypePtrOrNull();
662 switch (TP->getTypeClass()) {
663 case Type::ConstantArray:
664 ET = cast<ConstantArrayType> (TP)->getElementType();
666 case Type::IncompleteArray:
667 ET = cast<IncompleteArrayType> (TP)->getElementType();
669 case Type::VariableArray:
670 ET = cast<VariableArrayType> (TP)->getElementType();
672 case Type::DependentSizedArray:
673 ET = cast<DependentSizedArrayType> (TP)->getElementType();
676 ET = cast<VectorType> (TP)->getElementType();
679 ET = cast<ComplexType> (TP)->getElementType();
685 return MakeCXType(ET, GetTU(CT));
688 long long clang_getNumElements(CXType CT) {
689 long long result = -1;
690 QualType T = GetQualType(CT);
691 const Type *TP = T.getTypePtrOrNull();
694 switch (TP->getTypeClass()) {
695 case Type::ConstantArray:
696 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
699 result = cast<VectorType> (TP)->getNumElements();
708 CXType clang_getArrayElementType(CXType CT) {
709 QualType ET = QualType();
710 QualType T = GetQualType(CT);
711 const Type *TP = T.getTypePtrOrNull();
714 switch (TP->getTypeClass()) {
715 case Type::ConstantArray:
716 ET = cast<ConstantArrayType> (TP)->getElementType();
718 case Type::IncompleteArray:
719 ET = cast<IncompleteArrayType> (TP)->getElementType();
721 case Type::VariableArray:
722 ET = cast<VariableArrayType> (TP)->getElementType();
724 case Type::DependentSizedArray:
725 ET = cast<DependentSizedArrayType> (TP)->getElementType();
731 return MakeCXType(ET, GetTU(CT));
734 long long clang_getArraySize(CXType CT) {
735 long long result = -1;
736 QualType T = GetQualType(CT);
737 const Type *TP = T.getTypePtrOrNull();
740 switch (TP->getTypeClass()) {
741 case Type::ConstantArray:
742 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
751 long long clang_Type_getAlignOf(CXType T) {
752 if (T.kind == CXType_Invalid)
753 return CXTypeLayoutError_Invalid;
754 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
755 QualType QT = GetQualType(T);
756 // [expr.alignof] p1: return size_t value for complete object type, reference
758 // [expr.alignof] p3: if reference type, return size of referenced type
759 if (QT->isReferenceType())
760 QT = QT.getNonReferenceType();
761 if (QT->isIncompleteType())
762 return CXTypeLayoutError_Incomplete;
763 if (QT->isDependentType())
764 return CXTypeLayoutError_Dependent;
765 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
766 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
767 // if (QT->isVoidType()) return 1;
768 return Ctx.getTypeAlignInChars(QT).getQuantity();
771 CXType clang_Type_getClassType(CXType CT) {
772 QualType ET = QualType();
773 QualType T = GetQualType(CT);
774 const Type *TP = T.getTypePtrOrNull();
776 if (TP && TP->getTypeClass() == Type::MemberPointer) {
777 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
779 return MakeCXType(ET, GetTU(CT));
782 long long clang_Type_getSizeOf(CXType T) {
783 if (T.kind == CXType_Invalid)
784 return CXTypeLayoutError_Invalid;
785 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
786 QualType QT = GetQualType(T);
787 // [expr.sizeof] p2: if reference type, return size of referenced type
788 if (QT->isReferenceType())
789 QT = QT.getNonReferenceType();
790 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
792 // Note: We get the cxtype, not the cxcursor, so we can't call
793 // FieldDecl->isBitField()
794 // [expr.sizeof] p3: pointer ok, function not ok.
795 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
796 if (QT->isIncompleteType())
797 return CXTypeLayoutError_Incomplete;
798 if (QT->isDependentType())
799 return CXTypeLayoutError_Dependent;
800 if (!QT->isConstantSizeType())
801 return CXTypeLayoutError_NotConstantSize;
802 // [gcc extension] lib/AST/ExprConstant.cpp:1372
803 // HandleSizeof : {voidtype,functype} == 1
804 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
805 if (QT->isVoidType() || QT->isFunctionType())
807 return Ctx.getTypeSizeInChars(QT).getQuantity();
810 static long long visitRecordForValidation(const RecordDecl *RD) {
811 for (const auto *I : RD->fields()){
812 QualType FQT = I->getType();
813 if (FQT->isIncompleteType())
814 return CXTypeLayoutError_Incomplete;
815 if (FQT->isDependentType())
816 return CXTypeLayoutError_Dependent;
818 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
819 if (const RecordDecl *Child = ChildType->getDecl()) {
820 long long ret = visitRecordForValidation(Child);
825 // else try next field
830 static long long validateFieldParentType(CXCursor PC, CXType PT){
831 if (clang_isInvalid(PC.kind))
832 return CXTypeLayoutError_Invalid;
833 const RecordDecl *RD =
834 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
835 // validate parent declaration
836 if (!RD || RD->isInvalidDecl())
837 return CXTypeLayoutError_Invalid;
838 RD = RD->getDefinition();
840 return CXTypeLayoutError_Incomplete;
841 if (RD->isInvalidDecl())
842 return CXTypeLayoutError_Invalid;
843 // validate parent type
844 QualType RT = GetQualType(PT);
845 if (RT->isIncompleteType())
846 return CXTypeLayoutError_Incomplete;
847 if (RT->isDependentType())
848 return CXTypeLayoutError_Dependent;
849 // We recurse into all record fields to detect incomplete and dependent types.
850 long long Error = visitRecordForValidation(RD);
856 long long clang_Type_getOffsetOf(CXType PT, const char *S) {
857 // check that PT is not incomplete/dependent
858 CXCursor PC = clang_getTypeDeclaration(PT);
859 long long Error = validateFieldParentType(PC,PT);
863 return CXTypeLayoutError_InvalidFieldName;
865 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
866 IdentifierInfo *II = &Ctx.Idents.get(S);
867 DeclarationName FieldName(II);
868 const RecordDecl *RD =
869 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
870 // verified in validateFieldParentType
871 RD = RD->getDefinition();
872 RecordDecl::lookup_result Res = RD->lookup(FieldName);
873 // If a field of the parent record is incomplete, lookup will fail.
874 // and we would return InvalidFieldName instead of Incomplete.
875 // But this erroneous results does protects again a hidden assertion failure
876 // in the RecordLayoutBuilder
878 return CXTypeLayoutError_InvalidFieldName;
879 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
880 return Ctx.getFieldOffset(FD);
881 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
882 return Ctx.getFieldOffset(IFD);
883 // we don't want any other Decl Type.
884 return CXTypeLayoutError_InvalidFieldName;
887 long long clang_Cursor_getOffsetOfField(CXCursor C) {
888 if (clang_isDeclaration(C.kind)) {
889 // we need to validate the parent type
890 CXCursor PC = clang_getCursorSemanticParent(C);
891 CXType PT = clang_getCursorType(PC);
892 long long Error = validateFieldParentType(PC,PT);
895 // proceed with the offset calculation
896 const Decl *D = cxcursor::getCursorDecl(C);
897 ASTContext &Ctx = cxcursor::getCursorContext(C);
898 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
899 return Ctx.getFieldOffset(FD);
900 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
901 return Ctx.getFieldOffset(IFD);
906 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
907 QualType QT = GetQualType(T);
909 return CXRefQualifier_None;
910 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
912 return CXRefQualifier_None;
913 switch (FD->getRefQualifier()) {
915 return CXRefQualifier_None;
917 return CXRefQualifier_LValue;
919 return CXRefQualifier_RValue;
921 return CXRefQualifier_None;
924 unsigned clang_Cursor_isBitField(CXCursor C) {
925 if (!clang_isDeclaration(C.kind))
927 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
930 return FD->isBitField();
933 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
934 if (!clang_isDeclaration(C.kind))
935 return cxstring::createEmpty();
937 const Decl *D = cxcursor::getCursorDecl(C);
938 ASTContext &Ctx = cxcursor::getCursorContext(C);
939 std::string encoding;
941 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
942 encoding = Ctx.getObjCEncodingForMethodDecl(OMD);
943 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
944 encoding = Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr);
945 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
946 encoding = Ctx.getObjCEncodingForFunctionDecl(FD);
949 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
950 Ty = Ctx.getTypeDeclType(TD);
951 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
953 else return cxstring::createRef("?");
954 Ctx.getObjCEncodingForType(Ty, encoding);
957 return cxstring::createDup(encoding);
960 static unsigned GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA) {
961 unsigned size = TA.size();
962 for (const auto &Arg : TA)
963 if (Arg.getKind() == TemplateArgument::Pack)
964 size += Arg.pack_size() - 1;
968 int clang_Type_getNumTemplateArguments(CXType CT) {
969 QualType T = GetQualType(CT);
973 auto TA = GetTemplateArguments(T);
977 return GetTemplateArgumentArraySize(TA.getValue());
980 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) {
981 QualType T = GetQualType(CT);
983 return MakeCXType(QualType(), GetTU(CT));
985 auto TA = GetTemplateArguments(T);
987 return MakeCXType(QualType(), GetTU(CT));
989 Optional<QualType> QT = FindTemplateArgumentTypeAt(TA.getValue(), index);
990 return MakeCXType(QT.getValueOr(QualType()), GetTU(CT));
993 unsigned clang_Type_visitFields(CXType PT,
994 CXFieldVisitor visitor,
995 CXClientData client_data){
996 CXCursor PC = clang_getTypeDeclaration(PT);
997 if (clang_isInvalid(PC.kind))
999 const RecordDecl *RD =
1000 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
1001 if (!RD || RD->isInvalidDecl())
1003 RD = RD->getDefinition();
1004 if (!RD || RD->isInvalidDecl())
1007 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
1009 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
1010 // Callback to the client.
1011 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
1014 case CXVisit_Continue:
1021 unsigned clang_Cursor_isAnonymous(CXCursor C){
1022 if (!clang_isDeclaration(C.kind))
1024 const Decl *D = cxcursor::getCursorDecl(C);
1025 if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
1026 return FD->isAnonymousStructOrUnion();
1030 CXType clang_Type_getNamedType(CXType CT){
1031 QualType T = GetQualType(CT);
1032 const Type *TP = T.getTypePtrOrNull();
1034 if (TP && TP->getTypeClass() == Type::Elaborated)
1035 return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT));
1037 return MakeCXType(QualType(), GetTU(CT));