Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Parser_SymbolTable: Changes for Type safety and for Pointer Operators


Core:
Changes for stronger type safety in TypeInfo
Changes for better handling of Pointer Operators and CV Qualifiers

UI:
Updated ParserSymbolTable tests to reflect the above changes

-Andrew
 
Index: parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java,v
retrieving revision 1.13.2.3
diff -u -r1.13.2.3 ParserSymbolTableTest.java
--- parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java	14 May 2003 20:12:30 -0000	1.13.2.3
+++ parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java	20 May 2003 15:04:49 -0000
@@ -26,6 +26,7 @@
 //import org.eclipse.cdt.internal.core.pst.ParserSymbolTable.Declaration;
 import org.eclipse.cdt.internal.core.pst.ParserSymbolTable.Mark;
 import org.eclipse.cdt.internal.core.pst.ParserSymbolTable.TypeInfo;
+import org.eclipse.cdt.internal.core.pst.ParserSymbolTable.TypeInfo.PtrOp;
 
 /**
  * @author aniefer
@@ -1100,7 +1101,7 @@
 		ParserSymbolTable.Declaration f1 = table.new Declaration( "f" );
 		f1.setType( ParserSymbolTable.TypeInfo.t_function );
 		f1.setReturnType( ParserSymbolTable.TypeInfo.t_void );
-		f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, "", false );
+		f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false );
 		A.addSymbol( f1 );
 		
 		ISymbol look = compUnit.LookupNestedNameSpecifier("A");
@@ -1114,7 +1115,7 @@
 		IParameterizedSymbol f2 = table.newParameterizedSymbol("f");
 		f2.setType( ParserSymbolTable.TypeInfo.t_function );
 		f2.setReturnType( ParserSymbolTable.TypeInfo.t_void );
-		f2.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, "", false );
+		f2.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, null, false );
 		
 		A.addSymbol( f2 );
 		
@@ -1123,7 +1124,7 @@
 		compUnit.addSymbol( foo );
 
 		LinkedList paramList = new LinkedList();
-		ParserSymbolTable.TypeInfo param = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, null );
+		ParserSymbolTable.TypeInfo param = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, 0, null );
 		paramList.add( param );
 		
 		look = foo.UnqualifiedFunctionLookup( "f", paramList );
@@ -1160,7 +1161,8 @@
 		
 		IParameterizedSymbol fn = table.newParameterizedSymbol("function");
 		fn.setType( ParserSymbolTable.TypeInfo.t_function );
-		fn.setCVQualifier( ParserSymbolTable.TypeInfo.cvConst );
+		fn.getTypeInfo().addPtrOperator( new PtrOp( PtrOp.t_undef, true, false ) );
+		//fn.setCVQualifier( ParserSymbolTable.TypeInfo.cvConst );
 		
 		table.getCompilationUnit().addSymbol( cls );
 		cls.addSymbol( fn );
@@ -1170,8 +1172,8 @@
 		
 		assertEquals( look.getType(), ParserSymbolTable.TypeInfo.t_type );
 		assertEquals( look.getTypeSymbol(), cls );
-		assertEquals( look.getPtrOperator(), "*" );
-		assertEquals( look.getCVQualifier(), fn.getCVQualifier() );
+		assertEquals( ((PtrOp)look.getPtrOperators().getFirst()).getType(), TypeInfo.PtrOp.t_pointer );
+		assertTrue( ((PtrOp)look.getPtrOperators().getFirst()).isConst() );
 		assertEquals( look.getContainingSymbol(), fn );
 	}
 	
@@ -1239,7 +1241,7 @@
 		
 		ISymbol look = NS.Lookup( "T" );
 		assertEquals( look, T );				
-		f.addParameter( look, 0, "", false );
+		f.addParameter( look, null, false );
 		
 		NS.addSymbol( f );	
 				
@@ -1261,7 +1263,7 @@
 		LinkedList paramList = new LinkedList();
 		look = main.Lookup( "parm" );
 		assertEquals( look, param );
-		ParserSymbolTable.TypeInfo p = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, look, 0, null, false );
+		ParserSymbolTable.TypeInfo p = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, look );
 		paramList.add( p );
 		
 		look = main.UnqualifiedFunctionLookup( "f", paramList );
@@ -1304,7 +1306,7 @@
 		ParserSymbolTable.Declaration f1 = table.new Declaration( "f" );
 		f1.setType( ParserSymbolTable.TypeInfo.t_function );
 		f1.setReturnType( ParserSymbolTable.TypeInfo.t_void );
-		f1.addParameter( ParserSymbolTable.TypeInfo.t_void, 0, "*", false );
+		f1.addParameter( ParserSymbolTable.TypeInfo.t_void, 0, new PtrOp( PtrOp.t_pointer ), false );
 		NS1.addSymbol( f1 );
 		
 		IContainerSymbol NS2 = table.newContainerSymbol( "NS2" );
@@ -1323,7 +1325,7 @@
 		IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" );
 		f2.setType( ParserSymbolTable.TypeInfo.t_function );
 		f2.setReturnType( ParserSymbolTable.TypeInfo.t_void );
-		f2.addParameter( ParserSymbolTable.TypeInfo.t_void, 0, "*", false );
+		f2.addParameter( ParserSymbolTable.TypeInfo.t_void, 0, new PtrOp( PtrOp.t_pointer ), false );
 		NS2.addSymbol( f2 );
 		
 		IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" );
@@ -1347,7 +1349,7 @@
 		LinkedList paramList = new LinkedList();
 		look = compUnit.Lookup( "a" );
 		assertEquals( look, a );
-		ParserSymbolTable.TypeInfo param = new ParserSymbolTable.TypeInfo( look.getType(), look, 0, "&", false );
+		ParserSymbolTable.TypeInfo param = new ParserSymbolTable.TypeInfo( look.getType(), 0, look, new PtrOp( PtrOp.t_reference ), false );
 		paramList.add( param );
 		
 		look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
@@ -1386,22 +1388,22 @@
 		IParameterizedSymbol f1 = table.newParameterizedSymbol("foo");
 		f1.setType( ParserSymbolTable.TypeInfo.t_function );
 		f1.setReturnType( ParserSymbolTable.TypeInfo.t_void );
-		f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, "", false );
+		f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false );
 		C.addSymbol( f1 );
 		
 		IParameterizedSymbol f2 = table.newParameterizedSymbol("foo");
 		f2.setType( ParserSymbolTable.TypeInfo.t_function );
 		f2.setReturnType( ParserSymbolTable.TypeInfo.t_void );
-		f2.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, "", false );
-		f2.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, "", false );
+		f2.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false );
+		f2.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, null, false );
 		C.addSymbol( f2 );
 		
 		IParameterizedSymbol f3 = table.newParameterizedSymbol("foo");
 		f3.setType( ParserSymbolTable.TypeInfo.t_function );
 		f3.setReturnType( ParserSymbolTable.TypeInfo.t_void );
-		f3.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, "", false );
-		f3.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, "", false );
-		f3.addParameter( C, 0, "*", false );
+		f3.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false );
+		f3.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, null, false );
+		f3.addParameter( C, new PtrOp( PtrOp.t_pointer ), false );
 		C.addSymbol( f3 );
 		
 		ISymbol look = compUnit.Lookup("C");
@@ -1410,7 +1412,7 @@
 		ISymbol c = table.newSymbol("c");
 		c.setType( ParserSymbolTable.TypeInfo.t_type );
 		c.setTypeSymbol( look );
-		c.setPtrOperator( "*" );
+		c.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
 		compUnit.addSymbol( c );
 		
 		look = compUnit.Lookup( "c" );
@@ -1418,9 +1420,10 @@
 		assertEquals( look.getTypeSymbol(), C );
 		
 		LinkedList paramList = new LinkedList();
-		ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_int, null, 0, "", false);
-		ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, null, 0, "", false);
-		ParserSymbolTable.TypeInfo p3 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, c, 0, "", false);
+															  
+		ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_int, 0, null );
+		ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, 0, null );
+		ParserSymbolTable.TypeInfo p3 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, c );
 		
 		paramList.add( p1 );
 		look = C.MemberFunctionLookup( "foo", paramList );
@@ -1454,29 +1457,29 @@
 		
 		IParameterizedSymbol f1 = table.newParameterizedSymbol("f");
 		f1.setType( ParserSymbolTable.TypeInfo.t_function );
-		f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, "", false );
+		f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false );
 		compUnit.addSymbol( f1 );
 		
 		IParameterizedSymbol f2 = table.newParameterizedSymbol("f");
 		f2.setType( ParserSymbolTable.TypeInfo.t_function );
-		f2.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, "", true );
+		f2.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, null, true );
 		compUnit.addSymbol( f2 );
 		
 		LinkedList paramList = new LinkedList();
-		ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_int, null, 0, "", false );
+		ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_int, 0, null );
 		paramList.add( p1 );
 		
 		ISymbol look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f1 );
 		
 		paramList.clear();
-		ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, null, 0, "", false );
+		ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, 0, null );
 		paramList.add( p2 );
 		look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f2 );
 		
 		paramList.clear();
-		ParserSymbolTable.TypeInfo p3 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_bool, null, 0, "", false );
+		ParserSymbolTable.TypeInfo p3 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_bool, 0, null );
 		paramList.add( p3 );
 		look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f1 );
@@ -1523,32 +1526,32 @@
 		
 		IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" );
 		f1.setType( ParserSymbolTable.TypeInfo.t_function );
-		f1.addParameter( A, 0, "*", false );
+		f1.addParameter( A, new PtrOp( PtrOp.t_pointer ), false );
 		compUnit.addSymbol( f1 );
 		
 		IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" );
 		f2.setType( ParserSymbolTable.TypeInfo.t_function );
-		f2.addParameter( B, 0, "*", false );
+		f2.addParameter( B, new PtrOp( PtrOp.t_pointer ), false );
 		compUnit.addSymbol( f2 );
 		
 		ISymbol a = table.newSymbol( "a" );
 		a.setType( ParserSymbolTable.TypeInfo.t_type );
 		a.setTypeSymbol( A );
-		a.setPtrOperator( "*" );
+		a.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
 		
 		ISymbol c = table.newSymbol( "c" );
 		c.setType( ParserSymbolTable.TypeInfo.t_type );
 		c.setTypeSymbol( C );
-		c.setPtrOperator( "*" );
+		c.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
 		
 		LinkedList paramList = new LinkedList();
-		ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, a, 0, null, false );
+		ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, a );
 		paramList.add( p1 );
 		ISymbol look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f1 );
 		
 		paramList.clear();
-		ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, c, 0, "", false );
+		ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, c );
 		paramList.add( p2 );
 		look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f2 );
@@ -1586,17 +1589,17 @@
 		ISymbol B = table.newSymbol( "B" );
 		B.setType( ParserSymbolTable.TypeInfo.t_type );
 		B.setTypeSymbol( A );
-		B.setPtrOperator( "*" );
+		B.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
 		compUnit.addSymbol( B );
 		
 		IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" );
 		f1.setType( ParserSymbolTable.TypeInfo.t_function );
-		f1.addParameter( A, 0, "*", false );
+		f1.addParameter( A, new PtrOp( PtrOp.t_pointer ), false );
 		compUnit.addSymbol( f1 );
 		
 		IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" );
 		f2.setType( ParserSymbolTable.TypeInfo.t_function );
-		f2.addParameter( A, 0, null, false );
+		f2.addParameter( A, null, false );
 		compUnit.addSymbol( f2 );
 
 		ISymbol a = table.newSymbol( "a" );
@@ -1612,30 +1615,30 @@
 		ISymbol array = table.newSymbol( "array" );
 		array.setType( ParserSymbolTable.TypeInfo.t_type );
 		array.setTypeSymbol( A );
-		array.setPtrOperator( "[]" );
+		array.addPtrOperator( new PtrOp( PtrOp.t_array, false, false ) );
 				
 		LinkedList paramList = new LinkedList();
-		ParserSymbolTable.TypeInfo p = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, a, 0, null, false );
+		ParserSymbolTable.TypeInfo p = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, a );
 		paramList.add( p );
 		
 		ISymbol look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f2 );
 		
-		p.setPtrOperator( "&" );
+		p.addPtrOperator( new PtrOp( PtrOp.t_reference, false, false ) );
 		look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f1 );
 		
 		p.setTypeSymbol( b );
-		p.setPtrOperator( null );
+		p.getPtrOperators().clear();
 		look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f1 );
 		
-		p.setPtrOperator( "*" );
+		p.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
 		look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f2 );
 		
 		p.setTypeSymbol( array );
-		p.setPtrOperator( null );
+		p.getPtrOperators().clear();
 		look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f1 );
 		
@@ -1673,12 +1676,12 @@
 		//12.1-1 "Constructors do not have names"
 		IParameterizedSymbol constructor = table.newParameterizedSymbol("");
 		constructor.setType( ParserSymbolTable.TypeInfo.t_function );
-		constructor.addParameter( A, 0, null, false );
+		constructor.addParameter( A, null, false );
 		B.addSymbol( constructor );
 		
 		IParameterizedSymbol f = table.newParameterizedSymbol( "f" );
 		f.setType( ParserSymbolTable.TypeInfo.t_function );
-		f.addParameter( B, 0, null, false );
+		f.addParameter( B, null, false );
 		compUnit.addSymbol( f );
 		
 		ISymbol a = table.newSymbol( "a" );
@@ -1687,7 +1690,7 @@
 		compUnit.addSymbol( a );
 		
 		LinkedList paramList = new LinkedList();
-		ParserSymbolTable.TypeInfo p = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, a, 0, null, false );
+		ParserSymbolTable.TypeInfo p = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, a );
 		paramList.add( p );
 		
 		ISymbol look = compUnit.UnqualifiedFunctionLookup( "f", paramList );
@@ -1722,14 +1725,14 @@
 		
 		IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" );
 		f1.setType( ParserSymbolTable.TypeInfo.t_function );
-		f1.addParameter( ParserSymbolTable.TypeInfo.t_int, ParserSymbolTable.TypeInfo.cvConst, "*", false );
-		f1.addParameter( ParserSymbolTable.TypeInfo.t_int | ParserSymbolTable.TypeInfo.isShort, 0, null, false );
+		f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, new PtrOp( PtrOp.t_pointer, true, false ), false );
+		f1.addParameter( ParserSymbolTable.TypeInfo.t_int, ParserSymbolTable.TypeInfo.isShort, null, false );
 		
 		compUnit.addSymbol( f1 );
 		
 		IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" );
 		f2.setType( ParserSymbolTable.TypeInfo.t_function );
-		f2.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, "*", false );
+		f2.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, new PtrOp( PtrOp.t_pointer ), false );
 		f2.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false );
 		compUnit.addSymbol( f2 );
 		
@@ -1747,8 +1750,8 @@
 		compUnit.addSymbol( main );
 		
 		LinkedList params = new LinkedList();
-		ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, i, 0, "&", false );
-		ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, s, 0, null, false );
+		ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, i, new PtrOp( PtrOp.t_reference ), false );
+		ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, s );
 		params.add( p1 );
 		params.add( p2 );
 		
@@ -1762,21 +1765,21 @@
 		}
 		
 		params.clear();
-		ParserSymbolTable.TypeInfo p3 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_int | ParserSymbolTable.TypeInfo.isLong, null, 0, null, false );
+		ParserSymbolTable.TypeInfo p3 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_int, ParserSymbolTable.TypeInfo.isLong, null );
 		params.add( p1 );
 		params.add( p3 );
 		look = main.UnqualifiedFunctionLookup( "f", params );
 		assertEquals( look, f2 );
 		
 		params.clear();
-		ParserSymbolTable.TypeInfo p4 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, null, 0, null, false );
+		ParserSymbolTable.TypeInfo p4 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, 0, null );
 		params.add( p1 );
 		params.add( p4 );
 		look = main.UnqualifiedFunctionLookup( "f", params );
 		assertEquals( look, f2 );
 		
 		params.clear();
-		p1.setCVQualifier( ParserSymbolTable.TypeInfo.cvConst );
+		((PtrOp)p1.getPtrOperators().getFirst()).setConst( true );
 		params.add( p1 );
 		params.add( p3 );
 		look = main.UnqualifiedFunctionLookup( "f", params );
@@ -1824,7 +1827,7 @@
 		
 		IParameterizedSymbol constructA = table.newParameterizedSymbol( "" );
 		constructA.setType( ParserSymbolTable.TypeInfo.t_function );
-		constructA.addParameter( B, 0, "&", false );
+		constructA.addParameter( B, new PtrOp( PtrOp.t_reference ), false );
 		A.addSymbol( constructA );
 		
 		IParameterizedSymbol operator = table.newParameterizedSymbol( "operator A" );
@@ -1833,7 +1836,7 @@
 		
 		IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" );
 		f1.setType( ParserSymbolTable.TypeInfo.t_function );
-		f1.addParameter( A, 0, null, false );
+		f1.addParameter( A, null, false );
 		compUnit.addSymbol( f1 );
 		
 		ISymbol b = table.newSymbol( "b" );
@@ -1841,7 +1844,7 @@
 		b.setTypeSymbol( B );
 		
 		LinkedList params = new LinkedList();
-		ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, b, 0, null, false );
+		ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, b );
 		params.add( p1 );
 		
 		ISymbol look = null;
@@ -1859,12 +1862,12 @@
 		
 		IParameterizedSymbol constructC = table.newParameterizedSymbol("");
 		constructC.setType( ParserSymbolTable.TypeInfo.t_function );
-		constructC.addParameter( B, 0, "&", false );
+		constructC.addParameter( B, new PtrOp( PtrOp.t_reference ), false );
 		C.addSymbol( constructC );
 
 		IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" );
 		f2.setType( ParserSymbolTable.TypeInfo.t_function );
-		f2.addParameter(  C, 0, null, false );
+		f2.addParameter(  C, null, false );
 		compUnit.addSymbol( f2 );
 		
 		try{
@@ -1876,7 +1879,7 @@
 		
 		IParameterizedSymbol f3 = table.newParameterizedSymbol( "f" );
 		f3.setType( ParserSymbolTable.TypeInfo.t_function );
-		f3.addParameter(  B, 0, null, false );
+		f3.addParameter(  B, null, false );
 		compUnit.addSymbol( f3 );
 		
 		look = compUnit.UnqualifiedFunctionLookup( "f", params );
@@ -1913,7 +1916,7 @@
 		Mark mark3 = table.setMark();
 		
 		IParameterizedSymbol C = table.newParameterizedSymbol("C");
-		C.addParameter( TypeInfo.t_class, 0, "", false );
+		C.addParameter( TypeInfo.t_class, 0, null, false );
 		
 		assertEquals( C.getParameterList().size(), 1 );
 		table.rollBack( mark3 );
Index: parser/ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/ChangeLog,v
retrieving revision 1.48.2.3
diff -u -r1.48.2.3 ChangeLog
--- parser/ChangeLog	14 May 2003 20:12:27 -0000	1.48.2.3
+++ parser/ChangeLog	20 May 2003 15:04:09 -0000
@@ -1,4 +1,8 @@
-2003-05-13
+2003-05-20 Andrew Niefer
+	Introduce class eType for stronger type safety in TypeInfo.
+	Introduced PtrOp class for more correct handling of Pointer Operators & CV qualifiers
+	
+2003-05-13 Andrew Niefer
 	Moved symbol table to org.eclipse.cdt.internal.core.pst
 	Created interface for symbol table: ISymbol, IContainerSymbol, IDerivableContainerSymbol, 
 	IParameterizedSymbol, and ISpecializedSymbol.  These are all implemented by Declaration
Index: parser/org/eclipse/cdt/internal/core/pst/IContainerSymbol.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pst/Attic/IContainerSymbol.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 IContainerSymbol.java
--- parser/org/eclipse/cdt/internal/core/pst/IContainerSymbol.java	14 May 2003 20:12:27 -0000	1.1.2.1
+++ parser/org/eclipse/cdt/internal/core/pst/IContainerSymbol.java	20 May 2003 15:04:09 -0000
@@ -16,6 +16,8 @@
  */
 package org.eclipse.cdt.internal.core.pst;
 
