Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8244337: jextract generates struct static utils class for typedef names only if struct name is empty #143

Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -70,6 +70,11 @@
private final String pkgName;
private StructBuilder structBuilder;
private List<String> structSources = new ArrayList<>();
private Set<String> structClassNames = new HashSet<>();
private int structClassNameCount = 0;
private String uniqueStructClassName(String name) {
return structClassNames.add(name.toLowerCase())? name : (name + "$" + structClassNameCount++);
}

// have we seen this Variable earlier?
protected boolean variableSeen(Declaration.Variable tree) {
@@ -223,7 +228,7 @@ public Void visitScoped(Declaration.Scoped d, Declaration parent) {
return null;
}
String name = d.name();
if (name.isEmpty() && parent != null) {
if (parent instanceof Declaration.Typedef) {
name = parent.name();
}

@@ -234,10 +239,20 @@ public Void visitScoped(Declaration.Scoped d, Declaration parent) {
case STRUCT:
case UNION: {
structClass = true;
this.structBuilder = new StructBuilder("C" + name, pkgName, constantHelper);
/*
* We may have case-insensitive name collision! A C program may have
* defined structs with the names FooS, fooS, FoOs, fOOs. Because we
* map structs and unions to nested classes of header classes, such
* a case-insensitive name collision is problematic. This is because in
* a case-insensitive file system javac will overwrite classes for
* Header$CFooS, Header$CfooS, Header$CFoOs and so on! We solve this by
* generating unique case-insensitive names for classes.
*/
String structClassName = uniqueStructClassName("C" + name);
this.structBuilder = new StructBuilder(structClassName, pkgName, constantHelper);
structBuilder.incrAlign();
structBuilder.classBegin();
structBuilder.addLayoutGetter("C" + name, d.layout().get());
structBuilder.addLayoutGetter(structClassName, d.layout().get());
break;
}
}
@@ -309,9 +324,7 @@ 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()) {
if (!s.name().equals(tree.name())) {
return visitScoped(s, tree);
}
}
@@ -83,23 +83,32 @@ public void repeatedDecls() {
checkIntGetter(cls, "Y", 2);

// check Point layout
Class<?> pointCls = loader.loadClass("repeatedDecls_h$CPoint");
MemoryLayout pointLayout = findLayout(pointCls);
assertNotNull(pointLayout);
assertTrue(((GroupLayout)pointLayout).isStruct());
checkFieldABIType(pointLayout, "i", Type.INT);
checkFieldABIType(pointLayout, "j", Type.INT);
checkPoint(loader.loadClass("repeatedDecls_h$CPoint"));
checkPoint(loader.loadClass("repeatedDecls_h$CPoint_t"));
checkPoint(loader.loadClass("repeatedDecls_h$CPOINT$0"));

// check Point3D layout
Class<?> point3DCls = loader.loadClass("repeatedDecls_h$CPoint3D");
MemoryLayout point3DLayout = findLayout(point3DCls);
assertNotNull(point3DLayout);
assertTrue(((GroupLayout)point3DLayout).isStruct());
checkFieldABIType(point3DLayout, "i", Type.INT);
checkFieldABIType(point3DLayout, "j", Type.INT);
checkFieldABIType(point3DLayout, "k", Type.INT);
checkPoint3D(loader.loadClass("repeatedDecls_h$CPoint3D"));
checkPoint3D(loader.loadClass("repeatedDecls_h$CPoint3D_t"));
} finally {
deleteDir(repeatedDeclsOutput);
}
}

private void checkPoint(Class<?> pointCls) {
MemoryLayout pointLayout = findLayout(pointCls);
assertNotNull(pointLayout);
assertTrue(((GroupLayout)pointLayout).isStruct());
checkFieldABIType(pointLayout, "i", Type.INT);
checkFieldABIType(pointLayout, "j", Type.INT);
}

private void checkPoint3D(Class<?> point3DCls) {
MemoryLayout point3DLayout = findLayout(point3DCls);
assertNotNull(point3DLayout);
assertTrue(((GroupLayout)point3DLayout).isStruct());
checkFieldABIType(point3DLayout, "i", Type.INT);
checkFieldABIType(point3DLayout, "j", Type.INT);
checkFieldABIType(point3DLayout, "k", Type.INT);
}
}
@@ -61,14 +61,16 @@ struct Point {
};

typedef struct Point POINT;
typedef struct Point Point_t;

double distance(struct Point p);
double distance(POINT p);

struct Point3D {
typedef struct Point3D {
int i;
int j;
int k;
};
} Point3D_t;
struct Point3D;

enum RGBColor;