< prev index next >

src/jdk.jextract/share/classes/com/sun/tools/jextract/TypedefHandler.java

Print this page

        

@@ -36,33 +36,37 @@
 import com.sun.tools.jextract.tree.HeaderTree;
 import com.sun.tools.jextract.tree.SimpleTreeVisitor;
 import com.sun.tools.jextract.tree.StructTree;
 import com.sun.tools.jextract.tree.Tree;
 import com.sun.tools.jextract.tree.TreeMaker;
+import com.sun.tools.jextract.tree.TreePhase;
 import com.sun.tools.jextract.tree.TreePrinter;
 import com.sun.tools.jextract.tree.TypedefTree;
 import jdk.internal.clang.Cursor;
 
 /**
  * This visitor handles certain typedef declarations.
  *
  * 1. Remove redundant typedefs.
  * 2. Rename typedef'ed anonymous type definitions like
  *        typedef struct { int x; int y; } Point;
+ * 3. Remove redundant struct/union/enum forward/backward declarations
  */
-final class TypedefHandler extends SimpleTreeVisitor<Void, Void> {
+final class TypedefHandler extends SimpleTreeVisitor<Void, Void>
+        implements TreePhase {
     private final TreeMaker treeMaker = new TreeMaker();
 
     // Potential Tree instances that will go into transformed HeaderTree
     // are collected in this list.
     private final 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<>();
 
-    HeaderTree transform(HeaderTree ht) {
+    @Override
+    public HeaderTree transform(HeaderTree ht) {
         // Process all header declarations are collect potential
         // declarations that will go into transformed HeaderTree
         // into the this.decls field.
         ht.accept(this, null);
 

@@ -85,16 +89,66 @@
         decls.add(tree);
         return null;
     }
 
     @Override
+    public Void visitEnum(EnumTree e, Void v) {
+        /*
+         * If we're seeing a forward/backward declaration of an
+         * enum which is definied elsewhere in this compilation
+         * unit, ignore it. If no definition is found, we want to
+         * leave the declaration so that dummy definition will be
+         * generated.
+         *
+         * Example:
+         *
+         *  enum Color ; // <-- forward declaration
+         *  struct Point { int i; int j; };
+         *  struct Point3D { int i; int j; int k; };
+         *  struct Point3D; // <-- backward declaration
+         */
+
+        // include this only if this is a definition or a declaration
+        // for which no definition is found elsewhere.
+        if (e.isDefinition() || !e.definition().isPresent()) {
+            decls.add(e);
+        }
+        return null;
+    }
+
+    @Override
     public Void visitHeader(HeaderTree ht, Void v) {
         ht.declarations().forEach(decl -> decl.accept(this, null));
         return null;
     }
 
     @Override
+    public Void visitStruct(StructTree s, Void v) {
+        /*
+         * If we're seeing a forward/backward declaration of
+         * a struct which is definied elsewhere in this compilation
+         * unit, ignore it. If no definition is found, we want to
+         * leave the declaration so that dummy definition will be
+         * generated.
+         *
+         * Example:
+         *
+         *  struct Point; // <-- forward declaration
+         *  struct Point { int i; int j; };
+         *  struct Point3D { int i; int j; int k; };
+         *  struct Point3D; // <-- backward declaration
+         */
+
+        // include this only if this is a definition or a declaration
+        // for which no definition is found elsewhere.
+        if (s.isDefinition() || !s.definition().isPresent()) {
+            decls.add(s);
+        }
+        return null;
+    }
+
+    @Override
     public Void visitTypedef(TypedefTree tt, Void v) {
         Optional<Tree> def = tt.typeDefinition();
         if (def.isPresent()) {
             Tree defTree = def.get();
             if (defTree instanceof StructTree) {
< prev index next >