1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Patch for Andrew Niefer

This patch represents a couple of months work (off and on since the 
summer) on Parser Symbol Table support for templates.

This is symbol table support only, not parser support (that still needs to 
be done).

What does work:
- declarations, definitions & instantiations for class templates, function 
templates, & template templates 
- declarations, definitions & instantiations of class template partial 
specializations
- template ordering & argument deduction (allows implicit template 
function instatiation)

What doesn't (yet) work:
- Explicit specializations
- assorted smaller specific cases & bugs & things I havn't thought of yet
This commit is contained in:
John Camelon 2004-02-11 03:07:33 +00:00
parent 843606db1d
commit 409b1021af
28 changed files with 4979 additions and 1241 deletions

View file

@ -1,3 +1,7 @@
2004-02-10 Andrew Niefer
Added new File: ParserSymbolTableTemplateTests.java (contains 30 new tests)
Added new File: FailingTemplateTests.java (contains 5 test stubs for failing cases)
2004-02-10 John Camelon
Added testBug47682() to QuickParseASTTests.java.

View file

@ -0,0 +1,278 @@
/**********************************************************************
* Copyright (c) 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.core.parser.tests;
import junit.framework.TestCase;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
/**
* @author aniefer
*/
public class FailingTemplateTests extends TestCase {
public ParserSymbolTable table = null;
public FailingTemplateTests( String arg )
{
super( arg );
}
public ParserSymbolTable newTable(){
return newTable( ParserLanguage.CPP );
}
public ParserSymbolTable newTable( ParserLanguage language ){
table = new ParserSymbolTable( language, ParserMode.COMPLETE_PARSE );
return table;
}
/**
* These tests represent code snippets from the ANSI C++ spec
*/
/**
* template < class T > struct A {
* void f( int );
* template < class T2 > void f( T2 );
* };
*
* template <> void A<int>::f(int) {} //non-template member
* template <> template<> void A<int>::f<>( int ) {} //template member
*
* int main(){
* A< char > ac;
* ac.f( 1 ); //non-template
* ac.f( 'c' ); //template
* ac.f<>(1); //template
* }
* @throws Exception
*/
public void test_14_5_2__2_MemberFunctionTemplates() throws Exception{
//This code snippet is misleading, the two definitions are actually
//explicit specializations for T = int, and so would not be used
//below or A< char >. This needs to be rewritten.
// newTable();
//
// ITemplateSymbol templateA = table.newTemplateSymbol( "A" );
// ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
// templateA.addParameter( T );
//
// table.getCompilationUnit().addSymbol( templateA );
//
// IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_struct );
// templateA.addSymbol( A );
//
// IParameterizedSymbol f1 = table.newParameterizedSymbol("f", TypeInfo.t_function );
// f1.addParameter( TypeInfo.t_int, 0, null, false );
// f1.setIsForwardDeclaration( true );
// A.addSymbol( f1 );
//
// ITemplateSymbol templateF = table.newTemplateSymbol( "f" );
// ISymbol T2 = table.newSymbol( "T2", TypeInfo.t_templateParameter );
//
// IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
// f2.addParameter( T2, null, false );
// f2.setIsForwardDeclaration( true );
// templateF.addSymbol( f2 );
//
// A.addSymbol( templateF );
//
// List args = new LinkedList();
// args.add( new TypeInfo( TypeInfo.t_int,0, null ) );
// ITemplateFactory factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", new LinkedList(), args );
//
// LinkedList params = new LinkedList();
// params.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
// ISymbol look = factory.lookupMemberFunctionForDefinition( "f", params );
// assertEquals( look, f1 );
//
// IParameterizedSymbol f1Def = table.newParameterizedSymbol( "f", TypeInfo.t_function );
// f1Def.addParameter( TypeInfo.t_int, 0, null, false );
// look.setTypeSymbol( f1Def );
// factory.addSymbol( f1Def );
//
// factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", new LinkedList(), args );
// assertNotNull( factory );
//
// args.clear();
// args.add(table.newSymbol( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_int ) );
// factory = factory.lookupTemplateForMemberDefinition( "f", new LinkedList(), new LinkedList(), args );
}
/**
* A specialization of a member function template does not override a virtual
* function from a base class.
*
* class B {
* virtual void f( int );
* };
*
* class D : public B{
* template < class T > void f( T );
* };
*
* template <> void D::f< int > ( int ) {} //does not override B::f( int );
*
* void main(){
* D d;
* d.f( 1 ); //calls B::f( int )
* d.f<>( 1 ); //calls D::f<int>( int );
* }
* @throws Exception
*/
public void test_14_5_2__4_VirtualBaseClassFunctions() throws Exception{
//bug 51483 TBD
}
/**
* template < class T = int > struct A {
* static int x;
* };
*
* template <> struct A< double > {}; //specialize T == double
* template <> struct A<> {}; //specialize T == int
*
* template <> int A< char >::x = 0;
* template <> int A< float >::x = 0.5;
*
* @throws Exception
*/
public void test_14_7__3_ExplicitSpecialization() throws Exception{
//bug 51485
}
/**
* Each class template specialization instantiated from a template has its own
* copy of any static members
*
* template < class T > class X {
* static T s;
* }
*
* template < class T > T X<T>::s = 0;
*
* X<int> a; //a.s has type int
* X<char *> b; //b.s has type char *
* @throws Exception
*/
public void test_14_7__6_ExplicitSpecializationStaticMembers() throws Exception{
//bug 51485
}
/**
* template<class T> void f( void (*) (T, int) );
* template<class T> void foo( T, int );
*
* void g( int, int );
* void g( char, int );
*
* void h( int, int, int );
* void h( char, int );
*
* int m(){
* f( &g ); //error, ambiguous
* f( &h ); //ok, h(char, int) is a unique match
* f( &foo ); //error, foo is a template
* }
*
* @throws Exception
*/
public void test_14_8_2_4__16_ArgumentDeduction() throws Exception{
//This test will require resolving the address of an overloaded function
//without arguments. bug 45764
// newTable();
//
// ITemplateSymbol templateF = table.newTemplateSymbol( "f" );
//
// ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
// templateF.addParameter( T );
//
// IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
//
// IParameterizedSymbol fParam = table.newParameterizedSymbol( "", TypeInfo.t_function );
// fParam.setIsTemplateMember( true );
// fParam.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
// fParam.addParameter( T, null, false );
// fParam.addParameter( TypeInfo.t_int, 0, null, false );
// fParam.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
//
// f.addParameter( fParam );
//
// templateF.addSymbol( f );
// table.getCompilationUnit().addSymbol( templateF );
//
// ITemplateSymbol templateFoo = table.newTemplateSymbol( "foo" );
// T = table.newSymbol( "T", TypeInfo.t_templateParameter );
// templateFoo.addParameter( T );
//
// IParameterizedSymbol foo = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
// foo.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
// foo.addParameter( T, null, false );
// foo.addParameter( TypeInfo.t_int, 0, null, false );
//
// templateFoo.addSymbol( foo );
// table.getCompilationUnit().addSymbol( templateFoo );
//
// IParameterizedSymbol g1 = table.newParameterizedSymbol( "g", TypeInfo.t_function );
// g1.addParameter( TypeInfo.t_int, 0, null, false );
// g1.addParameter( TypeInfo.t_int, 0, null, false );
// table.getCompilationUnit().addSymbol( g1 );
//
// IParameterizedSymbol g2 = table.newParameterizedSymbol( "g", TypeInfo.t_function );
// g2.addParameter( TypeInfo.t_char, 0, null, false );
// g2.addParameter( TypeInfo.t_int, 0, null, false );
// table.getCompilationUnit().addSymbol( g2 );
//
// IParameterizedSymbol h1 = table.newParameterizedSymbol( "h", TypeInfo.t_function );
// h1.addParameter( TypeInfo.t_int, 0, null, false );
// h1.addParameter( TypeInfo.t_int, 0, null, false );
// h1.addParameter( TypeInfo.t_int, 0, null, false );
// table.getCompilationUnit().addSymbol( h1 );
//
// IParameterizedSymbol h2 = table.newParameterizedSymbol( "h", TypeInfo.t_function );
// h2.addParameter( TypeInfo.t_char, 0, null, false );
// h2.addParameter( TypeInfo.t_int, 0, null, false );
// table.getCompilationUnit().addSymbol( h2 );
//
//
//
// List args = new LinkedList();
//
//
// ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", args );
// assertTrue( look != null );
// assertTrue( look.isTemplateInstance() );
// assertEquals( look.getInstantiatedSymbol(), f );
//
// look = table.getCompilationUnit().lookup( "foo" );
// assertTrue( look != null );
// args.clear();
// TypeInfo arg = new TypeInfo( TypeInfo.t_type, 0, look );
// arg.addOperatorExpression( TypeInfo.OperatorExpression.addressof );
// args.add( arg );
//
// try{
// look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", args );
// assertTrue( false );
// }catch ( ParserSymbolTableException e ){
// assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateParameter );
// }
}
}

View file

