--- old/src/jdk.jextract/share/classes/com/sun/tools/jextract/AsmCodeFactory.java 2018-03-28 22:48:08.000000000 +0530 +++ new/src/jdk.jextract/share/classes/com/sun/tools/jextract/AsmCodeFactory.java 2018-03-28 22:48:08.000000000 +0530 @@ -222,7 +222,7 @@ // fields Printer dbg = new Printer(); - cursor.stream() + cursor.children() .filter(cx -> cx.kind() == CursorKind.FieldDecl) .forEachOrdered(cx -> addField(cw, cx, cursor.type())); // Write class @@ -535,13 +535,13 @@ break; default: logger.warning(() -> "Unsupported declaration Cursor:"); - logger.fine(() -> Printer.Stringifier(p -> p.dumpCursor(cursor, true))); + logger.warning(() -> Printer.Stringifier(p -> p.dumpCursor(cursor, true))); break; } } catch (Exception ex) { handleException(ex); logger.warning("Cursor causing above exception is: " + cursor.spelling()); - logger.fine(() -> Printer.Stringifier(p -> p.dumpCursor(cursor, true))); + logger.warning(() -> Printer.Stringifier(p -> p.dumpCursor(cursor, true))); } return this; } --- old/src/jdk.jextract/share/classes/com/sun/tools/jextract/HeaderFile.java 2018-03-28 22:48:10.000000000 +0530 +++ new/src/jdk.jextract/share/classes/com/sun/tools/jextract/HeaderFile.java 2018-03-28 22:48:09.000000000 +0530 @@ -112,6 +112,20 @@ ctx.err.println(Main.format("warn.symbol.not.found", name)); } } + + // C structs and unions can have nested structs, unions and enums. + if (c.kind() == CursorKind.StructDecl || + c.kind() == CursorKind.UnionDecl) { + c.children() + .filter(c1 -> c1.isDeclaration() && + (c1.kind() == CursorKind.StructDecl || + c1.kind() == CursorKind.UnionDecl || + c1.kind() == CursorKind.EnumDecl)) + .peek(c1 -> logger.finest( + () -> "Cursor: " + c1.spelling() + "@" + c1.USR() + "?" + c1.isDeclaration())) + .forEach(c1 -> processCursor(c1, main, isBuiltIn)); + } + JType jt = dict.computeIfAbsent(t, type -> { logger.fine(() -> "PH: Compute type for " + type.spelling()); return define(type); --- old/test/jdk/com/sun/tools/jextract/JextractToolProviderTest.java 2018-03-28 22:48:11.000000000 +0530 +++ new/test/jdk/com/sun/tools/jextract/JextractToolProviderTest.java 2018-03-28 22:48:11.000000000 +0530 @@ -429,4 +429,41 @@ deleteFile(helloJar); } } + + @Test + public void testNestedStructsUnions() { + Path nestedJar = getOutputFilePath("nested.jar"); + deleteFile(nestedJar); + Path nestedH = getInputFilePath("nested.h"); + try { + checkSuccess(null, "-o", nestedJar.toString(), nestedH.toString()); + assertNotNull(loadClass("nested", nestedJar)); + Class fooCls = loadClass("nested$Foo", nestedJar); + assertNotNull(fooCls); + // struct Foo has no getters for "x", "y" etc. + assertNull(findMethod(fooCls, "x$get")); + assertNull(findMethod(fooCls, "y$get")); + // struct Foo has getters for bar and color + assertNotNull(findMethod(fooCls, "bar$get")); + assertNotNull(findMethod(fooCls, "color$get")); + // make sure nested types are handled without nested namespace! + assertNotNull(loadClass("nested$Bar", nestedJar)); + assertNotNull(loadClass("nested$Color", nestedJar)); + + Class uCls = loadClass("nested$U", nestedJar); + assertNotNull(uCls); + // union U has no getters for "x", "y" etc. + assertNull(findMethod(uCls, "x$get")); + assertNull(findMethod(uCls, "y$get")); + // union U has getters for point, rgb, i + assertNotNull(findMethod(uCls, "point$get")); + assertNotNull(findMethod(uCls, "rgb$get")); + assertNotNull(findMethod(uCls, "i$get")); + // make sure nested types are handled without nested namespace! + assertNotNull(loadClass("nested$Point", nestedJar)); + assertNotNull(loadClass("nested$RGB", nestedJar)); + } finally { + deleteFile(nestedJar); + } + } } --- old/test/jdk/com/sun/tools/jextract/uniondecl.h 2018-03-28 22:48:12.000000000 +0530 +++ new/test/jdk/com/sun/tools/jextract/uniondecl.h 2018-03-28 22:48:12.000000000 +0530 @@ -1,5 +1,4 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * --- /dev/null 2018-03-28 22:48:14.000000000 +0530 +++ new/test/jdk/com/sun/tools/jextract/nested.h 2018-03-28 22:48:13.000000000 +0530 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +struct Foo { + struct Bar { + int x, y; + } bar; + + enum Color { + red, green, blue + } color; +}; + +union U { + struct Point { + short x, y; + } point; + + enum RGB { + r, g, b + } rgb; + + int i; +};