+import org.eclipse.cdt.internal.core.pst.ParserSymbolTable.TypeInfo; 
+
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -39,7 +41,7 @@
 			
 	public Map getContainedSymbols();
 	
-	public ISymbol ElaboratedLookup( int type, String name ) throws ParserSymbolTableException; 
+	public ISymbol ElaboratedLookup( TypeInfo.eType type, String name ) throws ParserSymbolTableException; 
 	public ISymbol Lookup( String name ) throws ParserSymbolTableException;
 	public ISymbol LookupMemberForDefinition( String name ) throws ParserSymbolTableException;
 	public IContainerSymbol LookupNestedNameSpecifier( String name ) throws ParserSymbolTableException;
Index: parser/org/eclipse/cdt/internal/core/pst/IDerivableContainerSymbol.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pst/Attic/IDerivableContainerSymbol.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 IDerivableContainerSymbol.java
--- parser/org/eclipse/cdt/internal/core/pst/IDerivableContainerSymbol.java	14 May 2003 20:12:27 -0000	1.1.2.1
+++ parser/org/eclipse/cdt/internal/core/pst/IDerivableContainerSymbol.java	20 May 2003 15:04:09 -0000
@@ -26,7 +26,6 @@
  */
 public interface IDerivableContainerSymbol extends IContainerSymbol {
 
-	public void addParent( IParentSymbol parent );
 	public void addParent( IDerivableContainerSymbol parent );
 	public void addParent( IDerivableContainerSymbol parent, boolean virtual );
 	public List getParents();
@@ -36,5 +35,6 @@
 		public void setParent( IDerivableContainerSymbol parent );
 		public IDerivableContainerSymbol getParent();
 		public boolean isVirtual();
+		public void setVirtual( boolean virtual );
 	}
 }