@ -41,7 +41,6 @@ import org.eclipse.cdt.internal.core.parser.pst.IUsingDirectiveSymbol;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException;
import org.eclipse.cdt.internal.core.parser.pst.StandardSymbolExtension;
import org.eclipse.cdt.internal.core.parser.pst.TemplateInstance;
import org.eclipse.cdt.internal.core.parser.pst.TypeFilter;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Mark;
@ -1970,391 +1969,6 @@ public class ParserSymbolTableTest extends TestCase {
assertEquals( C.getUsingDirectives().size(), 0 );
}
/**
*
* @throws Exception
*
* template < class T > class A : public T {};
*
* class B
* {
* int i;
* }
*
* A<B> a;
* a.i; //finds B::i;
*/
public void testTemplateParameterAsParent() throws Exception{
newTable();
IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol param = table.newSymbol( "T", TypeInfo.t_undef );
template.addParameter( param );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
template.addSymbol( A );
A.addParent( param );
table.getCompilationUnit().addSymbol( template );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
ISymbol i = table.newSymbol( "i", TypeInfo.t_int );
B.addSymbol( i );
TypeInfo type = new TypeInfo( TypeInfo.t_class, 0, B );
LinkedList args = new LinkedList();
args.add( type );
TemplateInstance instance = table.getCompilationUnit().templateLookup( "A", args );
assertEquals( instance.getInstantiatedSymbol(), A );
ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
a.setTypeSymbol( instance );
table.getCompilationUnit().addSymbol( a );
ISymbol look = table.getCompilationUnit().lookup( "a" );
assertEquals( look, a );
ISymbol symbol = a.getTypeSymbol();
assertEquals( symbol, instance );
look = ((IContainerSymbol)instance.getInstantiatedSymbol()).lookup( "i" );
assertEquals( look, i );
}
/**
*
* @throws Exception
*
* template < class T > class A { T t; }
* class B : public A< int > { }
*
* B b;
* b.t; //finds A::t, will be type int
*/
public void testTemplateInstanceAsParent() throws Exception{
newTable();
IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol param = table.newSymbol( "T", TypeInfo.t_undef );
template.addParameter( param );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
ISymbol look = template.lookup( "T" );
assertEquals( look, param );
t.setTypeSymbol( param );
template.addSymbol( A );
A.addSymbol( t );
table.getCompilationUnit().addSymbol( template );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
TypeInfo type = new TypeInfo( TypeInfo.t_int, 0 , null );
LinkedList args = new LinkedList();
args.add( type );
look = table.getCompilationUnit().templateLookup( "A", args );
assertTrue( look instanceof TemplateInstance );
B.addParent( look );
table.getCompilationUnit().addSymbol( B );
ISymbol b = table.newSymbol( "b", TypeInfo.t_type );
b.setTypeSymbol( B );
table.getCompilationUnit().addSymbol( b );
look = table.getCompilationUnit().lookup( "b" );
assertEquals( look, b );
look = ((IDerivableContainerSymbol) b.getTypeSymbol()).lookup( "t" );
assertTrue( look instanceof TemplateInstance );
TemplateInstance instance = (TemplateInstance) look;
assertEquals( instance.getInstantiatedSymbol(), t );
assertTrue( instance.isType( TypeInfo.t_int ) );
}
/**
* The scope of a template-parameter extends from its point of declaration
* until the end of its template. In particular, a template parameter can be used
* in the declaration of a subsequent template-parameter and its default arguments.
* @throws Exception
*
* template< class T, class U = T > class X
* {
* T t;
* U u;
* };
*
* X< char > x;
* x.t;
* x.u;
*/
public void testTemplateParameterDefaults() throws Exception{
newTable();
IParameterizedSymbol template = table.newParameterizedSymbol( "X", TypeInfo.t_template );
ISymbol paramT = table.newSymbol( "T", TypeInfo.t_undef );
template.addParameter( paramT );
ISymbol look = template.lookup( "T" );
assertEquals( look, paramT );
ISymbol paramU = table.newSymbol( "U", TypeInfo.t_undef );
paramU.getTypeInfo().setDefault( new TypeInfo( TypeInfo.t_type, 0, look ) );
template.addParameter( paramU );
IDerivableContainerSymbol X = table.newDerivableContainerSymbol( "X", TypeInfo.t_class );
template.addSymbol( X );
look = X.lookup( "T" );
assertEquals( look, paramT );
ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
t.setTypeSymbol( look );
X.addSymbol( t );
look = X.lookup( "U" );
assertEquals( look, paramU );
ISymbol u = table.newSymbol( "u", TypeInfo.t_type );
u.setTypeSymbol( look );
X.addSymbol( u );
table.getCompilationUnit().addSymbol( template );
TypeInfo type = new TypeInfo( TypeInfo.t_char, 0, null );
LinkedList args = new LinkedList();
args.add( type );
look = table.getCompilationUnit().templateLookup( "X", args );
assertTrue( look instanceof TemplateInstance );
TemplateInstance instance = (TemplateInstance) look;
look = ((IDerivableContainerSymbol) instance.getInstantiatedSymbol()).lookup( "t" );
assertTrue( look instanceof TemplateInstance );
assertTrue( ((TemplateInstance) look).isType( TypeInfo.t_char ) );
look = ((IDerivableContainerSymbol) instance.getInstantiatedSymbol()).lookup( "u" );
assertTrue( look instanceof TemplateInstance );
assertTrue( ((TemplateInstance) look).isType( TypeInfo.t_char ) );
}
/**
*
* @throws Exception
* template < class T > class A {
* T t;
* };
* class B {};
* void f( char c ) {}
* void f( A<B> b ) { ... }
* void f( int i ) {}
*
* A<B> a;
* f( a ); //calls f( A<B> )
*
*/
public void testTemplateParameterAsFunctionArgument() throws Exception{
newTable();
IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol paramT = table.newSymbol( "T", TypeInfo.t_undef );
template.addParameter( paramT );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
template.addSymbol( A );
ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
t.setTypeSymbol( paramT );
A.addSymbol( t );
table.getCompilationUnit().addSymbol( template );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( B );
IParameterizedSymbol temp = (IParameterizedSymbol) table.getCompilationUnit().lookup( "A" );
assertEquals( temp, template );
LinkedList args = new LinkedList();
TypeInfo arg = new TypeInfo( TypeInfo.t_type, 0, B );
args.add( arg );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.addParameter( TypeInfo.t_char, 0, null, false );
table.getCompilationUnit().addSymbol( f1 );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f2.addParameter( temp.instantiate( args ), null, false );
table.getCompilationUnit().addSymbol( f2 );
IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f3.addParameter( TypeInfo.t_int, 0, null, false );
table.getCompilationUnit().addSymbol( f3 );
ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
a.setTypeSymbol( temp.instantiate( args ) );
table.getCompilationUnit().addSymbol( a );
LinkedList params = new LinkedList();
params.add( new TypeInfo( TypeInfo.t_type, 0, a ) );
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", params );
assertEquals( look, f2 );
}
/**
*
* template < class T1, class T2, int I > class A {} //#1
* template < class T, int I > class A < T, T*, I > {} //#2
* template < class T1, class T2, int I > class A < T1*, T2, I > {} //#3
* template < class T > class A < int, T*, 5 > {} //#4
* template < class T1, class T2, int I > class A < T1, T2*, I > {} //#5
*
* A <int, int, 1> a1; //uses #1
* A <int, int*, 1> a2; //uses #2, T is int, I is 1
* A <int, char*, 5> a3; //uses #4, T is char
* A <int, char*, 1> a4; //uses #5, T is int, T2 is char, I is1
* A <int*, int*, 2> a5; //ambiguous, matches #3 & #5.
*
* @throws Exception
*/
//TODO
public void incompletetestTemplateSpecialization() throws Exception{
newTable();
IDerivableContainerSymbol cls1 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IDerivableContainerSymbol cls2 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IDerivableContainerSymbol cls3 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IDerivableContainerSymbol cls4 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IDerivableContainerSymbol cls5 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IParameterizedSymbol template1 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol T1p1 = table.newSymbol( "T1", TypeInfo.t_undef );
ISymbol T1p2 = table.newSymbol( "T2", TypeInfo.t_undef );
ISymbol T1p3 = table.newSymbol( "I", TypeInfo.t_int );
template1.addParameter( T1p1 );
template1.addParameter( T1p2 );
template1.addParameter( T1p3 );
template1.addSymbol( cls1 );
table.getCompilationUnit().addSymbol( template1 );
IParameterizedSymbol template2 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol T2p1 = table.newSymbol( "T", TypeInfo.t_undef );
ISymbol T2p2 = table.newSymbol( "I", TypeInfo.t_int );
template2.addParameter( T2p1 );
template2.addParameter( T2p2 );
ISymbol T2a1 = table.newSymbol( "T", TypeInfo.t_undef );
ISymbol T2a2 = table.newSymbol( "T", TypeInfo.t_undef );
T2a2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
ISymbol T2a3 = table.newSymbol( "I", TypeInfo.t_int );
template2.addArgument( T2a1 );
template2.addArgument( T2a2 );
template2.addArgument( T2a3 );
template2.addSymbol( cls2 );
template1.addSpecialization( template2 );
IParameterizedSymbol template3 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol T3p1 = table.newSymbol( "T1", TypeInfo.t_undef );
ISymbol T3p2 = table.newSymbol( "T2", TypeInfo.t_undef );
ISymbol T3p3 = table.newSymbol( "I", TypeInfo.t_int );
template3.addParameter( T3p1 );
template3.addParameter( T3p2 );
template3.addParameter( T3p3 );
ISymbol T3a1 = table.newSymbol( "T1", TypeInfo.t_undef );
T3a1.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
ISymbol T3a2 = table.newSymbol( "T2", TypeInfo.t_undef );
ISymbol T3a3 = table.newSymbol( "I", TypeInfo.t_int );
template3.addArgument( T3a1 );
template3.addArgument( T3a2 );
template3.addArgument( T3a3 );
template3.addSymbol( cls3 );
template1.addSpecialization( template3 );
IParameterizedSymbol template4 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol T4p1 = table.newSymbol( "T", TypeInfo.t_undef );
template4.addParameter( T4p1 );
ISymbol T4a1 = table.newSymbol( "", TypeInfo.t_int );
ISymbol T4a2 = table.newSymbol( "T", TypeInfo.t_undef );
T4a2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
ISymbol T4a3 = table.newSymbol( "", TypeInfo.t_int );
T4a3.getTypeInfo().setDefault( new Integer(5) );
template4.addArgument( T4a1 );
template4.addArgument( T4a2 );
template4.addArgument( T4a3 );
template4.addSymbol( cls4 );
template1.addSpecialization( template4 );
IParameterizedSymbol template5 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol T5p1 = table.newSymbol( "T1", TypeInfo.t_undef );
ISymbol T5p2 = table.newSymbol( "T2", TypeInfo.t_undef );
ISymbol T5p3 = table.newSymbol( "I", TypeInfo.t_int );
template5.addParameter( T5p1 );
template5.addParameter( T5p2 );
template5.addParameter( T5p3 );
ISymbol T5a1 = table.newSymbol( "T1", TypeInfo.t_undef );
ISymbol T5a2 = table.newSymbol( "T2", TypeInfo.t_undef );
T5a1.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
ISymbol T5a3 = table.newSymbol( "I", TypeInfo.t_int );
template5.addArgument( T5a1 );
template5.addArgument( T5a2 );
template5.addArgument( T5a3 );
template5.addSymbol( cls5 );
template1.addSpecialization( template5 );
IParameterizedSymbol a = (IParameterizedSymbol) table.getCompilationUnit().lookup( "A" );
LinkedList args = new LinkedList();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) );
TemplateInstance a1 = a.instantiate( args );
assertEquals( a1.getInstantiatedSymbol(), cls1 );
args.clear();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) );
TemplateInstance a2 = a.instantiate( args );
assertEquals( a2.getInstantiatedSymbol(), cls2 );
args.clear();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(5) ) );
TemplateInstance a3 = a.instantiate( args );
assertEquals( a3.getInstantiatedSymbol(), cls4 );
args.clear();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) );
TemplateInstance a4 = a.instantiate( args );
assertEquals( a4.getInstantiatedSymbol(), cls5 );
args.clear();
args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(2) ) );
try{
a.instantiate( args );
} catch ( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
}
/**
* class A;
*

View file

@ -30,6 +30,7 @@ public class ParserTestSuite extends TestCase {
suite.addTestSuite(ExprEvalTest.class);
suite.addTestSuite(QuickParseASTTests.class);
suite.addTestSuite(ParserSymbolTableTest.class);
suite.addTestSuite(ParserSymbolTableTemplateTests.class );
suite.addTestSuite(CModelElementsTests.class);
suite.addTestSuite(CompletionParseTest.class);
// suite.addTestSuite(MacroTests.class);

View file

@ -1,6 +1,17 @@
2004-02-10 John Camelon
Workaround for Bug 51502 - Parser spins on particular file (Scalability)
2004-02-10 Andrew Niefer
Templates in the symbol table (org.eclipse.cdt.internal.core.parser.pst)
ITemplateFactory.java
ITemplateSymbol.java
DeferredTemplateInstance.java
ParserSymbolTableError.java
TemplateEngine.java
TemplateFactory.java
TemplateSymbol.java
Most of the other main symbol table files (BasicSymbol, ContainerSymbol, etc) were modified
2004-02-10 John Camelon
Fixed Bug 51302 - Content Assist: No completion list available following namespace declaration.

View file

@ -1,8 +1,15 @@
/**********************************************************************
* Copyright (c) 2003, 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
/*
* Created on Nov 4, 2003
*
* To change the template for this generated file go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
package org.eclipse.cdt.internal.core.parser.pst;
@ -54,6 +61,17 @@ public class BasicSymbol implements Cloneable, ISymbol
return copy;
}
public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
if( !isTemplateMember() && !getContainingSymbol().isTemplateMember() ){
return null;
}
ISymbol newSymbol = (ISymbol) clone();
newSymbol.setTypeInfo( TemplateEngine.instantiateTypeInfo( newSymbol.getTypeInfo(), template, argMap ) );
newSymbol.setInstantiatedSymbol( this );
return newSymbol;
}
public String getName() { return _name; }
public void setName(String name) { _name = name; }
@ -160,14 +178,14 @@ public class BasicSymbol implements Cloneable, ISymbol
public void setIsTemplateMember( boolean isMember ){
_isTemplateMember = isMember;
}
public ISymbol getTemplateInstance(){
return _templateInstance;
public boolean isTemplateInstance(){
return ( _instantiatedSymbol != null );
}
public void setTemplateInstance( TemplateInstance instance ){
_templateInstance = instance;
public ISymbol getInstantiatedSymbol(){
return _instantiatedSymbol;
}
public Map getArgumentMap(){
return null;
public void setInstantiatedSymbol( ISymbol symbol ){
_instantiatedSymbol = symbol;
}
public boolean getIsInvisible(){
@ -183,7 +201,8 @@ public class BasicSymbol implements Cloneable, ISymbol
private IContainerSymbol _containingScope; //the scope that contains us
private int _depth; //how far down the scope stack we are
private boolean _isInvisible = false; //used by friend declarations (11.4-9)
private boolean _isTemplateMember = false;
private TemplateInstance _templateInstance;
private boolean _isInvisible = false; //used by friend declarations (11.4-9)
private boolean _isTemplateMember = false;
private ISymbol _instantiatedSymbol = null;
}

View file

@ -60,10 +60,77 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
copy._containedSymbols = ( _containedSymbols != null )? (Map)((TreeMap) _containedSymbols).clone() : null;
else
copy._containedSymbols = ( _containedSymbols != null )? (Map)((HashMap) _containedSymbols).clone() : null;
copy._contents = ( _contents != null )? (LinkedList) _contents.clone() : null;
return copy;
}
public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
if( !isTemplateMember() || template == null ){
return null;
}
ContainerSymbol newContainer = (ContainerSymbol) super.instantiate( template, argMap );
Iterator iter = getContentsIterator();
newContainer.getContainedSymbols().clear();
if( newContainer._contents != null ){
newContainer._contents.clear();
IExtensibleSymbol containedSymbol = null;
ISymbol newSymbol = null;
while( iter.hasNext() ){
containedSymbol = (IExtensibleSymbol) iter.next();
if( containedSymbol instanceof IUsingDirectiveSymbol ){
newContainer._contents.add( containedSymbol );
} else {
ISymbol symbol = (ISymbol) containedSymbol;
if( symbol.isForwardDeclaration() && symbol.getTypeSymbol() != null ){
continue;
}
Map instanceMap = argMap;
if( template.getDefinitionParameterMap() != null &&
template.getDefinitionParameterMap().containsKey( containedSymbol ) )
{
Map defMap = (Map) template.getDefinitionParameterMap().get( containedSymbol );
instanceMap = new HashMap();
Iterator i = defMap.keySet().iterator();
while( i.hasNext() ){
ISymbol p = (ISymbol) i.next();
instanceMap.put( p, argMap.get( defMap.get( p ) ) );
}
}
newSymbol = ((ISymbol)containedSymbol).instantiate( template, instanceMap );
newSymbol.setContainingSymbol( newContainer );
newContainer._contents.add( newSymbol );
if( newContainer.getContainedSymbols().containsKey( newSymbol.getName() ) ){
Object obj = newContainer.getContainedSymbols().get( newSymbol.getName() );
if( obj instanceof List ){
((List) obj).add( obj );
} else {
List list = new LinkedList();
list.add( obj );
list.add( newSymbol );
newContainer.getContainedSymbols().put( newSymbol.getName(), list );
}
} else {
newContainer.getContainedSymbols().put( newSymbol.getName(), newSymbol );
}
}
}
}
return newContainer;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
@ -83,13 +150,16 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
}
}
//Templates contain 1 declaration
if( getType() == TypeInfo.t_template ){
//declaration must be a class or a function
if( ( obj.getType() != TypeInfo.t_class && obj.getType() != TypeInfo.t_function ) ||
( getContainedSymbols() != null && getContainedSymbols().size() == 1 ) )
{
//throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
if( obj.isType( TypeInfo.t_template ) ){
if( ! TemplateEngine.canAddTemplate( containing, (ITemplateSymbol) obj ) ) {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
}
}
//14.6.1-4 A Template parameter shall not be redeclared within its scope.
if( isTemplateMember() || isType( TypeInfo.t_template ) ){
if( TemplateEngine.alreadyHasTemplateParameter( this, obj.getName() ) ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_RedeclaredTemplateParam );
}
}
@ -114,7 +184,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
} else if( origObj.getClass() == LinkedList.class ){
origList = (LinkedList)origObj;
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
boolean validOverride = ((origList == null) ? ParserSymbolTable.isValidOverload( origDecl, obj ) : ParserSymbolTable.isValidOverload( origList, obj ) );
@ -220,11 +290,10 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDeclaration(java.lang.String, org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol)
*/
public ISymbol addUsingDeclaration( String name, IContainerSymbol declContext ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_any, null );
LookupData data = new LookupData( name, TypeInfo.t_any );
if( declContext != null ){
data.qualified = true;
data.templateInstance = declContext.getTemplateInstance();
ParserSymbolTable.lookup( data, declContext );
} else {
ParserSymbolTable.lookup( data, this );
@ -291,22 +360,34 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#elaboratedLookup(org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType, java.lang.String)
*/
public ISymbol elaboratedLookup( TypeInfo.eType type, String name ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, type, getTemplateInstance() );
LookupData data = new LookupData( name, type );
ParserSymbolTable.lookup( data, this );
return ParserSymbolTable.resolveAmbiguities( data );
ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
if( isTemplateMember() && found instanceof ITemplateSymbol ) {
return TemplateEngine.instantiateWithinTemplateScope( this, (ITemplateSymbol) found );
}
return found;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookup(java.lang.String)
*/
public ISymbol lookup( String name ) throws ParserSymbolTableException {
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
LookupData data = new LookupData( name, TypeInfo.t_any );
ParserSymbolTable.lookup( data, this );
return ParserSymbolTable.resolveAmbiguities( data );
ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
if( isTemplateMember() && found instanceof ITemplateSymbol ) {
return TemplateEngine.instantiateWithinTemplateScope( this, (ITemplateSymbol) found );
}
return found;
}
/* (non-Javadoc)
@ -341,7 +422,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
* for a definition.
*/
public ISymbol lookupMemberForDefinition( String name ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
LookupData data = new LookupData( name, TypeInfo.t_any );
data.qualified = true;
IContainerSymbol container = this;
@ -360,7 +441,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
}
public IParameterizedSymbol lookupMethodForDefinition( String name, List parameters ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
LookupData data = new LookupData( name, TypeInfo.t_any );
data.qualified = true;
data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
@ -398,7 +479,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
private IContainerSymbol lookupNestedNameSpecifier(String name, IContainerSymbol inSymbol ) throws ParserSymbolTableException{
ISymbol foundSymbol = null;
LookupData data = new LookupData( name, TypeInfo.t_namespace, getTemplateInstance() );
LookupData data = new LookupData( name, TypeInfo.t_namespace );
data.filter.addAcceptedType( TypeInfo.t_class );
data.filter.addAcceptedType( TypeInfo.t_struct );
data.filter.addAcceptedType( TypeInfo.t_union );
@ -406,7 +487,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
data.foundItems = ParserSymbolTable.lookupInContained( data, inSymbol );
if( data.foundItems != null ){
foundSymbol = ParserSymbolTable.resolveAmbiguities( data );//, data.foundItems );
foundSymbol = ParserSymbolTable.resolveAmbiguities( data );
}
if( foundSymbol == null && inSymbol.getContainingSymbol() != null ){
@ -431,7 +512,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedLookup(java.lang.String, org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType)
*/
public ISymbol qualifiedLookup( String name, TypeInfo.eType t ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, t, getTemplateInstance() );
LookupData data = new LookupData( name, t );
data.qualified = true;
ParserSymbolTable.lookup( data, this );
@ -496,7 +577,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
}
}
LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
LookupData data = new LookupData( name, TypeInfo.t_function );
//if parameters == null, thats no parameters, but we need to distinguish that from
//no parameter information at all, so make an empty list.
data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
@ -554,7 +635,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
* include argument dependant scopes
*/
public IParameterizedSymbol memberFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
LookupData data = new LookupData( name, TypeInfo.t_function );
//if parameters == null, thats no parameters, but we need to distinguish that from
//no parameter information at all, so make an empty list.
data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
@ -567,7 +648,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedFunctionLookup(java.lang.String, java.util.List)
*/
public IParameterizedSymbol qualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
LookupData data = new LookupData( name, TypeInfo.t_function );
data.qualified = true;
//if parameters == null, thats no parameters, but we need to distinguish that from
//no parameter information at all, so make an empty list.
@ -581,21 +662,42 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#templateLookup(java.lang.String, java.util.List)
*/
public TemplateInstance templateLookup( String name, List arguments ) throws ParserSymbolTableException
public ISymbol lookupTemplate( String name, List arguments ) throws ParserSymbolTableException
{
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
data.parameters = arguments;
LookupData data = new LookupData( name, TypeInfo.t_any );
ParserSymbolTable.lookup( data, this );
ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
if( found.isType( TypeInfo.t_template ) ){
return ((IParameterizedSymbol) found).instantiate( arguments );
if( (found.isType( TypeInfo.t_templateParameter ) && found.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template) ||
found.isType( TypeInfo.t_template ) )
{
return ((ITemplateSymbol) found).instantiate( arguments );
} else if( found.getContainingSymbol().isType( TypeInfo.t_template ) ){
return ((ITemplateSymbol) found.getContainingSymbol()).instantiate( arguments );
}
return null;
}
public ITemplateFactory lookupTemplateForMemberDefinition( String name, List parameters, List arguments ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_any );
ParserSymbolTable.lookup( data, this );
ISymbol look = ParserSymbolTable.resolveAmbiguities( data );
if( look instanceof ITemplateSymbol ){
ITemplateSymbol template = TemplateEngine.selectTemplateOrSpecialization( (ITemplateSymbol) look, parameters, arguments );
if( template != null ){
return new TemplateFactory( template, parameters );
}
}
return null;
}
public List prefixLookup( TypeFilter filter, String prefix, boolean qualified ) throws ParserSymbolTableException{
LookupData data = new LookupData( prefix, filter, getTemplateInstance() );
LookupData data = new LookupData( prefix, filter );
data.qualified = qualified;
data.mode = ParserSymbolTable.LookupMode.PREFIX;
@ -640,11 +742,9 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
if( node instanceof IASTMember ){
ASTAccessVisibility visibility;
try {
visibility = ParserSymbolTable.getVisibility( symbol, qualifyingSymbol );
} catch (ParserSymbolTableException e) {
return false;
}
visibility = ParserSymbolTable.getVisibility( symbol, qualifyingSymbol );
if( visibility == ASTAccessVisibility.PUBLIC ){
return true;
}
@ -704,61 +804,6 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
return false;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#instantiate(java.util.List)
*/
public TemplateInstance instantiate( List arguments ) throws ParserSymbolTableException{
if( getType() != TypeInfo.t_template ){
return null;
}
//TODO uncomment when template specialization matching & ordering is working
//IParameterizedSymbol template = ParserSymbolTable.matchTemplatePartialSpecialization( this, arguments );
IParameterizedSymbol template = null;
if( template == null ){
template = (IParameterizedSymbol) this;
}
List paramList = template.getParameterList();
int numParams = ( paramList != null ) ? paramList.size() : 0;
if( numParams == 0 ){
return null;
}
HashMap map = new HashMap();
Iterator paramIter = paramList.iterator();
Iterator argIter = arguments.iterator();
ISymbol param = null;
TypeInfo arg = null;
for( int i = 0; i < numParams; i++ ){
param = (ISymbol) paramIter.next();
if( argIter.hasNext() ){
arg = (TypeInfo) argIter.next();
map.put( param, arg );
} else {
Object obj = param.getTypeInfo().getDefault();
if( obj != null && obj instanceof TypeInfo ){
map.put( param, obj );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
}
}
}
if( template.getContainedSymbols().size() != 1 ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
}
Iterator iter = template.getContainedSymbols().keySet().iterator();
IContainerSymbol symbol = (IContainerSymbol) template.getContainedSymbols().get( iter.next() );
TemplateInstance instance = new TemplateInstance( getSymbolTable(), symbol, map );
return instance;
}
protected List getContents(){
if(_contents == null ){

View file

@ -0,0 +1,74 @@
/**********************************************************************
* Copyright (c) 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.pst;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* @author aniefer
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class DeferredTemplateInstance extends BasicSymbol implements IDeferredTemplateInstance {
public DeferredTemplateInstance( ParserSymbolTable table, ITemplateSymbol template, List args ){
super(table, ParserSymbolTable.EMPTY_NAME );
_template = template;
_arguments = new LinkedList( args );
setContainingSymbol( template );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDeferredTemplateInstance#getTemplate()
*/
public ITemplateSymbol getTemplate() {
return _template;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDeferredTemplateInstance#getArgumentMap()
*/
public List getArguments() {
return _arguments;
}
public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
List args = getArguments();
List newArgs = new LinkedList();
Iterator iter = args.iterator();
while( iter.hasNext() ){
TypeInfo arg = (TypeInfo) iter.next();
newArgs.add( TemplateEngine.instantiateTypeInfo( arg, template, argMap ) );
}
ITemplateSymbol deferredTemplate = getTemplate();
if( deferredTemplate.isType( TypeInfo.t_templateParameter ) && argMap.containsKey( deferredTemplate ) ){
TypeInfo i = (TypeInfo) argMap.get( deferredTemplate );
deferredTemplate = (ITemplateSymbol) i.getTypeSymbol();
}
ISymbol instance = deferredTemplate.instantiate( newArgs );
// if( !( instance instanceof IDeferredTemplateInstance ) )
// return instance.instantiate( template, argMap );
// else
return instance;
}
private ITemplateSymbol _template;
private List _arguments;
}

View file

@ -54,6 +54,44 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
return copy;
}
public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
if( !isTemplateMember() ){
return null;
}
DerivableContainerSymbol newSymbol = (DerivableContainerSymbol) super.instantiate( template, argMap );
Iterator parents = getParents().iterator();
newSymbol.getParents().clear();
ParentWrapper wrapper = null, newWrapper = null;
while( parents.hasNext() ){
wrapper = (ParentWrapper) parents.next();
newWrapper = new ParentWrapper( wrapper.getParent(), wrapper.isVirtual(), wrapper.getAccess(), wrapper.getOffset(), wrapper.getReferences() );
ISymbol parent = newWrapper.getParent();
if( parent instanceof IDeferredTemplateInstance ){
newWrapper.setParent( ((IDeferredTemplateInstance)parent).instantiate( template, argMap ) );
} else if( parent.isType( TypeInfo.t_templateParameter ) && argMap.containsKey( parent ) ){
TypeInfo info = (TypeInfo) argMap.get( parent );
newWrapper.setParent( info.getTypeSymbol() );
}
newSymbol.getParents().add( newWrapper );
}
Iterator constructors = getConstructors().iterator();
newSymbol.getConstructors().clear();
IParameterizedSymbol constructor = null;
while( constructors.hasNext() ){
constructor = (IParameterizedSymbol) constructors.next();
newSymbol.getConstructors().add( constructor.instantiate( template, argMap ) );
}
//TODO: friends
return newSymbol;
}
public void addSymbol(ISymbol symbol) throws ParserSymbolTableException {
super.addSymbol( symbol );
@ -149,7 +187,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
*/
public IParameterizedSymbol lookupConstructor( List parameters ) throws ParserSymbolTableException
{
LookupData data = new LookupData( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_constructor, null );
LookupData data = new LookupData( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_constructor );
data.parameters = parameters;
List constructors = new LinkedList();
@ -194,7 +232,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
//of function will have them from the original declaration
boolean foundThis = false;
LookupData data = new LookupData( ParserSymbolTable.THIS, TypeInfo.t_any, null );
LookupData data = new LookupData( ParserSymbolTable.THIS, TypeInfo.t_any );
try {
Map map = ParserSymbolTable.lookupInContained( data, obj );
foundThis = map.containsKey( data.name );
@ -274,7 +312,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
* class scope.
*/
public ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
LookupData data = new LookupData( name, TypeInfo.t_any );
IContainerSymbol enclosing = getContainingSymbol();
if( enclosing != null && enclosing.isType( TypeInfo.t_namespace, TypeInfo.t_union ) ){
@ -290,7 +328,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
}
public IParameterizedSymbol lookupFunctionForFriendship( String name, List parameters ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
LookupData data = new LookupData( name, TypeInfo.t_any );
data.parameters = parameters;
@ -373,6 +411,15 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
this.references = r;
}
public Object clone(){
try{
return super.clone();
} catch ( CloneNotSupportedException e ){
//should not happen
return null;
}
}
public void setParent( ISymbol parent ){ this.parent = parent; }
public ISymbol getParent() { return parent; }
@ -380,7 +427,6 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
public void setVirtual( boolean virtual ){ isVirtual = virtual; }
public ASTAccessVisibility getVisibility(){ return access; }
public ASTAccessVisibility getAccess() { return access; }
public int getOffset() { return offset; }

View file

@ -10,9 +10,6 @@
******************************************************************************/
/*
* Created on May 9, 2003
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package org.eclipse.cdt.internal.core.parser.pst;
@ -52,8 +49,11 @@ public interface IContainerSymbol extends ISymbol {
public IParameterizedSymbol unqualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException;
public IParameterizedSymbol memberFunctionLookup( String name, List parameters ) throws ParserSymbolTableException;
public IParameterizedSymbol qualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException;
public TemplateInstance templateLookup( String name, List arguments ) throws ParserSymbolTableException;
public TemplateInstance instantiate( List arguments ) throws ParserSymbolTableException;
public ISymbol lookupTemplate( String name, List arguments ) throws ParserSymbolTableException;
public ITemplateFactory lookupTemplateForMemberDefinition( String name, List templateParameters,
List templateArguments ) throws ParserSymbolTableException;
public boolean isVisible( ISymbol symbol, IContainerSymbol qualifyingSymbol );

View file

@ -0,0 +1,24 @@
/**********************************************************************
* Copyright (c) 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.pst;
import java.util.List;
/**
* @author aniefer
*/
public interface IDeferredTemplateInstance extends ISymbol {
public ITemplateSymbol getTemplate();
public List getArguments();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@ -44,13 +44,13 @@ public interface IDerivableContainerSymbol extends IContainerSymbol {
public List getFriends();
public interface IParentSymbol{
public interface IParentSymbol extends Cloneable {
public Object clone();
public void setParent( ISymbol parent );
public ISymbol getParent();
public boolean isVirtual();
public void setVirtual( boolean virtual );
public ASTAccessVisibility getVisibility();
public ASTAccessVisibility getAccess();
public int getOffset();
public List getReferences();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@ -32,10 +32,6 @@ public interface IParameterizedSymbol extends IContainerSymbol {
public void addParameter( TypeInfo.eType type, int info, TypeInfo.PtrOp ptrOp, boolean hasDefault );
public void addParameter( ISymbol typeSymbol, TypeInfo.PtrOp ptrOp, boolean hasDefault );
public void addArgument( ISymbol arg );
public List getArgumentList();
//public void setArgumentList( List list );
public Map getParameterMap();
public List getParameterList();
//public void setParameterList( List list );
@ -47,8 +43,4 @@ public interface IParameterizedSymbol extends IContainerSymbol {
public void setHasVariableArgs( boolean var );
public boolean hasVariableArgs( );
public boolean hasSpecializations();
public void addSpecialization( IParameterizedSymbol spec );
public List getSpecializations();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* Copyright (c) 2003,2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@ -16,12 +16,21 @@
*/
package org.eclipse.cdt.internal.core.parser.pst;
import java.util.List;
/**
* @author aniefer
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public interface ISpecializedSymbol extends IParameterizedSymbol {
public interface ISpecializedSymbol extends ITemplateSymbol {
public void addArgument( TypeInfo arg );
public List getArgumentList();
public ITemplateSymbol getPrimaryTemplate();
public void setPrimaryTemplate( ITemplateSymbol templateSymbol );
}

View file

@ -21,6 +21,8 @@ public interface ISymbol extends Cloneable, IExtensibleSymbol {
public Object clone();
public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException;
public void setName(String name);
public String getName();
@ -43,12 +45,12 @@ public interface ISymbol extends Cloneable, IExtensibleSymbol {
public List getPtrOperators();
public void addPtrOperator( TypeInfo.PtrOp ptrOp );
public boolean isTemplateInstance();
public ISymbol getInstantiatedSymbol();
public void setInstantiatedSymbol( ISymbol symbol );
public boolean isTemplateMember();
public void setIsTemplateMember( boolean isMember );
public ISymbol getTemplateInstance();
public Map getArgumentMap();
public void setTemplateInstance( TemplateInstance instance );
public int getDepth();
public boolean getIsInvisible();
public void setIsInvisible( boolean invisible );

View file

@ -0,0 +1,31 @@
/**********************************************************************
* Copyright (c) 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.pst;
import java.util.List;
/**
* @author aniefer
**/
public interface ITemplateFactory {
public void addSymbol( ISymbol symbol ) throws ParserSymbolTableException;
public ISymbol lookupMemberForDefinition( String name ) throws ParserSymbolTableException;
public IParameterizedSymbol lookupMemberFunctionForDefinition( String name, List params ) throws ParserSymbolTableException;
public ITemplateFactory lookupTemplateForMemberDefinition( String name, List templateParameters,
List templateArguments ) throws ParserSymbolTableException;
public ITemplateSymbol getPrimaryTemplate();
public ISymbol lookupParam( String name ) throws ParserSymbolTableException;
}

View file

@ -0,0 +1,40 @@
/**********************************************************************
* Copyright (c) 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.pst;
import java.util.List;
import java.util.Map;
/**
* @author aniefer
*/
public interface ITemplateSymbol extends IParameterizedSymbol {
public void addTemplateParameter( ISymbol param ) throws ParserSymbolTableException;
public boolean hasSpecializations();
public void addSpecialization( ISpecializedSymbol spec );
public List getSpecializations();
public IContainerSymbol getTemplatedSymbol();
public Map getDefinitionParameterMap();
public ISpecializedSymbol findSpecialization(List parameters, List arguments);
public IContainerSymbol findInstantiation( List arguments );
public List findArgumentsFor( IContainerSymbol instance );
public void addInstantiation( IContainerSymbol instance, List args );
public ISymbol instantiate( List args ) throws ParserSymbolTableException;
public IDeferredTemplateInstance deferredInstance( List args );
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@ -53,12 +53,48 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
else
copy._parameterMap = ( _parameterMap != null ) ? (Map) ((HashMap) _parameterMap).clone() : null;
copy._argumentList = ( _argumentList != null ) ? (LinkedList) _argumentList.clone() : null;
copy._specializations = ( _specializations != null ) ? (LinkedList) _specializations.clone() : null;
return copy;
}
public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
if( !isTemplateMember() ){
return null;
}
ParameterizedSymbol newParameterized = (ParameterizedSymbol) super.instantiate( template, argMap );
if( _returnType != null ){
if( _returnType.isType( TypeInfo.t_templateParameter ) ){
if( argMap.containsKey( _returnType ) ){
newParameterized.setReturnType( getSymbolTable().newSymbol( ParserSymbolTable.EMPTY_NAME ) );
newParameterized.getReturnType().setTypeInfo( (TypeInfo) argMap.get( _returnType ) );
newParameterized.getReturnType().setInstantiatedSymbol( _returnType );
}
} else {
newParameterized.setReturnType( _returnType.instantiate( template, argMap ) );
}
}
Iterator iter = getParameterList().iterator();
newParameterized.getParameterList().clear();
newParameterized.getParameterMap().clear();
ISymbol param = null, newParam = null;
while( iter.hasNext() ){
param = (ISymbol) iter.next();
newParam = param.instantiate( template, argMap );
newParameterized.getParameterList().add( newParam );
if( !newParam.getName().equals( ParserSymbolTable.EMPTY_NAME ) ){
newParameterized.getParameterMap().put( newParam.getName(), newParam );
}
}
return newParameterized;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
@ -113,36 +149,6 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
addParameter( param );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addArgument(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
public void addArgument( ISymbol arg ){
List argumentList = getArgumentList();
argumentList.add( arg );
arg.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
Command command = new AddArgumentCommand( this, arg );
getSymbolTable().pushCommand( command );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getArgumentList()
*/
public List getArgumentList(){
if( _argumentList == null ){
_argumentList = new LinkedList();
}
return _argumentList;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#setArgumentList(java.util.List)
*/
// public void setArgumentList( List list ){
// _argumentList = new LinkedList( list );
// }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterMap()
*/
@ -222,33 +228,6 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
return _returnType;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasSpecializations()
*/
public boolean hasSpecializations(){
return ( _specializations != null && !_specializations.isEmpty() );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addSpecialization(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
*/
public void addSpecialization( IParameterizedSymbol spec ){
List specializationList = getSpecializations();
specializationList.add( spec );
spec.setContainingSymbol( getContainingSymbol() );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getSpecializations()
*/
public List getSpecializations() {
if( _specializations == null ){
_specializations = new LinkedList();
}
return _specializations;
}
public void setHasVariableArgs( boolean var ){
_hasVarArgs = var;
}
@ -277,23 +256,9 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
private ISymbol _param;
}
static private class AddArgumentCommand extends Command{
public AddArgumentCommand( IParameterizedSymbol container, ISymbol arg ){
_decl = container;
_arg = arg;
}
public void undoIt(){
_decl.getArgumentList().remove( _arg );
}
private IParameterizedSymbol _decl;
private ISymbol _arg;
}
private LinkedList _parameterList; //have my cake
private Map _parameterMap; //and eat it too
private LinkedList _specializations; //template specializations
private LinkedList _argumentList; //template specialization arguments
private ISymbol _returnType;
private boolean _hasVarArgs = false; //whether or not this function has variable arguments
}

View file

@ -82,6 +82,10 @@ public class ParserSymbolTable {
public IParameterizedSymbol newParameterizedSymbol( String name, TypeInfo.eType type ){
return new ParameterizedSymbol( this, name, type );
}
public ITemplateSymbol newTemplateSymbol( String name ){
return new TemplateSymbol( this, name );
}
public ISpecializedSymbol newSpecializedSymbol( String name ){
return new SpecializedSymbol( this, name );
}
@ -309,7 +313,7 @@ public class ParserSymbolTable {
if( declarations instanceof SortedMap ){
iterator = ((SortedMap)declarations).tailMap( data.name.toLowerCase() ).keySet().iterator();
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
}
@ -339,41 +343,83 @@ public class ParserSymbolTable {
}
if( lookIn instanceof IParameterizedSymbol ){
Map parameters = ((IParameterizedSymbol)lookIn).getParameterMap();
if( parameters != null ){
iterator = null;
if( data.mode == LookupMode.PREFIX ){
if( parameters instanceof SortedMap ){
iterator = ((SortedMap) parameters).tailMap( data.name.toLowerCase() ).keySet().iterator();
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
}
}
name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name;
while( name != null ){
if( nameMatches( data, name ) ){
obj = parameters.get( name );
obj = collectSymbol( data, obj );
if( obj != null ){
found.put( name, obj );
}
} else {
break;
}
if( iterator != null && iterator.hasNext() ){
name = (String) iterator.next();
} else {
name = null;
}
}
}
lookupInParameters(data, lookIn, found);
}
if( lookIn.isTemplateMember() && data.templateMember == null ){
IContainerSymbol containing = lookIn.getContainingSymbol();
IContainerSymbol outer = (containing != null ) ? containing.getContainingSymbol() : null;
if( ( containing instanceof IDerivableContainerSymbol && outer instanceof ITemplateSymbol) ||
( lookIn instanceof IParameterizedSymbol && containing instanceof ITemplateSymbol ) )
{
data.templateMember = lookIn;
}
}
return found;
}
/**
* @param data
* @param lookIn
* @param found
* @throws ParserSymbolTableException
*/
private static void lookupInParameters(LookupData data, IContainerSymbol lookIn, Map found) throws ParserSymbolTableException {
Object obj;
Iterator iterator;
String name;
if( lookIn instanceof ITemplateSymbol && ((ITemplateSymbol)lookIn).getDefinitionParameterMap() != null ){
ITemplateSymbol template = (ITemplateSymbol) lookIn;
if( data.templateMember != null && template.getDefinitionParameterMap().containsKey( data.templateMember ) ){
Map map = (Map) template.getDefinitionParameterMap().get( data.templateMember );
iterator = map.keySet().iterator();
while( iterator.hasNext() ){
ISymbol symbol = (ISymbol) iterator.next();
if( nameMatches( data, symbol.getName() ) ){
obj = collectSymbol( data, symbol );
if( obj != null ){
found.put( symbol.getName(), obj );
}
}
}
return;
}
}
Map parameters = ((IParameterizedSymbol)lookIn).getParameterMap();
if( parameters != null ){
iterator = null;
if( data.mode == LookupMode.PREFIX ){
if( parameters instanceof SortedMap ){
iterator = ((SortedMap) parameters).tailMap( data.name.toLowerCase() ).keySet().iterator();
} else {
throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
}
name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name;
while( name != null ){
if( nameMatches( data, name ) ){
obj = parameters.get( name );
obj = collectSymbol( data, obj );
if( obj != null ){
found.put( name, obj );
}
} else {
break;
}
if( iterator != null && iterator.hasNext() ){
name = (String) iterator.next();
} else {
name = null;
}
}
}
}
private static boolean nameMatches( LookupData data, String name ){
if( data.mode == LookupMode.PREFIX ){
return name.regionMatches( true, 0, data.name, 0, data.name.length() );
@ -386,15 +432,6 @@ public class ParserSymbolTable {
return true;
}
if( data.templateInstance != null && symbol.isTemplateMember() ){
if( symbol.isType( TypeInfo.t_type ) ){
symbol = symbol.getTypeSymbol();
}
if( symbol.isType( TypeInfo.t_undef ) && symbol.getContainingSymbol().isType( TypeInfo.t_template ) ){
TypeInfo info = (TypeInfo) data.templateInstance.getArgumentMap().get( symbol );
return data.filter.shouldAccept( symbol, info );
}
}
return data.filter.shouldAccept( symbol );
}
@ -409,22 +446,30 @@ public class ParserSymbolTable {
ISymbol symbol = ( iter != null ) ? (ISymbol) iter.next() : (ISymbol) object;
Set functionSet = new HashSet();
Set templateFunctionSet = new HashSet();
ISymbol obj = null;
IContainerSymbol cls = null;
while( symbol != null ){
if( symbol instanceof ITemplateSymbol ){
ISymbol temp = ((ITemplateSymbol)symbol).getTemplatedSymbol();
symbol = ( temp != null ) ? temp : symbol;
}
if( !symbol.getIsInvisible() && checkType( data, symbol ) ){//, data.type, data.upperType ) ){
if( symbol.isTemplateMember() && data.templateInstance != null )
foundSymbol = new TemplateInstance( symbol.getSymbolTable(), symbol, data.templateInstance.getArgumentMap() );
else
foundSymbol = symbol;
foundSymbol = symbol;
if( foundSymbol.isType( TypeInfo.t_function ) ){
if( foundSymbol.isForwardDeclaration() && foundSymbol.getTypeSymbol() != null ){
foundSymbol = foundSymbol.getTypeSymbol();
}
if( foundSymbol.getContainingSymbol().isType( TypeInfo.t_template ) ){
templateFunctionSet.add( foundSymbol );
} else {
functionSet.add( foundSymbol );
}
functionSet.add( foundSymbol );
} else {
//if this is a class-name, other stuff hides it
if( foundSymbol.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
@ -473,6 +518,7 @@ public class ParserSymbolTable {
}
int numFunctions = functionSet.size();
int numTemplateFunctions = templateFunctionSet.size();
boolean ambiguous = false;
@ -481,9 +527,23 @@ public class ParserSymbolTable {
if( obj != null && cls.getContainingSymbol() != obj.getContainingSymbol()){
ambiguous = true;
}
Iterator fnIter = null;
IParameterizedSymbol fn = null;
if( !templateFunctionSet.isEmpty() ){
fnIter = templateFunctionSet.iterator();
for( int i = numTemplateFunctions; i > 0; i-- ){
fn = (IParameterizedSymbol) fnIter.next();
if( cls.getContainingSymbol()!= fn.getContainingSymbol()){
ambiguous = true;
break;
}
}
}
if( !functionSet.isEmpty() ){
Iterator fnIter = functionSet.iterator();
IParameterizedSymbol fn = null;
fnIter = functionSet.iterator();
for( int i = numFunctions; i > 0; i-- ){
fn = (IParameterizedSymbol) fnIter.next();
if( cls.getContainingSymbol()!= fn.getContainingSymbol()){
@ -494,6 +554,17 @@ public class ParserSymbolTable {
}
}
if( numTemplateFunctions > 0 ){
if( data.parameters != null ){
List fns = TemplateEngine.selectTemplateFunctions( templateFunctionSet, data.parameters );
functionSet.addAll( fns );
numFunctions = functionSet.size();
} else {
functionSet.addAll( templateFunctionSet );
numFunctions += numTemplateFunctions;
}
}
if( obj != null && !ambiguous ){
if( numFunctions > 0 ){
ambiguous = true;
@ -526,13 +597,11 @@ public class ParserSymbolTable {
*/
private static Map lookupInParents( LookupData data, ISymbol lookIn ) throws ParserSymbolTableException{
IDerivableContainerSymbol container = null;
/*if( lookIn instanceof TemplateInstance ){
} else*/
if( lookIn instanceof IDerivableContainerSymbol ){
container = (IDerivableContainerSymbol) lookIn;
} else{
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
List scopes = container.getParents();
@ -561,14 +630,7 @@ public class ParserSymbolTable {
{
wrapper = (IDerivableContainerSymbol.IParentSymbol) iterator.next();
ISymbol parent = wrapper.getParent();
if( parent.isType( TypeInfo.t_undef ) && parent.getContainingSymbol().isType( TypeInfo.t_template ) ){
TypeInfo info = (TypeInfo) data.templateInstance.getArgumentMap().get( parent );
if( info.getTypeSymbol() instanceof IDerivableContainerSymbol ){
parent = (IDerivableContainerSymbol) info.getTypeSymbol();
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
}
}
if( !wrapper.isVirtual() || !data.visited.contains( parent ) ){
if( wrapper.isVirtual() ){
data.visited.add( parent );
@ -578,16 +640,7 @@ public class ParserSymbolTable {
//is circular inheritance
if( ! data.inheritanceChain.contains( parent ) ){
//is this name define in this scope?
if( parent instanceof TemplateInstance ){
ISymbol tempInstance = data.templateInstance;
data.templateInstance = (TemplateInstance) parent;
ISymbol instance = ((TemplateInstance)parent).getInstantiatedSymbol();
if( instance instanceof IContainerSymbol )
temp = lookupInContained( data, (IContainerSymbol)instance );
else
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
data.templateInstance = tempInstance;
} else if( parent instanceof IDerivableContainerSymbol ){
if( parent instanceof IDerivableContainerSymbol ){
temp = lookupInContained( data, (IDerivableContainerSymbol) parent );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
@ -707,6 +760,24 @@ public class ParserSymbolTable {
TypeInfo.eType origType = origSymbol.getType();
TypeInfo.eType newType = newSymbol.getType();
if( origType == TypeInfo.t_template ){
ITemplateSymbol template = (ITemplateSymbol) origSymbol;
origSymbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
if( origSymbol == null )
return true;
else
origType = origSymbol.getType();
}
if( newType == TypeInfo.t_template ){
ITemplateSymbol template = (ITemplateSymbol) newSymbol;
newSymbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
if( newSymbol == null )
return true;
else
newType = newSymbol.getType();
}
//handle forward decls
if( origSymbol.getTypeInfo().isForwardDeclaration() ){
if( origSymbol.getTypeSymbol() == newSymbol )
@ -736,7 +807,11 @@ public class ParserSymbolTable {
if( origList.size() == 1 ){
return isValidOverload( (ISymbol)origList.iterator().next(), newSymbol );
} else if ( origList.size() > 1 ){
if( newSymbol.isType( TypeInfo.t_template ) ){
ITemplateSymbol template = (ITemplateSymbol) newSymbol;
newSymbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
}
//the first thing can be a class-name or enumeration name, but the rest
//must be functions. So make sure the newDecl is a function before even
//considering the list
@ -746,13 +821,20 @@ public class ParserSymbolTable {
Iterator iter = origList.iterator();
ISymbol symbol = (ISymbol) iter.next();
boolean valid = isValidOverload( symbol, newSymbol );//( (symbol.getType().compareTo( TypeInfo.t_class ) >= 0 ) && (symbol.getType().compareTo( TypeInfo.t_enumeration ) <= 0 ) );
if( symbol.isType( TypeInfo.t_template ) ){
IParameterizedSymbol template = (IParameterizedSymbol) symbol;
symbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
}
if( !valid && (symbol instanceof IParameterizedSymbol) )
valid = isValidFunctionOverload( (IParameterizedSymbol)symbol, (IParameterizedSymbol)newSymbol );
boolean valid = isValidOverload( symbol, newSymbol );
while( valid && iter.hasNext() ){
symbol = (ISymbol) iter.next();
if( symbol.isType( TypeInfo.t_template ) ){
IParameterizedSymbol template = (IParameterizedSymbol) symbol;
symbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
}
valid = ( symbol instanceof IParameterizedSymbol) && isValidFunctionOverload( (IParameterizedSymbol)symbol, (IParameterizedSymbol)newSymbol );
}
@ -829,6 +911,11 @@ public class ParserSymbolTable {
if( symbol.isType( TypeInfo.t_function ) ){
functionList.add( symbol );
} else {
if( symbol.isTemplateMember() && !symbol.isTemplateInstance() &&
!symbol.isType( TypeInfo.t_templateParameter ) && symbol.getContainingSymbol().isType( TypeInfo.t_template ))
{
return symbol.getContainingSymbol();
}
return symbol;
}
}
@ -1010,6 +1097,17 @@ public class ParserSymbolTable {
ambiguous |= ( hasWorse && hasBetter ) || ( !hasWorse && !hasBetter );
if( !hasWorse ){
if( !hasBetter ){
//if they are both template functions, we can order them that way
if( bestFn.isTemplateInstance() && currFn.isTemplateInstance() ){
ITemplateSymbol t1 = (ITemplateSymbol) bestFn.getInstantiatedSymbol().getContainingSymbol();
ITemplateSymbol t2 = (ITemplateSymbol) currFn.getInstantiatedSymbol().getContainingSymbol();
int order = TemplateEngine.orderTemplateFunctions( t1, t2 );
if ( order < 0 ){
hasBetter = true;
}
}
}
if( hasBetter ){
//the new best function.
ambiguous = false;
@ -1177,16 +1275,8 @@ public class ParserSymbolTable {
return 0;
}
IDerivableContainerSymbol symbol = null;
TemplateInstance instance = null;
if( obj instanceof TemplateInstance ){
instance = (TemplateInstance) obj;
ISymbol temp = instance.getInstantiatedSymbol();
if( temp instanceof IDerivableContainerSymbol ){
symbol = (IDerivableContainerSymbol) temp;
} else {
return -1;
}
} else if( obj instanceof IDerivableContainerSymbol ){
if( obj instanceof IDerivableContainerSymbol ){
symbol = (IDerivableContainerSymbol) obj;
} else {
return -1;
@ -1203,48 +1293,23 @@ public class ParserSymbolTable {
for( int i = size; i > 0; i-- ){
wrapper = (IDerivableContainerSymbol.IParentSymbol) iter.next();
temp = wrapper.getParent();
boolean isVisible = ( wrapper.getVisibility() == ASTAccessVisibility.PUBLIC );
if( temp instanceof TemplateInstance ){
instance = (TemplateInstance) temp;
if( instance.getInstantiatedSymbol() instanceof IDerivableContainerSymbol ){
if( instance.getInstantiatedSymbol() == base ){
if( throwIfNotVisible && !isVisible )
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadVisibility );
else
return 1;
} else {
int n = hasBaseClass( instance, base, throwIfNotVisible );
if( n > 0 ){
return n + 1;
}
}
}
boolean isVisible = ( wrapper.getAccess() == ASTAccessVisibility.PUBLIC );
if ( temp instanceof IDerivableContainerSymbol ){
parent = (IDerivableContainerSymbol)temp;
} else {
if( temp.isType( TypeInfo.t_undef ) && temp.getContainingSymbol().isType( TypeInfo.t_template ) ){
if( instance == null ) continue;
TypeInfo info = (TypeInfo) instance.getArgumentMap().get( temp );
if( info == null || !info.isType( TypeInfo.t_class, TypeInfo.t_struct ) ){
continue;
}
parent = (IDerivableContainerSymbol) info.getTypeSymbol();
}
else if ( temp instanceof IDerivableContainerSymbol ){
parent = (IDerivableContainerSymbol)temp;
} else {
continue;
}
if( parent == base ){
if( throwIfNotVisible && !isVisible )
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadVisibility );
else
return 1;
} else {
int n = hasBaseClass( parent, base, throwIfNotVisible );
if( n > 0 ){
return n + 1;
}
}
continue;
}
if( parent == base ){
if( throwIfNotVisible && !isVisible )
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadVisibility );
else
return 1;
} else {
int n = hasBaseClass( parent, base, throwIfNotVisible );
if( n > 0 ){
return n + 1;
}
}
}
}
@ -1285,13 +1350,17 @@ public class ParserSymbolTable {
for( int i = size; i > 0; i-- ){
wrapper = (IDerivableContainerSymbol.IParentSymbol) iter.next();
base = wrapper.getParent();
classes.add( base );
if( base.getContainingSymbol().getType() == TypeInfo.t_namespace ){
classes.add( base.getContainingSymbol());
base = wrapper.getParent();
//TODO: what about IDeferredTemplateInstance parents?
if( base instanceof IDerivableContainerSymbol ){
classes.add( base );
if( base.getContainingSymbol().getType() == TypeInfo.t_namespace ){
classes.add( base.getContainingSymbol());
}
getBaseClassesAndContainingNamespaces( (IDerivableContainerSymbol) base, classes );
}
getBaseClassesAndContainingNamespaces( (IDerivableContainerSymbol) base, classes );
}
}
}
@ -1637,7 +1706,7 @@ public class ParserSymbolTable {
}
}
static private Cost checkStandardConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException{
static protected Cost checkStandardConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException{
Cost cost = lvalue_to_rvalue( source, target );
if( cost.source == null || cost.target == null ){
@ -1699,18 +1768,13 @@ public class ParserSymbolTable {
if( target.getType() == TypeInfo.t_type ){
targetDecl = target.getTypeSymbol();
if( targetDecl.isType( TypeInfo.t_class, TypeInfo.t_union ) ){
LookupData data = new LookupData( EMPTY_NAME, TypeInfo.t_constructor, null );
LookupData data = new LookupData( EMPTY_NAME, TypeInfo.t_constructor);
data.parameters = new LinkedList();
data.parameters.add( source );
data.forUserDefinedConversion = true;
IDerivableContainerSymbol container = (IDerivableContainerSymbol) targetDecl;
if( targetDecl instanceof TemplateInstance ){
data.templateInstance = targetDecl;
container = (IDerivableContainerSymbol)((TemplateInstance) targetDecl).getInstantiatedSymbol();
}
if( !container.getConstructors().isEmpty() ){
LinkedList constructors = new LinkedList( container.getConstructors() );
constructor = resolveFunction( data, constructors );
@ -1731,7 +1795,7 @@ public class ParserSymbolTable {
String name = target.toString();
if( !name.equals(EMPTY_NAME) ){
LookupData data = new LookupData( "operator " + name, TypeInfo.t_function, null ); //$NON-NLS-1$
LookupData data = new LookupData( "operator " + name, TypeInfo.t_function ); //$NON-NLS-1$
LinkedList params = new LinkedList();
data.parameters = params;
data.forUserDefinedConversion = true;
@ -1853,7 +1917,7 @@ public class ParserSymbolTable {
info = typeSymbol.getTypeInfo();
}
if( info.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
if( info.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) || info.isType( TypeInfo.t_function ) ){
returnInfo.setType( TypeInfo.t_type );
returnInfo.setTypeSymbol( typeSymbol );
} else {
@ -1868,7 +1932,7 @@ public class ParserSymbolTable {
if( topInfo.hasPtrOperators() ){
TypeInfo.PtrOp topPtr = (PtrOp) topInfo.getPtrOperators().iterator().next();
TypeInfo.PtrOp ptr = null;
if( returnInfo.hasPtrOperators() ){
if( returnInfo.hasPtrOperators() && topPtr.getType() == PtrOp.t_undef ){
ptr = (PtrOp)returnInfo.getPtrOperators().iterator().next();
} else {
ptr = new PtrOp();
@ -1886,336 +1950,6 @@ public class ParserSymbolTable {
return returnInfo;
}
//TODO Andrew - This code is dead, I didn't cut it out as I assume you plan to make it live soon. Be forewarned.
static private IParameterizedSymbol matchTemplatePartialSpecialization( IParameterizedSymbol template, List args ){
if( template == null ){
return null;
}
List specs = template.getSpecializations();
int size = ( specs != null ) ? specs.size() : 0;
if( size == 0 ){
return template;
}
IParameterizedSymbol bestMatch = null;
boolean bestMatchIsBest = true;
Iterator iter = specs.iterator();
IParameterizedSymbol spec = null;
List specArgs = null;
for( int i = size; i > 0; i-- ){
spec = (IParameterizedSymbol) iter.next();
specArgs = spec.getArgumentList();
if( specArgs == null || specArgs.size() != args.size() ){
continue;
}
ISymbol sym1 = null, sym2 = null;
Iterator iter1 = specArgs.iterator();
Iterator iter2 = args.iterator();
HashMap map = new HashMap();
//String name = null;
boolean match = true;
for( int j = specArgs.size(); j > 0; j-- ){
sym1 = (ISymbol)iter1.next();
TypeInfo info2 = (TypeInfo) iter2.next();
if( info2.isType( TypeInfo.t_type ) ){
sym2 = sym2.getTypeSymbol();
} else {
sym2 = template.getSymbolTable().newSymbol( EMPTY_NAME );
sym2.setTypeInfo( info2 );
}
if( !deduceTemplateArgument( map, sym1, sym2, null ) ){
match = false;
break;
}
/*
name = sym1.getName();
if( name.equals( "" ) ){
//no name, only type
} else if( map.containsKey( name ) ) {
ISymbol val = (ISymbol) map.get( name );
if( val.getType() != sym2.getType() ){
match = false;
break;
}
} else {
map.put( name, sym2 );
}
*/
}
if( match ){
int compare = orderSpecializations( bestMatch, spec );
if( compare == 0 ){
bestMatchIsBest = false;
} else if( compare < 0 ) {
bestMatch = spec;
bestMatchIsBest = true;
}
}
}
return bestMatchIsBest ? bestMatch : null;
}
/**
* Compare spec1 to spec2. Return > 0 if spec1 is more specialized, < 0 if spec2
* is more specialized, = 0 otherwise.
* @param spec1
* @param spec2
* @return
*/
static private int orderSpecializations( IParameterizedSymbol spec1, IParameterizedSymbol spec2 ){
if( spec1 == null ){
return -1;
}
Iterator iter = spec1.getContainedSymbols().keySet().iterator();
ISymbol decl = (ISymbol) spec1.getContainedSymbols().get( iter.next() );
//to order class template specializations, we need to transform them into function templates
if( decl.isType( TypeInfo.t_class ) ) {
spec1 = classTemplateSpecializationToFunctionTemplate( spec1 );
spec2 = classTemplateSpecializationToFunctionTemplate( spec2 );
}
TemplateInstance transformed1 = transformFunctionTemplateForOrdering( spec1 );
TemplateInstance transformed2 = transformFunctionTemplateForOrdering( spec2 );
//Using the transformed parameter list, perform argument deduction against the other
//function template
boolean d1 = deduceTemplateArguments( spec2, transformed1 );
boolean d2 = deduceTemplateArguments( spec1, transformed2 );
//The transformed template is at least as specialized as the other iff the deduction
//succeeds and the deduced parameter types are an exact match
//A template is more specialized than another iff it is at least as specialized as the
//other template and that template is not at least as specialized as the first.
if( d1 && d2 || !d1 && !d2 )
return 0;
else if( d1 && !d2 )
return 1;
else
return -1;
}
/**
*
* @param template
* @param args
* @return
*
* A type that is specified in terms of template parameters (P) is compared with an actual
* type (A), and an attempt is made to find template argument vaules that will make P,
* after substitution of the deduced values, compatible with A.
*/
static private boolean deduceTemplateArguments( IParameterizedSymbol template, TemplateInstance argSource ){
if( template.getContainedSymbols() == null || template.getContainedSymbols().size() != 1 ){
return false;
}
Iterator iter = template.getContainedSymbols().keySet().iterator();
ISymbol templateSymbol = (ISymbol) template.getContainedSymbols().get( iter.next() );
if( !templateSymbol.isType( TypeInfo.t_function ) ){
return false;
}
IParameterizedSymbol argTemplate = (IParameterizedSymbol)argSource.getInstantiatedSymbol();
iter = argTemplate.getContainedSymbols().keySet().iterator();
ISymbol argFunction = (ISymbol) argTemplate.getContainedSymbols().get( iter.next() );
if( !argFunction.isType( TypeInfo.t_function ) ){
return false;
}
List args = ((IParameterizedSymbol) argFunction).getParameterList();
IParameterizedSymbol function = (IParameterizedSymbol) templateSymbol;
if( function.getParameterList() == null || function.getParameterList().size() != args.size() ){
return false;
}
HashMap map = new HashMap();
Iterator pIter = function.getParameterList().iterator();
Iterator aIter = args.iterator();
while( pIter.hasNext() ){
if( !deduceTemplateArgument( map, (ISymbol) pIter.next(), (ISymbol) aIter.next(), argSource.getArgumentMap() ) ){
return false;
}
}
return true;
}
static private boolean deduceTemplateArgument( Map map, ISymbol p, ISymbol a, Map argumentMap ){
if( argumentMap != null && argumentMap.containsKey( a ) ){
a = (ISymbol) argumentMap.get( a );
}
ISymbol pSymbol = p, aSymbol = a;
if( p.isType( TypeInfo.t_type ) ){
pSymbol = p.getTypeSymbol();
aSymbol = a.isType( TypeInfo.t_type ) ? a.getTypeSymbol() : a;
return deduceTemplateArgument( map, pSymbol, aSymbol, argumentMap );
} else {
if( pSymbol.isTemplateMember() && pSymbol.isType( TypeInfo.t_undef ) ){
//T* or T& or T[ const ]
//also
List pPtrs = pSymbol.getPtrOperators();
List aPtrs = aSymbol.getPtrOperators();
if( pPtrs != null ){
TypeInfo.PtrOp pOp = (TypeInfo.PtrOp) pPtrs.iterator().next();
TypeInfo.PtrOp aOp = ( aPtrs != null ) ? (TypeInfo.PtrOp)pPtrs.iterator().next() : null;
if( pOp != null && aOp != null && pOp.getType() == aOp.getType() ){
if( pOp.getType() == TypeInfo.PtrOp.t_memberPointer ){
} else {
TypeInfo type = new TypeInfo( aSymbol.getTypeInfo() );
type.getPtrOperators().clear();
map.put( pSymbol.getName(), type );
return true;
}
} else {
return false;
}
} else {
//T
map.put( pSymbol.getName(), a.getTypeInfo() );
return true;
}
}
//template-name<T> or template-name<i>
else if( pSymbol.isType( TypeInfo.t_template ) && aSymbol.isType( TypeInfo.t_template ) ){
List pArgs = ((IParameterizedSymbol)pSymbol).getArgumentList();
List aArgs = ((IParameterizedSymbol)aSymbol).getArgumentList();
if( pArgs == null || aArgs == null || pArgs.size() != aArgs.size()){
return false;
}
Iterator pIter = pArgs.iterator();
Iterator aIter = aArgs.iterator();
while( pIter.hasNext() ){
if( !deduceTemplateArgument( map, (ISymbol) pIter.next(), (ISymbol) aIter.next(), argumentMap ) ){
return false;
}
}
}
//T (*) ( ), T ( T::* ) ( T ), & variations
else if( pSymbol.isType( TypeInfo.t_function ) && aSymbol.isType( TypeInfo.t_function ) ){
IParameterizedSymbol pFunction = (IParameterizedSymbol)pSymbol;
IParameterizedSymbol aFunction = (IParameterizedSymbol)aSymbol;
if( !deduceTemplateArgument( map, aFunction.getReturnType(), pFunction.getReturnType(), argumentMap ) ){
return false;
}
if( pSymbol.getPtrOperators() != null ){
List ptrs = pSymbol.getPtrOperators();
TypeInfo.PtrOp op = (TypeInfo.PtrOp) ptrs.iterator().next();
if( op.getType() == TypeInfo.PtrOp.t_memberPointer ){
if( !deduceTemplateArgument( map, op.getMemberOf(), pFunction.getContainingSymbol(), argumentMap ) ){
return false;
}
}
}
List pParams = pFunction.getParameterList();
List aParams = aFunction.getParameterList();
if( pParams.size() != aParams.size() ){
return false;
} else {
Iterator pIter = pParams.iterator();
Iterator aIter = aParams.iterator();
while( pIter.hasNext() ){
if( !deduceTemplateArgument( map, (ISymbol) pIter.next(), (ISymbol) aIter.next(), argumentMap ) ){
return false;
}
}
}
} else if( pSymbol.getType() == aSymbol.getType() ){
if( pSymbol.getTypeInfo().getHasDefault() ){
if( !aSymbol.getTypeInfo().getHasDefault() ||
aSymbol.getTypeInfo().getDefault().equals( pSymbol.getTypeInfo().getDefault() ) )
{
return false;
}
}
//value
map.put( pSymbol.getName(), aSymbol.getTypeInfo() );
return true;
}
}
return false;
}
/**
* transform the class template to a function template as described in the spec
* 14.5.4.2-1
* @param template
* @return IParameterizedSymbol
* the function template has the same template parameters as the partial specialization and
* has a single function parameter whose type is a class template specialization with the template
* arguments of the partial specialization
*/
static private IParameterizedSymbol classTemplateSpecializationToFunctionTemplate( IParameterizedSymbol template ){
IParameterizedSymbol transformed = (IParameterizedSymbol) template.clone();
transformed.getArgumentList().clear();
transformed.getContainedSymbols().clear();
IParameterizedSymbol function = template.getSymbolTable().newParameterizedSymbol( transformed.getName(), TypeInfo.t_function );
try{
transformed.addSymbol( function );
} catch ( ParserSymbolTableException e ){
//we shouldn't get this because there aren't any other symbols in the template
}
function.addParameter( template );
return transformed;
}
/**
* transform a function template for use in partial ordering, as described in the
* spec 14.5.5.2-3
* @param template
* @return
* -for each type template parameter, synthesize a unique type and substitute that for each
* occurence of that parameter in the function parameter list
* -for each non-type template parameter, synthesize a unique value of the appropriate type and
* susbstitute that for each occurence of that parameter in the function parameter list
* for each template template parameter, synthesize a unique class template and substitute that
* for each occurence of that parameter in the function parameter list
*/
static private TemplateInstance transformFunctionTemplateForOrdering( IParameterizedSymbol template ){
List paramList = template.getParameterList();
int size = ( paramList != null ) ? paramList.size() : 0;
if( size == 0 ){
return null;
}
HashMap map = new HashMap();
for( Iterator iterator = paramList.iterator(); iterator.hasNext(); ) {
ISymbol param = (ISymbol) iterator.next();
ISymbol val = template.getSymbolTable().newSymbol( EMPTY_NAME, TypeInfo.t_type );
if( false /* is value */ ){
//val.getTypeInfo().setHasDefault()
}
map.put( param, val );
}
return new TemplateInstance( template.getSymbolTable(), template, map );
}
//private Stack _contextStack = new Stack();
private IContainerSymbol _compilationUnit;
private ParserLanguage _language;
private ParserMode _mode;
@ -2302,10 +2036,11 @@ public class ParserSymbolTable {
public HashSet inheritanceChain; //used to detect circular inheritance
public List parameters; //parameter info for resolving functions
public List parameters; //parameter info for resolving functions
public HashSet associated; //associated namespaces for argument dependant lookup
public ISymbol stopAt; //stop looking along the stack once we hit this declaration
public TypeFilter filter = null;
public ISymbol templateMember; //to assit with template member defs
public boolean qualified = false;
public boolean ignoreUsingDirectives = false;
@ -2314,22 +2049,19 @@ public class ParserSymbolTable {
public Map foundItems = null;
public ISymbol templateInstance = null;
public LookupMode mode = LookupMode.NORMAL;
public LookupData( String n, TypeInfo.eType t, ISymbol i ){
public LookupData( String n, TypeInfo.eType t ){
name = n;
filter = new TypeFilter( t );
templateInstance = i;
}
public LookupData( String n, TypeFilter f, ISymbol i ){
public LookupData( String n, TypeFilter f ) {
name = n;
filter = ( f != null ) ? f : new TypeFilter( TypeInfo.t_any );
templateInstance = i;
}
}
static private class Cost
static protected class Cost
{
public Cost( TypeInfo s, TypeInfo t ){
@ -2445,7 +2177,7 @@ public class ParserSymbolTable {
* @param qualifyingSymbol
* @return
*/
public static ASTAccessVisibility getVisibility(ISymbol symbol, IContainerSymbol qualifyingSymbol) throws ParserSymbolTableException {
public static ASTAccessVisibility getVisibility(ISymbol symbol, IContainerSymbol qualifyingSymbol){
IContainerSymbol container = symbol.getContainingSymbol();
if( qualifyingSymbol == null || container.equals( qualifyingSymbol ) ){
@ -2454,12 +2186,12 @@ public class ParserSymbolTable {
if( node != null && node instanceof IASTMember ){
return ((IASTMember)node).getVisiblity();
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
}
if( ! (qualifyingSymbol instanceof IDerivableContainerSymbol) ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
List parents = ((IDerivableContainerSymbol) qualifyingSymbol).getParents();

View file

@ -0,0 +1,36 @@
/**********************************************************************
* Copyright (c) 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.pst;
/**
* @author aniefer
*/
public class ParserSymbolTableError extends Error {
/**
* Constructor for ParserSymbolTableError.
*/
public ParserSymbolTableError() {
super();
}
/**
* Constructor for ParserSymbolTableError.
* @param int r: reason
*/
public ParserSymbolTableError( int r ) {
reason = r;
}
public static final int r_InternalError = -1;
public static final int r_OperationNotSupported = 0;
public int reason = -1;
}

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* Copyright (c) 2002,2003, 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@ -13,11 +13,6 @@ package org.eclipse.cdt.internal.core.parser.pst;
/**
* @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 ParserSymbolTableException extends Exception {
@ -36,15 +31,18 @@ public class ParserSymbolTableException extends Exception {
reason = r;
}
public static final int r_InternalError = -1;
public static final int r_Ambiguous = 0;
public static final int r_BadTypeInfo = 1;
public static final int r_CircularInheritance = 2;
public static final int r_InvalidOverload = 3;
public static final int r_BadTemplate = 4;
public static final int r_InvalidUsing = 5;
public static final int r_BadVisibility = 6;
public static final int r_UnableToResolveFunction = 7;
public static final int r_InternalError = -1;
public static final int r_Ambiguous = 0;
public static final int r_BadTypeInfo = 1;
public static final int r_CircularInheritance = 2;
public static final int r_InvalidOverload = 3;
public static final int r_BadTemplate = 4;
public static final int r_InvalidUsing = 5;
public static final int r_BadVisibility = 6;
public static final int r_UnableToResolveFunction = 7;
public static final int r_BadTemplateArgument = 8;
public static final int r_BadTemplateParameter = 9;
public static final int r_RedeclaredTemplateParam = 10;
public int reason = -1;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@ -13,18 +13,146 @@
*/
package org.eclipse.cdt.internal.core.parser.pst;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Command;
/**
* @author aniefer
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
* @author aniefe
*/
public class SpecializedSymbol extends ParameterizedSymbol implements ISpecializedSymbol {
public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSymbol {
protected SpecializedSymbol( ParserSymbolTable table, String name ){
super( table, name, TypeInfo.t_template );
super( table, name );
}
protected SpecializedSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
super( table, name, obj );
}
public Object clone(){
SpecializedSymbol copy = (SpecializedSymbol)super.clone();
copy._argumentList = ( _argumentList != null ) ? (LinkedList) _argumentList.clone() : null;
return copy;
}
public ITemplateSymbol getPrimaryTemplate(){
return _primaryTemplate;
}
public void setPrimaryTemplate( ITemplateSymbol templateSymbol ){
_primaryTemplate = templateSymbol;
}
public ISymbol instantiate( List arguments ) throws ParserSymbolTableException{
Map argMap = new HashMap();
List specArgs = getArgumentList();
if( specArgs.size() != arguments.size() ){
return null;
}
List actualArgs = new LinkedList();
Iterator iter1 = specArgs.iterator();
Iterator iter2 = arguments.iterator();
ISymbol templatedSymbol = getTemplatedSymbol();
while( templatedSymbol.isTemplateInstance() ){
templatedSymbol = templatedSymbol.getInstantiatedSymbol();
}
while( iter1.hasNext() ){
TypeInfo info = (TypeInfo) iter1.next();
TypeInfo mappedInfo = (TypeInfo) iter2.next();
//If the argument is a template parameter, we can't instantiate yet, defer for later
if( mappedInfo.isType( TypeInfo.t_type ) && mappedInfo.getTypeSymbol().isType( TypeInfo.t_templateParameter ) ){
return deferredInstance( arguments );
}
actualArgs.add( mappedInfo );
if( info.isType( TypeInfo.t_type ) && info.getTypeSymbol().isType( TypeInfo.t_templateParameter )){
ISymbol param = info.getTypeSymbol();
param = TemplateEngine.translateParameterForDefinition ( templatedSymbol, param, getDefinitionParameterMap() );
if( !argMap.containsKey( param ) ){
argMap.put( param, mappedInfo );
}
}
}
//sanity check
if( getParameterList().size() != argMap.size() )
return null;
Iterator params = getParameterList().iterator();
while( params.hasNext() ){
if( !argMap.containsKey( params.next() ) )
return null;
}
IContainerSymbol instance = findInstantiation( actualArgs );
if( instance != null ){
return instance;
} else {
IContainerSymbol symbol = null;
if( getContainedSymbols().size() == 1 ){
Iterator iter = getContainedSymbols().keySet().iterator();
symbol = (IContainerSymbol)getContainedSymbols().get( iter.next() );
}
instance = (IContainerSymbol) symbol.instantiate( this, argMap );
addInstantiation( instance, actualArgs );
return instance;
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getArgumentList()
*/
public List getArgumentList(){
if( _argumentList == null ){
_argumentList = new LinkedList();
}
return _argumentList;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addArgument(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
public void addArgument(TypeInfo arg) {
List argumentList = getArgumentList();
argumentList.add( arg );
//arg.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
Command command = new AddArgumentCommand( this, arg );
getSymbolTable().pushCommand( command );
}
static private class AddArgumentCommand extends Command{
public AddArgumentCommand( ISpecializedSymbol container, TypeInfo arg ){
_decl = container;
_arg = arg;
}
public void undoIt(){
_decl.getArgumentList().remove( _arg );
}
private ISpecializedSymbol _decl;
private TypeInfo _arg;
}
private LinkedList _argumentList; //template specialization arguments
private ITemplateSymbol _primaryTemplate; //our primary template
}

View file

@ -0,0 +1,163 @@
/**********************************************************************
* Copyright (c) 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.pst;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.LookupData;
/**
* @author aniefer
*/
public class TemplateFactory implements ITemplateFactory {
protected TemplateFactory( ITemplateSymbol primary, List params ){
templatesList = new LinkedList();
templatesList.add( primary );
parametersList = new LinkedList();
parametersList.add( new LinkedList( params ) );
}
protected TemplateFactory( List templates, List params ){
templatesList = templates;
parametersList = params;
}
public ITemplateFactory lookupTemplateForMemberDefinition( String name, List parameters, List arguments ) throws ParserSymbolTableException{
if( templatesList == null || templatesList.isEmpty() ){
return null;
}
ITemplateSymbol template = (ITemplateSymbol) templatesList.get( 0 );
IContainerSymbol symbol = template.getTemplatedSymbol();
LookupData data = new LookupData( name, TypeInfo.t_any ); //, null );
ParserSymbolTable.lookup( data, symbol );
ISymbol look = ParserSymbolTable.resolveAmbiguities( data );
if( look.getContainingSymbol() instanceof ITemplateSymbol ){
template = TemplateEngine.selectTemplateOrSpecialization( (ITemplateSymbol) look.getContainingSymbol(), parameters, arguments );
if( template != null ){
List newTemplatesList = new LinkedList( templatesList );
List newParamsList = new LinkedList( parametersList );
newTemplatesList.add( template );
newParamsList.add( new LinkedList( parameters ) );
return new TemplateFactory( newTemplatesList, newParamsList );
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#addSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
public void addSymbol( ISymbol symbol ) throws ParserSymbolTableException {
Iterator templatesIter = getTemplatesList().iterator();
Iterator parametersIter = getParametersList().iterator();
while( templatesIter.hasNext() ){
Map defnMap = new HashMap();
ITemplateSymbol template = (ITemplateSymbol) templatesIter.next();
Iterator tempIter = template.getParameterList().iterator();
if( !parametersIter.hasNext() ){
throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
List params = (List) parametersIter.next();
Iterator iter = params.iterator();
while( iter.hasNext() ){
ISymbol param = (ISymbol) iter.next();
ISymbol tempParam = (ISymbol) tempIter.next();
defnMap.put( param, tempParam );
}
template.getDefinitionParameterMap().put( symbol, defnMap );
}
ITemplateSymbol template = (ITemplateSymbol) getTemplatesList().get( getTemplatesList().size() - 1 );
IContainerSymbol container = (IContainerSymbol) template.getTemplatedSymbol();
if( container.isForwardDeclaration() && container.getTypeSymbol() == symbol ){
template.addSymbol( symbol );
} else {
container.addSymbol( symbol );
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#lookupMemberForDefinition(java.lang.String)
*/
public ISymbol lookupMemberForDefinition(String name) throws ParserSymbolTableException {
Set keys = getPrimaryTemplate().getContainedSymbols().keySet();
IContainerSymbol symbol = (IContainerSymbol) getPrimaryTemplate().getContainedSymbols().get( keys.iterator().next() );
return (ISymbol) symbol.lookupMemberForDefinition( name );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#lookupMemberFunctionForDefinition(java.lang.String, java.util.List)
*/
public IParameterizedSymbol lookupMemberFunctionForDefinition( String name, List params) throws ParserSymbolTableException {
Set keys = getPrimaryTemplate().getContainedSymbols().keySet();
IContainerSymbol symbol = (IContainerSymbol) getPrimaryTemplate().getContainedSymbols().get( keys.iterator().next() );
return (IParameterizedSymbol) symbol.lookupMethodForDefinition( name, params );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#getPrimaryTemplate()
*/
public ITemplateSymbol getPrimaryTemplate() {
return (ITemplateSymbol) templatesList.get( 0 );
}
public ISymbol lookupParam( String name ) throws ParserSymbolTableException{
Iterator iter = getParametersList().iterator();
while( iter.hasNext() ){
List list = (List) iter.next();
Iterator params = list.iterator();
while( params.hasNext() ){
ISymbol p = (ISymbol) params.next();
if( p.getName().equals( name ) ){
return p;
}
}
}
return getPrimaryTemplate().lookup( name );
}
protected List getTemplatesList() {
return templatesList;
}
protected List getParametersList() {
return parametersList;
}
private List templatesList;
private List parametersList;
}

View file

@ -1,135 +0,0 @@
/*******************************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Corp. - Rational Software - initial implementation
******************************************************************************/
/*
* Created on Nov 6, 2003
*/
package org.eclipse.cdt.internal.core.parser.pst;
import java.util.Iterator;
import java.util.Map;
public class TemplateInstance extends BasicSymbol
{
//TODO ANDREW - this field is not read, is this a work in progress?
//private final ParserSymbolTable _table;
protected TemplateInstance( ParserSymbolTable table, ISymbol symbol, Map argMap ){
super(table, ParserSymbolTable.EMPTY_NAME );
//this._table = table;
_instantiatedSymbol = symbol;
symbol.setTemplateInstance( this );
_argumentMap = argMap;
}
public boolean equals( Object t ){
if( t == null || !( t instanceof TemplateInstance ) ){
return false;
}
TemplateInstance instance = (TemplateInstance) t;
if( _instantiatedSymbol != instance._instantiatedSymbol ){
return false;
}
//check arg map
Iterator iter1 = _argumentMap.keySet().iterator();
Iterator iter2 = instance._argumentMap.keySet().iterator();
int size = _argumentMap.size();
int size2 = instance._argumentMap.size();
ISymbol t1 = null, t2 = null;
if( size == size2 ){
for( int i = size; i > 0; i-- ){
t1 = (ISymbol)iter1.next();
t2 = (ISymbol)iter2.next();
if( t1 != t2 || !_argumentMap.get(t1).equals( instance._argumentMap.get(t2) ) ){
return false;
}
}
}
return true;
}
public ISymbol getInstantiatedSymbol(){
_instantiatedSymbol.setTemplateInstance( this );
return _instantiatedSymbol;
}
public TypeInfo.eType getType(){
ISymbol symbol = _instantiatedSymbol;
TypeInfo.eType returnType = _instantiatedSymbol.getType();
if( returnType == TypeInfo.t_type ){
symbol = symbol.getTypeSymbol();
TypeInfo info = null;
while( symbol != null && symbol.getType() == TypeInfo.t_undef && symbol.getContainingSymbol().getType() == TypeInfo.t_template ){
info = (TypeInfo) _argumentMap.get( symbol );
if( !info.isType( TypeInfo.t_type ) ){
break;
}
symbol = info.getTypeSymbol();
}
return ( info != null ) ? info.getType() : TypeInfo.t_type;
}
return returnType;
}
public boolean isType( TypeInfo.eType type ){
return ( type == TypeInfo.t_any || getType() == type );
}
public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType ){
if( type == TypeInfo.t_any )
return true;
if( upperType == TypeInfo.t_undef ){
return ( getType() == type );
} else {
return ( getType().compareTo( type ) >= 0 && getType().compareTo( upperType ) <= 0 );
}
}
public ISymbol getTypeSymbol(){
ISymbol symbol = _instantiatedSymbol.getTypeSymbol();
if( symbol != null && symbol.getType() == TypeInfo.t_undef &&
symbol.getContainingSymbol().getType() == TypeInfo.t_template )
{
TypeInfo info = (TypeInfo) _argumentMap.get( symbol );
return ( info != null ) ? info.getTypeSymbol() : null;
}
return symbol;
}
public TypeInfo getTypeInfo(){
ISymbol symbol = _instantiatedSymbol.getTypeSymbol();
if( symbol != null && symbol.getType() == TypeInfo.t_undef &&
symbol.getContainingSymbol().getType() == TypeInfo.t_template )
{
TypeInfo info = (TypeInfo) _argumentMap.get( symbol );
return info;
}
return _instantiatedSymbol.getTypeInfo();
}
public Map getArgumentMap(){
return _argumentMap;
}
private ISymbol _instantiatedSymbol;
//private LinkedList _arguments;
private Map _argumentMap;
}

View file

@ -0,0 +1,318 @@
/**********************************************************************
* Copyright (c) 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.pst;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
/**
* @author aniefer
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymbol {
protected TemplateSymbol ( ParserSymbolTable table, String name ){
super( table, name, TypeInfo.t_template );
}
protected TemplateSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
super( table, name, obj );
}
public Object clone(){
TemplateSymbol copy = (TemplateSymbol)super.clone();
//copy._specializations = ( _specializations != null ) ? (LinkedList) _specializations.clone() : null;
copy._defnParameterMap = ( _defnParameterMap != null ) ? (HashMap) _defnParameterMap.clone() : null;
copy._instantiations = ( _instantiations != null ) ? (HashMap) _instantiations.clone() : null;
return copy;
}
public IContainerSymbol getTemplatedSymbol(){
Iterator iter = getContentsIterator();
if( iter.hasNext() ){
IContainerSymbol contained = (IContainerSymbol) iter.next();
if( contained.isForwardDeclaration() && contained.getTypeSymbol() != null ){
ISymbol symbol = contained.getTypeSymbol();
if( symbol.getContainingSymbol() == this )
return (IContainerSymbol) symbol;
}
return contained;
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#instantiate(java.util.List)
*/
public ISymbol instantiate( List arguments ) throws ParserSymbolTableException{
if( getType() != TypeInfo.t_template &&
( getType() != TypeInfo.t_templateParameter ||
getTypeInfo().getTemplateParameterType() != TypeInfo.t_template ) )
{
return null;
}
ITemplateSymbol template = TemplateEngine.matchTemplatePartialSpecialization( this, arguments );
if( template != null && template instanceof ISpecializedSymbol ){
return template.instantiate( arguments );
}
if( template == null ){
template = this;
}
List paramList = template.getParameterList();
int numParams = ( paramList != null ) ? paramList.size() : 0;
if( numParams == 0 ){
return null;
}
HashMap map = new HashMap();
Iterator paramIter = paramList.iterator();
Iterator argIter = arguments.iterator();
ISymbol param = null;
TypeInfo arg = null;
List actualArgs = new LinkedList();
ISymbol templatedSymbol = template.getTemplatedSymbol();
while( templatedSymbol != null && templatedSymbol.isTemplateInstance() ){
templatedSymbol = templatedSymbol.getInstantiatedSymbol();
}
for( int i = 0; i < numParams; i++ ){
param = (ISymbol) paramIter.next();
param = TemplateEngine.translateParameterForDefinition ( templatedSymbol, param, getDefinitionParameterMap() );
if( argIter.hasNext() ){
arg = (TypeInfo) argIter.next();
//If the argument is a template parameter, we can't instantiate yet, defer for later
if( arg.isType( TypeInfo.t_type ) && arg.getTypeSymbol().isType( TypeInfo.t_templateParameter ) ){
return deferredInstance( arguments );
}
} else {
Object obj = param.getTypeInfo().getDefault();
if( obj != null && obj instanceof TypeInfo ){
arg = (TypeInfo) obj;
if( arg.isType( TypeInfo.t_type ) && arg.getTypeSymbol().isType( TypeInfo.t_templateParameter ) ){
if( map.containsKey( arg.getTypeSymbol() ) ){
arg = (TypeInfo) map.get( arg.getTypeSymbol() );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument );
}
}
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument );
}
}
if( TemplateEngine.matchTemplateParameterAndArgument( param, arg ) ){
map.put( param, arg );
actualArgs.add( arg );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument );
}
}
IContainerSymbol instance = findInstantiation( actualArgs );
if( instance != null ){
return instance;
} else {
if( template.isType( TypeInfo.t_templateParameter ) ){
//template template parameter. must defer instantiation
return deferredInstance( arguments );
}
IContainerSymbol symbol = template.getTemplatedSymbol();
instance = (IContainerSymbol) symbol.instantiate( template, map );
addInstantiation( instance, actualArgs );
return instance;
}
}
public void addParameter( ISymbol param ) {
throw new ParserSymbolTableError( ParserSymbolTableError.r_OperationNotSupported );
}
public void addTemplateParameter( ISymbol param ) throws ParserSymbolTableException {
if( isType( TypeInfo.t_template ) ){
if( !isAllowableTemplateParameter( param ) ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateParameter );
}
modifyTemplateParameter( param );
}
super.addParameter( param );
}
private boolean isAllowableTemplateParameter( ISymbol param ) {
if( !param.isType( TypeInfo.t_templateParameter ) )
return false;
if( param.getName().equals( getName() ) ){
return false;
}
if( param.getTypeInfo().getTemplateParameterType() != TypeInfo.t_typeName &&
param.getTypeInfo().getTemplateParameterType() != TypeInfo.t_template )
{
if( param.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
param.isType( TypeInfo.t_enumerator ) )
{
return true;
}
//a non-tpye template parameter shall have one of the following:
//integral or enumeration type
//pointer to object or pointer to function
//reference to object or reference to function
//pointer to member
//A non-type template-parameter shall not be declared to have floating point, class or void type
if( param.isType( TypeInfo.t_float ) ||
param.isType( TypeInfo.t_double )||
param.isType( TypeInfo.t_class ) ||
param.isType( TypeInfo.t_void ) )
{
return false;
}
}
return true;
}
private void modifyTemplateParameter( ISymbol param ){
List ptrs = param.getPtrOperators();
if( ptrs.size() > 0 ){
PtrOp op = (PtrOp) ptrs.get( 0 );
if( op.getType() == PtrOp.t_array ){
op.setType( PtrOp.t_pointer );
}
} else if ( param.isType( TypeInfo.t_type ) && param.getTypeSymbol().isType( TypeInfo.t_function ) ){
param.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasSpecializations()
*/
public boolean hasSpecializations(){
return ( _specializations != null && !_specializations.isEmpty() );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addSpecialization(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
*/
public void addSpecialization( ISpecializedSymbol spec ){
List specializationList = getSpecializations();
specializationList.add( spec );
spec.setContainingSymbol( getContainingSymbol() );
spec.setPrimaryTemplate( this );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getSpecializations()
*/
public List getSpecializations() {
if( _specializations == null ){
_specializations = new LinkedList();
}
return _specializations;
}
public void addInstantiation( IContainerSymbol instance, List args ){
List key = new LinkedList( args );
if( _instantiations == null ){
_instantiations = new HashMap();
}
_instantiations.put( key, instance );
}
public IContainerSymbol findInstantiation( List arguments ){
if( _instantiations == null ){
return null;
}
//TODO: we could optimize this by doing something other than a linear search.
Iterator iter = _instantiations.keySet().iterator();
List args = null;
while( iter.hasNext() ){
args = (List) iter.next();
if( args.equals( arguments ) ){
return (IContainerSymbol) _instantiations.get( args );
}
}
return null;
}
public List findArgumentsFor( IContainerSymbol instance ){
if( instance == null || !instance.isTemplateInstance() )
return null;
ITemplateSymbol template = (ITemplateSymbol) instance.getInstantiatedSymbol().getContainingSymbol();
if( template != this )
return null;
Iterator iter = _instantiations.keySet().iterator();
while( iter.hasNext() ){
List args = (List) iter.next();
if( _instantiations.get( args ) == instance ){
return args;
}
}
return null;
}
public Map getDefinitionParameterMap(){
if( _defnParameterMap == null ){
_defnParameterMap = new HashMap();
}
return _defnParameterMap;
}
public IDeferredTemplateInstance deferredInstance( List args ){
return new DeferredTemplateInstance( getSymbolTable(), this, args );
}
public ISpecializedSymbol findSpecialization(List parameters, List arguments) {
// TODO Auto-generated method stub
return null;
}
private LinkedList _specializations; //template specializations
private HashMap _defnParameterMap; //members could be defined with different template parameter names
private HashMap _instantiations;
}

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* Copyright (c) 2002,2003, 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@ -67,6 +67,7 @@ public class TypeInfo {
_typeDeclaration = info._typeDeclaration;
_ptrOperators = ( info._ptrOperators == null ) ? null : (LinkedList)info._ptrOperators.clone();
_hasDefaultValue = info._hasDefaultValue;
_defaultValue = info._defaultValue;
}
public static final int typeMask = 0x001f;
@ -117,6 +118,8 @@ public class TypeInfo {
public static final TypeInfo.eType t_template = new TypeInfo.eType( 19 );
public static final TypeInfo.eType t_asm = new TypeInfo.eType( 20 );
public static final TypeInfo.eType t_linkage = new TypeInfo.eType( 21 );
public static final TypeInfo.eType t_templateParameter = new TypeInfo.eType( 22 );
public static final TypeInfo.eType t_typeName = new TypeInfo.eType( 23 );
//public static final eType t_templateParameter = new eType( 18 );
@ -282,6 +285,14 @@ public class TypeInfo {
_typeInfo = typeInfo;
}
public eType getTemplateParameterType(){
return _templateParameterType;
}
public void setTemplateParameterType( eType type ){
_templateParameterType = type;
}
/**
*
* @param type
@ -476,19 +487,25 @@ public class TypeInfo {
boolean result = ( _typeInfo == type._typeInfo );
result &= ( _type == type._type );
if( _typeDeclaration instanceof TemplateInstance ){
result &= _typeDeclaration.equals( type._typeDeclaration );
if( _typeDeclaration != null && type._typeDeclaration != null &&
_typeDeclaration.isType( TypeInfo.t__Bool, TypeInfo.t_void ) &&
type._typeDeclaration.isType( TypeInfo.t__Bool, TypeInfo.t_void ) )
{
//if typeDeclaration is a basic type, then only need the types the same
result &= ( _typeDeclaration.getType() == type._typeDeclaration.getType() );
} else if( _typeDeclaration != null && type._typeDeclaration != null &&
_typeDeclaration.isType( TypeInfo.t_function ) &&
type._typeDeclaration.isType( TypeInfo.t_function ) )
{
//function pointers... functions must have same parameter lists and return types
IParameterizedSymbol f1 = (IParameterizedSymbol) _typeDeclaration;
IParameterizedSymbol f2 = (IParameterizedSymbol) type._typeDeclaration;
result &= f1.hasSameParameters( f2 );
result &= f1.getReturnType().getTypeInfo().equals( f2.getReturnType().getTypeInfo() );
} else {
if( _typeDeclaration != null && type._typeDeclaration != null &&
_typeDeclaration.isType( TypeInfo.t__Bool, TypeInfo.t_void ) &&
type._typeDeclaration.isType( TypeInfo.t__Bool, TypeInfo.t_void ) )
{
//if typeDeclaration is a basic type, then only need the types the same
result &= ( _typeDeclaration.getType() == type._typeDeclaration.getType() );
} else {
//otherwise, its a user defined type, need the decls the same
result &= ( _typeDeclaration == type._typeDeclaration );
}
//otherwise, its a user defined type, need the decls the same
result &= ( _typeDeclaration == type._typeDeclaration );
}
int size1 = (_ptrOperators == null) ? 0 : _ptrOperators.size();
@ -524,7 +541,8 @@ public class TypeInfo {
}
private int _typeInfo = 0;
private TypeInfo.eType _type = TypeInfo.t_undef;
private eType _type = TypeInfo.t_undef;
private eType _templateParameterType = t_typeName;
private ISymbol _typeDeclaration;
private boolean _hasDefaultValue = false;