summaryrefslogtreecommitdiffstats
path: root/src/net/java/games/gluegen/cgram
diff options
context:
space:
mode:
authordjp <[email protected]>2003-06-08 19:27:01 +0000
committerdjp <[email protected]>2003-06-08 19:27:01 +0000
commitd49fd968963909f181423eae46c613189468fac3 (patch)
treeb231329e6b65fd54aa24b3bcc0a3ecc623daec61 /src/net/java/games/gluegen/cgram
parent9c8fb046dee5d832bea3f36dcbd43285054f49a0 (diff)
Initial revision
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@3 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/net/java/games/gluegen/cgram')
-rw-r--r--src/net/java/games/gluegen/cgram/CSymbolTable.java132
-rw-r--r--src/net/java/games/gluegen/cgram/CToken.java32
-rw-r--r--src/net/java/games/gluegen/cgram/Define.java56
-rw-r--r--src/net/java/games/gluegen/cgram/GnuCEmitter.g1145
-rw-r--r--src/net/java/games/gluegen/cgram/GnuCParser.g864
-rw-r--r--src/net/java/games/gluegen/cgram/GnuCTreeParser.g852
-rw-r--r--src/net/java/games/gluegen/cgram/HeaderParser.g715
-rw-r--r--src/net/java/games/gluegen/cgram/LineObject.java126
-rw-r--r--src/net/java/games/gluegen/cgram/PreprocessorInfoChannel.java73
-rw-r--r--src/net/java/games/gluegen/cgram/StdCParser.g1375
-rw-r--r--src/net/java/games/gluegen/cgram/TNode.java433
-rw-r--r--src/net/java/games/gluegen/cgram/TNodeFactory.java33
-rw-r--r--src/net/java/games/gluegen/cgram/types/ArrayType.java131
-rw-r--r--src/net/java/games/gluegen/cgram/types/BitType.java87
-rw-r--r--src/net/java/games/gluegen/cgram/types/CVAttributes.java48
-rw-r--r--src/net/java/games/gluegen/cgram/types/CompoundType.java205
-rw-r--r--src/net/java/games/gluegen/cgram/types/CompoundTypeKind.java50
-rw-r--r--src/net/java/games/gluegen/cgram/types/DoubleType.java64
-rw-r--r--src/net/java/games/gluegen/cgram/types/EnumType.java147
-rw-r--r--src/net/java/games/gluegen/cgram/types/Field.java96
-rw-r--r--src/net/java/games/gluegen/cgram/types/FloatType.java64
-rw-r--r--src/net/java/games/gluegen/cgram/types/FunctionSymbol.java112
-rw-r--r--src/net/java/games/gluegen/cgram/types/FunctionType.java159
-rw-r--r--src/net/java/games/gluegen/cgram/types/IntType.java82
-rw-r--r--src/net/java/games/gluegen/cgram/types/MachineDescription.java78
-rw-r--r--src/net/java/games/gluegen/cgram/types/MachineDescription32Bit.java46
-rw-r--r--src/net/java/games/gluegen/cgram/types/PointerType.java136
-rw-r--r--src/net/java/games/gluegen/cgram/types/PrimitiveType.java50
-rw-r--r--src/net/java/games/gluegen/cgram/types/Type.java242
-rw-r--r--src/net/java/games/gluegen/cgram/types/TypeDictionary.java169
-rw-r--r--src/net/java/games/gluegen/cgram/types/TypeVisitor.java44
-rw-r--r--src/net/java/games/gluegen/cgram/types/VoidType.java56
32 files changed, 7902 insertions, 0 deletions
diff --git a/src/net/java/games/gluegen/cgram/CSymbolTable.java b/src/net/java/games/gluegen/cgram/CSymbolTable.java
new file mode 100644
index 000000000..e22274b90
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/CSymbolTable.java
@@ -0,0 +1,132 @@
+package net.java.games.gluegen.cgram;
+
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+
+
+public class CSymbolTable {
+
+ /** holds list of scopes */
+ private Vector scopeStack;
+
+ /** table where all defined names are mapped to TNode tree nodes */
+ private Hashtable symTable;
+
+ public CSymbolTable() {
+ scopeStack = new Vector(10);
+ symTable = new Hashtable(533);
+ }
+
+
+ /** push a new scope onto the scope stack.
+ */
+ public void pushScope(String s) {
+ //System.out.println("push scope:" + s);
+ scopeStack.addElement(s);
+ }
+
+ /** pop the last scope off the scope stack.
+ */
+ public void popScope() {
+ //System.out.println("pop scope");
+ int size = scopeStack.size();
+ if(size > 0)
+ scopeStack.removeElementAt(size - 1);
+ }
+
+ /** return the current scope as a string
+ */
+ public String currentScopeAsString() {
+ StringBuffer buf = new StringBuffer(100);
+ boolean first = true;
+ Enumeration e = scopeStack.elements();
+ while(e.hasMoreElements()) {
+ if(first)
+ first = false;
+ else
+ buf.append("::");
+ buf.append(e.nextElement().toString());
+ }
+ return buf.toString();
+ }
+
+ /** given a name for a type, append it with the
+ current scope.
+ */
+ public String addCurrentScopeToName(String name) {
+ String currScope = currentScopeAsString();
+ return addScopeToName(currScope, name);
+ }
+
+ /** given a name for a type, append it with the
+ given scope. MBZ
+ */
+ public String addScopeToName(String scope, String name) {
+ if(scope == null || scope.length() > 0)
+ return scope + "::" + name;
+ else
+ return name;
+ }
+
+ /** remove one level of scope from name MBZ*/
+ public String removeOneLevelScope(String scopeName) {
+ int index = scopeName.lastIndexOf("::");
+ if (index > 0) {
+ return scopeName.substring(0,index);
+ }
+ if (scopeName.length() > 0) {
+ return "";
+ }
+ return null;
+ }
+
+ /** add a node to the table with it's key as
+ the current scope and the name */
+ public TNode add(String name, TNode node) {
+ return (TNode)symTable.put(addCurrentScopeToName(name),node);
+ }
+
+
+ /** lookup a fully scoped name in the symbol table */
+ public TNode lookupScopedName(String scopedName) {
+ return (TNode)symTable.get(scopedName);
+ }
+
+ /** lookup an unscoped name in the table by prepending
+ the current scope.
+ MBZ -- if not found, pop scopes and look again
+ */
+ public TNode lookupNameInCurrentScope(String name) {
+ String scope = currentScopeAsString();
+ String scopedName;
+ TNode tnode = null;
+
+ //System.out.println( "\n"+ this.toString() );
+
+ while (tnode == null && scope != null) {
+ scopedName = addScopeToName(scope, name);
+ //System.out.println("lookup trying " + scopedName);
+ tnode = (TNode)symTable.get(scopedName);
+ scope = removeOneLevelScope(scope);
+ }
+ return tnode;
+ }
+
+ /** convert this table to a string */
+ public String toString() {
+ StringBuffer buff = new StringBuffer(300);
+ buff.append("CSymbolTable { \nCurrentScope: " + currentScopeAsString() +
+ "\nDefinedSymbols:\n");
+ Enumeration ke = symTable.keys();
+ Enumeration ve = symTable.elements();
+ while(ke.hasMoreElements()) {
+ buff.append(ke.nextElement().toString() + " (" +
+ TNode.getNameForType(((TNode)ve.nextElement()).getType()) + ")\n");
+ }
+ buff.append("}\n");
+ return buff.toString();
+ }
+
+};
diff --git a/src/net/java/games/gluegen/cgram/CToken.java b/src/net/java/games/gluegen/cgram/CToken.java
new file mode 100644
index 000000000..facd95a08
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/CToken.java
@@ -0,0 +1,32 @@
+package net.java.games.gluegen.cgram;
+
+import antlr.CommonToken;
+
+public class CToken extends antlr.CommonToken {
+ String source = "";
+ int tokenNumber;
+
+ public String getSource()
+ {
+ return source;
+ }
+
+ public void setSource(String src)
+ {
+ source = src;
+ }
+
+ public int getTokenNumber()
+ {
+ return tokenNumber;
+ }
+
+ public void setTokenNumber(int i)
+ {
+ tokenNumber = i;
+ }
+
+ public String toString() {
+ return "CToken:" +"(" + hashCode() + ")" + "[" + getType() + "] "+ getText() + " line:" + getLine() + " source:" + source ;
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/Define.java b/src/net/java/games/gluegen/cgram/Define.java
new file mode 100644
index 000000000..3ab7c9063
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/Define.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram;
+
+/** Represents a #define of a literal to a value (a number represented
+ in string form.) */
+
+public class Define {
+ private String name;
+ private String value;
+
+ public Define(String name, String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public String getName() { return name; }
+ public String getValue() { return value; }
+}
diff --git a/src/net/java/games/gluegen/cgram/GnuCEmitter.g b/src/net/java/games/gluegen/cgram/GnuCEmitter.g
new file mode 100644
index 000000000..87294fc53
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/GnuCEmitter.g
@@ -0,0 +1,1145 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Copyright (c) Non, Inc. 1998 -- All Rights Reserved
+
+PROJECT: C Compiler
+MODULE: GnuCEmitter
+FILE: GnuCEmitter.g
+
+AUTHOR: Monty Zukowski ([email protected]) April 28, 1998
+
+DESCRIPTION:
+
+ This tree grammar is for a Gnu C AST.
+ It turns the tree back into source code.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+
+header {
+ package net.java.games.gluegen.cgram;
+
+ import java.io.*;
+ import java.util.*;
+
+ import antlr.CommonAST;
+ import antlr.DumpASTVisitor;
+}
+
+
+class GnuCEmitter extends GnuCTreeParser;
+
+options
+ {
+ importVocab = GNUC;
+ buildAST = false;
+ ASTLabelType = "TNode";
+
+ // Copied following options from java grammar.
+ codeGenMakeSwitchThreshold = 2;
+ codeGenBitsetTestThreshold = 3;
+ }
+
+
+{
+
+
+int tabs = 0;
+PrintStream currentOutput = System.out;
+int lineNum = 1;
+String currentSource = "";
+LineObject trueSourceFile;
+final int lineDirectiveThreshold = Integer.MAX_VALUE;
+PreprocessorInfoChannel preprocessorInfoChannel = null;
+Stack sourceFiles = new Stack();
+
+public GnuCEmitter( PreprocessorInfoChannel preprocChannel )
+{
+ preprocessorInfoChannel = preprocChannel;
+}
+
+void initializePrinting()
+{
+ Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber( new Integer(1) );
+ printPreprocs(preprocs);
+/* if ( currentSource.equals("") ) {
+ trueSourceFile = new LineObject(currentSource);
+ currentOutput.println("# 1 \"" + currentSource + "\"\n");
+ sourceFiles.push(trueSourceFile);
+ }
+*/
+}
+
+void finalizePrinting() {
+ // flush any leftover preprocessing instructions to the stream
+
+ printPreprocs(
+ preprocessorInfoChannel.extractLinesPrecedingTokenNumber(
+ new Integer( preprocessorInfoChannel.getMaxTokenNumber() + 1 ) ));
+ //print a newline so file ends at a new line
+ currentOutput.println();
+}
+
+void printPreprocs( Vector preprocs )
+{
+ // if there was a preprocessingDirective previous to this token then
+ // print a newline and the directive, line numbers handled later
+ if ( preprocs.size() > 0 ) {
+ if ( trueSourceFile != null ) {
+ currentOutput.println(); //make sure we're starting a new line unless this is the first line directive
+ }
+ lineNum++;
+ Enumeration e = preprocs.elements();
+ while (e.hasMoreElements())
+ {
+ Object o = e.nextElement();
+ if ( o.getClass().getName().equals("LineObject") ) {
+ LineObject l = (LineObject) o;
+
+ // we always return to the trueSourceFile, we never enter it from another file
+ // force it to be returning if in fact we aren't currently in trueSourceFile
+ if (( trueSourceFile != null ) //trueSource exists
+ && ( !currentSource.equals(trueSourceFile.getSource()) ) //currently not in trueSource
+ && ( trueSourceFile.getSource().equals(l.getSource()) ) ) { //returning to trueSource
+ l.setEnteringFile( false );
+ l.setReturningToFile( true );
+ }
+
+
+ // print the line directive
+ currentOutput.println(l);
+ lineNum = l.getLine();
+ currentSource = l.getSource();
+
+
+ // the very first line directive always represents the true sourcefile
+ if ( trueSourceFile == null ) {
+ trueSourceFile = new LineObject(currentSource);
+ sourceFiles.push(trueSourceFile);
+ }
+
+ // keep our own stack of files entered
+ if ( l.getEnteringFile() ) {
+ sourceFiles.push(l);
+ }
+
+ // if returning to a file, pop the exited files off the stack
+ if ( l.getReturningToFile() ) {
+ LineObject top = (LineObject) sourceFiles.peek();
+ while (( top != trueSourceFile ) && (! l.getSource().equals(top.getSource()) )) {
+ sourceFiles.pop();
+ top = (LineObject) sourceFiles.peek();
+ }
+ }
+ }
+ else { // it was a #pragma or such
+ currentOutput.println(o);
+ lineNum++;
+ }
+ }
+ }
+
+}
+
+void print( TNode t ) {
+ int tLineNum = t.getLocalLineNum();
+ if ( tLineNum == 0 ) tLineNum = lineNum;
+
+ Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber((Integer)t.getAttribute("tokenNumber"));
+ printPreprocs(preprocs);
+
+ if ( (lineNum != tLineNum) ) {
+ // we know we'll be newlines or a line directive or it probably
+ // is just the case that this token is on the next line
+ // either way start a new line and indent it
+ currentOutput.println();
+ lineNum++;
+ printTabs();
+ }
+
+ if ( lineNum == tLineNum ){
+ // do nothing special, we're at the right place
+ }
+ else {
+ int diff = tLineNum - lineNum;
+ if ( lineNum < tLineNum ) {
+ // print out the blank lines to bring us up to right line number
+ for ( ; lineNum < tLineNum ; lineNum++ ) {
+ currentOutput.println();
+ }
+ printTabs();
+ }
+ else { // just reset lineNum
+ lineNum = tLineNum;
+ }
+ }
+ currentOutput.print( t.getText() + " " );
+}
+
+
+/* This was my attempt at being smart about line numbers
+ It didn't work quite right but I don't know why, I didn't
+ have enough test cases. Worked ok compiling rcs and ghostscript
+*/
+void printAddingLineDirectives( TNode t ) {
+ int tLineNum = t.getLocalLineNum();
+ String tSource = (String) t.getAttribute("source");
+
+ if ( tSource == null ) tSource = currentSource;
+ if ( tLineNum == 0 ) tLineNum = lineNum;
+
+ Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber((Integer)t.getAttribute("tokenNumber"));
+ printPreprocs(preprocs);
+
+ if ( (lineNum != tLineNum) || !currentSource.equals(tSource) ) {
+ // we know we'll be newlines or a line directive or it probably
+ // is just the case that this token is on the next line
+ // either way start a new line and indent it
+ currentOutput.println();
+ lineNum++;
+ printTabs();
+ }
+
+ if ( ( lineNum == tLineNum ) && ( currentSource.equals(tSource) ) ){
+ // do nothing special, we're at the right place
+ }
+ else if ( currentSource.equals(tSource) ) {
+ int diff = tLineNum - lineNum;
+ if (diff > 0 && diff < lineDirectiveThreshold) {
+ // print out the blank lines to bring us up to right line number
+ for ( ; lineNum < tLineNum ; lineNum++ ) {
+ currentOutput.println();
+ }
+ }
+ else { // print line directive to get us to right line number
+ // preserve flags 3 and 4 if present in current file
+ if ( ! sourceFiles.empty() ) {
+ LineObject l = (LineObject) sourceFiles.peek();
+ StringBuffer tFlags = new StringBuffer("");
+ if (l.getSystemHeader()) {
+ tFlags.append(" 3");
+ }
+ if (l.getTreatAsC()) {
+ tFlags.append(" 4");
+ }
+ currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + tFlags.toString());
+ lineNum = tLineNum;
+ }
+ }
+
+ printTabs();
+ }
+ else { // different source
+ Enumeration sources = sourceFiles.elements();
+ // see if we're returning to a file we entered earlier
+ boolean returningToEarlierFile = false;
+ while (sources.hasMoreElements()) {
+ LineObject l = (LineObject) sources.nextElement();
+ if (l.getSource().equals(tSource)) {
+ returningToEarlierFile = true;
+ break;
+ }
+ }
+ if (returningToEarlierFile) {
+ // pop off the files we're exiting, but never pop the trueSourceFile
+ LineObject l = (LineObject) sourceFiles.peek();
+ while ( ( l != trueSourceFile ) &&(! l.getSource().equals(tSource) ) ) {
+ sourceFiles.pop();
+ l = (LineObject) sourceFiles.peek();
+ }
+
+ // put in the return flag, plus others as needed
+ StringBuffer tFlags = new StringBuffer(" 2");
+ if (l.getSystemHeader()) {
+ tFlags.append(" 3");
+ }
+ if (l.getTreatAsC()) {
+ tFlags.append(" 4");
+ }
+
+ currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + tFlags);
+ lineNum = tLineNum;
+ currentSource = tSource;
+ printTabs();
+ }
+ else { // entering a file that wasn't in the original source
+ // pretend we're entering it from top of stack
+ currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + " 1");
+ lineNum = tLineNum;
+ currentSource = tSource;
+ printTabs();
+ }
+ }
+ currentOutput.print( t.getText() + " " );
+}
+
+/** It is not ok to print newlines from the String passed in as
+it will screw up the line number handling **/
+void print( String s ) {
+ currentOutput.print( s + " " );
+}
+
+void printTabs() {
+ for ( int i = 0; i< tabs; i++ ) {
+ currentOutput.print( "\t" );
+ }
+}
+
+void commaSep( TNode t ) {
+ print( t );
+ if ( t.getNextSibling() != null ) {
+ print( "," );
+ }
+}
+
+ int traceDepth = 0;
+ public void reportError(RecognitionException ex) {
+ if ( ex != null) {
+ System.err.println("ANTLR Tree Parsing RecognitionException Error: " + ex.getClass().getName() + " " + ex );
+ ex.printStackTrace(System.err);
+ }
+ }
+ public void reportError(NoViableAltException ex) {
+ System.err.println("ANTLR Tree Parsing NoViableAltException Error: " + ex.toString());
+ TNode.printTree( ex.node );
+ ex.printStackTrace(System.err);
+ }
+ public void reportError(MismatchedTokenException ex) {
+ if ( ex != null) {
+ TNode.printTree( ex.node );
+ System.err.println("ANTLR Tree Parsing MismatchedTokenException Error: " + ex );
+ ex.printStackTrace(System.err);
+ }
+ }
+ public void reportError(String s) {
+ System.err.println("ANTLR Error from String: " + s);
+ }
+ public void reportWarning(String s) {
+ System.err.println("ANTLR Warning from String: " + s);
+ }
+ protected void match(AST t, int ttype) throws MismatchedTokenException {
+ //System.out.println("match("+ttype+"); cursor is "+t);
+ super.match(t, ttype);
+ }
+ public void match(AST t, BitSet b) throws MismatchedTokenException {
+ //System.out.println("match("+b+"); cursor is "+t);
+ super.match(t, b);
+ }
+ protected void matchNot(AST t, int ttype) throws MismatchedTokenException {
+ //System.out.println("matchNot("+ttype+"); cursor is "+t);
+ super.matchNot(t, ttype);
+ }
+ public void traceIn(String rname, AST t) {
+ traceDepth += 1;
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ super.traceIn(rname, t);
+ }
+ public void traceOut(String rname, AST t) {
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ super.traceOut(rname, t);
+ traceDepth -= 1;
+ }
+
+
+
+}
+
+
+translationUnit options {
+ defaultErrorHandler=false;
+}
+ :
+ { initializePrinting(); }
+ ( externalList )?
+ { finalizePrinting(); }
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+
+externalList
+ : ( externalDef )+
+ ;
+
+
+externalDef
+ : declaration
+ | functionDef
+ | asm_expr
+ | typelessDeclaration
+ | s:SEMI { print( s ); }
+ ;
+
+typelessDeclaration
+ : #(NTypeMissing initDeclList s: SEMI) { print( s ); }
+ ;
+
+
+
+asm_expr
+ : #( a:"asm" { print( a ); }
+ ( v:"volatile" { print( v ); }
+ )?
+ lc:LCURLY { print( lc ); tabs++; }
+ expr
+ rc:RCURLY { tabs--; print( rc ); }
+ s:SEMI { print( s ); }
+ )
+ ;
+
+
+declaration
+ : #( NDeclaration
+ declSpecifiers
+ (
+ initDeclList
+ )?
+ ( s:SEMI { print( s ); } )+
+ )
+ ;
+
+
+declSpecifiers
+ : ( storageClassSpecifier
+ | typeQualifier
+ | typeSpecifier
+ )+
+ ;
+
+storageClassSpecifier
+ : a:"auto" { print( a ); }
+ | b:"register" { print( b ); }
+ | c:"typedef" { print( c ); }
+ | functionStorageClassSpecifier
+ ;
+
+
+functionStorageClassSpecifier
+ : a:"extern" { print( a ); }
+ | b:"static" { print( b ); }
+ | c:"inline" { print( c ); }
+ ;
+
+
+typeQualifier
+ : a:"const" { print( a ); }
+ | b:"volatile" { print( b ); }
+ ;
+
+
+typeSpecifier
+ : a:"void" { print( a ); }
+ | b:"char" { print( b ); }
+ | c:"short" { print( c ); }
+ | d:"int" { print( d ); }
+ | e:"long" { print( e ); }
+ | f:"float" { print( f ); }
+ | g:"double" { print( g ); }
+ | h:"signed" { print( h ); }
+ | i:"unsigned" { print( i ); }
+ | structSpecifier ( attributeDecl )*
+ | unionSpecifier ( attributeDecl )*
+ | enumSpecifier
+ | typedefName
+ | #(n:"typeof" lp:LPAREN { print( n ); print( lp ); }
+ ( (typeName )=> typeName
+ | expr
+ )
+ rp:RPAREN { print( rp ); }
+ )
+ | p:"__complex" { print( p ); }
+ ;
+
+
+typedefName
+ : #(NTypedefName i:ID { print( i ); } )
+ ;
+
+
+structSpecifier
+ : #( a:"struct" { print( a ); }
+ structOrUnionBody
+ )
+ ;
+
+unionSpecifier
+ : #( a:"union" { print( a ); }
+ structOrUnionBody
+ )
+ ;
+
+structOrUnionBody
+ : ( (ID LCURLY) => i1:ID lc1:LCURLY { print( i1 ); print ( "{" ); tabs++; }
+ ( structDeclarationList )?
+ rc1:RCURLY { tabs--; print( rc1 ); }
+ | lc2:LCURLY { print( lc2 ); tabs++; }
+ ( structDeclarationList )?
+ rc2:RCURLY { tabs--; print( rc2 ); }
+ | i2:ID { print( i2 ); }
+ )
+ ;
+
+structDeclarationList
+ : ( structDeclaration { print( ";" ); }
+ )+
+ ;
+
+
+structDeclaration
+ : specifierQualifierList structDeclaratorList
+ ;
+
+
+specifierQualifierList
+ : (
+ typeSpecifier
+ | typeQualifier
+ )+
+ ;
+
+
+structDeclaratorList
+ : structDeclarator
+ ( { print(","); } structDeclarator )*
+ ;
+
+
+structDeclarator
+ :
+ #( NStructDeclarator
+ ( declarator )?
+ ( c:COLON { print( c ); } expr )?
+ ( attributeDecl )*
+ )
+ ;
+
+
+enumSpecifier
+ : #( a:"enum" { print( a ); }
+ ( i:ID { print( i ); } )?
+ ( lc:LCURLY { print( lc ); tabs++; }
+ enumList
+ rc:RCURLY { tabs--; print( rc ); }
+ )?
+ )
+ ;
+
+
+enumList
+ :
+ enumerator ( {print(",");} enumerator)*
+ ;
+
+
+enumerator
+ : i:ID { print( i ); }
+ ( b:ASSIGN { print( b ); }
+ expr
+ )?
+ ;
+
+
+attributeDecl:
+ #( a:"__attribute" { print( a ); }
+ (b:. { print( b ); } )*
+ )
+ | #( n:NAsmAttribute { print( n ); }
+ lp:LPAREN { print( lp ); }
+ expr { print( ")" ); }
+ rp:RPAREN { print( rp ); }
+ )
+ ;
+
+initDeclList
+ : initDecl
+ ( { print( "," ); } initDecl )*
+ ;
+
+
+initDecl
+ { String declName = ""; }
+ : #(NInitDecl
+ declarator
+ ( attributeDecl )*
+ ( a:ASSIGN { print( a ); }
+ initializer
+ | b:COLON { print( b ); }
+ expr
+ )?
+ )
+ ;
+
+
+pointerGroup
+ : #( NPointerGroup
+ ( a:STAR { print( a ); }
+ ( typeQualifier )*
+ )+
+ )
+ ;
+
+
+
+idList
+ : i:ID { print( i ); }
+ ( c:COMMA { print( c ); }
+ id:ID { print( id ); }
+ )*
+ ;
+
+
+
+initializer
+ : #( NInitializer (initializerElementLabel)? expr )
+ | lcurlyInitializer
+ ;
+
+initializerElementLabel
+ : #( NInitializerElementLabel
+ (
+ ( l:LBRACKET { print( l ); }
+ expr
+ r:RBRACKET { print( r ); }
+ (a1:ASSIGN { print( a1 ); } )?
+ )
+ | i1:ID c:COLON { print( i1 ); print( c ); }
+ | d:DOT i2:ID a2:ASSIGN { print( d ); print( i2 ); print( a2 ); }
+ )
+ )
+ ;
+
+lcurlyInitializer
+ : #(n:NLcurlyInitializer { print( n ); tabs++; }
+ initializerList
+ rc:RCURLY { tabs--; print( rc ); }
+ )
+ ;
+
+initializerList
+ : ( i:initializer { commaSep( i ); }
+ )*
+ ;
+
+
+declarator
+ : #( NDeclarator
+ ( pointerGroup )?
+
+ ( id:ID { print( id ); }
+ | lp:LPAREN { print( lp ); } declarator rp:RPAREN { print( rp ); }
+ )
+
+ ( #( n:NParameterTypeList { print( n ); }
+ (
+ parameterTypeList
+ | (idList)?
+ )
+ r:RPAREN { print( r ); }
+ )
+ | lb:LBRACKET { print( lb );} ( expr )? rb:RBRACKET { print( rb ); }
+ )*
+ )
+ ;
+
+
+
+parameterTypeList
+ : ( parameterDeclaration
+ ( c:COMMA { print( c ); }
+ | s:SEMI { print( s ); }
+ )?
+ )+
+ ( v:VARARGS { print( v ); } )?
+ ;
+
+
+
+parameterDeclaration
+ : #( NParameterDeclaration
+ declSpecifiers
+ (declarator | nonemptyAbstractDeclarator)?
+ )
+ ;
+
+
+functionDef
+ : #( NFunctionDef
+ ( functionDeclSpecifiers)?
+ declarator
+ (declaration
+ | v:VARARGS { print( v ); }
+ )*
+ compoundStatement
+ )
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+functionDeclSpecifiers
+ :
+ ( functionStorageClassSpecifier
+ | typeQualifier
+ | typeSpecifier
+ )+
+ ;
+
+declarationList
+ :
+ ( //ANTLR doesn't know that declarationList properly eats all the declarations
+ //so it warns about the ambiguity
+ options {
+ warnWhenFollowAmbig = false;
+ } :
+ localLabelDecl
+ | declaration
+ )+
+ ;
+
+localLabelDecl
+ : #(a:"__label__" { print( a ); }
+ ( i:ID { commaSep( i ); }
+ )+
+ { print( ";" ); }
+ )
+ ;
+
+
+
+compoundStatement
+ : #( cs:NCompoundStatement { print( cs ); tabs++; }
+ ( declarationList
+ | functionDef
+ )*
+ ( statementList )?
+ rc:RCURLY { tabs--; print( rc ); }
+ )
+
+ ;
+
+statementList
+ : ( statement )+
+ ;
+
+statement
+ : statementBody
+ ;
+
+statementBody
+ : s:SEMI { print( s ); }
+
+ | compoundStatement // Group of statements
+
+ | #(NStatementExpr
+ expr { print( ";" ); }
+ ) // Expressions
+
+// Iteration statements:
+
+ | #( w:"while" { print( w ); print( "(" ); }
+ expr { print( ")" ); }
+ statement )
+
+ | #( d:"do" { print( d ); }
+ statement
+ { print( " while ( " ); }
+ expr
+ { print( " );" ); }
+ )
+
+ | #( f:"for" { print( f ); print( "(" ); }
+ expr { print( ";" ); }
+ expr { print( ";" ); }
+ expr { print( ")" ); }
+ statement
+ )
+
+
+// Jump statements:
+
+ | #( g:"goto" { print( g );}
+ expr { print( ";" ); }
+ )
+ | c:"continue" { print( c ); print( ";" );}
+ | b:"break" { print( b ); print( ";" );}
+ | #( r:"return" { print( r ); }
+ ( expr )?
+ { print( ";" ); }
+ )
+
+
+// Labeled statements:
+ | #( NLabel
+ ni:ID { print( ni ); print( ":" ); }
+ ( statement )?
+ )
+
+ | #(
+ ca:"case" { print( ca ); }
+ expr { print( ":" ); }
+ (statement)?
+ )
+
+ | #(
+ de:"default" { print( de ); print( ":" ); }
+ (statement)?
+ )
+
+
+
+// Selection statements:
+
+ | #( i:"if" { print( i ); print( "(" ); }
+ expr { print( ")" ); }
+ statement
+ ( e:"else" { print( e ); }
+ statement
+ )?
+ )
+ | #( sw:"switch" { print( sw ); print( "(" ); }
+ expr { print( ")" ); }
+ statement
+ )
+
+
+
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+
+
+
+
+
+expr
+ :
+ binaryExpr
+ | conditionalExpr
+ | castExpr
+ | unaryExpr
+ | postfixExpr
+ | primaryExpr
+ | emptyExpr
+ | compoundStatementExpr
+ | initializer
+ | rangeExpr
+ | gnuAsmExpr
+ ;
+
+emptyExpr
+ : NEmptyExpression
+ ;
+
+compoundStatementExpr
+ : #(l:LPAREN { print( l ); }
+ compoundStatement
+ r:RPAREN { print( r ); }
+ )
+ ;
+
+rangeExpr
+ : #(NRangeExpr expr v:VARARGS{ print( v ); } expr)
+ ;
+
+gnuAsmExpr
+ : #(n:NGnuAsmExpr { print( n ); }
+ (v:"volatile" { print( v ); } )?
+ lp:LPAREN { print( lp ); }
+ stringConst
+ ( options { warnWhenFollowAmbig = false; }:
+ c1:COLON { print( c1 );}
+ (strOptExprPair
+ ( c2:COMMA { print( c2 ); } strOptExprPair)*
+ )?
+ ( options { warnWhenFollowAmbig = false; }:
+ c3:COLON { print( c3 ); }
+ (strOptExprPair
+ ( c4:COMMA { print( c4 ); } strOptExprPair)*
+ )?
+ )?
+ )?
+ ( c5:COLON { print( c5 ); }
+ stringConst
+ ( c6:COMMA { print( c6 ); }
+ stringConst
+ )*
+ )?
+ rp:RPAREN { print( rp ); }
+ )
+ ;
+
+strOptExprPair
+ : stringConst
+ (
+ l:LPAREN { print( l ); }
+ expr
+ r:RPAREN { print( r ); }
+ )?
+ ;
+
+binaryOperator
+ : ASSIGN
+ | DIV_ASSIGN
+ | PLUS_ASSIGN
+ | MINUS_ASSIGN
+ | STAR_ASSIGN
+ | MOD_ASSIGN
+ | RSHIFT_ASSIGN
+ | LSHIFT_ASSIGN
+ | BAND_ASSIGN
+ | BOR_ASSIGN
+ | BXOR_ASSIGN
+ | LOR
+ | LAND
+ | BOR
+ | BXOR
+ | BAND
+ | EQUAL
+ | NOT_EQUAL
+ | LT
+ | LTE
+ | GT
+ | GTE
+ | LSHIFT
+ | RSHIFT
+ | PLUS
+ | MINUS
+ | STAR
+ | DIV
+ | MOD
+ | NCommaExpr
+ ;
+
+binaryExpr
+ : b:binaryOperator
+ // no rules allowed as roots, so here I manually get
+ // the first and second children of the binary operator
+ // and then print them out in the right order
+ { TNode e1, e2;
+ e1 = (TNode) b.getFirstChild();
+ e2 = (TNode) e1.getNextSibling();
+ expr( e1 );
+ print( b );
+ expr( e2 );
+ }
+
+ ;
+
+
+conditionalExpr
+ : #( q:QUESTION
+ expr { print( q ); }
+ ( expr )?
+ c:COLON { print( c ); }
+ expr
+ )
+ ;
+
+
+castExpr
+ : #(
+ c:NCast { print( c ); }
+ typeName
+ rp:RPAREN { print( rp ); }
+ expr
+ )
+ ;
+
+
+typeName
+ : specifierQualifierList (nonemptyAbstractDeclarator)?
+ ;
+
+nonemptyAbstractDeclarator
+ : #( NNonemptyAbstractDeclarator
+ ( pointerGroup
+ ( (lp1:LPAREN { print( lp1 ); }
+ ( nonemptyAbstractDeclarator
+ | parameterTypeList
+ )?
+ rp1:RPAREN { print( rp1 ); }
+ )
+ | (
+ lb1:LBRACKET { print( lb1 ); }
+ (expr)?
+ rb1:RBRACKET { print( rb1 ); }
+ )
+ )*
+
+ | ( (lp2:LPAREN { print( lp2 ); }
+ ( nonemptyAbstractDeclarator
+ | parameterTypeList
+ )?
+ rp2:RPAREN { print( rp2 ); }
+ )
+ | (
+ lb2:LBRACKET { print( lb2 ); }
+ (expr)?
+ rb2:RBRACKET { print( rb2 ); }
+ )
+ )+
+ )
+ )
+ ;
+
+
+
+unaryExpr
+ : #( i:INC { print( i ); } expr )
+ | #( d:DEC { print( d ); } expr )
+ | #( NUnaryExpr u:unaryOperator { print( u ); } expr)
+ | #( s:"sizeof" { print( s ); }
+ ( ( LPAREN typeName )=>
+ lps:LPAREN { print( lps ); }
+ typeName
+ rps:RPAREN { print( rps ); }
+ | expr
+ )
+ )
+ | #( a:"__alignof" { print( a ); }
+ ( ( LPAREN typeName )=>
+ lpa:LPAREN { print( lpa ); }
+ typeName
+ rpa:RPAREN { print( rpa ); }
+ | expr
+ )
+ )
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+ unaryOperator
+ : BAND
+ | STAR
+ | PLUS
+ | MINUS
+ | BNOT
+ | LNOT
+ | LAND
+ | "__real"
+ | "__imag"
+ ;
+
+
+postfixExpr
+ : #( NPostfixExpr
+ primaryExpr
+ ( a:PTR b:ID { print( a ); print( b ); }
+ | c:DOT d:ID { print( c ); print( d ); }
+ | #( n:NFunctionCallArgs { print( n ); }
+ (argExprList)?
+ rp:RPAREN { print( rp ); }
+ )
+ | lb:LBRACKET { print( lb ); }
+ expr
+ rb:RBRACKET { print( rb ); }
+ | f:INC { print( f ); }
+ | g:DEC { print( g ); }
+ )+
+ )
+ ;
+
+
+
+primaryExpr
+ : i:ID { print( i ); }
+ | n:Number { print( n ); }
+ | charConst
+ | stringConst
+
+// JTC:
+// ID should catch the enumerator
+// leaving it in gives ambiguous err
+// | enumerator
+
+ | #( eg:NExpressionGroup { print( eg ); }
+ expr { print( ")" ); }
+ )
+ ;
+
+
+
+argExprList
+ : expr ( {print( "," );} expr )*
+ ;
+
+
+
+protected
+charConst
+ : c:CharLiteral { print( c ); }
+ ;
+
+
+protected
+stringConst
+ : #( NStringSeq
+ (
+ s:StringLiteral { print( s ); }
+ )+
+ )
+ ;
+
+
+protected
+intConst
+ : IntOctalConst
+ | LongOctalConst
+ | UnsignedOctalConst
+ | IntIntConst
+ | LongIntConst
+ | UnsignedIntConst
+ | IntHexConst
+ | LongHexConst
+ | UnsignedHexConst
+ ;
+
+
+protected
+floatConst
+ : FloatDoubleConst
+ | DoubleDoubleConst
+ | LongDoubleConst
+ ;
+
+
+
+
+
+
+
+
+
+
diff --git a/src/net/java/games/gluegen/cgram/GnuCParser.g b/src/net/java/games/gluegen/cgram/GnuCParser.g
new file mode 100644
index 000000000..feed4518e
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/GnuCParser.g
@@ -0,0 +1,864 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Copyright (c) Non, Inc. 1998 -- All Rights Reserved
+
+PROJECT: C Compiler
+MODULE: GnuCParser
+FILE: GnuCParser.g
+
+AUTHOR: Monty Zukowski ([email protected]) April 28, 1998
+
+DESCRIPTION:
+ This is a grammar for the GNU C compiler. It is a
+ grammar subclass of StdCParser, overriding only those
+ rules which are different from Standard C.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+
+header {
+ package net.java.games.gluegen.cgram;
+
+ import java.io.*;
+
+ import antlr.CommonAST;
+ import antlr.DumpASTVisitor;
+}
+
+
+class GnuCParser extends StdCParser;
+
+options
+ {
+ k = 2;
+ exportVocab = GNUC;
+ buildAST = true;
+ ASTLabelType = "TNode";
+
+ // Copied following options from java grammar.
+ codeGenMakeSwitchThreshold = 2;
+ codeGenBitsetTestThreshold = 3;
+ }
+
+
+{
+ // Suppport C++-style single-line comments?
+ public static boolean CPPComments = true;
+
+ // access to symbol table
+ public CSymbolTable symbolTable = new CSymbolTable();
+
+ // source for names to unnamed scopes
+ protected int unnamedScopeCounter = 0;
+
+ public boolean isTypedefName(String name) {
+ boolean returnValue = false;
+ TNode node = symbolTable.lookupNameInCurrentScope(name);
+ for (; node != null; node = (TNode) node.getNextSibling() ) {
+ if(node.getType() == LITERAL_typedef) {
+ returnValue = true;
+ break;
+ }
+ }
+ return returnValue;
+ }
+
+
+ public String getAScopeName() {
+ return "" + (unnamedScopeCounter++);
+ }
+
+ public void pushScope(String scopeName) {
+ symbolTable.pushScope(scopeName);
+ }
+
+ public void popScope() {
+ symbolTable.popScope();
+ }
+
+ int traceDepth = 0;
+ public void reportError(RecognitionException ex) {
+ try {
+ System.err.println("ANTLR Parsing Error: "+ex + " token name:" + tokenNames[LA(1)]);
+ ex.printStackTrace(System.err);
+ }
+ catch (TokenStreamException e) {
+ System.err.println("ANTLR Parsing Error: "+ex);
+ ex.printStackTrace(System.err);
+ }
+ }
+ public void reportError(String s) {
+ System.err.println("ANTLR Parsing Error from String: " + s);
+ }
+ public void reportWarning(String s) {
+ System.err.println("ANTLR Parsing Warning from String: " + s);
+ }
+ public void match(int t) throws MismatchedTokenException {
+ boolean debugging = false;
+
+ if ( debugging ) {
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ try {
+ System.out.println("Match("+tokenNames[t]+") with LA(1)="+
+ tokenNames[LA(1)] + ((inputState.guessing>0)?" [inputState.guessing "+ inputState.guessing + "]":""));
+ }
+ catch (TokenStreamException e) {
+ System.out.println("Match("+tokenNames[t]+") " + ((inputState.guessing>0)?" [inputState.guessing "+ inputState.guessing + "]":""));
+
+ }
+
+ }
+ try {
+ if ( LA(1)!=t ) {
+ if ( debugging ){
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ System.out.println("token mismatch: "+tokenNames[LA(1)]
+ + "!="+tokenNames[t]);
+ }
+ throw new MismatchedTokenException(tokenNames, LT(1), t, false, getFilename());
+
+ } else {
+ // mark token as consumed -- fetch next token deferred until LA/LT
+ consume();
+ }
+ }
+ catch (TokenStreamException e) {
+ }
+
+ }
+ public void traceIn(String rname) {
+ traceDepth += 1;
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ try {
+ System.out.println("> "+rname+"; LA(1)==("+ tokenNames[LT(1).getType()]
+ + ") " + LT(1).getText() + " [inputState.guessing "+ inputState.guessing + "]");
+ }
+ catch (TokenStreamException e) {
+ }
+ }
+ public void traceOut(String rname) {
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ try {
+ System.out.println("< "+rname+"; LA(1)==("+ tokenNames[LT(1).getType()]
+ + ") "+LT(1).getText() + " [inputState.guessing "+ inputState.guessing + "]");
+ }
+ catch (TokenStreamException e) {
+ }
+ traceDepth -= 1;
+ }
+
+}
+
+
+translationUnit
+ : ( externalList )? /* Empty source files are allowed. */
+ ;
+asm_expr
+ : "asm"^
+ ("volatile")? LCURLY expr RCURLY ( SEMI )+
+ ;
+
+idList
+ : ID ( options{warnWhenFollowAmbig=false;}: COMMA ID )*
+ ;
+
+externalDef
+ : ( "typedef" | declaration )=> declaration
+ | ( functionPrefix )=> functionDef
+ | typelessDeclaration
+ | asm_expr
+ | SEMI
+ ;
+
+/* these two are here because GCC allows "cat = 13;" as a valid program! */
+functionPrefix
+ { String declName; }
+ : ( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers
+ | //epsilon
+ )
+ declName = d:declarator[true]
+ ( declaration )* (VARARGS)? ( SEMI )*
+ LCURLY
+ ;
+
+typelessDeclaration
+ { AST typeMissing = #[NTypeMissing]; }
+ : initDeclList[typeMissing] SEMI { ## = #( #[NTypeMissing], ##); }
+ ;
+
+initializer
+ : ( ( ( (initializerElementLabel)=> initializerElementLabel )?
+ ( assignExpr | lcurlyInitializer ) { ## = #( #[NInitializer], ## ); }
+ )
+ | lcurlyInitializer
+ )
+ ;
+
+// GCC allows more specific initializers
+initializerElementLabel
+ : ( ( LBRACKET ((constExpr VARARGS)=> rangeExpr | constExpr) RBRACKET (ASSIGN)? )
+ | ID COLON
+ | DOT ID ASSIGN
+ )
+ { ## = #( #[NInitializerElementLabel], ##) ; }
+ ;
+
+// GCC allows empty initializer lists
+lcurlyInitializer
+ :
+ LCURLY^ (initializerList ( COMMA! )? )? RCURLY
+ { ##.setType( NLcurlyInitializer ); }
+ ;
+
+initializerList
+ : initializer ( options{warnWhenFollowAmbig=false;}:COMMA! initializer )*
+ ;
+
+
+declarator[boolean isFunctionDefinition] returns [String declName]
+ { declName = ""; }
+ :
+ ( pointerGroup )?
+
+ ( id:ID { declName = id.getText(); }
+ | LPAREN declName = declarator[false] RPAREN
+ )
+
+ ( declaratorParamaterList[isFunctionDefinition, declName]
+ | LBRACKET ( expr )? RBRACKET
+ )*
+ { ## = #( #[NDeclarator], ## ); }
+ ;
+
+declaratorParamaterList[boolean isFunctionDefinition, String declName]
+ :
+ LPAREN^
+ {
+ if (isFunctionDefinition) {
+ pushScope(declName);
+ }
+ else {
+ pushScope("!"+declName);
+ }
+ }
+ (
+ (declSpecifiers)=> parameterTypeList
+ | (idList)?
+ )
+ {
+ popScope();
+ }
+ ( COMMA! )?
+ RPAREN
+ { ##.setType(NParameterTypeList); }
+ ;
+
+parameterTypeList
+ : parameterDeclaration
+ ( options {
+ warnWhenFollowAmbig = false;
+ } :
+ ( COMMA | SEMI )
+ parameterDeclaration
+ )*
+ ( ( COMMA | SEMI )
+ VARARGS
+ )?
+ ;
+
+
+declarationList
+ : ( options { // this loop properly aborts when
+ // it finds a non-typedefName ID MBZ
+ warnWhenFollowAmbig = false;
+ } :
+
+ localLabelDeclaration
+ | ( declarationPredictor )=> declaration
+ )+
+ ;
+localLabelDeclaration
+ : ( //GNU note: any __label__ declarations must come before regular declarations.
+ "__label__"^ ID (options{warnWhenFollowAmbig=false;}: COMMA! ID)* ( COMMA! )? ( SEMI! )+
+ )
+ ;
+
+
+declaration
+ { AST ds1 = null; }
+ : ds:declSpecifiers { ds1 = astFactory.dupList(#ds); }
+ (
+ initDeclList[ds1]
+ )?
+ ( SEMI )+
+ { ## = #( #[NDeclaration], ##); }
+
+ ;
+
+functionStorageClassSpecifier
+ : "extern"
+ | "static"
+ | "inline"
+ ;
+
+typeSpecifier [int specCount] returns [int retSpecCount]
+ { retSpecCount = specCount + 1; }
+ :
+ ( "void"
+ | "char"
+ | "short"
+ | "int"
+ | "__int64"
+ | "long"
+ | "float"
+ | "double"
+ | "signed"
+ | "unsigned"
+ | structOrUnionSpecifier ( options{warnWhenFollowAmbig=false;}: attributeDecl )*
+ | enumSpecifier
+ | { specCount==0 }? typedefName
+ | "typeof"^ LPAREN
+ ( ( typeName )=> typeName
+ | expr
+ )
+ RPAREN
+ | "__complex"
+ )
+ ;
+
+
+structOrUnionSpecifier
+ { String scopeName; }
+ : sou:structOrUnion!
+ ( ( ID LCURLY )=> i:ID l:LCURLY
+ {
+ scopeName = #sou.getText() + " " + #i.getText();
+ #l.setText(scopeName);
+ pushScope(scopeName);
+ }
+ ( structDeclarationList )?
+ { popScope();}
+ RCURLY
+ | l1:LCURLY
+ {
+ scopeName = getAScopeName();
+ #l1.setText(scopeName);
+ pushScope(scopeName);
+ }
+ ( structDeclarationList )?
+ { popScope(); }
+ RCURLY
+ | ID
+ )
+ {
+ ## = #( #sou, ## );
+ }
+ ;
+
+
+structDeclaration
+ : specifierQualifierList structDeclaratorList ( COMMA! )? ( SEMI! )+
+ ;
+
+structDeclaratorList
+ : structDeclarator ( options{warnWhenFollowAmbig=false;}: COMMA! structDeclarator )*
+ ;
+
+structDeclarator
+ : ( declarator[false] )?
+ ( COLON constExpr )?
+ ( attributeDecl )*
+ { ## = #( #[NStructDeclarator], ##); }
+ ;
+
+
+
+enumSpecifier
+ : "enum"^
+ ( ( ID LCURLY )=> i:ID LCURLY enumList[i.getText()] RCURLY
+ | LCURLY enumList["anonymous"] RCURLY
+ | ID
+ )
+ ;
+enumList[String enumName]
+ : enumerator[enumName] ( options{warnWhenFollowAmbig=false;}: COMMA! enumerator[enumName] )* ( COMMA! )?
+ ;
+
+
+initDeclList[AST declarationSpecifiers]
+ : initDecl[declarationSpecifiers]
+ ( options{warnWhenFollowAmbig=false;}: COMMA! initDecl[declarationSpecifiers] )*
+ ( COMMA! )?
+ ;
+
+initDecl[AST declarationSpecifiers]
+ { String declName = ""; }
+ : declName = d:declarator[false]
+ { AST ds1, d1;
+ ds1 = astFactory.dupList(declarationSpecifiers);
+ d1 = astFactory.dupList(#d);
+ symbolTable.add(declName, #(null, ds1, d1) );
+ }
+ ( attributeDecl )*
+ ( ASSIGN initializer
+ | COLON expr
+ )?
+ { ## = #( #[NInitDecl], ## ); }
+ ;
+
+attributeDecl
+ : "__attribute"^ LPAREN LPAREN attributeList RPAREN RPAREN
+ | "asm"^ LPAREN stringConst RPAREN { ##.setType( NAsmAttribute ); }
+ ;
+
+attributeList
+ : attribute ( options{warnWhenFollowAmbig=false;}: COMMA attribute)* ( COMMA )?
+ ;
+
+attribute
+ : ( ~(LPAREN | RPAREN | COMMA)
+ | LPAREN attributeList RPAREN
+ )*
+ ;
+compoundStatement[String scopeName]
+ : LCURLY^
+
+ {
+ pushScope(scopeName);
+ }
+ ( //this ambiguity is ok, declarationList and nestedFunctionDef end properly
+ options {
+ warnWhenFollowAmbig = false;
+ } :
+ ( "typedef" | "__label__" | declaration )=> declarationList
+ | (nestedFunctionDef)=> nestedFunctionDef
+ )*
+ ( statementList )?
+ { popScope(); }
+ RCURLY
+ { ##.setType( NCompoundStatement ); ##.setAttribute( "scopeName", scopeName ); }
+ ;
+
+nestedFunctionDef
+ { String declName; }
+ : ( "auto" )? //only for nested functions
+ ( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers
+ )?
+ declName = d:declarator[false]
+ {
+ AST d2, ds2;
+ d2 = astFactory.dupList(#d);
+ ds2 = astFactory.dupList(#ds);
+ symbolTable.add(declName, #(null, ds2, d2));
+ pushScope(declName);
+ }
+ ( declaration )*
+ { popScope(); }
+ compoundStatement[declName]
+ { ## = #( #[NFunctionDef], ## );}
+ ;
+
+statement
+ : SEMI // Empty statements
+
+ | compoundStatement[getAScopeName()] // Group of statements
+
+ | expr SEMI! { ## = #( #[NStatementExpr], ## );} // Expressions
+
+// Iteration statements:
+
+ | "while"^ LPAREN! expr RPAREN! statement
+ | "do"^ statement "while"! LPAREN! expr RPAREN! SEMI!
+ |! "for"
+ LPAREN ( e1:expr )? SEMI ( e2:expr )? SEMI ( e3:expr )? RPAREN
+ s:statement
+ {
+ if ( #e1 == null) { #e1 = (TNode) #[ NEmptyExpression ]; }
+ if ( #e2 == null) { #e2 = (TNode) #[ NEmptyExpression ]; }
+ if ( #e3 == null) { #e3 = (TNode) #[ NEmptyExpression ]; }
+ ## = #( #[LITERAL_for, "for"], #e1, #e2, #e3, #s );
+ }
+
+
+// Jump statements:
+
+ | "goto"^ expr SEMI!
+ | "continue" SEMI!
+ | "break" SEMI!
+ | "return"^ ( expr )? SEMI!
+
+
+ | ID COLON! (options {warnWhenFollowAmbig=false;}: statement)? { ## = #( #[NLabel], ## ); }
+// GNU allows range expressions in case statements
+ | "case"^ ((constExpr VARARGS)=> rangeExpr | constExpr) COLON! ( options{warnWhenFollowAmbig=false;}:statement )?
+ | "default"^ COLON! ( options{warnWhenFollowAmbig=false;}: statement )?
+
+// Selection statements:
+
+ | "if"^
+ LPAREN! expr RPAREN! statement
+ ( //standard if-else ambiguity
+ options {
+ warnWhenFollowAmbig = false;
+ } :
+ "else" statement )?
+ | "switch"^ LPAREN! expr RPAREN! statement
+ ;
+
+
+
+conditionalExpr
+ : logicalOrExpr
+ ( QUESTION^ (expr)? COLON conditionalExpr )?
+ ;
+
+rangeExpr //used in initializers only
+ : constExpr VARARGS constExpr
+ { ## = #(#[NRangeExpr], ##); }
+ ;
+
+castExpr
+ : ( LPAREN typeName RPAREN )=>
+ LPAREN^ typeName RPAREN ( castExpr | lcurlyInitializer )
+ { ##.setType(NCast); }
+
+ | unaryExpr
+ ;
+nonemptyAbstractDeclarator
+ : (
+ pointerGroup
+ ( (LPAREN
+ ( nonemptyAbstractDeclarator
+ | parameterTypeList
+ )?
+ ( COMMA! )?
+ RPAREN)
+ | (LBRACKET (expr)? RBRACKET)
+ )*
+
+ | ( (LPAREN
+ ( nonemptyAbstractDeclarator
+ | parameterTypeList
+ )?
+ ( COMMA! )?
+ RPAREN)
+ | (LBRACKET (expr)? RBRACKET)
+ )+
+ )
+ { ## = #( #[NNonemptyAbstractDeclarator], ## ); }
+
+ ;
+
+
+
+unaryExpr
+ : postfixExpr
+ | INC^ castExpr
+ | DEC^ castExpr
+ | u:unaryOperator castExpr { ## = #( #[NUnaryExpr], ## ); }
+
+ | "sizeof"^
+ ( ( LPAREN typeName )=> LPAREN typeName RPAREN
+ | unaryExpr
+ )
+ | "__alignof"^
+ ( ( LPAREN typeName )=> LPAREN typeName RPAREN
+ | unaryExpr
+ )
+ | gnuAsmExpr
+ ;
+
+unaryOperator
+ : BAND
+ | STAR
+ | PLUS
+ | MINUS
+ | BNOT //also stands for complex conjugation
+ | LNOT
+ | LAND //for label dereference (&&label)
+ | "__real"
+ | "__imag"
+ ;
+
+gnuAsmExpr
+ : "asm"^ ("volatile")?
+ LPAREN stringConst
+ ( options { warnWhenFollowAmbig = false; }:
+ COLON (strOptExprPair ( COMMA strOptExprPair)* )?
+ ( options { warnWhenFollowAmbig = false; }:
+ COLON (strOptExprPair ( COMMA strOptExprPair)* )?
+ )?
+ )?
+ ( COLON stringConst ( COMMA stringConst)* )?
+ RPAREN
+ { ##.setType(NGnuAsmExpr); }
+ ;
+
+//GCC requires the PARENs
+strOptExprPair
+ : stringConst ( LPAREN expr RPAREN )?
+ ;
+
+
+primaryExpr
+ : ID
+ | Number
+ | charConst
+ | stringConst
+// JTC:
+// ID should catch the enumerator
+// leaving it in gives ambiguous err
+// | enumerator
+ | (LPAREN LCURLY) => LPAREN^ compoundStatement[getAScopeName()] RPAREN
+ | LPAREN^ expr RPAREN { ##.setType(NExpressionGroup); }
+ ;
+
+
+{
+ import java.io.*;
+ import java.util.*;
+ import antlr.*;
+}
+
+class GnuCLexer extends StdCLexer;
+options
+ {
+ k = 3;
+ importVocab = GNUC;
+ testLiterals = false;
+ }
+tokens {
+ LITERAL___extension__ = "__extension__";
+}
+
+{
+ public void initialize(String src)
+ {
+ setOriginalSource(src);
+ initialize();
+ }
+
+ public void initialize()
+ {
+ literals.put(new ANTLRHashString("__alignof__", this), new Integer(LITERAL___alignof));
+ literals.put(new ANTLRHashString("__asm", this), new Integer(LITERAL_asm));
+ literals.put(new ANTLRHashString("__asm__", this), new Integer(LITERAL_asm));
+ literals.put(new ANTLRHashString("__attribute__", this), new Integer(LITERAL___attribute));
+ literals.put(new ANTLRHashString("__complex__", this), new Integer(LITERAL___complex));
+ literals.put(new ANTLRHashString("__const", this), new Integer(LITERAL_const));
+ literals.put(new ANTLRHashString("__const__", this), new Integer(LITERAL_const));
+ literals.put(new ANTLRHashString("__imag__", this), new Integer(LITERAL___imag));
+ literals.put(new ANTLRHashString("__inline", this), new Integer(LITERAL_inline));
+ literals.put(new ANTLRHashString("__inline__", this), new Integer(LITERAL_inline));
+ literals.put(new ANTLRHashString("__real__", this), new Integer(LITERAL___real));
+ literals.put(new ANTLRHashString("__signed", this), new Integer(LITERAL_signed));
+ literals.put(new ANTLRHashString("__signed__", this), new Integer(LITERAL_signed));
+ literals.put(new ANTLRHashString("__typeof", this), new Integer(LITERAL_typeof));
+ literals.put(new ANTLRHashString("__typeof__", this), new Integer(LITERAL_typeof));
+ literals.put(new ANTLRHashString("__volatile", this), new Integer(LITERAL_volatile));
+ literals.put(new ANTLRHashString("__volatile__", this), new Integer(LITERAL_volatile));
+ }
+
+
+ LineObject lineObject = new LineObject();
+ String originalSource = "";
+ PreprocessorInfoChannel preprocessorInfoChannel = new PreprocessorInfoChannel();
+ int tokenNumber = 0;
+ boolean countingTokens = true;
+ int deferredLineCount = 0;
+ List defines = new ArrayList();
+
+ public void setCountingTokens(boolean ct)
+ {
+ countingTokens = ct;
+ if ( countingTokens ) {
+ tokenNumber = 0;
+ }
+ else {
+ tokenNumber = 1;
+ }
+ }
+
+ public void setOriginalSource(String src)
+ {
+ originalSource = src;
+ lineObject.setSource(src);
+ }
+ public void setSource(String src)
+ {
+ lineObject.setSource(src);
+ }
+
+ public PreprocessorInfoChannel getPreprocessorInfoChannel()
+ {
+ return preprocessorInfoChannel;
+ }
+
+ public void setPreprocessingDirective(String pre)
+ {
+ preprocessorInfoChannel.addLineForTokenNumber( pre, new Integer(tokenNumber) );
+ }
+
+ public void addDefine(String name, String value)
+ {
+ defines.add(new Define(name, value));
+ }
+
+ /** Returns a list of Define objects corresponding to the
+ preprocessor definitions seen during parsing. */
+ public List getDefines() {
+ return defines;
+ }
+
+ protected Token makeToken(int t)
+ {
+ if ( t != Token.SKIP && countingTokens) {
+ tokenNumber++;
+ }
+ CToken tok = (CToken) super.makeToken(t);
+ tok.setLine(lineObject.line);
+ tok.setSource(lineObject.source);
+ tok.setTokenNumber(tokenNumber);
+
+ lineObject.line += deferredLineCount;
+ deferredLineCount = 0;
+ return tok;
+ }
+
+ public void deferredNewline() {
+ deferredLineCount++;
+ }
+
+ public void newline() {
+ lineObject.newline();
+ }
+
+
+
+
+
+
+}
+Whitespace
+ : ( ( ' ' | '\t' | '\014')
+ | "\r\n" { newline(); }
+ | ( '\n' | '\r' ) { newline(); }
+ ) { _ttype = Token.SKIP; }
+ ;
+
+
+protected
+Escape
+ : '\\'
+ ( options{warnWhenFollowAmbig=false;}:
+ ~('0'..'7' | 'x')
+ | ('0'..'3') ( options{warnWhenFollowAmbig=false;}: Digit )*
+ | ('4'..'7') ( options{warnWhenFollowAmbig=false;}: Digit )*
+ | 'x' ( options{warnWhenFollowAmbig=false;}: Digit | 'a'..'f' | 'A'..'F' )+
+ )
+ ;
+
+protected IntSuffix
+ : 'L'
+ | 'l'
+ | 'U'
+ | 'u'
+ | 'I'
+ | 'i'
+ | 'J'
+ | 'j'
+ ;
+protected NumberSuffix
+ :
+ IntSuffix
+ | 'F'
+ | 'f'
+ ;
+
+Number
+ : ( ( Digit )+ ( '.' | 'e' | 'E' ) )=> ( Digit )+
+ ( '.' ( Digit )* ( Exponent )?
+ | Exponent
+ )
+ ( NumberSuffix
+ )*
+
+ | ( "..." )=> "..." { _ttype = VARARGS; }
+
+ | '.' { _ttype = DOT; }
+ ( ( Digit )+ ( Exponent )?
+ { _ttype = Number; }
+ ( NumberSuffix
+ )*
+ )?
+
+ | '0' ( '0'..'7' )*
+ ( NumberSuffix
+ )*
+
+ | '1'..'9' ( Digit )*
+ ( NumberSuffix
+ )*
+
+ | '0' ( 'x' | 'X' ) ( 'a'..'f' | 'A'..'F' | Digit )+
+ ( IntSuffix
+ )*
+ ;
+
+IDMEAT
+ :
+ i:ID {
+
+ if ( i.getType() == LITERAL___extension__ ) {
+ $setType(Token.SKIP);
+ }
+ else {
+ $setType(i.getType());
+ }
+
+ }
+ ;
+
+protected ID
+ options
+ {
+ testLiterals = true;
+ }
+ : ( 'a'..'z' | 'A'..'Z' | '_' | '$')
+ ( 'a'..'z' | 'A'..'Z' | '_' | '$' | '0'..'9' )*
+ ;
+
+WideCharLiteral
+ :
+ 'L' CharLiteral
+ { $setType(CharLiteral); }
+ ;
+
+
+
+WideStringLiteral
+ :
+ 'L' StringLiteral
+ { $setType(StringLiteral); }
+ ;
+
+StringLiteral
+ :
+ '"'
+ ( ('\\' ~('\n'))=> Escape
+ | ( '\r' { newline(); }
+ | '\n' {
+ newline();
+ }
+ | '\\' '\n' {
+ newline();
+ }
+ )
+ | ~( '"' | '\r' | '\n' | '\\' )
+ )*
+ '"'
+ ;
+
+
+
+
diff --git a/src/net/java/games/gluegen/cgram/GnuCTreeParser.g b/src/net/java/games/gluegen/cgram/GnuCTreeParser.g
new file mode 100644
index 000000000..8400e3e59
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/GnuCTreeParser.g
@@ -0,0 +1,852 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Copyright (c) Non, Inc. 1998 -- All Rights Reserved
+
+PROJECT: C Compiler
+MODULE: GnuCTreeParser
+FILE: GnuCTreeParser.g
+
+AUTHOR: Monty Zukowski ([email protected]) April 28, 1998
+
+DESCRIPTION:
+
+ This tree grammar is for a Gnu C AST. No actions in it,
+ subclass to do something useful.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+
+header {
+ package net.java.games.gluegen.cgram;
+
+ import java.io.*;
+
+ import antlr.CommonAST;
+ import antlr.DumpASTVisitor;
+}
+
+
+class GnuCTreeParser extends TreeParser;
+
+options
+ {
+ importVocab = GNUC;
+ buildAST = false;
+ ASTLabelType = "TNode";
+
+ // Copied following options from java grammar.
+ codeGenMakeSwitchThreshold = 2;
+ codeGenBitsetTestThreshold = 3;
+ }
+
+
+{
+ int traceDepth = 0;
+ public void reportError(RecognitionException ex) {
+ if ( ex != null) {
+ System.err.println("ANTLR Tree Parsing RecognitionException Error: " + ex.getClass().getName() + " " + ex );
+ ex.printStackTrace(System.err);
+ }
+ }
+ public void reportError(NoViableAltException ex) {
+ System.err.println("ANTLR Tree Parsing NoViableAltException Error: " + ex.toString());
+ TNode.printTree( ex.node );
+ ex.printStackTrace(System.err);
+ }
+ public void reportError(MismatchedTokenException ex) {
+ if ( ex != null) {
+ TNode.printTree( ex.node );
+ System.err.println("ANTLR Tree Parsing MismatchedTokenException Error: " + ex );
+ ex.printStackTrace(System.err);
+ }
+ }
+ public void reportError(String s) {
+ System.err.println("ANTLR Error from String: " + s);
+ }
+ public void reportWarning(String s) {
+ System.err.println("ANTLR Warning from String: " + s);
+ }
+ protected void match(AST t, int ttype) throws MismatchedTokenException {
+ //System.out.println("match("+ttype+"); cursor is "+t);
+ super.match(t, ttype);
+ }
+ public void match(AST t, BitSet b) throws MismatchedTokenException {
+ //System.out.println("match("+b+"); cursor is "+t);
+ super.match(t, b);
+ }
+ protected void matchNot(AST t, int ttype) throws MismatchedTokenException {
+ //System.out.println("matchNot("+ttype+"); cursor is "+t);
+ super.matchNot(t, ttype);
+ }
+ public void traceIn(String rname, AST t) {
+ traceDepth += 1;
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ super.traceIn(rname, t);
+ }
+ public void traceOut(String rname, AST t) {
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ super.traceOut(rname, t);
+ traceDepth -= 1;
+ }
+
+
+}
+
+translationUnit options {
+ defaultErrorHandler=false;
+}
+ : ( externalList )?
+ ;
+
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+
+externalList
+ : ( externalDef )+
+ ;
+
+
+externalDef
+ : declaration
+ | functionDef
+ | asm_expr
+ | SEMI
+ | typelessDeclaration
+ ;
+
+typelessDeclaration
+ : #(NTypeMissing initDeclList SEMI)
+ ;
+
+
+
+asm_expr
+ : #( "asm" ( "volatile" )? LCURLY expr RCURLY ( SEMI )+ )
+ ;
+
+
+declaration
+ : #( NDeclaration
+ declSpecifiers
+ (
+ initDeclList
+ )?
+ ( SEMI )+
+ )
+ ;
+
+
+declSpecifiers
+ : ( storageClassSpecifier
+ | typeQualifier
+ | typeSpecifier
+ )+
+ ;
+
+storageClassSpecifier
+ : "auto"
+ | "register"
+ | "typedef"
+ | functionStorageClassSpecifier
+ ;
+
+
+functionStorageClassSpecifier
+ : "extern"
+ | "static"
+ | "inline"
+ ;
+
+
+typeQualifier
+ : "const"
+ | "volatile"
+ ;
+
+
+typeSpecifier
+ : "void"
+ | "char"
+ | "short"
+ | "int"
+ | "long"
+ | "float"
+ | "double"
+ | "signed"
+ | "unsigned"
+ | structSpecifier ( attributeDecl )*
+ | unionSpecifier ( attributeDecl )*
+ | enumSpecifier
+ | typedefName
+ | #("typeof" LPAREN
+ ( (typeName )=> typeName
+ | expr
+ )
+ RPAREN
+ )
+ | "__complex"
+ ;
+
+
+typedefName
+ : #(NTypedefName ID)
+ ;
+
+
+structSpecifier
+ : #( "struct" structOrUnionBody )
+ ;
+
+unionSpecifier
+ : #( "union" structOrUnionBody )
+ ;
+
+structOrUnionBody
+ : ( (ID LCURLY) => ID LCURLY
+ ( structDeclarationList )?
+ RCURLY
+ | LCURLY
+ ( structDeclarationList )?
+ RCURLY
+ | ID
+ )
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+
+structDeclarationList
+ : ( structDeclaration )+
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+
+
+structDeclaration
+ : specifierQualifierList structDeclaratorList
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+
+
+specifierQualifierList
+ : (
+ typeSpecifier
+ | typeQualifier
+ )+
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+
+
+structDeclaratorList
+ : ( structDeclarator )+
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+
+
+structDeclarator
+ :
+ #( NStructDeclarator
+ ( declarator )?
+ ( COLON expr )?
+ ( attributeDecl )*
+ )
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+
+
+
+enumSpecifier
+ : #( "enum"
+ ( ID )?
+ ( LCURLY enumList RCURLY )?
+ )
+ ;
+
+
+enumList
+ : ( enumerator )+
+ ;
+
+
+enumerator
+ : ID ( ASSIGN expr )?
+ ;
+
+
+
+attributeDecl:
+ #( "__attribute" (.)* )
+ | #( NAsmAttribute LPAREN expr RPAREN )
+ ;
+
+initDeclList
+ : ( initDecl )+
+ ;
+
+
+initDecl
+ { String declName = ""; }
+ : #( NInitDecl
+ declarator
+ ( attributeDecl )*
+ ( ASSIGN initializer
+ | COLON expr
+ )?
+ )
+ ;
+
+
+pointerGroup
+ : #( NPointerGroup ( STAR ( typeQualifier )* )+ )
+ ;
+
+
+
+idList
+ : ID ( COMMA ID )*
+ ;
+
+
+
+initializer
+ : #( NInitializer (initializerElementLabel)? expr )
+ | lcurlyInitializer
+ ;
+
+initializerElementLabel
+ : #( NInitializerElementLabel
+ (
+ ( LBRACKET expr RBRACKET (ASSIGN)? )
+ | ID COLON
+ | DOT ID ASSIGN
+ )
+ )
+ ;
+
+lcurlyInitializer
+ : #( NLcurlyInitializer
+ initializerList
+ RCURLY
+ )
+ ;
+
+initializerList
+ : ( initializer )*
+ ;
+
+
+declarator
+ : #( NDeclarator
+ ( pointerGroup )?
+
+ ( id:ID
+ | LPAREN declarator RPAREN
+ )
+
+ ( #( NParameterTypeList
+ (
+ parameterTypeList
+ | (idList)?
+ )
+ RPAREN
+ )
+ | LBRACKET ( expr )? RBRACKET
+ )*
+ )
+ ;
+
+
+
+parameterTypeList
+ : ( parameterDeclaration ( COMMA | SEMI )? )+ ( VARARGS )?
+ ;
+
+
+
+parameterDeclaration
+ : #( NParameterDeclaration
+ declSpecifiers
+ (declarator | nonemptyAbstractDeclarator)?
+ )
+ ;
+
+
+functionDef
+ : #( NFunctionDef
+ ( functionDeclSpecifiers)?
+ declarator
+ (declaration | VARARGS)*
+ compoundStatement
+ )
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+functionDeclSpecifiers
+ :
+ ( functionStorageClassSpecifier
+ | typeQualifier
+ | typeSpecifier
+ )+
+ ;
+
+declarationList
+ :
+ ( //ANTLR doesn't know that declarationList properly eats all the declarations
+ //so it warns about the ambiguity
+ options {
+ warnWhenFollowAmbig = false;
+ } :
+ localLabelDecl
+ | declaration
+ )+
+ ;
+
+localLabelDecl
+ : #("__label__" (ID)+ )
+ ;
+
+
+
+compoundStatement
+ : #( NCompoundStatement
+ ( declarationList
+ | functionDef
+ )*
+ ( statementList )?
+ RCURLY
+ )
+ ;
+
+statementList
+ : ( statement )+
+ ;
+
+statement
+ : statementBody
+ ;
+
+statementBody
+ : SEMI // Empty statements
+
+ | compoundStatement // Group of statements
+
+ | #(NStatementExpr expr) // Expressions
+
+// Iteration statements:
+
+ | #( "while" expr statement )
+ | #( "do" statement expr )
+ | #( "for"
+ expr expr expr
+ statement
+ )
+
+
+// Jump statements:
+
+ | #( "goto" expr )
+ | "continue"
+ | "break"
+ | #( "return" ( expr )? )
+
+
+// Labeled statements:
+ | #( NLabel ID (statement)? )
+ | #( "case" expr (statement)? )
+ | #( "default" (statement)? )
+
+
+
+// Selection statements:
+
+ | #( "if"
+ expr statement
+ ( "else" statement )?
+ )
+ | #( "switch" expr statement )
+
+
+
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+
+
+
+
+
+expr
+ : assignExpr
+ | conditionalExpr
+ | logicalOrExpr
+ | logicalAndExpr
+ | inclusiveOrExpr
+ | exclusiveOrExpr
+ | bitAndExpr
+ | equalityExpr
+ | relationalExpr
+ | shiftExpr
+ | additiveExpr
+ | multExpr
+ | castExpr
+ | unaryExpr
+ | postfixExpr
+ | primaryExpr
+ | commaExpr
+ | emptyExpr
+ | compoundStatementExpr
+ | initializer
+ | rangeExpr
+ | gnuAsmExpr
+ ;
+
+commaExpr
+ : #(NCommaExpr expr expr)
+ ;
+
+emptyExpr
+ : NEmptyExpression
+ ;
+
+compoundStatementExpr
+ : #(LPAREN compoundStatement RPAREN)
+ ;
+
+rangeExpr
+ : #(NRangeExpr expr VARARGS expr)
+ ;
+
+gnuAsmExpr
+ : #(NGnuAsmExpr
+ ("volatile")?
+ LPAREN stringConst
+ ( options { warnWhenFollowAmbig = false; }:
+ COLON (strOptExprPair ( COMMA strOptExprPair)* )?
+ ( options { warnWhenFollowAmbig = false; }:
+ COLON (strOptExprPair ( COMMA strOptExprPair)* )?
+ )?
+ )?
+ ( COLON stringConst ( COMMA stringConst)* )?
+ RPAREN
+ )
+ ;
+
+strOptExprPair
+ : stringConst ( LPAREN expr RPAREN )?
+ ;
+
+assignExpr
+ : #( ASSIGN expr expr)
+ | #( DIV_ASSIGN expr expr)
+ | #( PLUS_ASSIGN expr expr)
+ | #( MINUS_ASSIGN expr expr)
+ | #( STAR_ASSIGN expr expr)
+ | #( MOD_ASSIGN expr expr)
+ | #( RSHIFT_ASSIGN expr expr)
+ | #( LSHIFT_ASSIGN expr expr)
+ | #( BAND_ASSIGN expr expr)
+ | #( BOR_ASSIGN expr expr)
+ | #( BXOR_ASSIGN expr expr)
+ ;
+
+
+conditionalExpr
+ : #( QUESTION expr (expr)? COLON expr )
+ ;
+
+
+logicalOrExpr
+ : #( LOR expr expr)
+ ;
+
+
+logicalAndExpr
+ : #( LAND expr expr )
+ ;
+
+
+inclusiveOrExpr
+ : #( BOR expr expr )
+ ;
+
+
+exclusiveOrExpr
+ : #( BXOR expr expr )
+ ;
+
+
+bitAndExpr
+ : #( BAND expr expr )
+ ;
+
+
+
+equalityExpr
+ : #( EQUAL expr expr)
+ | #( NOT_EQUAL expr expr)
+ ;
+
+
+relationalExpr
+ : #( LT expr expr)
+ | #( LTE expr expr)
+ | #( GT expr expr)
+ | #( GTE expr expr)
+ ;
+
+
+
+shiftExpr
+ : #( LSHIFT expr expr)
+ | #( RSHIFT expr expr)
+ ;
+
+
+additiveExpr
+ : #( PLUS expr expr)
+ | #( MINUS expr expr)
+ ;
+
+
+multExpr
+ : #( STAR expr expr)
+ | #( DIV expr expr)
+ | #( MOD expr expr)
+ ;
+
+
+
+castExpr
+ : #( NCast typeName RPAREN expr)
+ ;
+
+
+typeName
+ : specifierQualifierList (nonemptyAbstractDeclarator)?
+ ;
+
+nonemptyAbstractDeclarator
+ : #( NNonemptyAbstractDeclarator
+ ( pointerGroup
+ ( (LPAREN
+ ( nonemptyAbstractDeclarator
+ | parameterTypeList
+ )?
+ RPAREN)
+ | (LBRACKET (expr)? RBRACKET)
+ )*
+
+ | ( (LPAREN
+ ( nonemptyAbstractDeclarator
+ | parameterTypeList
+ )?
+ RPAREN)
+ | (LBRACKET (expr)? RBRACKET)
+ )+
+ )
+ )
+ ;
+
+
+
+unaryExpr
+ : #( INC expr )
+ | #( DEC expr )
+ | #( NUnaryExpr unaryOperator expr)
+ | #( "sizeof"
+ ( ( LPAREN typeName )=> LPAREN typeName RPAREN
+ | expr
+ )
+ )
+ | #( "__alignof"
+ ( ( LPAREN typeName )=> LPAREN typeName RPAREN
+ | expr
+ )
+ )
+ ;
+/*
+exception
+catch [RecognitionException ex]
+ {
+ reportError(ex);
+ System.out.println("PROBLEM TREE:\n"
+ + _t.toStringList());
+ if (_t!=null) {_t = _t.getNextSibling();}
+ }
+*/
+
+ unaryOperator
+ : BAND
+ | STAR
+ | PLUS
+ | MINUS
+ | BNOT
+ | LNOT
+ | LAND
+ | "__real"
+ | "__imag"
+ ;
+
+
+postfixExpr
+ : #( NPostfixExpr
+ primaryExpr
+ ( PTR ID
+ | DOT ID
+ | #( NFunctionCallArgs (argExprList)? RPAREN )
+ | LBRACKET expr RBRACKET
+ | INC
+ | DEC
+ )+
+ )
+ ;
+
+
+
+primaryExpr
+ : ID
+ | Number
+ | charConst
+ | stringConst
+
+// JTC:
+// ID should catch the enumerator
+// leaving it in gives ambiguous err
+// | enumerator
+
+ | #( NExpressionGroup expr )
+ ;
+
+
+
+argExprList
+ : ( expr )+
+ ;
+
+
+
+protected
+charConst
+ : CharLiteral
+ ;
+
+
+protected
+stringConst
+ : #(NStringSeq (StringLiteral)+)
+ ;
+
+
+protected
+intConst
+ : IntOctalConst
+ | LongOctalConst
+ | UnsignedOctalConst
+ | IntIntConst
+ | LongIntConst
+ | UnsignedIntConst
+ | IntHexConst
+ | LongHexConst
+ | UnsignedHexConst
+ ;
+
+
+protected
+floatConst
+ : FloatDoubleConst
+ | DoubleDoubleConst
+ | LongDoubleConst
+ ;
+
+
+
+
+
+
+
+
+
diff --git a/src/net/java/games/gluegen/cgram/HeaderParser.g b/src/net/java/games/gluegen/cgram/HeaderParser.g
new file mode 100644
index 000000000..1263c30b8
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/HeaderParser.g
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+header {
+ package net.java.games.gluegen.cgram;
+
+ import java.io.*;
+ import java.util.*;
+
+ import antlr.CommonAST;
+ import net.java.games.gluegen.cgram.types.*;
+}
+
+class HeaderParser extends GnuCTreeParser;
+options {
+ k = 1;
+}
+
+{
+ /** Name assigned to a anonymous EnumType (e.g., "enum { ... }"). */
+ public static final String ANONYMOUS_ENUM_NAME = "<anonymous>";
+
+ /** Set the machine description for this HeaderParser. Must be
+ done before parsing. */
+ public void setMachineDescription(MachineDescription machDesc) {
+ this.machDesc = machDesc;
+ }
+
+ /** Returns the MachineDescription this HeaderParser uses. */
+ public MachineDescription machineDescription() {
+ return machDesc;
+ }
+
+ /** Set the dictionary mapping typedef names to types for this
+ HeaderParser. Must be done before parsing. */
+ public void setTypedefDictionary(TypeDictionary dict) {
+ this.typedefDictionary = dict;
+ }
+
+ /** Returns the typedef dictionary this HeaderParser uses. */
+ public TypeDictionary getTypedefDictionary() {
+ return typedefDictionary;
+ }
+
+ /** Set the dictionary mapping struct names (i.e., the "foo" in
+ "struct foo { ... };") to types for this HeaderParser. Must be done
+ before parsing. */
+ public void setStructDictionary(TypeDictionary dict) {
+ this.structDictionary = dict;
+ }
+
+ /** Returns the struct name dictionary this HeaderParser uses. */
+ public TypeDictionary getStructDictionary() {
+ return structDictionary;
+ }
+
+ /** Get the canonicalization map, which is a regular HashMap
+ mapping Type to Type and which is used for looking up the unique
+ instances of e.g. pointer-to-structure types that have been typedefed
+ and therefore have names. */
+ public Map getCanonMap() {
+ return canonMap;
+ }
+
+ /** Pre-define the list of EnumTypes for this HeaderParser. Must be
+ 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!");
+ }
+
+ /** Returns the EnumTypes this HeaderParser processed. */
+ public List/*<EnumType>*/ getEnums() {
+ return new ArrayList(enumHash.values());
+ }
+
+ /** Clears the list of functions this HeaderParser has parsed.
+ Useful when reusing the same HeaderParser for more than one
+ header file. */
+ public void clearParsedFunctions() {
+ functions.clear();
+ }
+
+ /** Returns the list of FunctionSymbols this HeaderParser has parsed. */
+ public List getParsedFunctions() {
+ return functions;
+ }
+
+ private CompoundType lookupInStructDictionary(String typeName,
+ CompoundTypeKind kind,
+ int cvAttrs) {
+ CompoundType t = (CompoundType) structDictionary.get(typeName);
+ if (t == null) {
+ t = new CompoundType(null, -1, kind, cvAttrs);
+ t.setStructName(typeName);
+ structDictionary.put(typeName, t);
+ }
+ return t;
+ }
+
+ private Type lookupInTypedefDictionary(String typeName) {
+ Type t = typedefDictionary.get(typeName);
+ if (t == null) {
+ throw new RuntimeException("Undefined reference to typedef name " + typeName);
+ }
+ return t;
+ }
+
+ static class ParameterDeclaration {
+ private String id;
+ private Type type;
+
+ ParameterDeclaration(String id, Type type) {
+ this.id = id;
+ this.type = type;
+ }
+ String id() { return id; }
+ Type type() { return type; }
+ }
+
+ // A box for a Type. Allows type to be passed down to be modified by recursive rules.
+ static class TypeBox {
+ private Type origType;
+ private Type type;
+ private boolean isTypedef;
+
+ TypeBox(Type type) {
+ this(type, false);
+ }
+
+ TypeBox(Type type, boolean isTypedef) {
+ this.origType = type;
+ this.isTypedef = isTypedef;
+ }
+
+ Type type() {
+ if (type == null) {
+ return origType;
+ }
+ return type;
+ }
+ void setType(Type type) {
+ this.type = type;
+ }
+ void reset() {
+ type = null;
+ }
+
+ 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() + " " +
+ type.getName() + "\"; signature=\"" + type + "\"; class " +
+ 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+">";
+ }
+ }
+
+ private MachineDescription machDesc;
+ private boolean doDeclaration; // Used to only process function typedefs
+ private String declId;
+ private List parameters;
+ private TypeDictionary typedefDictionary;
+ private TypeDictionary structDictionary;
+ private List/*<FunctionSymbol>*/ functions = new ArrayList();
+ // hash from name of an enumerated value to the EnumType to which it belongs
+ private HashMap/*<String,EnumType>*/ enumHash = new HashMap();
+
+ // Storage class specifiers
+ private static final int AUTO = 1 << 0;
+ private static final int REGISTER = 1 << 1;
+ private static final int TYPEDEF = 1 << 2;
+ // Function storage class specifiers
+ private static final int EXTERN = 1 << 3;
+ private static final int STATIC = 1 << 4;
+ private static final int INLINE = 1 << 5;
+ // Type qualifiers
+ private static final int CONST = 1 << 6;
+ private static final int VOLATILE = 1 << 7;
+ private static final int SIGNED = 1 << 8;
+ private static final int UNSIGNED = 1 << 9;
+
+ private void initDeclaration() {
+ doDeclaration = false;
+ declId = null;
+ }
+
+ private void doDeclaration() {
+ doDeclaration = true;
+ }
+
+ private void processDeclaration(Type returnType) {
+ if (doDeclaration) {
+ FunctionSymbol sym = new FunctionSymbol(declId, new FunctionType(null, -1, returnType, 0));
+ 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);
+ }
+ }
+
+ private int attrs2CVAttrs(int attrs) {
+ int cvAttrs = 0;
+ if ((attrs & CONST) != 0) {
+ cvAttrs |= CVAttributes.CONST;
+ }
+ if ((attrs & VOLATILE) != 0) {
+ cvAttrs |= CVAttributes.VOLATILE;
+ }
+ return cvAttrs;
+ }
+
+ /** Helper routine which handles creating a pointer or array type
+ for [] expressions */
+ private void handleArrayExpr(TypeBox tb, AST t) {
+ if (t != null) {
+ try {
+ // FIXME: this doesn't take into account struct alignment, which may be necessary
+ // See also FIXMEs in ArrayType.java
+ int len = parseIntConstExpr(t);
+ tb.setType(canonicalize(new ArrayType(tb.type(), len * tb.type().getSize(), len, 0)));
+ return;
+ } catch (RecognitionException e) {
+ // Fall through
+ }
+ }
+ tb.setType(canonicalize(new PointerType(machDesc.pointerSizeInBytes(),
+ tb.type(),
+ 0)));
+ }
+
+ private int parseIntConstExpr(AST t) throws RecognitionException {
+ return intConstExpr(t);
+ }
+
+ /** Utility function: creates a new EnumType with the given name, or
+ 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 = new EnumType(enumTypeName, machDesc.longSizeInBytes());
+ }
+
+ return enumType;
+ }
+
+ // Map used to canonicalize types. For example, we may typedef
+ // struct foo { ... } *pfoo; subsequent references to struct foo* should
+ // point to the same PointerType object that had its name set to "pfoo".
+ private Map canonMap = new HashMap();
+ private Type canonicalize(Type t) {
+ Type res = (Type) canonMap.get(t);
+ if (res != null) {
+ return res;
+ }
+ canonMap.put(t, t);
+ return t;
+ }
+}
+
+declarator[TypeBox tb] returns [String s] {
+ initDeclaration();
+ s = null;
+ List params = null;
+ String funcPointerName = null;
+ TypeBox dummyTypeBox = null;
+}
+ : #( NDeclarator
+ ( pointerGroup[tb] )?
+
+ ( id:ID { s = id.getText(); }
+ | LPAREN funcPointerName = declarator[dummyTypeBox] RPAREN
+ )
+
+ ( #( NParameterTypeList
+ (
+ params = parameterTypeList
+ | (idList)?
+ )
+ RPAREN
+ ) {
+ if (id != null) {
+ declId = id.getText();
+ parameters = params; // FIXME: Ken, why are we setting this class member here?
+ doDeclaration();
+ } else if ( funcPointerName != null ) {
+ /* TypeBox becomes function pointer in this case */
+ FunctionType ft = new FunctionType(null, -1, 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
+ // 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(); ) {
+ ParameterDeclaration pd = (ParameterDeclaration) iter.next();
+ ft.addArgument(pd.type(), pd.id());
+ }
+ }
+ tb.setType(canonicalize(new PointerType(machDesc.pointerSizeInBytes(),
+ ft,
+ 0)));
+ s = funcPointerName;
+ }
+ }
+ | LBRACKET ( e:expr )? RBRACKET { handleArrayExpr(tb, e); }
+ )*
+ )
+ ;
+
+typelessDeclaration {
+ TypeBox tb = null;
+}
+ : #(NTypeMissing initDeclList[tb] SEMI)
+ ;
+
+declaration {
+ TypeBox tb = null;
+}
+ : #( NDeclaration
+ tb = declSpecifiers
+ (
+ initDeclList[tb]
+ )?
+ ( SEMI )+
+ ) { processDeclaration(tb.type()); }
+ ;
+
+parameterTypeList returns [List l] { l = new ArrayList(); ParameterDeclaration decl = null; }
+ : ( decl = parameterDeclaration { if (decl != null) l.add(decl); } ( COMMA | SEMI )? )+ ( VARARGS )?
+ ;
+
+parameterDeclaration returns [ParameterDeclaration pd] {
+ Type t = null;
+ String decl = null;
+ pd = null;
+ TypeBox tb = null;
+}
+ : #( NParameterDeclaration
+ tb = declSpecifiers
+ (decl = declarator[tb] | nonemptyAbstractDeclarator[tb])?
+ ) { pd = new ParameterDeclaration(decl, tb.type()); }
+ ;
+
+functionDef {
+ TypeBox tb = null;
+}
+ : #( NFunctionDef
+ ( functionDeclSpecifiers)?
+ declarator[tb]
+ (declaration | VARARGS)*
+ compoundStatement
+ )
+ ;
+
+declSpecifiers returns [TypeBox tb] {
+ tb = null;
+ Type t = null;
+ int x = 0;
+ int y = 0;
+}
+ : ( y = storageClassSpecifier { x |= y; }
+ | y = typeQualifier { x |= y; }
+ | t = typeSpecifier[x]
+ )+
+{
+ if (t == null &&
+ (x & (SIGNED | UNSIGNED)) != 0) {
+ t = new IntType("int", machDesc.intSizeInBytes(), ((x & UNSIGNED) != 0), attrs2CVAttrs(x));
+ }
+ tb = new TypeBox(t, ((x & TYPEDEF) != 0));
+}
+ ;
+
+storageClassSpecifier returns [int x] { x = 0; }
+ : "auto" { x |= AUTO; }
+ | "register" { x |= REGISTER; }
+ | "typedef" { x |= TYPEDEF; }
+ | x = functionStorageClassSpecifier
+ ;
+
+
+functionStorageClassSpecifier returns [int x] { x = 0; }
+ : "extern" { x |= EXTERN; }
+ | "static" { x |= STATIC; }
+ | "inline" { x |= INLINE; }
+ ;
+
+
+typeQualifier returns [int x] { x = 0; }
+ : "const" { x |= CONST; }
+ | "volatile" { x |= VOLATILE; }
+ | "signed" { x |= SIGNED; }
+ | "unsigned" { x |= UNSIGNED; }
+ ;
+
+typeSpecifier[int attributes] returns [Type t] {
+ t = null;
+ int cvAttrs = attrs2CVAttrs(attributes);
+ boolean unsigned = ((attributes & UNSIGNED) != 0);
+}
+ : "void" { t = new VoidType(cvAttrs); }
+ | "char" { t = new IntType("char" , machDesc.charSizeInBytes(), unsigned, cvAttrs); }
+ | "short" { t = new IntType("short", machDesc.shortSizeInBytes(), unsigned, cvAttrs); }
+ | "int" { t = new IntType("int" , machDesc.intSizeInBytes(), unsigned, cvAttrs); }
+ | "long" { t = new IntType("long" , machDesc.longSizeInBytes(), unsigned, cvAttrs); }
+ | "__int64" { t = new IntType("__int64", machDesc.int64SizeInBytes(), unsigned, cvAttrs); }
+ | "float" { t = new FloatType("float", machDesc.floatSizeInBytes(), cvAttrs); }
+ | "double" { t = new DoubleType("double", machDesc.doubleSizeInBytes(), cvAttrs); }
+ | t = structSpecifier[cvAttrs] ( attributeDecl )*
+ | t = unionSpecifier [cvAttrs] ( attributeDecl )*
+ | t = enumSpecifier [cvAttrs]
+ | t = typedefName [cvAttrs]
+ | #("typeof" LPAREN
+ ( (typeName )=> typeName
+ | expr
+ )
+ RPAREN
+ )
+ | "__complex"
+ ;
+
+typedefName[int cvAttrs] returns [Type t] { t = null; }
+ : #(NTypedefName id : ID)
+ {
+ t = canonicalize(lookupInTypedefDictionary(id.getText()).getCVVariant(cvAttrs));
+ }
+ ;
+
+structSpecifier[int cvAttrs] returns [Type t] { t = null; }
+ : #( "struct" t = structOrUnionBody[CompoundTypeKind.STRUCT, cvAttrs] )
+ ;
+
+unionSpecifier[int cvAttrs] returns [Type t] { t = null; }
+ : #( "union" t = structOrUnionBody[CompoundTypeKind.UNION, cvAttrs] )
+ ;
+
+structOrUnionBody[CompoundTypeKind kind, int cvAttrs] returns [CompoundType t] {
+ t = null;
+}
+ : ( (ID LCURLY) => id:ID LCURLY {
+ t = (CompoundType) canonicalize(lookupInStructDictionary(id.getText(), kind, cvAttrs));
+ } ( structDeclarationList[t] )?
+ RCURLY { t.setBodyParsed(); }
+ | LCURLY { t = new CompoundType(null, -1, kind, cvAttrs); }
+ ( structDeclarationList[t] )?
+ RCURLY { t.setBodyParsed(); }
+ | id2:ID { t = (CompoundType) canonicalize(lookupInStructDictionary(id2.getText(), kind, cvAttrs)); }
+ )
+ ;
+
+structDeclarationList[CompoundType t]
+ : ( structDeclaration[t] )+
+ ;
+
+structDeclaration[CompoundType containingType] {
+ Type t = null;
+ boolean addedAny = false;
+}
+ : t = specifierQualifierList addedAny = structDeclaratorList[containingType, t] {
+ if (!addedAny) {
+ if (t != null) {
+ CompoundType ct = t.asCompound();
+ if (ct.isUnion()) {
+ // Anonymous union
+ containingType.addField(new Field(null, t, -1));
+ }
+ }
+ }
+ }
+ ;
+
+specifierQualifierList returns [Type t] {
+ t = null; int x = 0; int y = 0;
+}
+ : (
+ t = typeSpecifier[x]
+ | y = typeQualifier { x |= y; }
+ )+ {
+ if (t == null &&
+ (x & (SIGNED | UNSIGNED)) != 0) {
+ t = new IntType("int", machDesc.intSizeInBytes(), ((x & UNSIGNED) != 0), attrs2CVAttrs(x));
+ }
+}
+ ;
+
+structDeclaratorList[CompoundType containingType, Type t] returns [boolean addedAny] {
+ addedAny = false;
+ boolean y = false;
+}
+ : ( y = structDeclarator[containingType, t] { addedAny = y; })+
+ ;
+
+structDeclarator[CompoundType containingType, Type t] returns [boolean addedAny] {
+ addedAny = false;
+ String s = null;
+ TypeBox tb = new TypeBox(t);
+}
+ :
+ #( NStructDeclarator
+ ( s = declarator[tb] { containingType.addField(new Field(s, tb.type(), -1)); addedAny = true; } )?
+ ( COLON expr { /* FIXME: bit types not handled yet */ } ) ?
+ ( attributeDecl )*
+ )
+ ;
+
+// FIXME: this will not correctly set the name of the enumeration when
+// encountering a declaration like this:
+//
+// typedef enum { } enumName;
+//
+// In this case calling getName() on the EnumType return value will
+// incorrectly return HeaderParser.ANONYMOUS_ENUM_NAME instead of
+// "enumName"
+//
+// 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;
+}
+ : #( "enum"
+ ( ( ID LCURLY )=> i:ID LCURLY enumList[(EnumType)(t = getEnumType(i.getText()))] RCURLY
+ | LCURLY enumList[(EnumType)(t = getEnumType(ANONYMOUS_ENUM_NAME))] RCURLY
+ | ID { t = getEnumType(i.getText()); }
+ )
+ )
+ ;
+
+enumList[EnumType enumeration] {
+ long defaultEnumerantValue = 0;
+}
+ : ( defaultEnumerantValue = enumerator[enumeration, defaultEnumerantValue] )+
+ ;
+
+enumerator[EnumType enumeration, long defaultValue] returns [long newDefaultValue] {
+ newDefaultValue = defaultValue;
+}
+ : eName:ID ( ASSIGN eVal:expr )? {
+ // FIXME! Integer.parseInt() will throw if its argument is in octal or hex format.
+ long value = (eVal == null) ? defaultValue : Long.parseLong(eVal.getText());
+ 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 + ")");
+ }
+ ;
+
+initDeclList[TypeBox tb]
+ : ( initDecl[tb] )+
+ ;
+
+initDecl[TypeBox tb] {
+ String declName = null;
+}
+ : #( NInitDecl
+ declName = declarator[tb] {
+ //System.err.println("GOT declName: " + declName + " TB=" + tb);
+ }
+ ( attributeDecl )*
+ ( ASSIGN initializer
+ | COLON expr
+ )?
+ )
+{
+ if ((declName != null) && (tb != null) && tb.isTypedef()) {
+ Type t = tb.type();
+ //System.err.println("Adding typedef mapping: [" + declName + "] -> [" + t + "]");
+ if (!t.hasTypedefName()) {
+ t.setName(declName);
+ }
+ t = canonicalize(t);
+ typedefDictionary.put(declName, t);
+ // Clear out PointerGroup effects in case another typedef variant follows
+ tb.reset();
+ }
+}
+ ;
+
+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);
+ if (tb != null) {
+ tb.setType(canonicalize(new PointerType(machDesc.pointerSizeInBytes(),
+ tb.type(),
+ attrs2CVAttrs(x))));
+ }
+ }
+ )+ )
+ ;
+
+
+functionDeclSpecifiers
+ :
+ ( functionStorageClassSpecifier
+ | typeQualifier
+ | typeSpecifier[0]
+ )+
+ ;
+
+typeName {
+ TypeBox tb = null;
+}
+ : specifierQualifierList (nonemptyAbstractDeclarator[tb])?
+ ;
+
+
+/* FIXME: the handling of types in this rule has not been well thought
+ out and is known to be incomplete. Currently it is only used to handle
+ pointerGroups for unnamed parameters. */
+nonemptyAbstractDeclarator[TypeBox tb]
+ : #( NNonemptyAbstractDeclarator
+ ( pointerGroup[tb]
+ ( (LPAREN
+ ( nonemptyAbstractDeclarator[tb]
+ | parameterTypeList
+ )?
+ RPAREN)
+ | (LBRACKET (e1:expr)? RBRACKET) { handleArrayExpr(tb, e1); }
+ )*
+
+ | ( (LPAREN
+ ( nonemptyAbstractDeclarator[tb]
+ | parameterTypeList
+ )?
+ RPAREN)
+ | (LBRACKET (e2:expr)? RBRACKET) { handleArrayExpr(tb, e2); }
+ )+
+ )
+ )
+ ;
+
+/* Helper routine for parsing expressions which evaluate to integer
+ constants. Can be made more complicated as necessary. */
+intConstExpr returns [int i] { i = -1; }
+ : n:Number { return Integer.parseInt(n.getText()); }
+ ;
diff --git a/src/net/java/games/gluegen/cgram/LineObject.java b/src/net/java/games/gluegen/cgram/LineObject.java
new file mode 100644
index 000000000..578e14194
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/LineObject.java
@@ -0,0 +1,126 @@
+package net.java.games.gluegen.cgram;
+
+class LineObject {
+ LineObject parent = null;
+ String source = "";
+ int line = 1;
+ boolean enteringFile = false;
+ boolean returningToFile = false;
+ boolean systemHeader = false;
+ boolean treatAsC = false;
+
+ public LineObject()
+ {
+ super();
+ }
+
+ public LineObject( LineObject lobj )
+ {
+ parent = lobj.getParent();
+ source = lobj.getSource();
+ line = lobj.getLine();
+ enteringFile = lobj.getEnteringFile();
+ returningToFile = lobj.getReturningToFile();
+ systemHeader = lobj.getSystemHeader();
+ treatAsC = lobj.getTreatAsC();
+ }
+
+ public LineObject( String src)
+ {
+ source = src;
+ }
+
+ public void setSource(String src)
+ {
+ source = src;
+ }
+
+ public String getSource()
+ {
+ return source;
+ }
+
+ public void setParent(LineObject par)
+ {
+ parent = par;
+ }
+
+ public LineObject getParent()
+ {
+ return parent;
+ }
+
+ public void setLine(int l)
+ {
+ line = l;
+ }
+
+ public int getLine()
+ {
+ return line;
+ }
+
+ public void newline()
+ {
+ line++;
+ }
+
+ public void setEnteringFile(boolean v)
+ {
+ enteringFile = v;
+ }
+
+ public boolean getEnteringFile()
+ {
+ return enteringFile;
+ }
+
+ public void setReturningToFile(boolean v)
+ {
+ returningToFile = v;
+ }
+
+ public boolean getReturningToFile()
+ {
+ return returningToFile;
+ }
+
+ public void setSystemHeader(boolean v)
+ {
+ systemHeader = v;
+ }
+
+ public boolean getSystemHeader()
+ {
+ return systemHeader;
+ }
+
+ public void setTreatAsC(boolean v)
+ {
+ treatAsC = v;
+ }
+
+ public boolean getTreatAsC()
+ {
+ return treatAsC;
+ }
+
+ public String toString() {
+ StringBuffer ret;
+ ret = new StringBuffer("# " + line + " \"" + source + "\"");
+ if (enteringFile) {
+ ret.append(" 1");
+ }
+ if (returningToFile) {
+ ret.append(" 2");
+ }
+ if (systemHeader) {
+ ret.append(" 3");
+ }
+ if (treatAsC) {
+ ret.append(" 4");
+ }
+ return ret.toString();
+ }
+}
+
diff --git a/src/net/java/games/gluegen/cgram/PreprocessorInfoChannel.java b/src/net/java/games/gluegen/cgram/PreprocessorInfoChannel.java
new file mode 100644
index 000000000..f2de592c7
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/PreprocessorInfoChannel.java
@@ -0,0 +1,73 @@
+package net.java.games.gluegen.cgram;
+
+import java.util.*;
+
+public class PreprocessorInfoChannel
+{
+ Hashtable lineLists = new Hashtable(); // indexed by Token number
+ int firstValidTokenNumber = 0;
+ int maxTokenNumber = 0;
+
+ public void addLineForTokenNumber( Object line, Integer toknum )
+ {
+ if ( lineLists.containsKey( toknum ) ) {
+ Vector lines = (Vector) lineLists.get( toknum );
+ lines.addElement(line);
+ }
+ else {
+ Vector lines = new Vector();
+ lines.addElement(line);
+ lineLists.put(toknum, lines);
+ if ( maxTokenNumber < toknum.intValue() ) {
+ maxTokenNumber = toknum.intValue();
+ }
+ }
+ }
+
+ public int getMaxTokenNumber()
+ {
+ return maxTokenNumber;
+ }
+
+ public Vector extractLinesPrecedingTokenNumber( Integer toknum )
+ {
+ Vector lines = new Vector();
+ if (toknum == null) return lines;
+ for (int i = firstValidTokenNumber; i < toknum.intValue(); i++){
+ Integer inti = new Integer(i);
+ if ( lineLists.containsKey( inti ) ) {
+ Vector tokenLineVector = (Vector) lineLists.get( inti );
+ if ( tokenLineVector != null) {
+ Enumeration tokenLines = tokenLineVector.elements();
+ while ( tokenLines.hasMoreElements() ) {
+ lines.addElement( tokenLines.nextElement() );
+ }
+ lineLists.remove(inti);
+ }
+ }
+ }
+ firstValidTokenNumber = toknum.intValue();
+ return lines;
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer("PreprocessorInfoChannel:\n");
+ for (int i = 0; i <= maxTokenNumber + 1; i++){
+ Integer inti = new Integer(i);
+ if ( lineLists.containsKey( inti ) ) {
+ Vector tokenLineVector = (Vector) lineLists.get( inti );
+ if ( tokenLineVector != null) {
+ Enumeration tokenLines = tokenLineVector.elements();
+ while ( tokenLines.hasMoreElements() ) {
+ sb.append(inti + ":" + tokenLines.nextElement() + '\n');
+ }
+ }
+ }
+ }
+ return sb.toString();
+ }
+}
+
+
+
diff --git a/src/net/java/games/gluegen/cgram/StdCParser.g b/src/net/java/games/gluegen/cgram/StdCParser.g
new file mode 100644
index 000000000..65f7468bf
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/StdCParser.g
@@ -0,0 +1,1375 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Copyright (c) Non, Inc. 1997 -- All Rights Reserved
+
+PROJECT: C Compiler
+MODULE: Parser
+FILE: stdc.g
+
+AUTHOR: John D. Mitchell ([email protected]), Jul 12, 1997
+
+REVISION HISTORY:
+
+ Name Date Description
+ ---- ---- -----------
+ JDM 97.07.12 Initial version.
+ JTC 97.11.18 Declaration vs declarator & misc. hacking.
+ JDM 97.11.20 Fixed: declaration vs funcDef,
+ parenthesized expressions,
+ declarator iteration,
+ varargs recognition,
+ empty source file recognition,
+ and some typos.
+
+
+DESCRIPTION:
+
+ This grammar supports the Standard C language.
+
+ Note clearly that this grammar does *NOT* deal with
+ preprocessor functionality (including things like trigraphs)
+ Nor does this grammar deal with multi-byte characters nor strings
+ containing multi-byte characters [these constructs are "exercises
+ for the reader" as it were :-)].
+
+ Please refer to the ISO/ANSI C Language Standard if you believe
+ this grammar to be in error. Please cite chapter and verse in any
+ correspondence to the author to back up your claim.
+
+TODO:
+
+ - typedefName is commented out, needs a symbol table to resolve
+ ambiguity.
+
+ - trees
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+
+header {
+ package net.java.games.gluegen.cgram;
+
+ import java.io.*;
+
+ import antlr.CommonAST;
+ import antlr.DumpASTVisitor;
+}
+
+
+class StdCParser extends Parser;
+
+options
+ {
+ k = 2;
+ exportVocab = STDC;
+ buildAST = true;
+ ASTLabelType = "TNode";
+
+ // Copied following options from java grammar.
+ codeGenMakeSwitchThreshold = 2;
+ codeGenBitsetTestThreshold = 3;
+ }
+
+
+{
+ // Suppport C++-style single-line comments?
+ public static boolean CPPComments = true;
+
+ // access to symbol table
+ public CSymbolTable symbolTable = new CSymbolTable();
+
+ // source for names to unnamed scopes
+ protected int unnamedScopeCounter = 0;
+
+ public boolean isTypedefName(String name) {
+ boolean returnValue = false;
+ TNode node = symbolTable.lookupNameInCurrentScope(name);
+ for (; node != null; node = (TNode) node.getNextSibling() ) {
+ if(node.getType() == LITERAL_typedef) {
+ returnValue = true;
+ break;
+ }
+ }
+ return returnValue;
+ }
+
+
+ public String getAScopeName() {
+ return "" + (unnamedScopeCounter++);
+ }
+
+ public void pushScope(String scopeName) {
+ symbolTable.pushScope(scopeName);
+ }
+
+ public void popScope() {
+ symbolTable.popScope();
+ }
+
+ int traceDepth = 0;
+ public void reportError(RecognitionException ex) {
+ try {
+ System.err.println("ANTLR Parsing Error: "+ex + " token name:" + tokenNames[LA(1)]);
+ ex.printStackTrace(System.err);
+ }
+ catch (TokenStreamException e) {
+ System.err.println("ANTLR Parsing Error: "+ex);
+ ex.printStackTrace(System.err);
+ }
+ }
+ public void reportError(String s) {
+ System.err.println("ANTLR Parsing Error from String: " + s);
+ }
+ public void reportWarning(String s) {
+ System.err.println("ANTLR Parsing Warning from String: " + s);
+ }
+ public void match(int t) throws MismatchedTokenException {
+ boolean debugging = false;
+
+ if ( debugging ) {
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ try {
+ System.out.println("Match("+tokenNames[t]+") with LA(1)="+
+ tokenNames[LA(1)] + ((inputState.guessing>0)?" [inputState.guessing "+ inputState.guessing + "]":""));
+ }
+ catch (TokenStreamException e) {
+ System.out.println("Match("+tokenNames[t]+") " + ((inputState.guessing>0)?" [inputState.guessing "+ inputState.guessing + "]":""));
+
+ }
+
+ }
+ try {
+ if ( LA(1)!=t ) {
+ if ( debugging ){
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ System.out.println("token mismatch: "+tokenNames[LA(1)]
+ + "!="+tokenNames[t]);
+ }
+ throw new MismatchedTokenException(tokenNames, LT(1), t, false, getFilename());
+
+ } else {
+ // mark token as consumed -- fetch next token deferred until LA/LT
+ consume();
+ }
+ }
+ catch (TokenStreamException e) {
+ }
+
+ }
+ public void traceIn(String rname) {
+ traceDepth += 1;
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ try {
+ System.out.println("> "+rname+"; LA(1)==("+ tokenNames[LT(1).getType()]
+ + ") " + LT(1).getText() + " [inputState.guessing "+ inputState.guessing + "]");
+ }
+ catch (TokenStreamException e) {
+ }
+ }
+ public void traceOut(String rname) {
+ for (int x=0; x<traceDepth; x++) System.out.print(" ");
+ try {
+ System.out.println("< "+rname+"; LA(1)==("+ tokenNames[LT(1).getType()]
+ + ") "+LT(1).getText() + " [inputState.guessing "+ inputState.guessing + "]");
+ }
+ catch (TokenStreamException e) {
+ }
+ traceDepth -= 1;
+ }
+
+}
+
+
+
+translationUnit
+ : externalList
+
+ | /* Empty source files are *not* allowed. */
+ {
+ System.err.println ( "Empty source file!" );
+ }
+ ;
+
+
+externalList
+ : ( externalDef )+
+ ;
+
+
+externalDef
+ : ( "typedef" | declaration )=> declaration
+ | functionDef
+ | asm_expr
+ ;
+
+
+asm_expr
+ : "asm"^
+ ("volatile")? LCURLY! expr RCURLY! SEMI!
+ ;
+
+
+declaration
+ { AST ds1 = null; }
+ : ds:declSpecifiers { ds1 = astFactory.dupList(#ds); }
+ (
+ initDeclList[ds1]
+ )?
+ SEMI!
+ { ## = #( #[NDeclaration], ##); }
+
+ ;
+
+
+declSpecifiers
+ { int specCount=0; }
+ : ( options { // this loop properly aborts when
+ // it finds a non-typedefName ID MBZ
+ warnWhenFollowAmbig = false;
+ } :
+ s:storageClassSpecifier
+ | typeQualifier
+ | ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=>
+ specCount = typeSpecifier[specCount]
+ )+
+ ;
+
+storageClassSpecifier
+ : "auto"
+ | "register"
+ | "typedef"
+ | functionStorageClassSpecifier
+ ;
+
+
+functionStorageClassSpecifier
+ : "extern"
+ | "static"
+ ;
+
+
+typeQualifier
+ : "const"
+ | "volatile"
+ ;
+
+typeSpecifier [int specCount] returns [int retSpecCount]
+ { retSpecCount = specCount + 1; }
+ :
+ ( "void"
+ | "char"
+ | "short"
+ | "int"
+ | "long"
+ | "float"
+ | "double"
+ | "signed"
+ | "unsigned"
+ | structOrUnionSpecifier
+ | enumSpecifier
+ | { specCount == 0 }? typedefName
+ )
+ ;
+
+
+typedefName
+ : { isTypedefName ( LT(1).getText() ) }?
+ i:ID { ## = #(#[NTypedefName], #i); }
+ ;
+
+structOrUnionSpecifier
+ { String scopeName; }
+ : sou:structOrUnion!
+ ( ( ID LCURLY )=> i:ID l:LCURLY
+ {
+ scopeName = #sou.getText() + " " + #i.getText();
+ #l.setText(scopeName);
+ pushScope(scopeName);
+ }
+ structDeclarationList
+ { popScope();}
+ RCURLY!
+ | l1:LCURLY
+ {
+ scopeName = getAScopeName();
+ #l1.setText(scopeName);
+ pushScope(scopeName);
+ }
+ structDeclarationList
+ { popScope(); }
+ RCURLY!
+ | ID
+ )
+ {
+ ## = #( #sou, ## );
+ }
+ ;
+
+
+structOrUnion
+ : "struct"
+ | "union"
+ ;
+
+
+structDeclarationList
+ : ( structDeclaration )+
+ ;
+
+
+structDeclaration
+ : specifierQualifierList structDeclaratorList ( SEMI! )+
+ ;
+
+
+specifierQualifierList
+ { int specCount = 0; }
+ : ( options { // this loop properly aborts when
+ // it finds a non-typedefName ID MBZ
+ warnWhenFollowAmbig = false;
+ } :
+ ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=>
+ specCount = typeSpecifier[specCount]
+ | typeQualifier
+ )+
+ ;
+
+
+structDeclaratorList
+ : structDeclarator ( COMMA! structDeclarator )*
+ ;
+
+
+structDeclarator
+ :
+ ( COLON constExpr
+ | declarator[false] ( COLON constExpr )?
+ )
+ { ## = #( #[NStructDeclarator], ##); }
+ ;
+
+
+enumSpecifier
+ : "enum"^
+ ( ( ID LCURLY )=> i:ID LCURLY enumList[i.getText()] RCURLY!
+ | LCURLY enumList["anonymous"] RCURLY!
+ | ID
+ )
+ ;
+
+
+enumList[String enumName]
+ : enumerator[enumName] ( COMMA! enumerator[enumName] )*
+ ;
+
+enumerator[String enumName]
+ : i:ID { symbolTable.add( i.getText(),
+ #( null,
+ #[LITERAL_enum, "enum"],
+ #[ ID, enumName]
+ )
+ );
+ }
+ (ASSIGN constExpr)?
+ ;
+
+
+initDeclList[AST declarationSpecifiers]
+ : initDecl[declarationSpecifiers]
+ ( COMMA! initDecl[declarationSpecifiers] )*
+ ;
+
+
+initDecl[AST declarationSpecifiers]
+ { String declName = ""; }
+ : declName = d:declarator[false]
+ { AST ds1, d1;
+ ds1 = astFactory.dupList(declarationSpecifiers);
+ d1 = astFactory.dupList(#d);
+ symbolTable.add(declName, #(null, ds1, d1) );
+ }
+ ( ASSIGN initializer
+ | COLON expr
+ )?
+ { ## = #( #[NInitDecl], ## ); }
+
+ ;
+
+pointerGroup
+ : ( STAR ( typeQualifier )* )+ { ## = #( #[NPointerGroup], ##); }
+ ;
+
+
+
+idList
+ : ID ( COMMA! ID )*
+ ;
+
+
+initializer
+ : ( assignExpr
+ | LCURLY initializerList ( COMMA! )? RCURLY!
+ )
+ { ## = #( #[NInitializer], ## ); }
+ ;
+
+
+initializerList
+ : initializer ( COMMA! initializer )*
+ ;
+
+
+declarator[boolean isFunctionDefinition] returns [String declName]
+ { declName = ""; }
+ :
+ ( pointerGroup )?
+
+ ( id:ID { declName = id.getText(); }
+ | LPAREN declName = declarator[false] RPAREN
+ )
+
+ ( ! LPAREN
+ {
+ if (isFunctionDefinition) {
+ pushScope(declName);
+ }
+ else {
+ pushScope("!"+declName);
+ }
+ }
+ (
+ (declSpecifiers)=> p:parameterTypeList
+ {
+ ## = #( null, ##, #( #[NParameterTypeList], #p ) );
+ }
+
+ | (i:idList)?
+ {
+ ## = #( null, ##, #( #[NParameterTypeList], #i ) );
+ }
+ )
+ {
+ popScope();
+ }
+ RPAREN
+ | LBRACKET ( constExpr )? RBRACKET
+ )*
+ { ## = #( #[NDeclarator], ## ); }
+ ;
+
+parameterTypeList
+ : parameterDeclaration
+ ( options {
+ warnWhenFollowAmbig = false;
+ } :
+ COMMA!
+ parameterDeclaration
+ )*
+ ( COMMA!
+ VARARGS
+ )?
+ ;
+
+
+parameterDeclaration
+ { String declName; }
+ : ds:declSpecifiers
+ ( ( declarator[false] )=> declName = d:declarator[false]
+ {
+ AST d2, ds2;
+ d2 = astFactory.dupList(#d);
+ ds2 = astFactory.dupList(#ds);
+ symbolTable.add(declName, #(null, ds2, d2));
+ }
+ | nonemptyAbstractDeclarator
+ )?
+ {
+ ## = #( #[NParameterDeclaration], ## );
+ }
+ ;
+
+/* JTC:
+ * This handles both new and old style functions.
+ * see declarator rule to see differences in parameters
+ * and here (declaration SEMI)* is the param type decls for the
+ * old style. may want to do some checking to check for illegal
+ * combinations (but I assume all parsed code will be legal?)
+ */
+
+functionDef
+ { String declName; }
+ : ( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers
+ | //epsilon
+ )
+ declName = d:declarator[true]
+ {
+ AST d2, ds2;
+ d2 = astFactory.dupList(#d);
+ ds2 = astFactory.dupList(#ds);
+ symbolTable.add(declName, #(null, ds2, d2));
+ pushScope(declName);
+ }
+ ( declaration )* (VARARGS)? ( SEMI! )*
+ { popScope(); }
+ compoundStatement[declName]
+ { ## = #( #[NFunctionDef], ## );}
+ ;
+
+functionDeclSpecifiers
+ { int specCount = 0; }
+ : ( options { // this loop properly aborts when
+ // it finds a non-typedefName ID MBZ
+ warnWhenFollowAmbig = false;
+ } :
+ functionStorageClassSpecifier
+ | typeQualifier
+ | ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=>
+ specCount = typeSpecifier[specCount]
+ )+
+ ;
+
+declarationList
+ : ( options { // this loop properly aborts when
+ // it finds a non-typedefName ID MBZ
+ warnWhenFollowAmbig = false;
+ } :
+ ( declarationPredictor )=> declaration
+ )+
+ ;
+
+declarationPredictor
+ : (options { //only want to look at declaration if I don't see typedef
+ warnWhenFollowAmbig = false;
+ }:
+ "typedef"
+ | declaration
+ )
+ ;
+
+
+compoundStatement[String scopeName]
+ : LCURLY!
+ {
+ pushScope(scopeName);
+ }
+ ( ( declarationPredictor)=> declarationList )?
+ ( statementList )?
+ { popScope(); }
+ RCURLY!
+ { ## = #( #[NCompoundStatement, scopeName], ##); }
+ ;
+
+
+statementList
+ : ( statement )+
+ ;
+statement
+ : SEMI // Empty statements
+
+ | compoundStatement[getAScopeName()] // Group of statements
+
+ | expr SEMI! { ## = #( #[NStatementExpr], ## ); } // Expressions
+
+// Iteration statements:
+
+ | "while"^ LPAREN! expr RPAREN! statement
+ | "do"^ statement "while"! LPAREN! expr RPAREN! SEMI!
+ |! "for"
+ LPAREN ( e1:expr )? SEMI ( e2:expr )? SEMI ( e3:expr )? RPAREN
+ s:statement
+ {
+ if ( #e1 == null) { #e1 = (TNode) #[ NEmptyExpression ]; }
+ if ( #e2 == null) { #e2 = (TNode) #[ NEmptyExpression ]; }
+ if ( #e3 == null) { #e3 = (TNode) #[ NEmptyExpression ]; }
+ ## = #( #[LITERAL_for, "for"], #e1, #e2, #e3, #s );
+ }
+
+
+// Jump statements:
+
+ | "goto"^ ID SEMI!
+ | "continue" SEMI!
+ | "break" SEMI!
+ | "return"^ ( expr )? SEMI!
+
+
+// Labeled statements:
+ | ID COLON! (options {warnWhenFollowAmbig=false;}:statement)? { ## = #( #[NLabel], ## ); }
+ | "case"^ constExpr COLON! statement
+ | "default"^ COLON! statement
+
+
+
+// Selection statements:
+
+ | "if"^
+ LPAREN! expr RPAREN! statement
+ ( //standard if-else ambiguity
+ options {
+ warnWhenFollowAmbig = false;
+ } :
+ "else" statement )?
+ | "switch"^ LPAREN! expr RPAREN! statement
+ ;
+
+
+
+
+
+
+expr
+ : assignExpr (options {
+ /* MBZ:
+ COMMA is ambiguous between comma expressions and
+ argument lists. argExprList should get priority,
+ and it does by being deeper in the expr rule tree
+ and using (COMMA assignExpr)*
+ */
+ warnWhenFollowAmbig = false;
+ } :
+ c:COMMA^ { #c.setType(NCommaExpr); } assignExpr
+ )*
+ ;
+
+
+assignExpr
+ : conditionalExpr ( a:assignOperator! assignExpr { ## = #( #a, ## );} )?
+ ;
+
+assignOperator
+ : ASSIGN
+ | DIV_ASSIGN
+ | PLUS_ASSIGN
+ | MINUS_ASSIGN
+ | STAR_ASSIGN
+ | MOD_ASSIGN
+ | RSHIFT_ASSIGN
+ | LSHIFT_ASSIGN
+ | BAND_ASSIGN
+ | BOR_ASSIGN
+ | BXOR_ASSIGN
+ ;
+
+
+conditionalExpr
+ : logicalOrExpr
+ ( QUESTION^ expr COLON! conditionalExpr )?
+ ;
+
+
+constExpr
+ : conditionalExpr
+ ;
+
+logicalOrExpr
+ : logicalAndExpr ( LOR^ logicalAndExpr )*
+ ;
+
+
+logicalAndExpr
+ : inclusiveOrExpr ( LAND^ inclusiveOrExpr )*
+ ;
+
+inclusiveOrExpr
+ : exclusiveOrExpr ( BOR^ exclusiveOrExpr )*
+ ;
+
+
+exclusiveOrExpr
+ : bitAndExpr ( BXOR^ bitAndExpr )*
+ ;
+
+
+bitAndExpr
+ : equalityExpr ( BAND^ equalityExpr )*
+ ;
+
+
+
+equalityExpr
+ : relationalExpr
+ ( ( EQUAL^ | NOT_EQUAL^ ) relationalExpr )*
+ ;
+
+
+relationalExpr
+ : shiftExpr
+ ( ( LT^ | LTE^ | GT^ | GTE^ ) shiftExpr )*
+ ;
+
+
+
+shiftExpr
+ : additiveExpr
+ ( ( LSHIFT^ | RSHIFT^ ) additiveExpr )*
+ ;
+
+
+additiveExpr
+ : multExpr
+ ( ( PLUS^ | MINUS^ ) multExpr )*
+ ;
+
+
+multExpr
+ : castExpr
+ ( ( STAR^ | DIV^ | MOD^ ) castExpr )*
+ ;
+
+
+castExpr
+ : ( LPAREN typeName RPAREN )=>
+ LPAREN! typeName RPAREN! ( castExpr )
+ { ## = #( #[NCast, "("], ## ); }
+
+ | unaryExpr
+ ;
+
+
+typeName
+ : specifierQualifierList (nonemptyAbstractDeclarator)?
+ ;
+
+nonemptyAbstractDeclarator
+ : (
+ pointerGroup
+ ( (LPAREN
+ ( nonemptyAbstractDeclarator
+ | parameterTypeList
+ )?
+ RPAREN)
+ | (LBRACKET (expr)? RBRACKET)
+ )*
+
+ | ( (LPAREN
+ ( nonemptyAbstractDeclarator
+ | parameterTypeList
+ )?
+ RPAREN)
+ | (LBRACKET (expr)? RBRACKET)
+ )+
+ )
+ { ## = #( #[NNonemptyAbstractDeclarator], ## ); }
+
+ ;
+
+/* JTC:
+
+LR rules:
+
+abstractDeclarator
+ : nonemptyAbstractDeclarator
+ | // null
+ ;
+
+nonemptyAbstractDeclarator
+ : LPAREN nonemptyAbstractDeclarator RPAREN
+ | abstractDeclarator LPAREN RPAREN
+ | abstractDeclarator (LBRACKET (expr)? RBRACKET)
+ | STAR abstractDeclarator
+ ;
+*/
+
+unaryExpr
+ : postfixExpr
+ | INC^ unaryExpr
+ | DEC^ unaryExpr
+ | u:unaryOperator castExpr { ## = #( #[NUnaryExpr], ## ); }
+
+ | "sizeof"^
+ ( ( LPAREN typeName )=> LPAREN typeName RPAREN
+ | unaryExpr
+ )
+ ;
+
+
+unaryOperator
+ : BAND
+ | STAR
+ | PLUS
+ | MINUS
+ | BNOT
+ | LNOT
+ ;
+
+postfixExpr
+ : primaryExpr
+ (
+ postfixSuffix {## = #( #[NPostfixExpr], ## );}
+ )?
+ ;
+postfixSuffix
+ :
+ ( PTR ID
+ | DOT ID
+ | functionCall
+ | LBRACKET expr RBRACKET
+ | INC
+ | DEC
+ )+
+ ;
+
+functionCall
+ :
+ LPAREN^ (a:argExprList)? RPAREN
+ {
+ ##.setType( NFunctionCallArgs );
+ }
+ ;
+
+
+primaryExpr
+ : ID
+ | charConst
+ | intConst
+ | floatConst
+ | stringConst
+
+// JTC:
+// ID should catch the enumerator
+// leaving it in gives ambiguous err
+// | enumerator
+ | LPAREN! expr RPAREN! { ## = #( #[NExpressionGroup, "("], ## ); }
+ ;
+
+argExprList
+ : assignExpr ( COMMA! assignExpr )*
+ ;
+
+
+
+protected
+charConst
+ : CharLiteral
+ ;
+
+
+protected
+stringConst
+ : (StringLiteral)+ { ## = #(#[NStringSeq], ##); }
+ ;
+
+
+protected
+intConst
+ : IntOctalConst
+ | LongOctalConst
+ | UnsignedOctalConst
+ | IntIntConst
+ | LongIntConst
+ | UnsignedIntConst
+ | IntHexConst
+ | LongHexConst
+ | UnsignedHexConst
+ ;
+
+
+protected
+floatConst
+ : FloatDoubleConst
+ | DoubleDoubleConst
+ | LongDoubleConst
+ ;
+
+
+
+
+
+
+dummy
+ : NTypedefName
+ | NInitDecl
+ | NDeclarator
+ | NStructDeclarator
+ | NDeclaration
+ | NCast
+ | NPointerGroup
+ | NExpressionGroup
+ | NFunctionCallArgs
+ | NNonemptyAbstractDeclarator
+ | NInitializer
+ | NStatementExpr
+ | NEmptyExpression
+ | NParameterTypeList
+ | NFunctionDef
+ | NCompoundStatement
+ | NParameterDeclaration
+ | NCommaExpr
+ | NUnaryExpr
+ | NLabel
+ | NPostfixExpr
+ | NRangeExpr
+ | NStringSeq
+ | NInitializerElementLabel
+ | NLcurlyInitializer
+ | NAsmAttribute
+ | NGnuAsmExpr
+ | NTypeMissing
+ ;
+
+
+
+
+
+
+{
+ import java.io.*;
+ import antlr.*;
+}
+
+class StdCLexer extends Lexer;
+
+options
+ {
+ k = 3;
+ exportVocab = STDC;
+ testLiterals = false;
+ }
+
+{
+ LineObject lineObject = new LineObject();
+ String originalSource = "";
+ PreprocessorInfoChannel preprocessorInfoChannel = new PreprocessorInfoChannel();
+ int tokenNumber = 0;
+ boolean countingTokens = true;
+ int deferredLineCount = 0;
+
+ public void setCountingTokens(boolean ct)
+ {
+ countingTokens = ct;
+ if ( countingTokens ) {
+ tokenNumber = 0;
+ }
+ else {
+ tokenNumber = 1;
+ }
+ }
+
+ public void setOriginalSource(String src)
+ {
+ originalSource = src;
+ lineObject.setSource(src);
+ }
+ public void setSource(String src)
+ {
+ lineObject.setSource(src);
+ }
+
+ public PreprocessorInfoChannel getPreprocessorInfoChannel()
+ {
+ return preprocessorInfoChannel;
+ }
+
+ public void setPreprocessingDirective(String pre)
+ {
+ preprocessorInfoChannel.addLineForTokenNumber( pre, new Integer(tokenNumber) );
+ }
+
+ public void addDefine(String name, String value)
+ {
+ }
+
+ protected Token makeToken(int t)
+ {
+ if ( t != Token.SKIP && countingTokens) {
+ tokenNumber++;
+ }
+ CToken tok = (CToken) super.makeToken(t);
+ tok.setLine(lineObject.line);
+ tok.setSource(lineObject.source);
+ tok.setTokenNumber(tokenNumber);
+
+ lineObject.line += deferredLineCount;
+ deferredLineCount = 0;
+ return tok;
+ }
+
+ public void deferredNewline() {
+ deferredLineCount++;
+ }
+
+ public void newline() {
+ lineObject.newline();
+ }
+
+
+
+
+
+
+}
+
+protected
+Vocabulary
+ : '\3'..'\377'
+ ;
+
+
+/* Operators: */
+
+ASSIGN : '=' ;
+COLON : ':' ;
+COMMA : ',' ;
+QUESTION : '?' ;
+SEMI : ';' ;
+PTR : "->" ;
+
+
+// DOT & VARARGS are commented out since they are generated as part of
+// the Number rule below due to some bizarre lexical ambiguity shme.
+
+// DOT : '.' ;
+protected
+DOT:;
+
+// VARARGS : "..." ;
+protected
+VARARGS:;
+
+
+LPAREN : '(' ;
+RPAREN : ')' ;
+LBRACKET : '[' ;
+RBRACKET : ']' ;
+LCURLY : '{' ;
+RCURLY : '}' ;
+
+EQUAL : "==" ;
+NOT_EQUAL : "!=" ;
+LTE : "<=" ;
+LT : "<" ;
+GTE : ">=" ;
+GT : ">" ;
+
+DIV : '/' ;
+DIV_ASSIGN : "/=" ;
+PLUS : '+' ;
+PLUS_ASSIGN : "+=" ;
+INC : "++" ;
+MINUS : '-' ;
+MINUS_ASSIGN : "-=" ;
+DEC : "--" ;
+STAR : '*' ;
+STAR_ASSIGN : "*=" ;
+MOD : '%' ;
+MOD_ASSIGN : "%=" ;
+RSHIFT : ">>" ;
+RSHIFT_ASSIGN : ">>=" ;
+LSHIFT : "<<" ;
+LSHIFT_ASSIGN : "<<=" ;
+
+LAND : "&&" ;
+LNOT : '!' ;
+LOR : "||" ;
+
+BAND : '&' ;
+BAND_ASSIGN : "&=" ;
+BNOT : '~' ;
+BOR : '|' ;
+BOR_ASSIGN : "|=" ;
+BXOR : '^' ;
+BXOR_ASSIGN : "^=" ;
+
+
+Whitespace
+ : ( ( '\003'..'\010' | '\t' | '\013' | '\f' | '\016'.. '\037' | '\177'..'\377' | ' ' )
+ | "\r\n" { newline(); }
+ | ( '\n' | '\r' ) { newline(); }
+ ) { _ttype = Token.SKIP; }
+ ;
+
+
+Comment
+ : "/*"
+ ( { LA(2) != '/' }? '*'
+ | "\r\n" { deferredNewline(); }
+ | ( '\r' | '\n' ) { deferredNewline(); }
+ | ~( '*'| '\r' | '\n' )
+ )*
+ "*/" { _ttype = Token.SKIP;
+ }
+ ;
+
+
+CPPComment
+ :
+ "//" ( ~('\n') )*
+ {
+ _ttype = Token.SKIP;
+ }
+ ;
+
+protected NonWhitespace
+ : (~('\r' | '\n'))*
+ ;
+
+
+PREPROC_DIRECTIVE
+options {
+ paraphrase = "a line directive";
+}
+
+ :
+ '#'
+ ( ( "line" || (( ' ' | '\t' | '\014')+ '0'..'9')) => LineDirective
+ | ( (Space)* "define" (Space)* i:ID (Space)* (n:Number)?
+ nw:NonWhitespace
+ ("\r\n" | "\r" | "\n") ) { if (n != null) {
+ addDefine(i.getText(), n.getText());
+ } else {
+ setPreprocessingDirective("#define " + i.getText() + " " +
+ nw.getText());
+ }
+ }
+ | (~'\n')* { setPreprocessingDirective(getText()); }
+ )
+ {
+ _ttype = Token.SKIP;
+ }
+ ;
+
+protected Space:
+ ( ' ' | '\t' | '\014')
+ ;
+
+protected LineDirective
+{
+ boolean oldCountingTokens = countingTokens;
+ countingTokens = false;
+}
+:
+ {
+ lineObject = new LineObject();
+ deferredLineCount = 0;
+ }
+ ("line")? //this would be for if the directive started "#line", but not there for GNU directives
+ (Space)+
+ n:Number { lineObject.setLine(Integer.parseInt(n.getText())); }
+ (Space)+
+ ( fn:StringLiteral { try {
+ lineObject.setSource(fn.getText().substring(1,fn.getText().length()-1));
+ }
+ catch (StringIndexOutOfBoundsException e) { /*not possible*/ }
+ }
+ | fi:ID { lineObject.setSource(fi.getText()); }
+ )?
+ (Space)*
+ ("1" { lineObject.setEnteringFile(true); } )?
+ (Space)*
+ ("2" { lineObject.setReturningToFile(true); } )?
+ (Space)*
+ ("3" { lineObject.setSystemHeader(true); } )?
+ (Space)*
+ ("4" { lineObject.setTreatAsC(true); } )?
+ (~('\r' | '\n'))*
+ ("\r\n" | "\r" | "\n")
+ {
+ preprocessorInfoChannel.addLineForTokenNumber(new LineObject(lineObject), new Integer(tokenNumber));
+ countingTokens = oldCountingTokens;
+ }
+ ;
+
+
+
+/* Literals: */
+
+/*
+ * Note that we do NOT handle tri-graphs nor multi-byte sequences.
+ */
+
+
+/*
+ * Note that we can't have empty character constants (even though we
+ * can have empty strings :-).
+ */
+CharLiteral
+ : '\'' ( Escape | ~( '\'' ) ) '\''
+ ;
+
+
+/*
+ * Can't have raw imbedded newlines in string constants. Strict reading of
+ * the standard gives odd dichotomy between newlines & carriage returns.
+ * Go figure.
+ */
+StringLiteral
+ : '"'
+ ( Escape
+ | (
+ '\r' { deferredNewline(); }
+ | '\n' {
+ deferredNewline();
+ _ttype = BadStringLiteral;
+ }
+ | '\\' '\n' {
+ deferredNewline();
+ }
+ )
+ | ~( '"' | '\r' | '\n' | '\\' )
+ )*
+ '"'
+ ;
+
+
+protected BadStringLiteral
+ : // Imaginary token.
+ ;
+
+
+/*
+ * Handle the various escape sequences.
+ *
+ * Note carefully that these numeric escape *sequences* are *not* of the
+ * same form as the C language numeric *constants*.
+ *
+ * There is no such thing as a binary numeric escape sequence.
+ *
+ * Octal escape sequences are either 1, 2, or 3 octal digits exactly.
+ *
+ * There is no such thing as a decimal escape sequence.
+ *
+ * Hexadecimal escape sequences are begun with a leading \x and continue
+ * until a non-hexadecimal character is found.
+ *
+ * No real handling of tri-graph sequences, yet.
+ */
+
+protected
+Escape
+ : '\\'
+ ( options{warnWhenFollowAmbig=false;}:
+ 'a'
+ | 'b'
+ | 'f'
+ | 'n'
+ | 'r'
+ | 't'
+ | 'v'
+ | '"'
+ | '\''
+ | '\\'
+ | '?'
+ | ('0'..'3') ( options{warnWhenFollowAmbig=false;}: Digit ( options{warnWhenFollowAmbig=false;}: Digit )? )?
+ | ('4'..'7') ( options{warnWhenFollowAmbig=false;}: Digit )?
+ | 'x' ( options{warnWhenFollowAmbig=false;}: Digit | 'a'..'f' | 'A'..'F' )+
+ )
+ ;
+
+
+/* Numeric Constants: */
+
+protected
+Digit
+ : '0'..'9'
+ ;
+
+protected
+LongSuffix
+ : 'l'
+ | 'L'
+ ;
+
+protected
+UnsignedSuffix
+ : 'u'
+ | 'U'
+ ;
+
+protected
+FloatSuffix
+ : 'f'
+ | 'F'
+ ;
+
+protected
+Exponent
+ : ( 'e' | 'E' ) ( '+' | '-' )? ( Digit )+
+ ;
+
+
+protected
+DoubleDoubleConst:;
+
+protected
+FloatDoubleConst:;
+
+protected
+LongDoubleConst:;
+
+protected
+IntOctalConst:;
+
+protected
+LongOctalConst:;
+
+protected
+UnsignedOctalConst:;
+
+protected
+IntIntConst:;
+
+protected
+LongIntConst:;
+
+protected
+UnsignedIntConst:;
+
+protected
+IntHexConst:;
+
+protected
+LongHexConst:;
+
+protected
+UnsignedHexConst:;
+
+
+
+
+Number
+ : ( ( Digit )+ ( '.' | 'e' | 'E' ) )=> ( Digit )+
+ ( '.' ( Digit )* ( Exponent )?
+ | Exponent
+ ) { _ttype = DoubleDoubleConst; }
+ ( FloatSuffix { _ttype = FloatDoubleConst; }
+ | LongSuffix { _ttype = LongDoubleConst; }
+ )?
+
+ | ( "..." )=> "..." { _ttype = VARARGS; }
+
+ | '.' { _ttype = DOT; }
+ ( ( Digit )+ ( Exponent )?
+ { _ttype = DoubleDoubleConst; }
+ ( FloatSuffix { _ttype = FloatDoubleConst; }
+ | LongSuffix { _ttype = LongDoubleConst; }
+ )?
+ )?
+
+ | '0' ( '0'..'7' )* { _ttype = IntOctalConst; }
+ ( LongSuffix { _ttype = LongOctalConst; }
+ | UnsignedSuffix { _ttype = UnsignedOctalConst; }
+ )?
+
+ | '1'..'9' ( Digit )* { _ttype = IntIntConst; }
+ ( LongSuffix { _ttype = LongIntConst; }
+ | UnsignedSuffix { _ttype = UnsignedIntConst; }
+ )?
+
+ | '0' ( 'x' | 'X' ) ( 'a'..'f' | 'A'..'F' | Digit )+
+ { _ttype = IntHexConst; }
+ ( LongSuffix { _ttype = LongHexConst; }
+ | UnsignedSuffix { _ttype = UnsignedHexConst; }
+ )?
+ ;
+
+
+ID
+ options
+ {
+ testLiterals = true;
+ }
+ : ( 'a'..'z' | 'A'..'Z' | '_' )
+ ( 'a'..'z' | 'A'..'Z' | '_' | '0'..'9' )*
+ ;
+
+
diff --git a/src/net/java/games/gluegen/cgram/TNode.java b/src/net/java/games/gluegen/cgram/TNode.java
new file mode 100644
index 000000000..2a93b939c
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/TNode.java
@@ -0,0 +1,433 @@
+package net.java.games.gluegen.cgram;
+
+import antlr.collections.AST;
+import antlr.CommonAST;
+import antlr.Token;
+import java.lang.reflect.*;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/**
+ Class TNode is an implementation of the AST interface
+ and adds many useful features:
+
+ It is double-linked for reverse searching.
+ (this is currently incomplete, in that method doubleLink() must
+ be called after any changes to the tree to maintain the
+ reverse links).
+
+ It can store a definition node (defNode), so that nodes such
+ as scoped names can refer to the node that defines the name.
+
+ It stores line numbers for nodes.
+
+ Searches for parents and children of a tree can be done
+ based on their type.
+
+ The tree can be printed to System.out using a lisp-style syntax.
+
+
+
+ */
+public class TNode extends CommonAST {
+ protected int ttype;
+ protected String text;
+ protected int lineNum = 0;
+ protected TNode defNode;
+ protected TNode up;
+ protected TNode left;
+ protected boolean marker = false;
+ protected Hashtable attributes = null;
+ static String tokenVocabulary;
+
+
+
+
+ /** Set the token vocabulary to a tokentypes class
+ generated by antlr.
+ */
+ public static void setTokenVocabulary(String s) {
+ tokenVocabulary = s;
+ }
+
+
+public void initialize(Token token) {
+ CToken tok = (CToken) token;
+ setText(tok.getText());
+ setType(tok.getType());
+ setLineNum(tok.getLine());
+ setAttribute("source", tok.getSource());
+ setAttribute("tokenNumber", new Integer(tok.getTokenNumber()));
+}
+public void initialize(AST tr) {
+ TNode t = (TNode) tr;
+ setText(t.getText());
+ setType(t.getType());
+ setLineNum(t.getLineNum());
+ setDefNode(t.getDefNode());
+ this.attributes = t.getAttributesTable();
+}
+
+
+ /** Get the token type for this node */
+ public int getType() { return ttype; }
+
+ /** Set the token type for this node */
+ public void setType(int ttype_) {
+ ttype = ttype_;
+ }
+
+ /** Get the marker value for this node.
+ This member is a general-use marker.
+ */
+ public boolean getMarker() { return marker; }
+
+ /** Set the marker value for this node.
+ This property is a general-use boolean marker.
+ */
+ public void setMarker(boolean marker_) {
+ marker = marker_;
+ }
+
+ /** get the hashtable that holds attribute values.
+ */
+ public Hashtable getAttributesTable() {
+ if(attributes == null)
+ attributes = new Hashtable(7);
+ return attributes;
+ }
+
+ /** set an attribute in the attribute table.
+ */
+ public void setAttribute(String attrName, Object value) {
+ if(attributes == null)
+ attributes = new Hashtable(7);
+ attributes.put(attrName,value);
+ }
+
+ /** lookup the attribute name in the attribute table.
+ If the value does not exist, it returns null.
+ */
+ public Object getAttribute(String attrName) {
+ if(attributes == null)
+ return null;
+ else
+ return attributes.get(attrName);
+ }
+
+ /** Get the line number for this node.
+ If the line number is 0, search for a non-zero line num among children */
+ public int getLineNum() {
+ if(lineNum != 0)
+ return lineNum;
+ else
+ if(down == null)
+ return lineNum;
+ else
+ return ((TNode)down).getLocalLineNum();
+ }
+
+ public int getLocalLineNum() {
+ if(lineNum != 0)
+ return lineNum;
+ else
+ if(down == null)
+ if(right == null)
+ return lineNum;
+ else
+ return ((TNode)right).getLocalLineNum();
+ else
+ return ((TNode)down).getLocalLineNum();
+ }
+
+ /** Set the line number for this node */
+ public void setLineNum(int lineNum_) {
+ lineNum = lineNum_;
+ }
+
+ /** Get the token text for this node */
+ public String getText() { return text; }
+
+ /** Set the token text for this node */
+ public void setText(String text_) {
+ text = text_;
+ }
+
+ /** return the last child of this node, or null if there is none */
+ public TNode getLastChild() {
+ TNode down = (TNode)getFirstChild();
+ if(down != null)
+ return down.getLastSibling();
+ else
+ return null;
+ }
+
+ /** return the last sibling of this node, which is
+ this if the next sibling is null */
+ public TNode getLastSibling() {
+ TNode next = (TNode)getNextSibling();
+ if(next != null)
+ return next.getLastSibling();
+ else
+ return this;
+ }
+
+ /** return the first sibling of this node, which is
+ this if the prev sibling is null */
+ public TNode getFirstSibling() {
+ TNode prev = (TNode)left;
+ if(prev != null)
+ return prev.getFirstSibling();
+ else
+ return this;
+ }
+
+
+ /** return the parent node of this node */
+ public TNode getParent() {
+ return (TNode)getFirstSibling().up;
+ }
+
+
+ /** add the new node as a new sibling, inserting it ahead of any
+ existing next sibling. This method maintains double-linking.
+ if node is null, nothing happens. If the node has siblings,
+ then they are added in as well.
+ */
+ public void addSibling(AST node) {
+ if(node == null) return;
+ TNode next = (TNode)right;
+ right = (TNode)node;
+ ((TNode)node).left = this;
+ TNode nodeLastSib = ((TNode)node).getLastSibling();
+ nodeLastSib.right = next;
+ if(next != null)
+ next.left = nodeLastSib;
+ }
+
+
+ /** return the number of children of this node */
+ public int numberOfChildren() {
+ int count = 0;
+ AST child = getFirstChild();
+ while(child != null) {
+ count++;
+ child = child.getNextSibling();
+ }
+ return count;
+ }
+
+
+ /** remove this node from the tree, resetting sibling and parent
+ pointers as necessary. This method maintains double-linking */
+ public void removeSelf() {
+ TNode parent = (TNode)up;
+ TNode prev = (TNode)left;
+ TNode next = (TNode)right;
+
+ if(parent != null) {
+ parent.down = next;
+ if(next != null) {
+ next.up = parent;
+ next.left = prev; // which should be null
+ }
+ }
+ else {
+ if(prev != null)
+ prev.right = next;
+ if(next != null)
+ next.left = prev;
+ }
+ }
+
+
+ /** return the def node for this node */
+ public TNode getDefNode() {
+ return defNode;
+ }
+
+ /** set the def node for this node */
+ public void setDefNode(TNode n) {
+ defNode = n;
+ }
+
+
+ /** return a deep copy of this node, and all sub nodes.
+ New tree is doubleLinked, with no parent or siblings.
+ Marker value is not copied!
+ */
+ public TNode deepCopy() {
+ TNode copy = new TNode();
+ copy.ttype = ttype;
+ copy.text = text;
+ copy.lineNum = lineNum;
+ copy.defNode = defNode;
+ if(attributes != null)
+ copy.attributes = (Hashtable)attributes.clone();
+ if(down != null)
+ copy.down = ((TNode)down).deepCopyWithRightSiblings();
+ copy.doubleLink();
+ return copy;
+ }
+
+
+ /** return a deep copy of this node, all sub nodes,
+ and right siblings.
+ New tree is doubleLinked, with no parent or left siblings.
+ defNode is not copied */
+ public TNode deepCopyWithRightSiblings() {
+ TNode copy = new TNode();
+ copy.ttype = ttype;
+ copy.text = text;
+ copy.lineNum = lineNum;
+ copy.defNode = defNode;
+ if(attributes != null)
+ copy.attributes = (Hashtable)attributes.clone();
+ if(down != null)
+ copy.down = ((TNode)down).deepCopyWithRightSiblings();
+ if(right != null)
+ copy.right = ((TNode)right).deepCopyWithRightSiblings();
+ copy.doubleLink();
+ return copy;
+ }
+
+
+ /** return a short string representation of the node */
+ public String toString() {
+ StringBuffer str = new StringBuffer( getNameForType(getType()) +
+ "[" + getText() + ", " + "]");
+
+ if(this.getLineNum() != 0)
+ str.append(" line:" + (this.getLineNum() ) );
+
+ Enumeration keys = (this.getAttributesTable().keys());
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ str.append(" " + key + ":" + (this.getAttribute(key)));
+ }
+
+ return str.toString();
+ }
+
+
+ /** print given tree to System.out */
+ public static void printTree(AST t) {
+ if (t == null) return;
+ printASTNode(t,0);
+ System.out.print("\n");
+ }
+
+
+ /** protected method that does the work of printing */
+ protected static void printASTNode(AST t, int indent) {
+ AST child1, next;
+ child1 = t.getFirstChild();
+
+ System.out.print("\n");
+ for(int i = 0; i < indent; i++)
+ System.out.print(" ");
+
+ if(child1 != null)
+ System.out.print("(");
+
+ String s = t.getText();
+ if(s != null && s.length() > 0) {
+ System.out.print(getNameForType(t.getType()));
+ System.out.print(": \"" + s + "\"");
+ }
+ else
+ System.out.print(getNameForType(t.getType()));
+ if(((TNode)t).getLineNum() != 0)
+ System.out.print(" line:" + ((TNode)t).getLineNum() );
+
+ Enumeration keys = ((TNode)t).getAttributesTable().keys();
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ System.out.print(" " + key + ":" + ((TNode)t).getAttribute(key));
+ }
+ TNode def = ((TNode)t).getDefNode();
+ if(def != null)
+ System.out.print("[" + getNameForType(def.getType()) + "]");
+
+
+ if(child1 != null) {
+ printASTNode(child1,indent + 1);
+
+ System.out.print("\n");
+ for(int i = 0; i < indent; i++)
+ System.out.print(" ");
+ System.out.print(")");
+ }
+
+ next = t.getNextSibling();
+ if(next != null) {
+ printASTNode(next,indent);
+ }
+ }
+
+ /** converts an int tree token type to a name.
+ Does this by reflecting on nsdidl.IDLTreeTokenTypes,
+ and is dependent on how ANTLR 2.00 outputs that class. */
+ public static String getNameForType(int t) {
+ try{
+ Class c = Class.forName(tokenVocabulary);
+ Field[] fields = c.getDeclaredFields();
+ if(t-2 < fields.length)
+ return fields[t-2].getName();
+ } catch (Exception e) { System.out.println(e); }
+ return "unfoundtype: " + t;
+ }
+
+
+ /** set up reverse links between this node and its first
+ child and its first sibling, and link those as well */
+ public void doubleLink() {
+ TNode right = (TNode)getNextSibling();
+ if(right != null) {
+ right.left = this;
+ right.doubleLink();
+ }
+ TNode down = (TNode)getFirstChild();
+ if(down != null) {
+ down.up = this;
+ down.doubleLink();
+ }
+ }
+
+ /** find first parent of the given type,
+ return null on failure */
+ public TNode parentOfType(int type) {
+ if(up == null) {
+ if(left == null)
+ return null;
+ else
+ return left.parentOfType(type);
+ }
+ if(up.getType() == type)
+ return up;
+ return up.parentOfType(type);
+ }
+
+ /** find the first child of the node
+ of the given type, return null on failure */
+ public TNode firstChildOfType(int type) {
+ TNode down = (TNode)getFirstChild();
+ if(down == null)
+ return null;
+ if(down.getType() == type)
+ return down;
+ return down.firstSiblingOfType(type);
+ }
+
+ /** find the first sibling of the node
+ of the given type, return null on failure */
+ public TNode firstSiblingOfType(int type) {
+ TNode right = (TNode)getNextSibling();
+ if(right == null)
+ return null;
+ if(right.getType() == type)
+ return right;
+ return right.firstSiblingOfType(type);
+ }
+
+}
diff --git a/src/net/java/games/gluegen/cgram/TNodeFactory.java b/src/net/java/games/gluegen/cgram/TNodeFactory.java
new file mode 100644
index 000000000..8cda2cfa9
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/TNodeFactory.java
@@ -0,0 +1,33 @@
+package net.java.games.gluegen.cgram;
+
+import antlr.Token;
+import antlr.ASTFactory;
+import antlr.collections.AST;
+
+/** This class extends ASTFactory to build instances
+ of class TNode */
+public class TNodeFactory extends ASTFactory {
+
+ /** Create a new ampty AST node */
+ public AST create() {
+ return new TNode();
+ }
+
+ /** Create a new AST node from type and text */
+ public AST create(int ttype, String text) {
+ AST ast = new TNode();
+ ast.setType(ttype);
+ ast.setText(text);
+ return ast;
+ }
+
+ /** Create a new AST node from an existing AST node */
+ public AST create(AST ast) {
+ AST newast = new TNode();
+ newast.setType(ast.getType());
+ newast.setText(ast.getText());
+ return newast;
+ }
+
+
+}
diff --git a/src/net/java/games/gluegen/cgram/types/ArrayType.java b/src/net/java/games/gluegen/cgram/types/ArrayType.java
new file mode 100644
index 000000000..6394a39cb
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/ArrayType.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+/** 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
+ should be passed in to the constructor. */
+
+public class ArrayType extends Type {
+ private Type elementType;
+ private int length;
+ private String computedName;
+
+ public ArrayType(Type elementType, int sizeInBytes, int length, int cvAttributes) {
+ super(elementType.getName() + " *", sizeInBytes, cvAttributes);
+ this.elementType = elementType;
+ this.length = length;
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == this) return true;
+ if (arg == null || (!(arg instanceof ArrayType))) {
+ return false;
+ }
+ ArrayType t = (ArrayType) arg;
+ return (super.equals(arg) && elementType.equals(t.elementType) && (length == t.length));
+ }
+
+ public String getName(boolean includeCVAttrs) {
+ // Lazy computation of name due to lazy setting of compound type
+ // names during parsing
+ // Note: don't think cvAttributes can be set for array types (unlike pointer types)
+ if (computedName == null) {
+ computedName = elementType.getName() + " *";
+ computedName = computedName.intern();
+ }
+ return computedName;
+ }
+
+ public ArrayType asArray() { return this; }
+
+ public Type getElementType() { return elementType; }
+ public int getLength() { return length; }
+ public boolean hasLength() { return length >= 0; }
+
+ /** Return the bottommost element type if this is a multidimensional
+ array. */
+ public Type getBaseElementType() {
+ ArrayType t = this;
+ while (t.getElementType().isArray()) {
+ t = t.getElementType().asArray();
+ }
+ return t.getElementType();
+ }
+
+ /** Recompute the size of this array if necessary. This needs to be
+ done when the base element type is a compound type. */
+ public void recomputeSize() {
+ ArrayType arrayElementType = getElementType().asArray();
+ if (arrayElementType != null) {
+ arrayElementType.recomputeSize();
+ }
+ // FIXME: this doesn't take into account struct alignment, which may be necessary
+ // See also FIXME below and in HeaderParser.g
+ super.setSize(getLength() * elementType.getSize());
+ }
+
+ public String toString() {
+ return toString(null);
+ }
+
+ public String toString(String variableName) {
+ StringBuffer buf = new StringBuffer();
+ buf.append(elementType.getName());
+ if (variableName != null) {
+ buf.append(" ");
+ buf.append(variableName);
+ }
+ buf.append("[");
+ buf.append(length);
+ buf.append("]");
+ return buf.toString();
+ }
+
+ public void visit(TypeVisitor arg) {
+ super.visit(arg);
+ elementType.visit(arg);
+ }
+
+ Type newCVVariant(int cvAttributes) {
+ return new ArrayType(elementType, getSize(), length, cvAttributes);
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/BitType.java b/src/net/java/games/gluegen/cgram/types/BitType.java
new file mode 100644
index 000000000..48d81e933
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/BitType.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+/** Represents a bitfield in a struct. */
+
+public class BitType extends IntType {
+ private IntType underlyingType;
+ private int sizeInBits;
+ private int offset;
+
+ public BitType(IntType underlyingType, int sizeInBits, int lsbOffset, int cvAttributes) {
+ super(underlyingType.getName(), underlyingType.getSize(), underlyingType.isUnsigned(), cvAttributes);
+ this.underlyingType = underlyingType;
+ this.sizeInBits = sizeInBits;
+ this.offset = lsbOffset;
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == this) return true;
+ if (arg == null || (!(arg instanceof BitType))) {
+ return false;
+ }
+ BitType t = (BitType) arg;
+ return (super.equals(arg) && underlyingType.equals(t.underlyingType) &&
+ (sizeInBits == t.sizeInBits) && (offset == t.offset));
+ }
+
+ public BitType asBit() { return this; }
+
+ /** Size in bits of this type. */
+ public int getSizeInBits() {
+ return sizeInBits;
+ }
+
+ /** Offset from the least-significant bit (LSB) of the LSB of this
+ type */
+ public int getOffset() {
+ return offset;
+ }
+
+ public void visit(TypeVisitor arg) {
+ super.visit(arg);
+ underlyingType.visit(arg);
+ }
+
+ Type newCVVariant(int cvAttributes) {
+ return new BitType(underlyingType, sizeInBits, offset, cvAttributes);
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/CVAttributes.java b/src/net/java/games/gluegen/cgram/types/CVAttributes.java
new file mode 100644
index 000000000..e93d38cc5
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/CVAttributes.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+/** Enumeration for const/volatile attributes. These are passed in to
+ the constructor of the type. */
+
+public interface CVAttributes {
+ public static final int CONST = 0x01;
+ public static final int VOLATILE = 0x02;
+}
diff --git a/src/net/java/games/gluegen/cgram/types/CompoundType.java b/src/net/java/games/gluegen/cgram/types/CompoundType.java
new file mode 100644
index 000000000..a08193a13
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/CompoundType.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+import java.util.*;
+
+/** Models all compound types, i.e., those containing fields: structs
+ and unions. The boolean type accessors indicate how the type is
+ really defined. */
+
+public class CompoundType extends Type {
+ private CompoundTypeKind kind;
+ // The name "foo" in the construct "struct foo { ... }";
+ private String structName;
+ private ArrayList fields;
+ private boolean visiting;
+ private boolean bodyParsed;
+ private boolean computedHashcode;
+ private int hashcode;
+
+ public CompoundType(String name, int size, CompoundTypeKind kind, int cvAttributes) {
+ this(name, size, kind, cvAttributes, null);
+ }
+
+ private CompoundType(String name, int size, CompoundTypeKind kind, int cvAttributes, String structName) {
+ super(name, size, cvAttributes);
+ assert kind != null;
+ this.kind = kind;
+ this.structName = structName;
+ }
+
+ public int hashCode() {
+ if (computedHashcode) {
+ return hashcode;
+ }
+
+ if (structName != null) {
+ hashcode = structName.hashCode();
+ } else if (getName() != null) {
+ hashcode = getName().hashCode();
+ } else {
+ hashcode = System.identityHashCode(this);
+ }
+
+ computedHashcode = true;
+ return hashcode;
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == this) return true;
+ if (arg == null || (!(arg instanceof CompoundType))) {
+ return false;
+ }
+ CompoundType t = (CompoundType) arg;
+ return (super.equals(arg) &&
+ kind == t.kind &&
+ listsEqual(fields, t.fields));
+ }
+
+ /** Returns the struct name of this CompoundType, i.e. the "foo" in
+ the construct "struct foo { ... };". */
+ public String getStructName() {
+ return structName;
+ }
+
+ /** Sets the struct name of this CompoundType, i.e. the "foo" in the
+ construct "struct foo { ... };". */
+ public void setStructName(String structName) {
+ this.structName = structName;
+ }
+
+ public void setSize(int size) {
+ super.setSize(size);
+ }
+
+ public CompoundType asCompound() { return this; }
+
+ /** Returns the number of fields in this type. */
+ public int getNumFields() {
+ return ((fields == null) ? 0 : fields.size());
+ }
+
+ /** Returns the <i>i</i>th field of this type. */
+ public Field getField(int i) {
+ return (Field) fields.get(i);
+ }
+
+ /** Adds a field to this type. */
+ public void addField(Field f) {
+ if (bodyParsed) {
+ throw new RuntimeException("Body of this CompoundType has already been parsed; should not be adding more fields");
+ }
+ if (fields == null) {
+ fields = new ArrayList();
+ }
+ fields.add(f);
+ }
+
+ /** Indicates to this CompoundType that its body has been parsed and
+ that no more {@link addField} operations will be made. */
+ public void setBodyParsed() {
+ bodyParsed = true;
+ }
+
+ /** Indicates whether this type was declared as a struct. */
+ public boolean isStruct() { return (kind == CompoundTypeKind.STRUCT); }
+ /** Indicates whether this type was declared as a union. */
+ public boolean isUnion() { return (kind == CompoundTypeKind.UNION); }
+
+ public String toString() {
+ String cvAttributesString = getCVAttributesString();
+ if (getName() != null) {
+ return cvAttributesString + getName();
+ } else if (getStructName() != null) {
+ return cvAttributesString + "struct " + getStructName();
+ } else {
+ return cvAttributesString + getStructString();
+ }
+ }
+
+ public void visit(TypeVisitor arg) {
+ if (visiting) {
+ return;
+ }
+ try {
+ visiting = true;
+ super.visit(arg);
+ int n = getNumFields();
+ for (int i = 0; i < n; i++) {
+ Field f = getField(i);
+ f.getType().visit(arg);
+ }
+ } finally {
+ visiting = false;
+ }
+ }
+
+ public String getStructString() {
+ if (visiting) {
+ if (getName() != null) {
+ return getName();
+ }
+ return "struct {/*Recursive type reference*/}";
+ }
+
+ try {
+ visiting = true;
+ String kind = (isStruct() ? "struct {" : "union {");
+ StringBuffer res = new StringBuffer();
+ res.append(kind);
+ int n = getNumFields();
+ for (int i = 0; i < n; i++) {
+ res.append(" ");
+ res.append(getField(i));
+ }
+ res.append(" }");
+ return res.toString();
+ } finally {
+ visiting = false;
+ }
+ }
+
+ Type newCVVariant(int cvAttributes) {
+ CompoundType t = new CompoundType(getName(), getSize(), kind, cvAttributes, structName);
+ t.fields = fields;
+ return t;
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/CompoundTypeKind.java b/src/net/java/games/gluegen/cgram/types/CompoundTypeKind.java
new file mode 100644
index 000000000..9a1475d70
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/CompoundTypeKind.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+/** Type-safe enum for discriminating between structs and unions,
+ which are both represented as compound types. */
+
+public class CompoundTypeKind {
+ public static final CompoundTypeKind STRUCT = new CompoundTypeKind();
+ public static final CompoundTypeKind UNION = new CompoundTypeKind();
+
+ private CompoundTypeKind() {}
+}
diff --git a/src/net/java/games/gluegen/cgram/types/DoubleType.java b/src/net/java/games/gluegen/cgram/types/DoubleType.java
new file mode 100644
index 000000000..3c2869e58
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/DoubleType.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+/** Represents a double-word floating-point type (C type "double".) */
+
+public class DoubleType extends PrimitiveType {
+ public DoubleType(String name, int size, int cvAttributes) {
+ super(name, size, cvAttributes);
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == this) {
+ return true;
+ }
+ if (arg == null || (!(arg instanceof DoubleType))) {
+ return false;
+ }
+ return super.equals(arg);
+ }
+
+ public DoubleType asDouble() { return this; }
+
+ Type newCVVariant(int cvAttributes) {
+ return new DoubleType(getName(), getSize(), cvAttributes);
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/EnumType.java b/src/net/java/games/gluegen/cgram/types/EnumType.java
new file mode 100644
index 000000000..f85f64e23
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/EnumType.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+import java.util.*;
+
+/** Describes enumerated types. Enumerations are like ints except that
+ they have a set of named values. */
+
+public class EnumType extends IntType {
+ private IntType underlyingType;
+
+ private static class Enum {
+ String name;
+ long value;
+ Enum(String name, long value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ String getName() { return name; }
+ long getValue() { return value; }
+ }
+ private List/*<Enum>*/ enums;
+
+ private static final int longSizeBytes = 8;
+
+ public EnumType(String name) {
+ super(name, longSizeBytes, false, CVAttributes.CONST );
+ this.underlyingType = new IntType(name, longSizeBytes, false, CVAttributes.CONST);
+ }
+
+ public EnumType(String name, int enumSizeBytes) {
+ super(name, enumSizeBytes, false, CVAttributes.CONST );
+ this.underlyingType = new IntType(name, enumSizeBytes, false, CVAttributes.CONST);
+ }
+
+ protected EnumType(String name, IntType underlyingType, int cvAttributes) {
+ super(name, underlyingType.getSize(), underlyingType.isUnsigned(), cvAttributes);
+ this.underlyingType = underlyingType;
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == this) return true;
+ if (arg == null || (!(arg instanceof EnumType))) {
+ return false;
+ }
+ EnumType t = (EnumType) arg;
+ return (super.equals(arg) &&
+ underlyingType.equals(t.underlyingType) &&
+ listsEqual(enums, t.enums));
+ }
+
+ public EnumType asEnum() { return this; }
+
+ public void addEnum(String name, long val) {
+ if (enums == null) {
+ enums = new ArrayList();
+ }
+ enums.add(new Enum(name, val));
+ }
+
+ /** Number of enumerates defined in this enum. */
+ public int getNumEnumerates() { return enums.size(); }
+ /** Fetch <i>i</i>th (0..getNumEnumerates() - 1) name */
+ public String getEnumName(int i) { return ((Enum) enums.get(i)).getName(); }
+ /** Fetch <i>i</i>th (0..getNumEnumerates() - 1) value */
+ public long getEnumValue(int i) { return ((Enum) enums.get(i)).getValue(); }
+ /** Fetch the value of the enumerate with the given name. */
+ public long getEnumValue(String name) {
+ for (int i = 0; i < enums.size(); ++i) {
+ Enum n = ((Enum)enums.get(i));
+ if (n.getName().equals(name)) { return n.getValue(); }
+ }
+ throw new NoSuchElementException(
+ "No enumerate named \"" + name + "\" in EnumType \"" +
+ getName() + "\"");
+ }
+ /** Does this enum type contain an enumerate with the given name? */
+ public boolean containsEnumerate(String name) {
+ for (int i = 0; i < enums.size(); ++i) {
+ if (((Enum)enums.get(i)).getName().equals(name)) { return true; }
+ }
+ return false;
+ }
+ /** Remove the enumerate with the given name. Returns true if it was found
+ * and removed; false if it was not found.
+ */
+ public boolean removeEnumerate(String name) {
+ for (int i = 0; i < enums.size(); ++i) {
+ Enum e = (Enum)enums.get(i);
+ if (e.getName().equals(name)) {
+ enums.remove(e);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void visit(TypeVisitor arg) {
+ super.visit(arg);
+ underlyingType.visit(arg);
+ }
+
+ Type newCVVariant(int cvAttributes) {
+ EnumType t = new EnumType(getName(), underlyingType, cvAttributes);
+ t.enums = enums;
+ return t;
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/Field.java b/src/net/java/games/gluegen/cgram/types/Field.java
new file mode 100644
index 000000000..1c6f6f8a0
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/Field.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+/** Represents a field in a struct or union. */
+
+public class Field {
+ private String name;
+ private Type type;
+ private long offset;
+
+ public Field(String name, Type type, long offset) {
+ this.name = name;
+ this.type = type;
+ this.offset = offset;
+ }
+
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == null || (!(arg instanceof Field))) {
+ return false;
+ }
+
+ Field f = (Field) arg;
+ return (((name != null && name.equals(f.name)) ||
+ (name == null && f.name == null)) &&
+ type.equals(f.type) &&
+ offset == f.offset);
+ }
+
+ /** Name of this field in the containing data structure. */
+ public String getName() { return name; }
+
+ /** Type of this field. */
+ public Type getType() { return type; }
+
+ /** Offset, in bytes, of this field in the containing data structure. */
+ public long getOffset() { return offset; }
+
+ /** Sets the offset of this field in the containing data structure. */
+ public void setOffset(long offset) { this.offset = offset; }
+
+ public String toString() {
+ if (!getType().isFunctionPointer()) {
+ if (getName() == null &&
+ getType().asCompound() != null &&
+ getType().asCompound().isUnion()) {
+ return "" + getType() + ";";
+ }
+ return "" + getType() + " " + getName() + ";";
+ } else {
+ FunctionType ft = getType().asPointer().getTargetType().asFunction();
+ return ft.toString(getName(), true) + ";";
+ }
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/FloatType.java b/src/net/java/games/gluegen/cgram/types/FloatType.java
new file mode 100644
index 000000000..1ad28f1ba
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/FloatType.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+/** Represents a single-word floating-point type (C type "float".) */
+
+public class FloatType extends PrimitiveType {
+ public FloatType(String name, int size, int cvAttributes) {
+ super(name, size, cvAttributes);
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == this) {
+ return true;
+ }
+ if (arg == null || (!(arg instanceof FloatType))) {
+ return false;
+ }
+ return super.equals(arg);
+ }
+
+ public FloatType asFloat() { return this; }
+
+ Type newCVVariant(int cvAttributes) {
+ return new FloatType(getName(), getSize(), cvAttributes);
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/FunctionSymbol.java b/src/net/java/games/gluegen/cgram/types/FunctionSymbol.java
new file mode 100644
index 000000000..491961c5b
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/FunctionSymbol.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+import java.util.*;
+
+/** Describes a function symbol, which includes the name and
+ type. Since we are currently only concerned with processing
+ functions this is the only symbol type, though plausibly more
+ types should be added and a true symbol table constructed during
+ parsing. */
+
+public class FunctionSymbol {
+ private String name;
+ private FunctionType type;
+
+ public FunctionSymbol(String name, FunctionType type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public String getName() { return name; }
+
+ /** Returns the type of this function. Do not add arguments to it
+ directly; use addArgument instead. */
+ public FunctionType getType() { return type; }
+
+ /** Returns the return type of this function. */
+ public Type getReturnType() { return type.getReturnType(); }
+
+ public int getNumArguments() { return type.getNumArguments(); }
+
+ /** Returns the name of the <i>i</i>th argument. May return null if
+ no argument names were available during parsing. */
+ public String getArgumentName(int i) {
+ return type.getArgumentName(i);
+ }
+
+ /** Returns the type of the <i>i</i>th argument. */
+ public Type getArgumentType(int i) {
+ return type.getArgumentType(i);
+ }
+
+ /** Add an argument's name and type. Use null for unknown argument
+ names. */
+ public void addArgument(Type argumentType, String argumentName) {
+ type.addArgument(argumentType, argumentName);
+ }
+
+ public String toString() {
+ return getType().toString(getName());
+ }
+
+ public int hashCode() {
+ if (name == null) {
+ return 0;
+ }
+ return name.hashCode();
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == this) {
+ return true;
+ }
+
+ if (arg == null || (!(arg instanceof FunctionSymbol))) {
+ return false;
+ }
+
+ FunctionSymbol other = (FunctionSymbol) arg;
+ return (
+ (getName() == other.getName() || getName().equals(other.getName()))
+ && type.equals(other.type));
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/FunctionType.java b/src/net/java/games/gluegen/cgram/types/FunctionType.java
new file mode 100644
index 000000000..f864b4d2c
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/FunctionType.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+import java.util.*;
+
+/** Describes a function type, used to model both function
+ declarations and (via PointerType) function pointers. */
+
+public class FunctionType extends Type {
+ private Type returnType;
+ private ArrayList argumentTypes;
+ private ArrayList argumentNames;
+
+ public FunctionType(String name, int size, Type returnType, int cvAttributes) {
+ super(name, size, cvAttributes);
+ this.returnType = returnType;
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == this) return true;
+ if (arg == null || (!(arg instanceof FunctionType))) {
+ return false;
+ }
+ FunctionType t = (FunctionType) arg;
+ return (super.equals(arg) &&
+ returnType.equals(t.returnType) &&
+ listsEqual(argumentTypes, t.argumentTypes));
+ }
+
+ public FunctionType asFunction() { return this; }
+
+ /** Returns the return type of this function. */
+ public Type getReturnType() { return returnType; }
+
+ public int getNumArguments() { return ((argumentTypes == null) ? 0 : argumentTypes.size()); }
+
+ /** Returns the name of the <i>i</i>th argument. May return null if
+ no argument names were available during parsing. */
+ public String getArgumentName(int i) {
+ return (String) argumentNames.get(i);
+ }
+
+ /** Returns the type of the <i>i</i>th argument. */
+ public Type getArgumentType(int i) {
+ return (Type) argumentTypes.get(i);
+ }
+
+ /** Add an argument's name and type. Use null for unknown argument
+ names. */
+ public void addArgument(Type argumentType, String argumentName) {
+ if (argumentTypes == null) {
+ argumentTypes = new ArrayList();
+ argumentNames = new ArrayList();
+ }
+ argumentTypes.add(argumentType);
+ argumentNames.add(argumentName);
+ }
+
+ public String toString() {
+ return toString(null);
+ }
+
+ public String toString(String functionName) {
+ return toString(functionName, false);
+ }
+
+ String toString(String functionName, boolean isPointer) {
+ StringBuffer res = new StringBuffer();
+ res.append(getReturnType());
+ res.append(" ");
+ if (isPointer) {
+ res.append("(*");
+ }
+ if (functionName != null) {
+ res.append(functionName);
+ }
+ if (isPointer) {
+ res.append(")");
+ }
+ res.append("(");
+ int n = getNumArguments();
+ for (int i = 0; i < n; i++) {
+ Type t = getArgumentType(i);
+ if (t.isFunctionPointer()) {
+ FunctionType ft = t.asPointer().getTargetType().asFunction();
+ res.append(ft.toString(getArgumentName(i), true));
+ } else if (t.isArray()) {
+ res.append(t.asArray().toString(getArgumentName(i)));
+ } else {
+ res.append(t);
+ String argumentName = getArgumentName(i);
+ if (argumentName != null) {
+ res.append(" ");
+ res.append(argumentName);
+ }
+ }
+ if (i < n - 1) {
+ res.append(", ");
+ }
+ }
+ res.append(")");
+ if (!isPointer) {
+ res.append(";");
+ }
+ return res.toString();
+ }
+
+ public void visit(TypeVisitor arg) {
+ super.visit(arg);
+ returnType.visit(arg);
+ int n = getNumArguments();
+ for (int i = 0; i < n; i++) {
+ getArgumentType(i).visit(arg);
+ }
+ }
+
+ Type newCVVariant(int cvAttributes) {
+ // Functions don't have const/volatile attributes
+ return this;
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/IntType.java b/src/net/java/games/gluegen/cgram/types/IntType.java
new file mode 100644
index 000000000..84f9b4c13
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/IntType.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+public class IntType extends PrimitiveType {
+ private boolean unsigned;
+ private boolean typedefedUnsigned;
+
+ public IntType(String name, int size, boolean unsigned, int cvAttributes) {
+ this(name, size, unsigned, cvAttributes, false);
+ }
+
+ private IntType(String name, int size, boolean unsigned, int cvAttributes, boolean typedefedUnsigned) {
+ super(name, size, cvAttributes);
+ this.unsigned = unsigned;
+ this.typedefedUnsigned = typedefedUnsigned;
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == this) return true;
+ if (arg == null || (!(arg instanceof IntType))) {
+ return false;
+ }
+ IntType t = (IntType) arg;
+ return (super.equals(arg) && (unsigned == t.unsigned));
+ }
+
+ public void setName(String name) {
+ super.setName(name);
+ typedefedUnsigned = unsigned;
+ }
+
+ public IntType asInt() { return this; }
+
+ /** Indicates whether this type is unsigned */
+ public boolean isUnsigned() { return unsigned; }
+
+ public String toString() {
+ return getCVAttributesString() + ((isUnsigned() & (!typedefedUnsigned)) ? "unsigned " : "") + getName();
+ }
+
+ Type newCVVariant(int cvAttributes) {
+ return new IntType(getName(), getSize(), isUnsigned(), cvAttributes, typedefedUnsigned);
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/MachineDescription.java b/src/net/java/games/gluegen/cgram/types/MachineDescription.java
new file mode 100644
index 000000000..3db50d554
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/MachineDescription.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+public class MachineDescription {
+ private int charSizeInBytes;
+ private int shortSizeInBytes;
+ private int intSizeInBytes;
+ private int longSizeInBytes;
+ private int int64SizeInBytes;
+ private int floatSizeInBytes;
+ private int doubleSizeInBytes;
+ private int pointerSizeInBytes;
+
+ public MachineDescription(int charSizeInBytes,
+ int shortSizeInBytes,
+ int intSizeInBytes,
+ int longSizeInBytes,
+ int int64SizeInBytes,
+ int floatSizeInBytes,
+ int doubleSizeInBytes,
+ int pointerSizeInBytes) {
+ this.charSizeInBytes = charSizeInBytes;
+ this.shortSizeInBytes = shortSizeInBytes;
+ this.intSizeInBytes = intSizeInBytes;
+ this.longSizeInBytes = longSizeInBytes;
+ this.int64SizeInBytes = int64SizeInBytes;
+ this.floatSizeInBytes = floatSizeInBytes;
+ this.doubleSizeInBytes = doubleSizeInBytes;
+ this.pointerSizeInBytes = pointerSizeInBytes;
+ }
+
+ public int charSizeInBytes() { return charSizeInBytes; }
+ public int shortSizeInBytes() { return shortSizeInBytes; }
+ public int intSizeInBytes() { return intSizeInBytes; }
+ public int longSizeInBytes() { return longSizeInBytes; }
+ public int int64SizeInBytes() { return int64SizeInBytes; }
+ public int floatSizeInBytes() { return floatSizeInBytes; }
+ public int doubleSizeInBytes() { return doubleSizeInBytes; }
+ public int pointerSizeInBytes() { return pointerSizeInBytes; }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/MachineDescription32Bit.java b/src/net/java/games/gluegen/cgram/types/MachineDescription32Bit.java
new file mode 100644
index 000000000..337747047
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/MachineDescription32Bit.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+public class MachineDescription32Bit extends MachineDescription {
+ public MachineDescription32Bit() {
+ super(1, 2, 4, 4, 8, 4, 8, 4);
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/PointerType.java b/src/net/java/games/gluegen/cgram/types/PointerType.java
new file mode 100644
index 000000000..62bfe9c1a
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/PointerType.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+public class PointerType extends Type {
+ private Type targetType;
+ private String computedName;
+ private boolean hasTypedefedName;
+
+ public PointerType(int size, Type targetType, int cvAttributes) {
+ // can pass null for the final name parameter because the PointerType's getName()
+ // completely replaces superclass behavior
+ this(size, targetType, cvAttributes, false, null);
+ }
+
+ private PointerType(int size, Type targetType, int cvAttributes, boolean hasTypedefedName, String typedefedName) {
+ super(targetType.getName() + " *", size, cvAttributes);
+ this.hasTypedefedName = false;
+ this.targetType = targetType;
+ if (hasTypedefedName) {
+ setName(typedefedName);
+ }
+ }
+
+ public int hashCode() {
+ return targetType.hashCode();
+ }
+
+ public boolean equals(Object arg) {
+ if (arg == this) return true;
+ if (arg == null || (!(arg instanceof PointerType))) {
+ return false;
+ }
+ PointerType t = (PointerType) arg;
+ // Note we ignore the name of this type (which might be a typedef
+ // name) for comparison purposes because this is what allows
+ // e.g. a newly-fabricated type "PIXELFORMATDESCRIPTOR *" to be
+ // canonicalized to e.g. "LPPIXELFORMATDESCRIPTOR"
+ return ((getSize() == t.getSize()) &&
+ (getCVAttributes() == t.getCVAttributes()) &&
+ targetType.equals(t.targetType));
+ }
+
+ public void setName(String name) {
+ super.setName(name);
+ hasTypedefedName = true;
+ }
+
+ public String getName(boolean includeCVAttrs) {
+ if (hasTypedefedName) {
+ return super.getName(includeCVAttrs);
+ } else {
+ // Lazy computation of name due to lazy setting of compound type
+ // names during parsing
+ if (computedName == null) {
+ computedName = targetType.getName(includeCVAttrs) + " *";
+ computedName = computedName.intern();
+ }
+ if (!includeCVAttrs) {
+ return computedName;
+ }
+ return targetType.getName(includeCVAttrs) + " * " + getCVAttributesString();
+ }
+ }
+
+ public PointerType asPointer() { return this; }
+
+ public Type getTargetType() { return targetType; }
+
+ public boolean isFunctionPointer() { return targetType.isFunction(); }
+
+ public String toString() {
+ if (hasTypedefedName) {
+ return super.getName(true);
+ } else {
+ if (!targetType.isFunction()) {
+ return targetType.toString() + " * " + getCVAttributesString();
+ }
+ return toString(null); // this is a pointer to an unnamed function
+ }
+ }
+
+ /** For use only when printing function pointers */
+ public String toString(String functionName) {
+ if (!targetType.isFunction()) {
+ throw new RuntimeException("<Internal error or misuse> This method is only for use when printing function pointers");
+ }
+ return ((FunctionType) targetType).toString(functionName, true);
+ }
+
+ public void visit(TypeVisitor arg) {
+ super.visit(arg);
+ targetType.visit(arg);
+ }
+
+ Type newCVVariant(int cvAttributes) {
+ return new PointerType(getSize(), targetType, cvAttributes, hasTypedefedName, (hasTypedefedName ? getName() : null));
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/PrimitiveType.java b/src/net/java/games/gluegen/cgram/types/PrimitiveType.java
new file mode 100644
index 000000000..7b41510df
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/PrimitiveType.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+public abstract class PrimitiveType extends Type {
+ protected PrimitiveType(String name, int size, int cvAttributes) {
+ super(name, size, cvAttributes);
+ }
+
+ public boolean isPrimitive() {
+ return true;
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/Type.java b/src/net/java/games/gluegen/cgram/types/Type.java
new file mode 100644
index 000000000..531393aa5
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/Type.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+import java.util.List;
+
+/** Models a C type. Primitive types include int, float, and
+ double. All types have an associated name. Structs and unions are
+ modeled as "compound" types -- composed of fields of primitive or
+ other types. */
+
+public abstract class Type {
+ private String name;
+ private int size;
+ private int cvAttributes;
+ private int typedefedCVAttributes;
+ private boolean hasTypedefName;
+
+ protected Type(String name, int size, int cvAttributes) {
+ setName(name);
+ this.size = size;
+ this.cvAttributes = cvAttributes;
+ hasTypedefName = false;
+ }
+
+ /** Returns the name of this type. The returned string is suitable
+ for use as a type specifier. Does not include any const/volatile
+ attributes. */
+ public String getName() { return getName(false); }
+
+ /** Returns the name of this type, optionally including
+ const/volatile attributes. The returned string is suitable for
+ use as a type specifier. */
+ public String getName(boolean includeCVAttrs) {
+ if (!includeCVAttrs) {
+ return name;
+ }
+ return getCVAttributesString() + name;
+ }
+
+ /** Set the name of this type; used for handling typedefs. */
+ public void setName(String name) {
+ if (name == null) {
+ this.name = name;
+ } else {
+ this.name = name.intern();
+ }
+ // 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;
+ }
+
+ /** Size of this type in bytes. */
+ public int getSize() { return size; }
+ /** Set the size of this type; only available for CompoundTypes. */
+ void setSize(int size) { this.size = size; }
+
+ /** Casts this to a BitType or returns null if not a BitType. */
+ public BitType asBit() { return null; }
+ /** Casts this to an IntType or returns null if not an IntType. */
+ public IntType asInt() { return null; }
+ /** Casts this to an EnumType or returns null if not an EnumType. */
+ public EnumType asEnum() { return null; }
+ /** Casts this to a FloatType or returns null if not a FloatType. */
+ public FloatType asFloat() { return null; }
+ /** Casts this to a DoubleType or returns null if not a DoubleType. */
+ public DoubleType asDouble() { return null; }
+ /** Casts this to a PointerType or returns null if not a PointerType. */
+ public PointerType asPointer() { return null; }
+ /** Casts this to an ArrayType or returns null if not an ArrayType. */
+ public ArrayType asArray() { return null; }
+ /** Casts this to a CompoundType or returns null if not a CompoundType. */
+ public CompoundType asCompound() { return null; }
+ /** Casts this to a FunctionType or returns null if not a FunctionType. */
+ public FunctionType asFunction() { return null; }
+ /** Casts this to a VoidType or returns null if not a VoidType. */
+ public VoidType asVoid() { return null; }
+
+ /** Indicates whether this is a BitType. */
+ public boolean isBit() { return (asBit() != null); }
+ /** Indicates whether this is an IntType. */
+ public boolean isInt() { return (asInt() != null); }
+ /** Indicates whether this is an EnumType. */
+ public boolean isEnum() { return (asEnum() != null); }
+ /** Indicates whether this is a FloatType. */
+ public boolean isFloat() { return (asFloat() != null); }
+ /** Indicates whether this is a DoubleType. */
+ public boolean isDouble() { return (asDouble() != null); }
+ /** Indicates whether this is a PointerType. */
+ public boolean isPointer() { return (asPointer() != null); }
+ /** Indicates whether this is an ArrayType. */
+ public boolean isArray() { return (asArray() != null); }
+ /** Indicates whether this is a CompoundType. */
+ public boolean isCompound() { return (asCompound() != null); }
+ /** Indicates whether this is a FunctionType. */
+ public boolean isFunction() { return (asFunction() != null); }
+ /** Indicates whether this is a VoidType. */
+ public boolean isVoid() { return (asVoid() != null); }
+
+ /** Indicates whether this type is const. */
+ public boolean isConst() { return (((cvAttributes & ~typedefedCVAttributes) & CVAttributes.CONST) != 0); }
+ /** Indicates whether this type is volatile. */
+ public boolean isVolatile() { return (((cvAttributes & ~typedefedCVAttributes) & CVAttributes.VOLATILE) != 0); }
+
+ /** Indicates whether this type is a primitive type. */
+ public boolean isPrimitive(){ return false; }
+
+ /** Convenience routine indicating whether this Type is a pointer to
+ a function. */
+ public boolean isFunctionPointer() {
+ return (isPointer() && asPointer().getTargetType().isFunction());
+ }
+
+ /** Hashcode for Types. */
+ public int hashCode() {
+ if (name == null) {
+ return 0;
+ }
+
+ if (cvAttributes != 0)
+ {
+ String nameWithAttribs = name + cvAttributes;
+ return nameWithAttribs.hashCode();
+ }
+ return name.hashCode();
+ }
+
+ /**
+ * Equality test for Types.
+ */
+ public boolean equals(Object arg) {
+ if (arg == this) {
+ return true;
+ }
+ if (arg == null || (!(arg instanceof Type))) {
+ return false;
+ }
+ Type t = (Type) arg;
+ return ((name == t.name || (name != null && name.equals(name))) &&
+ (size == t.size) &&
+ (cvAttributes == t.cvAttributes));
+ }
+
+ /** Returns a string representation of this type. This string is not
+ necessarily suitable for use as a type specifier; for example,
+ it will contain an expanded description of structs/unions. */
+ public String toString() {
+ return getName(true);
+ }
+
+ /** Visit this type and all of the component types of this one; for
+ example, the return type and argument types of a FunctionType. */
+ public void visit(TypeVisitor visitor) {
+ visitor.visitType(this);
+ }
+
+ public final int getCVAttributes() {
+ return cvAttributes;
+ }
+
+ /** Returns a string indicating the const/volatile attributes of
+ this type. */
+ public final String getCVAttributesString() {
+ if (isConst() && isVolatile()) return "const volatile ";
+ if (isConst()) return "const ";
+ if (isVolatile()) return "volatile ";
+ return "";
+ }
+
+ /** Return a variant of this type matching the given const/volatile
+ attributes. May return this object if the attributes match. */
+ public final Type getCVVariant(int cvAttributes) {
+ if (this.cvAttributes == cvAttributes) {
+ return this;
+ }
+ return newCVVariant(cvAttributes);
+ }
+
+ /** Create a new variant of this type matching the given
+ const/volatile attributes. */
+ abstract Type newCVVariant(int cvAttributes);
+
+ /** Indicates whether setName() has been called on this type,
+ indicating that it already has a typedef name. */
+ public boolean hasTypedefName() {
+ return hasTypedefName;
+ }
+
+ /** Helper method for determining how many pointer indirections this
+ type represents (i.e., "void **" returns 2). */
+ public int pointerDepth() {
+ PointerType pt = asPointer();
+ if (pt == null) {
+ return 0;
+ }
+ return 1 + pt.getTargetType().pointerDepth();
+ }
+
+ /** Helper routine for list equality comparison */
+ static boolean listsEqual(List a, List b) {
+ return ((a == null && b == null) ||
+ (a != null && b != null && a.equals(b)));
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/TypeDictionary.java b/src/net/java/games/gluegen/cgram/types/TypeDictionary.java
new file mode 100644
index 000000000..bbf69b3c9
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/TypeDictionary.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+import java.util.*;
+
+/** Utility class for recording names of typedefs and structs. */
+
+public class TypeDictionary {
+ /** Mapping from type name to type.*/
+ private HashMap/*<String, Type>*/ map = new HashMap/*<String, Type>*/();
+
+ /** Reverse mapping; created lazily from the regular map */
+ private HashMap/*<Set<Type>, String>*/ reverseMap = new HashMap/*<Set<Type>, String>*/();
+
+ /** Has a type been added/removed since the last time the reverse map was
+ * calculated? */
+ private boolean reverseMapOutOfDate = false;
+
+ /**
+ * Create a mapping from a type to its name.
+ * @param name the name to which the type is defined
+ * @param type the type that can be referred to by the specified name.
+ */
+ public Type put(String name, Type type) {
+ reverseMapOutOfDate = true;
+ return (Type) map.put(name, type);
+ }
+
+ /** Get the type corresponding to the given name. Returns null if no type
+ * was found corresponding to the given name. */
+ public Type get(String name) {
+ return (Type) map.get(name);
+ }
+
+ /**
+ * Get the names that correspond to the given type. There will be more than
+ * one name in the returned list if the type has been defined to multiple
+ * names. Returns null if no names were found for given type.
+ */
+ public Set/*<String>*/ get(Type type) {
+ if (reverseMapOutOfDate) {
+ rebuildReverseMap();
+ reverseMapOutOfDate = false;
+ }
+ // Don't let callers muck with the set.
+ return Collections.unmodifiableSet((Set)reverseMap.get(type));
+ }
+
+ /** Remove the mapping from the specified name to its associated type.*/
+ public Type remove(String name) {
+ reverseMapOutOfDate = true;
+ return (Type) map.remove(name);
+ }
+
+ /** Get all the names that map to Types.
+ * @returns a Set of Strings that are the typedef names that map to Types in the dictionary.
+ */
+ public Set keySet() {
+ return map.keySet();
+ }
+
+ public Set entrySet() {
+ return map.entrySet();
+ }
+
+ public boolean containsKey(String key) {
+ return map.containsKey(key);
+ }
+
+ public boolean containsValue(Type value) {
+ return map.containsValue(value);
+ }
+
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ /** Returns a collection of all the Types in the dictionary that are mapped via typedefs names. */
+ public Collection values() {
+ return map.values();
+ }
+
+ /** Build the mapping of from each Type to all the names by which is may be
+ * referenced. Warning: this is a slow operation!
+ */
+ private void rebuildReverseMap() {
+ reverseMap.clear();
+ for (Iterator/*<String>*/ it = map.keySet().iterator(); it.hasNext(); ) {
+ String name = (String)it.next();
+ Type type = (Type)map.get(name);
+ if (type == null) {
+ throw new IllegalStateException("Internal error; TypedefDictionary contains null Type for name \"" + name + "\"");
+ }
+ HashSet allNamesForType = (HashSet)reverseMap.get(type);
+ if (allNamesForType == null) {
+ allNamesForType = new HashSet/*<String>*/();
+ reverseMap.put(type, allNamesForType);
+ }
+ allNamesForType.add(name);
+ }
+ }
+
+ /**
+ * Dumps the dictionary contents to the specified output stream, annotated
+ * with the specified description. Useful for debugging.
+ */
+ public void dumpDictionary(java.io.PrintStream out, String description) {
+ out.println("------------------------------------------------------------------------------");
+ out.println("TypeDictionary: " + (description == null ? "" : description));
+ out.println("------------------------------------------------------------------------------");
+ out.println("Forward mapping: ");
+ for (Iterator names = keySet().iterator(); names.hasNext(); ) {
+ String typeName = (String)names.next();
+ out.println(" [" + typeName + "]\t--> [" + get(typeName) + "]");
+ }
+ out.println("Reverse mapping: ");
+
+ // because the reverse mapping is built lazily upon query, we must force it to
+ // be built if it has not yet been built.
+ if (reverseMapOutOfDate) {
+ rebuildReverseMap();
+ reverseMapOutOfDate = false;
+ }
+ for (Iterator types = reverseMap.keySet().iterator(); types.hasNext(); ) {
+ Type type = (Type)types.next();
+ Set names = get(type);
+ out.println(" [" + type + "]\t--> " + names + "");
+ }
+ out.println("------------------------------------------------------------------------------");
+ }
+}
diff --git a/src/net/java/games/gluegen/cgram/types/TypeVisitor.java b/src/net/java/games/gluegen/cgram/types/TypeVisitor.java
new file mode 100644
index 000000000..e0bc57ed4
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/TypeVisitor.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+public interface TypeVisitor {
+ public void visitType(Type t);
+}
diff --git a/src/net/java/games/gluegen/cgram/types/VoidType.java b/src/net/java/games/gluegen/cgram/types/VoidType.java
new file mode 100644
index 000000000..948c156c0
--- /dev/null
+++ b/src/net/java/games/gluegen/cgram/types/VoidType.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.cgram.types;
+
+public class VoidType extends Type {
+ public VoidType(int cvAttributes) {
+ this("void", cvAttributes);
+ }
+
+ private VoidType(String name, int cvAttributes) {
+ super(name, 0, cvAttributes);
+ }
+
+ public VoidType asVoid() { return this; }
+
+ Type newCVVariant(int cvAttributes) {
+ return new VoidType(getName(), cvAttributes);
+ }
+}