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());
writer.print("TEAVM_FIELD(");
qualified.acceptVisitor(this);
writer.print(", ");
if (cls != null && isNative(cls)) {
InteropUtil.processInclude(cls.getAnnotations(), includes);
writer.print(", ").print(InteropUtil.getNativeName(cls))
.print(", ").print(InteropUtil.getNativeName(cls, field.getFieldName()));
InteropUtil.printNativeReference(writer, cls);
writer.print(", ").print(InteropUtil.getNativeName(cls, field.getFieldName()));
} else {
includes.includeClass(field.getClassName());
writer.print(", ").print(names.forClass(field.getClassName()))
.print(", ").print(names.forMemberField(field));
writer.print(names.forClass(field.getClassName())).print(", ").print(names.forMemberField(field));
}
writer.print(")");
} else {

View File

@ -15,6 +15,8 @@
*/
package org.teavm.backend.c.generate;
import org.teavm.backend.c.util.InteropUtil;
import org.teavm.model.ClassReader;
import org.teavm.model.ValueType;
public final class CodeGeneratorUtil {
@ -99,4 +101,14 @@ public final class CodeGeneratorUtil {
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;
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.InteropUtil;
import org.teavm.interop.Address;
import org.teavm.model.ClassReader;
import org.teavm.model.MethodReference;
@ -175,19 +175,17 @@ public class AddressIntrinsic implements Intrinsic {
invocation.getArguments().get(1));
context.emit(invocation.getArguments().get(2));
String structureName;
ClassReader cls = className != null ? context.classes().get(className) : null;
if (cls != null && InteropUtil.isNative(cls)) {
structureName = InteropUtil.getNativeName(cls);
InteropUtil.processInclude(cls.getAnnotations(), context.includes());
} else if (className != null) {
structureName = context.names().forClass(className);
context.includes().includeClass(className);
context.writer().print(" * sizeof(");
if (className != null) {
ClassReader cls = className != null ? context.classes().get(className) : null;
CodeGeneratorUtil.printClassReference(context.writer(), context.includes(),
context.names(), cls, className);
} else {
structureName = "**";
context.writer().print("**");
}
context.writer().print(" * sizeof(").print(structureName).print(")");
context.writer().print(")");
context.writer().print(")");
}
break;

View File

@ -15,10 +15,8 @@
*/
package org.teavm.backend.c.intrinsic;
import org.teavm.ast.ConstantExpr;
import org.teavm.ast.Expr;
import org.teavm.ast.InvocationExpr;
import org.teavm.backend.c.generate.StringPoolGenerator;
import org.teavm.interop.Strings;
import org.teavm.model.MethodReference;
@ -33,14 +31,9 @@ public class StringsIntrinsic implements Intrinsic {
switch (invocation.getMethod().getName()) {
case "toC": {
Expr arg = invocation.getArguments().get(0);
String literal = extractStringConstant(arg);
if (literal != null) {
StringPoolGenerator.generateSimpleStringLiteral(context.writer(), literal);
} else {
context.writer().print("teavm_stringToC(");
context.emit(arg);
context.writer().print(")");
}
context.writer().print("teavm_stringToC(");
context.emit(arg);
context.writer().print(")");
break;
}
case "fromC":
@ -50,13 +43,4 @@ public class StringsIntrinsic implements Intrinsic {
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;
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.InteropUtil;
import org.teavm.interop.Structure;
import org.teavm.model.ClassReader;
import org.teavm.model.MethodReference;
@ -64,7 +64,11 @@ public class StructureIntrinsic implements Intrinsic {
case "sizeOf": {
String className = ConstantUtil.getClassLiteral(context, invocation, invocation.getArguments().get(0));
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;
}
@ -72,15 +76,10 @@ public class StructureIntrinsic implements Intrinsic {
String className = ConstantUtil.getClassLiteral(context, invocation, invocation.getArguments().get(0));
if (className != null) {
ClassReader cls = context.classes().get(className);
String structureName;
if (InteropUtil.isNative(cls)) {
structureName = InteropUtil.getNativeName(cls);
InteropUtil.processInclude(cls.getAnnotations(), context.includes());
} else {
structureName = context.names().forClass(className);
context.includes().includeClass(className);
}
context.writer().print("TEAVM_STRUCTURE_ADD(").print(structureName).print(", ");
context.writer().print("TEAVM_STRUCTURE_ADD(");
CodeGeneratorUtil.printClassReference(context.writer(), context.includes(), context.names(), cls,
className);
context.writer().print(", ");
context.emit(invocation.getArguments().get(1));
context.writer().print(", ");
context.emit(invocation.getArguments().get(2));

View File

@ -15,6 +15,7 @@
*/
package org.teavm.backend.c.util;
import org.teavm.backend.c.generate.CodeWriter;
import org.teavm.backend.c.generate.IncludeManager;
import org.teavm.interop.c.Include;
import org.teavm.interop.c.Name;
@ -33,8 +34,18 @@ public final class InteropUtil {
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());
if (nameAnnot != null) {
return nameAnnot.getValue("value").getString();

View File

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