Index: parser/org/eclipse/cdt/internal/core/pst/IParameterizedSymbol.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pst/Attic/IParameterizedSymbol.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 IParameterizedSymbol.java
--- parser/org/eclipse/cdt/internal/core/pst/IParameterizedSymbol.java	14 May 2003 20:12:27 -0000	1.1.2.1
+++ parser/org/eclipse/cdt/internal/core/pst/IParameterizedSymbol.java	20 May 2003 15:04:09 -0000
@@ -16,6 +16,8 @@
  */
 package org.eclipse.cdt.internal.core.pst;
 
+import org.eclipse.cdt.internal.core.pst.ParserSymbolTable.TypeInfo;
+
 import java.util.List;
 import java.util.Map;
 
@@ -28,14 +30,18 @@
 public interface IParameterizedSymbol extends IContainerSymbol {
 	
 	public void addParameter( ISymbol param );
-	public void addParameter( int type, int cvQual, String ptrOperator, boolean hasDefault );
-	public void addParameter( ISymbol typeSymbol, int cvQual, String ptrOperator, boolean hasDefault );
+	public void addParameter( TypeInfo.eType type, int info, TypeInfo.PtrOp ptrOp, boolean hasDefault );
+	public void addParameter( ISymbol typeSymbol, TypeInfo.PtrOp ptrOp, boolean hasDefault );
 	
 	public Map getParameterMap();
 	public List getParameterList();
 
 	public boolean hasSameParameters(IParameterizedSymbol newDecl);
 	
-	public void setReturnType( int type );
+	public void setReturnType( TypeInfo.eType type );
+	
+	public boolean	hasSpecializations();
+	public void 	addSpecialization( ISpecializedSymbol spec );
+	public List		getSpecializations();		 
 
 }
Index: parser/org/eclipse/cdt/internal/core/pst/ISymbol.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pst/Attic/ISymbol.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 ISymbol.java
--- parser/org/eclipse/cdt/internal/core/pst/ISymbol.java	14 May 2003 20:12:27 -0000	1.1.2.1
+++ parser/org/eclipse/cdt/internal/core/pst/ISymbol.java	20 May 2003 15:04:09 -0000
@@ -10,6 +10,9 @@
 ***********************************************************************/
 package org.eclipse.cdt.internal.core.pst;
 
+import java.util.LinkedList;
+
+import org.eclipse.cdt.internal.core.pst.ParserSymbolTable.TypeInfo;
 /**
  * @author jcamelon
  *
@@ -24,19 +27,19 @@
 	public IContainerSymbol getContainingSymbol();
 	public void setContainingSymbol( IContainerSymbol containing );
 	
-	public boolean isType( int type );
-	public boolean isType( int type, int upperType );
-	public int getType();
-	public void setType(int t);
-	public ITypeInfo getTypeInfo();
+	public boolean isType( TypeInfo.eType type );
+	public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType );
+	public TypeInfo.eType getType();
+	public void setType(TypeInfo.eType t);
+	public TypeInfo getTypeInfo();
 	public ISymbol getTypeSymbol();
 	public void setTypeSymbol( ISymbol type );
-	public int getCVQualifier();
-	public void setCVQualifier( int cv );
-	public String getPtrOperator();
-	public void setPtrOperator( String ptrOp );
+
+	public int compareCVQualifiersTo( ISymbol symbol );
+	public LinkedList getPtrOperators();
+	public void addPtrOperator( TypeInfo.PtrOp ptrOp );
 	
-	public interface ITypeInfo {
+	/*public interface ITypeInfo {
 		public boolean checkBit(int mask);
 		public void setBit(boolean b, int mask);
 		public boolean isType( int type );
@@ -60,6 +63,6 @@
 		public boolean getHasDefault();
 		public void setHasDefault(boolean hasDefault);				
 	}
-	
+	*/
 	public int getDepth();
 }
Index: parser/org/eclipse/cdt/internal/core/pst/ParserSymbolTable.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pst/Attic/ParserSymbolTable.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 ParserSymbolTable.java
--- parser/org/eclipse/cdt/internal/core/pst/ParserSymbolTable.java	14 May 2003 20:12:27 -0000	1.1.2.1
+++ parser/org/eclipse/cdt/internal/core/pst/ParserSymbolTable.java	20 May 2003 15:04:10 -0000
@@ -22,16 +22,9 @@
 import java.util.Map;
 import java.util.Set;
 
