diff --git a/sources/ClangSharp.Interop/Extensions/CXType.cs b/sources/ClangSharp.Interop/Extensions/CXType.cs index 2b3106fc..a25e881f 100644 --- a/sources/ClangSharp.Interop/Extensions/CXType.cs +++ b/sources/ClangSharp.Interop/Extensions/CXType.cs @@ -65,6 +65,8 @@ public unsafe partial struct CXType : IEquatable public readonly bool IsFunctionTypeVariadic => clang.isFunctionTypeVariadic(this) != 0; + public readonly bool IsObjCInstanceType => (kind != CXType_Invalid) && clangsharp.Type_getIsObjCInstanceType(this) != 0; + public readonly bool IsPODType => clang.isPODType(this) != 0; public readonly bool IsRestrictQualified => clang.isRestrictQualifiedType(this) != 0; diff --git a/sources/ClangSharp.Interop/clangsharp/clangsharp.cs b/sources/ClangSharp.Interop/clangsharp/clangsharp.cs index cb0ea241..7af26355 100644 --- a/sources/ClangSharp.Interop/clangsharp/clangsharp.cs +++ b/sources/ClangSharp.Interop/clangsharp/clangsharp.cs @@ -1016,6 +1016,10 @@ public static partial class @clangsharp [DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Type_getInjectedTST", ExactSpelling = true)] public static extern CXType Type_getInjectedTST(CXType CT); + [DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Type_getIsObjCInstanceType", ExactSpelling = true)] + [return: NativeTypeName("unsigned int")] + public static extern uint Type_getIsObjCInstanceType(CXType CT); + [DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Type_getIsSigned", ExactSpelling = true)] [return: NativeTypeName("unsigned int")] public static extern uint Type_getIsSigned(CXType CT); diff --git a/sources/ClangSharp/Types/Type.cs b/sources/ClangSharp/Types/Type.cs index 1f3a280b..df2f5973 100644 --- a/sources/ClangSharp/Types/Type.cs +++ b/sources/ClangSharp/Types/Type.cs @@ -95,6 +95,8 @@ public bool IsIntegralOrEnumerationType public bool IsLocalConstQualified => Handle.IsConstQualified; + public bool IsObjCInstanceType => Handle.IsObjCInstanceType; + public bool IsObjCObjectPointerType => CanonicalType is ObjCObjectPointerType; public bool IsPointerType => CanonicalType is PointerType; diff --git a/sources/libClangSharp/ClangSharp.cpp b/sources/libClangSharp/ClangSharp.cpp index 1338c0e1..d26962b5 100644 --- a/sources/libClangSharp/ClangSharp.cpp +++ b/sources/libClangSharp/ClangSharp.cpp @@ -5291,6 +5291,13 @@ CXType clangsharp_Type_getInjectedTST(CXType CT) { return MakeCXType(QualType(), GetTypeTU(CT)); } +unsigned clangsharp_Type_getIsObjCInstanceType(CXType CT) { + QualType T = GetQualType(CT); + CXTranslationUnit tu = GetTypeTU(CT); + ASTContext& ctx = getASTUnit(tu)->getASTContext(); + return ctx.getObjCInstanceType() == T; +} + unsigned clangsharp_Type_getIsSigned(CXType CT) { QualType T = GetQualType(CT); const Type* TP = T.getTypePtrOrNull(); diff --git a/sources/libClangSharp/ClangSharp.h b/sources/libClangSharp/ClangSharp.h index c8a609c7..1d1b66a3 100644 --- a/sources/libClangSharp/ClangSharp.h +++ b/sources/libClangSharp/ClangSharp.h @@ -833,6 +833,8 @@ CLANGSHARP_LINKAGE CXType clangsharp_Type_getInjectedSpecializationType(CXType C CLANGSHARP_LINKAGE CXType clangsharp_Type_getInjectedTST(CXType CT); +CLANGSHARP_LINKAGE unsigned clangsharp_Type_getIsObjCInstanceType(CXType CT); + CLANGSHARP_LINKAGE unsigned clangsharp_Type_getIsSigned(CXType CT); CLANGSHARP_LINKAGE unsigned clangsharp_Type_getIsSugared(CXType CT); diff --git a/tests/ClangSharp.UnitTests/ObjectiveCTest.cs b/tests/ClangSharp.UnitTests/ObjectiveCTest.cs index 7588ba0c..cc2b8613 100644 --- a/tests/ClangSharp.UnitTests/ObjectiveCTest.cs +++ b/tests/ClangSharp.UnitTests/ObjectiveCTest.cs @@ -10,6 +10,34 @@ namespace ClangSharp.UnitTests; [Platform("macosx")] public sealed class ObjectiveCTest : TranslationUnitTest { + [Test] + public void Type_IsObjCInstanceType() + { + AssertNeedNewClangSharp(); + + var inputContents = $@" +@interface MyClass + -(instancetype) instanceMethod; + +(MyClass*) staticMethod; +@end +"; + + using var translationUnit = CreateTranslationUnit(inputContents, "objective-c++"); + + var classes = translationUnit.TranslationUnitDecl.Decls.OfType().ToList(); + Assert.That(classes.Count, Is.GreaterThanOrEqualTo(1), $"At least one class"); + var myClass = classes.SingleOrDefault(v => v.Name == "MyClass")!; + Assert.That(myClass, Is.Not.Null, "MyClass"); + + var methodInstanceMethod = myClass.Methods.SingleOrDefault(v => v.Name == "instanceMethod")!; + Assert.That(methodInstanceMethod, Is.Not.Null, "methodInstanceMethod"); + Assert.That(methodInstanceMethod.ReturnType.IsObjCInstanceType, Is.True, "methodInstanceMethod.ReturnType.IsObjCInstanceType"); + + var methodStaticMethod = myClass.Methods.SingleOrDefault(v => v.Name == "staticMethod")!; + Assert.That(methodStaticMethod, Is.Not.Null, "methodStaticMethod"); + Assert.That(methodStaticMethod.ReturnType.IsObjCInstanceType, Is.False, "methodStaticMethod.ReturnType.IsObjCInstanceType"); + } + [Test] public void Method_Selector() {