extract nullability from attributed types
diff --git a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt
index 8838c1f..f402bfb 100644
--- a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt
+++ b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt
@@ -656,7 +656,22 @@
         else -> UnsupportedType
     }
 
-    open fun convertType(type: CValue<CXType>, typeAttributes: CValue<CXTypeAttributes>? = null): Type {
+    private fun getTypeAttributes(attributedType: CValue<CXType>, attributes: TypeAttributes?): TypeAttributes {
+        check(attributedType.kind == CXType_Attributed) { attributedType.kind }
+        val objCNullability = when (clang_Type_getNullability(attributedType)) {
+            CXTypeNullability_Nullable -> ObjCPointer.Nullability.Nullable
+            CXTypeNullability_NonNull -> ObjCPointer.Nullability.NonNull
+            else -> ObjCPointer.Nullability.Unspecified
+        }
+        if (objCNullability == ObjCPointer.Nullability.Unspecified && attributes != null) {
+            // FIXME: unspecified is not the same as absent.
+            return attributes
+        }
+
+        return TypeAttributes(objCNullability = objCNullability)
+    }
+
+    open fun convertType(type: CValue<CXType>, typeAttributes: CValue<CXTypeAttributes>? = null, attributes: TypeAttributes? = null): Type {
         val primitiveType = convertUnqualifiedPrimitiveType(type)
         if (primitiveType != UnsupportedType) {
             return primitiveType
@@ -683,7 +698,7 @@
             }
 
             CXType_Attributed -> {
-                convertType(clang_Type_getModifiedType(type), typeAttributes)
+                convertType(clang_Type_getModifiedType(type), typeAttributes, getTypeAttributes(type, attributes))
             }
 
             CXType_Void -> VoidType
@@ -694,7 +709,7 @@
                 val underlying = convertType(clang_getTypedefDeclUnderlyingType(declCursor))
                 when {
                     declSpelling == "instancetype" && underlying is ObjCPointer ->
-                        ObjCInstanceType(getNullability(type, typeAttributes))
+                        ObjCInstanceType(getNullability(type, typeAttributes, attributes))
 
                     else -> getTypedef(type)
                 }
@@ -741,7 +756,7 @@
             CXType_ObjCObjectPointer -> objCType {
                 val declaration = clang_getTypeDeclaration(clang_getPointeeType(type))
                 val declarationKind = declaration.kind
-                val nullability = getNullability(type, typeAttributes)
+                val nullability = getNullability(type, typeAttributes, attributes)
                 when (declarationKind) {
                     CXCursorKind.CXCursor_NoDeclFound -> ObjCIdType(nullability, getProtocols(type))
 
@@ -762,13 +777,13 @@
                 }
             }
 
-            CXType_ObjCId -> objCType { ObjCIdType(getNullability(type, typeAttributes), getProtocols(type)) }
+            CXType_ObjCId -> objCType { ObjCIdType(getNullability(type, typeAttributes, attributes), getProtocols(type)) }
 
-            CXType_ObjCClass -> objCType { ObjCClassPointer(getNullability(type, typeAttributes), getProtocols(type)) }
+            CXType_ObjCClass -> objCType { ObjCClassPointer(getNullability(type, typeAttributes, attributes), getProtocols(type)) }
 
             CXType_ObjCSel -> PointerType(VoidType)
 
-            CXType_BlockPointer -> objCType { convertBlockPointerType(type, typeAttributes) }
+            CXType_BlockPointer -> objCType { convertBlockPointerType(type, typeAttributes, attributes) }
 
             else -> UnsupportedType
         }
@@ -791,16 +806,23 @@
     }
 
     private fun getNullability(
-            type: CValue<CXType>, typeAttributes: CValue<CXTypeAttributes>?
+            type: CValue<CXType>, typeAttributes: CValue<CXTypeAttributes>?, attributes: TypeAttributes?
     ): ObjCPointer.Nullability {
 
         if (typeAttributes == null) return ObjCPointer.Nullability.Unspecified
+        if (attributes == null) return ObjCPointer.Nullability.Unspecified
 
-        return when (clang_Type_getNullabilityKind(type, typeAttributes)) {
+        val oldNullability = when (clang_Type_getNullabilityKind(type, typeAttributes)) {
             CXNullabilityKind.CXNullabilityKind_Nullable -> ObjCPointer.Nullability.Nullable
             CXNullabilityKind.CXNullabilityKind_NonNull -> ObjCPointer.Nullability.NonNull
             CXNullabilityKind.CXNullabilityKind_Unspecified -> ObjCPointer.Nullability.Unspecified
         }
+
+        return attributes.objCNullability.also {
+            check(it == oldNullability) {
+                "Nullability mismatch: $oldNullability expected but $it found for type ${clang_getTypeSpelling(type).convertAndDispose()}"
+            }
+        }
     }
 
     private fun getProtocols(type: CValue<CXType>): List<ObjCProtocol> {
@@ -850,12 +872,12 @@
         }
     }
 
-    private fun convertBlockPointerType(type: CValue<CXType>, typeAttributes: CValue<CXTypeAttributes>?): ObjCPointer {
+    private fun convertBlockPointerType(type: CValue<CXType>, typeAttributes: CValue<CXTypeAttributes>?, attributes: TypeAttributes?): ObjCPointer {
         val kind = type.kind
         assert(kind == CXType_BlockPointer)
 
         val pointee = clang_getPointeeType(type)
-        val nullability = getNullability(type, typeAttributes)
+        val nullability = getNullability(type, typeAttributes, attributes)
 
         // TODO: also use nullability attributes of parameters and return value.
 
diff --git a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/NativeIndex.kt b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/NativeIndex.kt
index 39c4097..2409e2c 100644
--- a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/NativeIndex.kt
+++ b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/NativeIndex.kt
@@ -351,6 +351,8 @@
     val fullName: String get() = parentName?.let { "$it::$name" } ?: name
 }
 
+class TypeAttributes(val objCNullability: ObjCPointer.Nullability)
+
 /**
  * C type.
  */