C: allow to put 'struct' keyword before references to native structures

This commit is contained in:
Alexey Andreev 2019-06-06 18:37:37 +03:00
parent c84ae57b3a
commit 7831fd328f
7 changed files with 51 additions and 46 deletions

View File

@ -714,14 +714,14 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor {
ClassReader cls = context.getClassSource().get(field.getClassName()); ClassReader cls = context.getClassSource().get(field.getClassName());
writer.print("TEAVM_FIELD("); writer.print("TEAVM_FIELD(");
qualified.acceptVisitor(this); qualified.acceptVisitor(this);
writer.print(", ");
if (cls != null && isNative(cls)) { if (cls != null && isNative(cls)) {
InteropUtil.processInclude(cls.getAnnotations(), includes); InteropUtil.processInclude(cls.getAnnotations(), includes);
writer.print(", ").print(InteropUtil.getNativeName(cls)) InteropUtil.printNativeReference(writer, cls);
.print(", ").print(InteropUtil.getNativeName(cls, field.getFieldName())); writer.print(", ").print(InteropUtil.getNativeName(cls, field.getFieldName()));
} else { } else {
includes.includeClass(field.getClassName()); includes.includeClass(field.getClassName());
writer.print(", ").print(names.forClass(field.getClassName())) writer.print(names.forClass(field.getClassName())).print(", ").print(names.forMemberField(field));
.print(", ").print(names.forMemberField(field));
} }
writer.print(")"); writer.print(")");
} else { } else {

View File

@ -15,6 +15,8 @@
*/ */
package org.teavm.backend.c.generate; package org.teavm.backend.c.generate;
import org.teavm.backend.c.util.InteropUtil;
import org.teavm.model.ClassReader;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
public final class CodeGeneratorUtil { public final class CodeGeneratorUtil {
@ -99,4 +101,14 @@ public final class CodeGeneratorUtil {
writer.print(String.valueOf(v)); writer.print(String.valueOf(v));
} }
public static void printClassReference(CodeWriter writer, IncludeManager includes, NameProvider names,
ClassReader cls, String className) {
if (cls != null && InteropUtil.isNative(cls)) {
InteropUtil.processInclude(cls.getAnnotations(), includes);
InteropUtil.printNativeReference(writer, cls);
} else {
includes.includeClass(className);
writer.print(names.forClass(className));
}
}
} }

View File

@ -16,8 +16,8 @@
package org.teavm.backend.c.intrinsic; package org.teavm.backend.c.intrinsic;
import org.teavm.ast.InvocationExpr; import org.teavm.ast.InvocationExpr;
import org.teavm.backend.c.generate.CodeGeneratorUtil;
import org.teavm.backend.c.util.ConstantUtil; import org.teavm.backend.c.util.ConstantUtil;
import org.teavm.backend.c.util.InteropUtil;
import org.teavm.interop.Address; import org.teavm.interop.Address;
import org.teavm.model.ClassReader; import org.teavm.model.ClassReader;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
@ -175,19 +175,17 @@ public class AddressIntrinsic implements Intrinsic {
invocation.getArguments().get(1)); invocation.getArguments().get(1));
context.emit(invocation.getArguments().get(2)); context.emit(invocation.getArguments().get(2));
String structureName; context.writer().print(" * sizeof(");
ClassReader cls = className != null ? context.classes().get(className) : null;
if (cls != null && InteropUtil.isNative(cls)) { if (className != null) {
structureName = InteropUtil.getNativeName(cls); ClassReader cls = className != null ? context.classes().get(className) : null;
InteropUtil.processInclude(cls.getAnnotations(), context.includes()); CodeGeneratorUtil.printClassReference(context.writer(), context.includes(),
} else if (className != null) { context.names(), cls, className);
structureName = context.names().forClass(className);
context.includes().includeClass(className);
} else { } else {
structureName = "**"; context.writer().print("**");
} }
context.writer().print(" * sizeof(").print(structureName).print(")"); context.writer().print(")");
context.writer().print(")"); context.writer().print(")");
} }
break; break;

View File

@ -15,10 +15,8 @@
*/ */
package org.teavm.backend.c.intrinsic; package org.teavm.backend.c.intrinsic;
import org.teavm.ast.ConstantExpr;
import org.teavm.ast.Expr; import org.teavm.ast.Expr;
import org.teavm.ast.InvocationExpr; import org.teavm.ast.InvocationExpr;
import org.teavm.backend.c.generate.StringPoolGenerator;
import org.teavm.interop.Strings; import org.teavm.interop.Strings;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
@ -33,14 +31,9 @@ public class StringsIntrinsic implements Intrinsic {
switch (invocation.getMethod().getName()) { switch (invocation.getMethod().getName()) {
case "toC": { case "toC": {
Expr arg = invocation.getArguments().get(0); Expr arg = invocation.getArguments().get(0);
String literal = extractStringConstant(arg); context.writer().print("teavm_stringToC(");
if (literal != null) { context.emit(arg);
StringPoolGenerator.generateSimpleStringLiteral(context.writer(), literal); context.writer().print(")");
} else {
context.writer().print("teavm_stringToC(");
context.emit(arg);
context.writer().print(")");
}
break; break;
} }
case "fromC": case "fromC":
@ -50,13 +43,4 @@ public class StringsIntrinsic implements Intrinsic {
break; break;
} }
} }
private String extractStringConstant(Expr expr) {
if (!(expr instanceof ConstantExpr)) {
return null;
}
Object value = ((ConstantExpr) expr).getValue();
return value instanceof String ? (String) value : null;
}
} }

