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 jdk.internal.clang.Cursor; 26 import jdk.internal.clang.CursorKind; 27 import jdk.internal.clang.Type; 28 import jdk.internal.clang.TypeKind; 29 30 import java.nio.file.Path; 31 import java.util.concurrent.atomic.AtomicInteger; 32 import java.util.logging.Logger; 33 import java.util.List; 34 35 /** 36 * This class represent a native code header file 37 */ 38 public final class HeaderFile { 39 final Path path; 40 final String pkgName; 41 final String clsName; 42 final TypeDictionary dict; 43 // The top header file cause this file to be parsed 44 HeaderFile main; 45 CodeFactory cf; 46 List<String> libraries; 47 List<String> libraryPaths; 48 49 private final AtomicInteger serialNo; 50 private final Context.SymbolChecker symChecker; 51 52 final Logger logger = Logger.getLogger(getClass().getPackage().getName()); 53 54 HeaderFile(Path path, String pkgName, String clsName, HeaderFile main, Context.SymbolChecker symChecker) { 55 this.path = path; 56 this.pkgName = pkgName; 57 this.clsName = clsName; 58 dict = TypeDictionary.of(pkgName); 59 serialNo = new AtomicInteger(); 60 this.main = main == null ? this : main; 61 this.symChecker = symChecker; 62 } 63 64 void useLibraries(List<String> libraries, List<String> libraryPaths) { 65 this.libraries = libraries; 66 this.libraryPaths = libraryPaths; 67 } 68 69 /** 70 * Call this function to enable code generation for this HeaderFile. 71 * This function should only be called once to turn on code generation and before process any cursor. 72 * @param cf The CodeFactory used to generate code 73 */ 74 void useCodeFactory(CodeFactory cf) { 75 if (null != this.cf) { 76 logger.config(() -> "CodeFactory had been initialized for " + path); 77 // Diagnosis code 78 if (Main.DEBUG) { 79 new Throwable().printStackTrace(Context.getInstance().err); 80 } 81 } else { 82 this.cf = cf; 83 } 84 } 85 86 @Override 87 public String toString() { 88 return "HeaderFile(path=" + path + ")"; 89 } 90 91 private int serialNo() { 92 return serialNo.incrementAndGet(); 93 } 94 95 void processCursor(Cursor c, HeaderFile main, boolean isBuiltIn) { 96 if (c.isDeclaration()) { 97 Type t = c.type(); 98 if (symChecker != null) { 99 if (t.kind() == TypeKind.FunctionProto || 100 t.kind() == TypeKind.FunctionNoProto) { 101 String name = c.spelling(); 102 if (!symChecker.lookup(name)) { 103 Context.getInstance().err.println(Main.format("warn.symbol.not.found", name)); 104 } 105 } 106 } 107 JType jt = dict.computeIfAbsent(t, type -> { 108 logger.fine(() -> "PH: Compute type for " + type.spelling()); 109 return define(type); 110 }); 111 assert (jt instanceof JType2); 112 // Only main file can define interface 113 if (cf != null && this.main == main) { 114 cf.addType(jt, c); 115 } 116 } else if (c.isPreprocessing()) { 117 if (cf != null && c.kind() == CursorKind.MacroDefinition && !isBuiltIn && this.main == main) { 118 cf.addMacro(c); 119 } 120 } 121 } 122 123 JType globalLookup(Type type) { | 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 jdk.internal.clang.Cursor; 26 import jdk.internal.clang.CursorKind; 27 import jdk.internal.clang.Type; 28 import jdk.internal.clang.TypeKind; 29 30 import java.nio.file.Path; 31 import java.util.Collections; 32 import java.util.concurrent.atomic.AtomicInteger; 33 import java.util.logging.Logger; 34 import java.util.List; 35 36 /** 37 * This class represent a native code header file 38 */ 39 public final class HeaderFile { 40 private final Context ctx; 41 final Path path; 42 final String pkgName; 43 final String clsName; 44 private final TypeDictionary dict; 45 // The top header file cause this file to be parsed 46 private HeaderFile main; 47 private CodeFactory cf; 48 List<String> libraries; // immutable 49 List<String> libraryPaths; // immutable 50 51 private final AtomicInteger serialNo; 52 private final Context.SymbolChecker symChecker; 53 54 private final Logger logger = Logger.getLogger(getClass().getPackage().getName()); 55 56 HeaderFile(Context ctx, Path path, String pkgName, String clsName, HeaderFile main, Context.SymbolChecker symChecker) { 57 this.ctx = ctx; 58 this.path = path; 59 this.pkgName = pkgName; 60 this.clsName = clsName; 61 dict = ctx.typeDictionaryFor(pkgName); 62 serialNo = new AtomicInteger(); 63 this.main = main == null ? this : main; 64 this.symChecker = symChecker; 65 } 66 67 void useLibraries(List<String> libraries, List<String> libraryPaths) { 68 this.libraries = Collections.unmodifiableList(libraries); 69 this.libraryPaths = Collections.unmodifiableList(libraryPaths); 70 } 71 72 CodeFactory getCodeFactory() { 73 return cf; 74 } 75 76 /** 77 * Call this function to enable code generation for this HeaderFile. 78 * This function should only be called once to turn on code generation and before process any cursor. 79 * @param cf The CodeFactory used to generate code 80 */ 81 void useCodeFactory(CodeFactory cf) { 82 if (null != this.cf) { 83 logger.config(() -> "CodeFactory had been initialized for " + path); 84 // Diagnosis code 85 if (Main.DEBUG) { 86 new Throwable().printStackTrace(ctx.err); 87 } 88 } else { 89 this.cf = cf; 90 } 91 } 92 93 @Override 94 public String toString() { 95 return "HeaderFile(path=" + path + ")"; 96 } 97 98 private int serialNo() { 99 return serialNo.incrementAndGet(); 100 } 101 102 void processCursor(Cursor c, HeaderFile main, boolean isBuiltIn) { 103 if (c.isDeclaration()) { 104 Type t = c.type(); 105 if (symChecker != null) { 106 if (t.kind() == TypeKind.FunctionProto || 107 t.kind() == TypeKind.FunctionNoProto) { 108 String name = c.spelling(); 109 if (!symChecker.lookup(name)) { 110 ctx.err.println(Main.format("warn.symbol.not.found", name)); 111 } 112 } 113 } 114 JType jt = dict.computeIfAbsent(t, type -> { 115 logger.fine(() -> "PH: Compute type for " + type.spelling()); 116 return define(type); 117 }); 118 assert (jt instanceof JType2); 119 // Only main file can define interface 120 if (cf != null && this.main == main) { 121 cf.addType(jt, c); 122 } 123 } else if (c.isPreprocessing()) { 124 if (cf != null && c.kind() == CursorKind.MacroDefinition && !isBuiltIn && this.main == main) { 125 cf.addMacro(c); 126 } 127 } 128 } 129 130 JType globalLookup(Type type) { |