From eca019cdea4017227e951d8a9eb30cb34fca4a07 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Sat, 7 Mar 2015 08:25:36 +0100
Subject: Bug 1134 - Pass ASTLocationTag to all types, used for
 GlueGenException

Enhances semantic exception in code generation
by adding the AST location of the type or function declaration.
---
 .../com/jogamp/gluegen/CMethodBindingEmitter.java  |  70 +++++++-----
 src/java/com/jogamp/gluegen/GlueGen.java           |   6 +-
 src/java/com/jogamp/gluegen/JavaEmitter.java       | 118 +++++++++++--------
 src/java/com/jogamp/gluegen/ReferencedStructs.java |   2 +-
 .../com/jogamp/gluegen/cgram/types/ArrayType.java  |  17 ++-
 .../com/jogamp/gluegen/cgram/types/BitType.java    |  13 ++-
 .../jogamp/gluegen/cgram/types/CompoundType.java   |  17 ++-
 .../com/jogamp/gluegen/cgram/types/DoubleType.java |  12 +-
 .../com/jogamp/gluegen/cgram/types/EnumType.java   |  19 ++--
 .../com/jogamp/gluegen/cgram/types/FloatType.java  |  12 +-
 .../jogamp/gluegen/cgram/types/FunctionType.java   |  11 +-
 .../gluegen/cgram/types/MemoryLayoutType.java      |   6 +-
 .../jogamp/gluegen/cgram/types/PointerType.java    |  26 +++--
 .../jogamp/gluegen/cgram/types/PrimitiveType.java  |   6 +-
 .../com/jogamp/gluegen/cgram/types/StructType.java |  16 ++-
 src/java/com/jogamp/gluegen/cgram/types/Type.java  | 126 +++++++++++++++------
 .../com/jogamp/gluegen/cgram/types/UnionType.java  |  16 ++-
 .../com/jogamp/gluegen/cgram/types/VoidType.java   |  16 ++-
 .../ProcAddressCMethodBindingEmitter.java          |   2 +-
 .../structgen/CStructAnnotationProcessor.java      |   9 +-
 20 files changed, 332 insertions(+), 188 deletions(-)

(limited to 'src/java/com')

diff --git a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
index 47b2811..85c6d7e 100644
--- a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
@@ -607,9 +607,9 @@ public class CMethodBindingEmitter extends FunctionEmitter {
             // FIXME: if the arg type is non-const, the sematics might be that
             // the function modifies the argument -- we don't yet support
             // this.
-            throw new RuntimeException(
-              "Cannot copy data for ptr-to-ptr arg type \"" + cArgType +
-              "\": support for non-const ptr-to-ptr types not implemented.");
+            throw new GlueGenException(
+              "Cannot copy data for ptr-to-ptr arg type \"" + cArgType.getDebugString() +
+              "\": support for non-const ptr-to-ptr types not implemented: "+binding, binding.getCSymbol().getASTLocusTag());
           }
 
           writer.println();
@@ -653,9 +653,10 @@ public class CMethodBindingEmitter extends FunctionEmitter {
                   error = 100;
               }
               if( 0 < error ) {
-                throw new RuntimeException(
-                  "Could not copy data for type \"" + cArgType +
-                  "\"; currently only pointer- and array-types are supported. (error "+error+")");
+                throw new GlueGenException(
+                  "Could not copy data for type \"" + cArgType.getDebugString() +
+                  "\"; currently only pointer- and array-types are supported. (error "+error+"): "+binding,
+                  binding.getCSymbol().getASTLocusTag());
               }
           }
           emitMalloc(
@@ -715,7 +716,8 @@ public class CMethodBindingEmitter extends FunctionEmitter {
                                        null, true);
           } else {
             if( null == cArgElementType2 ) {
-                throw new RuntimeException("XXX: Type "+cArgType+" not properly handled as ptr-to-ptr");
+                throw new GlueGenException("XXX: Type "+cArgType.getDebugString()+" not properly handled as ptr-to-ptr: "+binding,
+                                           binding.getCSymbol().getASTLocusTag());
             }
             // Question: do we always need to copy the sub-arrays, or just
             // GetPrimitiveArrayCritical on each jobjectarray element and
@@ -732,8 +734,9 @@ public class CMethodBindingEmitter extends FunctionEmitter {
                        "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.getCName() +
-                              "\"; need to add support for copying ptr-to-ptr-to-primitiveType subarrays");
+                throw new GlueGenException("Cannot yet handle type \"" + cArgType.getDebugString() +
+                                           "\"; need to add support for copying ptr-to-ptr-to-primitiveType subarrays: "+binding,
+                                           binding.getCSymbol().getASTLocusTag());
             }
 
           }
@@ -817,9 +820,10 @@ public class CMethodBindingEmitter extends FunctionEmitter {
                                           null);
               writer.println("    }");
             } else {
-              throw new RuntimeException(
-                "Cannot clean up copied data for ptr-to-ptr arg type \"" + cArgType +
-                "\": support for cleaning up most non-const ptr-to-ptr types not implemented.");
+              throw new GlueGenException(
+                "Cannot clean up copied data for ptr-to-ptr arg type \"" + cArgType.getDebugString() +
+                "\": support for cleaning up most non-const ptr-to-ptr types not implemented.",
+                binding.getCSymbol().getASTLocusTag());
             }
           }
 
@@ -840,9 +844,10 @@ public class CMethodBindingEmitter extends FunctionEmitter {
             // free each element
             final PointerType cArgPtrType = cArgType.asPointer();
             if (cArgPtrType == null) {
-              throw new RuntimeException(
-                "Could not copy data for type \"" + cArgType +
-                "\"; currently only pointer types supported.");
+              throw new GlueGenException(
+                "Could not copy data for type \"" + cArgType.getDebugString() +
+                "\"; currently only pointer types supported.",
+                binding.getCSymbol().getASTLocusTag());
             }
 
             // process each element in the array
@@ -861,9 +866,10 @@ public class CMethodBindingEmitter extends FunctionEmitter {
               writer.print(convName+"_copy[_copyIndex]");
               writer.println(");");
             } else {
-              if (true) throw new RuntimeException(
-                "Cannot yet handle type \"" + cArgType.getCName() +
-                "\"; need to add support for cleaning up copied ptr-to-ptr-to-primitiveType subarrays");
+              if (true) throw new GlueGenException(
+                "Cannot yet handle type \"" + cArgType.getDebugString() +
+                "\"; need to add support for cleaning up copied ptr-to-ptr-to-primitiveType subarrays",
+                binding.getCSymbol().getASTLocusTag());
             }
             writer.println("    }");
           }
