1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-27 19:05:38 +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 2003-11-13 Hoda Amer
Added CompleteParseASTTest::testBug44342(): Failure to dereference function calls after a . or an -> Added CompleteParseASTTest::testBug44342(): Failure to dereference function calls after a . or an ->
Moved testErrorHandling_1() to FailedCompleteParseASTTest 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.ParserSymbolTable;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException; 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.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.TypeInfo;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Mark; 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.OperatorExpression;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp; import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
@ -92,7 +92,7 @@ public class ParserSymbolTableTest extends TestCase {
public void testSimpleLookup() throws Exception{ public void testSimpleLookup() throws Exception{
newTable(); //new symbol table newTable(); //new symbol table
ISymbol x = table.new Declaration( "x" ); ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( x ); table.getCompilationUnit().addSymbol( x );
ISymbol look = table.getCompilationUnit().lookup( "x" ); ISymbol look = table.getCompilationUnit().lookup( "x" );
@ -110,7 +110,7 @@ public class ParserSymbolTableTest extends TestCase {
public void testSimpleSetGetObject() throws Exception{ public void testSimpleSetGetObject() throws Exception{
newTable(); newTable();
IContainerSymbol x = table.new Declaration("x"); IContainerSymbol x = table.newContainerSymbol( "x", TypeInfo.t_namespace );
ISymbolASTExtension extension = new StandardSymbolExtension(x,null); ISymbolASTExtension extension = new StandardSymbolExtension(x,null);
@ -188,7 +188,7 @@ public class ParserSymbolTableTest extends TestCase {
class1.setType( TypeInfo.t_class ); class1.setType( TypeInfo.t_class );
class1.addParent( parent ); class1.addParent( parent );
ISymbol decl = table.new Declaration("x"); ISymbol decl = table.newSymbol( "x", TypeInfo.t_int );
parent.addSymbol( decl ); parent.addSymbol( decl );
table.getCompilationUnit().addSymbol( parent ); table.getCompilationUnit().addSymbol( parent );
@ -216,7 +216,7 @@ public class ParserSymbolTableTest extends TestCase {
IDerivableContainerSymbol class1 = (IDerivableContainerSymbol) table.getCompilationUnit().lookup( "class" ); IDerivableContainerSymbol class1 = (IDerivableContainerSymbol) table.getCompilationUnit().lookup( "class" );
class1.addParent( parent2 ); class1.addParent( parent2 );
ISymbol decl = table.new Declaration("x"); ISymbol decl = table.newSymbol( "x", TypeInfo.t_int );
parent2.addSymbol( decl ); parent2.addSymbol( decl );
try{ try{
@ -283,7 +283,7 @@ public class ParserSymbolTableTest extends TestCase {
IContainerSymbol compUnit = table.getCompilationUnit(); IContainerSymbol compUnit = table.getCompilationUnit();
compUnit.addSymbol( c ); compUnit.addSymbol( c );
ISymbol x = table.new Declaration( "x" ); ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
c.addSymbol( x ); c.addSymbol( x );
compUnit.addSymbol( decl ); compUnit.addSymbol( decl );
@ -357,16 +357,14 @@ public class ParserSymbolTableTest extends TestCase {
compUnit.addSymbol( c ); compUnit.addSymbol( c );
compUnit.addSymbol( d ); compUnit.addSymbol( d );
IContainerSymbol enum = table.new Declaration("enum"); IContainerSymbol enum = table.newContainerSymbol( "enum", TypeInfo.t_enumeration );
enum.setType( TypeInfo.t_enumeration );
ISymbol enumerator = table.new Declaration( "enumerator" ); ISymbol enumerator = table.newSymbol( "enumerator", TypeInfo.t_enumerator );
enumerator.setType( TypeInfo.t_enumerator );
ISymbol stat = table.new Declaration("static"); ISymbol stat = table.newSymbol( "static", TypeInfo.t_int );
stat.getTypeInfo().setBit( true, TypeInfo.isStatic ); 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( enum );
d.addSymbol( stat ); d.addSymbol( stat );
@ -1110,12 +1108,10 @@ public class ParserSymbolTableTest extends TestCase {
IContainerSymbol compUnit = table.getCompilationUnit(); IContainerSymbol compUnit = table.getCompilationUnit();
ParserSymbolTable.Declaration A = table.new Declaration( "A" ); IContainerSymbol A = table.newContainerSymbol( "A", TypeInfo.t_namespace );
A.setType( TypeInfo.t_namespace );
compUnit.addSymbol( A ); compUnit.addSymbol( A );
ParserSymbolTable.Declaration f1 = table.new Declaration( "f" ); IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.setType( TypeInfo.t_function );
f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f1.addParameter( TypeInfo.t_int, 0, null, false ); f1.addParameter( TypeInfo.t_int, 0, null, false );
A.addSymbol( f1 ); A.addSymbol( f1 );
@ -1172,8 +1168,7 @@ public class ParserSymbolTableTest extends TestCase {
public void testThisPointer() throws Exception{ public void testThisPointer() throws Exception{
newTable(); newTable();
IContainerSymbol cls = table.newContainerSymbol("class"); IDerivableContainerSymbol cls = table.newDerivableContainerSymbol( "class", TypeInfo.t_class );
cls.setType( TypeInfo.t_class );
IParameterizedSymbol fn = table.newParameterizedSymbol("function"); IParameterizedSymbol fn = table.newParameterizedSymbol("function");
fn.setType( TypeInfo.t_function ); fn.setType( TypeInfo.t_function );
@ -1319,8 +1314,7 @@ public class ParserSymbolTableTest extends TestCase {
compUnit.addSymbol( NS1 ); compUnit.addSymbol( NS1 );
ParserSymbolTable.Declaration f1 = table.new Declaration( "f" ); IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.setType( TypeInfo.t_function );
f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f1.addParameter( TypeInfo.t_void, 0, new PtrOp( PtrOp.t_pointer ), false ); f1.addParameter( TypeInfo.t_void, 0, new PtrOp( PtrOp.t_pointer ), false );
NS1.addSymbol( f1 ); NS1.addSymbol( f1 );
@ -1992,7 +1986,7 @@ public class ParserSymbolTableTest extends TestCase {
LinkedList args = new LinkedList(); LinkedList args = new LinkedList();
args.add( type ); args.add( type );
ParserSymbolTable.TemplateInstance instance = table.getCompilationUnit().templateLookup( "A", args ); TemplateInstance instance = table.getCompilationUnit().templateLookup( "A", args );
assertEquals( instance.getInstantiatedSymbol(), A ); assertEquals( instance.getInstantiatedSymbol(), A );
ISymbol a = table.newSymbol( "a", TypeInfo.t_type ); ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
@ -2047,7 +2041,7 @@ public class ParserSymbolTableTest extends TestCase {
args.add( type ); args.add( type );
look = table.getCompilationUnit().templateLookup( "A", args ); look = table.getCompilationUnit().templateLookup( "A", args );
assertTrue( look instanceof ParserSymbolTable.TemplateInstance ); assertTrue( look instanceof TemplateInstance );
B.addParent( look ); B.addParent( look );
table.getCompilationUnit().addSymbol( B ); 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 2003-11-13 Hoda Amer
Changed the getExpressionResultType() in the complete factory to return Changed the getExpressionResultType() in the complete factory to return
an object of type ExpressionResult. 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.ast.NamedOffsets;
import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol; 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.ISymbol;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable; import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol.IParentSymbol;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Declaration.ParentWrapper;
/** /**
* @author jcamelon * @author jcamelon
@ -65,7 +64,7 @@ public class ASTClassSpecifier extends ASTScope implements IASTClassSpecifier
if( ! hasNext() ) if( ! hasNext() )
throw new NoSuchElementException(); 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() ); 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.List;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
/** /**
* @author aniefer * @author aniefer

View file

@ -43,6 +43,10 @@ public interface IDerivableContainerSymbol extends IContainerSymbol {
public ISymbol getParent(); public ISymbol getParent();
public boolean isVirtual(); public boolean isVirtual();
public void setVirtual( boolean virtual ); public void setVirtual( boolean virtual );
public ASTAccessVisibility getVisibility(); 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 void addArgument( ISymbol arg );
public List getArgumentList(); public List getArgumentList();
public void setArgumentList( List list ); //public void setArgumentList( List list );
public Map getParameterMap(); public Map getParameterMap();
public List getParameterList(); public List getParameterList();
public void setParameterList( List list ); //public void setParameterList( List list );
public boolean hasSameParameters(IParameterizedSymbol newDecl); 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.List;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
/** /**
* @author jcamelon * @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 java.util.ListIterator;
import org.eclipse.cdt.core.parser.Enum; import org.eclipse.cdt.core.parser.Enum;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
public class TypeInfo { public class TypeInfo {
@ -316,17 +315,38 @@ public class TypeInfo {
} }
public List getPtrOperators(){ public List getPtrOperators(){
if( _ptrOperators == null ){
_ptrOperators = new LinkedList();
}
return _ptrOperators; return _ptrOperators;
} }
public boolean hasSamePtrs( TypeInfo type ){ public boolean hasSamePtrs( TypeInfo type ){
int size = hasPtrOperators() ? getPtrOperators().size() : 0; int size = getPtrOperators().size();
int size2 = type.hasPtrOperators() ? type.getPtrOperators().size() : 0; 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 == size2 ){
if( size > 0 ){ 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-- ){ for( int i = size; i > 0; i-- ){
ptr1 = (TypeInfo.PtrOp)iter1.next(); ptr1 = (TypeInfo.PtrOp)iter1.next();
ptr2 = (TypeInfo.PtrOp)iter2.next(); ptr2 = (TypeInfo.PtrOp)iter2.next();
@ -336,11 +356,14 @@ public class TypeInfo {
} }
} }
return true; return true;
} }
return false; return false;
} }
public List getOperatorExpressions(){ public List getOperatorExpressions(){
if( _operatorExpressions == null ){
_operatorExpressions = new LinkedList();
}
return _operatorExpressions; return _operatorExpressions;
} }