diff options
author | Sven Gothel <[email protected]> | 2010-11-06 03:44:12 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-11-06 03:44:12 +0100 |
commit | 6b6b9b3b81cdc85b7260664ebec547756a6be5d7 (patch) | |
tree | 5f2b4e83d4d04117ea27571d278b4074ae9ca038 /src/java/com/sun/gluegen/cgram/HeaderParser.g | |
parent | 33ea83cfcad373e477791a0aca49864399357877 (diff) |
Fix native type representation; Retain typedef declName in resulting Type for variables; Misc
Fix native type representation
----------------------------------
The following custom types were previously build-in:
__int32, __int64
Adding the following native build-in types (necessary):
ptrdiff_t, size_t
These compiler/platform specific types shall not be typedef'ed
via header files. Hence we provide proper typing for such,
as the compiler would do.
Adding the following native build-in types (convenience):
int32_t, uint32_t, int64_t, uint64_t
These are provided due to their lack of support on certain platforms,
and probable source of bugs, when defined by the user.
Retain typedef declName in resulting Type for variables.
--------------------------------------------------------
Adding Clonable to all cgram Type derivations.
Assume use case:
typedef khronos_ssize_t GLsizeiptr
typedef size_t khronos_ssize_t
The previous code picked a one level depth type in the dictionary
if exists. Hence it made khronos_ssize_t visible in the javadoc and native code.
It is our believe that the generated native code, as well as the javadoc comments
shall reflect the original GlueGen'ed API and it's types.
Also, aliasing or reducing native types via GlueGen could result in plattorm dependencies
and in worst cases, incompatible native types.
This patch clones the 1 level depth Type (typedef), clones it
and sets the declName, so it's visible to the GlueGen layers.
Misc
-------
GlueGen's debug flag is passed to HeaderParser,
where it traces misc information.
Diffstat (limited to 'src/java/com/sun/gluegen/cgram/HeaderParser.g')
-rw-r--r-- | src/java/com/sun/gluegen/cgram/HeaderParser.g | 223 |
1 files changed, 139 insertions, 84 deletions
diff --git a/src/java/com/sun/gluegen/cgram/HeaderParser.g b/src/java/com/sun/gluegen/cgram/HeaderParser.g index 7c13968..9040c29 100644 --- a/src/java/com/sun/gluegen/cgram/HeaderParser.g +++ b/src/java/com/sun/gluegen/cgram/HeaderParser.g @@ -1,5 +1,6 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 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 @@ -56,6 +57,16 @@ options { /** Name assigned to a anonymous EnumType (e.g., "enum { ... }"). */ public static final String ANONYMOUS_ENUM_NAME = "<anonymous>"; + boolean debug = false; + + public boolean getDebug() { + return debug; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + /** Set the dictionary mapping typedef names to types for this HeaderParser. Must be done before parsing. */ public void setTypedefDictionary(TypeDictionary dict) { @@ -88,13 +99,13 @@ options { } /** Pre-define the list of EnumTypes for this HeaderParser. Must be - done before parsing. */ + done before parsing. */ public void setEnums(List/*<EnumType>*/ enumTypes) { // FIXME: Need to take the input set of EnumTypes, extract all // the enumerates from each EnumType, and fill in the enumHash // so that each enumerate maps to the enumType to which it // belongs. - throw new RuntimeException("setEnums is Unimplemented!"); + throw new RuntimeException("setEnums is Unimplemented!"); } /** Returns the EnumTypes this HeaderParser processed. */ @@ -176,24 +187,53 @@ options { boolean isTypedef() { return isTypedef; } - // for easier debugging - public String toString() { - String tStr = "Type=NULL_REF"; - if (type == origType) { - tStr = "Type=ORIG_TYPE"; - } else if (type != null) { - tStr = "Type: name=\"" + type.getCVAttributesString() + " " + + // for easier debugging + public String toString() { + String tStr = "Type=NULL_REF"; + if (type == origType) { + tStr = "Type=ORIG_TYPE"; + } else if (type != null) { + tStr = "Type: name=\"" + type.getCVAttributesString() + " " + type.getName() + "\"; signature=\"" + type + "\"; class " + - type.getClass().getName(); - } - String oStr = "OrigType=NULL_REF"; - if (origType != null) { - oStr = "OrigType: name=\"" + origType.getCVAttributesString() + " " + + type.getClass().getName(); + } + String oStr = "OrigType=NULL_REF"; + if (origType != null) { + oStr = "OrigType: name=\"" + origType.getCVAttributesString() + " " + origType.getName() + "\"; signature=\"" + origType + "\"; class " + - origType.getClass().getName(); - } - return "<["+tStr + "] [" + oStr + "] " + " isTypedef=" + isTypedef+">"; - } + origType.getClass().getName(); + } + return "<["+tStr + "] [" + oStr + "] " + " isTypedef=" + isTypedef+">"; + } + } + + private String getTypeString(Type t) { + StringBuffer sb = new StringBuffer(); + sb.append("["); + sb.append(t); + sb.append(", size: "); + if(null!=t) { + SizeThunk st = t.getSize(); + if(null!=st) { + sb.append(st.getClass().getName()); + } else { + sb.append("undef"); + } + } + sb.append("]"); + return sb.toString(); + } + + private void debugPrintln(String msg) { + if(debug) { + System.err.println(msg); + } + } + + private void debugPrint(String msg) { + if(debug) { + System.err.print(msg); + } } private boolean doDeclaration; // Used to only process function typedefs @@ -231,12 +271,12 @@ options { private void processDeclaration(Type returnType) { if (doDeclaration) { FunctionSymbol sym = new FunctionSymbol(declId, new FunctionType(null, null, returnType, 0)); - if (parameters != null) { // handle funcs w/ empty parameter lists (e.g., "foo()") + if (parameters != null) { // handle funcs w/ empty parameter lists (e.g., "foo()") for (Iterator iter = parameters.iterator(); iter.hasNext(); ) { ParameterDeclaration pd = (ParameterDeclaration) iter.next(); sym.addArgument(pd.type(), pd.id()); } - } + } functions.add(sym); } } @@ -276,29 +316,29 @@ options { } /** Utility function: creates a new EnumType with the given name, or - returns an existing one if it has already been created. */ + returns an existing one if it has already been created. */ private EnumType getEnumType(String enumTypeName) { - EnumType enumType = null; - Iterator it = enumHash.values().iterator(); - while (it.hasNext()) { - EnumType potentialMatch = (EnumType)it.next(); - if (potentialMatch.getName().equals(enumTypeName)) { - enumType = potentialMatch; - break; - } - } - - if (enumType == null) { + EnumType enumType = null; + Iterator it = enumHash.values().iterator(); + while (it.hasNext()) { + EnumType potentialMatch = (EnumType)it.next(); + if (potentialMatch.getName().equals(enumTypeName)) { + enumType = potentialMatch; + break; + } + } + + if (enumType == null) { // This isn't quite correct. In theory the enum should expand to // the size of the largest element, so if there were a long long // entry the enum should expand to e.g. int64. However, using // "long" here (which is what used to be the case) was // definitely incorrect and caused problems. - enumType = new EnumType(enumTypeName, SizeThunk.INT); - } - - return enumType; - } + enumType = new EnumType(enumTypeName, SizeThunk.INT); + } + + return enumType; + } // Map used to canonicalize types. For example, we may typedef // struct foo { ... } *pfoo; subsequent references to struct foo* should @@ -343,17 +383,17 @@ declarator[TypeBox tb] returns [String s] { /* TypeBox becomes function pointer in this case */ FunctionType ft = new FunctionType(null, null, tb.type(), 0); if (params == null) { - // If the function pointer has no declared parameters, it's a - // void function. I'm not sure if the parameter name is - // ever referenced anywhere when the type is VoidType, so + // If the function pointer has no declared parameters, it's a + // void function. I'm not sure if the parameter name is + // ever referenced anywhere when the type is VoidType, so // just in case I'll set it to a comment string so it will - // still compile if written out to code anywhere. - ft.addArgument(new VoidType(0), "/*unnamed-void*/"); - } else { - for (Iterator iter = params.iterator(); iter.hasNext(); ) { + // still compile if written out to code anywhere. + ft.addArgument(new VoidType(0), "/*unnamed-void*/"); + } else { + for (Iterator iter = params.iterator(); iter.hasNext(); ) { ParameterDeclaration pd = (ParameterDeclaration) iter.next(); ft.addArgument(pd.type(), pd.id()); - } + } } tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, ft, @@ -457,15 +497,21 @@ typeSpecifier[int attributes] returns [Type t] { int cvAttrs = attrs2CVAttrs(attributes); boolean unsigned = ((attributes & UNSIGNED) != 0); } - : "void" { t = new VoidType(cvAttrs); } - | "char" { t = new IntType("char" , SizeThunk.CHAR, unsigned, cvAttrs); } - | "short" { t = new IntType("short", SizeThunk.SHORT, unsigned, cvAttrs); } - | "int" { t = new IntType("int" , SizeThunk.INT, unsigned, cvAttrs); } - | "long" { t = new IntType("long" , SizeThunk.LONG, unsigned, cvAttrs); } - | "__int32" { t = new IntType("__int32", SizeThunk.INT, unsigned, cvAttrs); } - | "__int64" { t = new IntType("__int64", SizeThunk.INT64, unsigned, cvAttrs); } - | "float" { t = new FloatType("float", SizeThunk.FLOAT, cvAttrs); } - | "double" { t = new DoubleType("double", SizeThunk.DOUBLE, cvAttrs); } + : "void" { t = new VoidType(cvAttrs); } + | "char" { t = new IntType("char" , SizeThunk.CHAR, unsigned, cvAttrs); } + | "short" { t = new IntType("short", SizeThunk.SHORT, unsigned, cvAttrs); } + | "int" { t = new IntType("int" , SizeThunk.INT, unsigned, cvAttrs); } + | "long" { t = new IntType("long" , SizeThunk.LONG, unsigned, cvAttrs); } + | "float" { t = new FloatType("float", SizeThunk.FLOAT, cvAttrs); } + | "double" { t = new DoubleType("double", SizeThunk.DOUBLE, cvAttrs); } + | "__int32" { t = new IntType("__int32", SizeThunk.INT, unsigned, cvAttrs); } + | "int32_t" { t = new IntType("int32_t", SizeThunk.INT, false, cvAttrs); /* TS: always signed */ } + | "uint32_t" { t = new IntType("uint32_t", SizeThunk.INT, true, cvAttrs); /* TS: always unsigned */ } + | "__int64" { t = new IntType("__int64", SizeThunk.INT64, unsigned, cvAttrs); } + | "int64_t" { t = new IntType("int64_t", SizeThunk.INT64, false, cvAttrs); /* TS: always signed */ } + | "uint64_t" { t = new IntType("uint64_t", SizeThunk.INT64, true, cvAttrs); /* TS: always unsigned */ } + | "ptrdiff_t" { t = new IntType("ptrdiff_t", SizeThunk.POINTER, false, cvAttrs); /* TS: always signed */ } + | "size_t" { t = new IntType("size_t", SizeThunk.POINTER, true, cvAttrs); /* TS: always unsigned */ } | t = structSpecifier[cvAttrs] ( attributeDecl )* | t = unionSpecifier [cvAttrs] ( attributeDecl )* | t = enumSpecifier [cvAttrs] @@ -481,8 +527,10 @@ typeSpecifier[int attributes] returns [Type t] { typedefName[int cvAttrs] returns [Type t] { t = null; } : #(NTypedefName id : ID) - { - t = canonicalize(lookupInTypedefDictionary(id.getText()).getCVVariant(cvAttrs)); + { + Type tdict = lookupInTypedefDictionary(id.getText()); + t = canonicalize(tdict.getCVVariant(cvAttrs)); + debugPrintln("Adding typedef canon : [" + id.getText() + "] -> [" + tdict + "] -> "+getTypeString(t)); } ; @@ -575,7 +623,7 @@ structDeclarator[CompoundType containingType, Type t] returns [boolean addedAny] // I haven't implemented it yet because I'm not sure how to get the // "enumName" *before* executing the enumList rule. enumSpecifier [int cvAttrs] returns [Type t] { - t = null; + t = null; } : #( "enum" ( ( ID LCURLY )=> i:ID LCURLY enumList[(EnumType)(t = getEnumType(i.getText()))] RCURLY @@ -586,18 +634,18 @@ enumSpecifier [int cvAttrs] returns [Type t] { ; enumList[EnumType enumeration] { - long defaultEnumerantValue = 0; + long defaultEnumerantValue = 0; } : ( defaultEnumerantValue = enumerator[enumeration, defaultEnumerantValue] )+ ; enumerator[EnumType enumeration, long defaultValue] returns [long newDefaultValue] { - newDefaultValue = defaultValue; + newDefaultValue = defaultValue; } : eName:ID ( ASSIGN eVal:expr )? { long value = 0; if (eVal != null) { - String vTxt = eVal.getAllChildrenText(); + String vTxt = eVal.getAllChildrenText(); if (enumHash.containsKey(vTxt)) { EnumType oldEnumType = (EnumType) enumHash.get(vTxt); value = oldEnumType.getEnumValue(vTxt); @@ -605,7 +653,7 @@ enumerator[EnumType enumeration, long defaultValue] returns [long newDefaultValu try { value = Long.decode(vTxt).longValue(); } catch (NumberFormatException e) { - System.err.println("NumberFormatException: ID[" + eName.getText() + "], VALUE=[" + vTxt + "]"); + System.err.println("NumberFormatException: ID[" + eName.getText() + "], VALUE=[" + vTxt + "]"); throw e; } } @@ -613,25 +661,25 @@ enumerator[EnumType enumeration, long defaultValue] returns [long newDefaultValu value = defaultValue; } - newDefaultValue = value+1; - String eTxt = eName.getText(); - if (enumHash.containsKey(eTxt)) { - EnumType oldEnumType = (EnumType) enumHash.get(eTxt); - long oldValue = oldEnumType.getEnumValue(eTxt); - System.err.println("WARNING: redefinition of enumerated value '" + eTxt + "';" + - " existing definition is in enumeration '" + oldEnumType.getName() + - "' with value " + oldValue + " and new definition is in enumeration '" + - enumeration.getName() + "' with value " + value); - // remove old definition - oldEnumType.removeEnumerate(eTxt); - } - // insert new definition - enumeration.addEnum(eTxt, value); - enumHash.put(eTxt, enumeration); - //System.err.println("ENUM [" + enumeration.getName() + "]: " + eTxt + " = " + enumeration.getEnumValue(eTxt) + - // " (new default = " + newDefaultValue + ")"); - } - ; + newDefaultValue = value+1; + String eTxt = eName.getText(); + if (enumHash.containsKey(eTxt)) { + EnumType oldEnumType = (EnumType) enumHash.get(eTxt); + long oldValue = oldEnumType.getEnumValue(eTxt); + System.err.println("WARNING: redefinition of enumerated value '" + eTxt + "';" + + " existing definition is in enumeration '" + oldEnumType.getName() + + "' with value " + oldValue + " and new definition is in enumeration '" + + enumeration.getName() + "' with value " + value); + // remove old definition + oldEnumType.removeEnumerate(eTxt); + } + // insert new definition + enumeration.addEnum(eTxt, value); + enumHash.put(eTxt, enumeration); + debugPrintln("ENUM [" + enumeration.getName() + "]: " + eTxt + " = " + enumeration.getEnumValue(eTxt) + + " (new default = " + newDefaultValue + ")"); + } + ; initDeclList[TypeBox tb] : ( initDecl[tb] )+ @@ -642,8 +690,8 @@ initDecl[TypeBox tb] { } : #( NInitDecl declName = declarator[tb] { - //System.err.println("GOT declName: " + declName + " TB=" + tb); - } + debugPrintln("GOT declName: " + declName + " TB=" + tb); + } ( attributeDecl )* ( ASSIGN initializer | COLON expr @@ -652,11 +700,18 @@ initDecl[TypeBox tb] { { if ((declName != null) && (tb != null) && tb.isTypedef()) { Type t = tb.type(); - //System.err.println("Adding typedef mapping: [" + declName + "] -> [" + t + "]"); + debugPrint("Adding typedef mapping: [" + declName + "] -> "+getTypeString(t)); if (!t.hasTypedefName()) { t.setName(declName); + debugPrint(" - declName -> "+getTypeString(t)); + } else { + // copy type to preserve declName ! + t = (Type) t.clone(); + t.setName(declName); + debugPrint(" - copy -> "+getTypeString(t)); } t = canonicalize(t); + debugPrintln(" - canon -> "+getTypeString(t)); typedefDictionary.put(declName, t); // Clear out PointerGroup effects in case another typedef variant follows tb.reset(); @@ -667,7 +722,7 @@ initDecl[TypeBox tb] { pointerGroup[TypeBox tb] { int x = 0; int y = 0; } : #( NPointerGroup ( STAR { x = 0; y = 0; } ( y = typeQualifier { x |= y; } )* { - //System.err.println("IN PTR GROUP: TB=" + tb); + debugPrintln("IN PTR GROUP: TB=" + tb); if (tb != null) { tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, tb.type(), |