diff options
author | Sven Gothel <[email protected]> | 2015-03-09 03:09:18 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-03-09 03:09:18 +0100 |
commit | 9eb9403d774db0c55ea3cb2fc5bd04114b8b5feb (patch) | |
tree | 266780ea786df13e582d4ecdd0b05ef9c46bccfb /src/java/com/jogamp/gluegen | |
parent | cf9f28cf249393f42d7d2835775521dfadee6b92 (diff) |
Bug 1134 - Fix aliased typedef struct emission
- Code regarding 'aliased typedef struct' is tagged in JavaEmitter and HeaderParser:
'NOTE: Struct Name Resolution (JavaEmitter, HeaderParser)'
Prefers containing cstruct typedef pointer
if available _and_ if cstruct is _not_ a typedef!
- Removed: 'HeaderParser.resolveAnonCompound(..)' no more required,
since CompoundType always sets its name!
Commit cf9f28cf249393f42d7d2835775521dfadee6b92
- JavaEmitter.emitStruct:
- Regard above 'aliased typedef struct' NOTE
- JavaEmitter.typeToJavaType:
- Regard above 'aliased typedef struct' NOTE
- ReferencedStructs
- Drop duplicate CompoundType instances of same name.
This can happen due to const/volatile and ASTLocusTag variants.
Diffstat (limited to 'src/java/com/jogamp/gluegen')
-rw-r--r-- | src/java/com/jogamp/gluegen/GlueGen.java | 13 | ||||
-rw-r--r-- | src/java/com/jogamp/gluegen/JavaEmitter.java | 91 | ||||
-rw-r--r-- | src/java/com/jogamp/gluegen/ReferencedStructs.java | 56 |
3 files changed, 89 insertions, 71 deletions
diff --git a/src/java/com/jogamp/gluegen/GlueGen.java b/src/java/com/jogamp/gluegen/GlueGen.java index 4ef5648..c4eb1c5 100644 --- a/src/java/com/jogamp/gluegen/GlueGen.java +++ b/src/java/com/jogamp/gluegen/GlueGen.java @@ -294,8 +294,7 @@ public class GlueGen implements GlueEmitterControls { 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 - // to be skipped). + // emitted (e.g., if an Ignore directive in the JavaEmitter causes it to be skipped). sym.getType().visit(referencedStructs); } @@ -315,13 +314,9 @@ public class GlueGen implements GlueEmitterControls { // Lay out structs emit.beginStructLayout(); - for (final Iterator<Type> iter = referencedStructs.results(); iter.hasNext();) { - final Type t = iter.next(); - if (t.isCompound()) { - emit.layoutStruct(t.asCompound()); - } else if (t.isPointer()) { - final PointerType p = t.asPointer(); - final CompoundType c = p.getTargetType().asCompound(); + for (final Iterator<CompoundType> iter = referencedStructs.layouts(); iter.hasNext();) { + final CompoundType c = iter.next(); + if( !c.isLayouted() ) { emit.layoutStruct(c); } } diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java index ca89b0e..52e8834 100644 --- a/src/java/com/jogamp/gluegen/JavaEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaEmitter.java @@ -877,53 +877,64 @@ public class JavaEmitter implements GlueEmitter { } @Override - public void emitStruct(final CompoundType structCType, final Type typedefed) throws Exception { + public void emitStruct(final CompoundType structCType, final Type structCTypedefPtr) throws Exception { final String structCTypeName, typedefedName; { final String _name = structCType.getName(); - if ( null == _name && null != typedefed && null != typedefed.getName() ) { - // use typedef'ed name - typedefedName = typedefed.getName(); + if ( null != structCTypedefPtr && null != structCTypedefPtr.getName() ) { + // always use typedef'ed name if available + typedefedName = structCTypedefPtr.getName(); structCTypeName = typedefedName; } else { - // use actual struct type name + // fall back to actual struct type name typedefedName = null; structCTypeName = _name; } - } - LOG.log(INFO, structCType.getASTLocusTag(), - "Struct emission of structCType \"{0}\" -> {1}", structCTypeName, structCType); - LOG.log(INFO, structCType.getASTLocusTag(), - " which has a typedef \"{0}\" -> {1}", typedefedName, typedefed); - - if ( null == structCTypeName ) { - final String structName = structCType.getStructName(); - if ( null != structName && cfg.shouldIgnoreInInterface(structName) ) { + LOG.log(INFO, structCType.getASTLocusTag(), "Struct emission of structCType {0}", structCType); + LOG.log(INFO, structCType.getASTLocusTag()," structCTypedefPtr {0}", structCTypedefPtr); + LOG.log(INFO, structCType.getASTLocusTag()," : structCTypeName \"{0}\" -> typedefedName \"{1}\" -> \"{2}\"", + _name, typedefedName, structCTypeName); + if ( null == structCTypeName ) { LOG.log(INFO, structCType.getASTLocusTag(), - "skipping emission of unnamed ignored struct \"{0}\": {1}", structName, structCType); + "skipping emission of unnamed struct {0} w/o typedef", structCType); return; - } else { + } + final AliasedSymbol.AliasedSymbolImpl aliases = new AliasedSymbol.AliasedSymbolImpl(structCTypeName); + aliases.addAliasedName(_name); + aliases.addAliasedName(typedefedName); + if ( cfg.shouldIgnoreInInterface(aliases) ) { LOG.log(INFO, structCType.getASTLocusTag(), - "skipping emission of unnamed struct {0}, typedef {1} ", structCType, typedefed); + "skipping emission of ignored \"{0}\": {1}", aliases, structCType); return; } } - if ( cfg.shouldIgnoreInInterface(structCTypeName) ) { + + if( null != structCTypedefPtr && isOpaque(structCTypedefPtr) ) { LOG.log(INFO, structCType.getASTLocusTag(), - "skipping emission of ignored \"{0}\": {1}", structCTypeName, structCType); + "skipping emission of opaque typedef {0}", structCTypedefPtr); return; } - if( null != typedefed && isOpaque(typedefed) ) { + if( isOpaque(structCType) ) { LOG.log(INFO, structCType.getASTLocusTag(), - "skipping emission of opaque typedef {0}, c-struct {1}", typedefed, structCType); + "skipping emission of opaque c-struct {0}", structCType); return; } final Type containingCType; { - final Type aptr = new PointerType(SizeThunk.POINTER, structCType, 0); - aptr.setTypedefName(typedefedName); + // NOTE: Struct Name Resolution (JavaEmitter, HeaderParser) + final Type aptr; + int mode; + if( null != typedefedName ) { + aptr = structCTypedefPtr; + mode = 1; + } else { + aptr = new PointerType(SizeThunk.POINTER, structCType, 0); + aptr.setTypedefName(typedefedName); + mode = 2; + } containingCType = canonicalize(aptr); + LOG.log(INFO, structCType.getASTLocusTag(), "containingCType[{0}]: {1} -canon-> {2}", mode, aptr, containingCType); } final JavaType containingJType = typeToJavaType(containingCType, null); if( containingJType.isOpaqued() ) { @@ -939,15 +950,7 @@ public class JavaEmitter implements GlueEmitter { final String containingJTypeName = containingJType.getName(); LOG.log(INFO, structCType.getASTLocusTag(), "perform emission of \"{0}\" -> \"{1}\": {2}", structCTypeName, containingJTypeName, structCType); - if( GlueGen.debug() ) { - if( null != typedefed ) { - LOG.log(INFO, structCType.getASTLocusTag(), " typedefed {0}", typedefed); - } else { - LOG.log(INFO, structCType.getASTLocusTag(), " typedefed {0}", (Object)null); - } - LOG.log(INFO, structCType.getASTLocusTag(), " containingCType {0}", containingCType); - LOG.log(INFO, structCType.getASTLocusTag(), " containingJType {0}", containingJType); - } + if( 0 == structCType.getNumFields() ) { LOG.log(INFO, structCType.getASTLocusTag(), "emission of \"{0}\" with zero fields {1}", containingJTypeName, structCType); @@ -2168,14 +2171,22 @@ public class JavaEmitter implements GlueEmitter { cType.getName().equals("jobject")) { return javaType(java.lang.Object.class); } - String name = targetType.getName(); - if (name == null) { - // Try containing pointer type for any typedefs - name = cType.getName(); - if (name == null) { - throw new GlueGenException("Couldn't find a proper type name for pointer type " + cType.getDebugString(), - cType.getASTLocusTag()); - } + // NOTE: Struct Name Resolution (JavaEmitter, HeaderParser) + String name; + if( !targetType.isTypedef() && cType.isTypedef() ) { + // If compound is not a typedef _and_ containing pointer is typedef, use the latter. + name = cType.getName(); + } else { + // .. otherwise try compound name + name = targetType.getName(); + if( null == name ) { + // .. fall back to pointer type name + name = cType.getName(); + if (name == null) { + throw new GlueGenException("Couldn't find a proper type name for pointer type " + cType.getDebugString(), + cType.getASTLocusTag()); + } + } } return JavaType.createForCStruct(cfg.renameJavaType(name)); } else { diff --git a/src/java/com/jogamp/gluegen/ReferencedStructs.java b/src/java/com/jogamp/gluegen/ReferencedStructs.java index 46a2a7e..26deb3a 100644 --- a/src/java/com/jogamp/gluegen/ReferencedStructs.java +++ b/src/java/com/jogamp/gluegen/ReferencedStructs.java @@ -44,31 +44,43 @@ import com.jogamp.gluegen.cgram.types.*; public class ReferencedStructs implements TypeVisitor { - private final Set<Type> results = new HashSet<Type>(); + private final Map<String, Type> resultMap = new HashMap<String, Type>(); + private final Set<CompoundType> layoutSet = new HashSet<CompoundType>(); + private final Set<Type> skip = new HashSet<Type>(); - public void clear() { - results.clear(); - } + public void clear() { + resultMap.clear(); + } - public Iterator<Type> results() { - return results.iterator(); - } + public Iterator<Type> results() { + return resultMap.values().iterator(); + } + public Iterator<CompoundType> layouts() { + return layoutSet.iterator(); + } - @Override - public void visitType(final Type t) { - if (t.isPointer()) { - final PointerType p = t.asPointer(); - if (p.isTypedef()) { - final CompoundType c = p.getTargetType().asCompound(); - if (c != null && c.getName() == null) { - // This otherwise-unnamed CompoundType is referred to by a - // PointerType that has a typedef name. Assume that it is - // referred to in the glue code and emit it. - results.add(p); + @Override + public void visitType(final Type t) { + if( skip.contains(t) ) { + return; + } + if ( t.isPointer() ) { + final PointerType p = t.asPointer(); + final CompoundType c = p.getTargetType().asCompound(); + if( p.isTypedef() && null != c ) { + // If containing pointer is typedef, use it (preferred) + skip.add(c); // earmark to skip the compound! + resultMap.put(c.getName(), p); + layoutSet.add(c); + } else { + // .. otherwise skip pointer and use followup compound + } + } else if( t.isCompound() ) { + // Use compound if not yet mapped, e.g. by typedef'ed (preferred) + if( !resultMap.containsKey(t.getName()) ) { + resultMap.put(t.getName(), t); + } + layoutSet.add(t.asCompound()); // always: could be const/volatile variants .. } - } - } else if (t.isCompound()) { - results.add(t); } - } } |