changeset 58896:c988fcd00fc0 foreign

8221838: jextract generates non-existent type reference for typedef on typedef Reviewed-by: mcimadamore
author sundar
date Wed, 03 Apr 2019 16:06:00 +0530
parents 83254f963efc
children 9dce1cda7e5a 598c7de32482 39cc1b0e0f2d
files src/jdk.jextract/share/classes/com/sun/tools/jextract/TypedefHandler.java test/jdk/com/sun/tools/jextract/test8221838/StructTypedefsTest.java test/jdk/com/sun/tools/jextract/test8221838/libStructtypedefs.c test/jdk/com/sun/tools/jextract/test8221838/structtypedefs.h
diffstat 4 files changed, 134 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.jextract/share/classes/com/sun/tools/jextract/TypedefHandler.java	Thu Mar 28 17:47:10 2019 +0530
+++ b/src/jdk.jextract/share/classes/com/sun/tools/jextract/TypedefHandler.java	Wed Apr 03 16:06:00 2019 +0530
@@ -32,7 +32,6 @@
 import java.util.Optional;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.util.stream.Collectors;
 import com.sun.tools.jextract.parser.Parser;
 import com.sun.tools.jextract.tree.HeaderTree;
 import com.sun.tools.jextract.tree.SimpleTreeVisitor;
@@ -60,8 +59,8 @@
     private List<Tree> decls = new ArrayList<>();
 
     // Tree instances that are to be replaced from "decls" list are
-    // saved in the following Map.
-    private final Map<Cursor, Tree> replacements = new HashMap<>();
+    // saved in the following Map. One or more Trees can replace a Tree.
+    private final Map<Cursor, List<Tree>> replacements = new HashMap<>();
 
     private final Log log;
 
@@ -79,13 +78,14 @@
         // Replace trees from this.decls with Trees found in this.replacements.
         // We need this two step process so that named StructTree instances
         // will replace with original unnamed StructTree instances.
-        List<Tree> newDecls = decls.stream().map(tx -> {
+        List<Tree> newDecls = new ArrayList<>();
+        decls.stream().forEach(tx -> {
             if (replacements.containsKey(tx.cursor())) {
-                return replacements.get(tx.cursor());
+                newDecls.addAll(replacements.get(tx.cursor()));
             } else {
-                return tx;
+                newDecls.add(tx);
             }
-        }).collect(Collectors.toList());
+        });
 
         return treeMaker.createHeader(ht.cursor(), ht.path(), newDecls);
     }
@@ -115,7 +115,19 @@
                  * and second one for typedef decl. We map it as a single named struct
                  * declaration.
                  */
-                replacements.put(defTree.cursor(), ((StructTree)defTree).withName(tt.name()));
+                Cursor dc = defTree.cursor();
+
+                /*
+                 * There may be more than one typedef on underlying anonymous struct/union.
+                 * Example:
+                 *
+                 * typedef struct { int x; int y; } Point;
+                 * typedef Point Vector;
+                 */
+                List<Tree> trees = replacements.containsKey(dc)?
+                    replacements.get(defTree.cursor()) : new ArrayList<>();
+                trees.add(((StructTree)defTree).withName(tt.name()));
+                replacements.put(dc, trees);
                 log.print(Level.FINE, () -> "Typedef " + defTree.type().spelling() + " as " + tt.name());
                 return null;
             } else if (defTree.name().equals(tt.name())) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/tools/jextract/test8221838/StructTypedefsTest.java	Wed Apr 03 16:06:00 2019 +0530
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+
+import java.foreign.memory.Pointer;
+import org.testng.annotations.Test;
+import static test8221838.structtypedefs_h.*;
+
+/*
+ * @test
+ * @bug 8221838
+ * @summary jextract generates non-existent type reference for typedef on typedef
+ * @library ..
+ * @run driver JtregJextract -t test8221838 -l structtypedefs -- structtypedefs.h
+ * @run testng StructTypedefsTest
+ */
+public class StructTypedefsTest {
+    @Test
+    public void test() {
+        norm(Pointer.ofNull());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/tools/jextract/test8221838/libStructtypedefs.c	Wed Apr 03 16:06:00 2019 +0530
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+
+#include "structtypedefs.h"
+
+int norm(Vector* v) {
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/tools/jextract/test8221838/structtypedefs.h	Wed Apr 03 16:06:00 2019 +0530
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#ifdef _WIN64
+#define EXPORT __declspec(dllexport)
+#else
+#define EXPORT
+#endif
+
+typedef struct {
+    int x;
+    int y;
+} Point;
+
+typedef Point Vector;
+
+EXPORT int norm(Vector* v);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus