diff --git a/src/jdk.incubator.jextract/share/classes/jdk/incubator/jextract/Declaration.java b/src/jdk.incubator.jextract/share/classes/jdk/incubator/jextract/Declaration.java index 842f9ded9af..1e0cd5ea6fa 100644 --- a/src/jdk.incubator.jextract/share/classes/jdk/incubator/jextract/Declaration.java +++ b/src/jdk.incubator.jextract/share/classes/jdk/incubator/jextract/Declaration.java @@ -164,10 +164,6 @@ * Bitfields declaration. */ BITFIELDS, - /** - * Type definition declaration. - */ - TYPEDEF, /** * Toplevel declaration. */ @@ -197,6 +193,17 @@ Kind kind(); } + /** + * A typedef declaration + */ + interface Typedef extends Declaration { + /** + * The canonical type associated with this typedef declaration. + * @return The canonical type associated with this typedef declaration. + */ + Type type(); + } + /** * A variable declaration. */ @@ -297,6 +304,14 @@ */ default R visitConstant(Constant d, P p) { return visitDeclaration(d, p); } + /** + * Visit a typedef declaration. + * @param d the typedef declaration. + * @param p the visitor parameter. + * @return the result of visiting the given typedef declaration through this visitor object. + */ + default R visitTypedef(Typedef d, P p) { return visitDeclaration(d, p); } + /** * Visit a declaration. * @param d the declaration. @@ -516,10 +531,10 @@ * Creates a new typedef declaration with given name and declared type. * @param pos the typedef declaration position. * @param name the typedef declaration name. - * @param decl the typedef declared type - * @return a new typedef declaration with given name and declared type. + * @param type the typedef type + * @return a new type declaration with given name and declared type. */ - static Declaration.Scoped typedef(Position pos, String name, Declaration decl) { - return new DeclarationImpl.ScopedImpl(Scoped.Kind.TYPEDEF, List.of(decl), name, pos); + static Declaration.Typedef typedef(Position pos, String name, Type type) { + return new DeclarationImpl.TypedefImpl(type, name, pos, null); } } diff --git a/src/jdk.incubator.jextract/share/classes/jdk/incubator/jextract/tool/OutputFactory.java b/src/jdk.incubator.jextract/share/classes/jdk/incubator/jextract/tool/OutputFactory.java index e5853a7ecaa..a5aa26dce06 100644 --- a/src/jdk.incubator.jextract/share/classes/jdk/incubator/jextract/tool/OutputFactory.java +++ b/src/jdk.incubator.jextract/share/classes/jdk/incubator/jextract/tool/OutputFactory.java @@ -217,9 +217,6 @@ public Void visitConstant(Declaration.Constant constant, Declaration parent) { @Override public Void visitScoped(Declaration.Scoped d, Declaration parent) { - if (d.kind() == Declaration.Scoped.Kind.TYPEDEF) { - return d.members().get(0).accept(this, d); - } if (d.layout().isEmpty()) { //skip decl-only return null; @@ -307,6 +304,20 @@ public Void visitFunction(Declaration.Function funcTree, Declaration parent) { } } + @Override + public Void visitTypedef(Declaration.Typedef tree, Declaration parent) { + Type type = tree.type(); + if (type instanceof Type.Declared) { + Declaration.Scoped s = ((Type.Declared) type).tree(); + // only generate unnamed for now + // skip typedef with different name + if (s.name().isEmpty()) { + return visitScoped(s, tree); + } + } + return null; + } + @Override public Void visitVariable(Declaration.Variable tree, Declaration parent) { if (parent == null && variableSeen(tree)) { @@ -339,8 +350,7 @@ public Void visitVariable(Declaration.Variable tree, Declaration parent) { MemoryLayout treeLayout = tree.layout().orElseThrow(); if (parent != null) { //struct field - Declaration.Scoped parentC = (Declaration.Scoped) parent; - MemoryLayout parentLayout = parentLayout(parentC); + MemoryLayout parentLayout = parentLayout(parent); structBuilder.addVarHandleGetter(fieldName, tree.name(), treeLayout, clazz, parentLayout); structBuilder.addGetter(fieldName, tree.name(), treeLayout, clazz, parentLayout); structBuilder.addSetter(fieldName, tree.name(), treeLayout, clazz, parentLayout); @@ -368,10 +378,15 @@ private boolean isRecord(Declaration declaration) { } } - protected static MemoryLayout parentLayout(Declaration.Scoped parent) { + protected static MemoryLayout parentLayout(Declaration parent) { + if (parent instanceof Declaration.Typedef) { + Declaration.Typedef alias = (Declaration.Typedef) parent; + return Type.layoutFor(alias.type()).orElseThrow(); + } else if (parent instanceof Declaration.Scoped) { + return ((Declaration.Scoped) parent).layout().orElseThrow(); + } else { + throw new IllegalArgumentException("Unexpected parent declaration"); + } // case like `typedef struct { ... } Foo` - return (parent.kind() == Declaration.Scoped.Kind.TYPEDEF - ? (Declaration.Scoped) parent.members().get(0) - : parent).layout().orElseThrow(); } } diff --git a/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/DeclarationImpl.java b/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/DeclarationImpl.java index 58016e45baa..ff629ffbf87 100644 --- a/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/DeclarationImpl.java +++ b/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/DeclarationImpl.java @@ -99,6 +99,50 @@ public int hashCode() { return Objects.hash(name); } + public static final class TypedefImpl extends DeclarationImpl implements Declaration.Typedef { + final Type type; + + public TypedefImpl(Type type, String name, Position pos, Map> attrs) { + super(name, pos, attrs); + this.type = Objects.requireNonNull(type); + } + + @Override + public R accept(Visitor visitor, D data) { + return visitor.visitTypedef(this, data); + } + + @Override + public Type type() { + return type; + } + + @Override + public Typedef withAttributes(Map> attrs) { + return new TypedefImpl(type, name(), pos(), attrs); + } + + @Override + public Typedef stripAttributes() { + return new TypedefImpl(type, name(), pos(), null); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Declaration.Typedef)) return false; + + Declaration.Typedef other = (Declaration.Typedef) o; + return name().equals(other.name()) && + type.equals(other.type()); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), type); + } + } + public static final class VariableImpl extends DeclarationImpl implements Declaration.Variable { final Variable.Kind kind; @@ -154,8 +198,9 @@ public Variable stripAttributes() { public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Declaration.Variable)) return false; - if (!super.equals(o)) return false; + Declaration.Variable variable = (Declaration.Variable) o; + if (!super.equals(o)) return false; return kind == variable.kind() && type.equals(variable.type()); } diff --git a/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/PrettyPrinter.java b/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/PrettyPrinter.java index 070df770dbc..719e305efef 100644 --- a/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/PrettyPrinter.java +++ b/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/PrettyPrinter.java @@ -49,7 +49,7 @@ void decr() { void indent() { builder.append(" ".substring(0, align)); } - + StringBuilder builder = new StringBuilder(); private void getAttributes(Declaration decl) { @@ -118,6 +118,15 @@ public Void visitConstant(Declaration.Constant d, Void aVoid) { return null; } + @Override + public Void visitTypedef(Declaration.Typedef d, Void aVoid) { + indent(); + builder.append("Typedef: ").append(d.name()).append(" = ") + .append(d.type().accept(typeVisitor, null)).append("\n"); + getAttributes(d); + return null; + } + private static Type.Visitor typeVisitor = new Type.Visitor<>() { @Override public String visitPrimitive(Type.Primitive t, Void aVoid) { diff --git a/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/TreeMaker.java b/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/TreeMaker.java index 4d308f7bfbe..2c7f1107433 100644 --- a/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/TreeMaker.java +++ b/src/jdk.incubator.jextract/share/classes/jdk/internal/jextract/impl/TreeMaker.java @@ -250,15 +250,17 @@ private static boolean isEnum(Declaration d) { .collect(Collectors.toList()); } - private Declaration.Scoped createTypedef(Cursor c) { - Optional decl = c.children().findFirst(); - if (decl.isPresent() && decl.get().isDefinition() && decl.get().spelling().isEmpty()) { - Declaration def = createTree(decl.get()); - if (def instanceof Declaration.Scoped) { - return Declaration.typedef(toPos(c), c.spelling(), def); + private Declaration.Typedef createTypedef(Cursor c) { + Type.Delegated typedef = (Type.Delegated) toType(c); + Type canonicalType = typedef.type(); + if (canonicalType instanceof Type.Declared) { + Declaration.Scoped s = ((Type.Declared) canonicalType).tree(); + if (s.name().equals(c.spelling())) { + // typedef record with the same name, no need to present twice + return null; } } - return null; + return Declaration.typedef(toPos(c), c.spelling(), canonicalType); } private Declaration.Variable createVar(Declaration.Variable.Kind kind, Cursor c, VarFactoryNoLayout varFactory) { diff --git a/test/jdk/java/jextract/JextractApiTestBase.java b/test/jdk/java/jextract/JextractApiTestBase.java index e0e93d4788d..aade53924c5 100644 --- a/test/jdk/java/jextract/JextractApiTestBase.java +++ b/test/jdk/java/jextract/JextractApiTestBase.java @@ -23,8 +23,11 @@ import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import java.util.function.Predicate; + import jdk.incubator.jextract.Declaration; import jdk.incubator.jextract.JextractTask; import jdk.incubator.jextract.Type; @@ -46,13 +49,44 @@ return task.parse(parseOptions); } + public static void checkNames(List members, String... fields) { + assertEquals(members.size(), fields.length); + for (int i = 0; i < fields.length; i++) { + assertEquals(members.get(i).name(), fields[i]); + } + } + public static Declaration.Scoped checkScoped(Declaration.Scoped toplevel, String name, Declaration.Scoped.Kind kind, String... fields) { Declaration.Scoped scoped = findDecl(toplevel, name, Declaration.Scoped.class); - assertEquals(scoped.members().size(), fields.length); assertTrue(scoped.kind() == kind); - for (int i = 0; i < fields.length; i++) { - assertEquals(scoped.members().get(i).name(), fields[i]); - } + checkNames(scoped.members(), fields); + return scoped; + } + + private static List getNamedFields(Declaration.Scoped scoped) { + List fields = new ArrayList<>(); + scoped.members().forEach(d -> { + if (d instanceof Declaration.Variable) { + Declaration.Variable v = (Declaration.Variable) d; + if (v.kind() == Declaration.Variable.Kind.FIELD) { + assert (!v.name().isEmpty()); + fields.add(v); + } + } else if (d instanceof Declaration.Scoped) { + Declaration.Scoped record = (Declaration.Scoped) d; + if (record.name().isEmpty()) { + fields.addAll(getNamedFields(record)); + } else { + fields.add(record); + } + } + }); + return fields; + } + + public static Declaration.Scoped checkRecord(Declaration.Scoped scoped, String name, Declaration.Scoped.Kind kind, String... fields) { + assertTrue(scoped.kind() == kind); + checkNames(getNamedFields(scoped), fields); return scoped; } @@ -68,26 +102,26 @@ return checkScoped(toplevel, name, Declaration.Scoped.Kind.UNION, fields); } - public static Declaration.Variable checkConstant(Declaration.Scoped scope, String name, Type type) { + public static Declaration.Variable checkVariable(Declaration.Scoped scope, String name, Type type) { Declaration.Variable var = findDecl(scope, name, Declaration.Variable.class); assertTypeEquals(type, var.type()); return var; } public static Declaration.Variable checkGlobal(Declaration.Scoped toplevel, String name, Type type) { - Declaration.Variable global = checkConstant(toplevel, name, type); + Declaration.Variable global = checkVariable(toplevel, name, type); assertEquals(global.kind(), Declaration.Variable.Kind.GLOBAL); return global; } public static Declaration.Variable checkField(Declaration.Scoped record, String name, Type type) { - Declaration.Variable global = checkConstant(record, name, type); + Declaration.Variable global = checkVariable(record, name, type); assertEquals(global.kind(), Declaration.Variable.Kind.FIELD); return global; } public static Declaration.Variable checkBitField(Declaration.Scoped record, String name, Type type, int size) { - Declaration.Variable global = checkConstant(record, name, type); + Declaration.Variable global = checkVariable(record, name, type); assertEquals(global.kind(), Declaration.Variable.Kind.BITFIELD); assertEquals(global.layout().get().bitSize(), size); return global; @@ -165,4 +199,72 @@ public static void assertTypeEquals(Type expected, Type found) { } } } + + public static Type unwrapDelegatedType(Type type, Type.Delegated.Kind kind) { + assertTrue(type instanceof Type.Delegated, + "Expecting Type.Delegated, got " + type.getClass()); + Type.Delegated delegated = (Type.Delegated) type; + assertEquals(delegated.kind(), kind); + return delegated.type(); + } + + public static Type unwrapPointerType(Type type) { + return unwrapDelegatedType(type, Type.Delegated.Kind.POINTER); + } + + public static Type unwrapTypedefType(Type type) { + return unwrapDelegatedType(type, Type.Delegated.Kind.TYPEDEF); + } + + public static Type unwrapArrayType(Type type, long size) { + assertTrue(type instanceof Type.Array, + "Expecting Type.Array, got " + type.getClass()); + Type.Array arType = (Type.Array) type; + assertEquals(arType.elementCount().getAsLong(), size); + return arType.elementType(); + } + + public static Type unwrapArrayType(Type type) { + assertTrue(type instanceof Type.Array, + "Expecting Type.Array, got " + type.getClass()); + Type.Array arType = (Type.Array) type; + assertTrue(arType.elementCount().isEmpty()); + return arType.elementType(); + } + + static class TypeUnwrapper { + private Type type; + + private TypeUnwrapper(Type type) { + this.type = type; + } + + public static TypeUnwrapper of(Type type) { + return new TypeUnwrapper(type); + } + + public TypeUnwrapper unwrapPointer() { + type = unwrapPointerType(type); + return this; + } + + public TypeUnwrapper unwrapTypedef() { + type = unwrapTypedefType(type); + return this; + } + + public TypeUnwrapper unwrapArray(long size) { + type = unwrapArrayType(type, size); + return this; + } + + public TypeUnwrapper unwrapArray() { + type = unwrapArrayType(type); + return this; + } + + public Type get() { + return type; + } + } } diff --git a/test/jdk/java/jextract/TestTypedef.java b/test/jdk/java/jextract/TestTypedef.java new file mode 100644 index 00000000000..31e1d1fea97 --- /dev/null +++ b/test/jdk/java/jextract/TestTypedef.java @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2020, 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. + */ + +/* + * @test + * @build JextractApiTestBase + * @run testng/othervm -ea TestTypedef + */ + +import java.util.Set; +import java.util.Optional; +import java.util.function.Consumer; +import jdk.incubator.jextract.Declaration; +import jdk.incubator.jextract.Type; + +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +public class TestTypedef extends JextractApiTestBase { + Declaration.Scoped root; + + @BeforeClass + public void parse() { + root = parse("testTypedef.h"); + System.out.println(root); + } + + private Declaration[] findAllWithName(Declaration.Scoped scope, String name) { + return scope.members().stream().filter(byName(name)).toArray(Declaration[]::new); + } + + public static Type getTypedefType(Declaration.Scoped scope, String name) { + Declaration.Typedef d = findDecl(scope, name, Declaration.Typedef.class); + Type type = d.type(); + // Typedef declaration should return canonical type + if (type instanceof Type.Delegated) { + assertNotEquals(((Type.Delegated) type).kind(), Type.Delegated.Kind.TYPEDEF); + } + return d.type(); + } + + private Declaration.Scoped assertDeclaredTypedef(Declaration.Typedef decl) { + Type type = decl.type(); + assertTrue(type instanceof Type.Declared, "Expecting Type.Declared, got " + type.getClass()); + return ((Type.Declared) type).tree(); + } + + private Declaration.Scoped assertAnonymousRecord(Declaration.Scoped scope, String name) { + Declaration[] ar = findAllWithName(scope, name); + assertEquals(ar.length, 1); + assertTrue(ar[0] instanceof Declaration.Typedef, "Expectint Declaration.Typedef, but got " + ar[0].getClass()); + Declaration.Scoped record = assertDeclaredTypedef((Declaration.Typedef) ar[0]); + return record; + } + + private Declaration.Scoped assertNamedRecord(Declaration.Scoped scope, String name) { + Declaration[] ar = findAllWithName(scope, name); + assertEquals(ar.length, 1); + assertTrue(ar[0] instanceof Declaration.Scoped, "Expectint Declaration.Scoped, but got " + ar[0].getClass()); + return (Declaration.Scoped) ar[0]; + } + + @Test + public void NoDuplicateSameNameTypedef() { + // When typedef a named record with the same name, present the scoped + // declaration and ignore the typedef + Declaration.Scoped s = assertNamedRecord(root, "Point3D"); + assertEquals(s.kind(), Declaration.Scoped.Kind.STRUCT); + checkNames(s.members(), "i", "j", "k"); + + s = assertNamedRecord(root, "SIZE"); + assertEquals(s.kind(), Declaration.Scoped.Kind.ENUM); + checkNames(s.members(), "XS", "S", "M", "L", "XL"); + } + + @Test + public void TypedefReferences() { + // When reference to a typedef, the Type should be Type.Delegated + // With the type to be the referenced type + Declaration.Scoped pt3d = checkStruct(root, "Point3D", "i", "j", "k"); + Declaration.Function drawParamid = findDecl(root, "drawParamid", Declaration.Function.class); + Type.Function fnType = drawParamid.type(); + // Array in function argument is lowered to pointer + Type type = TypeUnwrapper.of(fnType.argumentTypes().get(0)) + .unwrapPointer().unwrapTypedef().get(); + assertEquals(type, Type.declared(pt3d)); + + Declaration.Function do_ops = findDecl(root, "do_ops", Declaration.Function.class); + fnType = do_ops.type(); + type = unwrapTypedefType(fnType.returnType()); + assertEquals(type, getTypedefType(root, "op_sequence")); + type = fnType.argumentTypes().get(0); + type = unwrapTypedefType(type); + assertEquals(type, getTypedefType(root, "int_op")); + type = fnType.argumentTypes().get(1); + type = unwrapTypedefType(type); + assertEquals(type, getTypedefType(root, "count_t")); + } + + @Test + public void TypedefsToSameType() { + // For typedef declaration, the type will be the canonical type + // Which means, the type will not be another typedef + // However, it can be other delegated type or an array + Declaration.Scoped pt = checkStruct(root, "Point", "i", "j"); + Type.Declared type = Type.declared(pt); + assertEquals(getTypedefType(root, "POINT"), type); + assertEquals(getTypedefType(root, "point_t"), type); + + Type canonical = TypeUnwrapper.of(getTypedefType(root, "rectangle")) + .unwrapArray(4) + // FIXME? If we would like to generate array using typedef type + // then we need to use typedef as array element type and + // requires following line to pass the test. + // .unwrapTypedef() + .get(); + assertEquals(canonical, type); + + Declaration.Variable canvas = findDecl(root, "canvas", Declaration.Variable.class); + assertEquals(canvas.kind(), Declaration.Variable.Kind.GLOBAL); + Type ref = TypeUnwrapper.of(canvas.type()) + .unwrapTypedef() + .unwrapArray(4) + .get(); + assertEquals(ref, type); + + getTypedefType(root, "count_t"); + } + + @Test + public void TypedefsArrays() { + Type intType = getTypedefType(root, "cordinate_t"); + + // As noted earlier, we currently have canonical array element type from typedef + Type type = getTypedefType(root, "location2D"); + Type elementType = unwrapArrayType(type, 2); + assertEquals(elementType, intType); + + Type count_t = getTypedefType(root, "count_t"); + type = getTypedefType(root, "dimensions"); + elementType = unwrapArrayType(type); + assertEquals(elementType, count_t); + type = getTypedefType(root, "count_ptr"); + assertEquals(type, Type.pointer(count_t)); + } + + @Test + public void AnonymousRecordTypedef() { + // For anonymous typedef, present the typedef declaration and + // the Scope declaration can be obtained via Variable.type() + Declaration.Scoped record = assertAnonymousRecord(root, "op_sequence"); + assertEquals(record.kind(), Declaration.Scoped.Kind.STRUCT); + checkNames(record.members(), "times", "op"); + + record = assertAnonymousRecord(root, "IntOrFloat"); + assertEquals(record.kind(), Declaration.Scoped.Kind.UNION); + checkNames(record.members(), "i", "f"); + + record = assertAnonymousRecord(root, "codetype_t"); + assertEquals(record.kind(), Declaration.Scoped.Kind.ENUM); + checkNames(record.members(), "Java", "C", "CPP", "Python", "Ruby"); + } + + @Test + public void CheckAnonyousDeclarations() { + // Should we expunge anonymous declaration? + // They only needed if referenced as a field or gloabal variable + // Exception enum, as they can be used as pleased, so we need to + // elevate them into constants. + // Anyhow, current implementation pass through enum, not elevate them. + // So we just check that + Declaration[] ar = findAllWithName(root, ""); + assertEquals(ar.length, 2); + Declaration.Scoped e = (Declaration.Scoped) ar[0]; + assertEquals(e.kind(), Declaration.Scoped.Kind.ENUM); + checkNames(e.members(), "RED", "GREEN", "BLUE"); + e = (Declaration.Scoped) ar[1]; + assertEquals(e.kind(), Declaration.Scoped.Kind.ENUM); + checkNames(e.members(), "Java", "C", "CPP", "Python", "Ruby"); + } + + @Test + public void CheckFunctionPointers() { + Type intType = getTypedefType(root, "cordinate_t"); + Type intOpType = getTypedefType(root, "int_op"); + assertEquals(intOpType, Type.pointer(Type.function(false, intType, intType))); + Type intOp2Type = getTypedefType(root, "int_op2"); + assertEquals(intOp2Type, Type.pointer(Type.function(false, intType, intType, intType))); + + checkGlobal(root, "another_int_op", intOpType); + + Declaration.Function getFn = findDecl(root, "getFn", Declaration.Function.class); + assertEquals(getFn.parameters().size(), 0); + Type.Delegated retType = (Type.Delegated) getFn.type().returnType(); + assertTrue(retType.kind() == Type.Delegated.Kind.POINTER); + Type.Function fnType = (Type.Function) retType.type(); + assertEquals(fnType.returnType(), Type.void_()); + assertEquals(fnType.argumentTypes().get(1), + Type.typedef("count_t", getTypedefType(root, "count_t"))); + } +} diff --git a/test/jdk/java/jextract/testTypedef.h b/test/jdk/java/jextract/testTypedef.h new file mode 100644 index 00000000000..78943c5f8d7 --- /dev/null +++ b/test/jdk/java/jextract/testTypedef.h @@ -0,0 +1,90 @@ +typedef unsigned long count_t; +typedef int (*int_op)(int); +typedef int (*int_op2)(int, int); + +typedef struct { + count_t times; + int_op op; +} op_sequence; + +int_op add; + +// Global variable with unnamed function type +int (*another_int_op)(int); + +// Function prototype +op_sequence do_ops(int_op op, count_t times); + +// anonymous typedef +typedef union { + int i; + float f; +} IntOrFloat; + +// Completely anonymous enum +enum { + RED = 0xff0000, + GREEN = 0x00ff00, + BLUE = 0x0000ff +}; + +typedef enum SIZE { + XS, + S, + M, + L, + XL +} SIZE; + +// Typedef anonymous enum +typedef enum { + Java, + C, + CPP, + Python, + Ruby +} codetype_t; + +// declaration only +struct Point; +// definition +struct Point { + int i; + int j; +}; +// different name struct typedef +typedef struct Point POINT; +// layered typedef +typedef POINT point_t; +typedef point_t rectangle[4]; + +rectangle canvas; + +typedef int cordinate_t; +typedef cordinate_t location2D[2]; +typedef count_t dimensions[]; +typedef count_t *count_ptr; + +// same name struct typedef +typedef struct Point3D { + int i; + int j; + int k; +} Point3D; +// User of same name typedef +void drawParamid(Point3D vertices[4]); + +// anonymous types not references +struct { + int foo; + int bar; +}; + +static union { + int i; + long l; +}; + +// No way to declare anonymous function type +// But here is a function getFn to return a function type +void (*getFn(void))(int, count_t, int_op); \ No newline at end of file diff --git a/test/jdk/tools/jextract/JextractToolRunner.java b/test/jdk/tools/jextract/JextractToolRunner.java index 3ce9c61009d..89b0edf5263 100644 --- a/test/jdk/tools/jextract/JextractToolRunner.java +++ b/test/jdk/tools/jextract/JextractToolRunner.java @@ -94,12 +94,12 @@ protected Path getOutputFilePath(String fileName) { } protected JextractResult checkSuccess() { - assertEquals(exitCode, 0, "Sucess excepted, failed: " + exitCode); + assertEquals(exitCode, 0, "Sucess expected, failed: " + exitCode); return this; } protected JextractResult checkFailure() { - assertNotEquals(exitCode, 0, "Failure excepted, succeeded!"); + assertNotEquals(exitCode, 0, "Failure expected, succeeded!"); return this; }