View File

@ -16,8 +16,8 @@
package org.teavm.backend.c.intrinsic; package org.teavm.backend.c.intrinsic;
import org.teavm.ast.InvocationExpr; import org.teavm.ast.InvocationExpr;
import org.teavm.backend.c.generate.CodeGeneratorUtil;
import org.teavm.backend.c.util.ConstantUtil; import org.teavm.backend.c.util.ConstantUtil;
import org.teavm.backend.c.util.InteropUtil;
import org.teavm.interop.Structure; import org.teavm.interop.Structure;
import org.teavm.model.ClassReader; import org.teavm.model.ClassReader;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
@ -64,7 +64,11 @@ public class StructureIntrinsic implements Intrinsic {
case "sizeOf": { case "sizeOf": {
String className = ConstantUtil.getClassLiteral(context, invocation, invocation.getArguments().get(0)); String className = ConstantUtil.getClassLiteral(context, invocation, invocation.getArguments().get(0));
if (className != null) { if (className != null) {
context.writer().print("sizeof(").print(context.names().forClass(className)).print(")"); context.writer().print("sizeof(");
ClassReader cls = context.classes().get(className);
CodeGeneratorUtil.printClassReference(context.writer(), context.includes(), context.names(), cls,
className);
context.writer().print(")");
} }
break; break;
} }
@ -72,15 +76,10 @@ public class StructureIntrinsic implements Intrinsic {
String className = ConstantUtil.getClassLiteral(context, invocation, invocation.getArguments().get(0)); String className = ConstantUtil.getClassLiteral(context, invocation, invocation.getArguments().get(0));
if (className != null) { if (className != null) {
ClassReader cls = context.classes().get(className); ClassReader cls = context.classes().get(className);
String structureName; context.writer().print("TEAVM_STRUCTURE_ADD(");
if (InteropUtil.isNative(cls)) { CodeGeneratorUtil.printClassReference(context.writer(), context.includes(), context.names(), cls,
structureName = InteropUtil.getNativeName(cls); className);
InteropUtil.processInclude(cls.getAnnotations(), context.includes()); context.writer().print(", ");
} else {
structureName = context.names().forClass(className);
context.includes().includeClass(className);
}
context.writer().print("TEAVM_STRUCTURE_ADD(").print(structureName).print(", ");
context.emit(invocation.getArguments().get(1)); context.emit(invocation.getArguments().get(1));
context.writer().print(", "); context.writer().print(", ");
context.emit(invocation.getArguments().get(2)); context.emit(invocation.getArguments().get(2));

View File

@ -15,6 +15,7 @@
*/ */
package org.teavm.backend.c.util; package org.teavm.backend.c.util;
import org.teavm.backend.c.generate.CodeWriter;
import org.teavm.backend.c.generate.IncludeManager; import org.teavm.backend.c.generate.IncludeManager;
import org.teavm.interop.c.Include; import org.teavm.interop.c.Include;
import org.teavm.interop.c.Name; import org.teavm.interop.c.Name;
@ -33,8 +34,18 @@ public final class InteropUtil {
return cls.getAnnotations().get(Native.class.getName()) != null; return cls.getAnnotations().get(Native.class.getName()) != null;
} }
public static void printNativeReference(CodeWriter writer, ClassReader cls) {
AnnotationReader annot = cls.getAnnotations().get(Native.class.getName());
if (annot != null) {
AnnotationValue fieldValue = annot.getValue("structKeyword");
if (fieldValue != null && fieldValue.getBoolean()) {
writer.print("struct ");
}
}
writer.print(getNativeName(cls));
}
public static String getNativeName(ClassReader cls) { private static String getNativeName(ClassReader cls) {
AnnotationReader nameAnnot = cls.getAnnotations().get(Name.class.getName()); AnnotationReader nameAnnot = cls.getAnnotations().get(Name.class.getName());
if (nameAnnot != null) { if (nameAnnot != null) {
return nameAnnot.getValue("value").getString(); return nameAnnot.getValue("value").getString();

View File

@ -23,4 +23,5 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
public @interface Native { public @interface Native {
boolean structKeyword() default false;
} }