Author: mwu Date: Thu Aug 2 20:03:20 2018 New Revision: 338804 URL: http://llvm.org/viewvc/llvm-project?rev=338804&view=rev Log: [libclang 1/8] Add support for ObjCObjectType
Summary: This patch adds support to the clang-c API for identifying ObjCObjects in CXTypes, enumerating type args and protocols on ObjCObjectTypes, and retrieving the base type of ObjCObjectTypes. Currently only ObjCInterfaceTypes are exposed, which do not have type args or protocols. Reviewers: yvvan, jbcoe Reviewed By: yvvan Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D49063 Added: cfe/trunk/test/Index/objc-typeargs-protocols.m Modified: cfe/trunk/include/clang-c/Index.h cfe/trunk/test/Index/print-type.m cfe/trunk/tools/c-index-test/c-index-test.c cfe/trunk/tools/libclang/CXType.cpp cfe/trunk/tools/libclang/libclang.exports Modified: cfe/trunk/include/clang-c/Index.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=338804&r1=338803&r2=338804&view=diff ============================================================================== --- cfe/trunk/include/clang-c/Index.h (original) +++ cfe/trunk/include/clang-c/Index.h Thu Aug 2 20:03:20 2018 @@ -3265,7 +3265,9 @@ enum CXTypeKind { CXType_OCLSampler = 157, CXType_OCLEvent = 158, CXType_OCLQueue = 159, - CXType_OCLReserveID = 160 + CXType_OCLReserveID = 160, + + CXType_ObjCObject = 161 }; /** @@ -3627,6 +3629,43 @@ CINDEX_LINKAGE int clang_getNumArgTypes( CINDEX_LINKAGE CXType clang_getArgType(CXType T, unsigned i); /** + * Retrieves the base type of the ObjCObjectType. + * + * If the type is not an ObjC object, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getObjCObjectBaseType(CXType T); + +/** + * Retrieve the number of protocol references associated with an ObjC object/id. + * + * If the type is not an ObjC object, 0 is returned. + */ +CINDEX_LINKAGE unsigned clang_Type_getNumObjCProtocolRefs(CXType T); + +/** + * Retrieve the decl for a protocol reference for an ObjC object/id. + * + * If the type is not an ObjC object or there are not enough protocol + * references, an invalid cursor is returned. + */ +CINDEX_LINKAGE CXCursor clang_Type_getObjCProtocolDecl(CXType T, unsigned i); + +/** + * Retreive the number of type arguments associated with an ObjC object. + * + * If the type is not an ObjC object, 0 is returned. + */ +CINDEX_LINKAGE unsigned clang_Type_getNumObjCTypeArgs(CXType T); + +/** + * Retrieve a type argument associated with an ObjC object. + * + * If the type is not an ObjC or the index is not valid, + * an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getObjCTypeArg(CXType T, unsigned i); + +/** * Return 1 if the CXType is a variadic function type, and 0 otherwise. */ CINDEX_LINKAGE unsigned clang_isFunctionTypeVariadic(CXType T); Added: cfe/trunk/test/Index/objc-typeargs-protocols.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/objc-typeargs-protocols.m?rev=338804&view=auto ============================================================================== --- cfe/trunk/test/Index/objc-typeargs-protocols.m (added) +++ cfe/trunk/test/Index/objc-typeargs-protocols.m Thu Aug 2 20:03:20 2018 @@ -0,0 +1,28 @@ + +@interface TestA +@end + +@interface TestB +@end + +@protocol Bar +@end + +@interface Base +@end + +@interface Foo<FirstType, SecondType> : Base +@end + +Foo *a; +Foo<TestA *, TestB *> *b; +Foo<Bar> *c; +Foo<TestA *, TestB *><Bar> *d; +id<Bar> e; + +// RUN: c-index-test -test-print-type %s | FileCheck %s +// CHECK: VarDecl=a:17:6 [type=Foo *] [typekind=ObjCObjectPointer] [basetype=Foo] [basekind=ObjCInterface] [isPOD=1] [pointeetype=Foo] [pointeekind=ObjCInterface] +// CHECK: VarDecl=b:18:24 [type=Foo<TestA *,TestB *> *] [typekind=ObjCObjectPointer] [basetype=Foo] [basekind=ObjCInterface] [typeargs= [TestA *] [ObjCObjectPointer] [TestB *] [ObjCObjectPointer]] [isPOD=1] [pointeetype=Foo<TestA *,TestB *>] [pointeekind=ObjCObject] +// CHECK: VarDecl=c:19:11 [type=Foo<Bar> *] [typekind=ObjCObjectPointer] [basetype=Foo] [basekind=ObjCInterface] [protocols=ObjCProtocolDecl=Bar:8:11 (Definition)] [isPOD=1] [pointeetype=Foo<Bar>] [pointeekind=ObjCObject] +// CHECK: VarDecl=d:20:29 [type=Foo<TestA *,TestB *><Bar> *] [typekind=ObjCObjectPointer] [basetype=Foo] [basekind=ObjCInterface] [typeargs= [TestA *] [ObjCObjectPointer] [TestB *] [ObjCObjectPointer]] [protocols=ObjCProtocolDecl=Bar:8:11 (Definition)] [isPOD=1] [pointeetype=Foo<TestA *,TestB *><Bar>] [pointeekind=ObjCObject] +// CHECK: VarDecl=e:21:9 [type=id<Bar>] [typekind=ObjCObjectPointer] [basetype=id] [basekind=ObjCId] [protocols=ObjCProtocolDecl=Bar:8:11 (Definition)] [isPOD=1] [pointeetype=id<Bar>] [pointeekind=ObjCObject] Modified: cfe/trunk/test/Index/print-type.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-type.m?rev=338804&r1=338803&r2=338804&view=diff ============================================================================== --- cfe/trunk/test/Index/print-type.m (original) +++ cfe/trunk/test/Index/print-type.m Thu Aug 2 20:03:20 2018 @@ -15,5 +15,5 @@ // CHECK: ObjCInstanceMethodDecl=methodIn:andOut::5:10 (variadic) [Bycopy,] [type=] [typekind=Invalid] [resulttype=id] [resulttypekind=ObjCId] [args= [int] [Int] [short *] [Pointer]] [isPOD=0] // CHECK: ParmDecl=i:5:27 (Definition) [In,] [type=int] [typekind=Int] [isPOD=1] // CHECK: ParmDecl=j:5:49 (Definition) [Out,] [type=short *] [typekind=Pointer] [isPOD=1] [pointeetype=short] [pointeekind=Short] -// CHECK: ParmDecl=p:6:36 (Definition) [type=__kindof Foo *] [typekind=ObjCObjectPointer] [canonicaltype=__kindof Foo *] [canonicaltypekind=ObjCObjectPointer] [isPOD=1] [pointeetype=Foo] [pointeekind=ObjCInterface] +// CHECK: ParmDecl=p:6:36 (Definition) [type=__kindof Foo *] [typekind=ObjCObjectPointer] [canonicaltype=__kindof Foo *] [canonicaltypekind=ObjCObjectPointer] [basetype=Foo] [basekind=ObjCInterface] [isPOD=1] [pointeetype=Foo] [pointeekind=ObjCInterface] // CHECK: ObjCPropertyDecl=classProp:7:23 [class,] [type=int] [typekind=Int] [isPOD=1] Modified: cfe/trunk/tools/c-index-test/c-index-test.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=338804&r1=338803&r2=338804&view=diff ============================================================================== --- cfe/trunk/tools/c-index-test/c-index-test.c (original) +++ cfe/trunk/tools/c-index-test/c-index-test.c Thu Aug 2 20:03:20 2018 @@ -1500,6 +1500,7 @@ static enum CXChildVisitResult PrintType CXClientData d) { if (!clang_isInvalid(clang_getCursorKind(cursor))) { CXType T = clang_getCursorType(cursor); + CXType PT = clang_getPointeeType(T); enum CXRefQualifierKind RQ = clang_Type_getCXXRefQualifier(T); PrintCursor(cursor, NULL); PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]"); @@ -1545,11 +1546,45 @@ static enum CXChildVisitResult PrintType printf("]"); } } + /* Print ObjC base types, type arguments, and protocol list if available. */ + { + CXType BT = clang_Type_getObjCObjectBaseType(PT); + if (BT.kind != CXType_Invalid) { + PrintTypeAndTypeKind(BT, " [basetype=%s] [basekind=%s]"); + } + } + { + unsigned NumTypeArgs = clang_Type_getNumObjCTypeArgs(PT); + if (NumTypeArgs > 0) { + unsigned i; + printf(" [typeargs="); + for (i = 0; i < NumTypeArgs; ++i) { + CXType TA = clang_Type_getObjCTypeArg(PT, i); + if (TA.kind != CXType_Invalid) { + PrintTypeAndTypeKind(TA, " [%s] [%s]"); + } + } + printf("]"); + } + } + { + unsigned NumProtocols = clang_Type_getNumObjCProtocolRefs(PT); + if (NumProtocols > 0) { + unsigned i; + printf(" [protocols="); + for (i = 0; i < NumProtocols; ++i) { + CXCursor P = clang_Type_getObjCProtocolDecl(PT, i); + if (!clang_isInvalid(clang_getCursorKind(P))) { + PrintCursor(P, NULL); + } + } + printf("]"); + } + } /* Print if this is a non-POD type. */ printf(" [isPOD=%d]", clang_isPODType(T)); /* Print the pointee type. */ { - CXType PT = clang_getPointeeType(T); if (PT.kind != CXType_Invalid) { PrintTypeAndTypeKind(PT, " [pointeetype=%s] [pointeekind=%s]"); } Modified: cfe/trunk/tools/libclang/CXType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXType.cpp?rev=338804&r1=338803&r2=338804&view=diff ============================================================================== --- cfe/trunk/tools/libclang/CXType.cpp (original) +++ cfe/trunk/tools/libclang/CXType.cpp Thu Aug 2 20:03:20 2018 @@ -98,6 +98,7 @@ static CXTypeKind GetTypeKind(QualType T TKCASE(Enum); TKCASE(Typedef); TKCASE(ObjCInterface); + TKCASE(ObjCObject); TKCASE(ObjCObjectPointer); TKCASE(FunctionNoProto); TKCASE(FunctionProto); @@ -575,6 +576,7 @@ CXString clang_getTypeKindSpelling(enum TKIND(Enum); TKIND(Typedef); TKIND(ObjCInterface); + TKIND(ObjCObject); TKIND(ObjCObjectPointer); TKIND(FunctionNoProto); TKIND(FunctionProto); @@ -1098,6 +1100,74 @@ CXType clang_Type_getTemplateArgumentAsT return MakeCXType(QT.getValueOr(QualType()), GetTU(CT)); } +CXType clang_Type_getObjCObjectBaseType(CXType CT) { + 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)); + + return MakeCXType(OT->getBaseType(), GetTU(CT)); +} + +unsigned clang_Type_getNumObjCProtocolRefs(CXType CT) { + QualType T = GetQualType(CT); + if (T.isNull()) + return 0; + + const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); + if (!OT) + return 0; + + return OT->getNumProtocols(); +} + +CXCursor clang_Type_getObjCProtocolDecl(CXType CT, unsigned i) { + QualType T = GetQualType(CT); + if (T.isNull()) + return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); + + const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); + if (!OT) + return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); + + const ObjCProtocolDecl *PD = OT->getProtocol(i); + if (!PD) + return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); + + return cxcursor::MakeCXCursor(PD, GetTU(CT)); +} + +unsigned clang_Type_getNumObjCTypeArgs(CXType CT) { + QualType T = GetQualType(CT); + if (T.isNull()) + return 0; + + const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T); + if (!OT) + return 0; + + return OT->getTypeArgs().size(); +} + +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)); +} + unsigned clang_Type_visitFields(CXType PT, CXFieldVisitor visitor, CXClientData client_data){ Modified: cfe/trunk/tools/libclang/libclang.exports URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=338804&r1=338803&r2=338804&view=diff ============================================================================== --- cfe/trunk/tools/libclang/libclang.exports (original) +++ cfe/trunk/tools/libclang/libclang.exports Thu Aug 2 20:03:20 2018 @@ -98,6 +98,11 @@ clang_Type_getCXXRefQualifier clang_Type_visitFields clang_Type_getNamedType clang_Type_isTransparentTagTypedef +clang_Type_getObjCObjectBaseType +clang_Type_getNumObjCProtocolRefs +clang_Type_getObjCProtocolDecl +clang_Type_getNumObjCTypeArgs +clang_Type_getObjCTypeArg clang_VerbatimBlockLineComment_getText clang_VerbatimLineComment_getText clang_HTMLTagComment_getAsString _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits