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.parser;
24
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.io.PrintWriter;
28 import java.util.Arrays;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.LinkedHashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Optional;
36 import java.util.function.Predicate;
37 import java.util.logging.Logger;
38 import java.util.stream.Collectors;
39 import jdk.internal.clang.Cursor;
40 import jdk.internal.clang.CursorKind;
41 import jdk.internal.clang.Diagnostic;
42 import jdk.internal.clang.Index;
43 import jdk.internal.clang.LibClang;
44 import jdk.internal.clang.SourceLocation;
45 import jdk.internal.clang.SourceRange;
46 import jdk.internal.clang.TranslationUnit;
47 import com.sun.tools.jextract.tree.HeaderTree;
48 import com.sun.tools.jextract.tree.MacroTree;
49 import com.sun.tools.jextract.tree.SimpleTreeVisitor;
50 import com.sun.tools.jextract.tree.Tree;
51 import com.sun.tools.jextract.tree.TreeMaker;
52 import com.sun.tools.jextract.tree.TreePrinter;
53
54 public class Parser {
55 private final PrintWriter out;
56 private final PrintWriter err;
57 private final TreeMaker treeMaker;
58 private final boolean supportMacros;
59 private final Logger logger = Logger.getLogger(getClass().getPackage().getName());
60
61 public Parser(PrintWriter out, PrintWriter err, boolean supportMacros) {
62 this.out = out;
63 this.err = err;
64 this.treeMaker = new TreeMaker();
65 this.supportMacros = supportMacros;
66 }
67
68 public Parser(boolean supportMacros) {
69 this(new PrintWriter(System.out, true),
70 new PrintWriter(System.err, true), supportMacros);
71 }
72
73 public List<HeaderTree> parse(Collection<Path> paths, Collection<String> args, Predicate<Cursor> include) {
74 final List<HeaderTree> headers = new ArrayList<>();
75 final Index index = LibClang.createIndex();
76 for (Path path : paths) {
77 logger.info(() -> {
78 StringBuilder sb = new StringBuilder(
79 "Parsing header file " + path + " with following args:\n");
80 int i = 0;
81 for (String arg : args) {
82 sb.append("arg[");
83 sb.append(i++);
84 sb.append("] = ");
85 sb.append(arg);
86 sb.append("\n");
87 }
88 return sb.toString();
89 });
90
91 Cursor tuCursor = index.parse(path.toString(),
92 d -> {
93 err.println(d);
94 if (d.severity() > Diagnostic.CXDiagnostic_Warning) {
95 throw new RuntimeException(d.toString());
96 }
97 },
98 supportMacros, args.toArray(new String[0]));
99
100 MacroParser macroParser = new MacroParser();
101 List<Tree> decls = new ArrayList<>();
102 tuCursor.children().
103 filter(c -> include.test(c)).
104 peek(c -> logger.finest(
105 () -> "Cursor: " + c.spelling() + "@" + c.USR() + "?" + c.isDeclaration())).
106 forEach(c -> {
107 SourceLocation loc = c.getSourceLocation();
108 if (loc == null) {
109 logger.info(() -> "Ignore Cursor " + c.spelling() + "@" + c.USR() + " has no SourceLocation");
110 return;
111 }
112
113 SourceLocation.Location src = loc.getFileLocation();
114 if (src == null) {
115 logger.info(() -> "Cursor " + c.spelling() + "@" + c.USR() + " has no FileLocation");
116 return;
117 }
118
119 logger.fine(() -> "Do cursor: " + c.spelling() + "@" + c.USR());
120
121 if (c.isDeclaration()) {
122 if (c.kind() == CursorKind.UnexposedDecl ||
123 c.kind() == CursorKind.Namespace) {
169 SourceRange range = cursor.getExtent();
170 String[] tokens = tu.tokens(range);
171
172 macroParser.parse(cursor, tokens);
173 }
174
175 private boolean isMacro(Cursor c) {
176 return c.isPreprocessing() && c.kind() == CursorKind.MacroDefinition;
177 }
178
179 public static void main(String[] args) {
180 if (args.length == 0) {
181 System.err.println("Expected a header file");
182 return;
183 }
184
185 Parser p = new Parser(true);
186 List<Path> paths = Arrays.stream(args).map(Paths::get).collect(Collectors.toList());
187 Path builtinInc = Paths.get(System.getProperty("java.home"), "conf", "jextract");
188 List<String> clangArgs = List.of("-I" + builtinInc);
189 List<HeaderTree> headers = p.parse(paths, clangArgs, c->true);
190 TreePrinter printer = new TreePrinter();
191 for (HeaderTree ht : headers) {
192 ht.accept(printer, null);
193 }
194 }
195 }
|
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.parser;
24
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.io.PrintWriter;
28 import java.util.Arrays;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.LinkedHashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Optional;
36 import java.util.logging.Logger;
37 import java.util.stream.Collectors;
38 import jdk.internal.clang.Cursor;
39 import jdk.internal.clang.CursorKind;
40 import jdk.internal.clang.Diagnostic;
41 import jdk.internal.clang.Index;
42 import jdk.internal.clang.LibClang;
43 import jdk.internal.clang.SourceLocation;
44 import jdk.internal.clang.SourceRange;
45 import jdk.internal.clang.TranslationUnit;
46 import com.sun.tools.jextract.tree.HeaderTree;
47 import com.sun.tools.jextract.tree.MacroTree;
48 import com.sun.tools.jextract.tree.SimpleTreeVisitor;
49 import com.sun.tools.jextract.tree.Tree;
50 import com.sun.tools.jextract.tree.TreeMaker;
51 import com.sun.tools.jextract.tree.TreePrinter;
52
53 public class Parser {
54 private final PrintWriter out;
55 private final PrintWriter err;
56 private final TreeMaker treeMaker;
57 private final boolean supportMacros;
58 private final Logger logger = Logger.getLogger(getClass().getPackage().getName());
59
60 public Parser(PrintWriter out, PrintWriter err, boolean supportMacros) {
61 this.out = out;
62 this.err = err;
63 this.treeMaker = new TreeMaker();
64 this.supportMacros = supportMacros;
65 }
66
67 public Parser(boolean supportMacros) {
68 this(new PrintWriter(System.out, true),
69 new PrintWriter(System.err, true), supportMacros);
70 }
71
72 public List<HeaderTree> parse(Collection<Path> paths, Collection<String> args) {
73 final List<HeaderTree> headers = new ArrayList<>();
74 final Index index = LibClang.createIndex();
75 for (Path path : paths) {
76 logger.info(() -> {
77 StringBuilder sb = new StringBuilder(
78 "Parsing header file " + path + " with following args:\n");
79 int i = 0;
80 for (String arg : args) {
81 sb.append("arg[");
82 sb.append(i++);
83 sb.append("] = ");
84 sb.append(arg);
85 sb.append("\n");
86 }
87 return sb.toString();
88 });
89
90 Cursor tuCursor = index.parse(path.toString(),
91 d -> {
92 err.println(d);
93 if (d.severity() > Diagnostic.CXDiagnostic_Warning) {
94 throw new RuntimeException(d.toString());
95 }
96 },
97 supportMacros, args.toArray(new String[0]));
98
99 MacroParser macroParser = new MacroParser();
100 List<Tree> decls = new ArrayList<>();
101 tuCursor.children().
102 peek(c -> logger.finest(
103 () -> "Cursor: " + c.spelling() + "@" + c.USR() + "?" + c.isDeclaration())).
104 forEach(c -> {
105 SourceLocation loc = c.getSourceLocation();
106 if (loc == null) {
107 logger.info(() -> "Ignore Cursor " + c.spelling() + "@" + c.USR() + " has no SourceLocation");
108 return;
109 }
110
111 SourceLocation.Location src = loc.getFileLocation();
112 if (src == null) {
113 logger.info(() -> "Cursor " + c.spelling() + "@" + c.USR() + " has no FileLocation");
114 return;
115 }
116
117 logger.fine(() -> "Do cursor: " + c.spelling() + "@" + c.USR());
118
119 if (c.isDeclaration()) {
120 if (c.kind() == CursorKind.UnexposedDecl ||
121 c.kind() == CursorKind.Namespace) {
167 SourceRange range = cursor.getExtent();
168 String[] tokens = tu.tokens(range);
169
170 macroParser.parse(cursor, tokens);
171 }
172
173 private boolean isMacro(Cursor c) {
174 return c.isPreprocessing() && c.kind() == CursorKind.MacroDefinition;
175 }
176
177 public static void main(String[] args) {
178 if (args.length == 0) {
179 System.err.println("Expected a header file");
180 return;
181 }
182
183 Parser p = new Parser(true);
184 List<Path> paths = Arrays.stream(args).map(Paths::get).collect(Collectors.toList());
185 Path builtinInc = Paths.get(System.getProperty("java.home"), "conf", "jextract");
186 List<String> clangArgs = List.of("-I" + builtinInc);
187 List<HeaderTree> headers = p.parse(paths, clangArgs);
188 TreePrinter printer = new TreePrinter();
189 for (HeaderTree ht : headers) {
190 ht.accept(printer, null);
191 }
192 }
193 }
|