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.

Refactor the symbol table by splitting the ParserSymbolTable.Declaration 
class in 4 classes and moving it to not be nested
Tests have been updated and tested on windows & Linux
This commit is contained in:
John Camelon 2003-11-20 15:23:01 +00:00
parent 7e02ddb252
commit fcfd56c2af
16 changed files with 1764 additions and 1441 deletions

View file

@ -1,3 +1,6 @@
2003-11-18 Andrew Niefer
update ParserSymbolTableTest to reflect refactoring of Declaration into 4 separate classes.
2003-11-13 Hoda Amer
Added CompleteParseASTTest::testBug44342(): Failure to dereference function calls after a . or an ->
Moved testErrorHandling_1() to FailedCompleteParseASTTest

View file

@ -27,9 +27,9 @@ import org.eclipse.cdt.internal.core.parser.pst.ISymbolASTExtension;
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.TypeInfo;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Mark;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.OperatorExpression;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
@ -92,7 +92,7 @@ public class ParserSymbolTableTest extends TestCase {
public void testSimpleLookup() throws Exception{
newTable(); //new symbol table
ISymbol x = table.new Declaration( "x" );
ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( x );
ISymbol look = table.getCompilationUnit().lookup( "x" );
@ -110,7 +110,7 @@ public class ParserSymbolTableTest extends TestCase {
public void testSimpleSetGetObject() throws Exception{
newTable();
IContainerSymbol x = table.new Declaration("x");
IContainerSymbol x = table.newContainerSymbol( "x", TypeInfo.t_namespace );
ISymbolASTExtension extension = new StandardSymbolExtension(x,null);
@ -188,7 +188,7 @@ public class ParserSymbolTableTest extends TestCase {
class1.setType( TypeInfo.t_class );
class1.addParent( parent );
ISymbol decl = table.new Declaration("x");
ISymbol decl = table.newSymbol( "x", TypeInfo.t_int );
parent.addSymbol( decl );
table.getCompilationUnit().addSymbol( parent );
@ -216,7 +216,7 @@ public class ParserSymbolTableTest extends TestCase {
IDerivableContainerSymbol class1 = (IDerivableContainerSymbol) table.getCompilationUnit().lookup( "class" );
class1.addParent( parent2 );
ISymbol decl = table.new Declaration("x");
ISymbol decl = table.newSymbol( "x", TypeInfo.t_int );
parent2.addSymbol( decl );
try{
@ -283,7 +283,7 @@ public class ParserSymbolTableTest extends TestCase {
IContainerSymbol compUnit = table.getCompilationUnit();
compUnit.addSymbol( c );
ISymbol x = table.new Declaration( "x" );
ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
c.addSymbol( x );
compUnit.addSymbol( decl );
@ -357,16 +357,14 @@ public class ParserSymbolTableTest extends TestCase {
compUnit.addSymbol( c );
compUnit.addSymbol( d );
IContainerSymbol enum = table.new Declaration("enum");
enum.setType( TypeInfo.t_enumeration );
IContainerSymbol enum = table.newContainerSymbol( "enum", TypeInfo.t_enumeration );
ISymbol enumerator = table.new Declaration( "enumerator" );
enumerator.setType( TypeInfo.t_enumerator );
ISymbol enumerator = table.newSymbol( "enumerator", TypeInfo.t_enumerator );
ISymbol stat = table.new Declaration("static");
ISymbol stat = table.newSymbol( "static", TypeInfo.t_int );
stat.getTypeInfo().setBit( true, TypeInfo.isStatic );
ISymbol x = table.new Declaration("x");
ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
d.addSymbol( enum );
d.addSymbol( stat );
@ -1110,12 +1108,10 @@ public class ParserSymbolTableTest extends TestCase {
IContainerSymbol compUnit = table.getCompilationUnit();
ParserSymbolTable.Declaration A = table.new Declaration( "A" );
A.setType( TypeInfo.t_namespace );
IContainerSymbol A = table.newContainerSymbol( "A", TypeInfo.t_namespace );
compUnit.addSymbol( A );
ParserSymbolTable.Declaration f1 = table.new Declaration( "f" );
f1.setType( TypeInfo.t_function );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f1.addParameter( TypeInfo.t_int, 0, null, false );
A.addSymbol( f1 );
@ -1172,8 +1168,7 @@ public class ParserSymbolTableTest extends TestCase {
public void testThisPointer() throws Exception{
newTable();
IContainerSymbol cls = table.newContainerSymbol("class");
cls.setType( TypeInfo.t_class );
IDerivableContainerSymbol cls = table.newDerivableContainerSymbol( "class", TypeInfo.t_class );
IParameterizedSymbol fn = table.newParameterizedSymbol("function");
fn.setType( TypeInfo.t_function );
@ -1319,8 +1314,7 @@ public class ParserSymbolTableTest extends TestCase {
compUnit.addSymbol( NS1 );
ParserSymbolTable.Declaration f1 = table.new Declaration( "f" );
f1.setType( TypeInfo.t_function );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f1.addParameter( TypeInfo.t_void, 0, new PtrOp( PtrOp.t_pointer ), false );
NS1.addSymbol( f1 );
@ -1992,7 +1986,7 @@ public class ParserSymbolTableTest extends TestCase {
LinkedList args = new LinkedList();
args.add( type );
ParserSymbolTable.TemplateInstance instance = table.getCompilationUnit().templateLookup( "A", args );
TemplateInstance instance = table.getCompilationUnit().templateLookup( "A", args );
assertEquals( instance.getInstantiatedSymbol(), A );
ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
@ -2047,7 +2041,7 @@ public class ParserSymbolTableTest extends TestCase {
args.add( type );
look = table.getCompilationUnit().templateLookup( "A", args );
assertTrue( look instanceof ParserSymbolTable.TemplateInstance );
assertTrue( look instanceof TemplateInstance );
B.addParent( look );
table.getCompilationUnit().addSymbol( B );

View file

@ -1,3 +1,7 @@
2003-11-18 Andrew Niefer
Refactor PST: Split Declaration into 4 classes : ContainerSymbol, DerivableContainerSymbol, ParameterizedContainerSymbol,
SpecializedSymbol. Move these along with BasicSymbol & TemplateInstance to no longer be nested in ParserSymbolTable.
2003-11-13 Hoda Amer
Changed the getExpressionResultType() in the complete factory to return
an object of type ExpressionResult.

View file

@ -24,8 +24,7 @@ import org.eclipse.cdt.internal.core.parser.ast.ASTQualifiedNamedElement;
import org.eclipse.cdt.internal.core.parser.ast.NamedOffsets;
import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Declaration.ParentWrapper;
import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol.IParentSymbol;
/**
* @author jcamelon
@ -65,7 +64,7 @@ public class ASTClassSpecifier extends ASTScope implements IASTClassSpecifier
if( ! hasNext() )
throw new NoSuchElementException();
ParserSymbolTable.Declaration.ParentWrapper pw = (ParentWrapper)parents.next();
IParentSymbol pw = (IParentSymbol)parents.next();
return new ASTBaseSpecifier( pw.getParent(), pw.isVirtual(), pw.getAccess(), pw.getOffset(), pw.getReferences() );

View file

@ -0,0 +1,180 @@
/*
* Created on Nov 4, 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;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class BasicSymbol implements Cloneable, ISymbol
{
private final ParserSymbolTable _table;
public BasicSymbol( ParserSymbolTable table, String name ){
super();
this._table = table;
_name = name;
_typeInfo = new TypeInfo();
}
public BasicSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
super();
this._table = table;
_name = name;
_object = obj;
_typeInfo = new TypeInfo();
}
public BasicSymbol( ParserSymbolTable table, String name, TypeInfo.eType typeInfo )
{
super();
this._table = table;
_name = name;
_typeInfo = new TypeInfo( typeInfo, 0, null );
}
public ParserSymbolTable getSymbolTable(){
return _table;
}
public Object clone(){
BasicSymbol copy = null;
try{
copy = (BasicSymbol)super.clone();
} catch ( CloneNotSupportedException e ){
//should not happen
return null;
}
copy._object = null;
return copy;
}
public String getName() { return _name; }
public void setName(String name) { _name = name; }
public ISymbolASTExtension getASTExtension() { return _object; }
public void setASTExtension( ISymbolASTExtension obj ) { _object = obj; }
public IContainerSymbol getContainingSymbol() { return _containingScope; }
public void setContainingSymbol( IContainerSymbol scope ){
_containingScope = scope;
_depth = scope.getDepth() + 1;
}
public void setType(TypeInfo.eType t){
getTypeInfo().setType( t );
}
public TypeInfo.eType getType(){
return getTypeInfo().getType();
}
public boolean isType( TypeInfo.eType type ){
return getTypeInfo().isType( type, TypeInfo.t_undef );
}
public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType ){
return getTypeInfo().isType( type, upperType );
}
public ISymbol getTypeSymbol(){
ISymbol symbol = getTypeInfo().getTypeSymbol();
if( symbol != null && symbol.getTypeInfo().isForwardDeclaration() && symbol.getTypeSymbol() != null ){
return symbol.getTypeSymbol();
}
return symbol;
}
public void setTypeSymbol( ISymbol type ){
getTypeInfo().setTypeSymbol( type );
}
public TypeInfo getTypeInfo(){
return _typeInfo;
}
public void setTypeInfo( TypeInfo info ) {
_typeInfo = info;
}
public boolean isForwardDeclaration(){
return getTypeInfo().isForwardDeclaration();
}
public void setIsForwardDeclaration( boolean forward ){
getTypeInfo().setIsForwardDeclaration( forward );
}
/**
* returns 0 if same, non zero otherwise
*/
public int compareCVQualifiersTo( ISymbol symbol ){
int size = symbol.getTypeInfo().hasPtrOperators() ? symbol.getTypeInfo().getPtrOperators().size() : 0;
int size2 = getTypeInfo().hasPtrOperators() ? getTypeInfo().getPtrOperators().size() : 0;
if( size != size2 ){
return size2 - size;
} else if( size == 0 )
return 0;
else {
Iterator iter1 = symbol.getTypeInfo().getPtrOperators().iterator();
Iterator iter2 = getTypeInfo().getPtrOperators().iterator();
TypeInfo.PtrOp op1 = null, op2 = null;
for( int i = size; i > 0; i-- ){
op1 = (TypeInfo.PtrOp)iter1.next();
op2 = (TypeInfo.PtrOp)iter2.next();
if( op1.compareCVTo( op2 ) != 0 ){
return -1;
}
}
}
return 0;
}
public List getPtrOperators(){
return getTypeInfo().getPtrOperators();
}
public void addPtrOperator( TypeInfo.PtrOp ptrOp ){
getTypeInfo().addPtrOperator( ptrOp );
}
public int getDepth(){
return _depth;
}
public boolean isTemplateMember(){
return _isTemplateMember;
}
public void setIsTemplateMember( boolean isMember ){
_isTemplateMember = isMember;
}
public ISymbol getTemplateInstance(){
return _templateInstance;
}
public void setTemplateInstance( TemplateInstance instance ){
_templateInstance = instance;
}
public Map getArgumentMap(){
return null;
}
private String _name; //our name
private ISymbolASTExtension _object; //the object associated with us
private TypeInfo _typeInfo; //our type info
private IContainerSymbol _containingScope; //the scope that contains us
private int _depth; //how far down the scope stack we are
private boolean _isTemplateMember = false;
private TemplateInstance _templateInstance;
}

View file

@ -0,0 +1,650 @@
/*******************************************************************************
* 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 4, 2003
*/
package org.eclipse.cdt.internal.core.parser.pst;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Command;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.LookupData;
/**
* @author aniefer
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
protected ContainerSymbol( ParserSymbolTable table, String name ){
super( table, name );
}
protected ContainerSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
super( table, name, obj );
}
protected ContainerSymbol( ParserSymbolTable table, String name, TypeInfo.eType typeInfo ){
super( table, name, typeInfo );
}
public Object clone(){
ContainerSymbol copy = (ContainerSymbol)super.clone();
copy._usingDirectives = ( _usingDirectives != null ) ? (LinkedList) _usingDirectives.clone() : null;
copy._containedSymbols = ( _containedSymbols != null )? (HashMap) _containedSymbols.clone() : null;
return copy;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
public void addSymbol( ISymbol obj ) throws ParserSymbolTableException{
IContainerSymbol containing = this;
//handle enumerators
if( obj.getType() == TypeInfo.t_enumerator ){
//a using declaration of an enumerator will not be contained in a
//enumeration.
if( containing.getType() == TypeInfo.t_enumeration ){
//Following the closing brace of an enum-specifier, each enumerator has the type of its
//enumeration
obj.setTypeSymbol( containing );
//Each enumerator is declared in the scope that immediately contains the enum-specifier
containing = containing.getContainingSymbol();
}
}
//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 );
}
}
Map declarations = containing.getContainedSymbols();
boolean unnamed = obj.getName().equals( ParserSymbolTable.EMPTY_NAME );
Object origObj = null;
obj.setContainingSymbol( containing );
//does this name exist already?
origObj = declarations.get( obj.getName() );
if( origObj != null )
{
ISymbol origDecl = null;
LinkedList origList = null;
if( origObj instanceof ISymbol ){
origDecl = (ISymbol)origObj;
} else if( origObj.getClass() == LinkedList.class ){
origList = (LinkedList)origObj;
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
}
boolean validOverride = ((origList == null) ? ParserSymbolTable.isValidOverload( origDecl, obj ) : ParserSymbolTable.isValidOverload( origList, obj ) );
if( unnamed || validOverride )
{
if( origList == null ){
origList = new LinkedList();
origList.add( origDecl );
origList.add( obj );
declarations.remove( origDecl );
declarations.put( obj.getName(), origList );
} else {
origList.add( obj );
//origList is already in _containedDeclarations
}
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidOverload );
}
} else {
declarations.put( obj.getName(), obj );
}
obj.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
Command command = new AddSymbolCommand( (ISymbol) obj, containing );
getSymbolTable().pushCommand( command );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#hasUsingDirectives()
*/
public boolean hasUsingDirectives(){
return ( _usingDirectives != null && !_usingDirectives.isEmpty() );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getUsingDirectives()
*/
public List getUsingDirectives(){
if( _usingDirectives == null ){
_usingDirectives = new LinkedList();
}
return _usingDirectives;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDirective(org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol)
*/
public void addUsingDirective( IContainerSymbol namespace ) throws ParserSymbolTableException{
if( namespace.getType() != TypeInfo.t_namespace ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidUsing );
}
//handle namespace aliasing
ISymbol alias = namespace.getTypeSymbol();
if( alias != null && alias.isType( TypeInfo.t_namespace ) ){
namespace = (IContainerSymbol) alias;
}
List usingDirectives = getUsingDirectives();
usingDirectives.add( namespace );
Command command = new AddUsingDirectiveCommand( this, namespace );
getSymbolTable().pushCommand( command );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDeclaration(java.lang.String)
*/
/**
* addUsingDeclaration
* @param obj
* @throws ParserSymbolTableException
*
* 7.3.3-9 The entity declared by a using-declaration shall be known in the
* context using it according to its definition at the point of the using-
* declaration. Definitions added to the namespace after the using-
* declaration are not considered when a use of the name is made.
*
* 7.3.3-4 A using-declaration used as a member-declaration shall refer to a
* member of a base class of the class being defined, shall refer to a
* member of an anonymous union that is a member of a base class of the
* class being defined, or shall refer to an enumerator for an enumeration
* type that is a member of a base class of the class being defined.
*/
public ISymbol addUsingDeclaration( String name ) throws ParserSymbolTableException {
return addUsingDeclaration( name, null );
}
/* (non-Javadoc)
* @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 );
if( declContext != null ){
data.qualified = true;
data.templateInstance = declContext.getTemplateInstance();
ParserSymbolTable.lookup( data, declContext );
} else {
ParserSymbolTable.lookup( data, this );
}
//figure out which declaration we are talking about, if it is a set of functions,
//then they will be in data.foundItems (since we provided no parameter info);
ISymbol obj = null;
try{
obj = ParserSymbolTable.resolveAmbiguities( data );
} catch ( ParserSymbolTableException e ) {
if( e.reason != ParserSymbolTableException.r_UnableToResolveFunction ){
throw e;
}
}
if( data.foundItems == null ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidUsing );
}
ISymbol clone = null;
//if obj != null, then that is the only object to consider, so size is 1,
//otherwise we consider the foundItems set
int size = ( obj == null ) ? data.foundItems.size() : 1;
Iterator iter = data.foundItems.iterator();
for( int i = size; i > 0; i-- ){
obj = ( obj != null && size == 1 ) ? obj : (ISymbol) iter.next();
if( ParserSymbolTable.okToAddUsingDeclaration( obj, this ) ){
clone = (BasicSymbol) obj.clone(); //7.3.3-9
addSymbol( clone );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidUsing );
}
}
return ( size == 1 ) ? clone : null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getContainedSymbols()
*/
public Map getContainedSymbols(){
if( _containedSymbols == null ){
_containedSymbols = new HashMap();
}
return _containedSymbols;
}
/* (non-Javadoc)
* @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() );
ParserSymbolTable.lookup( data, this );
return ParserSymbolTable.resolveAmbiguities( data );
}
/* (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() );
ParserSymbolTable.lookup( data, this );
return ParserSymbolTable.resolveAmbiguities( data );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupMemberForDefinition(java.lang.String)
*/
/**
* LookupMemberForDefinition
* @param name
* @return Declaration
* @throws ParserSymbolTableException
*
* In a definition for a namespace member in which the declarator-id is a
* qualified-id, given that the qualified-id for the namespace member has
* the form "nested-name-specifier unqualified-id", the unqualified-id shall
* name a member of the namespace designated by the nested-name-specifier.
*
* ie:
* you have this:
* namespace A{
* namespace B{
* void f1(int);
* }
* using namespace B;
* }
*
* if you then do this
* void A::f1(int) { ... } //ill-formed, f1 is not a member of A
* but, you can do this (Assuming f1 has been defined elsewhere)
* A::f1( 1 ); //ok, finds B::f1
*
* ie, We need a seperate lookup function for looking up the member names
* for a definition.
*/
public ISymbol lookupMemberForDefinition( String name ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
data.qualified = true;
IContainerSymbol container = this;
//handle namespace aliases
if( container.isType( TypeInfo.t_namespace ) ){
ISymbol symbol = container.getTypeSymbol();
if( symbol != null && symbol.isType( TypeInfo.t_namespace ) ){
container = (IContainerSymbol) symbol;
}
}
ParserSymbolTable.lookupInContained( data, container );
return ParserSymbolTable.resolveAmbiguities( data );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupNestedNameSpecifier(java.lang.String)
*/
/**
* Method LookupNestedNameSpecifier.
* @param name
* @return Declaration
* The name of a class or namespace member can be referred to after the ::
* scope resolution operator applied to a nested-name-specifier that
* nominates its class or namespace. During the lookup for a name preceding
* the ::, object, function and enumerator names are ignored. If the name
* is not a class-name or namespace-name, the program is ill-formed
*/
public IContainerSymbol lookupNestedNameSpecifier( String name ) throws ParserSymbolTableException {
return lookupNestedNameSpecifier( name, this );
}
private IContainerSymbol lookupNestedNameSpecifier(String name, IContainerSymbol inSymbol ) throws ParserSymbolTableException{
ISymbol foundSymbol = null;
LookupData data = new LookupData( name, TypeInfo.t_namespace, getTemplateInstance() );
data.upperType = TypeInfo.t_union;
ParserSymbolTable.lookupInContained( data, inSymbol );
if( data.foundItems != null ){
foundSymbol = (ISymbol) ParserSymbolTable.resolveAmbiguities( data );//, data.foundItems );
}
if( foundSymbol == null && inSymbol.getContainingSymbol() != null ){
foundSymbol = lookupNestedNameSpecifier( name, inSymbol.getContainingSymbol() );
}
if( foundSymbol instanceof IContainerSymbol )
return (IContainerSymbol) foundSymbol;
else
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedLookup(java.lang.String)
*/
public ISymbol qualifiedLookup( String name ) throws ParserSymbolTableException{
return qualifiedLookup(name, TypeInfo.t_any);
}
/* (non-Javadoc)
* @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() );
data.qualified = true;
ParserSymbolTable.lookup( data, this );
return ParserSymbolTable.resolveAmbiguities( data );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#unqualifiedFunctionLookup(java.lang.String, java.util.List)
*/
/**
* UnqualifiedFunctionLookup
* @param name
* @param parameters
* @return Declaration
* @throws ParserSymbolTableException
*
* 3.4.2-1 When an unqualified name is used as the post-fix expression in a
* function call, other namespaces not consdiered during the usual
* unqualified lookup may be searched.
*
* 3.4.2-2 For each argument type T in the function call, there is a set of
* zero or more associated namespaces and a set of zero or more associated
* classes to be considered.
*
* If the ordinary unqualified lookup of the name find the declaration of a
* class member function, the associated namespaces and classes are not
* considered. Otherwise, the set of declarations found by the lookup of
* the function name is the union of the set of declarations found using
* ordinary unqualified lookup and the set of declarations found in the
* namespaces and classes associated with the argument types.
*/
public IParameterizedSymbol unqualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{
//figure out the set of associated scopes first, so we can remove those that are searched
//during the normal lookup to avoid doing them twice
HashSet associated = new HashSet();
//collect associated namespaces & classes.
int size = ( parameters == null ) ? 0 : parameters.size();
Iterator iter = ( parameters == null ) ? null : parameters.iterator();
TypeInfo param = null;
ISymbol paramType = null;
for( int i = size; i > 0; i-- ){
param = (TypeInfo) iter.next();
paramType = ParserSymbolTable.getFlatTypeInfo( param ).getTypeSymbol();
if( paramType == null ){
continue;
}
ParserSymbolTable.getAssociatedScopes( paramType, associated );
//if T is a pointer to a data member of class X, its associated namespaces and classes
//are those associated with the member type together with those associated with X
if( param.hasPtrOperators() && param.getPtrOperators().size() == 1 ){
TypeInfo.PtrOp op = (TypeInfo.PtrOp)param.getPtrOperators().iterator().next();
if( op.getType() == TypeInfo.PtrOp.t_pointer &&
paramType.getContainingSymbol().isType( TypeInfo.t_class, TypeInfo.t_union ) )
{
ParserSymbolTable.getAssociatedScopes( paramType.getContainingSymbol(), associated );
}
}
}
LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
//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;
data.associated = associated;
ParserSymbolTable.lookup( data, this );
ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
//if we haven't found anything, or what we found is not a class member, consider the
//associated scopes
if( found == null || found.getContainingSymbol().getType() != TypeInfo.t_class ){
if( found != null ){
data.foundItems.add( found );
}
IContainerSymbol associatedScope;
//dump the hash to an array and iterate over the array because we
//could be removing items from the collection as we go and we don't
//want to get ConcurrentModificationExceptions
Object [] scopes = associated.toArray();
size = associated.size();
for( int i = 0; i < size; i++ ){
associatedScope = (IContainerSymbol) scopes[ i ];
if( associated.contains( associatedScope ) ){
data.qualified = true;
data.ignoreUsingDirectives = true;
ParserSymbolTable.lookup( data, associatedScope );
}
}
found = ParserSymbolTable.resolveAmbiguities( data );
}
if( found instanceof IParameterizedSymbol )
return (IParameterizedSymbol) found;
else
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#memberFunctionLookup(java.lang.String, java.util.List)
*/
/**
* MemberFunctionLookup
* @param name
* @param parameters
* @return Declaration
* @throws ParserSymbolTableException
*
* Member lookup really proceeds as an unqualified lookup, but doesn't
* include argument dependant scopes
*/
public IParameterizedSymbol memberFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
//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;
ParserSymbolTable.lookup( data, (IContainerSymbol) this );
return (IParameterizedSymbol) ParserSymbolTable.resolveAmbiguities( data );
}
/* (non-Javadoc)
* @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() );
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.
data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
ParserSymbolTable.lookup( data, (IContainerSymbol)this );
return (IParameterizedSymbol) ParserSymbolTable.resolveAmbiguities( data );
}
/* (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
{
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
data.parameters = arguments;
ParserSymbolTable.lookup( data, (IContainerSymbol) this );
ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
if( found.isType( TypeInfo.t_template ) ){
return ((IParameterizedSymbol) found).instantiate( arguments );
}
return null;
}
/* (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;
}
static private class AddSymbolCommand extends Command{
AddSymbolCommand( ISymbol newDecl, IContainerSymbol context ){
_symbol = newDecl;
_context = context;
}
public void undoIt(){
Object obj = _context.getContainedSymbols().get( _symbol.getName() );
if( obj instanceof LinkedList ){
LinkedList list = (LinkedList)obj;
ListIterator iter = list.listIterator();
int size = list.size();
ISymbol item = null;
for( int i = 0; i < size; i++ ){
item = (ISymbol)iter.next();
if( item == _symbol ){
iter.remove();
break;
}
}
if( list.size() == 1 ){
_context.getContainedSymbols().remove( _symbol.getName() );
_context.getContainedSymbols().put( _symbol.getName(), list.getFirst() );
}
} else if( obj instanceof BasicSymbol ){
_context.getContainedSymbols().remove( _symbol.getName() );
}
// if( _removeThis && _symbol instanceof IParameterizedSymbol ){
// ((IParameterizedSymbol)_symbol).getContainedSymbols().remove( ParserSymbolTable.THIS );
// }
}
private ISymbol _symbol;
private IContainerSymbol _context;
}
static private class AddUsingDirectiveCommand extends Command{
public AddUsingDirectiveCommand( IContainerSymbol container, IContainerSymbol namespace ){
_decl = container;
_namespace = namespace;
}
public void undoIt(){
_decl.getUsingDirectives().remove( _namespace );
}
private IContainerSymbol _decl;
private IContainerSymbol _namespace;
}
private LinkedList _usingDirectives; //collection of nominated namespaces
private HashMap _containedSymbols; //declarations contained by us.
}

View file

@ -0,0 +1,357 @@
/*******************************************************************************
* 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.LinkedList;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Command;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.LookupData;
/**
* @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
*/
public class DerivableContainerSymbol extends ContainerSymbol implements IDerivableContainerSymbol {
protected DerivableContainerSymbol( ParserSymbolTable table, String name ){
super( table, name );
}
protected DerivableContainerSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
super( table, name, obj );
}
protected DerivableContainerSymbol( ParserSymbolTable table, String name, TypeInfo.eType typeInfo ){
super( table, name, typeInfo );
}
public Object clone(){
DerivableContainerSymbol copy = (DerivableContainerSymbol)super.clone();
copy._parentScopes = ( _parentScopes != null ) ? (LinkedList) _parentScopes.clone() : null;
copy._constructors = ( _constructors != null ) ? (LinkedList) _constructors.clone() : null;
return copy;
}
public void addSymbol(ISymbol symbol) throws ParserSymbolTableException {
super.addSymbol( symbol );
//take care of the this pointer
if( symbol instanceof IParameterizedSymbol ){
addThis( (IParameterizedSymbol) symbol );
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#addParent(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
public void addParent( ISymbol parent ){
addParent( parent, false, ASTAccessVisibility.PUBLIC, -1, null );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#addParent(org.eclipse.cdt.internal.core.parser.pst.ISymbol, boolean, org.eclipse.cdt.core.parser.ast.ASTAccessVisibility, int, java.util.List)
*/
public void addParent( ISymbol parent, boolean virtual, ASTAccessVisibility visibility, int offset, List references ){
if( _parentScopes == null ){
_parentScopes = new LinkedList();
}
ParentWrapper wrapper = new ParentWrapper( parent, virtual, visibility, offset, references );
_parentScopes.add( wrapper );
Command command = new AddParentCommand( this, wrapper );
getSymbolTable().pushCommand( command );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#getParents()
*/
public List getParents(){
if( _parentScopes == null ){
_parentScopes = new LinkedList();
}
return _parentScopes;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#hasParents()
*/
public boolean hasParents(){
return ( _parentScopes != null && !_parentScopes.isEmpty() );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#addConstructor(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
*/
public void addConstructor(IParameterizedSymbol constructor) throws ParserSymbolTableException {
if( !constructor.isType( TypeInfo.t_constructor ) )
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
List constructors = getConstructors();
if( constructors.size() == 0 || ParserSymbolTable.isValidOverload( constructors, constructor ) ){
constructors.add( constructor );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidOverload );
}
constructor.setContainingSymbol( this );
addThis( constructor );
Command command = new AddConstructorCommand( constructor, this );
getSymbolTable().pushCommand( command );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#addCopyConstructor()
*/
public void addCopyConstructor() throws ParserSymbolTableException{
List parameters = new LinkedList();
TypeInfo param = new TypeInfo( TypeInfo.t_type, 0, this, new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference, true, false ), false );
parameters.add( param );
IParameterizedSymbol constructor = lookupConstructor( parameters );
if( constructor == null ){
constructor = getSymbolTable().newParameterizedSymbol( getName(), TypeInfo.t_constructor );
constructor.addParameter( this, new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference, true, false ), false );
addConstructor( constructor );
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#lookupConstructor(java.util.List)
*/
public IParameterizedSymbol lookupConstructor( List parameters ) throws ParserSymbolTableException
{
LookupData data = new LookupData( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_constructor, null );
data.parameters = parameters;
List constructors = new LinkedList();
if( !getConstructors().isEmpty() )
constructors.addAll( getConstructors() );
return ParserSymbolTable.resolveFunction( data, constructors );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#getConstructors()
*/
public List getConstructors(){
if( _constructors == null ){
_constructors = new LinkedList();
}
return _constructors;
}
/**
*
* @param obj
* @throws ParserSymbolTableException
* 9.3.2-1 In the body of a nonstatic member function... the type of this of
* a class X is X*. If the member function is declared const, the type of
* this is const X*, if the member function is declared volatile, the type
* of this is volatile X*....
*/
private boolean addThis( IParameterizedSymbol obj ){
if( getSymbolTable().getLanguage() != ParserLanguage.CPP ){
return false;
}
TypeInfo type = obj.getTypeInfo();
if( ( !type.isType( TypeInfo.t_function ) && !type.isType( TypeInfo.t_constructor) ) ||
type.checkBit( TypeInfo.isStatic ) ){
return false;
}
if( obj.getContainingSymbol().isType( TypeInfo.t_class, TypeInfo.t_union ) ){
//check to see if there is already a this object, since using declarations
//of function will have them from the original declaration
LookupData data = new LookupData( ParserSymbolTable.THIS, TypeInfo.t_any, null );
ParserSymbolTable.lookupInContained( data, obj );
//if we didn't find "this" then foundItems will still be null, no need to actually
//check its contents
if( data.foundItems == null ){
ISymbol thisObj = getSymbolTable().newSymbol( ParserSymbolTable.THIS, TypeInfo.t_type );
thisObj.setTypeSymbol( obj.getContainingSymbol() );
//thisObj.setCVQualifier( obj.getCVQualifier() );
TypeInfo.PtrOp ptr = new TypeInfo.PtrOp();
ptr.setType( TypeInfo.PtrOp.t_pointer );
if( obj.getTypeInfo().hasPtrOperators() ){
ptr.setConst( ((TypeInfo.PtrOp) obj.getPtrOperators().iterator().next()).isConst() );
ptr.setVolatile( ((TypeInfo.PtrOp) obj.getPtrOperators().iterator().next()).isVolatile() );
}
thisObj.addPtrOperator(ptr);
try{
obj.addSymbol( thisObj );
} catch ( ParserSymbolTableException e ) {
//shouldn't happen because we checked that "this" didn't exist already
return false;
}
}
}
return true;
}
/**
*
* @param name
* @return Declaration
* @throws ParserSymbolTableException
*
* 7.3.1.2-3 If a friend declaration in a non-local class first declares a
* class or function, the friend class or function is a member of the
* innermost enclosing namespace.
*
* TODO: if/when the parser symbol table starts caring about visibility
* (public/protected/private) we will need to do more to record friendship.
*/
private ISymbol addFriend( String name ) throws ParserSymbolTableException{
ISymbol friend = lookupForFriendship( name );
if( friend == null ){
friend = getSymbolTable().newSymbol( name );
friend.getTypeInfo().setIsForwardDeclaration( true );
IContainerSymbol containing = getContainingSymbol();
//find innermost enclosing namespace
while( containing != null && containing.getType() != TypeInfo.t_namespace ){
containing = containing.getContainingSymbol();
}
IContainerSymbol namespace = ( containing == null ) ? getSymbolTable().getCompilationUnit() : containing;
namespace.addSymbol( friend );
}
return friend;
}
/**
* LookupForFriendship
* @param name
* @return Declaration
* 7.3.1.2-3 When looking for a prior declaration of a class or a function
* declared as a friend, scopes outside the innermost enclosing namespace
* scope are not considered.
* 11.4-9 If a friend declaration appears in a local class and the name
* specified is an unqualified name, a prior declaration is looked up
* without considering scopes that are outside the innermost enclosing non-
* class scope.
*/
private ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
boolean inClass = ( getType() == TypeInfo.t_class);
IContainerSymbol enclosing = getContainingSymbol();
while( enclosing != null && (inClass ? enclosing.getType() != TypeInfo.t_class
: enclosing.getType() == TypeInfo.t_namespace) )
{
enclosing = enclosing.getContainingSymbol();
}
data.stopAt = enclosing;
ParserSymbolTable.lookup( data, this );
return ParserSymbolTable.resolveAmbiguities( data );
}
static private class AddParentCommand extends Command{
public AddParentCommand( IDerivableContainerSymbol container, ParentWrapper wrapper ){
_decl = container;
_wrapper = wrapper;
}
public void undoIt(){
List parents = _decl.getParents();
parents.remove( _wrapper );
}
private IDerivableContainerSymbol _decl;
private ParentWrapper _wrapper;
}
static private class AddConstructorCommand extends Command{
AddConstructorCommand( IParameterizedSymbol newConstr, IDerivableContainerSymbol context ){
_constructor = newConstr;
_context = context;
}
public void undoIt(){
List constructors = _context.getConstructors();
ListIterator iter = constructors.listIterator();
int size = constructors.size();
IParameterizedSymbol item = null;
for( int i = 0; i < size; i++ ){
item = (IParameterizedSymbol)iter.next();
if( item == _constructor ){
iter.remove();
break;
}
}
}
private IParameterizedSymbol _constructor;
private IDerivableContainerSymbol _context;
}
public class ParentWrapper implements IDerivableContainerSymbol.IParentSymbol
{
public ParentWrapper( ISymbol p, boolean v, ASTAccessVisibility s, int offset, List r ){
parent = p;
isVirtual = v;
access = s;
this.offset = offset;
this.references = r;
}
public void setParent( ISymbol parent ){ this.parent = parent; }
public ISymbol getParent() { return parent; }
public boolean isVirtual() { return isVirtual; }
public void setVirtual( boolean virtual ){ isVirtual = virtual; }
public ASTAccessVisibility getVisibility(){ return access; }
public ASTAccessVisibility getAccess() { return access; }
public int getOffset() { return offset; }
public List getReferences() { return references; }
private boolean isVirtual = false;
protected ISymbol parent = null;
private final ASTAccessVisibility access;
private final int offset;
private final List references;
}
private LinkedList _constructors; //constructor list
private LinkedList _parentScopes; //inherited scopes (is base classes)
}

View file

@ -19,7 +19,6 @@ package org.eclipse.cdt.internal.core.parser.pst;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
/**
* @author aniefer

View file

@ -43,6 +43,10 @@ public interface IDerivableContainerSymbol extends IContainerSymbol {
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

@ -34,11 +34,11 @@ public interface IParameterizedSymbol extends IContainerSymbol {
public void addArgument( ISymbol arg );
public List getArgumentList();
public void setArgumentList( List list );
//public void setArgumentList( List list );
public Map getParameterMap();
public List getParameterList();
public void setParameterList( List list );
//public void setParameterList( List list );
public boolean hasSameParameters(IParameterizedSymbol newDecl);

View file

@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.parser.pst;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
/**
* @author jcamelon
*

View file

@ -0,0 +1,282 @@
/*******************************************************************************
* 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.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
*/
public class ParameterizedSymbol extends ContainerSymbol implements IParameterizedSymbol {
protected ParameterizedSymbol( ParserSymbolTable table, String name ){
super( table, name );
}
protected ParameterizedSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
super( table, name, obj );
}
protected ParameterizedSymbol( ParserSymbolTable table, String name, TypeInfo.eType typeInfo ){
super( table, name, typeInfo );
}
public Object clone(){
ParameterizedSymbol copy = (ParameterizedSymbol)super.clone();
copy._parameterList = ( _parameterList != null ) ? (LinkedList) _parameterList.clone() : null;
copy._parameterMap = ( _parameterMap != null ) ? (HashMap) _parameterMap.clone() : null;
copy._argumentList = ( _argumentList != null ) ? (LinkedList) _argumentList.clone() : null;
copy._specializations = ( _specializations != null ) ? (LinkedList) _specializations.clone() : null;
return copy;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
public void addParameter( ISymbol param ){
List paramList = getParameterList();
paramList.add( param );
String name = param.getName();
if( name != null && !name.equals(ParserSymbolTable.EMPTY_NAME) )
{
Map paramMap = getParameterMap();
if( !paramMap.containsKey( name ) )
paramMap.put( name, param );
}
param.setContainingSymbol( this );
param.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
Command command = new AddParameterCommand( this, (BasicSymbol)param );
getSymbolTable().pushCommand( command );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType, int, org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp, boolean)
*/
public void addParameter( TypeInfo.eType type, int info, TypeInfo.PtrOp ptrOp, boolean hasDefault ){
BasicSymbol param = new BasicSymbol(getSymbolTable(), ParserSymbolTable.EMPTY_NAME);
TypeInfo t = param.getTypeInfo();
t.setTypeInfo( info );
t.setType( type );
t.addPtrOperator( ptrOp );
t.setHasDefault( hasDefault );
addParameter( param );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol, org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp, boolean)
*/
public void addParameter( ISymbol typeSymbol, TypeInfo.PtrOp ptrOp, boolean hasDefault ){
BasicSymbol param = new BasicSymbol(getSymbolTable(), ParserSymbolTable.EMPTY_NAME);
TypeInfo info = param.getTypeInfo();
info.setType( TypeInfo.t_type );
info.setTypeSymbol( typeSymbol );
info.addPtrOperator( ptrOp );
info.setHasDefault( hasDefault );
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, (BasicSymbol) 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()
*/
public Map getParameterMap(){
if( _parameterMap == null ){
_parameterMap = new HashMap();
}
return _parameterMap;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterList()
*/
public List getParameterList(){
if( _parameterList == null ){
_parameterList = new LinkedList();
}
return _parameterList;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#setParameterList(java.util.List)
*/
// public void setParameterList( List list ){
// _parameterList = new LinkedList( list );
// }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasSameParameters(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
*/
public boolean hasSameParameters( IParameterizedSymbol function ){
if( function.getType() != getType() ){
return false;
}
int size = ( getParameterList() == null ) ? 0 : getParameterList().size();
int fsize = ( function.getParameterList() == null ) ? 0 : function.getParameterList().size();
if( fsize != size ){
return false;
}
if( fsize == 0 )
return true;
Iterator iter = getParameterList().iterator();
Iterator fIter = function.getParameterList().iterator();
TypeInfo info = null;
TypeInfo fInfo = null;
for( int i = size; i > 0; i-- ){
info = ((BasicSymbol)iter.next()).getTypeInfo();
fInfo = ((BasicSymbol) fIter.next()).getTypeInfo();
if( !info.equals( fInfo ) ){
return false;
}
}
return true;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#setReturnType(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
public void setReturnType( ISymbol type ){
_returnType = type;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getReturnType()
*/
public ISymbol getReturnType(){
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;
}
static private class AddParameterCommand extends Command{
public AddParameterCommand( IParameterizedSymbol container, ISymbol parameter ){
_decl = container;
_param = parameter;
}
public void undoIt(){
_decl.getParameterList().remove( _param );
String name = _param.getName();
if( name != null && !name.equals( ParserSymbolTable.EMPTY_NAME) )
{
_decl.getParameterMap().remove( name );
}
}
private IParameterizedSymbol _decl;
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 HashMap _parameterMap; //and eat it too
private LinkedList _specializations; //template specializations
private LinkedList _argumentList; //template specialization arguments
private ISymbol _returnType;
}

View file

@ -0,0 +1,30 @@
/*******************************************************************************
* 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;
/**
* @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
*/
public class SpecializedSymbol extends ParameterizedSymbol implements ISpecializedSymbol {
protected SpecializedSymbol( ParserSymbolTable table, String name ){
super( table, name, TypeInfo.t_template );
}
protected SpecializedSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
super( table, name, obj );
}
}

View file

@ -0,0 +1,134 @@
/*******************************************************************************
* 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
{
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

@ -16,7 +16,6 @@ import java.util.List;
import java.util.ListIterator;
import org.eclipse.cdt.core.parser.Enum;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
public class TypeInfo {
@ -316,17 +315,38 @@ public class TypeInfo {
}
public List getPtrOperators(){
if( _ptrOperators == null ){
_ptrOperators = new LinkedList();
}
return _ptrOperators;
}
public boolean hasSamePtrs( TypeInfo type ){
int size = hasPtrOperators() ? getPtrOperators().size() : 0;
int size2 = type.hasPtrOperators() ? type.getPtrOperators().size() : 0;
int size = getPtrOperators().size();
int size2 = type.getPtrOperators().size();
Iterator iter1 = getPtrOperators().iterator();
Iterator iter2 = type.getPtrOperators().iterator();
TypeInfo.PtrOp ptr1 = null, ptr2 = null;
if( size2 < size ) {
for( int i = size; i > size2; i-- ){
ptr2 = (PtrOp) iter1.next();
if( ptr2.getType() != PtrOp.t_undef ){
return false;
}
}
size = size2;
} else if ( size < size2 ){
for( int i = size2; i > size; i-- ){
ptr1 = (PtrOp)iter2.next();
if( ptr1.getType() != PtrOp.t_undef ){
return false;
}
}
size2 = size;
}
if( size == size2 ){
if( size > 0 ){
Iterator iter1 = getPtrOperators().iterator();
Iterator iter2 = type.getPtrOperators().iterator();
TypeInfo.PtrOp ptr1 = null, ptr2 = null;
for( int i = size; i > 0; i-- ){
ptr1 = (TypeInfo.PtrOp)iter1.next();
ptr2 = (TypeInfo.PtrOp)iter2.next();
@ -336,11 +356,14 @@ public class TypeInfo {
}
}
return true;
}
}
return false;
}
public List getOperatorExpressions(){
if( _operatorExpressions == null ){
_operatorExpressions = new LinkedList();
}
return _operatorExpressions;
}