diff --git a/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt b/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt index 99b2100cdc4..bd4f5cfeef0 100644 --- a/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt +++ b/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt @@ -276,7 +276,7 @@ internal class NativeIndexImpl(val library: NativeLibrary, val verbose: Boolean val name = clang_getCursorSpelling(childCursor).convertAndDispose() val value = clang_getEnumConstantDeclValue(childCursor) - val constant = EnumConstant(name, value, isExplicitlyDefined = !childCursor.isLeaf()) + val constant = EnumConstant(name, value, isExplicitlyDefined = childCursor.hasExpressionChild()) enumDef.constants.add(constant) } diff --git a/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt b/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt index ff912da3d88..3fb0dd97ec0 100644 --- a/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt +++ b/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt @@ -201,15 +201,19 @@ fun StructDef.fieldsHaveDefaultAlignment(): Boolean { return true } -internal fun CValue.isLeaf(): Boolean { - var hasChildren = false +internal fun CValue.hasExpressionChild(): Boolean { + var result = false - visitChildren(this) { _, _ -> - hasChildren = true - CXChildVisitResult.CXChildVisit_Break + visitChildren(this) { cursor, _ -> + if (clang_isExpression(cursor.kind) != 0) { + result = true + CXChildVisitResult.CXChildVisit_Break + } else { + CXChildVisitResult.CXChildVisit_Continue + } } - return !hasChildren + return result } internal fun List.toNativeStringArray(scope: AutofreeScope): CArrayPointer> { diff --git a/backend.native/tests/interop/basics/ctypes.def b/backend.native/tests/interop/basics/ctypes.def index 3b6cf0bee37..a0a11ca243d 100644 --- a/backend.native/tests/interop/basics/ctypes.def +++ b/backend.native/tests/interop/basics/ctypes.def @@ -48,4 +48,25 @@ static int vlaSum2DBothDimensions(int rows, int columns, int array[rows][columns static int vlaSum2DForward(int size; int array[][size], int size) { return vlaSum2D(size, array); } -*/ \ No newline at end of file +*/ + +// "Strict" enums heuristic based on whether enum constants are defined explicitly: +enum StrictEnum1 { + StrictEnum1A, + StrictEnum1B +}; + +enum StrictEnum2 { + StrictEnum2A __attribute__((unused)), + StrictEnum2B __attribute__((unused)) +}; + +enum NonStrictEnum1 { + NonStrictEnum1A = 0, + NonStrictEnum1B __attribute__((unused)) +}; + +enum NonStrictEnum2 { + NonStrictEnum2A, + NonStrictEnum2B __attribute__((unused)) = 1 +}; \ No newline at end of file diff --git a/backend.native/tests/interop/basics/types.kt b/backend.native/tests/interop/basics/types.kt index 599afdf9dae..17888e3dd07 100644 --- a/backend.native/tests/interop/basics/types.kt +++ b/backend.native/tests/interop/basics/types.kt @@ -16,4 +16,9 @@ fun main() { // Not supported by clang: // assertEquals(10, vlaSum2DForward(cValuesOf(1, 2, 3, 4), 2)) + + assertEquals(0u, StrictEnum1.StrictEnum1A.value) + assertEquals(1u, StrictEnum2.StrictEnum2B.value) + assertEquals(0u, NonStrictEnum1A) + assertEquals(1u, NonStrictEnum2B) } \ No newline at end of file