@@ -1047,12 +1053,13 @@ public class CMethodBindingEmitter extends FunctionEmitter {
                 {
                     // fully declared non-anonymous struct pointer: pass content
                     if ( cReturnTargetType.getSize() == null ) {
-                      throw new RuntimeException(
+                      throw new GlueGenException(
                         "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
+                        cReturnTargetType.getDebugString() + " was not) for "+binding,
+                        binding.getCSymbol().getASTLocusTag()
                       );
                     }
                     writer.println("sizeof(" + cReturnTargetType.getCName() + ") );");
@@ -1103,8 +1110,8 @@ public class CMethodBindingEmitter extends FunctionEmitter {
                  (javaReturnType.isArray() && javaReturnType.isNIOByteBufferArray())) {
         writer.println("  if (NULL == _res) return NULL;");
         if (returnValueLengthExpression == null) {
-          throw new RuntimeException("Error while generating C code: no length specified for array returned from function " +
-                                     binding);
+          throw new GlueGenException("Error while generating C code: no length specified for array returned from function " +
+                                      binding, binding.getCSymbol().getASTLocusTag());
         }
         writer.println("  " + arrayResLength + " = " + returnValueLengthExpression.format(argumentNameArray()) + ";");
         writer.println("  " + arrayRes + " = (*env)->NewObjectArray(env, " + arrayResLength + ", (*env)->FindClass(env, \"java/nio/ByteBuffer\"), NULL);");
@@ -1126,9 +1133,10 @@ public class CMethodBindingEmitter extends FunctionEmitter {
         // expression which computes the array size (already present
         // as ReturnValueCapacity, not yet implemented / tested here)
 
-        throw new RuntimeException(
+        throw new GlueGenException(
                                    "Could not emit native code for function \"" + binding +
-                                   "\": array return values for non-char types not implemented yet, for "+binding);
+                                   "\": array return values for non-char types not implemented yet, for "+binding,
+                                   binding.getCSymbol().getASTLocusTag());
 
         // FIXME: This is approximately what will be required here
         //
@@ -1150,8 +1158,8 @@ public class CMethodBindingEmitter extends FunctionEmitter {
         //writer.print(arrayRes);
         //writer.println(";");
       } else {
-        System.err.print("Unhandled return type: "+javaReturnType.getDebugString());
-        throw new RuntimeException("Unhandled return type: "+javaReturnType.getDebugString()+" for "+binding);
+        throw new GlueGenException("Unhandled return type: "+javaReturnType.getDebugString()+" for "+binding,
+                                   binding.getCSymbol().getReturnType().getASTLocusTag());
       }
     }
   }
@@ -1178,7 +1186,8 @@ public class CMethodBindingEmitter extends FunctionEmitter {
         // We should only see "void" as the first argument of a 1-argument function
         // FIXME: should normalize this in the parser
         if ((i != 0) || (binding.getNumArguments() > 1)) {
-          throw new RuntimeException("Saw illegal \"void\" argument while emitting \"" + getName() + "\"");
+          throw new GlueGenException("Saw illegal \"void\" argument while emitting arg "+i+" of "+binding,
+                                     binding.getCArgumentType(i).getASTLocusTag());
         }
       } else {
         Class<?> c = type.getJavaClass();
@@ -1210,7 +1219,8 @@ public class CMethodBindingEmitter extends FunctionEmitter {
           // These are not exposed at the Java level
         } else {
           // FIXME: add support for char* -> String conversion
-          throw new RuntimeException("Unknown kind of JavaType: name="+type.getName());
+          throw new GlueGenException("Unknown kind of JavaType: arg "+i+", name="+type.getName()+" of "+binding,
+                                     binding.getCArgumentType(i).getASTLocusTag());
         }
       }
     }
@@ -1450,12 +1460,12 @@ public class CMethodBindingEmitter extends FunctionEmitter {
           } 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.getCName() + "\"");
+            throw new GlueGenException("Unsupported pointer type: \"" + cType.getDebugString() + "\"", cType.getASTLocusTag());
           }
         } 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.getCName() + "\"");
+          throw new GlueGenException("Unsupported pointer type: \"" + cType.getDebugString() + "\"", cType.getASTLocusTag());
         }
       }
     } else {
diff --git a/src/java/com/jogamp/gluegen/GlueGen.java b/src/java/com/jogamp/gluegen/GlueGen.java
index 2833154..4ef5648 100644
--- a/src/java/com/jogamp/gluegen/GlueGen.java
+++ b/src/java/com/jogamp/gluegen/GlueGen.java
@@ -73,6 +73,8 @@ public class GlueGen implements GlueEmitterControls {
 
     private static Level logLevel = null;
 
+    public static void setDebug(final boolean v) { debug=v; }
+    public static void setLogLevel(final Level l) { logLevel=l; }
     public static boolean debug() { return debug; }
 
     @Override
@@ -330,12 +332,12 @@ 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;
+                    assert t.isTypedef() && 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.hasTypedefName() && c.getName() == null : "ReferencedStructs incorrectly recorded pointer type " + p;
+                    assert p.isTypedef() && c.getName() == null : "ReferencedStructs incorrectly recorded pointer type " + p;
                     emit.emitStruct(c, p);
                 }
             }
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index 7ffa88d..c291022 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -820,7 +820,7 @@ public class JavaEmitter implements GlueEmitter {
         }
       } // end iteration over expanded bindings
     } catch (final Exception e) {
-      throw new RuntimeException("Error while generating bindings for \"" + sym + "\"", e);
+      throw new GlueGenException("Error while generating bindings for \"" + sym + "\"", sym.getASTLocusTag(), e);
     }
 
     return allEmitters;
@@ -899,7 +899,12 @@ public class JavaEmitter implements GlueEmitter {
         return;
     }
 