-//import java.util.Stack;
-
 
 /**
  * @author aniefer
- *
- * To change this generated comment edit the template variable "typecomment":
- * Window>Preferences>Java>Templates.
- * To enable and disable the creation of type comments go to
- * Window>Preferences>Java>Code Generation.
  */
 
 public class ParserSymbolTable {
@@ -52,8 +45,8 @@
 	public IContainerSymbol newContainerSymbol( String name ){
 		return new Declaration( name );
 	}
-	public IContainerSymbol newContainerSymbol( String name, int typeInfo ){
-		return new Declaration( name, typeInfo );
+	public IContainerSymbol newContainerSymbol( String name, TypeInfo.eType type ){
+		return new Declaration( name, type );
 	}
 	
 	public ISymbol newSymbol( String name ){
@@ -65,14 +58,14 @@
 	public IParameterizedSymbol newParameterizedSymbol( String name ){
 		return new Declaration( name );
 	}
-	public IParameterizedSymbol newParameterizedSymbol( String name, int typeInfo ){
-		return new Declaration( name, typeInfo);
+	public IParameterizedSymbol newParameterizedSymbol( String name, TypeInfo.eType type ){
+		return new Declaration( name, type );
 	}
 	public ISpecializedSymbol newSpecializedSymbol( String name ){
 		return new Declaration( name );
 	}
-	public ISpecializedSymbol newSpecializedSymbol( String name, int typeInfo ){
-		return new Declaration( name, typeInfo);
+	public ISpecializedSymbol newSpecializedSymbol( String name, TypeInfo.eType type ){
+		return new Declaration( name, type );
 	}		
 	/**
 	 * Lookup the name from LookupData starting in the inDeclaration
@@ -83,7 +76,7 @@
 	 */
 	static private void Lookup( LookupData data, IContainerSymbol inSymbol ) throws ParserSymbolTableException
 	{
-		if( data.type != -1 && data.type < TypeInfo.t_class && data.upperType > TypeInfo.t_union ){
+		if( data.type != TypeInfo.t_any && data.type.compareTo(TypeInfo.t_class) < 0 && data.upperType.compareTo(TypeInfo.t_union) > 0 ){
 			throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
 		}
 		
@@ -167,7 +160,7 @@
 	 * directives, the effect is as if the using-directives from the second
 	 * namespace also appeared in the first.
 	 */
-	static private void LookupInNominated( LookupData data, IContainerSymbol symbol, LinkedList transitiveDirectives ) throws ParserSymbolTableException{
+	static private void LookupInNominated( LookupData data, IContainerSymbol symbol, LinkedList transitiveDirectives ){
 		//if the data.usingDirectives is empty, there is nothing to do.
 		if( data.usingDirectives == null ){
 			return;
@@ -214,11 +207,11 @@
 	 * function LookupInContained
 	 * @param data
 	 * @return List
-	 * @throws ParserSymbolTableException
 	 * 
 	 * Look for data.name in our collection _containedDeclarations
 	 */
-	private static boolean LookupInContained( LookupData data, IContainerSymbol lookIn ) throws ParserSymbolTableException{
+	private static boolean LookupInContained( LookupData data, IContainerSymbol lookIn ){
+	
 		boolean foundSomething = false;
 		ISymbol temp  = null;
 		Object obj = null;
@@ -348,7 +341,7 @@
 				} else if ( temp != null ) {
 					//it is not ambiguous if temp & decl are the same thing and it is static
 					//or an enumerator
-					ISymbol.ITypeInfo type = temp.getTypeInfo();
+					TypeInfo type = temp.getTypeInfo();
 					
 					if( symbol == temp && ( type.checkBit( TypeInfo.isStatic ) || type.isType( TypeInfo.t_enumerator ) ) ){
 						temp = null;
@@ -380,11 +373,11 @@
 	 * it finds the name to be a function name"
 	 */
 	private static boolean isValidOverload( ISymbol origSymbol, ISymbol newSymbol ){
-		int origType = origSymbol.getType();
-		int newType  = newSymbol.getType();
+		TypeInfo.eType origType = origSymbol.getType();
+		TypeInfo.eType newType  = newSymbol.getType();
 		
-		if( (origType >= TypeInfo.t_class && origType <= TypeInfo.t_enumeration) && //class name or enumeration ...
-			( newType == TypeInfo.t_type || (newType >= TypeInfo.t_function && newType <= TypeInfo.typeMask) ) ){
+		if( (origType.compareTo(TypeInfo.t_class) >= 0 && origType.compareTo(TypeInfo.t_enumeration) <= 0) && //class name or enumeration ...
+			( newType == TypeInfo.t_type || (newType.compareTo( TypeInfo.t_function ) >= 0 /*&& newType <= TypeInfo.typeMask*/) ) ){
 				
 			return true;
 		}
@@ -410,7 +403,7 @@
 			
 			Iterator iter = origList.iterator();
 			ISymbol symbol = (ISymbol) iter.next();
-			boolean valid = ( (symbol.getType() >= TypeInfo.t_class) && (symbol.getType() <= TypeInfo.t_enumeration) );
+			boolean valid = ( (symbol.getType().compareTo( TypeInfo.t_class ) >= 0 ) && (symbol.getType().compareTo( TypeInfo.t_enumeration ) <= 0 ) );
 			if( !valid && (symbol instanceof IParameterizedSymbol) )
 				valid = isValidFunctionOverload( (IParameterizedSymbol)symbol, (IParameterizedSymbol)newSymbol );
 			
@@ -440,7 +433,7 @@
 			
 			//if none of them are static, then the function can be overloaded if they differ in the type
 			//of their implicit object parameter.
-			if( origSymbol.getCVQualifier() != newSymbol.getCVQualifier() ){
+			if( origSymbol.compareCVQualifiersTo( newSymbol ) != 0 ){
 				return true;
 			}
 			
@@ -617,8 +610,8 @@
 		Cost cost = null;
 		Cost temp = null;
 		
-		ISymbol.ITypeInfo source = null;
-		ISymbol.ITypeInfo target = null;
+		TypeInfo source = null;
+		TypeInfo target = null;
 		 
 		boolean hasWorse = false;
 		boolean hasBetter = false;
@@ -647,7 +640,7 @@
 			comparison = 0;
 			
 			for( int j = 0; j < numParams; j++ ){
-				source = (ISymbol.ITypeInfo) sourceParams.next();
+				source = (TypeInfo) sourceParams.next();
 				target = ((ISymbol)targetParams.next()).getTypeInfo();
 				if( source.equals( target ) ){
 					cost = new Cost( source, target );
@@ -727,7 +720,7 @@
 			//A candidate function having fewer than m parameters is viable only if it has an 
 			//ellipsis in its parameter list.
 			else if( num < numParameters ) {
-				//TBD ellipsis
+				//TODO ellipsis
 				//not enough parameters, remove it
 				iter.remove();		
 			} 
@@ -735,7 +728,7 @@
 			//parameter has a default argument
 			else {
 				ListIterator listIter = function.getParameterList().listIterator( num );
-				ISymbol.ITypeInfo param;
+				TypeInfo param;
 				for( int i = num; i > ( numParameters - num + 1); i-- ){
 					param = ((IParameterizedSymbol)listIter.previous()).getTypeInfo();
 					if( !param.getHasDefault() ){
@@ -939,39 +932,114 @@
 		return okToAdd;
 	}
 
-	static private Cost lvalue_to_rvalue( ISymbol.ITypeInfo source, ISymbol.ITypeInfo target ) throws ParserSymbolTableException{
+	static private Cost lvalue_to_rvalue( TypeInfo source, TypeInfo target ){
+
 		//lvalues will have type t_type
 		if( source.isType( TypeInfo.t_type ) ){
 			source = getFlatTypeInfo( source );
 		}
-	
-		String sourcePtr = source.getPtrOperator();
-		String targetPtr = target.getPtrOperator();
 		
-		if( sourcePtr != null && sourcePtr.length() > 0 ){
-			char sourcePtrArray [] = sourcePtr.toCharArray();
-			if( sourcePtrArray[ 0 ] == '&' ){
-				source.setPtrOperator( new String(sourcePtrArray, 1, sourcePtr.length() - 1 ) );
+		Cost cost = new Cost( source, target );
+		TypeInfo.PtrOp op = null;
+		
+		if( cost.source.hasPtrOperators() ){
+			LinkedList sourcePtrs = cost.source.getPtrOperators();
+			TypeInfo.PtrOp ptr = (TypeInfo.PtrOp)sourcePtrs.getFirst();
+			
+			if( ptr.getType() == TypeInfo.PtrOp.t_reference ){
+				sourcePtrs.removeFirst();
+			}
+			int size = sourcePtrs.size();
+			Iterator iter = sourcePtrs.iterator();
+			
+			for( int i = size; i > 0; i-- ){
+				op = (TypeInfo.PtrOp) iter.next();
+				if( op.getType() == TypeInfo.PtrOp.t_array ){
+					op.setType( TypeInfo.PtrOp.t_pointer );		
+				}
 			}
 		}
 		
-		if( targetPtr != null && targetPtr.length() > 0 ){
-			char targetPtrArray [] = targetPtr.toCharArray();
-			if( targetPtrArray[ 0 ] == '&' ){
-				target.setPtrOperator ( new String( targetPtrArray, 1, targetPtr.length() - 1 ) );
+		if( cost.target.hasPtrOperators() ){
+			LinkedList targetPtrs = cost.target.getPtrOperators();
+			TypeInfo.PtrOp ptr = (TypeInfo.PtrOp)targetPtrs.getFirst();
+			
+			if( ptr.getType() == TypeInfo.PtrOp.t_reference ){
+				targetPtrs.removeFirst();
+			}
+			int size = targetPtrs.size();
+			Iterator iter = targetPtrs.iterator();
+			
+			for( int i = size; i > 0; i-- ){
+				op = (TypeInfo.PtrOp) iter.next();
+				if( op.getType() == TypeInfo.PtrOp.t_array ){
+					op.setType( TypeInfo.PtrOp.t_pointer );		
+				}
 			}
 		}
 		
-		Cost cost = new Cost( source, target );
-	
 		return cost;
 	}
 	
 	static private void qualificationConversion( Cost cost ){
-		if(  cost.source.getCVQualifier() == cost.target.getCVQualifier() || 
-			( cost.target.getCVQualifier() - cost.source.getCVQualifier()) > 1 )
-		{
-			cost.qualification = cost.target.getCVQualifier() + 1;
+		int size = cost.source.hasPtrOperators() ? cost.source.getPtrOperators().size() : 0;
+		int size2 = cost.target.hasPtrOperators() ? cost.target.getPtrOperators().size() : 0;
+		
+		TypeInfo.PtrOp op1 = null, op2 = null;
+		boolean canConvert = true;
+		
+		Iterator iter1 = cost.source.hasPtrOperators() ? cost.source.getPtrOperators().iterator() : null;
+		Iterator iter2 = cost.target.hasPtrOperators() ? cost.target.getPtrOperators().iterator() : null;
+		
+		if( size != size2 ){
+			cost.qualification = 0;
+			return;
+		} else if ( size == 1 ){
+			op1 = (TypeInfo.PtrOp) iter1.next();
+			op2 = (TypeInfo.PtrOp) iter2.next();
+			
+			if( ( op1.isConst()    && !op2.isConst() ) ||
+				( op1.isVolatile() && !op2.isVolatile() ) )
+			{
+				cost.qualification = 0;
+				return;
+			}
+			canConvert = true;
+		} else if( size > 0 ){
+			op1 = (TypeInfo.PtrOp) iter1.next();
+			op2 = (TypeInfo.PtrOp) iter2.next();
+
+			boolean constInEveryCV2k = true;
+			
+			for( int j= 1; j < size; j++ ){
+				op1 = (TypeInfo.PtrOp) iter1.next();
+				op2 = (TypeInfo.PtrOp) iter2.next();
+				
+				//pointer types are similar
+				if( op1.getType() != op2.getType() ){
+					canConvert = false;
+					break;
+				}
+				//if const is in cv1,j then const is in cv2,j.  Similary for volatile
+				if( ( op1.isConst()    && !op2.isConst()    ) ||
+				    ( op1.isVolatile() && !op2.isVolatile() )  )
+				{
+					canConvert = false;
+					break;
+				}
+				
+				//if cv1,j and cv2,j are different then const is in every cv2,k for 0<k<j
+				if( ( op1.compareCVTo( op2 ) != 0 ) && !constInEveryCV2k ){
+					canConvert = false;
+					break; 
+				}
+				
+				constInEveryCV2k &= op2.isConst();
+			}
+		}
+		
+		if( canConvert == true ){
+			cost.qualification = 1;
 			cost.rank = 0;
 		} else {
 			cost.qualification = 0;
@@ -993,8 +1061,8 @@
 	 * 4.6 float can be promoted to double
 	 */
 	static private void promotion( Cost cost ){
-		ISymbol.ITypeInfo src = cost.source;
-		ISymbol.ITypeInfo trg = cost.target;
+		TypeInfo src = cost.source;
+		TypeInfo trg = cost.target;
 		 
 		int mask = TypeInfo.isShort | TypeInfo.isLong | TypeInfo.isUnsigned;
 		
@@ -1027,62 +1095,59 @@
 	 * 
 	 */
 	static private void conversion( Cost cost ){
-		ISymbol.ITypeInfo src = cost.source;
-		ISymbol.ITypeInfo trg = cost.target;
+		TypeInfo src = cost.source;
+		TypeInfo trg = cost.target;
 		
 		int temp;
 		
-		String tempStr = src.getPtrOperator();
-		String srcPtr = ( tempStr == null ) ? new String("") : tempStr;
-		
-		tempStr = trg.getPtrOperator();
-		String trgPtr = ( tempStr == null ) ? new String("") : tempStr;
-		
 		cost.conversion = 0;
 		cost.detail = 0;
 		
-		if( !srcPtr.equals( trgPtr ) ){
+		if( !src.hasSamePtrs( trg ) ){
 			return;
 		} 
-		if( srcPtr.equals("*") ){
-			ISymbol srcDecl = src.isType( TypeInfo.t_type ) ? src.getTypeSymbol() : null;
-			ISymbol trgDecl = trg.isType( TypeInfo.t_type ) ? trg.getTypeSymbol() : null;
-
-			if( srcDecl == null || (trgDecl == null && !trg.isType( TypeInfo.t_void )) ){
-				return;	
-			}
-			
-			//4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be
-			//converted to an rvalue of type "pointer to cv void"
-			if( trg.isType( TypeInfo.t_void ) ){
-				cost.rank = 2;
-				cost.conversion = 1;
-				cost.detail = 2;
-				return;	
-			}
-			
-			cost.detail = 1;
-			
-			//4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted
-			// to an rvalue of type "pointer to cv B", where B is a base class of D.
-			if( (srcDecl instanceof IDerivableContainerSymbol) && trgDecl.isType( srcDecl.getType() ) ){
-				temp = hasBaseClass( (IDerivableContainerSymbol) srcDecl, (IDerivableContainerSymbol) trgDecl );
-				cost.rank = 2;
-				cost.conversion = ( temp > -1 ) ? temp : 0;
+		if( src.hasPtrOperators() && src.getPtrOperators().size() == 1 ){
+			TypeInfo.PtrOp ptr = (TypeInfo.PtrOp)src.getPtrOperators().getFirst();
+			if( ptr.getType() == TypeInfo.PtrOp.t_pointer ){
+				ISymbol srcDecl = src.isType( TypeInfo.t_type ) ? src.getTypeSymbol() : null;
+				ISymbol trgDecl = trg.isType( TypeInfo.t_type ) ? trg.getTypeSymbol() : null;
+	
+				if( srcDecl == null || (trgDecl == null && !trg.isType( TypeInfo.t_void )) ){
+					return;	
+				}
+				
+				//4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be
+				//converted to an rvalue of type "pointer to cv void"
+				if( trg.isType( TypeInfo.t_void ) ){
+					cost.rank = 2;
+					cost.conversion = 1;
+					cost.detail = 2;
+					return;	
+				}
+				
 				cost.detail = 1;
-				return;
-			}
-			
-			//4.11-2 An rvalue of type "pointer to member of B of type cv T", where B is a class type, 
-			//can be converted to an rvalue of type "pointer to member of D of type cv T" where D is a
-			//derived class of B
-			if( srcDecl.getContainingSymbol().isType( TypeInfo.t_class ) && trgDecl.getContainingSymbol().isType( TypeInfo.t_class ) ){
-				temp = hasBaseClass( (IDerivableContainerSymbol)trgDecl.getContainingSymbol(), (IDerivableContainerSymbol)srcDecl.getContainingSymbol() );
-				cost.rank = 2;
-				cost.conversion = ( temp > -1 ) ? temp : 0;
-				return;
+				
+				//4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted
+				// to an rvalue of type "pointer to cv B", where B is a base class of D.
+				if( (srcDecl instanceof IDerivableContainerSymbol) && trgDecl.isType( srcDecl.getType() ) ){
+					temp = hasBaseClass( (IDerivableContainerSymbol) srcDecl, (IDerivableContainerSymbol) trgDecl );
+					cost.rank = 2;
+					cost.conversion = ( temp > -1 ) ? temp : 0;
+					cost.detail = 1;
+					return;
+				}
+				
+				//4.11-2 An rvalue of type "pointer to member of B of type cv T", where B is a class type, 
+				//can be converted to an rvalue of type "pointer to member of D of type cv T" where D is a
+				//derived class of B
+				if( srcDecl.getContainingSymbol().isType( TypeInfo.t_class ) && trgDecl.getContainingSymbol().isType( TypeInfo.t_class ) ){
+					temp = hasBaseClass( (IDerivableContainerSymbol)trgDecl.getContainingSymbol(), (IDerivableContainerSymbol)srcDecl.getContainingSymbol() );
+					cost.rank = 2;
+					cost.conversion = ( temp > -1 ) ? temp : 0;
+					return;
+				}
 			}
-		} else {
+		} else if( !src.hasPtrOperators() ) {
 			//4.7 An rvalue of an integer type can be converted to an rvalue of another integer type.  
 			//An rvalue of an enumeration type can be converted to an rvalue of an integer type.
 			if( src.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
@@ -1099,7 +1164,7 @@
 		}
 	}
 	
-	static private Cost checkStandardConversionSequence( ISymbol.ITypeInfo source, ISymbol.ITypeInfo target ) throws ParserSymbolTableException {
+	static private Cost checkStandardConversionSequence( TypeInfo source, TypeInfo target ){
 		Cost cost = lvalue_to_rvalue( source, target );
 		
 		if( cost.source.equals( cost.target ) ){
@@ -1124,7 +1189,7 @@
 		return cost;	
 	}
 	
-	static private Cost checkUserDefinedConversionSequence( ISymbol.ITypeInfo source, ISymbol.ITypeInfo target ) throws ParserSymbolTableException {
+	static private Cost checkUserDefinedConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException {
 		Cost cost = null;
 		Cost constructorCost = null;
 		Cost conversionCost = null;
@@ -1167,10 +1232,10 @@
 		}
 		
 		if( constructor != null ){
-			constructorCost = checkStandardConversionSequence( (ISymbol.ITypeInfo) new TypeInfo( TypeInfo.t_type, constructor.getContainingSymbol() ), target );
+			constructorCost = checkStandardConversionSequence( (TypeInfo) new TypeInfo( TypeInfo.t_type, 0, constructor.getContainingSymbol() ), target );
 		}
 		if( conversion != null ){
-			conversionCost = checkStandardConversionSequence( (ISymbol.ITypeInfo) new TypeInfo( target.getType(), target.getTypeSymbol() ), target );
+			conversionCost = checkStandardConversionSequence( (TypeInfo) new TypeInfo( target.getType(), 0, target.getTypeSymbol() ), target );
 		}
 		
 		//if both are valid, then the conversion is ambiguous
@@ -1199,17 +1264,16 @@
 	 * 
 	 * @param decl
 	 * @return TypeInfo
-	 * @throws ParserSymbolTableException
 	 * The top level TypeInfo represents modifications to the object and the
 	 * remaining TypeInfo's represent the object.
 	 */
 	// TODO move this to ITypeInfo ?
-	static private ISymbol.ITypeInfo getFlatTypeInfo( ISymbol.ITypeInfo topInfo ){
-		ISymbol.ITypeInfo returnInfo = topInfo;
-		ISymbol.ITypeInfo info = null;
+	static private TypeInfo getFlatTypeInfo( TypeInfo topInfo ){
+		TypeInfo returnInfo = topInfo;
+		TypeInfo info = null;
 		
 		if( topInfo.getType() == TypeInfo.t_type ){
-			returnInfo = (ISymbol.ITypeInfo)new TypeInfo();
+			returnInfo = (TypeInfo)new TypeInfo();
 			
 			ISymbol typeSymbol = topInfo.getTypeSymbol();
 			
@@ -1218,8 +1282,8 @@
 			while( info.getType() == TypeInfo.t_type ){
 				typeSymbol = info.getTypeSymbol();
 				
-				returnInfo.addCVQualifier( info.getCVQualifier() );
-				returnInfo.addPtrOperator( info.getPtrOperator() );	
+				//returnInfo.addCVQualifier( info.getCVQualifier() );
+				returnInfo.addPtrOperator( info.getPtrOperators() );	
 				
 				info = info.getTypeSymbol().getTypeInfo();
 			}
@@ -1229,18 +1293,11 @@
 				returnInfo.setTypeSymbol( typeSymbol );
 			} else {
 				returnInfo.setTypeInfo( info.getTypeInfo() );
+				returnInfo.setType( info.getType() );
 				returnInfo.setTypeSymbol( null );
 			}
 			
-			String ptrOp = returnInfo.getPtrOperator();
-			returnInfo.setPtrOperator( topInfo.getInvertedPtrOperator() );
-			
-			if( ptrOp != null ){
-				returnInfo.addPtrOperator( ptrOp );
-			}
-			
-			returnInfo.setCVQualifier( info.getCVQualifier() );
-			returnInfo.addCVQualifier( topInfo.getCVQualifier() );
+			returnInfo.applyPtrsAsUnaryOperators( topInfo.getPtrOperators() );
 		}
 		
 		return returnInfo;	
@@ -1397,14 +1454,14 @@
 		public HashSet associated;				//associated namespaces for argument dependant lookup
 		public ISymbol stopAt;					//stop looking along the stack once we hit this declaration
 				 
-		public int type = -1;
-		public int upperType = 0;
+		public TypeInfo.eType type = TypeInfo.t_any;
+		public TypeInfo.eType upperType = TypeInfo.t_undef;
 		public boolean qualified = false;
 		public boolean ignoreUsingDirectives = false;
 
 		public HashSet foundItems = null;
 		
-		public LookupData( String n, int t ){
+		public LookupData( String n, TypeInfo.eType t ){
 			name = n;
 			type = t;
 		}
@@ -1412,13 +1469,13 @@
 	
 	static private class Cost
 	{
-		public Cost( ISymbol.ITypeInfo s, ISymbol.ITypeInfo t ){
+		public Cost( TypeInfo s, TypeInfo t ){
 			source = s;
 			target = t;
 		}
 		
-		public ISymbol.ITypeInfo source;
-		public ISymbol.ITypeInfo target;
+		public TypeInfo source;
+		public TypeInfo target;
 		
 		public int lvalue;
 		public int promotion;
@@ -1461,7 +1518,43 @@
 			}
 			
 			if( result == 0 ){
-				result = cost.qualification - qualification;
+				if( cost.qualification != qualification ){
+					return cost.qualification - qualification;
+				} else if( (cost.qualification == qualification) && qualification == 0 ){
+					return 0;
+				} else {
+					int size = cost.target.hasPtrOperators() ? cost.target.getPtrOperators().size() : 0;
+					int size2 = target.hasPtrOperators() ? target.getPtrOperators().size() : 0;
+					
+					ListIterator iter1 = cost.target.getPtrOperators().listIterator( size );
+					ListIterator iter2 = target.getPtrOperators().listIterator( size2 );
+					
+					TypeInfo.PtrOp op1 = null, op2 = null;
+					
+					int subOrSuper = 0;
+					for( int i = ( size < size2 ) ? size : size2; i > 0; i-- ){
+						op1 = (TypeInfo.PtrOp)iter1.previous();
+						op2 = (TypeInfo.PtrOp)iter2.previous();
+						
+						if( subOrSuper == 0)
+							subOrSuper = op1.compareCVTo( op2 );
+						else if( ( subOrSuper > 0 && ( op1.compareCVTo( op2 ) < 0 )) ||
+								 ( subOrSuper < 0 && ( op1.compareCVTo( op2 ) > 0 )) )
+						{
+							result = -1;
+							break;	
+						}
+					}
+					if( result == -1 ){
+						result = 0;
+					} else {
+						if( size == size2 ){
+							result = subOrSuper;
+						} else {
+							result = size - size2; 
+						}
+					}
+				}
 			}
 			 
 			return result;
@@ -1488,10 +1581,10 @@
 			_typeInfo = new TypeInfo();
 		}
 		
-		public Declaration( String name, int typeInfo )
+		public Declaration( String name, TypeInfo.eType typeInfo )
 		{
 			_name =name;
-			_typeInfo = new TypeInfo( typeInfo, this );
+			_typeInfo = new TypeInfo( typeInfo, 0, this );
 		}
 
 		/**
@@ -1529,19 +1622,19 @@
 			return copy;	
 		}
 	
-		public void setType(int t){
+		public void setType(TypeInfo.eType t){
 			_typeInfo.setType( t );	 
 		}
 	
-		public int getType(){ 
+		public TypeInfo.eType getType(){ 
 			return _typeInfo.getType(); 
 		}
 	
-		public boolean isType( int type ){
-			return _typeInfo.isType( type, 0 ); 
+		public boolean isType( TypeInfo.eType type ){
+			return _typeInfo.isType( type, TypeInfo.t_undef ); 
 		}
 
-		public boolean isType( int type, int upperType ){
+		public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType ){
 			return _typeInfo.isType( type, upperType );
 		}
 		
@@ -1553,7 +1646,7 @@
 			_typeInfo.setTypeSymbol( type ); 
 		}
 
-		public ISymbol.ITypeInfo getTypeInfo(){
+		public TypeInfo getTypeInfo(){
 			return _typeInfo;
 		}
 	
@@ -1626,26 +1719,50 @@
 			_needsDefinition = need;
 		}
 	
-		public int getCVQualifier(){
-			return _cvQualifier;
-		}
+		/**
+		 * returns 0 if same, non zero otherwise
+		 */
+		public int compareCVQualifiersTo( ISymbol symbol ){
+			int size = symbol.getTypeInfo().hasPtrOperators() ? symbol.getTypeInfo().getPtrOperators().size() : 0;
+			int size2 = getTypeInfo().hasPtrOperators() ? getTypeInfo().getPtrOperators().size() : 0;
+				
+			if( size != size2 ){
+				return size2 - size;
+			} else {
+				Iterator iter1 = symbol.getTypeInfo().getPtrOperators().iterator();
+				Iterator iter2 = getTypeInfo().getPtrOperators().iterator();
+	
+				TypeInfo.PtrOp op1 = null, op2 = null;
 	
-		public void setCVQualifier( int cv ){
-			_cvQualifier = cv;
+				int subOrSuper = 0;
+				for( int i = size; i > 0; i-- ){
+					op1 = (TypeInfo.PtrOp)iter1.next();
+					op2 = (TypeInfo.PtrOp)iter2.next();
+		
+					if( op1.compareCVTo( op2 ) != 0 ){
+						return -1;
+					}
+				}
+			}
+			
+			return 0;
 		}
 	
-		public String getPtrOperator(){
-			return _typeInfo.getPtrOperator();
+		public LinkedList getPtrOperators(){
+			return _typeInfo.getPtrOperators();
 		}
-		public void setPtrOperator( String ptrOp ){
-			_typeInfo.setPtrOperator( ptrOp );
+		public void addPtrOperator( TypeInfo.PtrOp ptrOp ){
+			_typeInfo.addPtrOperator( ptrOp );
 		}
+		//public void addPtrOperator( String ptrStr, boolean isConst, boolean isVolatile ){
+		//	_typeInfo.addPtrOperator( ptrStr, isConst, isVolatile );
+		//}
 	
-		public int getReturnType(){
+		public TypeInfo.eType getReturnType(){
 			return _returnType;
 		}
 	
-		public void setReturnType( int type ){
+		public void setReturnType( TypeInfo.eType type ){
 			_returnType = type;
 		}
 	
@@ -1675,27 +1792,26 @@
 			pushCommand( command );
 		}
 		
-		public void addParameter( ISymbol typeSymbol, int cvQual, String ptrOperator, boolean hasDefault ){
+		public void addParameter( ISymbol typeSymbol, TypeInfo.PtrOp ptrOp, boolean hasDefault ){
 			Declaration param = new Declaration("");
 			
-			ISymbol.ITypeInfo info = param.getTypeInfo();
+			TypeInfo info = param.getTypeInfo();
 			info.setType( TypeInfo.t_type );
 			info.setTypeSymbol( typeSymbol );
-			info.setCVQualifier( cvQual );
-			info.setPtrOperator( ptrOperator );
+			info.addPtrOperator( ptrOp );
 			info.setHasDefault( hasDefault );
 				
 			addParameter( param );
 		}
 	
-		public void addParameter( int type, int cvQual, String ptrOperator, boolean hasDefault ){
+		public void addParameter( TypeInfo.eType type, int info, TypeInfo.PtrOp ptrOp, boolean hasDefault ){
 			Declaration param = new Declaration("");
 					
-			ISymbol.ITypeInfo info = param.getTypeInfo();
-			info.setTypeInfo( type );
-			info.setCVQualifier( cvQual );
-			info.setPtrOperator( ptrOperator );
-			info.setHasDefault( hasDefault );
+			TypeInfo t = param.getTypeInfo();
+			t.setTypeInfo( info );
+			t.setType( type );
+			t.addPtrOperator( ptrOp );
+			t.setHasDefault( hasDefault );
 				
 			addParameter( param );
 		}
@@ -1713,8 +1829,8 @@
 			Iterator iter = getParameterList().iterator();
 			Iterator fIter = function.getParameterList().iterator();
 		
-			ISymbol.ITypeInfo info = null;
-			ISymbol.ITypeInfo fInfo = null;
+			TypeInfo info = null;
+			TypeInfo fInfo = null;
 		
 			for( int i = size; i > 0; i-- ){
 				info = ((Declaration)iter.next()).getTypeInfo();
@@ -1792,7 +1908,7 @@
 			}
 		
 			//take care of the this pointer
-			ISymbol.ITypeInfo type = obj.getTypeInfo();
+			TypeInfo type = obj.getTypeInfo();
 			boolean addedThis = false;
 			if( type.isType( TypeInfo.t_function ) && !type.checkBit( TypeInfo.isStatic ) ){
 				addThis( (Declaration) obj );
@@ -1812,8 +1928,8 @@
 		 * this is const X*, if the member function is declared volatile, the type
 		 * of this is volatile X*....
 		 */
-		private void addThis( Declaration obj ) throws ParserSymbolTableException{
-			ISymbol.ITypeInfo type = obj.getTypeInfo();
+		private void addThis( Declaration obj ){
+			TypeInfo type = obj.getTypeInfo();
 			if( !type.isType( TypeInfo.t_function ) || type.checkBit( TypeInfo.isStatic ) ){
 				return;
 			}
@@ -1821,7 +1937,7 @@
 			if( obj.getContainingSymbol().isType( TypeInfo.t_class, TypeInfo.t_union ) ){
 				//check to see if there is already a this object, since using declarations
 				//of function will have them from the original declaration
-				LookupData data = new LookupData( "this", -1 );
+				LookupData data = new LookupData( "this", TypeInfo.t_any );
 				LookupInContained( data, obj );
 				//if we didn't find "this" then foundItems will still be null, no need to actually
 				//check its contents 
@@ -1829,10 +1945,22 @@
 					Declaration thisObj = new Declaration("this");
 					thisObj.setType( TypeInfo.t_type );
 					thisObj.setTypeSymbol( obj.getContainingSymbol() );
-					thisObj.setCVQualifier( obj.getCVQualifier() );
-					thisObj.setPtrOperator("*");
-			
-					obj.addSymbol( thisObj );
+					//thisObj.setCVQualifier( obj.getCVQualifier() );
+					TypeInfo.PtrOp ptr = new TypeInfo.PtrOp();
+					ptr.setType( TypeInfo.PtrOp.t_pointer );
+					if( obj.getTypeInfo().hasPtrOperators() ){
+						ptr.setConst( ((TypeInfo.PtrOp) obj.getPtrOperators().getFirst()).isConst() );
+						ptr.setVolatile( ((TypeInfo.PtrOp) obj.getPtrOperators().getFirst()).isVolatile() );
+					}
+					
+					thisObj.addPtrOperator(ptr);
+					
+					try{
+						obj.addSymbol( thisObj );
+					} catch ( ParserSymbolTableException e ) {
+						//won't happen because we checked that "this" didn't exist already
+					}
+					
 				}
 			}		
 		}
@@ -1883,7 +2011,7 @@
 		 * class scope.
 		 */
 		private Declaration LookupForFriendship( String name ) throws ParserSymbolTableException{
-			LookupData data = new LookupData( name, -1 );
+			LookupData data = new LookupData( name, TypeInfo.t_any );
 		
 			boolean inClass = ( getType() == TypeInfo.t_class);
 		
@@ -1921,7 +2049,7 @@
 		}
 
 		public ISymbol addUsingDeclaration( String name, IContainerSymbol declContext ) throws ParserSymbolTableException{
-			LookupData data = new LookupData( name, -1 );
+			LookupData data = new LookupData( name, TypeInfo.t_any );
 	
 			if( declContext != null ){				
 				data.qualified = true;
@@ -1981,7 +2109,7 @@
 			return _usingDirectives;
 		}
 		
-		public ISymbol ElaboratedLookup( int type, String name ) throws ParserSymbolTableException{
+		public ISymbol ElaboratedLookup( TypeInfo.eType type, String name ) throws ParserSymbolTableException{
 			LookupData data = new LookupData( name, type );
 		
 			ParserSymbolTable.Lookup( data, this );
@@ -1990,7 +2118,7 @@
 		}
 		
 		public ISymbol Lookup( String name ) throws ParserSymbolTableException {
-			LookupData data = new LookupData( name, -1 );
+			LookupData data = new LookupData( name, TypeInfo.t_any );
 		
 			ParserSymbolTable.Lookup( data, this );
 		
@@ -2026,7 +2154,7 @@
 		 * for a definition.
 		 */
 		public ISymbol LookupMemberForDefinition( String name ) throws ParserSymbolTableException{
-			LookupData data = new LookupData( name, -1 );
+			LookupData data = new LookupData( name, TypeInfo.t_any );
 			data.qualified = true;
 	
 			ParserSymbolTable.LookupInContained( data, this );
@@ -2099,7 +2227,7 @@
 		}
 		
 		public ISymbol QualifiedLookup( String name ) throws ParserSymbolTableException{
-			LookupData data = new LookupData( name, -1 );
+			LookupData data = new LookupData( name, TypeInfo.t_any );
 			data.qualified = true;
 			ParserSymbolTable.Lookup( data, this );
 		
@@ -2147,11 +2275,13 @@
 			
 				//if T is a pointer to a data member of class X, its associated namespaces and classes
 				//are those associated with the member type together with those associated with X
-				if( param.getPtrOperator() != null && 
-				   (param.getPtrOperator().equals("*") || param.getPtrOperator().equals("[]")) &&
-					paramType.getContainingSymbol().isType( TypeInfo.t_class, TypeInfo.t_union ) )
-				{
-					ParserSymbolTable.getAssociatedScopes( paramType.getContainingSymbol(), associated );
+				if( param.hasPtrOperators() && param.getPtrOperators().size() == 1 ){
+					TypeInfo.PtrOp op = (TypeInfo.PtrOp)param.getPtrOperators().getFirst();
+					if( op.getType() == TypeInfo.PtrOp.t_pointer && 
+						paramType.getContainingSymbol().isType( TypeInfo.t_class, TypeInfo.t_union ) )
+					{
+						ParserSymbolTable.getAssociatedScopes( paramType.getContainingSymbol(), associated );	
+					}
 				}
 			}
 		
@@ -2196,7 +2326,19 @@
 		
 			return found;
 		}
-			
+		
+		public boolean hasSpecializations(){
+			return ( _specializations != null && !_specializations.isEmpty() );
+		}
+		
+		public List	getSpecializations(){
+			return _specializations;
+		}
+		
+		public void addSpecialization( ISpecializedSymbol spec ){
+			_specializations.add( spec );	
+		}
+
 		private 	String 		_name;					//our name
 		private		Object 		_object;				//the object associated with us
 		private		boolean		_needsDefinition;		//this name still needs to be defined
@@ -2208,10 +2350,12 @@
 		private		LinkedList 	_usingDirectives;		//collection of nominated namespaces
 		private		HashMap 	_containedDeclarations;	//declarations contained by us.
 	
+		private		LinkedList	_specializations;		//template specializations
+		
 		private 	LinkedList	_parameterList;			//have my cake
 		private 	HashMap		_parameterHash;			//and eat it too
 		
-		private 	int			_returnType;			
+		private 	TypeInfo.eType	_returnType;			
 	
 		private		int 		_depth;					//how far down the scope stack we are
 		
@@ -2234,28 +2378,38 @@
 				return isVirtual;
 			}
 			
+			public void setVirtual( boolean virtual ){
+				isVirtual = virtual;
+			}
+			
 			private boolean isVirtual = false;
 			private Declaration parent = null;
 		}
 	}
 	
-	static public class TypeInfo implements ISymbol.ITypeInfo{
+	static public class TypeInfo {
 		public TypeInfo(){
 			super();	
 		}
 	
-		public TypeInfo( int type, ISymbol symbol ){
+		public TypeInfo( eType type, int info, ISymbol symbol ){
 			super();
-			_typeInfo = type;
+			_typeInfo = info;
+			_type = type;
 			_typeDeclaration = symbol;	
 		}
 	
-		public TypeInfo( int type, ISymbol symbol, int cvQualifier, String ptrOp, boolean hasDefault ){
+		public TypeInfo( eType type, int info, ISymbol symbol, PtrOp op, boolean hasDefault ){
 			super();
-			_typeInfo = type;
+			_typeInfo = info;
+			_type = type;
 			_typeDeclaration = symbol;
-			_cvQualifier = cvQualifier;
-			_ptrOperator = ( ptrOp != null ) ? new String( ptrOp ) : null;
+			if( op != null ){
+				_ptrOperators = new LinkedList();
+				_ptrOperators.add( op );
+			} else {
+				_ptrOperators = null;
+			}
 			_hasDefaultValue = hasDefault;
 		}
 	
@@ -2263,9 +2417,9 @@
 			super();
 		
 			_typeInfo = info._typeInfo;
+			_type = info._type;
 			_typeDeclaration = info._typeDeclaration;
-			_cvQualifier = info._cvQualifier;
-			_ptrOperator = ( info._ptrOperator == null ) ? null : new String( info._ptrOperator );
+			_ptrOperators = ( info._ptrOperators == null ) ? null : (LinkedList)info._ptrOperators.clone();
 			_hasDefaultValue = info._hasDefaultValue;
 		}
 	
@@ -2289,25 +2443,93 @@
 		// Types (maximum type is typeMask
 		// Note that these should be considered ordered and if you change
 		// the order, you should consider the ParserSymbolTable uses
-		public static final int t_undef       =  0; //not specified
-		public static final int t_type        =  1; // Type Specifier
-		public static final int t_namespace   =  2;
-		public static final int t_class       =  3;
-		public static final int t_struct      =  4;
-		public static final int t_union       =  5;
-		public static final int t_enumeration =  6;
-		public static final int t_function    =  7;
-		public static final int t_bool        =  8;
-		public static final int t_char        =  9;
-		public static final int t_wchar_t     = 10;
-		public static final int t_int         = 11;
-		public static final int t_float       = 12;
-		public static final int t_double      = 13;
-		public static final int t_void        = 14;
-		public static final int t_enumerator  = 15;
-		public static final int t_block       = 16;
-		public static final int t_template    = 17;
+		public static final eType t_any         = new eType( -1 ); //don't care
+		public static final eType t_undef       = new eType(  0 ); //not specified
+		public static final eType t_type        = new eType(  1 ); //Type Specifier
+		public static final eType t_namespace   = new eType(  2 );
+		public static final eType t_class       = new eType(  3 );
+		public static final eType t_struct      = new eType(  4 );
+		public static final eType t_union       = new eType(  5 );
+		public static final eType t_enumeration = new eType(  6 );
+		public static final eType t_function    = new eType(  7 );
+		public static final eType t_bool        = new eType(  8 );
+		public static final eType t_char        = new eType(  9 );
+		public static final eType t_wchar_t     = new eType( 10 );
+		public static final eType t_int         = new eType( 11 );
+		public static final eType t_float       = new eType( 12 );
+		public static final eType t_double      = new eType( 13 );
+		public static final eType t_void        = new eType( 14 );
+		public static final eType t_enumerator  = new eType( 15 );
+		public static final eType t_block       = new eType( 16 );
+		public static final eType t_template    = new eType( 17 );
 		
+		public static class eType implements Comparable{
+			private eType( int v ){
+				_val = v;
+			}
+			
+			public int compareTo( Object o ){
+				eType t = (eType) o;
+				return _val - t._val;
+			}
+			
+			public int toInt(){
+				return _val;
+			}
+			
+			private int _val;
+		}
+		
+		public static class PtrOp {
+			public PtrOp( eType type ){
+				this.type = type;
+			}
+			public PtrOp( eType type, boolean isConst, boolean isVolatile ){
+				this.type = type;
+				this.isConst = isConst;
+				this.isVolatile = isVolatile;
+			}
+			public PtrOp(){
+				super();
+			}
+			
+			public static final eType t_undef	  = new eType( 0 );
+			public static final eType t_pointer   = new eType( 1 );
+			public static final eType t_reference = new eType( 2 );
+			public static final eType t_array = new eType( 3 );
+			
+			
+			private eType type = t_undef;
+			private boolean isConst = false;
+			private boolean isVolatile = false;
+			
+			public eType getType()			 { return type; }
+			public void setType( eType type ){ this.type = type; }
+			
+			public boolean isConst()	{ return isConst; }
+			public boolean isVolatile()	{ return isVolatile; }
+			public void setConst( boolean isConst ) 	 { this.isConst = isConst; }
+			public void setVolatile( boolean isVolatile ){ this.isVolatile = isVolatile; }
+			
+			public int compareCVTo( PtrOp ptr ){
+				int cv1 = ( isConst() ? 1 : 0 ) + ( isVolatile() ? 1 : 0 );
+				int cv2 = ( ptr.isConst() ? 1 : 0 ) + ( ptr.isVolatile() ? 1 : 0 );
+				
+				return cv1 - cv2;
+			}
+			public boolean equals( Object o ){
+				if( o == null || !(o instanceof PtrOp) ){
+					return false;
+				}	
+				PtrOp op = (PtrOp)o;
+				
+				return ( isConst() == op.isConst() &&
+						 isVolatile() == op.isVolatile() &&
+						 getType() == op.getType() );
+			}
+			
+		}
+
 		private static final String _image[] = {	"", 
 													"", 
 													"namespace", 
@@ -2332,9 +2554,9 @@
 		// none		< const volatile
 		// const	< const volatile
 		// volatile < const volatile
-		public static final int cvConst 			= 2;
+		public static final int cvConst 		= 2;
 		public static final int cvVolatile 		= 3;
-		public static final int cvConstVolatile 	= 5;
+		public static final int cvConstVolatile = 5;
 	
 			// Convenience methods
 		public void setBit(boolean b, int mask){
@@ -2349,21 +2571,16 @@
 			return (_typeInfo & mask) != 0;
 		}	
 		
-		public void setType(int t){
-			//sanity check, t must fit in its allocated 5 bits in _typeInfo
-			if( t > typeMask ){
-				return;
-			}
-		
-			_typeInfo = _typeInfo & ~typeMask | t; 
+		public void setType( eType t){
+			_type = t; 
 		}
 		
-		public int getType(){ 
-			return _typeInfo & typeMask; 
+		public eType getType(){ 
+			return _type; 
 		}
 	
-		public boolean isType( int type ){
-			return isType( type, 0 ); 
+		public boolean isType( eType type ){
+			return isType( type, t_undef ); 
 		}
 	
 		public int getTypeInfo(){
@@ -2384,16 +2601,16 @@
 		 * upperType (inclusive).  upperType of 0 means no range and our type must
 		 * be type.
 		 */
-		public boolean isType( int type, int upperType ){
+		public boolean isType( eType type, eType upperType ){
 			//type of -1 means we don't care
-			if( type == -1 )
+			if( type == t_any )
 				return true;
 		
 			//upperType of 0 means no range
-			if( upperType == 0 ){
+			if( upperType == t_undef ){
 				return ( getType() == type );
 			} else {
-				return ( getType() >= type && getType() <= upperType );
+				return ( getType().compareTo( type ) >= 0 && getType().compareTo( upperType ) <= 0 );
 			}
 		}
 		
@@ -2404,133 +2621,91 @@
 		public void setTypeSymbol( ISymbol type ){
 			_typeDeclaration = (Declaration) type; 
 		}
-	
-		public int getCVQualifier(){
-			return _cvQualifier;
+
+		public boolean hasPtrOperators(){
+			return ( _ptrOperators != null && _ptrOperators.size() > 0 );	
 		}
-	
-		public void setCVQualifier( int cv ){
-			_cvQualifier = cv;
+		
+		public LinkedList getPtrOperators(){
+			return _ptrOperators;
 		}
-
-		public void addCVQualifier( int cv ){
-			switch( _cvQualifier ){
-				case 0:
-					_cvQualifier = cv;
-					break;
-				
-				case cvConst:
-					if( cv != cvConst ){
-						_cvQualifier = cvConstVolatile;
-					}
-					break;
-			
-				case cvVolatile:
-					if( cv != cvVolatile ){
-						_cvQualifier = cvConstVolatile;
+		
+		public boolean hasSamePtrs( TypeInfo type ){
+			int size = hasPtrOperators() ? getPtrOperators().size() : 0;
+			int size2 = type.hasPtrOperators() ? type.getPtrOperators().size() : 0;
+			if( size == size2 ){
+				if( size > 0 ){
+					Iterator iter1 = getPtrOperators().iterator();
+					Iterator iter2 = type.getPtrOperators().iterator();
+					PtrOp ptr1 = null, ptr2 = null;
+					for( int i = size; i > 0; i-- ){
+						ptr1 = (PtrOp)iter1.next();
+						ptr2 = (PtrOp)iter2.next();
+						if( ptr1.getType() != ptr2.getType() ){
+							return false;
+						}
 					}
-					break;
-			
-				case cvConstVolatile:
-					break;	//nothing to do
+				}
+				return true;
 			}
+			return false;
 		}
-	
-		public String getPtrOperator(){
-			return _ptrOperator;
-		}
-	
-		public void setPtrOperator( String ptr ){
-			_ptrOperator = ptr;
-		}
-	
-		public void addPtrOperator( String ptr ){
-			if( ptr == null ){
+
+		public void applyPtrsAsUnaryOperators( LinkedList ptrs ){
+			if( ptrs == null || ptrs.isEmpty() )
 				return;
-			}
-		
-			char chars[] = ( _ptrOperator == null ) ? ptr.toCharArray() : ( ptr + _ptrOperator ).toCharArray();
-		
-			int nChars = ( _ptrOperator == null ) ? ptr.length() : ptr.length() + _ptrOperator.length();
-		
-			char dest[] = new char [ nChars ];
-			int j = 0;
-		
-			char currChar, nextChar, tempChar;
-		
-			for( int i = 0; i < nChars; i++ ){
-				currChar = chars[ i ];
-				nextChar = ( i + 1 < nChars ) ? chars[ i + 1 ] : 0;
-			
-				switch( currChar ){
-					case '&':{
-						switch( nextChar ){
-							case '[':
-								tempChar = ( i + 2 < nChars ) ? chars[ i + 2 ] : 0;
-								if( tempChar == ']' ){
-									i++;
-									nextChar = '*'; 
+				
+			int size = ptrs.size();
+			Iterator iter = ptrs.iterator();
+			PtrOp op = null;
+			for( int i = size; i > 0; i-- ){
+				op = (PtrOp)iter.next();
+				if( op.getType() == PtrOp.t_pointer ){
+					//indirection operator, can only be applied to a pointer
+					if( hasPtrOperators() ){
+						PtrOp first = (PtrOp)getPtrOperators().getFirst();
+						if( first.getType() == PtrOp.t_pointer )
+						{
+							getPtrOperators().removeFirst();
+							if( op.isConst() || op.isVolatile() ){
+								
+								if( hasPtrOperators() ){
+									((PtrOp)getPtrOperators().getFirst()).setConst( op.isConst() );
+									((PtrOp)getPtrOperators().getFirst()).setVolatile( op.isVolatile() );
+								} else {
+									PtrOp newOp = new PtrOp( PtrOp.t_undef, op.isConst(), op.isVolatile() );
+									addPtrOperator( newOp );
 								}
-								//fall through to '*'
-							case '*':
-								i++;
-								break;
-							case '&':
-							default:
-								dest[ j++ ] = currChar;
-								break;
-						}
-						break;
-					}
-					case '[':{
-						if( nextChar == ']' ){
-							i++;
-							currChar = '*';
-							nextChar = ( i + 2 < nChars ) ? chars[ i + 2 ] : 0;
+							}
 						}
-						//fall through to '*'
-					}
-					case '*':{
-					
-						if( nextChar == '&' ){
-							i++;
-						} else {
-							dest[ j++ ] = currChar;
-						}
-						break;
+					} else {
+						//???
 					}
-					default:
-						break;
-
+				} else if( op.getType() == PtrOp.t_reference ){
+					//Address-of unary operator, results in pointer to T
+					//TODO or pointer to member
+					PtrOp newOp = new PtrOp( PtrOp.t_pointer, op.isConst(), op.isVolatile() );
+					addPtrOperator( newOp );
 				}
 			}
-		
-			_ptrOperator = new String( dest, 0, j );
 		}
 	
-		public String getInvertedPtrOperator(){
-			if( _ptrOperator == null ){
-				return null;
+		public void addPtrOperator( PtrOp ptr ){
+			if( _ptrOperators == null ){
+				_ptrOperators = new LinkedList();
 			}
+			if( ptr != null )
+				_ptrOperators.add( ptr );	
+		}
 		
-			char chars[] = _ptrOperator.toCharArray();
-			int nChars = _ptrOperator.length();
-		
-			char dest[] = new char [ nChars ];
-			char currChar;
-		
-			for( int i = 0; i < nChars; i++ ){
-				currChar = chars[ i ];
-				switch( currChar ){
-					case '*' :	dest[ i ] = '&'; 		break;
-					case '&' :	dest[ i ] = '*'; 		break;
-					default: 	dest[ i ] = currChar;	break;
-				}
+		public void addPtrOperator( List ptrs ){
+			if( _ptrOperators == null ){
+				_ptrOperators = new LinkedList();
 			}
-		
-			return new String( dest );
+			if( ptrs != null )
+				_ptrOperators.addAll( ptrs );
 		}
-	
+		
 		public boolean getHasDefault(){
 			return _hasDefaultValue;
 		}
@@ -2548,8 +2723,8 @@
 		 * TODO, for now return true if our type is "larger" (based on ordering of
 		 * the type values)
 		 */
-		public boolean canHold( ISymbol.ITypeInfo type ){
-			return getType() >= type.getType();	
+		public boolean canHold( TypeInfo type ){
+			return getType().compareTo( type.getType() ) >= 0;	
 		}
 	
 		public boolean equals( Object t ){
@@ -2560,13 +2735,30 @@
 			TypeInfo type = (TypeInfo)t;
 		
 			boolean result = ( _typeInfo == type._typeInfo );
+			result &= ( _type == type._type );
 			result &= ( _typeDeclaration == type._typeDeclaration );
-			result &= ( _cvQualifier == type._cvQualifier );
-		
-			String op1 = ( _ptrOperator != null && _ptrOperator.equals("") ) ? null : _ptrOperator;
-			String op2 = ( type._ptrOperator != null && type._ptrOperator.equals("") ) ? null : type._ptrOperator;
-			result &= (( op1 != null && op2 != null && op1.equals( op2 ) ) || op1 == op2 );
 		
+			int size1 = (_ptrOperators == null) ? 0 : _ptrOperators.size();
+			int size2 = (type._ptrOperators == null) ? 0 : type._ptrOperators.size();
+			if( size1 == size2 ){
+				if( size1 != 0 ){
+					Iterator iter1 = _ptrOperators.iterator();
+					Iterator iter2 = type._ptrOperators.iterator();
+					
+					PtrOp op1 = null, op2 = null;
+					for( int i = size1; i > 0; i-- ){
+						op1 = (PtrOp)iter1.next();
+						op2 = (PtrOp)iter2.next();
+						
+						if( !op1.equals(op2) ){
+							return false;
+						}
+					}
+				}
+			} else {
+				return false;
+			}
+			
 			return result;
 		}
 	
@@ -2574,15 +2766,15 @@
 			if( isType( t_type ) ){
 				return _typeDeclaration.getName();
 			} else {
-				return _image[ getType() ];
+				return _image[ getType().toInt() ];
 			}
 		}
 
-		private int 		 _typeInfo = 0;
+		private int 	_typeInfo = 0;
+		private eType   _type = t_undef;
 		private ISymbol _typeDeclaration;	
-		private int		 _cvQualifier = 0;
 	
 		private boolean	_hasDefaultValue = false;
-		private String		_ptrOperator;	
+		private LinkedList _ptrOperators;	
 	}
 }

Back to the top