1 /*
  2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 import jdk.incubator.foreign.Addressable;
 25 import jdk.incubator.foreign.CLinker;
 26 import org.testng.annotations.Test;
 27 
 28 import java.nio.file.Path;
 29 import jdk.incubator.foreign.GroupLayout;
 30 import jdk.incubator.foreign.MemoryLayout;
 31 import jdk.incubator.foreign.MemorySegment;
 32 import static org.testng.Assert.assertNotNull;
 33 import static org.testng.Assert.assertTrue;
 34 
 35 /*
 36  * @test
 37  * @bug 8240300
 38  * @summary jextract produces non compilable code with repeated declarations
 39  * @modules jdk.incubator.jextract
 40  * @library /test/lib
 41  * @build JextractToolRunner
 42  * @run testng/othervm --enable-native-access=jdk.incubator.jextract,ALL-UNNAMED RepeatedDeclsTest
 43  */
 44 public class RepeatedDeclsTest extends JextractToolRunner {
 45     @Test
 46     public void repeatedDecls() throws Throwable {
 47         Path repeatedDeclsOutput = getOutputFilePath("repeatedDeclsgen");
 48         Path repeatedDeclsH = getInputFilePath("repeatedDecls.h");
 49         run("-d", repeatedDeclsOutput.toString(), repeatedDeclsH.toString()).checkSuccess();
 50         try(Loader loader = classLoader(repeatedDeclsOutput)) {
 51             Class<?> cls = loader.loadClass("repeatedDecls_h");
 52             // check a method for "void func(int)"
 53             assertNotNull(findMethod(cls, "func", int.class));
 54 
 55             // check a method for "void func2(int)"
 56             assertNotNull(findMethod(cls, "func2", int.class));
 57 
 58             // check a method for "void func3(int*)"
 59             assertNotNull(findMethod(cls, "func3", Addressable.class));
 60 
 61             // check a method for "void func4(int*)"
 62             assertNotNull(findMethod(cls, "func4", Addressable.class));
 63 
 64             // check a method for "void func5(int)"
 65             assertNotNull(findMethod(cls, "func5", int.class));
 66 
 67             // check a method for "double distance(struct Point)"
 68             assertNotNull(findMethod(cls, "distance", MemorySegment.class));
 69 
 70             // check a getter method for "i"
 71             assertNotNull(findMethod(cls, "i$get"));
 72 
 73             // check a setter method for "i"
 74             assertNotNull(findMethod(cls, "i$set", int.class));
 75 
 76             // make sure that enum constants are generated fine
 77             checkIntGetter(cls, "R", 0);
 78             checkIntGetter(cls, "G", 1);
 79             checkIntGetter(cls, "B", 2);
 80             checkIntGetter(cls, "C", 0);
 81             checkIntGetter(cls, "M", 1);
 82             checkIntGetter(cls, "Y", 2);
 83 
 84             // check Point layout
 85             Class<?> pointCls = loader.loadClass("Point");
 86             checkPoint(pointCls);
 87             Class<?> point_tCls = loader.loadClass("Point_t");
 88             checkPoint(point_tCls);
 89             assertTrue(pointCls.isAssignableFrom(point_tCls));
 90             Class<?> point$0Cls = loader.loadClass("POINT$0");
 91             checkPoint(point$0Cls);
 92             assertTrue(pointCls.isAssignableFrom(point$0Cls));
 93 
 94             // check Point3D layout
 95             Class<?> point3DCls = loader.loadClass("Point3D");
 96             checkPoint3D(point3DCls);
 97             Class<?> point3D_tCls = loader.loadClass("Point3D_t");
 98             checkPoint3D(point3D_tCls);
 99             assertTrue(point3DCls.isAssignableFrom(point3D_tCls));
100         } finally {
101             deleteDir(repeatedDeclsOutput);
102         }
103     }
104 
105     private void checkPoint(Class<?> pointCls) {
106         MemoryLayout pointLayout = findLayout(pointCls);
107         assertNotNull(pointLayout);
108         assertTrue(((GroupLayout)pointLayout).isStruct());
109         checkField(pointLayout, "i", C_INT);
110         checkField(pointLayout, "j", C_INT);
111     }
112 
113     private void checkPoint3D(Class<?> point3DCls) {
114         MemoryLayout point3DLayout = findLayout(point3DCls);
115         assertNotNull(point3DLayout);
116         assertTrue(((GroupLayout)point3DLayout).isStruct());
117         checkField(point3DLayout, "i", C_INT);
118         checkField(point3DLayout, "j", C_INT);
119         checkField(point3DLayout, "k", C_INT);
120     }
121 }