-    final Type containingCType = canonicalize(new PointerType(SizeThunk.POINTER, structCType, 0, typedefedName));
+    final Type containingCType;
+    {
+        final Type aptr = new PointerType(SizeThunk.POINTER, structCType, 0);
+        aptr.setTypedefName(typedefedName);
+        containingCType = canonicalize(aptr);
+    }
     final JavaType containingJType = typeToJavaType(containingCType, null);
     if( containingJType.isOpaqued() ) {
         LOG.log(INFO, "skipping emission of opaque {0}, {1}", containingJType.getDebugString(), structCType.getDebugString());
@@ -913,11 +918,11 @@ public class JavaEmitter implements GlueEmitter {
     LOG.log(INFO, "perform emission of \"{0}\" -> \"{1}\": {2}", structCTypeName, containingJTypeName, structCType.getDebugString());
     if( GlueGen.debug() ) {
         if( null != typedefed ) {
-            LOG.log(INFO, "    typedefed {0}", typedefed.getDebugString());
+            LOG.log(INFO, "    typedefed {0}", typedefed.getDebugString(true));
         } else {
             LOG.log(INFO, "    typedefed {0}", (Object)null);
         }
-        LOG.log(INFO, "    containingCType {0}", containingCType.getDebugString());
+        LOG.log(INFO, "    containingCType {0}", containingCType.getDebugString(true));
         LOG.log(INFO, "    containingJType {0}", containingJType.getDebugString());
     }
     if( 0 == structCType.getNumFields() ) {
@@ -1061,8 +1066,8 @@ public class JavaEmitter implements GlueEmitter {
           // handle the union in jawt_Win32DrawingSurfaceInfo (fabricate
           // a name?)
           if (fieldType.getName() == null) {
-            throw new RuntimeException("Anonymous structs as fields not supported yet, field \"" +
-                                       cfgFieldName1 + "\", "+fieldType.getDebugString());
+            throw new GlueGenException("Anonymous structs as fields not supported yet, field \"" +
+                                       cfgFieldName1 + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag());
           }
           if( GlueGen.debug() ) {
             System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "compound");
@@ -1080,11 +1085,11 @@ public class JavaEmitter implements GlueEmitter {
           try {
             externalJavaType = typeToJavaType(fieldType, machDescJava);
           } catch (final Exception e) {
-            throw new RuntimeException("Error occurred while creating accessor for field \"" +
-                                       cfgFieldName1 + "\", "+fieldType.getDebugString(), e);
+            throw new GlueGenException("Error occurred while creating accessor for field \"" +
+                                       cfgFieldName1 + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag(), e);
           }
           if( GlueGen.debug() ) {
-              System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, fieldName, fieldType.getDebugString(), "MISC");
+              System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "MISC");
               System.err.printf("SE.os.%02d: javaType %s%n", (i+1), externalJavaType.getDebugString());
           }
           if (externalJavaType.isPrimitive()) {
@@ -1160,8 +1165,9 @@ public class JavaEmitter implements GlueEmitter {
           // FIXME: will need to support this at least in order to
           // handle the union in jawt_Win32DrawingSurfaceInfo (fabricate a name?)
           if (fieldType.getName() == null) {
-            throw new RuntimeException("Anonymous structs as fields not supported yet (field \"" +
-                                       field + "\" in type \"" + structCTypeName + "\")");
+            throw new GlueGenException("Anonymous structs as fields not supported yet (field \"" +
+                                       field + "\" in type \"" + structCTypeName + "\")",
+                                       fieldType.getASTLocusTag());
           }
           javaWriter.println();
           generateGetterSignature(javaWriter, fieldType, false, false, fieldType.getName(), capitalizeString(fieldName), null, null);
@@ -1179,9 +1185,8 @@ public class JavaEmitter implements GlueEmitter {
           try {
             javaType = typeToJavaType(fieldType, machDescJava);
           } catch (final Exception e) {
-            LOG.log(SEVERE, "Error occurred while creating accessor for field \"{0}\", {1}",
-                               field.getName(), fieldType.getDebugString());
-            throw(e);
+            throw new GlueGenException("Error occurred while creating accessor for field \"" +
+                                       field.getName() + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag(), e);
           }
           if (javaType.isPrimitive()) {
             // Primitive type
@@ -1582,14 +1587,15 @@ public class JavaEmitter implements GlueEmitter {
                                              final PrintWriter javaWriter, final PrintWriter jniWriter,
                                              final String structCTypeName, final String structClassPkgName,
                                              final Type containingCType, final JavaType containingJType,
-                                             final int i, final Field field, final String fieldName, final String returnSizeLookupName) throws Exception {
+                                             final int i, final Field field, final String fieldName,
+                                             final String returnSizeLookupName) throws Exception {
       final Type fieldType = field.getType();
       final JavaType javaType;
       try {
         javaType = typeToJavaType(fieldType, machDescJava);
       } catch (final Exception e) {
-        throw new RuntimeException("Error occurred while creating array/pointer accessor for field \"" +
-                                   returnSizeLookupName + "\", "+fieldType.getDebugString(), e);
+        throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" +
+                                   returnSizeLookupName + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag(), e);
       }
       if( GlueGen.debug() ) {
           System.err.printf("SE.ac.%02d: javaType  %s%n", (i+1), javaType.getDebugString());
@@ -1668,8 +1674,9 @@ public class JavaEmitter implements GlueEmitter {
               try {
                   baseJElemType = typeToJavaType(baseCElemType, machDescJava);
               } catch (final Exception e ) {
-                  throw new RuntimeException("Error occurred while creating array/pointer accessor for field \"" +
-                                              returnSizeLookupName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(), e);
+                  throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" +
+                                              returnSizeLookupName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(),
+                                              fieldType.getASTLocusTag(), e);
               }
               baseJElemTypeName = baseJElemType.getName();
               baseCElemNativeSizeFixed = baseCElemType.isPrimitive() ? baseCElemType.getSize().hasFixedNativeSize() : true;
@@ -2073,8 +2080,9 @@ public class JavaEmitter implements GlueEmitter {
        case 2:  return javaType(Short.TYPE);
        case 4:  return javaType(Integer.TYPE);
        case 8:  return javaType(Long.TYPE);
-       default: throw new RuntimeException("Unknown integer type of size " +
-                                           cType.getSize(curMachDesc) + " and name " + cType.getName());
+       default: throw new GlueGenException("Unknown integer type of size " +
+                                           cType.getSize(curMachDesc) + " and name " + cType.getName(),
+                                           cType.getASTLocusTag());
       }
     } else if (cType.isFloat()) {
       return javaType(Float.TYPE);
@@ -2109,8 +2117,9 @@ public class JavaEmitter implements GlueEmitter {
               case 2:  return JavaType.createForCShortPointer();
               case 4:  return JavaType.createForCInt32Pointer();
               case 8:  return JavaType.createForCInt64Pointer();
-              default: throw new RuntimeException("Unknown integer array type of size " +
-                                                  cType.getSize(curMachDesc) + " and name " + cType.getName()+", "+cType.getDebugString());
+              default: throw new GlueGenException("Unknown integer array type of size " +
+                                                  cType.getSize(curMachDesc) + " and name " + cType.getName()+", "+cType.getDebugString(),
+                                                  cType.getASTLocusTag());
             }
           } else if (targetType.isFloat()) {
             return JavaType.createForCFloatPointer();
@@ -2130,13 +2139,15 @@ public class JavaEmitter implements GlueEmitter {
               // Try containing pointer type for any typedefs
               name = cType.getName();
               if (name == null) {
-                throw new RuntimeException("Couldn't find a proper type name for pointer type " + cType.getDebugString());
+                throw new GlueGenException("Couldn't find a proper type name for pointer type " + cType.getDebugString(),
+                                            cType.getASTLocusTag());
               }
             }
             return JavaType.createForCStruct(cfg.renameJavaType(name));
           } else {
-            throw new RuntimeException("Don't know how to convert pointer/array type \"" +
-                                       cType.getDebugString() + "\"");
+            throw new GlueGenException("Don't know how to convert pointer/array type \"" +
+                                       cType.getDebugString() + "\"",
+                                       cType.getASTLocusTag());
           }
         }
         // Handle Types of form pointer-to-pointer-to-type or
@@ -2179,16 +2190,17 @@ public class JavaEmitter implements GlueEmitter {
                 case 2: return javaType(ArrayTypes.shortBufferArrayClass);
                 case 4: return javaType(ArrayTypes.intBufferArrayClass);
                 case 8: return javaType(ArrayTypes.longBufferArrayClass);
-                default: throw new RuntimeException("Unknown two-dimensional integer array type of element size " +
-                                                    bottomType.getSize(curMachDesc) + " and name " + bottomType.getName()+", "+bottomType.getDebugString());
+                default: throw new GlueGenException("Unknown two-dimensional integer array type of element size " +
+                                                    bottomType.getSize(curMachDesc) + " and name " + bottomType.getName()+", "+bottomType.getDebugString(),
+                                                    bottomType.getASTLocusTag());
               }
             } else if (bottomType.isFloat()) {
               return javaType(ArrayTypes.floatBufferArrayClass);
             } else if (bottomType.isDouble()) {
               return javaType(ArrayTypes.doubleBufferArrayClass);
             } else {
-              throw new RuntimeException("Unexpected primitive type " + bottomType.getDebugString() +
-                                         " in two-dimensional array");
+              throw new GlueGenException("Unexpected primitive type " + bottomType.getDebugString() +
+                                         " in two-dimensional array", bottomType.getASTLocusTag());
             }
           } else if (bottomType.isVoid()) {
             return javaType(ArrayTypes.bufferArrayClass);
@@ -2197,32 +2209,38 @@ public class JavaEmitter implements GlueEmitter {
             // Array of pointers; convert as array of StructAccessors
             return JavaType.createForCArray(bottomType);
           } else {
-            throw new RuntimeException(
+            throw new GlueGenException(
               "Could not convert C type \"" + cType.getDebugString() + "\" " +
               "to appropriate Java type; need to add more support for " +
               "depth=2 pointer/array types [debug info: targetType=\"" +
-              targetType + "\"]");
+              targetType + "\"]", cType.getASTLocusTag());
           }
         } else {
           // can't handle this type of pointer/array argument
-          throw new RuntimeException(
+          throw new GlueGenException(
             "Could not convert C pointer/array \"" + cType.getDebugString() + "\" to " +
             "appropriate Java type; types with pointer/array depth " +
             "greater than 2 are not yet supported [debug info: " +
             "pointerDepth=" + cType.pointerDepth() + " arrayDimension=" +
-            cType.arrayDimension() + " targetType=\"" + targetType + "\"]");
+            cType.arrayDimension() + " targetType=\"" + targetType + "\"]",
+            cType.getASTLocusTag());
         }
 
-    } else if(cType.isCompound() ) { // FIXME: Compound and Compound-Arrays
-        final String name = cType.getName();
+    } else if( cType.isCompound() ) { // FIXME: Compound and Compound-Arrays
+        String name = cType.getName();
         if (name == null) {
-          throw new RuntimeException("Couldn't find a proper type name for pointer type " + cType.getDebugString());
+          name = cType.asCompound().getStructName();
+          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 {
-        throw new RuntimeException(
+        throw new GlueGenException(
           "Could not convert C type \"" + cType.getDebugString() + "\" (class " +
-          cType.getClass().getName() + ") to appropriate Java type");
+          cType.getClass().getName() + ") to appropriate Java type",
+          cType.getASTLocusTag());
     }
   }
 
@@ -2258,7 +2276,7 @@ public class JavaEmitter implements GlueEmitter {
   }
 
   private boolean isOpaque(final Type type) {
-    return (cfg.typeInfo(type) != null);
+    return null != cfg.typeInfo(type);
   }
 
   private String compatiblePrimitiveJavaTypeName(final Type fieldType,
@@ -2267,14 +2285,16 @@ public class JavaEmitter implements GlueEmitter {
     final Class<?> c = javaType.getJavaClass();
     if (!isIntegerType(c)) {
       // FIXME
-      throw new RuntimeException("Can't yet handle opaque definitions of structs' fields to non-integer types (byte, short, int, long, etc.): type: "+fieldType+", javaType "+javaType+", javaClass "+c);
+      throw new GlueGenException("Can't yet handle opaque definitions of structs' fields to non-integer types (byte, short, int, long, etc.): type: "+fieldType+", javaType "+javaType+", javaClass "+c,
+                                 fieldType.getASTLocusTag());
     }
     switch ((int) fieldType.getSize(curMachDesc)) {
       case 1:  return "byte";
       case 2:  return "short";
       case 4:  return "int";
       case 8:  return "long";
-      default: throw new RuntimeException("Can't handle opaque definitions if the starting type isn't compatible with integral types");
+      default: throw new GlueGenException("Can't handle opaque definitions if the starting type isn't compatible with integral types",
+                                          fieldType.getASTLocusTag());
     }
   }
 
@@ -2662,9 +2682,10 @@ public class JavaEmitter implements GlueEmitter {
       if (prt == null ||
           prt.getTargetType().asInt() == null ||
           prt.getTargetType().getSize(curMachDesc) != 1) {
-        throw new RuntimeException(
+        throw new GlueGenException(
           "Cannot apply ReturnsString configuration directive to \"" + sym +
-          "\". ReturnsString requires native method to have return type \"char *\"");
+          "\". ReturnsString requires native method to have return type \"char *\"",
+          sym.getASTLocusTag());
       }
       binding.setJavaReturnType(javaType(java.lang.String.class));
     } else {
@@ -2703,10 +2724,11 @@ public class JavaEmitter implements GlueEmitter {
           }
         }
         else {
-        throw new RuntimeException(
+        throw new GlueGenException(
           "Cannot apply ArgumentIsString configuration directive to " +
           "argument " + i + " of \"" + sym + "\": argument type is not " +
-          "a \"void*\", \"char *\", \"short *\", \"char**\", or \"short**\" equivalent");
+          "a \"void*\", \"char *\", \"short *\", \"char**\", or \"short**\" equivalent",
+          sym.getASTLocusTag());
         }
       }
       binding.addJavaArgumentType(mappedType);
@@ -2776,7 +2798,7 @@ public class JavaEmitter implements GlueEmitter {
             result = result.replaceJavaArgumentType(i, JavaType.forNIODoubleBufferClass());
           }
         } else {
-          throw new RuntimeException("Unknown C pointer type " + t);
+          throw new GlueGenException("Unknown C pointer type " + t);
         }
       }
     }
@@ -2801,7 +2823,7 @@ public class JavaEmitter implements GlueEmitter {
       } else if (t.isCDoublePointerType()) {
         result = result.replaceJavaArgumentType(-1, JavaType.forNIODoubleBufferClass());
       } else {
-        throw new RuntimeException("Unknown C pointer type " + t);
+        throw new GlueGenException("Unknown C pointer type " + t, result.getCReturnType().getASTLocusTag());
       }
     }
 
