aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2015-03-05 07:14:04 +0100
committerSven Gothel <[email protected]>2015-03-05 07:14:04 +0100
commit72d3635279ffc8ad88e47dff9bbe95d211226d11 (patch)
tree62b3735680dfc5980a94afa14c56045bd082af24 /src/java/com/jogamp
parentdd2440cbadc642a561d8f92c502fe822b2f11762 (diff)
Bug 1134 - Enhance GlueGen Compiler: Minimal GL Header Changes _and_ Typesafety
- We shall be able to import 'most' vanilla GL header, i.e. only change the typedef part using our GlueGen types - Type Safety: - GlueGen now detects '#define' and 'enum' redefines and throw an exception in this case. This helps detecting wrongly renamed GL extensions into core! - GlueGen now detects function redefines (overloading) and throw an exception in this case. Hence the semantics of duplicate functions has to be equal! This helps detecting wrongly renamed GL extensions into core! - Semantic equality for all types is provided via interface TypeComparator.SemanticEqualityOp, i.e. 'boolean equalSemantics(..)' implemented by com.jogamp.gluegen.cgram.types.Type. Semantic equality can be relaxed via config "RelaxedEqualSemanticsTest true", i.e. ignoring integer size, and const / volatile qualifiers. - All equality/hash methods of 'com.jogamp.gluegen.cgram.types.*' are restructured. - Track and simplify renamed 'symbol', i.e. use a common sub-interface for all renamed symbols (ConstantDefinition, FunctionSymbol, ..) - This is provided in a unified manner via interface com.jogamp.gluegen.cgram.types.AliasedSymbol and its common implementation AliasedSymbolImpl - All JavaConfiguration.shouldIgnore* methods operate w/ 'AliasedSymbol' trying to match all aliases. - Support 'struct NAME [ { ... } ]' w/o typedef's - New GL / CL headers do not use typedef's for anonymous opaque types - Opaque Type handling - JavaConfiguration.typeInfo(..), identifying opaque types, no more back references from target-type -> typedef. Hence the following is possible now: typedef void * Opaque01; // Opaque typedef void * APointerBuffer; // A Buffer - All Logger instances are no more static and derive their warning level from the package's root Logger via Logging.getLogger(..).
Diffstat (limited to 'src/java/com/jogamp')
-rw-r--r--src/java/com/jogamp/gluegen/CMethodBindingEmitter.java130
-rw-r--r--src/java/com/jogamp/gluegen/ConstantDefinition.java153
-rw-r--r--src/java/com/jogamp/gluegen/DebugEmitter.java25
-rw-r--r--src/java/com/jogamp/gluegen/FunctionEmitter.java13
-rw-r--r--src/java/com/jogamp/gluegen/GlueEmitter.java7
-rw-r--r--src/java/com/jogamp/gluegen/GlueGen.java103
-rw-r--r--src/java/com/jogamp/gluegen/JavaConfiguration.java327
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java256
-rw-r--r--src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java43
-rw-r--r--src/java/com/jogamp/gluegen/JavaType.java79
-rw-r--r--src/java/com/jogamp/gluegen/Logging.java32
-rw-r--r--src/java/com/jogamp/gluegen/MethodBinding.java32
-rw-r--r--src/java/com/jogamp/gluegen/ReferencedStructs.java2
-rw-r--r--src/java/com/jogamp/gluegen/TypeConfig.java52
-rw-r--r--src/java/com/jogamp/gluegen/TypeInfo.java2
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/AliasedSymbol.java154
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/ArrayType.java44
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/BitType.java39
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/CompoundType.java151
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/DoubleType.java29
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/EnumType.java89
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/Field.java33
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/FloatType.java25
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/FunctionSymbol.java60
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/FunctionType.java42
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/IntType.java38
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java4
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/PointerType.java96
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/SizeThunk.java141
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/StructType.java11
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/Type.java225
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/TypeComparator.java143
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/TypeDictionary.java35
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/UnionType.java11
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/VoidType.java20
-rw-r--r--src/java/com/jogamp/gluegen/pcpp/PCPP.java6
-rw-r--r--src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java14
37 files changed, 1965 insertions, 701 deletions
diff --git a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
index 93a1ecc..734f536 100644
--- a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
@@ -51,13 +51,14 @@ import java.util.logging.Logger;
/** Emits the C-side component of the Java<->C JNI binding. */
public class CMethodBindingEmitter extends FunctionEmitter {
- protected static final Logger LOG = Logger.getLogger(CMethodBindingEmitter.class.getPackage().getName());
protected static final CommentEmitter defaultCommentEmitter = new DefaultCommentEmitter();
protected static final String arrayResLength = "_array_res_length";
protected static final String arrayRes = "_array_res";
protected static final String arrayIdx = "_array_idx";
+ protected final Logger LOG;
+
protected MethodBinding binding;
/** Name of the package in which the corresponding Java method resides.*/
@@ -124,9 +125,11 @@ public class CMethodBindingEmitter extends FunctionEmitter {
final boolean isJavaMethodStatic,
final boolean forImplementingMethodCall,
final boolean forIndirectBufferAndArrayImplementation,
- final MachineDataInfo machDesc)
+ final MachineDataInfo machDesc,
+ final JavaConfiguration configuration)
{
- super(output, false);
+ super(output, false, configuration);
+ LOG = Logging.getLogger(CMethodBindingEmitter.class.getPackage().getName());
assert(binding != null);
assert(javaClassName != null);
@@ -152,6 +155,11 @@ public class CMethodBindingEmitter extends FunctionEmitter {
return binding.getName();
}
+ @Override
+ public FunctionSymbol getCSymbol() {
+ return binding.getCSymbol();
+ }
+
/**
* Get the expression for the capacity of the returned java.nio.Buffer.
*/
@@ -451,7 +459,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
if (!cReturnType.isVoid()) {
writer.print(" ");
// Note we must respect const/volatile for return argument
- writer.print(binding.getCSymbol().getReturnType().getName(true));
+ writer.print(binding.getCSymbol().getReturnType().getCName(true));
writer.println(" _res;");
if (javaReturnType.isNIOByteBufferArray() ||
javaReturnType.isArrayOfCompoundTypeWrappers()) {
@@ -569,7 +577,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
writer.println(" if ( NULL != " + javaArgName + " ) {");
final Type cArgType = binding.getCArgumentType(i);
- String cArgTypeName = cArgType.getName();
+ String cArgTypeName = cArgType.getCName();
final String convName = pointerConversionArgumentName(javaArgName);
@@ -654,7 +662,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
emitMalloc(
writer,
convName+"_copy",
- cArgElementType.getName(),
+ cArgElementType.getCName(),
isBaseTypeConst(cArgType),
arrayLenName,
"Could not allocate buffer for copying data in argument \\\""+javaArgName+"\\\"");
@@ -692,7 +700,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
in the method binding. */
emitGetDirectBufferAddress(writer,
"_tmpObj",
- cArgElementType.getName(),
+ cArgElementType.getCName(),
convName + "_copy[_copyIndex]",
true,
"_offsetHandle[_copyIndex]", true);
@@ -702,7 +710,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
// offset argument
emitGetDirectBufferAddress(writer,
"_tmpObj",
- cArgElementType.getName(),
+ cArgElementType.getCName(),
"("+convName + "_copy + _copyIndex)",
false /* !receivingIsPtrPtr -> linear layout -> use memcpy */,
null, true);
@@ -719,13 +727,13 @@ public class CMethodBindingEmitter extends FunctionEmitter {
emitMalloc(
writer,
convName+"_copy[_copyIndex]",
- cArgElementType2.getName(), // assumes cArgPtrType is ptr-to-ptr-to-primitive !!
+ cArgElementType2.getCName(), // assumes cArgPtrType is ptr-to-ptr-to-primitive !!
isBaseTypeConst(cArgType),
"(*env)->GetArrayLength(env, _tmpObj)",
"Could not allocate buffer during copying of data in argument \\\""+javaArgName+"\\\"");
// FIXME: copy the data (use matched Get/ReleasePrimitiveArrayCritical() calls)
if (true) {
- throw new RuntimeException("Cannot yet handle type \"" + cArgType.getName() +
+ throw new RuntimeException("Cannot yet handle type \"" + cArgType.getCName() +
"\"; need to add support for copying ptr-to-ptr-to-primitiveType subarrays");
}
@@ -804,7 +812,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
writer.println(" _tmpObj = (*env)->GetObjectArrayElement(env, " + javaArgName + ", _copyIndex);");
emitReturnDirectBufferAddress(writer,
"_tmpObj",
- cArgType.asArray().getBaseElementType().getName(),
+ cArgType.asArray().getBaseElementType().getCName(),
"("+convName + "_copy + _copyIndex)",
false /* receivingIsPtrPtr */,
null);
@@ -855,7 +863,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
writer.println(");");
} else {
if (true) throw new RuntimeException(
- "Cannot yet handle type \"" + cArgType.getName() +
+ "Cannot yet handle type \"" + cArgType.getCName() +
"\"; need to add support for cleaning up copied ptr-to-ptr-to-primitiveType subarrays");
}
writer.println(" }");
@@ -927,7 +935,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
}
}
- writer.print(cArgType.getName());
+ writer.print(cArgType.getCName());
writer.print(") ");
if (cArgType.isPointer() && javaArgType.isPrimitive()) {
writer.print("(intptr_t) ");
@@ -1020,7 +1028,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
if (returnValueCapacityExpression != null) {
returnSizeOf = returnValueCapacityExpression.format(argumentNameArray());
} else {
- returnSizeOf = "sizeof(" + cReturnType.getName() + ")";
+ returnSizeOf = "sizeof(" + cReturnType.getCName() + ")";
}
writer.println(" return JVMUtil_NewDirectByteBufferCopy(env, &_res, "+returnSizeOf+");");
} else if (javaReturnType.isNIOBuffer() || javaReturnType.isCompoundTypeWrapper()) {
@@ -1029,27 +1037,66 @@ public class CMethodBindingEmitter extends FunctionEmitter {
// See whether capacity has been specified
if (returnValueCapacityExpression != null) {
- writer.print( returnValueCapacityExpression.format( argumentNameArray() ) );
+ writer.println( returnValueCapacityExpression.format( argumentNameArray() ) + ");");
} else {
- if (cReturnType.isPointer() &&
- cReturnType.asPointer().getTargetType().isCompound()) {
- if (cReturnType.asPointer().getTargetType().getSize() == null) {
- throw new RuntimeException(
- "Error emitting code for compound return type "+
- "for function \"" + binding + "\": " +
- "Structs to be emitted should have been laid out by this point " +
- "(type " + cReturnType.asPointer().getTargetType().getName() + " / " +
- cReturnType.asPointer().getTargetType() + " was not) for "+binding
- );
+ final Type cReturnTargetType = cReturnType.isPointer() ? cReturnType.getTargetType() : null;
+ int mode = 0;
+ if ( 1 == cReturnType.pointerDepth() && null != cReturnTargetType ) {
+ if( cReturnTargetType.isCompound() ) {
+ if( !cReturnTargetType.isAnonymous() &&
+ cReturnTargetType.asCompound().getNumFields() > 0 )
+ {
+ // fully declared non-anonymous struct pointer: pass content
+ if ( cReturnTargetType.getSize() == null ) {
+ throw new RuntimeException(
+ "Error emitting code for compound return type "+
+ "for function \"" + binding + "\": " +
+ "Structs to be emitted should have been laid out by this point " +
+ "(type " + cReturnTargetType.getCName() + " / " +
+ cReturnTargetType.getDebugString() + " was not) for "+binding
+ );
+ }
+ writer.println("sizeof(" + cReturnTargetType.getCName() + ") );");
+ mode = 10;
+ } else if( cReturnTargetType.asCompound().getNumFields() == 0 ) {
+ // anonymous struct pointer: pass pointer
+ writer.println("sizeof(" + cReturnType.getCName() + ") );");
+ mode = 11;
+ }
+ }
+ if( 0 == mode ) {
+ if( cReturnTargetType.isPrimitive() ) {
+ // primitive pointer: pass primitive
+ writer.println("sizeof(" + cReturnTargetType.getCName() + ") );");
+ mode = 20;
+ } else if( cReturnTargetType.isVoid() ) {
+ // void pointer: pass pointer
+ writer.println("sizeof(" + cReturnType.getCName() + ") );");
+ mode = 21;
+ }
+ }
+ }
+ if( 0 == mode ) {
+ if( null != cfg.typeInfo(cReturnType) ) {
+ // Opaque
+ writer.println("sizeof(" + cReturnType.getCName() + ") );");
+ mode = 88;
+ } else {
+ final String wmsg = "Assumed return size of equivalent C return type";
+ writer.println("sizeof(" + cReturnType.getCName() + ") ); // WARNING: "+wmsg);
+ mode = 99;
+ LOG.warning(
+ "No capacity specified for java.nio.Buffer return " +
+ "value for function \"" + binding.getName() + "\". " + wmsg + " (sizeof(" + cReturnType.getCName() + ")): " + binding);
}
}
- writer.print("sizeof(" + cReturnType.getName() + ")");
- LOG.warning(
- "No capacity specified for java.nio.Buffer return " +
- "value for function \"" + binding.getName() + "\"" +
- " assuming size of equivalent C return type (sizeof(" + cReturnType.getName() + ")): " + binding);
+ writer.println(" /** ");
+ writer.println(" * mode: "+mode);
+ writer.println(" * cReturnType: "+cReturnType.getDebugString());
+ writer.println(" * cReturnTargetType: "+cReturnTargetType.getDebugString());
+ writer.println(" * javaReturnType: "+javaReturnType.getDebugString());
+ writer.println(" */");
}
- writer.println(");");
} else if (javaReturnType.isString()) {
writer.println(" if (NULL == _res) return NULL;");
writer.println(" return (*env)->NewStringUTF(env, _res);");
@@ -1071,7 +1118,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
pointerType = retType.asArray().getBaseElementType();
}
writer.println(" (*env)->SetObjectArrayElement(env, " + arrayRes + ", " + arrayIdx +
- ", (*env)->NewDirectByteBuffer(env, (void *)_res[" + arrayIdx + "], sizeof(" + pointerType.getName() + ")));");
+ ", (*env)->NewDirectByteBuffer(env, (void *)_res[" + arrayIdx + "], sizeof(" + pointerType.getCName() + ")));");
writer.println(" }");
writer.println(" return " + arrayRes + ";");
} else if (javaReturnType.isArray()) {
@@ -1386,33 +1433,34 @@ public class CMethodBindingEmitter extends FunctionEmitter {
// Note that we don't need to obey const/volatile for outgoing arguments
//
if (javaType.isNIOBuffer()) {
- ptrTypeString = cType.getName();
+ // primitive NIO object
+ ptrTypeString = cType.getCName();
} else if (javaType.isArray() || javaType.isArrayOfCompoundTypeWrappers()) {
needsDataCopy = javaArgTypeNeedsDataCopy(javaType);
if (javaType.isPrimitiveArray() ||
javaType.isNIOBufferArray() ||
javaType.isArrayOfCompoundTypeWrappers()) {
- ptrTypeString = cType.getName();
+ ptrTypeString = cType.getCName();
} else if (!javaType.isStringArray()) {
final Class<?> elementType = javaType.getJavaClass().getComponentType();
if (elementType.isArray()) {
final Class<?> subElementType = elementType.getComponentType();
if (subElementType.isPrimitive()) {
// type is pointer to pointer to primitive
- ptrTypeString = cType.getName();
+ ptrTypeString = cType.getCName();
} else {
// type is pointer to pointer of some type we don't support (maybe
// it's an array of pointers to structs?)
- throw new RuntimeException("Unsupported pointer type: \"" + cType.getName() + "\"");
+ throw new RuntimeException("Unsupported pointer type: \"" + cType.getCName() + "\"");
}
} else {
// type is pointer to pointer of some type we don't support (maybe
// it's an array of pointers to structs?)
- throw new RuntimeException("Unsupported pointer type: \"" + cType.getName() + "\"");
+ throw new RuntimeException("Unsupported pointer type: \"" + cType.getCName() + "\"");
}
}
} else {
- ptrTypeString = cType.getName();
+ ptrTypeString = cType.getCName();
}
writer.print(" ");
@@ -1434,7 +1482,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
String cElementTypeName = "char *";
final PointerType cPtrType = cType.asPointer();
if (cPtrType != null) {
- cElementTypeName = cPtrType.getTargetType().asPointer().getName();
+ cElementTypeName = cPtrType.getTargetType().asPointer().getCName();
}
if (isBaseTypeConst(cType)) {
writer.print("const ");
@@ -1470,9 +1518,9 @@ public class CMethodBindingEmitter extends FunctionEmitter {
final String cVariableType;
if( !cType.isPointer() && type.isCompoundTypeWrapper() ) { // FIXME: Compound call-by-value
- cVariableType = cType.getName()+" *";
+ cVariableType = cType.getCName()+" *";
} else {
- cVariableType = cType.getName();
+ cVariableType = cType.getCName();
}
emitGetDirectBufferAddress(writer,
incomingArgumentName,
diff --git a/src/java/com/jogamp/gluegen/ConstantDefinition.java b/src/java/com/jogamp/gluegen/ConstantDefinition.java
index ca67001..78d2e43 100644
--- a/src/java/com/jogamp/gluegen/ConstantDefinition.java
+++ b/src/java/com/jogamp/gluegen/ConstantDefinition.java
@@ -33,100 +33,131 @@
package com.jogamp.gluegen;
-import java.util.*;
+import com.jogamp.gluegen.cgram.types.AliasedSymbol.AliasedSymbolImpl;
+import com.jogamp.gluegen.cgram.types.TypeComparator.AliasedSemanticSymbol;
+import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
/** Represents the definition of a constant which was provided either
via a #define statement or through an enum definition. */
-public class ConstantDefinition {
-
- private final String origName;
- private final HashSet<String> aliasedNames;
- private String name;
- private final String value;
+public class ConstantDefinition extends AliasedSymbolImpl implements AliasedSemanticSymbol {
+ private final boolean relaxedEqSem;
+ private final String sValue;
+ private final long iValue;
+ private final boolean hasIntValue;
private final boolean isEnum;
private final String enumName;
- private Set<String> aliases;
+ /** Covering enums */
public ConstantDefinition(final String name,
- final String value,
- final boolean isEnum,
+ final long value,
final String enumName) {
- this.origName = name;
- this.name = name;
- this.value = value;
- this.isEnum = isEnum;
+ super(name);
+ this.relaxedEqSem = TypeConfig.relaxedEqualSemanticsTest();
+ this.sValue = String.valueOf(value);
+ this.iValue = value;
+ this.hasIntValue = true;
+ this.isEnum = true;
this.enumName = enumName;
- this.aliasedNames=new HashSet<String>();
- }
-
- public boolean equals(final ConstantDefinition other) {
- return (equals(name, other.name) &&
- equals(value, other.value) &&
- equals(enumName, other.enumName));
}
- private boolean equals(final String s1, final String s2) {
- if (s1 == null || s2 == null) {
- if (s1 == null && s2 == null) {
- return true;
+ /** Covering defines */
+ public ConstantDefinition(final String name,
+ final String value) {
+ super(name);
+ this.relaxedEqSem = TypeConfig.relaxedEqualSemanticsTest();
+ this.sValue = value;
+ {
+ // Attempt to parse define string as number
+ long v;
+ boolean b;
+ try {
+ v = Long.decode(value).longValue();
+ b = true;
+ } catch (final NumberFormatException e) {
+ v = 0;
+ b = false;
}
- return false;
+ this.iValue = v;
+ this.hasIntValue = b;
}
-
- return s1.equals(s2);
+ this.isEnum = false;
+ this.enumName = null;
}
+ /**
+ * Hash by its given {@link #getName() name}.
+ */
@Override
- public int hashCode() {
- return name.hashCode();
- }
-
- /** Supports renaming in Java binding. */
- public void rename(final String name) {
- if(null!=name) {
- this.name = name;
- aliasedNames.add(origName);
- }
+ public final int hashCode() {
+ return getName().hashCode();
}
- public void addAliasedName(final String name) {
- aliasedNames.add(name);
- }
- public Collection<String> getAliasedNames() {
- return aliasedNames;
+ /**
+ * Equality test by its given {@link #getName() name}.
+ */
+ @Override
+ public final boolean equals(final Object arg) {
+ if (arg == this) {
+ return true;
+ } else if ( !(arg instanceof ConstantDefinition) ) {
+ return false;
+ } else {
+ final ConstantDefinition t = (ConstantDefinition)arg;
+ return equals(getName(), t.getName());
+ }
}
- public String getOrigName() {
- return origName;
+ @Override
+ public final int hashCodeSemantics() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + ( null != getName() ? getName().hashCode() : 0 );
+ hash = ((hash << 5) - hash) + ( null != sValue ? sValue.hashCode() : 0 );
+ return ((hash << 5) - hash) + ( null != enumName ? enumName.hashCode() : 0 );
}
- public String getName() {
- return name;
+ @Override
+ public final boolean equalSemantics(final SemanticEqualityOp arg) {
+ if (arg == this) {
+ return true;
+ } else if ( !(arg instanceof ConstantDefinition) ) {
+ return false;
+ } else {
+ final ConstantDefinition t = (ConstantDefinition) arg;
+ if( !equals(getName(), t.getName()) ||
+ !equals(enumName, t.enumName) ) {
+ return false;
+ }
+ if( hasIntValue ) {
+ return iValue == t.iValue;
+ } else {
+ // define's string value may be semantical equal .. but formatted differently!
+ return relaxedEqSem || equals(sValue, t.sValue);
+ }
+ }
}
- public String getValue() { return value; }
+ public String getValue() { return sValue; }
/** Returns null if this definition was not part of an
enumeration, or if the enum was anonymous. */
public String getEnumName() { return enumName; }
public boolean isEnum() { return isEnum; }
- public Set<String> getAliases() {
- return aliases;
+ @Override
+ public String toString() {
+ return "ConstantDefinition [name " + getName()
+ + ", value " + sValue + " (isInt " + hasIntValue
+ + "), enumName " + enumName + ", isEnum " + isEnum + "]";
}
- public void addAlias(final String alias) {
- if (aliases == null) {
- aliases = new LinkedHashSet<String>();
+ private static boolean equals(final String s1, final String s2) {
+ if (s1 == null || s2 == null) {
+ if (s1 == null && s2 == null) {
+ return true;
+ }
+ return false;
}
- aliases.add(alias);
- }
- @Override
- public String toString() {
- return "ConstantDefinition [name " + name + " origName " + origName + " value " + value
- + " aliasedNames " + aliasedNames + " aliases " + aliases
- + " enumName " + enumName + " isEnum " + isEnum + "]";
+ return s1.equals(s2);
}
-
}
diff --git a/src/java/com/jogamp/gluegen/DebugEmitter.java b/src/java/com/jogamp/gluegen/DebugEmitter.java
index 6381c8c..582a1d7 100644
--- a/src/java/com/jogamp/gluegen/DebugEmitter.java
+++ b/src/java/com/jogamp/gluegen/DebugEmitter.java
@@ -39,6 +39,7 @@
package com.jogamp.gluegen;
+import java.io.IOException;
import java.util.*;
import com.jogamp.gluegen.cgram.types.*;
@@ -46,9 +47,16 @@ import com.jogamp.gluegen.cgram.types.*;
/** Debug emitter which prints the parsing results to standard output. */
public class DebugEmitter implements GlueEmitter {
+ protected JavaConfiguration cfg;
@Override
- public void readConfigurationFile(final String filename) {}
+ public void readConfigurationFile(final String filename) throws IOException {
+ cfg = createConfig();
+ cfg.read(filename);
+ }
+
+ @Override
+ public JavaConfiguration getConfiguration() { return cfg; }
@Override
public void beginEmission(final GlueEmitterControls controls) {
@@ -110,10 +118,10 @@ public class DebugEmitter implements GlueEmitter {
}
@Override
- public void emitStruct(final CompoundType t, final String alternateName) {
+ public void emitStruct(final CompoundType t, final Type typedefType) {
String name = t.getName();
- if (name == null && alternateName != null) {
- name = alternateName;
+ if (name == null && typedefType != null) {
+ name = typedefType.getName();
}
System.out.println("Referenced type \"" + name + "\"");
@@ -121,4 +129,13 @@ public class DebugEmitter implements GlueEmitter {
@Override
public void endStructs() {}
+
+ /**
+ * Create the object that will read and store configuration information for
+ * this JavaEmitter.
+ */
+ protected JavaConfiguration createConfig() {
+ return new JavaConfiguration();
+ }
+
}
diff --git a/src/java/com/jogamp/gluegen/FunctionEmitter.java b/src/java/com/jogamp/gluegen/FunctionEmitter.java
index 8e9d306..5655e0e 100644
--- a/src/java/com/jogamp/gluegen/FunctionEmitter.java
+++ b/src/java/com/jogamp/gluegen/FunctionEmitter.java
@@ -42,6 +42,7 @@ package com.jogamp.gluegen;
import java.util.*;
import java.io.*;
+import com.jogamp.gluegen.cgram.types.FunctionSymbol;
import com.jogamp.gluegen.cgram.types.Type;
public abstract class FunctionEmitter {
@@ -52,25 +53,29 @@ public abstract class FunctionEmitter {
private final ArrayList<EmissionModifier> modifiers;
private CommentEmitter commentEmitter = null;
private final PrintWriter defaultOutput;
+ // Only present to provide more clear comments
+ protected final JavaConfiguration cfg;
/**
* Constructs the FunctionEmitter with a CommentEmitter that emits nothing.
*/
- public FunctionEmitter(final PrintWriter defaultOutput, final boolean isInterface) {
+ public FunctionEmitter(final PrintWriter defaultOutput, final boolean isInterface, final JavaConfiguration configuration) {
assert(defaultOutput != null);
+ this.isInterfaceVal = isInterface;
this.modifiers = new ArrayList<EmissionModifier>();
this.defaultOutput = defaultOutput;
- this.isInterfaceVal = isInterface;
+ this.cfg = configuration;
}
/**
* Makes this FunctionEmitter a copy of the passed one.
*/
public FunctionEmitter(final FunctionEmitter arg) {
+ isInterfaceVal = arg.isInterfaceVal;
modifiers = new ArrayList<EmissionModifier>(arg.modifiers);
commentEmitter = arg.commentEmitter;
defaultOutput = arg.defaultOutput;
- isInterfaceVal = arg.isInterfaceVal;
+ cfg = arg.cfg;
}
public boolean isInterface() { return isInterfaceVal; }
@@ -113,6 +118,8 @@ public abstract class FunctionEmitter {
public abstract String getName();
+ public abstract FunctionSymbol getCSymbol();
+
/**
* Emit the function to the specified output (instead of the default
* output).
diff --git a/src/java/com/jogamp/gluegen/GlueEmitter.java b/src/java/com/jogamp/gluegen/GlueEmitter.java
index bb46cf5..0e8d61f 100644
--- a/src/java/com/jogamp/gluegen/GlueEmitter.java
+++ b/src/java/com/jogamp/gluegen/GlueEmitter.java
@@ -50,6 +50,7 @@ import com.jogamp.gluegen.cgram.types.*;
public interface GlueEmitter {
public void readConfigurationFile(String filename) throws Exception;
+ public JavaConfiguration getConfiguration();
/**
* Begin the emission of glue code. This might include opening files,
@@ -91,11 +92,11 @@ public interface GlueEmitter {
public void beginStructs(TypeDictionary typedefDictionary,
TypeDictionary structDictionary,
Map<Type, Type> canonMap) throws Exception;
- /** Emit glue code for the given CompoundType. alternateName is
+ /** Emit glue code for the given CompoundType. typedefType is
provided when the CompoundType (e.g. "struct foo_t") has not
been typedefed to anything but the type of "pointer to struct
foo_t" has (e.g. "typedef struct foo_t {} *Foo"); in this case
- alternateName would be set to Foo. */
- public void emitStruct(CompoundType t, String alternateName) throws Exception;
+ typedefType would be set to pointer type Foo. */
+ public void emitStruct(CompoundType t, Type typedefType) throws Exception;
public void endStructs() throws Exception;
}
diff --git a/src/java/com/jogamp/gluegen/GlueGen.java b/src/java/com/jogamp/gluegen/GlueGen.java
index e123910..6428469 100644
--- a/src/java/com/jogamp/gluegen/GlueGen.java
+++ b/src/java/com/jogamp/gluegen/GlueGen.java
@@ -43,8 +43,10 @@ import com.jogamp.common.GlueGenVersion;
import java.io.*;
import java.util.*;
+import java.util.logging.Level;
import antlr.*;
+
import com.jogamp.gluegen.cgram.*;
import com.jogamp.gluegen.cgram.types.*;
import com.jogamp.gluegen.pcpp.*;
@@ -64,8 +66,8 @@ public class GlueGen implements GlueEmitterControls {
private PCPP preprocessor;
// State for SymbolFilters
- private List<ConstantDefinition> constants;
- private List<FunctionSymbol> functions;
+ private List<ConstantDefinition> allConstants;
+ private List<FunctionSymbol> allFunctions;
private static boolean debug = false;
@@ -83,14 +85,14 @@ public class GlueGen implements GlueEmitterControls {
@Override
public void runSymbolFilter(final SymbolFilter filter) {
- filter.filterSymbols(constants, functions);
+ filter.filterSymbols(allConstants, allFunctions);
final List<ConstantDefinition> newConstants = filter.getConstants();
final List<FunctionSymbol> newFunctions = filter.getFunctions();
if (newConstants != null) {
- constants = newConstants;
+ allConstants = newConstants;
}
if (newFunctions != null) {
- functions = newFunctions;
+ allFunctions = newFunctions;
}
}
@@ -99,6 +101,25 @@ public class GlueGen implements GlueEmitterControls {
public void run(final Reader reader, final String filename, final Class<?> emitterClass, final List<String> includePaths, final List<String> cfgFiles, final String outputRootDir, final boolean copyPCPPOutput2Stderr) {
try {
+ if(debug) {
+ Logging.getLogger().setLevel(Level.ALL);
+ }
+ final GlueEmitter emit;
+ if (emitterClass == null) {
+ emit = new JavaEmitter();
+ } else {
+ try {
+ emit = (GlueEmitter) emitterClass.newInstance();
+ } catch (final Exception e) {
+ throw new RuntimeException("Exception occurred while instantiating emitter class.", e);
+ }
+ }
+
+ for (final String config : cfgFiles) {
+ emit.readConfigurationFile(config);
+ }
+ final JavaConfiguration cfg = emit.getConfiguration();
+
final File out = File.createTempFile("PCPPTemp", ".pcpp");
final FileOutputStream outStream = new FileOutputStream(out);
@@ -115,6 +136,9 @@ public class GlueGen implements GlueEmitterControls {
preprocessor.run(reader, filename);
outStream.flush();
outStream.close();
+ if(debug) {
+ System.err.println("PCPP done");
+ }
final FileInputStream inStream = new FileInputStream(out);
final DataInputStream dis = new DataInputStream(inStream);
@@ -140,6 +164,7 @@ public class GlueGen implements GlueEmitterControls {
final HeaderParser headerParser = new HeaderParser();
headerParser.setDebug(debug);
+ headerParser.setJavaConfiguration(cfg);
final TypeDictionary td = new TypeDictionary();
headerParser.setTypedefDictionary(td);
final TypeDictionary sd = new TypeDictionary();
@@ -162,21 +187,6 @@ public class GlueGen implements GlueEmitterControls {
// generate glue code: the #defines to constants, the set of
// typedefs, and the set of functions.
- GlueEmitter emit = null;
- if (emitterClass == null) {
- emit = new JavaEmitter();
- } else {
- try {
- emit = (GlueEmitter) emitterClass.newInstance();
- } catch (final Exception e) {
- throw new RuntimeException("Exception occurred while instantiating emitter class.", e);
- }
- }
-
- for (final String config : cfgFiles) {
- emit.readConfigurationFile(config);
- }
-
if (null != outputRootDir && outputRootDir.trim().length() > 0) {
if (emit instanceof JavaEmitter) {
// FIXME: hack to interfere with the *Configuration setting via commandlines
@@ -189,7 +199,7 @@ public class GlueGen implements GlueEmitterControls {
// Repackage the enum and #define statements from the parser into a common format
// so that SymbolFilters can operate upon both identically
- constants = new ArrayList<ConstantDefinition>();
+ allConstants = new ArrayList<ConstantDefinition>();
for (final EnumType enumeration : headerParser.getEnums()) {
String enumName = enumeration.getName();
if (enumName.equals("<anonymous>")) {
@@ -198,32 +208,56 @@ public class GlueGen implements GlueEmitterControls {
// iterate over all values in the enumeration
for (int i = 0; i < enumeration.getNumEnumerates(); ++i) {
final String enumElementName = enumeration.getEnumName(i);
- final String value = String.valueOf(enumeration.getEnumValue(i));
- constants.add(new ConstantDefinition(enumElementName, value, true, enumName));
+ allConstants.add(new ConstantDefinition(enumElementName, enumeration.getEnumValue(i), enumName));
}
}
for (final Object elem : lexer.getDefines()) {
final Define def = (Define) elem;
- constants.add(new ConstantDefinition(def.getName(), def.getValue(), false, null));
+ allConstants.add(new ConstantDefinition(def.getName(), def.getValue()));
}
- functions = headerParser.getParsedFunctions();
+ allFunctions = headerParser.getParsedFunctions();
- // begin emission of glue code
+ // begin emission of glue code,
+ // incl. firing up 'runSymbolFilter(SymbolFilter)' calls, which:
+ // - filters all ConstantDefinition
+ // - filters all FunctionSymbol
emit.beginEmission(this);
+ if( debug() ) {
+ int i=0;
+ System.err.println("Filtered Constants: "+allConstants.size());
+ for (final ConstantDefinition def : allConstants) {
+ if( debug() ) {
+ System.err.println("Filtered ["+i+"]: "+def.getAliasedString());
+ i++;
+ }
+ }
+ i=0;
+ System.err.println("Filtered Functions: "+allFunctions.size());
+ for (final FunctionSymbol cFunc : allFunctions) {
+ System.err.println("Filtered ["+i+"]: "+cFunc.getAliasedString());
+ i++;
+ }
+ }
+
emit.beginDefines();
final Set<String> emittedDefines = new HashSet<String>(100);
// emit java equivalent of enum { ... } statements
final StringBuilder comment = new StringBuilder();
- for (final ConstantDefinition def : constants) {
+ for (final ConstantDefinition def : allConstants) {
if (!emittedDefines.contains(def.getName())) {
emittedDefines.add(def.getName());
- final Set<String> aliases = def.getAliases();
- if (aliases != null) {
+ final Set<String> aliases = cfg.getAliasedDocNames(def);
+ if (aliases != null && aliases.size() > 0 ) {
+ int i=0;
comment.append("Alias for: <code>");
for (final String alias : aliases) {
- comment.append(" ").append(alias);
+ if(0 < i) {
+ comment.append("</code>, <code>");
+ }
+ comment.append(alias);
+ i++;
}
comment.append("</code>");
}
@@ -249,7 +283,7 @@ public class GlueGen implements GlueEmitterControls {
// Iterate through the functions finding structs that are referenced in
// the function signatures; these will be remembered for later emission
final ReferencedStructs referencedStructs = new ReferencedStructs();
- for (final FunctionSymbol sym : functions) {
+ for (final FunctionSymbol sym : allFunctions) {
// FIXME: this doesn't take into account the possibility that some of
// the functions we send to emitMethodBindings() might not actually be
// emitted (e.g., if an Ignore directive in the JavaEmitter causes it
@@ -290,19 +324,20 @@ public class GlueGen implements GlueEmitterControls {
for (final Iterator<Type> iter = referencedStructs.results(); iter.hasNext();) {
final Type t = iter.next();
if (t.isCompound()) {
+ assert t.hasTypedefName() && t.getName() == null : "ReferencedStructs incorrectly recorded compound type " + t;
emit.emitStruct(t.asCompound(), null);
} else if (t.isPointer()) {
final PointerType p = t.asPointer();
final CompoundType c = p.getTargetType().asCompound();
- assert p.hasTypedefedName() && c.getName() == null : "ReferencedStructs incorrectly recorded pointer type " + p;
- emit.emitStruct(c, p.getName());
+ assert p.hasTypedefName() && c.getName() == null : "ReferencedStructs incorrectly recorded pointer type " + p;
+ emit.emitStruct(c, p);
}
}
emit.endStructs();
// emit java and C code to interface with the native functions
emit.beginFunctions(td, sd, headerParser.getCanonMap());
- emit.emitFunctions(functions);
+ emit.emitFunctions(allFunctions);
emit.endFunctions();
// end emission of glue code
diff --git a/src/java/com/jogamp/gluegen/JavaConfiguration.java b/src/java/com/jogamp/gluegen/JavaConfiguration.java
index 346920d..5eadf94 100644
--- a/src/java/com/jogamp/gluegen/JavaConfiguration.java
+++ b/src/java/com/jogamp/gluegen/JavaConfiguration.java
@@ -46,7 +46,6 @@ import com.jogamp.gluegen.JavaEmitter.MethodAccess;
import java.io.*;
import java.lang.reflect.Array;
import java.util.*;
-import java.util.Map.Entry;
import java.util.regex.*;
import com.jogamp.gluegen.jgram.*;
@@ -54,7 +53,6 @@ import com.jogamp.gluegen.cgram.types.*;
import java.util.logging.Logger;
-import jogamp.common.os.MachineDataInfoRuntime;
import static java.util.logging.Level.*;
import static com.jogamp.gluegen.JavaEmitter.MethodAccess.*;
import static com.jogamp.gluegen.JavaEmitter.EmissionStyle.*;
@@ -73,7 +71,7 @@ public class JavaConfiguration {
private String className;
private String implClassName;
- protected static final Logger LOG = Logger.getLogger(JavaConfiguration.class.getPackage().getName());
+ protected final Logger LOG;
public static String NEWLINE = System.getProperty("line.separator");
@@ -108,6 +106,13 @@ public class JavaConfiguration {
private boolean tagNativeBinding;
/**
+ * If true, {@link TypeConfig.SemanticEqualityOp#equalSemantics(TypeConfig.SemanticEqualityOp)}
+ * will attempt to perform a relaxed semantic equality test, e.g. skip the {@code const} and {@code volatile} qualifiers.
+ * Otherwise a full semantic equality test will be performed.
+ */
+ private boolean relaxedEqualSemanticsTest;
+
+ /**
* Style of code emission. Can emit everything into one class
* (AllStatic), separate interface and implementing classes
* (InterfaceAndImpl), only the interface (InterfaceOnly), or only
@@ -180,6 +185,10 @@ public class JavaConfiguration {
private final Map<String, List<String>> javaPrologues = new HashMap<String, List<String>>();
private final Map<String, List<String>> javaEpilogues = new HashMap<String, List<String>>();
+ public JavaConfiguration() {
+ LOG = Logging.getLogger(JavaConfiguration.class.getPackage().getName());
+ }
+
/** Reads the configuration file.
@param filename path to file that should be read
*/
@@ -317,6 +326,15 @@ public class JavaConfiguration {
return tagNativeBinding;
}
+ /**
+ * Returns whether {@link TypeConfig.SemanticEqualityOp#equalSemantics(TypeConfig.SemanticEqualityOp)}
+ * shall attempt to perform a relaxed semantic equality test, e.g. skip the {@code const} and {@code volatile} qualifier
+ * - or not.
+ */
+ public boolean relaxedEqualSemanticsTest() {
+ return relaxedEqualSemanticsTest;
+ }
+
/** Returns the code emission style (constants in JavaEmitter) parsed from the configuration file. */
public EmissionStyle emissionStyle() {
return emissionStyle;
@@ -361,12 +379,12 @@ public class JavaConfiguration {
/** If this type should be considered opaque, returns the TypeInfo
describing the replacement type. Returns null if this type
should not be considered opaque. */
- public TypeInfo typeInfo(Type type, final TypeDictionary typedefDictionary) {
+ public TypeInfo typeInfo(Type type) {
// Because typedefs of pointer types can show up at any point,
// walk the pointer chain looking for a typedef name that is in
// the TypeInfo map.
if (DEBUG_TYPE_INFO)
- System.err.println("Incoming type = " + type);
+ System.err.println("Incoming type = " + type + ", " + type.getDebugString());
final int pointerDepth = type.pointerDepth();
for (int i = 0; i <= pointerDepth; i++) {
String name = type.getName();
@@ -377,12 +395,13 @@ public class JavaConfiguration {
if (name != null) {
final TypeInfo info = closestTypeInfo(name, i + type.pointerDepth());
if (info != null) {
+ final TypeInfo res = promoteTypeInfo(info, i);
if (DEBUG_TYPE_INFO) {
- System.err.println(" info.name=" + info.name() + ", name=" + name +
+ System.err.println(" [1] info.name=" + info.name() + ", name=" + name +
", info.pointerDepth=" + info.pointerDepth() +
- ", type.pointerDepth=" + type.pointerDepth());
+ ", type.pointerDepth=" + type.pointerDepth() + " -> "+res);
}
- return promoteTypeInfo(info, i);
+ return res;
}
}
@@ -392,33 +411,13 @@ public class JavaConfiguration {
if (name != null) {
final TypeInfo info = closestTypeInfo(name, i + type.pointerDepth());
if (info != null) {
+ final TypeInfo res = promoteTypeInfo(info, i);
if (DEBUG_TYPE_INFO) {
- System.err.println(" info.name=" + info.name() + ", name=" + name +
- ", info.pointerDepth=" + info.pointerDepth() +
- ", type.pointerDepth=" + type.pointerDepth());
- }
- return promoteTypeInfo(info, i);
- }
- }
- }
-
- // Try all typedef names that map to this type
- final Set<Entry<String, Type>> entrySet = typedefDictionary.entrySet();
- for (final Map.Entry<String, Type> entry : entrySet) {
- // "eq" equality is OK to use here since all types have been canonicalized
- if (entry.getValue() == type) {
- name = entry.getKey();
- if (DEBUG_TYPE_INFO) {
- System.err.println("Looking under typedef name " + name);
- }
- final TypeInfo info = closestTypeInfo(name, i + type.pointerDepth());
- if (info != null) {
- if (DEBUG_TYPE_INFO) {
- System.err.println(" info.name=" + info.name() + ", name=" + name +
+ System.err.println(" [2] info.name=" + info.name() + ", name=" + name +
", info.pointerDepth=" + info.pointerDepth() +
- ", type.pointerDepth=" + type.pointerDepth());
+ ", type.pointerDepth=" + type.pointerDepth() + " -> "+res);
}
- return promoteTypeInfo(info, i);
+ return res;
}
}
}
@@ -427,7 +426,9 @@ public class JavaConfiguration {
type = type.asPointer().getTargetType();
}
}
-
+ if (DEBUG_TYPE_INFO) {
+ System.err.println(" [X] NULL");
+ }
return null;
}
@@ -782,120 +783,184 @@ public class JavaConfiguration {
}
/**
- * Returns true if this #define, function, struct, or field within
- * a struct should be ignored during glue code generation of interfaces and implementation.
+ * Returns true if the given struct, or field within a struct
+ * should be ignored during glue code generation of interfaces and implementation.
+ * For other types, use {@link #shouldIgnoreInInterface(AliasedSymbol)}.
+ * <p>
+ * This method only considers the {@link AliasedSymbol#getName() current-name}
+ * of the given symbol, i.e. does not test the {@link #getJavaSymbolRename(String) renamed-symbol}.
+ * </p>
* <p>
* For struct fields see {@link #canonicalStructFieldSymbol(String, String)}.
* </p>
+ * <p>
+ * Implementation calls {@link #shouldIgnoreInInterface(AliasedSymbol)}
+ * </p>
+ * @param symbol the symbolic name to check for exclusion
+ *
+ */
+ public final boolean shouldIgnoreInInterface(final String symbol) {
+ return shouldIgnoreInInterface( new AliasedSymbol.NoneAliasedSymbol(symbol) );
+ }
+ /**
+ * Returns true if this aliased symbol should be ignored
+ * during glue code generation of interfaces and implementation.
+ * <p>
+ * Both, the {@link AliasedSymbol#getName() current-name}
+ * and all {@link AliasedSymbol#getAliasedNames() aliases} shall be considered.
+ * </p>
+ * <p>
+ * Implementation calls {@link #shouldIgnoreInInterface_Int(AliasedSymbol)}
+ * and overriding implementations shall ensure its being called as well!
+ * </p>
+ * @param symbol the symbolic aliased name to check for exclusion
*/
- public boolean shouldIgnoreInInterface(final String symbol) {
- if(DEBUG_IGNORES) {
- dumpIgnoresOnce();
- }
- // Simple case-1; the entire symbol (orig or renamed) is in the interface ignore table
- final String renamedSymbol = getJavaSymbolRename(symbol);
- if ( extendedIntfSymbolsIgnore.contains( symbol ) ||
- extendedIntfSymbolsIgnore.contains( renamedSymbol ) ) {
+ public boolean shouldIgnoreInInterface(final AliasedSymbol symbol) {
+ return shouldIgnoreInInterface_Int(symbol);
+ }
+ private static boolean oneInSet(final Set<String> ignoreSymbols, final Set<String> symbols) {
+ if( null != ignoreSymbols && ignoreSymbols.size() > 0 &&
+ null != symbols && symbols.size() > 0 ) {
+ for(final String sym : symbols) {
+ if( ignoreSymbols.contains( sym ) ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ /** private static boolean allInSet(final Set<String> ignoreSymbols, final Set<String> symbols) {
+ if( null != ignoreSymbols && ignoreSymbols.size() > 0 &&
+ null != symbols && symbols.size() > 0 ) {
+ return ignoreSymbols.containsAll(symbols);
+ }
+ return false;
+ } */
+ private static boolean onePatternMatch(final Pattern ignoreRegexp, final Set<String> symbols) {
+ if( null != ignoreRegexp && null != symbols && symbols.size() > 0 ) {
+ for(final String sym : symbols) {
+ final Matcher matcher = ignoreRegexp.matcher(sym);
+ if (matcher.matches()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ protected final boolean shouldIgnoreInInterface_Int(final AliasedSymbol symbol) {
if(DEBUG_IGNORES) {
- System.err.println("Ignore Intf ignore : "+symbol);
+ dumpIgnoresOnce();
}
- return true;
- }
- // Simple case-2; the entire symbol (orig or renamed) is _not_ in the not-empty interface only table
- if ( !extendedIntfSymbolsOnly.isEmpty() &&
- !extendedIntfSymbolsOnly.contains( symbol ) &&
- !extendedIntfSymbolsOnly.contains( renamedSymbol ) ) {
+ final String name = symbol.getName();
+ final Set<String> aliases = symbol.getAliasedNames();
+
+ // Simple case-1; the symbol (orig or renamed) is in the interface ignore table
+ if ( extendedIntfSymbolsIgnore.contains( name ) ||
+ oneInSet(extendedIntfSymbolsIgnore, aliases)
+ )
+ {
if(DEBUG_IGNORES) {
- System.err.println("Ignore Intf !extended: " + symbol);
+ System.err.println("Ignore Intf ignore (one): "+symbol.getAliasedString());
}
return true;
- }
- return shouldIgnoreInImpl_Int(symbol);
+ }
+ // Simple case-2; the entire symbol (orig and renamed) is _not_ in the not-empty interface only table
+ if ( !extendedIntfSymbolsOnly.isEmpty() &&
+ !extendedIntfSymbolsOnly.contains( name ) &&
+ !oneInSet(extendedIntfSymbolsOnly, aliases) ) {
+ if(DEBUG_IGNORES) {
+ System.err.println("Ignore Intf !extended (all): " + symbol.getAliasedString());
+ }
+ return true;
+ }
+ return shouldIgnoreInImpl_Int(symbol);
}
/**
- * Returns true if this #define, function, struct, or field within
- * a struct should be ignored during glue code generation of implementation only.
+ * Returns true if this aliased symbol should be ignored
+ * during glue code generation of implementation only.
* <p>
- * For struct fields see {@link #canonicalStructFieldSymbol(String, String)}.
+ * Both, the {@link AliasedSymbol#getName() current-name}
+ * and all {@link AliasedSymbol#getAliasedNames() aliases} shall be considered.
+ * </p>
+ * <p>
+ * Implementation calls {@link #shouldIgnoreInImpl_Int(AliasedSymbol)}
+ * and overriding implementations shall ensure its being called as well!
* </p>
+ * @param symbol the symbolic aliased name to check for exclusion
*/
- public boolean shouldIgnoreInImpl(final String symbol) {
+ public boolean shouldIgnoreInImpl(final AliasedSymbol symbol) {
return shouldIgnoreInImpl_Int(symbol);
}
+ protected final boolean shouldIgnoreInImpl_Int(final AliasedSymbol symbol) {
+ final String name = symbol.getName();
+ final Set<String> aliases = symbol.getAliasedNames();
- private boolean shouldIgnoreInImpl_Int(final String symbol) {
-
- if(DEBUG_IGNORES) {
- dumpIgnoresOnce();
- }
-
- // Simple case-1; the entire symbol (orig or renamed) is in the implementation ignore table
- final String renamedSymbol = getJavaSymbolRename(symbol);
- if ( extendedImplSymbolsIgnore.contains( symbol ) ||
- extendedImplSymbolsIgnore.contains( renamedSymbol ) ) {
- if(DEBUG_IGNORES) {
- System.err.println("Ignore Impl ignore : "+symbol);
+ // Simple case-1; the symbol (orig or renamed) is in the interface ignore table
+ if ( extendedImplSymbolsIgnore.contains( name ) ||
+ oneInSet(extendedImplSymbolsIgnore, aliases)
+ )
+ {
+ if(DEBUG_IGNORES) {
+ System.err.println("Ignore Impl ignore (one): "+symbol.getAliasedString());
+ }
+ return true;
}
- return true;
- }
- // Simple case-2; the entire symbol (orig or renamed) is _not_ in the not-empty implementation only table
- if ( !extendedImplSymbolsOnly.isEmpty() &&
- !extendedImplSymbolsOnly.contains( symbol ) &&
- !extendedImplSymbolsOnly.contains( renamedSymbol ) ) {
+ // Simple case-2; the entire symbol (orig and renamed) is _not_ in the not-empty interface only table
+ if ( !extendedImplSymbolsOnly.isEmpty() &&
+ !extendedImplSymbolsOnly.contains( name ) &&
+ !oneInSet(extendedImplSymbolsOnly, aliases) ) {
if(DEBUG_IGNORES) {
- System.err.println("Ignore Impl !extended: " + symbol);
+ System.err.println("Ignore Impl !extended (all): " + symbol.getAliasedString());
}
return true;
- }
-
- // Ok, the slow case. We need to check the entire table, in case the table
- // contains an regular expression that matches the symbol.
- for (final Pattern regexp : ignores) {
- final Matcher matcher = regexp.matcher(symbol);
- if (matcher.matches()) {
- if(DEBUG_IGNORES) {
- System.err.println("Ignore Impl RegEx: "+symbol);
- }
- return true;
}
- }
- // Check negated ignore table if not empty
- if (ignoreNots.size() > 0) {
// Ok, the slow case. We need to check the entire table, in case the table
// contains an regular expression that matches the symbol.
- for (final Pattern regexp : ignoreNots) {
- final Matcher matcher = regexp.matcher(symbol);
- if (!matcher.matches()) {
- // Special case as this is most often likely to be the case.
- // Unignores are not used very often.
- if(unignores.isEmpty()) {
- if(DEBUG_IGNORES) {
- System.err.println("Ignore Impl unignores==0: "+symbol);
- }
- return true;
+ for (final Pattern ignoreRegexp : ignores) {
+ final Matcher matcher = ignoreRegexp.matcher(name);
+ if ( matcher.matches() || onePatternMatch(ignoreRegexp, aliases) ) {
+ if(DEBUG_IGNORES) {
+ System.err.println("Ignore Impl RegEx: "+symbol.getAliasedString());
+ }
+ return true;
}
+ }
- boolean unignoreFound = false;
- for (final Pattern unignoreRegexp : unignores) {
- final Matcher unignoreMatcher = unignoreRegexp.matcher(symbol);
- if (unignoreMatcher.matches()) {
- unignoreFound = true;
- break;
- }
+ // Check negated ignore table if not empty
+ if (ignoreNots.size() > 0) {
+ // Ok, the slow case. We need to check the entire table, in case the table
+ // contains an regular expression that matches the symbol.
+ for (final Pattern ignoreNotRegexp : ignoreNots) {
+ final Matcher matcher = ignoreNotRegexp.matcher(name);
+ if ( !matcher.matches() && !onePatternMatch(ignoreNotRegexp, aliases) ) {
+ // Special case as this is most often likely to be the case.
+ // Unignores are not used very often.
+ if(unignores.isEmpty()) {
+ if(DEBUG_IGNORES) {
+ System.err.println("Ignore Impl unignores==0: "+symbol.getAliasedString()+" -> "+name);
+ }
+ return true;
+ }
+ boolean unignoreFound = false;
+ for (final Pattern unignoreRegexp : unignores) {
+ final Matcher unignoreMatcher = unignoreRegexp.matcher(name);
+ if ( unignoreMatcher.matches() || onePatternMatch(unignoreRegexp, aliases) ) {
+ unignoreFound = true;
+ break;
+ }
+ }
+
+ if (!unignoreFound)
+ if(DEBUG_IGNORES) {
+ System.err.println("Ignore Impl !unignore: "+symbol.getAliasedString()+" -> "+name);
+ }
+ return true;
+ }
}
-
- if (!unignoreFound)
- if(DEBUG_IGNORES) {
- System.err.println("Ignore Impl !unignore: "+symbol);
- }
- return true;
- }
}
- }
-
- return false;
+ return false;
}
/** Returns true if this function should be given a body which
@@ -914,6 +979,19 @@ public class JavaConfiguration {
return false;
}
+ /**
+ * Return a set of aliased-name for comment in docs.
+ * <p>
+ * This is usually {@link AliasedSymbol#addAliasedName(String)},
+ * however an implementation may choose otherwise.
+ * </p>
+ * @param symbol the aliased symbol to retrieve the aliases
+ * @return set of aliased-names or {@code null}.
+ */
+ public Set<String> getAliasedDocNames(final AliasedSymbol symbol) {
+ return symbol.getAliasedNames();
+ }
+
/** Returns a replacement name for this type, which should be the
name of a Java wrapper class for a C struct, or the name
unchanged if no RenameJavaType directive was specified for this
@@ -1033,6 +1111,9 @@ public class JavaConfiguration {
nativeOutputUsesJavaHierarchy = Boolean.valueOf(tmp).booleanValue();
} else if (cmd.equalsIgnoreCase("TagNativeBinding")) {
tagNativeBinding = readBoolean("TagNativeBinding", tok, filename, lineNo).booleanValue();
+ } else if (cmd.equalsIgnoreCase("RelaxedEqualSemanticsTest")) {
+ relaxedEqualSemanticsTest = readBoolean("RelaxedEqualSemanticsTest", tok, filename, lineNo).booleanValue();
+ TypeConfig.setRelaxedEqualSemanticsTest(relaxedEqualSemanticsTest); // propagate ..
} else if (cmd.equalsIgnoreCase("Style")) {
try{
emissionStyle = EmissionStyle.valueOf(readString("Style", tok, filename, lineNo));
@@ -1222,7 +1303,7 @@ public class JavaConfiguration {
protected void readOpaque(final StringTokenizer tok, final String filename, final int lineNo) {
try {
- final JavaType javaType = JavaType.createForClass(stringToPrimitiveType(tok.nextToken()));
+ final JavaType javaType = JavaType.createForOpaqueClass(stringToPrimitiveType(tok.nextToken()));
String cType = null;
while (tok.hasMoreTokens()) {
if (cType == null) {
@@ -1755,6 +1836,16 @@ public class JavaConfiguration {
return new TypeInfo(typeName, pointerDepth, javaType);
}
+ public TypeInfo addTypeInfo(final String alias, final Type superType) {
+ final TypeInfo superInfo = typeInfo(superType);
+ if( null != superInfo ) {
+ final TypeInfo res = new TypeInfo(alias, superInfo.pointerDepth(), superInfo.javaType());
+ addTypeInfo(res);
+ return res;
+ } else {
+ return null;
+ }
+ }
protected void addTypeInfo(final TypeInfo info) {
TypeInfo tmp = typeInfoMap.get(info.name());
if (tmp == null) {
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index d2dc4ba..4db0482 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -49,6 +49,7 @@ import java.util.*;
import java.text.MessageFormat;
import com.jogamp.gluegen.cgram.types.*;
+import com.jogamp.gluegen.cgram.types.TypeComparator.AliasedSemanticSymbol;
import java.nio.Buffer;
import java.util.logging.Logger;
@@ -70,7 +71,6 @@ import static com.jogamp.gluegen.JavaEmitter.MethodAccess.*;
public class JavaEmitter implements GlueEmitter {
private StructLayout layout;
- private TypeDictionary typedefDictionary;
private Map<Type, Type> canonMap;
protected JavaConfiguration cfg;
private boolean requiresStaticInitialization = false;
@@ -103,7 +103,11 @@ public class JavaEmitter implements GlueEmitter {
private final MachineDataInfo machDescJava = MachineDataInfo.StaticConfig.LP64_UNIX.md;
private final MachineDataInfo.StaticConfig[] machDescTargetConfigs = MachineDataInfo.StaticConfig.values();
- protected final static Logger LOG = Logger.getLogger(JavaEmitter.class.getPackage().getName());
+ protected final Logger LOG;
+
+ public JavaEmitter() {
+ LOG = Logging.getLogger(JavaEmitter.class.getPackage().getName());
+ }
@Override
public void readConfigurationFile(final String filename) throws Exception {
@@ -111,39 +115,83 @@ public class JavaEmitter implements GlueEmitter {
cfg.read(filename);
}
- class ConstantRenamer implements SymbolFilter {
+ @Override
+ public JavaConfiguration getConfiguration() { return cfg; }
+ class ConstFuncRenamer implements SymbolFilter {
private List<ConstantDefinition> constants;
-
- @Override
- public void filterSymbols(final List<ConstantDefinition> constants, final List<FunctionSymbol> functions) {
- this.constants = constants;
- doWork();
- }
+ private List<FunctionSymbol> functions;
@Override
public List<ConstantDefinition> getConstants() {
return constants;
}
-
@Override
public List<FunctionSymbol> getFunctions() {
- return null;
+ return functions;
+ }
+
+ private <T extends AliasedSemanticSymbol> List<T> filterSymbolsInt(final List<T> inList, final List<T> outList) {
+ final JavaConfiguration cfg = getConfig();
+ final HashMap<String, T> symMap = new HashMap<String, T>(100);
+ for (final T sym : inList) {
+ final String origName = sym.getName();
+ final String newName = cfg.getJavaSymbolRename(origName);
+ if( null != newName ) {
+ // Alias Name
+ final T dupSym = symMap.get(newName);
+ if( null != dupSym ) {
+ // Duplicate alias .. check and add aliased name
+ sym.rename(newName); // only rename to allow 'equalSemantics' to not care ..
+ if( !dupSym.equalSemantics(sym) ) {
+ throw new RuntimeException(
+ String.format("Duplicate Name (alias) w/ incompatible value:%n have '%s',%n this '%s'",
+ dupSym.getAliasedString(), sym.getAliasedString()));
+ }
+ dupSym.addAliasedName(origName);
+ } else {
+ // No duplicate .. rename and add
+ sym.rename(newName);
+ symMap.put(newName, sym);
+ }
+ } else {
+ // Original Name
+ final T dupSym = symMap.get(origName);
+ if( null != dupSym ) {
+ // Duplicate orig .. check and drop
+ if( !dupSym.equalSemantics(sym) ) {
+ throw new RuntimeException(
+ String.format("Duplicate Name (orig) w/ incompatible value:%n have '%s',%n this '%s'",
+ dupSym.getAliasedString(), sym.getAliasedString()));
+ }
+ } else {
+ // No duplicate orig .. add
+ symMap.put(origName, sym);
+ }
+ }
+ }
+ outList.addAll(symMap.values());
+ // sort constants to make them easier to find in native code
+ Collections.sort(outList, new Comparator<T>() {
+ @Override
+ public int compare(final T o1, final T o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ return outList;
}
- private void doWork() {
- final List<ConstantDefinition> newConstants = new ArrayList<ConstantDefinition>();
- final JavaConfiguration cfg = getConfig();
- for (final ConstantDefinition def : constants) {
- def.rename(cfg.getJavaSymbolRename(def.getName()));
- newConstants.add(def);
- }
- constants = newConstants;
+ @Override
+ public void filterSymbols(final List<ConstantDefinition> inConstList, final List<FunctionSymbol> inFuncList) {
+ constants = filterSymbolsInt(inConstList, new ArrayList<ConstantDefinition>(100));
+ functions = filterSymbolsInt(inFuncList, new ArrayList<FunctionSymbol>(100));
}
}
@Override
public void beginEmission(final GlueEmitterControls controls) throws IOException {
+ // Handle renaming of constants and functions
+ controls.runSymbolFilter(new ConstFuncRenamer());
// Request emission of any structs requested
for (final String structs : cfg.forcedStructs()) {
@@ -157,9 +205,6 @@ public class JavaEmitter implements GlueEmitter {
throw new RuntimeException("Unable to open files for writing", e);
}
emitAllFileHeaders();
-
- // Handle renaming of constants
- controls.runSymbolFilter(new ConstantRenamer());
}
}
@@ -374,7 +419,7 @@ public class JavaEmitter implements GlueEmitter {
final String name = def.getName();
String value = def.getValue();
- if (!cfg.shouldIgnoreInInterface(name)) {
+ if ( !cfg.shouldIgnoreInInterface(def) ) {
final String type = getJavaType(name, value);
if (optionalComment != null && optionalComment.length() != 0) {
javaWriter().println(" /** " + optionalComment + " */");
@@ -402,7 +447,7 @@ public class JavaEmitter implements GlueEmitter {
final TypeDictionary structDictionary,
final Map<Type, Type> canonMap) throws Exception {
- this.typedefDictionary = typedefDictionary;
+ // this.typedefDictionary = typedefDictionary;
this.canonMap = canonMap;
this.requiresStaticInitialization = false; // reset
@@ -412,55 +457,44 @@ public class JavaEmitter implements GlueEmitter {
}
@Override
- public Iterator<FunctionSymbol> emitFunctions(final List<FunctionSymbol> originalCFunctions) throws Exception {
-
- // Sometimes headers will have the same function prototype twice, once
- // with the argument names and once without. We'll remember the signatures
- // we've already processed we don't generate duplicate bindings.
- //
- // Note: this code assumes that on the equals() method in FunctionSymbol
- // only considers function name and argument types (i.e., it does not
- // consider argument *names*) when comparing FunctionSymbols for equality
- final Set<FunctionSymbol> funcsToBindSet = new HashSet<FunctionSymbol>(100);
- for (final FunctionSymbol cFunc : originalCFunctions) {
- if (!funcsToBindSet.contains(cFunc)) {
- funcsToBindSet.add(cFunc);
- }
- }
-
- // validateFunctionsToBind(funcsToBindSet);
-
- final ArrayList<FunctionSymbol> funcsToBind = new ArrayList<FunctionSymbol>(funcsToBindSet);
- // sort functions to make them easier to find in native code
- Collections.sort(funcsToBind, new Comparator<FunctionSymbol>() {
- @Override
- public int compare(final FunctionSymbol o1, final FunctionSymbol o2) {
- return o1.getName().compareTo(o2.getName());
- }
- });
-
+ public Iterator<FunctionSymbol> emitFunctions(final List<FunctionSymbol> funcsToBind) throws Exception {
// Bind all the C funcs to Java methods
final HashSet<MethodBinding> methodBindingSet = new HashSet<MethodBinding>();
final ArrayList<FunctionEmitter> methodBindingEmitters = new ArrayList<FunctionEmitter>(2*funcsToBind.size());
- for (final FunctionSymbol cFunc : funcsToBind) {
- // Check to see whether this function should be ignored
- if (!cfg.shouldIgnoreInImpl(cFunc.getName())) {
- methodBindingEmitters.addAll(generateMethodBindingEmitters(methodBindingSet, cFunc));
- }
+ {
+ int i=0;
+ for (final FunctionSymbol cFunc : funcsToBind) {
+ // Check to see whether this function should be ignored
+ if ( !cfg.shouldIgnoreInImpl(cFunc) ) {
+ methodBindingEmitters.addAll(generateMethodBindingEmitters(methodBindingSet, cFunc));
+ if( GlueGen.debug() ) {
+ System.err.println("Non-Ignored Impl["+i+"]: "+cFunc.getAliasedString());
+ i++;
+ }
+ }
+ }
}
// Emit all the methods
- for (final FunctionEmitter emitter : methodBindingEmitters) {
- try {
- if (!emitter.isInterface() || !cfg.shouldIgnoreInInterface(emitter.getName())) {
- emitter.emit();
- emitter.getDefaultOutput().println(); // put newline after method body
+ {
+ int i=0;
+ for (final FunctionEmitter emitter : methodBindingEmitters) {
+ try {
+ final FunctionSymbol cFunc = emitter.getCSymbol();
+ if ( !emitter.isInterface() || !cfg.shouldIgnoreInInterface(cFunc) ) {
+ emitter.emit();
+ emitter.getDefaultOutput().println(); // put newline after method body
+ if( GlueGen.debug() ) {
+ System.err.println("Non-Ignored Intf["+i+"]: "+cFunc.getAliasedString());
+ i++;
+ }
+ }
+ } catch (final Exception e) {
+ throw new RuntimeException(
+ "Error while emitting binding for \"" + emitter.getName() + "\"", e);
+ }
}
- } catch (final Exception e) {
- throw new RuntimeException(
- "Error while emitting binding for \"" + emitter.getName() + "\"", e);
- }
}
// Return the list of FunctionSymbols that we generated gluecode for
@@ -658,7 +692,7 @@ public class JavaEmitter implements GlueEmitter {
cfg.allStatic(),
(binding.needsNIOWrappingOrUnwrapping() || hasPrologueOrEpilogue),
!cfg.useNIODirectOnly(binding.getName()),
- machDescJava);
+ machDescJava, getConfiguration());
prepCEmitter(binding.getName(), binding.getJavaReturnType(), cEmitter);
allEmitters.add(cEmitter);
}
@@ -821,40 +855,69 @@ public class JavaEmitter implements GlueEmitter {
public void beginStructs(final TypeDictionary typedefDictionary,
final TypeDictionary structDictionary,
final Map<Type, Type> canonMap) throws Exception {
- this.typedefDictionary = typedefDictionary;
+ // this.typedefDictionary = typedefDictionary;
this.canonMap = canonMap;
}
@Override
- public void emitStruct(final CompoundType structCType, final String alternateName) throws Exception {
- final String structCTypeName;
+ public void emitStruct(final CompoundType structCType, final Type typedefed) throws Exception {
+ final String structCTypeName, typedefedName;
{
- String _name = structCType.getName();
- if (_name == null && alternateName != null) {
- _name = alternateName;
+ final String _name = structCType.getName();
+ if ( null == _name && null != typedefed && null != typedefed.getName() ) {
+ // use typedef'ed name
+ typedefedName = typedefed.getName();
+ structCTypeName = typedefedName;
+ } else {
+ // use actual struct type name
+ typedefedName = null;
+ structCTypeName = _name;
}
- structCTypeName = _name;
}
-
- if (structCTypeName == null) {
+ if ( null == structCTypeName ) {
final String structName = structCType.getStructName();
if ( null != structName && cfg.shouldIgnoreInInterface(structName) ) {
+ LOG.log(INFO, "skipping emission of unnamed ignored struct \"{0}\": {1}", new Object[] { structName, structCType.getDebugString() });
+ return;
+ } else {
+ final String d1 = null != typedefed ? typedefed.getDebugString() : null;
+ LOG.log(INFO, "skipping emission of unnamed struct {0}, typedef {1} ", new Object[] { structCType.getDebugString(), d1 });
return;
}
- LOG.log(WARNING, "skipping emission of unnamed struct \"{0}\"", structCType);
+ }
+ if ( cfg.shouldIgnoreInInterface(structCTypeName) ) {
+ LOG.log(INFO, "skipping emission of ignored \"{0}\": {1}", new Object[] { structCTypeName, structCType.getDebugString() });
return;
}
-
- if (cfg.shouldIgnoreInInterface(structCTypeName)) {
- return;
+ if( null != typedefed && isOpaque(typedefed) ) {
+ LOG.log(INFO, "skipping emission of opaque typedef {0}, c-struct {1}", new Object[] { typedefed.getDebugString(), structCType.getDebugString() });
+ return;
}
- final Type containingCType = canonicalize(new PointerType(SizeThunk.POINTER, structCType, 0));
+ final Type containingCType = canonicalize(new PointerType(SizeThunk.POINTER, structCType, 0, typedefedName));
final JavaType containingJType = typeToJavaType(containingCType, null);
- if (!containingJType.isCompoundTypeWrapper()) {
- return;
+ if( containingJType.isOpaqued() ) {
+ LOG.log(INFO, "skipping emission of opaque {0}, {1}", new Object[] { containingJType.getDebugString(), structCType.getDebugString() });
+ return;
+ }
+ if( !containingJType.isCompoundTypeWrapper() ) {
+ LOG.log(WARNING, "skipping emission of non-compound {0}, {1}", new Object[] { containingJType.getDebugString(), structCType.getDebugString() });
+ return;
}
final String containingJTypeName = containingJType.getName();
+ LOG.log(INFO, "perform emission of \"{0}\" -> \"{1}\": {2}", new Object[] { structCTypeName, containingJTypeName, structCType.getDebugString()});
+ if( GlueGen.debug() ) {
+ if( null != typedefed ) {
+ LOG.log(INFO, " typedefed {0}", typedefed.getDebugString());
+ } else {
+ LOG.log(INFO, " typedefed NULL");
+ }
+ LOG.log(INFO, " containingCType {0}", containingCType.getDebugString());
+ LOG.log(INFO, " containingJType {0}", containingJType.getDebugString());
+ }
+ if( 0 == structCType.getNumFields() ) {
+ LOG.log(INFO, "emission of \"{0}\" with zero fields {1}", new Object[] { containingJTypeName, structCType.getDebugString() });
+ }
this.requiresStaticInitialization = false; // reset
@@ -1355,7 +1418,7 @@ public class JavaEmitter implements GlueEmitter {
false,
true,
false, // forIndirectBufferAndArrayImplementation
- machDescJava);
+ machDescJava, getConfiguration());
cEmitter.setIsCStructFunctionPointer(true);
prepCEmitter(returnSizeLookupName, binding.getJavaReturnType(), cEmitter);
cEmitter.emit();
@@ -1420,7 +1483,7 @@ public class JavaEmitter implements GlueEmitter {
false,
true,
false, // forIndirectBufferAndArrayImplementation
- machDescJava);
+ machDescJava, getConfiguration());
cEmitter.setIsCStructFunctionPointer(false);
final String lenExprSet;
if( null != nativeArrayLenExpr ) {
@@ -1947,10 +2010,9 @@ public class JavaEmitter implements GlueEmitter {
}
}
- private static final boolean DEBUG_TYPEC2JAVA = false;
private JavaType typeToJavaType(final Type cType, final MachineDataInfo curMachDesc) {
final JavaType jt = typeToJavaTypeImpl(cType, curMachDesc);
- if( DEBUG_TYPEC2JAVA ) {
+ if( GlueGen.debug() ) {
System.err.println("typeToJavaType: "+cType.getDebugString()+" -> "+jt.getDebugString());
}
return jt;
@@ -1968,7 +2030,7 @@ public class JavaEmitter implements GlueEmitter {
}
// Opaque specifications override automatic conversions
// in case the identity is being used .. not if ptr-ptr
- final TypeInfo info = cfg.typeInfo(cType, typedefDictionary);
+ final TypeInfo info = cfg.typeInfo(cType);
if (info != null) {
boolean isPointerPointer = false;
if (cType.pointerDepth() > 0 || cType.arrayDimension() > 0) {
@@ -1986,16 +2048,15 @@ public class JavaEmitter implements GlueEmitter {
// target type)
if (targetType.isPointer()) {
isPointerPointer = true;
-
- // t is<type>**, targetType is <type>*, we need to get <type>
- final Type bottomType = targetType.asPointer().getTargetType();
if( GlueGen.debug() ) {
+ // t is<type>**, targetType is <type>*, we need to get <type>
+ final Type bottomType = targetType.asPointer().getTargetType();
LOG.log(INFO, "Opaque Type: {0}, targetType: {1}, bottomType: {2} is ptr-ptr", new Object[]{cType.getDebugString(), targetType, bottomType});
}
}
}
}
- if(!isPointerPointer) {
+ if( !isPointerPointer ) {
return info.javaType();
}
}
@@ -2066,7 +2127,6 @@ public class JavaEmitter implements GlueEmitter {
throw new RuntimeException("Couldn't find a proper type name for pointer type " + cType.getDebugString());
}
}
-
return JavaType.createForCStruct(cfg.renameJavaType(name));
} else {
throw new RuntimeException("Don't know how to convert pointer/array type \"" +
@@ -2189,7 +2249,7 @@ public class JavaEmitter implements GlueEmitter {
}
private boolean isOpaque(final Type type) {
- return (cfg.typeInfo(type, typedefDictionary) != null);
+ return (cfg.typeInfo(type) != null);
}
private String compatiblePrimitiveJavaTypeName(final Type fieldType,
@@ -2586,9 +2646,6 @@ public class JavaEmitter implements GlueEmitter {
final MachineDataInfo curMachDesc) {
final MethodBinding binding = new MethodBinding(sym, containingType, containingCType);
-
- binding.renameMethodName(cfg.getJavaSymbolRename(sym.getName()));
-
// System.out.println("bindFunction(0) "+sym.getReturnType());
if (cfg.returnsString(binding.getName())) {
@@ -2779,10 +2836,11 @@ public class JavaEmitter implements GlueEmitter {
private Type canonicalize(final Type t) {
final Type res = canonMap.get(t);
if (res != null) {
- return res;
+ return res;
+ } else {
+ canonMap.put(t, t);
+ return t;
}
- canonMap.put(t, t);
- return t;
}
/**
diff --git a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
index 6966315..9d02c14 100644
--- a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
@@ -40,14 +40,17 @@
package com.jogamp.gluegen;
import com.jogamp.gluegen.cgram.HeaderParser;
+import com.jogamp.gluegen.cgram.types.AliasedSymbol;
import com.jogamp.gluegen.cgram.types.ArrayType;
import com.jogamp.gluegen.cgram.types.EnumType;
+import com.jogamp.gluegen.cgram.types.FunctionSymbol;
import com.jogamp.gluegen.cgram.types.Type;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
/**
* An emitter that emits only the interface for a Java<->C JNI binding.
@@ -97,9 +100,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
// represent an array of compound type wrappers
private static final String COMPOUND_ARRAY_SUFFIX = "_buf_array_copy";
- // Only present to provide more clear comments
- private final JavaConfiguration cfg;
-
public JavaMethodBindingEmitter(final MethodBinding binding,
final PrintWriter output,
final String runtimeExceptionType,
@@ -115,7 +115,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
final boolean isUnimplemented,
final boolean isInterface,
final JavaConfiguration configuration) {
- super(output, isInterface);
+ super(output, isInterface, configuration);
this.binding = binding;
this.runtimeExceptionType = runtimeExceptionType;
this.unsupportedExceptionType = unsupportedExceptionType;
@@ -133,7 +133,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
} else {
setCommentEmitter(defaultInterfaceCommentEmitter);
}
- cfg = configuration;
}
public JavaMethodBindingEmitter(final JavaMethodBindingEmitter arg) {
@@ -154,7 +153,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
epilogue = arg.epilogue;
returnedArrayLengthExpression = arg.returnedArrayLengthExpression;
returnedArrayLengthExpressionOnlyForComments = arg.returnedArrayLengthExpressionOnlyForComments;
- cfg = arg.cfg;
}
public final MethodBinding getBinding() { return binding; }
@@ -168,6 +166,11 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
return binding.getName();
}
+ @Override
+ public FunctionSymbol getCSymbol() {
+ return binding.getCSymbol();
+ }
+
protected String getArgumentName(final int i) {
return binding.getArgumentName(i);
}
@@ -812,6 +815,26 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
* emitter java method.
*/
protected class DefaultCommentEmitter implements CommentEmitter {
+ protected void emitAliasedDocNamesComment(final AliasedSymbol sym, final PrintWriter writer) {
+ writer.print(emitAliasedDocNamesComment(sym, new StringBuilder()).toString());
+ }
+ protected StringBuilder emitAliasedDocNamesComment(final AliasedSymbol sym, final StringBuilder sb) {
+ final Set<String> aliases = cfg.getAliasedDocNames(sym);
+ if (aliases != null && aliases.size() > 0 ) {
+ int i=0;
+ sb.append("Alias for: <code>");
+ for (final String alias : aliases) {
+ if(0 < i) {
+ sb.append("</code>, <code>");
+ }
+ sb.append(alias);
+ i++;
+ }
+ sb.append("</code>");
+ }
+ return sb;
+ }
+
@Override
public void emit(final FunctionEmitter emitter, final PrintWriter writer) {
emitBeginning(emitter, writer);
@@ -826,9 +849,11 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
writer.print("Entry point to C language function: ");
}
protected void emitBindingCSignature(final MethodBinding binding, final PrintWriter writer) {
- writer.print("<code> ");
- writer.print(binding.getCSymbol().toString(tagNativeBinding));
- writer.print(" </code> ");
+ final FunctionSymbol funcSym = binding.getCSymbol();
+ writer.print("<code>");
+ writer.print(funcSym.toString(tagNativeBinding));
+ writer.print("</code><br>");
+ emitAliasedDocNamesComment(funcSym, writer);
}
protected void emitEnding(final FunctionEmitter emitter, final PrintWriter writer) {
// If argument type is a named enum, then emit a comment detailing the
diff --git a/src/java/com/jogamp/gluegen/JavaType.java b/src/java/com/jogamp/gluegen/JavaType.java
index 87804bd..9bcd663 100644
--- a/src/java/com/jogamp/gluegen/JavaType.java
+++ b/src/java/com/jogamp/gluegen/JavaType.java
@@ -63,6 +63,7 @@ public class JavaType {
private final String structName; // Types we're generating glue code for (i.e., C structs)
private final Type elementType; // Element type if this JavaType represents a C array
private final C_PTR primitivePointerType;
+ private final boolean opaqued;
private static JavaType nioBufferType;
private static JavaType nioByteBufferType;
@@ -107,12 +108,20 @@ public class JavaType {
return elementType;
}
+ /** Creates a JavaType corresponding to the given opaque Java type. This
+ can be used to represent arrays of primitive values or Strings;
+ the emitters understand how to perform proper conversion from
+ the corresponding C type. */
+ public static JavaType createForOpaqueClass(final Class<?> clazz) {
+ return new JavaType(clazz, true);
+ }
+
/** Creates a JavaType corresponding to the given Java type. This
can be used to represent arrays of primitive values or Strings;
the emitters understand how to perform proper conversion from
the corresponding C type. */
public static JavaType createForClass(final Class<?> clazz) {
- return new JavaType(clazz);
+ return new JavaType(clazz, false);
}
/** Creates a JavaType corresponding to the specified C CompoundType
@@ -336,6 +345,8 @@ public class JavaType {
return "jobject";
}
+ public boolean isOpaqued() { return opaqued; }
+
public boolean isNIOBuffer() {
return clazz != null && ( java.nio.Buffer.class.isAssignableFrom(clazz) ||
com.jogamp.common.nio.NativeBuffer.class.isAssignableFrom(clazz)) ;
@@ -528,34 +539,39 @@ public class JavaType {
append(sb, "primitivePointerType = "+primitivePointerType, prepComma); prepComma=true;
}
append(sb, "is[", prepComma); prepComma=false;
- if( isArray() ) {
- append(sb, "array", prepComma); prepComma=true;
- }
- if( isArrayOfCompoundTypeWrappers() ) {
- append(sb, "compoundArray", prepComma); prepComma=true;
- }
- if( isCompoundTypeWrapper() ) {
- append(sb, "compound", prepComma); prepComma=true;
- }
- if( isArray() ) {
- append(sb, "array", prepComma); prepComma=true;
- }
- if( isPrimitive() ) {
- append(sb, "primitive", prepComma); prepComma=true;
- }
- if( isPrimitiveArray() ) {
- append(sb, "primitiveArray", prepComma); prepComma=true;
- }
- if( isNIOBuffer() ) {
- append(sb, "nioBuffer", prepComma); prepComma=true;
- }
- if( isNIOBufferArray() ) {
- append(sb, "nioBufferArray", prepComma); prepComma=true;
- }
- if( isCPrimitivePointerType() ) {
- append(sb, "C-Primitive-Pointer", prepComma); prepComma=true;
+ {
+ if( isOpaqued() ) {
+ append(sb, "opaque", prepComma); prepComma=true;
+ }
+ if( isArray() ) {
+ append(sb, "array", prepComma); prepComma=true;
+ }
+ if( isArrayOfCompoundTypeWrappers() ) {
+ append(sb, "compoundArray", prepComma); prepComma=true;
+ }
+ if( isCompoundTypeWrapper() ) {
+ append(sb, "compound", prepComma); prepComma=true;
+ }
+ if( isArray() ) {
+ append(sb, "array", prepComma); prepComma=true;
+ }
+ if( isPrimitive() ) {
+ append(sb, "primitive", prepComma); prepComma=true;
+ }
+ if( isPrimitiveArray() ) {
+ append(sb, "primitiveArray", prepComma); prepComma=true;
+ }
+ if( isNIOBuffer() ) {
+ append(sb, "nioBuffer", prepComma); prepComma=true;
+ }
+ if( isNIOBufferArray() ) {
+ append(sb, "nioBufferArray", prepComma); prepComma=true;
+ }
+ if( isCPrimitivePointerType() ) {
+ append(sb, "C-Primitive-Pointer", prepComma); prepComma=true;
+ }
}
- append(sb, "descriptor '"+getDescriptor()+"'", prepComma); prepComma=true;
+ append(sb, "], descriptor '"+getDescriptor()+"']", prepComma); prepComma=true;
return sb.toString();
}
@@ -563,11 +579,12 @@ public class JavaType {
* Constructs a representation for a type corresponding to the given Class
* argument.
*/
- private JavaType(final Class<?> clazz) {
+ private JavaType(final Class<?> clazz, final boolean opaqued) {
this.primitivePointerType = null;
this.clazz = clazz;
this.structName = null;
this.elementType = null;
+ this.opaqued = opaqued;
}
/** Constructs a type representing a named C struct. */
@@ -576,6 +593,7 @@ public class JavaType {
this.clazz = null;
this.structName = structName;
this.elementType = null;
+ this.opaqued = false;
}
/** Constructs a type representing a pointer to a C primitive
@@ -585,6 +603,7 @@ public class JavaType {
this.clazz = null;
this.structName = null;
this.elementType = null;
+ this.opaqued = false;
}
/** Constructs a type representing an array of C pointers. */
@@ -593,6 +612,7 @@ public class JavaType {
this.clazz = null;
this.structName = null;
this.elementType = elementType;
+ this.opaqued = false;
}
/** clone only */
@@ -601,6 +621,7 @@ public class JavaType {
this.clazz = clazz;
this.structName = name;
this.elementType = elementType;
+ this.opaqued = false;
}
private String arrayName(Class<?> clazz) {
diff --git a/src/java/com/jogamp/gluegen/Logging.java b/src/java/com/jogamp/gluegen/Logging.java
index 40eadcb..77856f4 100644
--- a/src/java/com/jogamp/gluegen/Logging.java
+++ b/src/java/com/jogamp/gluegen/Logging.java
@@ -33,6 +33,7 @@ package com.jogamp.gluegen;
import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
+import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
@@ -41,11 +42,13 @@ import com.jogamp.common.util.PropertyAccess;
/**
*
- * @author Michael Bien
+ * @author Michael Bien, et.al.
*/
public class Logging {
- static void init() {
+ final static Logger rootPackageLogger;
+
+ static {
final String packageName = Logging.class.getPackage().getName();
final String property = PropertyAccess.getProperty(packageName+".level", true);
Level level;
@@ -64,12 +67,35 @@ public class Logging {
handler.setFormatter(new PlainLogFormatter());
handler.setLevel(level);
- final Logger rootPackageLogger = Logger.getLogger(packageName);
+ rootPackageLogger = Logger.getLogger(packageName);
rootPackageLogger.setUseParentHandlers(false);
rootPackageLogger.setLevel(level);
rootPackageLogger.addHandler(handler);
}
+ /** provokes static initialization */
+ static void init() { }
+
+ /** Returns the <i>root package logger</i>. */
+ public static Logger getLogger() {
+ return rootPackageLogger;
+ }
+ /** Returns the demanded logger, while aligning its log-level to the root logger's level. */
+ public static synchronized Logger getLogger(final String name) {
+ final Logger l = Logger.getLogger(name);
+ alignLevel(l);
+ return l;
+ }
+ /** Align log-level of given logger to the root logger's level. */
+ public static void alignLevel(final Logger l) {
+ final Level level = rootPackageLogger.getLevel();
+ l.setLevel(level);
+ final Handler[] hs = l.getHandlers();
+ for(final Handler h:hs) {
+ h.setLevel(level);
+ }
+ }
+
/**
* This log formatter needs usually one line per log record.
* @author Michael Bien
diff --git a/src/java/com/jogamp/gluegen/MethodBinding.java b/src/java/com/jogamp/gluegen/MethodBinding.java
index 93c55d5..56b4fc8 100644
--- a/src/java/com/jogamp/gluegen/MethodBinding.java
+++ b/src/java/com/jogamp/gluegen/MethodBinding.java
@@ -44,7 +44,6 @@ import com.jogamp.gluegen.cgram.types.Type;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
/** Represents the binding of a C function to a Java method. Also used
@@ -54,8 +53,6 @@ import java.util.List;
public class MethodBinding {
private final FunctionSymbol sym;
- private String renamedMethodName;
- private final HashSet<String> aliasedNames;
private JavaType javaReturnType;
private List<JavaType> javaArgumentTypes;
private boolean computedSignatureProperties;
@@ -81,8 +78,6 @@ public class MethodBinding {
public MethodBinding(final MethodBinding bindingToCopy) {
this.sym = bindingToCopy.sym;
- this.renamedMethodName = bindingToCopy.renamedMethodName;
- this.aliasedNames = new HashSet<String>(bindingToCopy.aliasedNames);
this.containingType = bindingToCopy.containingType;
this.containingCType = bindingToCopy.containingCType;
this.javaReturnType = bindingToCopy.javaReturnType;
@@ -104,7 +99,6 @@ public class MethodBinding {
/** Constructor for calling a C function. */
public MethodBinding(final FunctionSymbol sym) {
this.sym = sym;
- this.aliasedNames = new HashSet<String>();
}
/** Constructor for calling a function pointer contained in a
@@ -113,7 +107,6 @@ public class MethodBinding {
this.sym = sym;
this.containingType = containingType;
this.containingCType = containingCType;
- this.aliasedNames = new HashSet<String>();
}
public void setJavaReturnType(final JavaType type) {
@@ -166,34 +159,13 @@ public class MethodBinding {
return "arg" + i;
}
- public String getOrigName() {
- return sym.getName();
+ public Collection<String> getAliasedNames() {
+ return sym.getAliasedNames();
}
-
public String getName() {
- // Defaults to same as C symbol unless renamed
- if (renamedMethodName != null) {
- return renamedMethodName;
- }
return sym.getName();
}
- /** Supports renaming C function in Java binding. */
- public void renameMethodName(final String name) {
- if (null != name) {
- renamedMethodName = name;
- aliasedNames.add(sym.getName());
- }
- }
-
- public void addAliasedName(final String name) {
- aliasedNames.add(name);
- }
-
- public Collection<String> getAliasedNames() {
- return aliasedNames;
- }
-
/** Creates a new MethodBinding replacing the specified Java
argument type with a new argument type. If argumentNumber is
less than 0 then replaces the return type. */
diff --git a/src/java/com/jogamp/gluegen/ReferencedStructs.java b/src/java/com/jogamp/gluegen/ReferencedStructs.java
index d06d47f..546726f 100644
--- a/src/java/com/jogamp/gluegen/ReferencedStructs.java
+++ b/src/java/com/jogamp/gluegen/ReferencedStructs.java
@@ -58,7 +58,7 @@ public class ReferencedStructs implements TypeVisitor {
public void visitType(final Type t) {
if (t.isPointer()) {
final PointerType p = t.asPointer();
- if (p.hasTypedefedName()) {
+ if (p.hasTypedefName()) {
final CompoundType c = p.getTargetType().asCompound();
if (c != null && c.getName() == null) {
// This otherwise-unnamed CompoundType is referred to by a
diff --git a/src/java/com/jogamp/gluegen/TypeConfig.java b/src/java/com/jogamp/gluegen/TypeConfig.java
new file mode 100644
index 0000000..5f389f4
--- /dev/null
+++ b/src/java/com/jogamp/gluegen/TypeConfig.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright 2015 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.gluegen;
+
+import com.jogamp.gluegen.cgram.types.SizeThunk;
+import com.jogamp.gluegen.cgram.types.Type;
+
+/**
+ * Static {@link Type} config helper
+ * binding {@link JavaConfiguration#relaxedEqualSemanticsTest()} system wide.
+ */
+public class TypeConfig {
+ private static boolean relaxedEqualSemanticsTest = false;
+
+ /**
+ * Returns whether {@link TypeConfig.SemanticEqualityOp#equalSemantics(TypeConfig.SemanticEqualityOp)}
+ * shall attempt to perform a relaxed semantic equality test, e.g. skip the {@code const} and {@code volatile} qualifier
+ * - or not.
+ */
+ public static boolean relaxedEqualSemanticsTest() {
+ return relaxedEqualSemanticsTest;
+ }
+ /* pp */ static void setRelaxedEqualSemanticsTest(final boolean v) {
+ relaxedEqualSemanticsTest = v;
+ SizeThunk.setRelaxedEqualSemanticsTest(v);
+ }
+}
diff --git a/src/java/com/jogamp/gluegen/TypeInfo.java b/src/java/com/jogamp/gluegen/TypeInfo.java
index d89ac79..52fdc04 100644
--- a/src/java/com/jogamp/gluegen/TypeInfo.java
+++ b/src/java/com/jogamp/gluegen/TypeInfo.java
@@ -66,7 +66,7 @@ public class TypeInfo {
buf.append(name);
buf.append(" pointerDepth ");
buf.append(pointerDepth);
- buf.append(" JavaType " + javaType);
+ buf.append(" JavaType " + javaType.getDebugString());
return buf.toString();
}
}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/AliasedSymbol.java b/src/java/com/jogamp/gluegen/cgram/types/AliasedSymbol.java
new file mode 100644
index 0000000..a924876
--- /dev/null
+++ b/src/java/com/jogamp/gluegen/cgram/types/AliasedSymbol.java
@@ -0,0 +1,154 @@
+/**
+ * Copyright 2015 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.gluegen.cgram.types;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Supports symbol aliasing, i.e. renaming,
+ * while preserving all its original names, i.e. aliases.
+ */
+public interface AliasedSymbol {
+ /**
+ * Rename this symbol with the given {@code newName} if not equal {@link #getName() current-name}.
+ * <p>
+ * Before renaming the {@link #getName() current-name} will be added
+ * to the list of {@link #getAliasedNames() aliases}.
+ * while the given {@code newName} will be removed.
+ * </p>
+ * @param newName the new {@link #getName() current-name}
+ */
+ void rename(final String newName);
+ /**
+ * Add the given {@code origName} to the list of {@link #getAliasedNames() aliases}
+ * if not equal {@link #getName() current-name}.
+ * @param origName the new alias to be added
+ */
+ void addAliasedName(final String origName);
+ /**
+ *
+ * Returns {@code true} if this symbol has aliases, i.e. either being {@link #rename(String) renamed}
+ * or {@link #addAliasedName(String) aliases-added}.
+ * <p>
+ * Otherwise {@code false} is being returned.
+ * </p>
+ */
+ boolean hasAliases();
+ /**
+ * Return all aliases for this symbol, i.e. original names, for this symbol.
+ * <p>
+ * Exclusive {@link #getName() current-name}.
+ * </p>
+ * <p>
+ * May return {@code null} or a zero sized {@link Set} for no aliases.
+ * </p>
+ */
+ Set<String> getAliasedNames();
+ /**
+ * Return the current-name, which is the last {@link #rename(String) renamed-name} if issued,
+ * or the original-name.
+ */
+ String getName();
+ /**
+ * Return this object's {@link #toString()} wrapped w/ the {@link #getName() current-name}
+ * and all {@link #getAliasedNames() aliases}.
+ */
+ String getAliasedString();
+
+ public static class AliasedSymbolImpl implements AliasedSymbol {
+ private final HashSet<String> aliasedNames;
+ private String name;
+
+ public AliasedSymbolImpl(final String origName) {
+ this.aliasedNames=new HashSet<String>();
+ this.name = origName;
+ }
+ @Override
+ public void rename(final String newName) {
+ if( !name.equals(newName) ) {
+ aliasedNames.add(name);
+ aliasedNames.remove(newName);
+ name = newName;
+ }
+ }
+ @Override
+ public void addAliasedName(final String origName) {
+ if( !name.equals(origName) ) {
+ aliasedNames.add(origName);
+ }
+ }
+ @Override
+ public boolean hasAliases() {
+ return aliasedNames.size() > 0;
+ }
+ @Override
+ public Set<String> getAliasedNames() {
+ return aliasedNames;
+ }
+ @Override
+ public String getName() {
+ return name;
+ }
+ @Override
+ public String getAliasedString() {
+ return "["+name+", aliases "+aliasedNames.toString()+", "+toString()+"]";
+ }
+ }
+ public static class NoneAliasedSymbol implements AliasedSymbol {
+ private final String name;
+
+ public NoneAliasedSymbol(final String origName) {
+ this.name = origName;
+ }
+ @Override
+ public void rename(final String newName) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void addAliasedName(final String origName) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public boolean hasAliases() {
+ return false;
+ }
+ @Override
+ public Set<String> getAliasedNames() {
+ return null;
+ }
+ @Override
+ public String getName() {
+ return name;
+ }
+ @Override
+ public String getAliasedString() {
+ return toString();
+ }
+ }
+}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java b/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java
index d867b40..281c68d 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java
@@ -48,7 +48,6 @@ package com.jogamp.gluegen.cgram.types;
public class ArrayType extends MemoryLayoutType implements Cloneable {
private final Type elementType;
private final int length;
- private String computedName;
public ArrayType(final Type elementType, final SizeThunk sizeInBytes, final int length, final int cvAttributes) {
super(elementType.getName() + " *", sizeInBytes, cvAttributes);
@@ -57,24 +56,39 @@ public class ArrayType extends MemoryLayoutType implements Cloneable {
}
@Override
- public boolean equals(final Object arg) {
- if (arg == this) return true;
- if (arg == null || (!(arg instanceof ArrayType))) {
- return false;
- }
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ final int hash = elementType.hashCode();
+ return ((hash << 5) - hash) + length;
+ }
+
+ @Override
+ protected boolean equalsImpl(final Type arg) {
+ final ArrayType t = (ArrayType) arg;
+ return elementType.equals(t.elementType) &&
+ length == t.length;
+ }
+
+ @Override
+ protected int hashCodeSemanticsImpl() {
+ // 31 * x == (x << 5) - x
+ final int hash = elementType.hashCodeSemantics();
+ return ((hash << 5) - hash) + length;
+ }
+
+ @Override
+ protected boolean equalSemanticsImpl(final Type arg) {
final ArrayType t = (ArrayType) arg;
- return (super.equals(arg) && elementType.equals(t.elementType) && (length == t.length));
+ return elementType.equalSemantics(t.elementType) &&
+ length == t.length;
}
@Override
+ public boolean hasName() { return null != elementType.getName(); }
+
+ @Override
public String getName(final boolean includeCVAttrs) {
- // Lazy computation of name due to lazy setting of compound type
- // names during parsing
- // Note: don't think cvAttributes can be set for array types (unlike pointer types)
- if (computedName == null) {
- computedName = (elementType.getName() + " *").intern();
- }
- return computedName;
+ return elementType.getName() + " *";
}
@Override
@@ -114,7 +128,7 @@ public class ArrayType extends MemoryLayoutType implements Cloneable {
if(elementType.isConst()) {
buf.append("const ");
}
- buf.append(elementType.getName());
+ buf.append(elementType.getCName());
if (variableName != null) {
buf.append(" ");
buf.append(variableName);
diff --git a/src/java/com/jogamp/gluegen/cgram/types/BitType.java b/src/java/com/jogamp/gluegen/cgram/types/BitType.java
index 2644551..87eb8ce 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/BitType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/BitType.java
@@ -40,6 +40,8 @@
package com.jogamp.gluegen.cgram.types;
+import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
+
/** Represents a bitfield in a struct. */
public class BitType extends IntType implements Cloneable {
@@ -55,14 +57,35 @@ public class BitType extends IntType implements Cloneable {
}
@Override
- public boolean equals(final Object arg) {
- if (arg == this) return true;
- if (arg == null || (!(arg instanceof BitType))) {
- return false;
- }
- final BitType t = (BitType) arg;
- return (super.equals(arg) && underlyingType.equals(t.underlyingType) &&
- (sizeInBits == t.sizeInBits) && (offset == t.offset));
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ int hash = underlyingType.hashCode();
+ hash = ((hash << 5) - hash) + sizeInBits;
+ return ((hash << 5) - hash) + offset;
+ }
+
+ @Override
+ protected boolean equalsImpl(final Type arg) {
+ final BitType t = (BitType) arg;
+ return underlyingType.equals(t.underlyingType) &&
+ sizeInBits == t.sizeInBits &&
+ offset == t.offset;
+ }
+
+ @Override
+ protected int hashCodeSemanticsImpl() {
+ // 31 * x == (x << 5) - x
+ int hash = underlyingType.hashCodeSemantics();
+ hash = ((hash << 5) - hash) + sizeInBits;
+ return ((hash << 5) - hash) + offset;
+ }
+
+ @Override
+ protected boolean equalSemanticsImpl(final Type arg) {
+ final BitType t = (BitType) arg;
+ return underlyingType.equalSemantics(t.underlyingType) &&
+ sizeInBits == t.sizeInBits &&
+ offset == t.offset;
}
@Override
diff --git a/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java b/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java
index 9716f54..c3aca40 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java
@@ -46,29 +46,67 @@ import java.util.*;
and unions. The boolean type accessors indicate how the type is
really defined. */
-public abstract class CompoundType extends MemoryLayoutType implements Cloneable {
+public abstract class CompoundType extends MemoryLayoutType implements Cloneable, AliasedSymbol {
// The name "foo" in the construct "struct foo { ... }";
- private String structName;
+ private final String structName;
private ArrayList<Field> fields;
private boolean visiting;
private boolean bodyParsed;
- private boolean computedHashcode;
- private int hashcode;
-
+ /**
+ *
+ * @param name
+ * @param size
+ * @param cvAttributes
+ * @param structName
+ */
CompoundType(final String name, final SizeThunk size, final int cvAttributes, final String structName) {
super(name, size, cvAttributes);
this.structName = structName;
}
- public static CompoundType create(final String name, final SizeThunk size, final CompoundTypeKind kind, final int cvAttributes) {
+ @Override
+ public void rename(final String newName) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void addAliasedName(final String origName) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public boolean hasAliases() {
+ return false;
+ }
+ @Override
+ public Set<String> getAliasedNames() {
+ return null;
+ }
+ @Override
+ public String getAliasedString() {
+ return toString();
+ }
+
+ /**
+ * @param structName struct name of this CompoundType, i.e. the "foo" in the
+ construct {@code struct foo { int a, ... };} or {@code struct foo;} <i>even</i> for anonymous structs.
+ * @param size
+ * @param kind
+ * @param cvAttributes
+ * @return
+ */
+ public static CompoundType create(final String structName, final SizeThunk size, final CompoundTypeKind kind, final int cvAttributes)
+ {
+ final CompoundType res;
switch (kind) {
case STRUCT:
- return new StructType(name, size, cvAttributes);
+ res = new StructType(null, size, cvAttributes, structName);
+ break;
case UNION:
- return new UnionType(name, size, cvAttributes);
+ res = new UnionType(null, size, cvAttributes, structName);
+ break;
default:
throw new RuntimeException("OO relation "+kind+" / Compount not yet supported");
}
+ return res;
}
@Override
@@ -81,34 +119,31 @@ public abstract class CompoundType extends MemoryLayoutType implements Cloneable
}
@Override
- public int hashCode() {
- if (computedHashcode) {
- return hashcode;
- }
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ final int hash = 31 + ( null != structName ? structName.hashCode() : 0 );
+ return ((hash << 5) - hash) + TypeComparator.listsHashCode(fields);
+ }
- if (structName != null) {
- hashcode = structName.hashCode();
- } else if (getName() != null) {
- hashcode = getName().hashCode();
- } else {
- hashcode = 0;
- }
+ @Override
+ protected boolean equalsImpl(final Type arg) {
+ final CompoundType ct = (CompoundType) arg;
+ return ( (structName == null ? ct.structName == null : structName.equals(ct.structName)) ||
+ (structName != null && structName.equals(ct.structName))
+ ) &&
+ TypeComparator.listsEqual(fields, ct.fields);
+ }
- computedHashcode = true;
- return hashcode;
+ @Override
+ protected int hashCodeSemanticsImpl() {
+ // 31 * x == (x << 5) - x
+ return TypeComparator.listsHashCodeSemantics(fields);
}
@Override
- public boolean equals(final Object arg) {
- if (arg == this) return true;
- if (arg == null || !(arg instanceof CompoundType)) {
- return false;
- }
- final CompoundType t = (CompoundType) arg;
- return super.equals(arg) &&
- ((structName == null ? t.structName == null : structName.equals(t.structName)) ||
- (structName != null && structName.equals(t.structName))) &&
- listsEqual(fields, t.fields);
+ protected boolean equalSemanticsImpl(final Type arg) {
+ final CompoundType ct = (CompoundType) arg;
+ return TypeComparator.listsEqualSemantics(fields, ct.fields);
}
/** Returns the struct name of this CompoundType, i.e. the "foo" in
@@ -117,12 +152,6 @@ public abstract class CompoundType extends MemoryLayoutType implements Cloneable
return structName;
}
- /** Sets the struct name of this CompoundType, i.e. the "foo" in the
- construct "struct foo { ... };". */
- public void setStructName(final String structName) {
- this.structName = structName;
- }
-
@Override
public void setSize(final SizeThunk size) {
super.setSize(size);
@@ -131,8 +160,17 @@ public abstract class CompoundType extends MemoryLayoutType implements Cloneable
@Override
public CompoundType asCompound() { return this; }
+ @Override
+ public String getCName(final boolean includeCVAttrs) {
+ if( hasTypedefName() ) {
+ return getName(includeCVAttrs);
+ } else {
+ return (isStruct() ? "struct " : "union ")+getName(includeCVAttrs);
+ }
+ }
+
ArrayList<Field> getFields() { return fields; }
- void setFields(final ArrayList<Field> fields) { this.fields = fields; }
+ void setFields(final ArrayList<Field> fields) { this.fields = fields; clearCache(); }
/** Returns the number of fields in this type. */
public int getNumFields() {
@@ -147,18 +185,42 @@ public abstract class CompoundType extends MemoryLayoutType implements Cloneable
/** Adds a field to this type. */
public void addField(final Field f) {
if (bodyParsed) {
- throw new RuntimeException("Body of this CompoundType has already been parsed; should not be adding more fields");
+ throw new IllegalStateException("Body of this CompoundType has been already closed");
}
if (fields == null) {
fields = new ArrayList<Field>();
}
fields.add(f);
+ clearCache();
}
- /** Indicates to this CompoundType that its body has been parsed and
- that no more {@link #addField} operations will be made. */
- public void setBodyParsed() {
+ /**
+ * Indicates to this CompoundType that its body has been parsed and
+ * that no more {@link #addField} operations will be made.
+ * <p>
+ * If {@code evalStructTypeName} is {@code true}, {@link #evalStructTypeName()} is performed.
+ * </p>
+ * @throws IllegalStateException If called twice.
+ */
+ public void setBodyParsed(final boolean evalStructTypeName) throws IllegalStateException {
+ if (bodyParsed) {
+ throw new IllegalStateException("Body of this CompoundType has been already closed");
+ }
bodyParsed = true;
+ if( evalStructTypeName ) {
+ evalStructTypeName();
+ }
+ }
+ public boolean isBodyParsed() { return bodyParsed; }
+ /**
+ * {@link #getName() name} is set to {@link #getStructName() struct-name},
+ * which promotes this instance for emission by its struct-name.
+ */
+ public Type evalStructTypeName() {
+ if( null == getName() ) {
+ setName(structName);
+ }
+ return this;
}
/** Indicates whether this type was declared as a struct. */
@@ -169,8 +231,9 @@ public abstract class CompoundType extends MemoryLayoutType implements Cloneable
@Override
public String toString() {
final String cvAttributesString = getCVAttributesString();
- if (getName() != null) {
- return cvAttributesString + getName();
+ final String cname = getCName();
+ if ( null != cname ) {
+ return cvAttributesString + cname;
} else if (getStructName() != null) {
return cvAttributesString + "struct " + getStructName();
} else {
diff --git a/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java b/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java
index de42522..1e13701 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java
@@ -47,19 +47,28 @@ public class DoubleType extends PrimitiveType implements Cloneable {
}
@Override
- public boolean equals(final Object arg) {
- if (arg == this) {
- return true;
- }
- if (arg == null || (!(arg instanceof DoubleType))) {
- return false;
- }
- return super.equals(arg);
+ public DoubleType asDouble() {
+ return this;
}
@Override
- public DoubleType asDouble() {
- return this;
+ protected int hashCodeImpl() {
+ return 0;
+ }
+
+ @Override
+ protected boolean equalsImpl(final Type t) {
+ return true;
+ }
+
+ @Override
+ protected int hashCodeSemanticsImpl() {
+ return 0;
+ }
+
+ @Override
+ protected boolean equalSemanticsImpl(final Type t) {
+ return true;
}
@Override
diff --git a/src/java/com/jogamp/gluegen/cgram/types/EnumType.java b/src/java/com/jogamp/gluegen/cgram/types/EnumType.java
index 0b1193b..f0e71dc 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/EnumType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/EnumType.java
@@ -42,6 +42,8 @@ package com.jogamp.gluegen.cgram.types;
import java.util.ArrayList;
import java.util.NoSuchElementException;
+import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
+
/** Describes enumerated types. Enumerations are like ints except that
they have a set of named values. */
@@ -49,10 +51,9 @@ public class EnumType extends IntType implements Cloneable {
private IntType underlyingType;
- private static class Enum {
-
- String name;
- long value;
+ private static class Enum implements TypeComparator.SemanticEqualityOp {
+ final String name;
+ final long value;
Enum(final String name, final long value) {
this.name = name;
@@ -66,6 +67,37 @@ public class EnumType extends IntType implements Cloneable {
long getValue() {
return value;
}
+
+ @Override
+ public int hashCode() {
+ // 31 * x == (x << 5) - x
+ final int hash = name.hashCode();
+ return ((hash << 5) - hash) + (int)(value ^ (value >>> 32));
+ }
+
+ @Override
+ public boolean equals(final Object arg) {
+ if (arg == this) {
+ return true;
+ } else if ( !(arg instanceof Enum) ) {
+ return false;
+ }
+ final Enum t = (Enum) arg;
+ return name.equals(t.name) &&
+ value == t.value;
+ }
+
+ @Override
+ public int hashCodeSemantics() {
+ return hashCode();
+ }
+
+ @Override
+ public boolean equalSemantics(final SemanticEqualityOp arg) {
+ return equals(arg);
+ }
+
+ public String toString() { return name+" = "+value; }
}
private ArrayList<Enum> enums;
@@ -98,17 +130,31 @@ public class EnumType extends IntType implements Cloneable {
}
@Override
- public boolean equals(final Object arg) {
- if (arg == this) {
- return true;
- }
- if (arg == null || (!(arg instanceof EnumType))) {
- return false;
- }
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ final int hash = underlyingType.hashCode();
+ return ((hash << 5) - hash) + TypeComparator.listsHashCode(enums);
+ }
+
+ @Override
+ protected boolean equalsImpl(final Type arg) {
final EnumType t = (EnumType) arg;
- return (super.equals(arg)
- && underlyingType.equals(t.underlyingType)
- && listsEqual(enums, t.enums));
+ return underlyingType.equals(t.underlyingType) &&
+ TypeComparator.listsEqual(enums, t.enums);
+ }
+
+ @Override
+ protected int hashCodeSemanticsImpl() {
+ // 31 * x == (x << 5) - x
+ final int hash = underlyingType.hashCodeSemantics();
+ return ((hash << 5) - hash) + TypeComparator.listsHashCodeSemantics(enums);
+ }
+
+ @Override
+ protected boolean equalSemanticsImpl(final Type arg) {
+ final EnumType t = (EnumType) arg;
+ return underlyingType.equalSemantics(t.underlyingType) &&
+ TypeComparator.listsEqualSemantics(enums, t.enums);
}
@Override
@@ -116,11 +162,14 @@ public class EnumType extends IntType implements Cloneable {
return this;
}
+ public Type getUnderlyingType() { return this.underlyingType; }
+
public void addEnum(final String name, final long val) {
if (enums == null) {
enums = new ArrayList<Enum>();
}
enums.add(new Enum(name, val));
+ clearCache();
}
/** Number of enumerates defined in this enum. */
@@ -169,12 +218,24 @@ public class EnumType extends IntType implements Cloneable {
final Enum e = enums.get(i);
if (e.getName().equals(name)) {
enums.remove(e);
+ clearCache();
return true;
}
}
return false;
}
+ public StringBuilder appendEnums(final StringBuilder sb, final boolean cr) {
+ for(int i=0; i<enums.size(); i++) {
+ sb.append(enums.get(i)).append(", ");
+ if( cr ) {
+ sb.append(String.format("%n"));
+ }
+ }
+ sb.append("}");
+ return sb;
+ }
+
@Override
public void visit(final TypeVisitor arg) {
super.visit(arg);
diff --git a/src/java/com/jogamp/gluegen/cgram/types/Field.java b/src/java/com/jogamp/gluegen/cgram/types/Field.java
index 858d81a..a8fc599 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/Field.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/Field.java
@@ -40,10 +40,11 @@
package com.jogamp.gluegen.cgram.types;
import com.jogamp.common.os.MachineDataInfo;
+import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
/** Represents a field in a struct or union. */
-public class Field {
+public class Field implements SemanticEqualityOp {
private final String name;
private final Type type;
private SizeThunk offset;
@@ -56,21 +57,41 @@ public class Field {
@Override
public int hashCode() {
- return name.hashCode();
+ // 31 * x == (x << 5) - x
+ final int hash = 31 + ( null != name ? name.hashCode() : 0 );
+ return ((hash << 5) - hash) + type.hashCode();
}
@Override
public boolean equals(final Object arg) {
- if (arg == null || (!(arg instanceof Field))) {
+ if ( !(arg instanceof Field) ) {
return false;
}
final Field f = (Field) arg;
// Note: don't know how to examine offset any more since it's
// implemented in terms of code and they're not canonicalized
- return (((name != null && name.equals(f.name)) ||
- (name == null && f.name == null)) &&
- type.equals(f.type));
+ return ( ( name != null && name.equals(f.name) ) ||
+ ( name == null && f.name == null )
+ ) &&
+ type.equals(f.type);
+ }
+
+ @Override
+ public int hashCodeSemantics() {
+ return type.hashCodeSemantics();
+ }
+
+ @Override
+ public boolean equalSemantics(final SemanticEqualityOp arg) {
+ if ( !(arg instanceof Field) ) {
+ return false;
+ }
+
+ final Field f = (Field) arg;
+ // Note: don't know how to examine offset any more since it's
+ // implemented in terms of code and they're not canonicalized
+ return type.equalSemantics(f.type);
}
/** Name of this field in the containing data structure. */
diff --git a/src/java/com/jogamp/gluegen/cgram/types/FloatType.java b/src/java/com/jogamp/gluegen/cgram/types/FloatType.java
index d8b0b13..0428543 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/FloatType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/FloatType.java
@@ -48,18 +48,27 @@ public class FloatType extends PrimitiveType implements Cloneable {
}
@Override
- public boolean equals(final Object arg) {
- if (arg == this) {
+ public FloatType asFloat() { return this; }
+
+ @Override
+ protected int hashCodeImpl() {
+ return 0;
+ }
+
+ @Override
+ protected boolean equalsImpl(final Type t) {
return true;
- }
- if (arg == null || (!(arg instanceof FloatType))) {
- return false;
- }
- return super.equals(arg);
}
@Override
- public FloatType asFloat() { return this; }
+ protected int hashCodeSemanticsImpl() {
+ return 0;
+ }
+
+ @Override
+ protected boolean equalSemanticsImpl(final Type t) {
+ return true;
+ }
@Override
Type newCVVariant(final int cvAttributes) {
diff --git a/src/java/com/jogamp/gluegen/cgram/types/FunctionSymbol.java b/src/java/com/jogamp/gluegen/cgram/types/FunctionSymbol.java
index d41f2fd..ee68b68 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/FunctionSymbol.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/FunctionSymbol.java
@@ -38,6 +38,12 @@
*/
package com.jogamp.gluegen.cgram.types;
+import java.util.List;
+
+import com.jogamp.gluegen.cgram.types.AliasedSymbol.AliasedSymbolImpl;
+import com.jogamp.gluegen.cgram.types.TypeComparator.AliasedSemanticSymbol;
+import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
+
/**
* Describes a function symbol, which includes the name and
@@ -51,20 +57,15 @@ package com.jogamp.gluegen.cgram.types;
* Deep comparison can be performed via {@link #isCompletelyEqual(Object o)};
* </p>
**/
-public class FunctionSymbol {
+public class FunctionSymbol extends AliasedSymbolImpl implements AliasedSemanticSymbol {
- private final String name;
private final FunctionType type;
public FunctionSymbol(final String name, final FunctionType type) {
- this.name = name;
+ super(name);
this.type = type;
}
- public String getName() {
- return name;
- }
-
/** Returns the type of this function. Do not add arguments to it
directly; use addArgument instead. */
public FunctionType getType() {
@@ -109,10 +110,10 @@ public class FunctionSymbol {
@Override
public int hashCode() {
- if (name == null) {
+ if (getName() == null) {
return 0;
}
- return name.hashCode();
+ return getName().hashCode();
}
@Override
@@ -120,25 +121,54 @@ public class FunctionSymbol {
if (arg == this) {
return true;
}
-
- if (arg == null || (!(arg instanceof FunctionSymbol))) {
+ if ( !(arg instanceof FunctionSymbol) ) {
return false;
}
-
final FunctionSymbol other = (FunctionSymbol) arg;
-
if (getName() == null && other.getName() != null) {
return false;
}
-
return getName().equals(other.getName());
}
+ @Override
+ public int hashCodeSemantics() {
+ return type.hashCodeSemantics();
+ }
+ @Override
+ public final boolean equalSemantics(final SemanticEqualityOp arg) {
+ if (arg == this) {
+ return true;
+ }
+ if ( !(arg instanceof FunctionSymbol) ) {
+ return false;
+ }
+ final FunctionSymbol other = (FunctionSymbol) arg;
+ return type.equalSemantics(other.type);
+ }
+
+
+ public static boolean containsExactly(final List<FunctionSymbol> l, final FunctionSymbol s) {
+ return exactIndexOf(l, s) >= 0;
+ }
+
+ public static int exactIndexOf(final List<FunctionSymbol> l, final FunctionSymbol s) {
+ final int size = l.size();
+ for (int i = 0; i < size; i++) {
+ final FunctionSymbol e = l.get(i);
+ if( null == s && null == e ||
+ s.equals( e ) && s.type.equals(e.type) ) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
/**
* Compares the function type as well, since {@link #equals(Object)}
* and {@link #hashCode()} won't.
*/
- public boolean isCompletelyEqual(final Object arg) {
+ public boolean exactlyEqual(final Object arg) {
if( !this.equals(arg) ) {
return false;
}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java b/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java
index 4b39a34..b0d16e1 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java
@@ -41,6 +41,8 @@ package com.jogamp.gluegen.cgram.types;
import java.util.*;
+import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
+
/** Describes a function type, used to model both function
declarations and (via PointerType) function pointers. */
public class FunctionType extends Type implements Cloneable {
@@ -67,17 +69,31 @@ public class FunctionType extends Type implements Cloneable {
}
@Override
- public boolean equals(final Object arg) {
- if (arg == this) {
- return true;
- }
- if (arg == null || (!(arg instanceof FunctionType))) {
- return false;
- }
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ final int hash = returnType.hashCode();
+ return ((hash << 5) - hash) + TypeComparator.listsHashCode(argumentTypes);
+ }
+
+ @Override
+ protected boolean equalsImpl(final Type arg) {
+ final FunctionType t = (FunctionType) arg;
+ return returnType.equals(t.returnType) &&
+ TypeComparator.listsEqual(argumentTypes, t.argumentTypes);
+ }
+
+ @Override
+ protected int hashCodeSemanticsImpl() {
+ // 31 * x == (x << 5) - x
+ final int hash = returnType.hashCodeSemantics();
+ return ((hash << 5) - hash) + TypeComparator.listsHashCodeSemantics(argumentTypes);
+ }
+
+ @Override
+ protected boolean equalSemanticsImpl(final Type arg) {
final FunctionType t = (FunctionType) arg;
- return (super.equals(arg)
- && returnType.equals(t.returnType)
- && listsEqual(argumentTypes, t.argumentTypes));
+ return returnType.equalSemantics(t.returnType) &&
+ TypeComparator.listsEqualSemantics(argumentTypes, t.argumentTypes);
}
@Override
@@ -115,10 +131,12 @@ public class FunctionType extends Type implements Cloneable {
}
argumentTypes.add(argumentType);
argumentNames.add(argumentName);
+ clearCache();
}
public void setArgumentName(final int i, final String name) {
argumentNames.set(i, name);
+ clearCache();
}
@Override
@@ -136,7 +154,7 @@ public class FunctionType extends Type implements Cloneable {
String toString(final String functionName, final String callingConvention, final boolean emitNativeTag, final boolean isPointer) {
final StringBuilder res = new StringBuilder();
- res.append(getReturnType());
+ res.append(getReturnType().getCName(true));
res.append(" ");
if (isPointer) {
res.append("(");
@@ -169,7 +187,7 @@ public class FunctionType extends Type implements Cloneable {
} else if (t.isArray()) {
res.append(t.asArray().toString(getArgumentName(i)));
} else {
- res.append(t);
+ res.append(t.getCName(true));
final String argumentName = getArgumentName(i);
if (argumentName != null) {
res.append(" ");
diff --git a/src/java/com/jogamp/gluegen/cgram/types/IntType.java b/src/java/com/jogamp/gluegen/cgram/types/IntType.java
index 3f8dddc..502fe2a 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/IntType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/IntType.java
@@ -55,20 +55,36 @@ public class IntType extends PrimitiveType implements Cloneable {
}
@Override
- public boolean equals(final Object arg) {
- if (arg == this) {
- return true;
- }
- if (arg == null || (!(arg instanceof IntType))) {
- return false;
- }
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ final int hash = 31 + ( unsigned ? 1 : 0 );
+ return ((hash << 5) - hash) + ( typedefedUnsigned ? 1 : 0 );
+ }
+
+ @Override
+ protected boolean equalsImpl(final Type arg) {
+ final IntType t = (IntType) arg;
+ return unsigned == t.unsigned &&
+ typedefedUnsigned == t.typedefedUnsigned;
+ }
+
+ @Override
+ protected int hashCodeSemanticsImpl() {
+ return hashCodeImpl();
+ }
+
+ @Override
+ protected boolean equalSemanticsImpl(final Type arg) {
final IntType t = (IntType) arg;
- return (super.equals(arg) && (unsigned == t.unsigned));
+ return relaxedEqSem ||
+ ( unsigned == t.unsigned &&
+ typedefedUnsigned == t.typedefedUnsigned
+ );
}
@Override
- public void setName(final String name) {
- super.setName(name);
+ public void setTypedefName(final String name) {
+ super.setTypedefName(name);
typedefedUnsigned = unsigned;
}
@@ -89,7 +105,7 @@ public class IntType extends PrimitiveType implements Cloneable {
@Override
public String toString() {
- return getCVAttributesString() + ((isUnsigned() & (!typedefedUnsigned)) ? "unsigned " : "") + getName();
+ return getCVAttributesString() + ((isUnsigned() & (!typedefedUnsigned)) ? "unsigned " : "") + getCName();
}
@Override
diff --git a/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java b/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java
index 25d2d1d..fb8c86b 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java
@@ -36,6 +36,8 @@ public abstract class MemoryLayoutType extends Type {
}
public boolean isLayouted() { return isLayouted; }
- public void setLayouted() { isLayouted = true; }
+ public void setLayouted() {
+ isLayouted = true;
+ }
}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/PointerType.java b/src/java/com/jogamp/gluegen/cgram/types/PointerType.java
index d1dfb17..c6496bb 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/PointerType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/PointerType.java
@@ -42,72 +42,68 @@ package com.jogamp.gluegen.cgram.types;
public class PointerType extends Type implements Cloneable {
private final Type targetType;
- private String computedName;
- private boolean hasTypedefedName;
- public PointerType(final SizeThunk size, final Type targetType, final int cvAttributes) {
+ public PointerType(final SizeThunk size, final Type targetType, final int cvAttributes, final String typedefedName) {
// can pass null for the final name parameter because the PointerType's getName()
// completely replaces superclass behavior
- this(size, targetType, cvAttributes, false, null);
- }
-
- private PointerType(final SizeThunk size, final Type targetType, final int cvAttributes, final boolean hasTypedefedName, final String typedefedName) {
super(targetType.getName() + " *", size, cvAttributes);
- this.hasTypedefedName = false;
this.targetType = targetType;
- if (hasTypedefedName) {
- setName(typedefedName);
+ if (null != typedefedName) {
+ setTypedefName(typedefedName);
}
}
@Override
- public int hashCode() {
- return targetType.hashCode();
+ protected int hashCodeImpl() {
+ return targetType.hashCode();
}
@Override
- public boolean equals(final Object arg) {
- if (arg == this) {
- return true;
- }
- if (arg == null || (!(arg instanceof PointerType))) {
- return false;
- }
+ protected boolean equalsImpl(final Type arg) {
final PointerType t = (PointerType) arg;
- // Note we ignore the name of this type (which might be a typedef
- // name) for comparison purposes because this is what allows
- // e.g. a newly-fabricated type "PIXELFORMATDESCRIPTOR *" to be
- // canonicalized to e.g. "LPPIXELFORMATDESCRIPTOR"
- return ((getSize() == t.getSize())
- && (getCVAttributes() == t.getCVAttributes())
- && targetType.equals(t.targetType));
+ return targetType.equals(t.targetType);
+ }
+
+ @Override
+ protected int hashCodeSemanticsImpl() {
+ return targetType.hashCodeSemantics();
+ }
+
+ @Override
+ protected boolean equalSemanticsImpl(final Type arg) {
+ final PointerType pt = (PointerType) arg;
+ return targetType.equalSemantics(pt.targetType);
}
@Override
- public void setName(final String name) {
- super.setName(name);
- hasTypedefedName = true;
+ public boolean hasName() {
+ if ( hasTypedefName() ) {
+ return super.hasName();
+ } else {
+ return targetType.hasName();
+ }
}
@Override
public String getName(final boolean includeCVAttrs) {
- if (hasTypedefedName) {
+ if ( hasTypedefName() ) {
return super.getName(includeCVAttrs);
+ } else if (!includeCVAttrs) {
+ return targetType.getName(includeCVAttrs) + " *";
} else {
- // Lazy computation of name due to lazy setting of compound type
- // names during parsing
- if (computedName == null) {
- computedName = (targetType.getName(includeCVAttrs) + " *").intern();
- }
- if (!includeCVAttrs) {
- return computedName;
- }
return targetType.getName(includeCVAttrs) + " * " + getCVAttributesString();
}
}
- public boolean hasTypedefedName() {
- return hasTypedefedName;
+ @Override
+ public String getCName(final boolean includeCVAttrs) {
+ if ( hasTypedefName() ) {
+ return super.getCName(includeCVAttrs);
+ } else if (!includeCVAttrs) {
+ return targetType.getCName(includeCVAttrs) + " *";
+ } else {
+ return targetType.getCName(includeCVAttrs) + " * " + getCVAttributesString();
+ }
}
@Override
@@ -115,6 +111,7 @@ public class PointerType extends Type implements Cloneable {
return this;
}
+ @Override
public Type getTargetType() {
return targetType;
}
@@ -137,13 +134,18 @@ public class PointerType extends Type implements Cloneable {
@Override
public String toString() {
- if (hasTypedefedName) {
- return super.getName(true);
+ if ( hasTypedefName() ) {
+ return super.getCName(true);
+ } else {
+ return toStringInt();
+ }
+ }
+ private String toStringInt() {
+ if (!targetType.isFunction()) {
+ return targetType.getCName(true) + " * " + getCVAttributesString();
} else {
- if (!targetType.isFunction()) {
- return targetType.toString() + " * " + getCVAttributesString();
- }
- return toString(null, null); // this is a pointer to an unnamed function
+ // return toString(null, null); // this is a pointer to an unnamed function
+ return ((FunctionType) targetType).toString(null /* functionName */, null /* callingConvention */, false, true);
}
}
@@ -165,6 +167,6 @@ public class PointerType extends Type implements Cloneable {
@Override
Type newCVVariant(final int cvAttributes) {
- return new PointerType(getSize(), targetType, cvAttributes, hasTypedefedName, (hasTypedefedName ? getName() : null));
+ return new PointerType(getSize(), targetType, cvAttributes, (hasTypedefName() ? getName() : null));
}
}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/SizeThunk.java b/src/java/com/jogamp/gluegen/cgram/types/SizeThunk.java
index 9843d6b..7a9c62a 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/SizeThunk.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/SizeThunk.java
@@ -41,17 +41,25 @@
package com.jogamp.gluegen.cgram.types;
import com.jogamp.common.os.MachineDataInfo;
+import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
/** Provides a level of indirection between the definition of a type's
size and the absolute value of this size. Necessary when
generating glue code for two different CPU architectures (e.g.,
32-bit and 64-bit) from the same internal representation of the
various types involved. */
-public abstract class SizeThunk implements Cloneable {
+public abstract class SizeThunk implements Cloneable, SemanticEqualityOp {
+ /* pp */ static boolean relaxedEqSem = false;
private final boolean fixedNativeSize;
+ public static void setRelaxedEqualSemanticsTest(final boolean v) {
+ relaxedEqSem = v;
+ }
+
// Private constructor because there are only a few of these
- private SizeThunk(final boolean fixedNativeSize) { this.fixedNativeSize = fixedNativeSize; }
+ private SizeThunk(final boolean fixedNativeSize) {
+ this.fixedNativeSize = fixedNativeSize;
+ }
@Override
public Object clone() {
@@ -67,6 +75,55 @@ public abstract class SizeThunk implements Cloneable {
public abstract long computeSize(MachineDataInfo machDesc);
public abstract long computeAlignment(MachineDataInfo machDesc);
+ @Override
+ public final int hashCode() {
+ final int hash = 0x02DEAD6F; // magic hash start
+ return ((hash << 5) - hash) + hashCodeImpl();
+ }
+ /* pp */ abstract int hashCodeImpl();
+
+ @Override
+ public final boolean equals(final Object arg) {
+ if (arg == this) {
+ return true;
+ } else if ( !(arg instanceof SizeThunk) ) {
+ return false;
+ } else {
+ final SizeThunk t = (SizeThunk) arg;
+ return hashCodeImpl() == t.hashCodeImpl();
+ }
+ }
+
+ @Override
+ public final int hashCodeSemantics() {
+ final int hash = 0x01DEAD5F; // magic hash start
+ return ((hash << 5) - hash) + hashCodeSemanticsImpl();
+ }
+ /* pp */ abstract int hashCodeSemanticsImpl();
+
+ @Override
+ public final boolean equalSemantics(final SemanticEqualityOp arg) {
+ if (arg == this) {
+ return true;
+ } else if ( !(arg instanceof SizeThunk) ) {
+ return false;
+ } else {
+ final SizeThunk t = (SizeThunk) arg;
+ return hashCodeSemanticsImpl() == t.hashCodeSemanticsImpl();
+ }
+ }
+
+ static final int magic_int08 = 0x00000010;
+ static final int magic_int16 = 0x00000012;
+ static final int magic_int32 = 0x00000014;
+ static final int magic_intxx = 0x00000016;
+ static final int magic_long64 = 0x00000020;
+ static final int magic_longxx = 0x00000022;
+ static final int magic_float32 = 0x00000030;
+ static final int magic_float64 = 0x00000032;
+ static final int magic_aptr64 = 0x00000040;
+ static final int magic_ops = 0x00010000;
+
public static final SizeThunk INT8 = new SizeThunk(true) {
@Override
public long computeSize(final MachineDataInfo machDesc) {
@@ -76,6 +133,10 @@ public abstract class SizeThunk implements Cloneable {
public long computeAlignment(final MachineDataInfo machDesc) {
return machDesc.int8AlignmentInBytes();
}
+ @Override
+ protected int hashCodeImpl() { return 1; }
+ @Override
+ protected int hashCodeSemanticsImpl() { return relaxedEqSem ? magic_int32 : magic_int08; }
};
public static final SizeThunk INT16 = new SizeThunk(true) {
@@ -87,6 +148,10 @@ public abstract class SizeThunk implements Cloneable {
public long computeAlignment(final MachineDataInfo machDesc) {
return machDesc.int16AlignmentInBytes();
}
+ @Override
+ protected int hashCodeImpl() { return 2; }
+ @Override
+ protected int hashCodeSemanticsImpl() { return relaxedEqSem ? magic_int32 : magic_int16; }
};
public static final SizeThunk INT32 = new SizeThunk(true) {
@@ -98,6 +163,10 @@ public abstract class SizeThunk implements Cloneable {
public long computeAlignment(final MachineDataInfo machDesc) {
return machDesc.int32AlignmentInBytes();
}
+ @Override
+ protected int hashCodeImpl() { return 3; }
+ @Override
+ protected int hashCodeSemanticsImpl() { return magic_int32; }
};
public static final SizeThunk INTxx = new SizeThunk(false) {
@@ -109,6 +178,10 @@ public abstract class SizeThunk implements Cloneable {
public long computeAlignment(final MachineDataInfo machDesc) {
return machDesc.intAlignmentInBytes();
}
+ @Override
+ protected int hashCodeImpl() { return 4; }
+ @Override
+ protected int hashCodeSemanticsImpl() { return relaxedEqSem ? magic_int32 : magic_intxx; }
};
public static final SizeThunk LONG = new SizeThunk(false) {
@@ -120,6 +193,10 @@ public abstract class SizeThunk implements Cloneable {
public long computeAlignment(final MachineDataInfo machDesc) {
return machDesc.longAlignmentInBytes();
}
+ @Override
+ protected int hashCodeImpl() { return 5; }
+ @Override
+ protected int hashCodeSemanticsImpl() { return relaxedEqSem ? magic_long64 : magic_longxx; }
};
public static final SizeThunk INT64 = new SizeThunk(true) {
@@ -131,6 +208,10 @@ public abstract class SizeThunk implements Cloneable {
public long computeAlignment(final MachineDataInfo machDesc) {
return machDesc.int64AlignmentInBytes();
}
+ @Override
+ protected int hashCodeImpl() { return 6; }
+ @Override
+ protected int hashCodeSemanticsImpl() { return magic_long64; }
};
public static final SizeThunk FLOAT = new SizeThunk(true) {
@@ -142,6 +223,10 @@ public abstract class SizeThunk implements Cloneable {
public long computeAlignment(final MachineDataInfo machDesc) {
return machDesc.floatAlignmentInBytes();
}
+ @Override
+ protected int hashCodeImpl() { return 7; }
+ @Override
+ protected int hashCodeSemanticsImpl() { return magic_float32; }
};
public static final SizeThunk DOUBLE = new SizeThunk(true) {
@@ -153,6 +238,10 @@ public abstract class SizeThunk implements Cloneable {
public long computeAlignment(final MachineDataInfo machDesc) {
return machDesc.doubleAlignmentInBytes();
}
+ @Override
+ protected int hashCodeImpl() { return 8; }
+ @Override
+ protected int hashCodeSemanticsImpl() { return magic_float64; }
};
public static final SizeThunk POINTER = new SizeThunk(false) {
@@ -164,6 +253,10 @@ public abstract class SizeThunk implements Cloneable {
public long computeAlignment(final MachineDataInfo machDesc) {
return machDesc.pointerAlignmentInBytes();
}
+ @Override
+ protected int hashCodeImpl() { return 9; }
+ @Override
+ protected int hashCodeSemanticsImpl() { return magic_aptr64; }
};
// Factory methods for performing certain limited kinds of
@@ -181,6 +274,15 @@ public abstract class SizeThunk implements Cloneable {
final long thunk2A = thunk2.computeAlignment(machDesc);
return ( thunk1A > thunk2A ) ? thunk1A : thunk2A ;
}
+ @Override
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + 10;
+ hash = ((hash << 5) - hash) + ( null != thunk1 ? thunk1.hashCode() : 0 );
+ return ((hash << 5) - hash) + ( null != thunk2 ? thunk2.hashCode() : 0 );
+ }
+ @Override
+ protected int hashCodeSemanticsImpl() { return magic_ops + 1; }
};
}
@@ -197,6 +299,15 @@ public abstract class SizeThunk implements Cloneable {
final long thunk2A = thunk2.computeAlignment(machDesc);
return ( thunk1A > thunk2A ) ? thunk1A : thunk2A ;
}
+ @Override
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + 11;
+ hash = ((hash << 5) - hash) + ( null != thunk1 ? thunk1.hashCode() : 0 );
+ return ((hash << 5) - hash) + ( null != thunk2 ? thunk2.hashCode() : 0 );
+ }
+ @Override
+ protected int hashCodeSemanticsImpl() { return magic_ops + 2; }
};
}
@@ -239,6 +350,15 @@ public abstract class SizeThunk implements Cloneable {
final long thunk2A = alignmentThunk.computeAlignment(machDesc);
return ( thunk1A > thunk2A ) ? thunk1A : thunk2A ;
}
+ @Override
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + 12;
+ hash = ((hash << 5) - hash) + ( null != offsetThunk ? offsetThunk.hashCode() : 0 );
+ return ((hash << 5) - hash) + ( null != alignmentThunk ? alignmentThunk.hashCode() : 0 );
+ }
+ @Override
+ protected int hashCodeSemanticsImpl() { return magic_ops + 3; }
};
}
@@ -255,6 +375,15 @@ public abstract class SizeThunk implements Cloneable {
final long thunk2A = thunk2.computeAlignment(machDesc);
return ( thunk1A > thunk2A ) ? thunk1A : thunk2A ;
}
+ @Override
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + 13;
+ hash = ((hash << 5) - hash) + ( null != thunk1 ? thunk1.hashCode() : 0 );
+ return ((hash << 5) - hash) + ( null != thunk2 ? thunk2.hashCode() : 0 );
+ }
+ @Override
+ protected int hashCodeSemanticsImpl() { return magic_ops + 4; }
};
}
@@ -268,6 +397,14 @@ public abstract class SizeThunk implements Cloneable {
public long computeAlignment(final MachineDataInfo machDesc) {
return 1; // no alignment for constants
}
+ @Override
+ protected int hashCodeImpl() {
+ // 31 * x == (x << 5) - x
+ final int hash = 31 + 14;
+ return ((hash << 5) - hash) + constant;
+ }
+ @Override
+ protected int hashCodeSemanticsImpl() { return magic_ops + 5; }
};
}
}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/StructType.java b/src/java/com/jogamp/gluegen/cgram/types/StructType.java
index 27099e9..4998484 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/StructType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/StructType.java
@@ -38,14 +38,6 @@ public class StructType extends CompoundType {
}
@Override
- public boolean equals(final Object arg) {
- if (arg == null || !(arg instanceof StructType)) {
- return false;
- }
- return super.equals(arg);
- }
-
- @Override
public final boolean isStruct() { return true; }
@Override
public final boolean isUnion() { return false; }
@@ -54,6 +46,9 @@ public class StructType extends CompoundType {
Type newCVVariant(final int cvAttributes) {
final StructType t = new StructType(getName(), getSize(), cvAttributes, getStructName());
t.setFields(getFields());
+ if( hasTypedefName() ) {
+ t.setTypedefName( getName() );
+ }
return t;
}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/Type.java b/src/java/com/jogamp/gluegen/cgram/types/Type.java
index 28ba6b4..cd48aa0 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/Type.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/Type.java
@@ -40,27 +40,45 @@
package com.jogamp.gluegen.cgram.types;
-import java.util.List;
-
import com.jogamp.common.os.MachineDataInfo;
+import com.jogamp.gluegen.GlueGen;
+import com.jogamp.gluegen.TypeConfig;
+import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
/** Models a C type. Primitive types include int, float, and
double. All types have an associated name. Structs and unions are
modeled as "compound" types -- composed of fields of primitive or
other types. */
-public abstract class Type implements Cloneable {
-
+public abstract class Type implements Cloneable, SemanticEqualityOp {
+ public final boolean relaxedEqSem;
+ private final int cvAttributes;
private String name;
private SizeThunk size;
- private final int cvAttributes;
private int typedefedCVAttributes;
private boolean hasTypedefName;
+ private boolean hasCachedHash;
+ private int cachedHash;
+ private boolean hasCachedSemanticHash;
+ private int cachedSemanticHash;
protected Type(final String name, final SizeThunk size, final int cvAttributes) {
setName(name);
- this.size = size;
+ this.relaxedEqSem = TypeConfig.relaxedEqualSemanticsTest();
this.cvAttributes = cvAttributes;
- hasTypedefName = false;
+ this.size = size;
+ this.typedefedCVAttributes = 0;
+ this.hasTypedefName = false;
+ this.hasCachedHash = false;
+ this.cachedHash = 0;
+ this.hasCachedSemanticHash = false;
+ this.cachedSemanticHash = 0;
+ }
+
+ protected final void clearCache() {
+ cachedHash = 0;
+ hasCachedHash = false;
+ cachedSemanticHash = 0;
+ hasCachedHash = false;
}
@Override
@@ -72,14 +90,28 @@ public abstract class Type implements Cloneable {
}
}
+ public final boolean isAnonymous() { return null == name; }
+
+ public boolean hasName() { return null != name; }
+
+ /** Returns the name of this type. The returned string is suitable
+ for use as a type specifier for native C. Does not include any const/volatile
+ attributes. */
+ public final String getCName() { return getCName(false); }
+
+ /** Returns the name of this type, optionally including
+ const/volatile attributes. The returned string is suitable for
+ use as a type specifier for native C. */
+ public String getCName(final boolean includeCVAttrs) { return getName(includeCVAttrs); }
+
/** Returns the name of this type. The returned string is suitable
- for use as a type specifier. Does not include any const/volatile
+ for use as a type specifier for Java. Does not include any const/volatile
attributes. */
public final String getName() { return getName(false); }
/** Returns the name of this type, optionally including
const/volatile attributes. The returned string is suitable for
- use as a type specifier. */
+ use as a type specifier for Java. */
public String getName(final boolean includeCVAttrs) {
if (!includeCVAttrs) {
return name;
@@ -87,6 +119,18 @@ public abstract class Type implements Cloneable {
return getCVAttributesString() + name;
}
+ /**
+ * Returns a string representation of this type.
+ * The returned string is suitable for use as a type specifier for native C.
+ * It does contain an expanded description of structs/unions,
+ * hence may not be suitable for type declarations.
+ */
+ @Override
+ public String toString() {
+ return getCName(true);
+ }
+
+
private void append(final StringBuilder sb, final String val, final boolean prepComma) {
if( prepComma ) {
sb.append(", ");
@@ -98,15 +142,30 @@ public abstract class Type implements Cloneable {
final StringBuilder sb = new StringBuilder();
boolean prepComma = false;
sb.append("CType[");
+ sb.append("(").append(getClass().getSimpleName()).append(") ");
+ if( hasTypedefName() ) {
+ sb.append("typedef ");
+ }
if( null != name ) {
- append(sb, "'"+name+"'", prepComma); prepComma=true;
+ sb.append("'").append(name).append("'");
} else {
- append(sb, "ANON", prepComma); prepComma=true;
+ sb.append("ANON");
}
- if( hasTypedefName() ) {
- sb.append(" (typedef)");
+ final Type targetType = getTargetType();
+ if( null != targetType && this != targetType ) {
+ sb.append(" -> ");
+ if (!targetType.isFunction()) {
+ sb.append(targetType.toString() + " * " + getCVAttributesString());
+ } else {
+ sb.append(((FunctionType) targetType).toString(null /* functionName */, null /* callingConvention */, false, true));
+ }
+ }
+ if( GlueGen.debug() ) {
+ // sb.append(", o=0x"+Integer.toHexString(objHash())+" h=0x"+Integer.toHexString(hashCode()));
+ sb.append(", o=0x"+Integer.toHexString(objHash()));
}
- append(sb, "size ", prepComma); prepComma=true;
+ sb.append(", size ");
+ prepComma=true;
if( null != size ) {
final long mdSize;
{
@@ -137,14 +196,17 @@ public abstract class Type implements Cloneable {
append(sb, "bit", prepComma); prepComma=true;
}
if( isCompound() ) {
- sb.append("struct{").append(asCompound().getNumFields());
+ sb.append("struct{").append(asCompound().getStructName()).append(": ").append(asCompound().getNumFields());
append(sb, "}", prepComma); prepComma=true;
}
if( isDouble() ) {
append(sb, "double", prepComma); prepComma=true;
}
if( isEnum() ) {
- append(sb, "enum", prepComma); prepComma=true;
+ final EnumType eT = asEnum();
+ sb.append("enum ").append(" [").append(eT.getUnderlyingType()).append("] {").append(eT.getNumEnumerates()).append(": ");
+ eT.appendEnums(sb, false);
+ prepComma=true;
}
if( isFloat() ) {
append(sb, "float", prepComma); prepComma=true;
@@ -164,20 +226,33 @@ public abstract class Type implements Cloneable {
sb.append("]]");
return sb.toString();
}
+ private final int objHash() { return super.hashCode(); }
- /** Set the name of this type; used for handling typedefs. */
- public void setName(final String name) {
+
+ protected final void setName(final String name) {
if (name == null) {
this.name = name;
} else {
this.name = name.intern();
}
+ clearCache();
+ }
+
+ /** Set the name of this type; used for handling typedefs. */
+ public void setTypedefName(final String name) {
+ setName(name);
// Capture the const/volatile attributes at the time of typedef so
// we don't redundantly repeat them in the CV attributes string
typedefedCVAttributes = cvAttributes;
hasTypedefName = true;
}
+ /** Indicates whether {@link #setTypedefName(String)} has been called on this type,
+ indicating that it already has a typedef name. */
+ public final boolean hasTypedefName() {
+ return hasTypedefName;
+ }
+
/** SizeThunk which computes size of this type in bytes. */
public SizeThunk getSize() { return size; }
/** Size of this type in bytes according to the given MachineDataInfo. */
@@ -189,7 +264,10 @@ public abstract class Type implements Cloneable {
return thunk.computeSize(machDesc);
}
/** Set the size of this type; only available for CompoundTypes. */
- void setSize(final SizeThunk size) { this.size = size; }
+ void setSize(final SizeThunk size) {
+ this.size = size;
+ clearCache();
+ }
/** Casts this to a BitType or returns null if not a BitType. */
public BitType asBit() { return null; }
@@ -249,43 +327,92 @@ public abstract class Type implements Cloneable {
/** Hashcode for Types. */
@Override
- public int hashCode() {
- if (name == null) {
- return 0;
- }
-
- if (cvAttributes != 0) {
- final String nameWithAttribs = name + cvAttributes;
- return nameWithAttribs.hashCode();
+ public final int hashCode() {
+ if( !hasCachedHash ) {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + ( hasTypedefName ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( null != size ? size.hashCode() : 0 );
+ hash = ((hash << 5) - hash) + cvAttributes;
+ hash = ((hash << 5) - hash) + ( null != name ? name.hashCode() : 0 );
+ if( !hasTypedefName ) {
+ hash = ((hash << 5) - hash) + hashCodeImpl();
+ }
+ cachedHash = hash;
+ hasCachedHash = true;
}
- return name.hashCode();
+ return cachedHash;
}
+ protected abstract int hashCodeImpl();
/**
- * Equality test for Types.
+ * Equality test for Types inclusive its given {@link #getName() name}.
*/
@Override
- public boolean equals(final Object arg) {
+ public final boolean equals(final Object arg) {
if (arg == this) {
- return true;
+ return true;
+ } else if ( !getClass().isInstance(arg) ) { // implies null == arg || !(arg instanceof Type)
+ return false;
+ } else {
+ final Type t = (Type)arg;
+ if( hasTypedefName == t.hasTypedefName &&
+ ( ( null != size && size.equals(t.size) ) ||
+ ( null == size && null == t.size )
+ ) &&
+ cvAttributes == t.cvAttributes &&
+ ( null == name ? null == t.name : name.equals(t.name) )
+ )
+ {
+ if( !hasTypedefName ) {
+ return equalsImpl(t);
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
}
+ }
+ protected abstract boolean equalsImpl(final Type t);
- if ( !(arg instanceof Type) ) {
- return false;
+ @Override
+ public final int hashCodeSemantics() {
+ if( !hasCachedSemanticHash ) {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + ( null != size ? size.hashCodeSemantics() : 0 );
+ if( !relaxedEqSem ) {
+ hash = ((hash << 5) - hash) + cvAttributes;
+ }
+ hash = ((hash << 5) - hash) + hashCodeSemanticsImpl();
+ cachedSemanticHash = hash;
+ hasCachedSemanticHash = true;
}
-
- final Type t = (Type)arg;
- return size == t.size && cvAttributes == t.cvAttributes &&
- ( null == name ? null == t.name : name.equals(t.name) ) ;
+ return cachedSemanticHash;
}
+ protected abstract int hashCodeSemanticsImpl();
- /** Returns a string representation of this type. This string is not
- necessarily suitable for use as a type specifier; for example,
- it will contain an expanded description of structs/unions. */
@Override
- public String toString() {
- return getName(true);
+ public final boolean equalSemantics(final SemanticEqualityOp arg) {
+ if (arg == this) {
+ return true;
+ } else if ( !(arg instanceof Type) ||
+ !getClass().isInstance(arg) ) { // implies null == arg
+ return false;
+ } else {
+ final Type t = (Type) arg;
+ if( ( ( null != size && size.equalSemantics(t.size) ) ||
+ ( null == size && null == t.size )
+ ) &&
+ ( relaxedEqSem || cvAttributes == t.cvAttributes )
+ )
+ {
+ return equalSemanticsImpl(t);
+ } else {
+ return false;
+ }
+ }
}
+ protected abstract boolean equalSemanticsImpl(final Type t);
/** Visit this type and all of the component types of this one; for
example, the return type and argument types of a FunctionType. */
@@ -319,12 +446,6 @@ public abstract class Type implements Cloneable {
const/volatile attributes. */
abstract Type newCVVariant(int cvAttributes);
- /** Indicates whether setName() has been called on this type,
- indicating that it already has a typedef name. */
- public boolean hasTypedefName() {
- return hasTypedefName;
- }
-
/** Helper method for determining how many pointer indirections this
type represents (i.e., "void **" returns 2). Returns 0 if this
type is not a pointer type. */
@@ -358,8 +479,10 @@ public abstract class Type implements Cloneable {
return this;
}
- /** Helper routine for list equality comparison */
- static <C> boolean listsEqual(final List<C> a, final List<C> b) {
- return ((a == null && b == null) || (a != null && b != null && a.equals(b)));
+ /**
+ * Helper method to returns the target type of this type, in case another type is being referenced.
+ */
+ public Type getTargetType() {
+ return this;
}
}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/TypeComparator.java b/src/java/com/jogamp/gluegen/cgram/types/TypeComparator.java
new file mode 100644
index 0000000..850d953
--- /dev/null
+++ b/src/java/com/jogamp/gluegen/cgram/types/TypeComparator.java
@@ -0,0 +1,143 @@
+/**
+ * Copyright 2015 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.gluegen.cgram.types;
+
+import java.util.List;
+
+public class TypeComparator {
+ /**
+ * Supports semantic equality and hash functions for types.
+ */
+ public static interface SemanticEqualityOp {
+ /**
+ * Semantic hashcode for Types exclusive its given {@link #getName() name}.
+ * @see #equalSemantics(SemanticEqualityOp)
+ */
+ int hashCodeSemantics();
+
+ /**
+ * Semantic equality test for Types exclusive its given {@link #getName() name}.
+ * @see #hashCodeSemantics()
+ */
+ boolean equalSemantics(final SemanticEqualityOp arg);
+ }
+ /**
+ * Supports common interface for {@link SemanticEqualityOp} and {@link AliasedSymbol}.
+ */
+ public static interface AliasedSemanticSymbol extends AliasedSymbol, SemanticEqualityOp { };
+
+ /** Helper routine for list equality comparison*/
+ static <C> boolean listsEqual(final List<C> a, final List<C> b) {
+ if( a == null ) {
+ if( null != b ) {
+ return false;
+ } else {
+ return true; // elements equal, i.e. both null
+ }
+ }
+ if( b != null && a.size() == b.size() ) {
+ final int count = a.size();
+ for(int i=0; i<count; i++) {
+ final C ac = a.get(i);
+ final C bc = b.get(i);
+ if( null == ac ) {
+ if( null != bc ) {
+ return false;
+ } else {
+ continue; // elements equal, i.e. both null
+ }
+ }
+ if( !ac.equals(bc) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /** Helper routine for list hashCode */
+ static <C extends SemanticEqualityOp> int listsHashCode(final List<C> a) {
+ if( a == null ) {
+ return 0;
+ } else {
+ final int count = a.size();
+ int hash = 31;
+ for(int i=0; i<count; i++) {
+ final C ac = a.get(i);
+ hash = ((hash << 5) - hash) + ( null != ac ? ac.hashCode() : 0 );
+ }
+ return hash;
+ }
+ }
+
+ /** Helper routine for list semantic equality comparison*/
+ static <C extends SemanticEqualityOp> boolean listsEqualSemantics(final List<C> a, final List<C> b) {
+ if( a == null ) {
+ if( null != b ) {
+ return false;
+ } else {
+ return true; // elements equal, i.e. both null
+ }
+ }
+ if( b != null && a.size() == b.size() ) {
+ final int count = a.size();
+ for(int i=0; i<count; i++) {
+ final C ac = a.get(i);
+ final C bc = b.get(i);
+ if( null == ac ) {
+ if( null != bc ) {
+ return false;
+ } else {
+ continue; // elements equal, i.e. both null
+ }
+ }
+ if( !ac.equalSemantics(bc) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /** Helper routine for list hashCode */
+ static <C extends SemanticEqualityOp> int listsHashCodeSemantics(final List<C> a) {
+ if( a == null ) {
+ return 0;
+ } else {
+ final int count = a.size();
+ int hash = 31;
+ for(int i=0; i<count; i++) {
+ final C ac = a.get(i);
+ hash = ((hash << 5) - hash) + ( null != ac ? ac.hashCodeSemantics() : 0 );
+ }
+ return hash;
+ }
+ }
+}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/TypeDictionary.java b/src/java/com/jogamp/gluegen/cgram/types/TypeDictionary.java
index cd03388..c1cfcdf 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/TypeDictionary.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/TypeDictionary.java
@@ -41,6 +41,9 @@ package com.jogamp.gluegen.cgram.types;
import java.util.*;
+import com.jogamp.gluegen.GlueGen;
+import com.jogamp.gluegen.JavaConfiguration;
+
/** Utility class for recording names of typedefs and structs. */
@@ -63,6 +66,38 @@ public class TypeDictionary {
return map.get(name);
}
+ public List<Type> getEqualSemantics(final Type s, final JavaConfiguration cfg, final boolean skipOpaque) {
+ final List<Type> res = new ArrayList<Type>();
+ if( !skipOpaque || null == cfg.typeInfo(s) ) {
+ final Set<Map.Entry<String, Type>> entries = entrySet();
+ for(final Iterator<Map.Entry<String, Type>> iter = entries.iterator(); iter.hasNext(); ) {
+ final Map.Entry<String, Type> entry = iter.next();
+ final Type t = entry.getValue();
+ if( s.equalSemantics(t) ) {
+ if( !skipOpaque || null == cfg.typeInfo(t) ) {
+ if( GlueGen.debug() ) {
+ System.err.println(" tls["+res.size()+"]: -> "+entry.getKey()+" -> "+t.getDebugString());
+ }
+ res.add(t);
+ }
+ }
+ }
+ }
+ return res;
+ }
+ public Type getEqualSemantics1(final Type s, final JavaConfiguration cfg, final boolean skipOpaque) {
+ final List<Type> tls = getEqualSemantics(s, cfg, skipOpaque);
+ if( tls.size() > 0 ) {
+ final Type res = tls.get(0);
+ if( GlueGen.debug() ) {
+ System.err.println(" tls.0: "+res.getDebugString());
+ }
+ return res;
+ } else {
+ return null;
+ }
+ }
+
//this method is broken
/**
* Get the names that correspond to the given type. There will be more than
diff --git a/src/java/com/jogamp/gluegen/cgram/types/UnionType.java b/src/java/com/jogamp/gluegen/cgram/types/UnionType.java
index 99d2fed..6ccc4a2 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/UnionType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/UnionType.java
@@ -38,14 +38,6 @@ public class UnionType extends CompoundType {
}
@Override
- public boolean equals(final Object arg) {
- if (arg == null || !(arg instanceof UnionType)) {
- return false;
- }
- return super.equals(arg);
- }
-
- @Override
public final boolean isStruct() { return false; }
@Override
public final boolean isUnion() { return true; }
@@ -54,6 +46,9 @@ public class UnionType extends CompoundType {
Type newCVVariant(final int cvAttributes) {
final UnionType t = new UnionType(getName(), getSize(), cvAttributes, getStructName());
t.setFields(getFields());
+ if( hasTypedefName() ) {
+ t.setTypedefName( getName() );
+ }
return t;
}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/VoidType.java b/src/java/com/jogamp/gluegen/cgram/types/VoidType.java
index 2e1f069..f6adaac 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/VoidType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/VoidType.java
@@ -58,4 +58,24 @@ public class VoidType extends Type implements Cloneable {
Type newCVVariant(final int cvAttributes) {
return new VoidType(getName(), cvAttributes);
}
+
+ @Override
+ protected int hashCodeImpl() {
+ return 0;
+ }
+
+ @Override
+ protected boolean equalsImpl(final Type t) {
+ return true;
+ }
+
+ @Override
+ protected int hashCodeSemanticsImpl() {
+ return 0;
+ }
+
+ @Override
+ protected boolean equalSemanticsImpl(final Type t) {
+ return true;
+ }
}
diff --git a/src/java/com/jogamp/gluegen/pcpp/PCPP.java b/src/java/com/jogamp/gluegen/pcpp/PCPP.java
index aca7b14..72b46a1 100644
--- a/src/java/com/jogamp/gluegen/pcpp/PCPP.java
+++ b/src/java/com/jogamp/gluegen/pcpp/PCPP.java
@@ -57,6 +57,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
+
+import com.jogamp.gluegen.Logging;
+
import static java.util.logging.Level.*;
/** A minimal pseudo-C-preprocessor designed in particular to preserve
@@ -65,7 +68,7 @@ import static java.util.logging.Level.*;
public class PCPP {
- private static final Logger LOG = Logger.getLogger(PCPP.class.getPackage().getName());
+ private final Logger LOG;
/** Map containing the results of #define statements. We must
evaluate certain very simple definitions (to properly handle
@@ -86,6 +89,7 @@ public class PCPP {
private final boolean enableCopyOutput2Stderr;
public PCPP(final List<String> includePaths, final boolean debug, final boolean copyOutput2Stderr) {
+ LOG = Logging.getLogger(PCPP.class.getPackage().getName());
this.includePaths = includePaths;
setOut(System.out);
enableDebugPrint = debug;
diff --git a/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
index 5c059c9..abbe521 100644
--- a/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
@@ -42,7 +42,9 @@ package com.jogamp.gluegen.procaddress;
import com.jogamp.gluegen.CMethodBindingEmitter;
import com.jogamp.gluegen.MethodBinding;
import com.jogamp.gluegen.JavaType;
+
import java.io.*;
+
import com.jogamp.gluegen.cgram.types.*;
public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
@@ -55,8 +57,11 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
private static final String procAddressJavaTypeName = JavaType.createForClass(Long.TYPE).jniTypeName();
private ProcAddressEmitter emitter;
- public ProcAddressCMethodBindingEmitter(final CMethodBindingEmitter methodToWrap, final boolean callThroughProcAddress,
- final boolean needsLocalTypedef, final String localTypedefCallingConvention, final ProcAddressEmitter emitter) {
+ public ProcAddressCMethodBindingEmitter(final CMethodBindingEmitter methodToWrap,
+ final boolean callThroughProcAddress,
+ final boolean needsLocalTypedef,
+ final String localTypedefCallingConvention,
+ final ProcAddressEmitter emitter) {
super(
new MethodBinding(methodToWrap.getBinding()) {
@@ -76,7 +81,8 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
methodToWrap.getIsJavaMethodStatic(),
true,
methodToWrap.forIndirectBufferAndArrayImplementation(),
- methodToWrap.getMachineDataInfo()
+ methodToWrap.getMachineDataInfo(),
+ emitter.getConfiguration()
);
if (methodToWrap.getReturnValueCapacityExpression() != null) {
@@ -124,7 +130,7 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
// We (probably) didn't get a typedef for this function
// pointer type in the header file; the user requested that we
// forcibly generate one. Here we force the emission of one.
- final PointerType funcPtrType = new PointerType(null, cSym.getType(), 0);
+ final PointerType funcPtrType = new PointerType(null, cSym.getType(), 0, null);
// Just for safety, emit this name slightly differently than
// the mangling would otherwise produce
funcPointerTypedefName = "_local_" + funcPointerTypedefName;