< prev index next >

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

Print this page




   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 package com.sun.tools.jextract;
  24 
  25 import java.nio.file.Path;

  26 import java.util.Collections;
  27 import java.util.List;

  28 import java.util.concurrent.atomic.AtomicInteger;
  29 import java.util.logging.Logger;

  30 import jdk.internal.clang.Cursor;
  31 import jdk.internal.clang.CursorKind;
  32 import jdk.internal.clang.Type;
  33 import jdk.internal.clang.TypeKind;
  34 
  35 /**
  36  * This class represent a native code header file
  37  */
  38 public final class HeaderFile {
  39     private final Context ctx;
  40     final Path path;
  41     final String pkgName;
  42     final String clsName;
  43     private final TypeDictionary dict;
  44     // The top header file cause this file to be parsed
  45     private HeaderFile main;


  46     private AsmCodeFactory cf;
  47     List<String> libraries; // immutable
  48     List<String> libraryPaths; // immutable
  49 
  50     private final AtomicInteger serialNo;
  51 
  52     private final Logger logger = Logger.getLogger(getClass().getPackage().getName());
  53 
  54     HeaderFile(Context ctx, Path path, String pkgName, String clsName, HeaderFile main) {
  55         this.ctx = ctx;
  56         this.path = path;
  57         this.pkgName = pkgName;
  58         this.clsName = clsName;
  59         dict = ctx.typeDictionaryFor(pkgName);
  60         serialNo = new AtomicInteger();
  61         this.main = main == null ? this : main;





  62     }
  63 
  64     void useLibraries(List<String> libraries, List<String> libraryPaths) {
  65         this.libraries = Collections.unmodifiableList(libraries);
  66         this.libraryPaths = Collections.unmodifiableList(libraryPaths);
  67     }
  68 
  69     AsmCodeFactory getCodeFactory() {
  70         return cf;
  71     }
  72 
  73     /**
  74      * Call this function to enable code generation for this HeaderFile.
  75      * This function should only be called once to turn on code generation and before process any cursor.
  76      * @param cf The CodeFactory used to generate code
  77      */
  78     void useCodeFactory(AsmCodeFactory cf) {
  79         if (null != this.cf) {
  80             logger.config(() -> "CodeFactory had been initialized for " + path);
  81             // Diagnosis code
  82             if (Main.DEBUG) {
  83                 new Throwable().printStackTrace(ctx.err);
  84             }
  85         } else {
  86             this.cf = cf;







  87         }
  88     }
  89 
  90     @Override
  91     public String toString() {
  92         return "HeaderFile(path=" + path + ")";
  93     }
  94 
  95     private int serialNo() {
  96         return serialNo.incrementAndGet();
  97     }
  98 
  99     void processCursor(Cursor c, HeaderFile main, boolean isBuiltIn) {
 100         if (c.isDeclaration()) {
 101             logger.finest(() -> "Looking at cursor " + c.spelling() + " of kind " + c.kind());
 102             if (c.kind() == CursorKind.UnexposedDecl ||
 103                     c.kind() == CursorKind.Namespace) {
 104                 c.children()
 105                         .filter(c1 -> c1.isDeclaration())
 106                         .peek(c1 -> logger.finest(


 211                 t, defC.isInvalid() ? dcl : defC);
 212         if (gen_code) {
 213             cf.addType(jt, defC);
 214         }
 215         return jt;
 216     }
 217 
 218     // Use of dict.lookup() and lookup() is tricky, if a type should have being
 219     // declared earlier, use dict.lookup(); otherwise use lookup() for potentially
 220     // local declaration of a type.
 221     JType define(Type t) {
 222         JType jt;
 223         JType2 jt2;
 224         logger.fine("Define " + t.kind() + ":" + t.spelling() + " for TD " + pkgName);
 225         switch (t.kind()) {
 226             case Unexposed:
 227             case Elaborated:
 228                 jt = define(t.canonicalType());
 229                 break;
 230             case ConstantArray:
 231                 jt = JType.ofArray(globalLookup(t.getElementType()));
 232                 break;
 233             case IncompleteArray:
 234                 jt = JType.ofArray(globalLookup(t.getElementType()));
 235                 break;
 236             case FunctionProto:
 237             case FunctionNoProto:
 238                 JType[] args = new JType[t.numberOfArgs()];
 239                 for (int i = 0; i < args.length; i++) {
 240                     // argument could be function pointer declared locally
 241                     args[i] = globalLookup(t.argType(i));
 242                 }
 243                 jt = new JType.Function(Utils.getFunction(t), t.isVariadic(), globalLookup(t.resultType()), args);
 244                 break;
 245             case Enum:
 246                 String name = Utils.toInternalName(pkgName, clsName,
 247                         Utils.toClassName(Utils.getIdentifier(t)));
 248                 jt = TypeAlias.of(name, JType.Int);
 249                 break;
 250             case Invalid:
 251                 throw new IllegalArgumentException("Invalid type");
 252             case Record:




   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 package com.sun.tools.jextract;
  24 
  25 import java.nio.file.Path;
  26 import java.util.ArrayList;
  27 import java.util.Collections;
  28 import java.util.List;
  29 import java.util.Objects;
  30 import java.util.concurrent.atomic.AtomicInteger;
  31 import java.util.logging.Logger;
  32 import java.util.stream.Stream;
  33 import jdk.internal.clang.Cursor;
  34 import jdk.internal.clang.CursorKind;
  35 import jdk.internal.clang.Type;
  36 import jdk.internal.clang.TypeKind;
  37 
  38 /**
  39  * This class represent a native code header file
  40  */
  41 public final class HeaderFile {
  42     private final Context ctx;
  43     final Path path;
  44     final String pkgName;
  45     final String clsName;
  46     private final TypeDictionary dict;
  47     // The top header file cause this file to be parsed
  48     private HeaderFile main;
  49     // files included that are from the same directory
  50     private final List<HeaderFile> includedFiles;
  51     private AsmCodeFactory cf;
  52     List<String> libraries; // immutable
  53     List<String> libraryPaths; // immutable
  54 
  55     private final AtomicInteger serialNo;
  56 
  57     private final Logger logger = Logger.getLogger(getClass().getPackage().getName());
  58 
  59     HeaderFile(Context ctx, Path path, String pkgName, String clsName, HeaderFile main) {
  60         this.ctx = ctx;
  61         this.path = path;
  62         this.pkgName = pkgName;
  63         this.clsName = clsName;
  64         this.dict = ctx.typeDictionaryFor(pkgName);
  65         this.serialNo = new AtomicInteger();
  66         this.main = main == null ? this : main;
  67         this.includedFiles = new ArrayList<>();
  68     }
  69 
  70     Stream<HeaderFile> getIncludedFiles() {
  71         return includedFiles.stream();
  72     }
  73 
  74     void useLibraries(List<String> libraries, List<String> libraryPaths) {
  75         this.libraries = Collections.unmodifiableList(libraries);
  76         this.libraryPaths = Collections.unmodifiableList(libraryPaths);
  77     }
  78 
  79     AsmCodeFactory getCodeFactory() {
  80         return cf;
  81     }
  82 
  83     /**
  84      * Call this function to enable code generation for this HeaderFile.
  85      * This function should only be called once to turn on code generation and before process any cursor.
  86      * @param cf The CodeFactory used to generate code
  87      */
  88     void useCodeFactory(AsmCodeFactory cf) {
  89         if (null != this.cf) {
  90             logger.config(() -> "CodeFactory had been initialized for " + path);
  91             // Diagnosis code
  92             if (Main.DEBUG) {
  93                 new Throwable().printStackTrace(ctx.err);
  94             }
  95         } else {
  96             this.cf = cf;
  97             // The 'main' header interface inherits from included header interfaces
  98             // only if the included file is assigned to the same package and is from
  99             // the same directory.
 100             if (this != main && Objects.equals(pkgName, main.pkgName) &&
 101                     Objects.equals(path.getParent(), main.path.getParent())) {
 102                 main.includedFiles.add(this);
 103             }
 104         }
 105     }
 106 
 107     @Override
 108     public String toString() {
 109         return "HeaderFile(path=" + path + ")";
 110     }
 111 
 112     private int serialNo() {
 113         return serialNo.incrementAndGet();
 114     }
 115 
 116     void processCursor(Cursor c, HeaderFile main, boolean isBuiltIn) {
 117         if (c.isDeclaration()) {
 118             logger.finest(() -> "Looking at cursor " + c.spelling() + " of kind " + c.kind());
 119             if (c.kind() == CursorKind.UnexposedDecl ||
 120                     c.kind() == CursorKind.Namespace) {
 121                 c.children()
 122                         .filter(c1 -> c1.isDeclaration())
 123                         .peek(c1 -> logger.finest(


 228                 t, defC.isInvalid() ? dcl : defC);
 229         if (gen_code) {
 230             cf.addType(jt, defC);
 231         }
 232         return jt;
 233     }
 234 
 235     // Use of dict.lookup() and lookup() is tricky, if a type should have being
 236     // declared earlier, use dict.lookup(); otherwise use lookup() for potentially
 237     // local declaration of a type.
 238     JType define(Type t) {
 239         JType jt;
 240         JType2 jt2;
 241         logger.fine("Define " + t.kind() + ":" + t.spelling() + " for TD " + pkgName);
 242         switch (t.kind()) {
 243             case Unexposed:
 244             case Elaborated:
 245                 jt = define(t.canonicalType());
 246                 break;
 247             case ConstantArray:


 248             case IncompleteArray:
 249                 jt = JType.ofArray(globalLookup(t.getElementType()));
 250                 break;
 251             case FunctionProto:
 252             case FunctionNoProto:
 253                 JType[] args = new JType[t.numberOfArgs()];
 254                 for (int i = 0; i < args.length; i++) {
 255                     // argument could be function pointer declared locally
 256                     args[i] = globalLookup(t.argType(i));
 257                 }
 258                 jt = new JType.Function(Utils.getFunction(t), t.isVariadic(), globalLookup(t.resultType()), args);
 259                 break;
 260             case Enum:
 261                 String name = Utils.toInternalName(pkgName, clsName,
 262                         Utils.toClassName(Utils.getIdentifier(t)));
 263                 jt = TypeAlias.of(name, JType.Int);
 264                 break;
 265             case Invalid:
 266                 throw new IllegalArgumentException("Invalid type");
 267             case Record:


< prev index next >