diff --git a/src/java/com/jogamp/gluegen/ReferencedStructs.java b/src/java/com/jogamp/gluegen/ReferencedStructs.java
index 546726f..46a2a7e 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.hasTypedefName()) {
+      if (p.isTypedef()) {
         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/cgram/types/ArrayType.java b/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java
index 281c68d..672bccf 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java
@@ -40,6 +40,8 @@
 
 package com.jogamp.gluegen.cgram.types;
 
+import com.jogamp.gluegen.ASTLocusTag;
+
 /** Represents an array type. This differs from a pointer type in C
     syntax by the use of "[]" rather than "*". The length may or may
     not be known; if the length is unknown then a negative number
@@ -49,8 +51,13 @@ public class ArrayType extends MemoryLayoutType implements Cloneable {
   private final Type elementType;
   private final int length;
 
-  public ArrayType(final Type elementType, final SizeThunk sizeInBytes, final int length, final int cvAttributes) {
-    super(elementType.getName() + " *", sizeInBytes, cvAttributes);
+  public ArrayType(final Type elementType, final SizeThunk sizeInBytes, final int length,
+                   final int cvAttributes) {
+    this(elementType, sizeInBytes, length, cvAttributes, null);
+  }
+  public ArrayType(final Type elementType, final SizeThunk sizeInBytes, final int length,
+                   final int cvAttributes, final ASTLocusTag astLocus) {
+    super(elementType.getName() + " *", sizeInBytes, cvAttributes, astLocus);
     this.elementType = elementType;
     this.length      = length;
   }
@@ -147,6 +154,10 @@ public class ArrayType extends MemoryLayoutType implements Cloneable {
 
   @Override
   Type newCVVariant(final int cvAttributes) {
-    return new ArrayType(elementType, getSize(), length, cvAttributes);
+    final Type t = new ArrayType(elementType, getSize(), length, cvAttributes, astLocus);
+    if( isTypedef() ) {
+        t.setTypedef(getTypedefCVAttributes());
+    }
+    return t;
   }
 }
diff --git a/src/java/com/jogamp/gluegen/cgram/types/BitType.java b/src/java/com/jogamp/gluegen/cgram/types/BitType.java
index 87eb8ce..b7488ea 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/BitType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/BitType.java
@@ -40,7 +40,7 @@
 
 package com.jogamp.gluegen.cgram.types;
 
-import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
+import com.jogamp.gluegen.ASTLocusTag;
 
 /** Represents a bitfield in a struct. */
 
@@ -49,8 +49,9 @@ public class BitType extends IntType implements Cloneable {
   private final int sizeInBits;
   private final int offset;
 
-  public BitType(final IntType underlyingType, final int sizeInBits, final int lsbOffset, final int cvAttributes) {
-    super(underlyingType.getName(), underlyingType.getSize(), underlyingType.isUnsigned(), cvAttributes);
+  public BitType(final IntType underlyingType, final int sizeInBits, final int lsbOffset,
+                 final int cvAttributes, final ASTLocusTag astLocus) {
+    super(underlyingType.getName(), underlyingType.getSize(), underlyingType.isUnsigned(), cvAttributes, astLocus);
     this.underlyingType = underlyingType;
     this.sizeInBits = sizeInBits;
     this.offset = lsbOffset;
@@ -110,6 +111,10 @@ public class BitType extends IntType implements Cloneable {
 
   @Override
   Type newCVVariant(final int cvAttributes) {
-    return new BitType(underlyingType, sizeInBits, offset, cvAttributes);
+    final Type t = new BitType(underlyingType, sizeInBits, offset, cvAttributes, astLocus);
+    if( isTypedef() ) {
+        t.setTypedef(getTypedefCVAttributes());
+    }
+    return t;
   }
 }
diff --git a/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java b/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java
index c9c4223..264389b 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/CompoundType.java
@@ -42,6 +42,8 @@ package com.jogamp.gluegen.cgram.types;
 
 import java.util.*;
 
+import com.jogamp.gluegen.ASTLocusTag;
+
 /** Models all compound types, i.e., those containing fields: structs
     and unions. The boolean type accessors indicate how the type is
     really defined. */
@@ -59,8 +61,9 @@ public abstract class CompoundType extends MemoryLayoutType implements Cloneable
    * @param cvAttributes
    * @param structName
    */
-  CompoundType(final String name, final SizeThunk size, final int cvAttributes, final String structName) {
-    super(name, size, cvAttributes);
+  CompoundType(final String name, final SizeThunk size, final int cvAttributes,
+               final String structName, final ASTLocusTag astLocus) {
+    super(name, size, cvAttributes, astLocus);
     this.structName = structName;
   }
 
@@ -96,15 +99,17 @@ public abstract class CompoundType extends MemoryLayoutType implements Cloneable
    * @param cvAttributes
    * @return
    */
-  public static CompoundType create(final String structName, final SizeThunk size, final CompoundTypeKind kind, final int cvAttributes)
+  public static CompoundType create(final String structName, final SizeThunk size,
+                                    final CompoundTypeKind kind, final int cvAttributes,
+                                    final ASTLocusTag astLocus)
   {
     final CompoundType res;
     switch (kind) {
       case STRUCT:
-          res = new StructType(null, size, cvAttributes, structName);
+          res = new StructType(null, size, cvAttributes, structName, astLocus);
           break;
       case UNION:
-          res = new UnionType(null, size, cvAttributes, structName);
+          res = new UnionType(null, size, cvAttributes, structName, astLocus);
           break;
       default:
           throw new RuntimeException("OO relation "+kind+" / Compount not yet supported");
@@ -165,7 +170,7 @@ public abstract class CompoundType extends MemoryLayoutType implements Cloneable
 
   @Override
   public String getCName(final boolean includeCVAttrs) {
-      if( hasTypedefName() ) {
+      if( isTypedef() ) {
           return getName(includeCVAttrs);
       } else {
           return (isStruct() ? "struct " : "union ")+getName(includeCVAttrs);
diff --git a/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java b/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java
index 1e13701..7bcf767 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/DoubleType.java
@@ -39,11 +39,13 @@
  */
 package com.jogamp.gluegen.cgram.types;
 
+import com.jogamp.gluegen.ASTLocusTag;
+
 /** Represents a double-word floating-point type (C type "double".) */
 public class DoubleType extends PrimitiveType implements Cloneable {
 
-    public DoubleType(final String name, final SizeThunk size, final int cvAttributes) {
-        super(name, size, cvAttributes);
+    public DoubleType(final String name, final SizeThunk size, final int cvAttributes, final ASTLocusTag astLocus) {
+        super(name, size, cvAttributes, astLocus);
     }
 
     @Override
@@ -73,6 +75,10 @@ public class DoubleType extends PrimitiveType implements Cloneable {
 
     @Override
     Type newCVVariant(final int cvAttributes) {
-        return new DoubleType(getName(), getSize(), cvAttributes);
+        final Type t = new DoubleType(getName(), getSize(), cvAttributes, astLocus);
+        if( isTypedef() ) {
+            t.setTypedef(getTypedefCVAttributes());
+        }
+        return t;
     }
 }
diff --git a/src/java/com/jogamp/gluegen/cgram/types/EnumType.java b/src/java/com/jogamp/gluegen/cgram/types/EnumType.java
index 7fa22e4..47691cd 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/EnumType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/EnumType.java
@@ -43,13 +43,12 @@ import java.util.ArrayList;
 import java.util.NoSuchElementException;
 
 import com.jogamp.gluegen.ASTLocusTag;
-import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider;
 import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
 
 
 /** Describes enumerated types. Enumerations are like ints except that
 they have a set of named values. */
-public class EnumType extends IntType implements Cloneable, ASTLocusTagProvider {
+public class EnumType extends IntType implements Cloneable {
 
     private IntType underlyingType;
 
@@ -103,29 +102,22 @@ public class EnumType extends IntType implements Cloneable, ASTLocusTagProvider
     }
 
     private ArrayList<Enum> enums;
-    private final ASTLocusTag astLocus;
 
     public EnumType(final String name) {
         super(name, SizeThunk.LONG, false, CVAttributes.CONST);
         this.underlyingType = new IntType(name, SizeThunk.LONG, false, CVAttributes.CONST);
-        this.astLocus = null;
     }
 
     public EnumType(final String name, final SizeThunk enumSizeInBytes, final ASTLocusTag astLocus) {
-        super(name, enumSizeInBytes, false, CVAttributes.CONST);
-        this.underlyingType = new IntType(name, enumSizeInBytes, false, CVAttributes.CONST);
-        this.astLocus = astLocus;
+        super(name, enumSizeInBytes, false, CVAttributes.CONST, astLocus);
+        this.underlyingType = new IntType(name, enumSizeInBytes, false, CVAttributes.CONST, astLocus);
     }
 
     protected EnumType(final String name, final IntType underlyingType, final int cvAttributes, final ASTLocusTag astLocus) {
-        super(name, underlyingType.getSize(), underlyingType.isUnsigned(), cvAttributes);
+        super(name, underlyingType.getSize(), underlyingType.isUnsigned(), cvAttributes, astLocus);
         this.underlyingType = underlyingType;
-        this.astLocus = astLocus;
     }
 
-    @Override
-    public ASTLocusTag getASTLocusTag() { return astLocus; }
-
     @Override
     public Object clone() {
         final EnumType n = (EnumType) super.clone();
@@ -255,6 +247,9 @@ public class EnumType extends IntType implements Cloneable, ASTLocusTagProvider
     Type newCVVariant(final int cvAttributes) {
         final EnumType t = new EnumType(getName(), underlyingType, cvAttributes, astLocus);
         t.enums = enums;
+        if( isTypedef() ) {
+            t.setTypedef(getTypedefCVAttributes());
+        }
         return t;
     }
 }
diff --git a/src/java/com/jogamp/gluegen/cgram/types/FloatType.java b/src/java/com/jogamp/gluegen/cgram/types/FloatType.java
index 0428543..2632409 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/FloatType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/FloatType.java
@@ -40,11 +40,13 @@
 
 package com.jogamp.gluegen.cgram.types;
 
+import com.jogamp.gluegen.ASTLocusTag;
+
 /** Represents a single-word floating-point type (C type "float".) */
 
 public class FloatType extends PrimitiveType implements Cloneable {
-  public FloatType(final String name, final SizeThunk size, final int cvAttributes) {
-    super(name, size, cvAttributes);
+  public FloatType(final String name, final SizeThunk size, final int cvAttributes, final ASTLocusTag astLocus) {
+    super(name, size, cvAttributes, astLocus);
   }
 
   @Override
@@ -72,6 +74,10 @@ public class FloatType extends PrimitiveType implements Cloneable {
 
   @Override
   Type newCVVariant(final int cvAttributes) {
-    return new FloatType(getName(), getSize(), cvAttributes);
+    final Type t = new FloatType(getName(), getSize(), cvAttributes, astLocus);
+    if( isTypedef() ) {
+        t.setTypedef(getTypedefCVAttributes());
+    }
+    return t;
   }
 }
diff --git a/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java b/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java
index b0d16e1..7ccc4c0 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java
@@ -41,7 +41,7 @@ package com.jogamp.gluegen.cgram.types;
 
 import java.util.*;
 
-import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
+import com.jogamp.gluegen.ASTLocusTag;
 
 /** Describes a function type, used to model both function
 declarations and (via PointerType) function pointers. */
@@ -51,8 +51,13 @@ public class FunctionType extends Type implements Cloneable {
     private ArrayList<Type> argumentTypes;
     private ArrayList<String> argumentNames;
 
-    public FunctionType(final String name, final SizeThunk size, final Type returnType, final int cvAttributes) {
-        super(name, size, cvAttributes);
+    public FunctionType(final String name, final SizeThunk size, final Type returnType,
+                        final int cvAttributes) {
+        this(name, size, returnType, cvAttributes, null);
+    }
+    public FunctionType(final String name, final SizeThunk size, final Type returnType,
+                        final int cvAttributes, final ASTLocusTag astLocus) {
+        super(name, size, cvAttributes, astLocus);
         this.returnType = returnType;
     }
 
diff --git a/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java b/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java
index fb8c86b..ba46aed 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/MemoryLayoutType.java
@@ -27,11 +27,13 @@
  */
 package com.jogamp.gluegen.cgram.types;
 
+import com.jogamp.gluegen.ASTLocusTag;
+
 public abstract class MemoryLayoutType extends Type {
   private boolean isLayouted;
 
-  protected MemoryLayoutType(final String name, final SizeThunk size, final int cvAttributes) {
-      super(name, size, cvAttributes);
+  protected MemoryLayoutType(final String name, final SizeThunk size, final int cvAttributes, final ASTLocusTag astLocus) {
+      super(name, size, cvAttributes, astLocus);
       isLayouted = false;
   }
 
diff --git a/src/java/com/jogamp/gluegen/cgram/types/PointerType.java b/src/java/com/jogamp/gluegen/cgram/types/PointerType.java
index c6496bb..1528f9f 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/PointerType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/PointerType.java
@@ -39,18 +39,20 @@
  */
 package com.jogamp.gluegen.cgram.types;
 
+import com.jogamp.gluegen.ASTLocusTag;
+
 public class PointerType extends Type implements Cloneable {
 
     private final Type targetType;
 
-    public PointerType(final SizeThunk size, final Type targetType, final int cvAttributes, final String typedefedName) {
+    public PointerType(final SizeThunk size, final Type targetType, final int cvAttributes) {
+        this(size, targetType, cvAttributes, null);
+    }
+    public PointerType(final SizeThunk size, final Type targetType, final int cvAttributes, final ASTLocusTag astLocus) {
         // can pass null for the final name parameter because the PointerType's getName()
         // completely replaces superclass behavior
-        super(targetType.getName() + " *", size, cvAttributes);
+        super(targetType.getName() + " *", size, cvAttributes, astLocus);
         this.targetType = targetType;
-        if (null != typedefedName) {
-            setTypedefName(typedefedName);
-        }
     }
 
     @Override
@@ -77,7 +79,7 @@ public class PointerType extends Type implements Cloneable {
 
     @Override
     public boolean hasName() {
-        if ( hasTypedefName() ) {
+        if ( isTypedef() ) {
             return super.hasName();
         } else {
             return targetType.hasName();
@@ -86,7 +88,7 @@ public class PointerType extends Type implements Cloneable {
 
     @Override
     public String getName(final boolean includeCVAttrs) {
-        if ( hasTypedefName() ) {
+        if ( isTypedef() ) {
             return super.getName(includeCVAttrs);
         } else if (!includeCVAttrs) {
             return targetType.getName(includeCVAttrs) + " *";
@@ -97,7 +99,7 @@ public class PointerType extends Type implements Cloneable {
 
     @Override
     public String getCName(final boolean includeCVAttrs) {
-        if ( hasTypedefName() ) {
+        if ( isTypedef() ) {
             return super.getCName(includeCVAttrs);
         } else if (!includeCVAttrs) {
             return targetType.getCName(includeCVAttrs) + " *";
@@ -134,7 +136,7 @@ public class PointerType extends Type implements Cloneable {
 
     @Override
     public String toString() {
-        if ( hasTypedefName() ) {
+        if ( isTypedef() ) {
             return super.getCName(true);
         } else {
             return toStringInt();
@@ -167,6 +169,10 @@ public class PointerType extends Type implements Cloneable {
 
     @Override
     Type newCVVariant(final int cvAttributes) {
-        return new PointerType(getSize(), targetType, cvAttributes, (hasTypedefName() ? getName() : null));
+        final Type t = new PointerType(getSize(), targetType, cvAttributes, astLocus);
+        if( isTypedef() ) {
+            t.setTypedef(getName(), getTypedefCVAttributes());
+        }
+        return t;
     }
 }
diff --git a/src/java/com/jogamp/gluegen/cgram/types/PrimitiveType.java b/src/java/com/jogamp/gluegen/cgram/types/PrimitiveType.java
index 8a86337..69e28ab 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/PrimitiveType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/PrimitiveType.java
@@ -39,10 +39,12 @@
  */
 package com.jogamp.gluegen.cgram.types;
 
+import com.jogamp.gluegen.ASTLocusTag;
+
 public abstract class PrimitiveType extends Type implements Cloneable {
 
-    protected PrimitiveType(final String name, final SizeThunk size, final int cvAttributes) {
-        super(name, size, cvAttributes);
+    protected PrimitiveType(final String name, final SizeThunk size, final int cvAttributes, final ASTLocusTag astLocus) {
+        super(name, size, cvAttributes, astLocus);
     }
 
     @Override
diff --git a/src/java/com/jogamp/gluegen/cgram/types/StructType.java b/src/java/com/jogamp/gluegen/cgram/types/StructType.java
index 4998484..7f2f865 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/StructType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/StructType.java
@@ -27,14 +27,12 @@
  */
 package com.jogamp.gluegen.cgram.types;
 
-public class StructType extends CompoundType {
+import com.jogamp.gluegen.ASTLocusTag;
 
-  public StructType(final String name, final SizeThunk size, final int cvAttributes) {
-      this(name, size, cvAttributes, null);
-  }
+public class StructType extends CompoundType {
 
-  StructType(final String name, final SizeThunk size, final int cvAttributes, final String structName) {
-    super (name, size, cvAttributes, structName);
+  StructType(final String name, final SizeThunk size, final int cvAttributes, final String structName, final ASTLocusTag astLocus) {
+    super (name, size, cvAttributes, structName, astLocus);
   }
 
   @Override
@@ -44,10 +42,10 @@ public class StructType extends CompoundType {
 
   @Override
   Type newCVVariant(final int cvAttributes) {
-    final StructType t = new StructType(getName(), getSize(), cvAttributes, getStructName());
+    final StructType t = new StructType(getName(), getSize(), cvAttributes, getStructName(), astLocus);
     t.setFields(getFields());
-    if( hasTypedefName() ) {
-        t.setTypedefName( getName() );
+    if( isTypedef() ) {
+        t.setTypedef(getTypedefCVAttributes());
     }
     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 cd48aa0..9fd51fe 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/Type.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/Type.java
@@ -41,6 +41,8 @@
 package com.jogamp.gluegen.cgram.types;
 
 import com.jogamp.common.os.MachineDataInfo;
+import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider;
+import com.jogamp.gluegen.ASTLocusTag;
 import com.jogamp.gluegen.GlueGen;
 import com.jogamp.gluegen.TypeConfig;
 import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
@@ -49,36 +51,34 @@ import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
     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, SemanticEqualityOp {
+public abstract class Type implements Cloneable, SemanticEqualityOp, ASTLocusTagProvider {
   public final boolean relaxedEqSem;
   private final int cvAttributes;
   private String name;
   private SizeThunk size;
-  private int typedefedCVAttributes;
-  private boolean hasTypedefName;
+  private int typedefCVAttributes;
+  private boolean isTypedef;
   private boolean hasCachedHash;
   private int cachedHash;
   private boolean hasCachedSemanticHash;
   private int cachedSemanticHash;
+  final ASTLocusTag astLocus;
 
-  protected Type(final String name, final SizeThunk size, final int cvAttributes) {
-    setName(name);
+  protected Type(final String name, final SizeThunk size, final int cvAttributes, final ASTLocusTag astLocus) {
+    setName(name); // -> clearCache()
     this.relaxedEqSem = TypeConfig.relaxedEqualSemanticsTest();
     this.cvAttributes = cvAttributes;
     this.size = size;
-    this.typedefedCVAttributes = 0;
-    this.hasTypedefName = false;
-    this.hasCachedHash = false;
-    this.cachedHash = 0;
-    this.hasCachedSemanticHash = false;
-    this.cachedSemanticHash = 0;
+    this.typedefCVAttributes = 0;
+    this.isTypedef = false;
+    this.astLocus = astLocus;
   }
 
   protected final void clearCache() {
-    cachedHash = 0;
     hasCachedHash = false;
+    cachedHash = 0;
+    hasCachedSemanticHash = false;
     cachedSemanticHash = 0;
-    hasCachedHash = false;
   }
 
   @Override
@@ -90,6 +90,9 @@ public abstract class Type implements Cloneable, SemanticEqualityOp {
     }
   }
 
+  @Override
+  public final ASTLocusTag getASTLocusTag() { return astLocus; }
+
   public final boolean isAnonymous() { return null == name; }
 
   public boolean hasName() { return null != name; }
@@ -139,11 +142,15 @@ public abstract class Type implements Cloneable, SemanticEqualityOp {
   }
   // For debugging
   public String getDebugString() {
+      return getDebugString(false);
+  }
+  // For debugging
+  public String getDebugString(final boolean withASTLoc) {
     final StringBuilder sb = new StringBuilder();
     boolean prepComma = false;
     sb.append("CType[");
     sb.append("(").append(getClass().getSimpleName()).append(") ");
-    if( hasTypedefName() ) {
+    if( isTypedef() ) {
         sb.append("typedef ");
     }
     if( null != name ) {
@@ -223,34 +230,85 @@ public abstract class Type implements Cloneable, SemanticEqualityOp {
     if( isVoid() ) {
         append(sb, "void", prepComma); prepComma=true;
     }
-    sb.append("]]");
+    sb.append("]");
+    if( withASTLoc ) {
+        sb.append(", loc ").append(astLocus);
+    }
+    sb.append("]");
     return sb.toString();
   }
   private final int objHash() { return super.hashCode(); }
 
 
-  protected final void setName(final String name) {
-    if (name == null) {
+  /**
+   * Returns {@code true} if given {@code name} is not {@code null}
+   * and has a length &gt; 0. In this case this instance's names will
+   * be set to the internalized version.
+   * <p>
+   * Otherwise method returns {@code false}
+   * and this instance's name will be set to {@code null}.
+   * </p>
+   * <p>
+   * Method issues {@link #clearCache()}, to force re-evaluation
+   * of hashes.
+   * </p>
+   */
+  protected final boolean setName(final String name) {
+    clearCache();
+    if( null == name || 0 == name.length() ) {
       this.name = name;
+      return false;
     } else {
       this.name = name.intern();
+      return true;
     }
-    clearCache();
   }
 
-  /** Set the name of this type; used for handling typedefs. */
+  /**
+   * Set the typedef name of this type and renders this type a typedef,
+   * if given {@code name} has a length.
+   * <p>
+   * Method issues {@link #clearCache()}, to force re-evaluation
+   * of hashes.
+   * </p>
+   */
   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;
+    if( setName(name) ) {
+        // Capture the const/volatile attributes at the time of typedef so
+        // we don't redundantly repeat them in the CV attributes string
+        typedefCVAttributes = cvAttributes;
+        isTypedef = true;
+    }
+  }
+  /**
+   * Set the typedef name of this type and renders this type a typedef,
+   * if given {@code name} has a length.
+   * <p>
+   * Method issues {@link #clearCache()}, to force re-evaluation
+   * of hashes.
+   * </p>
+   */
+  final void setTypedef(final String name, final int typedefedCVAttributes) {
+    if( setName(name) ) {
+        this.typedefCVAttributes = typedefedCVAttributes;
+        this.isTypedef = true;
+    }
+  }
+  final void setTypedef(final int typedefedCVAttributes) {
+    this.typedefCVAttributes = typedefedCVAttributes;
+    this.isTypedef = true;
+    clearCache();
+  }
+  final int getTypedefCVAttributes() {
+    return typedefCVAttributes;
   }
 
-  /** 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;
+  /**
+   * Indicates whether this type is a typedef type,
+   * i.e. declared via {@link #setTypedefName(String)}.
+   */
+  public final boolean isTypedef() {
+    return isTypedef;
   }
 
   /** SizeThunk which computes size of this type in bytes. */
@@ -312,9 +370,9 @@ public abstract class Type implements Cloneable, SemanticEqualityOp {
   public boolean      isVoid()     { return (asVoid()     != null); }
 
   /** Indicates whether this type is const. */
-  public boolean      isConst()    { return (((cvAttributes & ~typedefedCVAttributes) & CVAttributes.CONST) != 0); }
+  public boolean      isConst()    { return (((cvAttributes & ~typedefCVAttributes) & CVAttributes.CONST) != 0); }
   /** Indicates whether this type is volatile. */
-  public boolean      isVolatile() { return (((cvAttributes & ~typedefedCVAttributes) & CVAttributes.VOLATILE) != 0); }
+  public boolean      isVolatile() { return (((cvAttributes & ~typedefCVAttributes) & CVAttributes.VOLATILE) != 0); }
 
   /** Indicates whether this type is a primitive type. */
   public boolean      isPrimitive(){ return false; }
@@ -330,11 +388,11 @@ public abstract class Type implements Cloneable, SemanticEqualityOp {
   public final int hashCode() {
     if( !hasCachedHash ) {
         // 31 * x == (x << 5) - x
-        int hash = 31 + ( hasTypedefName ? 1 : 0 );
+        int hash = 31 + ( isTypedef ? 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 ) {
+        if( !isTypedef ) {
             hash = ((hash << 5) - hash) + hashCodeImpl();
         }
         cachedHash = hash;
@@ -355,7 +413,7 @@ public abstract class Type implements Cloneable, SemanticEqualityOp {
         return false;
     } else {
         final Type t = (Type)arg;
-        if( hasTypedefName == t.hasTypedefName &&
+        if( isTypedef == t.isTypedef &&
             ( ( null != size && size.equals(t.size) ) ||
               ( null == size && null == t.size )
             ) &&
@@ -363,7 +421,7 @@ public abstract class Type implements Cloneable, SemanticEqualityOp {
             ( null == name ? null == t.name : name.equals(t.name) )
           )
         {
-            if( !hasTypedefName ) {
+            if( !isTypedef ) {
                 return equalsImpl(t);
             } else {
                 return true;
diff --git a/src/java/com/jogamp/gluegen/cgram/types/UnionType.java b/src/java/com/jogamp/gluegen/cgram/types/UnionType.java
index 6ccc4a2..e03d671 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/UnionType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/UnionType.java
@@ -27,14 +27,12 @@
  */
 package com.jogamp.gluegen.cgram.types;
 
-public class UnionType extends CompoundType {
+import com.jogamp.gluegen.ASTLocusTag;
 
-  public UnionType(final String name, final SizeThunk size, final int cvAttributes) {
-      this(name, size, cvAttributes, null);
-  }
+public class UnionType extends CompoundType {
 
-  UnionType(final String name, final SizeThunk size, final int cvAttributes, final String structName) {
-    super (name, size, cvAttributes, structName);
+  UnionType(final String name, final SizeThunk size, final int cvAttributes, final String structName, final ASTLocusTag astLocus) {
+    super (name, size, cvAttributes, structName, astLocus);
   }
 
   @Override
@@ -44,10 +42,10 @@ public class UnionType extends CompoundType {
 
   @Override
   Type newCVVariant(final int cvAttributes) {
-    final UnionType t = new UnionType(getName(), getSize(), cvAttributes, getStructName());
+    final UnionType t = new UnionType(getName(), getSize(), cvAttributes, getStructName(), astLocus);
     t.setFields(getFields());
-    if( hasTypedefName() ) {
-        t.setTypedefName( getName() );
+    if( isTypedef() ) {
+        t.setTypedef(getTypedefCVAttributes());
     }
     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 f6adaac..f63bda3 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/VoidType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/VoidType.java
@@ -39,14 +39,16 @@
  */
 package com.jogamp.gluegen.cgram.types;
 
+import com.jogamp.gluegen.ASTLocusTag;
+
 public class VoidType extends Type implements Cloneable {
 
-    public VoidType(final int cvAttributes) {
-        this("void", cvAttributes);
+    public VoidType(final int cvAttributes, final ASTLocusTag astLocus) {
+        this("void", cvAttributes, astLocus);
     }
 
-    private VoidType(final String name, final int cvAttributes) {
-        super(name, null, cvAttributes);
+    private VoidType(final String name, final int cvAttributes, final ASTLocusTag astLocus) {
+        super(name, null, cvAttributes, astLocus);
     }
 
     @Override
@@ -56,7 +58,11 @@ public class VoidType extends Type implements Cloneable {
 
     @Override
     Type newCVVariant(final int cvAttributes) {
-        return new VoidType(getName(), cvAttributes);
+        final Type t = new VoidType(getName(), cvAttributes, astLocus);
+        if( isTypedef() ) {
+            t.setTypedef(getTypedefCVAttributes());
+        }
+        return t;
     }
 
     @Override
diff --git a/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
index 982e16d..09e6822 100644
--- a/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
@@ -134,7 +134,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, null);
+                final PointerType funcPtrType = new PointerType(null, cSym.getType(), 0);
                 // Just for safety, emit this name slightly differently than
                 // the mangling would otherwise produce
                 funcPointerTypedefName = "_local_" + funcPointerTypedefName;
diff --git a/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java b/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java
index c4dedb7..7ccfd1b 100644
--- a/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java
+++ b/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java
@@ -131,7 +131,11 @@ public class CStructAnnotationProcessor extends AbstractProcessor {
             if( f.exists() ) {
                 return f;
             }
-        } catch (final IOException e) { if(DEBUG) { System.err.println("Caught "+e.getClass().getSimpleName()+": "+e.getMessage()); /* e.printStackTrace(); */ } }
+        } catch (final IOException e) {
+            if(DEBUG) {
+                System.err.println("Caught "+e.getClass().getSimpleName()+": "+e.getMessage()); /* e.printStackTrace(); */
+            }
+        }
         return null;
     }
 
@@ -263,6 +267,9 @@ public class CStructAnnotationProcessor extends AbstractProcessor {
         } catch (final FileNotFoundException ex) {
             throw new RuntimeException("input file not found", ex);
         }
+        if( DEBUG  ) {
+            GlueGen.setDebug(true);
+        }
         new GlueGen().run(reader, filename, AnnotationProcessorJavaStructEmitter.class,
                           includePaths, cfgFiles, outputPath1, false /* copyCPPOutput2Stderr */);
 
-- 
cgit v1.2.3