CXType clang_getCanonicalType(CXType CT) { if (CT.kind == CXType_Invalid) return CT; QualType T = GetQualType(CT); CXTranslationUnit TU = GetTU(CT); if (T.isNull()) return MakeCXType(QualType(), GetTU(CT)); ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData); return MakeCXType(AU->getASTContext().getCanonicalType(T), TU); }
CXType clang_getCanonicalType(CXType CT) { if (CT.kind == CXType_Invalid) return CT; QualType T = GetQualType(CT); CXTranslationUnit TU = GetTU(CT); if (T.isNull()) return MakeCXType(QualType(), GetTU(CT)); return MakeCXType(cxtu::getASTUnit(TU)->getASTContext() .getCanonicalType(T), TU); }
CXType clang_getArgType(CXType X, unsigned i) { QualType T = GetQualType(X); if (T.isNull()) return MakeCXType(QualType(), GetTU(X)); if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) { unsigned numArgs = FD->getNumArgs(); if (i >= numArgs) return MakeCXType(QualType(), GetTU(X)); return MakeCXType(FD->getArgType(i), GetTU(X)); } return MakeCXType(QualType(), GetTU(X)); }
CXType clang_Type_getObjCTypeArg(CXType CT, unsigned i) { QualType T = GetQualType(CT); if (T.isNull()) return MakeCXType(QualType(), GetTU(CT)); const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); if (!OT) return MakeCXType(QualType(), GetTU(CT)); const ArrayRef<QualType> TA = OT->getTypeArgs(); if ((size_t)i >= TA.size()) return MakeCXType(QualType(), GetTU(CT)); return MakeCXType(TA[i], GetTU(CT)); }
CXType clang_getArrayElementType(CXType CT) { QualType ET = QualType(); QualType T = GetQualType(CT); const Type *TP = T.getTypePtrOrNull(); if (TP) { switch (TP->getTypeClass()) { case Type::ConstantArray: ET = cast<ConstantArrayType> (TP)->getElementType(); break; case Type::IncompleteArray: ET = cast<IncompleteArrayType> (TP)->getElementType(); break; case Type::VariableArray: ET = cast<VariableArrayType> (TP)->getElementType(); break; case Type::DependentSizedArray: ET = cast<DependentSizedArrayType> (TP)->getElementType(); break; default: break; } } return MakeCXType(ET, GetTU(CT)); }
CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { CXTypeKind TK = CXType_Invalid; if (TU && !T.isNull()) { ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext(); if (Ctx.getLangOpts().ObjC1) { QualType UnqualT = T.getUnqualifiedType(); if (Ctx.isObjCIdType(UnqualT)) TK = CXType_ObjCId; else if (Ctx.isObjCClassType(UnqualT)) TK = CXType_ObjCClass; else if (Ctx.isObjCSelType(UnqualT)) TK = CXType_ObjCSel; } /* Handle decayed types as the original type */ if (const DecayedType *DT = T->getAs<DecayedType>()) { return MakeCXType(DT->getOriginalType(), TU); } } if (TK == CXType_Invalid) TK = GetTypeKind(T); CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }}; return CT; }
CXType clang_getEnumDeclIntegerType(CXCursor C) { using namespace cxcursor; CXTranslationUnit TU = cxcursor::getCursorTU(C); if (clang_isDeclaration(C.kind)) { const Decl *D = cxcursor::getCursorDecl(C); if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) { QualType T = TD->getIntegerType(); return MakeCXType(T, TU); } return MakeCXType(QualType(), TU); } return MakeCXType(QualType(), TU); }
CXType clang_getTypedefDeclUnderlyingType(CXCursor C) { using namespace cxcursor; CXTranslationUnit TU = cxcursor::getCursorTU(C); if (clang_isDeclaration(C.kind)) { const Decl *D = cxcursor::getCursorDecl(C); if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) { QualType T = TD->getUnderlyingType(); return MakeCXType(T, TU); } return MakeCXType(QualType(), TU); } return MakeCXType(QualType(), TU); }
CXType clang_Type_getClassType(CXType CT) { QualType ET = QualType(); QualType T = GetQualType(CT); const Type *TP = T.getTypePtrOrNull(); if (TP && TP->getTypeClass() == Type::MemberPointer) { ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0); } return MakeCXType(ET, GetTU(CT)); }
CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { CXTypeKind TK = CXType_Invalid; if (TU && !T.isNull()) { // Handle attributed types as the original type if (auto *ATT = T->getAs<AttributedType>()) { if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes)) { return MakeCXType(ATT->getModifiedType(), TU); } } // Handle paren types as the original type if (auto *PTT = T->getAs<ParenType>()) { return MakeCXType(PTT->getInnerType(), TU); } ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext(); if (Ctx.getLangOpts().ObjC) { QualType UnqualT = T.getUnqualifiedType(); if (Ctx.isObjCIdType(UnqualT)) TK = CXType_ObjCId; else if (Ctx.isObjCClassType(UnqualT)) TK = CXType_ObjCClass; else if (Ctx.isObjCSelType(UnqualT)) TK = CXType_ObjCSel; } /* Handle decayed types as the original type */ if (const DecayedType *DT = T->getAs<DecayedType>()) { return MakeCXType(DT->getOriginalType(), TU); } } if (TK == CXType_Invalid) TK = GetTypeKind(T); CXType CT = { TK, { TK == CXType_Invalid ? nullptr : T.getAsOpaquePtr(), TU } }; return CT; }
CXType clang_getPointeeType(CXType CT) { QualType T = GetQualType(CT); const Type *TP = T.getTypePtrOrNull(); if (!TP) return MakeCXType(QualType(), GetTU(CT)); try_again: switch (TP->getTypeClass()) { case Type::Pointer: T = cast<PointerType>(TP)->getPointeeType(); break; case Type::BlockPointer: T = cast<BlockPointerType>(TP)->getPointeeType(); break; case Type::LValueReference: case Type::RValueReference: T = cast<ReferenceType>(TP)->getPointeeType(); break; case Type::ObjCObjectPointer: T = cast<ObjCObjectPointerType>(TP)->getPointeeType(); break; case Type::MemberPointer: T = cast<MemberPointerType>(TP)->getPointeeType(); break; case Type::Auto: case Type::DeducedTemplateSpecialization: TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull(); if (TP) goto try_again; break; default: T = QualType(); break; } return MakeCXType(T, GetTU(CT)); }
CXType clang_getElementType(CXType CT) { QualType ET = QualType(); QualType T = GetQualType(CT); const Type *TP = T.getTypePtrOrNull(); if (TP) { switch (TP->getTypeClass()) { case Type::ConstantArray: ET = cast<ConstantArrayType> (TP)->getElementType(); break; case Type::Vector: ET = cast<VectorType> (TP)->getElementType(); break; case Type::Complex: ET = cast<ComplexType> (TP)->getElementType(); break; default: break; } } return MakeCXType(ET, GetTU(CT)); }
CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) { QualType T = GetQualType(CT); if (T.isNull()) return MakeCXType(QualType(), GetTU(CT)); const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl(); if (!RecordDecl) return MakeCXType(QualType(), GetTU(CT)); const ClassTemplateSpecializationDecl *TemplateDecl = dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl); if (!TemplateDecl) return MakeCXType(QualType(), GetTU(CT)); const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs(); if (TA.size() <= i) return MakeCXType(QualType(), GetTU(CT)); const TemplateArgument &A = TA.get(i); if (A.getKind() != TemplateArgument::Type) return MakeCXType(QualType(), GetTU(CT)); return MakeCXType(A.getAsType(), GetTU(CT)); }
CXType clang_getCursorType(CXCursor C) { using namespace cxcursor; CXTranslationUnit TU = cxcursor::getCursorTU(C); if (!TU) return MakeCXType(QualType(), TU); ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext(); if (clang_isExpression(C.kind)) { QualType T = cxcursor::getCursorExpr(C)->getType(); return MakeCXType(T, TU); } if (clang_isDeclaration(C.kind)) { const Decl *D = cxcursor::getCursorDecl(C); if (!D) return MakeCXType(QualType(), TU); if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) return MakeCXType(Context.getTypeDeclType(TD), TU); if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) return MakeCXType(Context.getObjCInterfaceType(ID), TU); if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) return MakeCXType(VD->getType(), TU); if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) return MakeCXType(PD->getType(), TU); if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) return MakeCXType(FD->getType(), TU); return MakeCXType(QualType(), TU); } if (clang_isReference(C.kind)) { switch (C.kind) { case CXCursor_ObjCSuperClassRef: { QualType T = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first); return MakeCXType(T, TU); } case CXCursor_ObjCClassRef: { QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first); return MakeCXType(T, TU); } case CXCursor_TypeRef: { QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first); return MakeCXType(T, TU); } case CXCursor_CXXBaseSpecifier: return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU); case CXCursor_MemberRef: return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU); case CXCursor_VariableRef: return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU); case CXCursor_ObjCProtocolRef: case CXCursor_TemplateRef: case CXCursor_NamespaceRef: case CXCursor_OverloadedDeclRef: default: break; } return MakeCXType(QualType(), TU); } return MakeCXType(QualType(), TU); }