1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

reduce the number of LinkedLists created by the symbol table.

This commit is contained in:
Andrew Niefer 2004-05-03 20:09:15 +00:00
parent 56bd43a638
commit 0eef7aec8a
8 changed files with 203 additions and 175 deletions

View file

@ -58,14 +58,14 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
public Object clone(){ public Object clone(){
ContainerSymbol copy = (ContainerSymbol)super.clone(); ContainerSymbol copy = (ContainerSymbol)super.clone();
copy._usingDirectives = ( _usingDirectives != null ) ? (LinkedList) _usingDirectives.clone() : null; copy._usingDirectives = (_usingDirectives != ParserSymbolTable.EMPTY_LIST) ? (LinkedList) _usingDirectives.clone() : _usingDirectives;
if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE ) if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE )
copy._containedSymbols = ( _containedSymbols != null )? (Map)((TreeMap) _containedSymbols).clone() : null; copy._containedSymbols = ( _containedSymbols != ParserSymbolTable.EMPTY_MAP )? (Map)((TreeMap) _containedSymbols).clone() : _containedSymbols;
else else
copy._containedSymbols = ( _containedSymbols != null )? (Map)((HashMap) _containedSymbols).clone() : null; copy._containedSymbols = ( _containedSymbols != ParserSymbolTable.EMPTY_MAP )? (Map)((HashMap) _containedSymbols).clone() : _containedSymbols;
copy._contents = ( _contents != null )? (LinkedList) _contents.clone() : null; copy._contents = (_contents != ParserSymbolTable.EMPTY_LIST) ? (LinkedList) _contents.clone() : _contents;
return copy; return copy;
} }
@ -80,7 +80,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
Iterator iter = getContentsIterator(); Iterator iter = getContentsIterator();
newContainer.getContainedSymbols().clear(); newContainer.getContainedSymbols().clear();
if( newContainer._contents != null ){ if( !newContainer._contents.isEmpty() ){
newContainer._contents.clear(); newContainer._contents.clear();
IExtensibleSymbol containedSymbol = null; IExtensibleSymbol containedSymbol = null;
@ -117,7 +117,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
} }
Map instanceMap = argMap; Map instanceMap = argMap;
if( template.getDefinitionParameterMap() != null && if( !template.getDefinitionParameterMap().isEmpty() &&
template.getDefinitionParameterMap().containsKey( containedSymbol ) ) template.getDefinitionParameterMap().containsKey( containedSymbol ) )
{ {
Map defMap = (Map) template.getDefinitionParameterMap().get( containedSymbol ); Map defMap = (Map) template.getDefinitionParameterMap().get( containedSymbol );
@ -144,10 +144,10 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
List list = new LinkedList(); List list = new LinkedList();
list.add( obj ); list.add( obj );
list.add( newSymbol ); list.add( newSymbol );
newContainer.getContainedSymbols().put( newSymbol.getName(), list ); newContainer.putInContainedSymbols( newSymbol.getName(), list );
} }
} else { } else {
newContainer.getContainedSymbols().put( newSymbol.getName(), newSymbol ); newContainer.putInContainedSymbols( newSymbol.getName(), newSymbol );
} }
} }
} }
@ -199,8 +199,6 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
} }
} }
Map declarations = containing.getContainedSymbols();
boolean unnamed = obj.getName().equals( ParserSymbolTable.EMPTY_NAME ); boolean unnamed = obj.getName().equals( ParserSymbolTable.EMPTY_NAME );
Object origObj = null; Object origObj = null;
@ -208,7 +206,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
obj.setContainingSymbol( containing ); obj.setContainingSymbol( containing );
//does this name exist already? //does this name exist already?
origObj = declarations.get( obj.getName() ); origObj = containing.getContainedSymbols().get( obj.getName() );
if( origObj != null ) if( origObj != null )
{ {
@ -234,7 +232,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
origList.add( origDecl ); origList.add( origDecl );
origList.add( obj ); origList.add( obj );
declarations.put( obj.getName(), origList ); ((ContainerSymbol)containing).putInContainedSymbols( obj.getName(), origList );
} else { } else {
origList.add( obj ); origList.add( obj );
//origList is already in _containedDeclarations //origList is already in _containedDeclarations
@ -243,12 +241,12 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidOverload ); throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidOverload );
} }
} else { } else {
declarations.put( obj.getName(), obj ); ((ContainerSymbol)containing).putInContainedSymbols( obj.getName(), obj );
} }
obj.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template ); obj.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
getContents().add( obj ); addToContents( obj );
Command command = new AddSymbolCommand( obj, containing ); Command command = new AddSymbolCommand( obj, containing );
getSymbolTable().pushCommand( command ); getSymbolTable().pushCommand( command );
@ -294,18 +292,20 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#hasUsingDirectives() * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#hasUsingDirectives()
*/ */
public boolean hasUsingDirectives(){ public boolean hasUsingDirectives(){
return ( _usingDirectives != null && !_usingDirectives.isEmpty() ); return !_usingDirectives.isEmpty();
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getUsingDirectives() * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getUsingDirectives()
*/ */
public List getUsingDirectives(){ public List getUsingDirectives(){
if( _usingDirectives == null ){ return _usingDirectives;
_usingDirectives = new LinkedList();
} }
return _usingDirectives; protected void addToUsingDirectives( IExtensibleSymbol symbol ){
if( _usingDirectives == ParserSymbolTable.EMPTY_LIST )
_usingDirectives = new LinkedList();
_usingDirectives.add( symbol );
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDirective(org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDirective(org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol)
@ -325,12 +325,10 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
namespace = (IContainerSymbol) alias; namespace = (IContainerSymbol) alias;
} }
List usingDirectives = getUsingDirectives();
IUsingDirectiveSymbol usingDirective = new UsingDirectiveSymbol( getSymbolTable(), namespace ); IUsingDirectiveSymbol usingDirective = new UsingDirectiveSymbol( getSymbolTable(), namespace );
usingDirectives.add( usingDirective );
getContents().add( usingDirective ); addToUsingDirectives( usingDirective );
addToContents( usingDirective );
Command command = new AddUsingDirectiveCommand( this, usingDirective ); Command command = new AddUsingDirectiveCommand( this, usingDirective );
getSymbolTable().pushCommand( command ); getSymbolTable().pushCommand( command );
@ -407,7 +405,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
while( symbol != null ){ while( symbol != null ){
if( ParserSymbolTable.okToAddUsingDeclaration( symbol, this ) ){ if( ParserSymbolTable.okToAddUsingDeclaration( symbol, this ) ){
if( ! addedUsingToContained ){ if( ! addedUsingToContained ){
getContents().add( usingDeclaration ); addToContents( usingDeclaration );
addedUsingToContained = true; addedUsingToContained = true;
} }
clone = (ISymbol) symbol.clone(); //7.3.3-9 clone = (ISymbol) symbol.clone(); //7.3.3-9
@ -433,17 +431,19 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getContainedSymbols() * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getContainedSymbols()
*/ */
public Map getContainedSymbols(){ public Map getContainedSymbols(){
if( _containedSymbols == null ){ return _containedSymbols;
}
protected void putInContainedSymbols( String key, Object obj ){
if( _containedSymbols == ParserSymbolTable.EMPTY_MAP ){
if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE ){ if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE ){
_containedSymbols = new TreeMap( new SymbolTableComparator() ); _containedSymbols = new TreeMap( new SymbolTableComparator() );
} else { } else {
_containedSymbols = new HashMap( ); _containedSymbols = new HashMap( );
} }
} }
return _containedSymbols; _containedSymbols.put( key, obj );
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#elaboratedLookup(org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType, java.lang.String) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#elaboratedLookup(org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType, java.lang.String)
*/ */
@ -534,14 +534,15 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
} }
data.foundItems = ParserSymbolTable.lookupInContained( data, container ); data.foundItems = ParserSymbolTable.lookupInContained( data, container );
if( data.foundItems != null )
return ParserSymbolTable.resolveAmbiguities( data ); return ParserSymbolTable.resolveAmbiguities( data );
return null;
} }
public IParameterizedSymbol lookupMethodForDefinition( String name, List parameters ) throws ParserSymbolTableException{ public IParameterizedSymbol lookupMethodForDefinition( String name, List parameters ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_any ); LookupData data = new LookupData( name, TypeInfo.t_any );
data.qualified = true; data.qualified = true;
data.parameters = ( parameters == null ) ? new LinkedList() : parameters; data.parameters = ( parameters == null ) ? ParserSymbolTable.EMPTY_LIST : parameters;
data.exactFunctionsOnly = true; data.exactFunctionsOnly = true;
IContainerSymbol container = this; IContainerSymbol container = this;
@ -556,9 +557,13 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
data.foundItems = ParserSymbolTable.lookupInContained( data, container ); data.foundItems = ParserSymbolTable.lookupInContained( data, container );
if( data.foundItems != null ){
ISymbol symbol = ParserSymbolTable.resolveAmbiguities( data ); ISymbol symbol = ParserSymbolTable.resolveAmbiguities( data );
return (IParameterizedSymbol) (( symbol instanceof IParameterizedSymbol ) ? symbol : null); return (IParameterizedSymbol) (( symbol instanceof IParameterizedSymbol ) ? symbol : null);
} }
return null;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupNestedNameSpecifier(java.lang.String) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupNestedNameSpecifier(java.lang.String)
*/ */
@ -679,7 +684,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
LookupData data = new LookupData( name, TypeInfo.t_function ); LookupData data = new LookupData( name, TypeInfo.t_function );
//if parameters == null, thats no parameters, but we need to distinguish that from //if parameters == null, thats no parameters, but we need to distinguish that from
//no parameter information at all, so make an empty list. //no parameter information at all, so make an empty list.
data.parameters = ( parameters == null ) ? new LinkedList() : parameters; data.parameters = ( parameters == null ) ? ParserSymbolTable.EMPTY_LIST : parameters;
data.associated = associated; data.associated = associated;
ParserSymbolTable.lookup( data, this ); ParserSymbolTable.lookup( data, this );
@ -737,7 +742,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
LookupData data = new LookupData( name, TypeInfo.t_function ); LookupData data = new LookupData( name, TypeInfo.t_function );
//if parameters == null, thats no parameters, but we need to distinguish that from //if parameters == null, thats no parameters, but we need to distinguish that from
//no parameter information at all, so make an empty list. //no parameter information at all, so make an empty list.
data.parameters = ( parameters == null ) ? new LinkedList() : parameters; data.parameters = ( parameters == null ) ? ParserSymbolTable.EMPTY_LIST : parameters;
ParserSymbolTable.lookup( data, this ); ParserSymbolTable.lookup( data, this );
return (IParameterizedSymbol) ParserSymbolTable.resolveAmbiguities( data ); return (IParameterizedSymbol) ParserSymbolTable.resolveAmbiguities( data );
@ -751,7 +756,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
data.qualified = true; data.qualified = true;
//if parameters == null, thats no parameters, but we need to distinguish that from //if parameters == null, thats no parameters, but we need to distinguish that from
//no parameter information at all, so make an empty list. //no parameter information at all, so make an empty list.
data.parameters = ( parameters == null ) ? new LinkedList() : parameters; data.parameters = ( parameters == null ) ? ParserSymbolTable.EMPTY_LIST : parameters;
ParserSymbolTable.lookup( data, this ); ParserSymbolTable.lookup( data, this );
@ -924,10 +929,13 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
return container; return container;
} }
protected List getContents(){ protected void addToContents( IExtensibleSymbol symbol ){
if(_contents == null ){ if( _contents == ParserSymbolTable.EMPTY_LIST )
_contents = new LinkedList(); _contents = new LinkedList();
_contents.add( symbol );
} }
protected List getContents(){
return _contents; return _contents;
} }
@ -1096,9 +1104,9 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
} }
} }
private LinkedList _contents; //ordered list of all contents of this symbol private LinkedList _contents = ParserSymbolTable.EMPTY_LIST; //ordered list of all contents of this symbol
private LinkedList _usingDirectives; //collection of nominated namespaces private LinkedList _usingDirectives = ParserSymbolTable.EMPTY_LIST; //collection of nominated namespaces
private Map _containedSymbols; //declarations contained by us. private Map _containedSymbols = ParserSymbolTable.EMPTY_MAP; //declarations contained by us.
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addTemplateId(org.eclipse.cdt.internal.core.parser.pst.ISymbol, java.util.List) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addTemplateId(org.eclipse.cdt.internal.core.parser.pst.ISymbol, java.util.List)
*/ */

View file

@ -48,8 +48,9 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
public Object clone(){ public Object clone(){
DerivableContainerSymbol copy = (DerivableContainerSymbol)super.clone(); DerivableContainerSymbol copy = (DerivableContainerSymbol)super.clone();
copy._parentScopes = ( _parentScopes != null ) ? (LinkedList) _parentScopes.clone() : null; copy._parentScopes = ( _parentScopes != ParserSymbolTable.EMPTY_LIST ) ? (LinkedList) _parentScopes.clone() : _parentScopes;
copy._constructors = ( _constructors != null ) ? (LinkedList) _constructors.clone() : null; copy._constructors = ( _constructors != ParserSymbolTable.EMPTY_LIST ) ? (LinkedList) _constructors.clone() : _constructors;
copy._friends = ( _friends != ParserSymbolTable.EMPTY_LIST ) ? (LinkedList) _friends.clone() : _friends;
return copy; return copy;
} }
@ -64,22 +65,20 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
Iterator parents = getParents().iterator(); Iterator parents = getParents().iterator();
newSymbol.getParents().clear(); newSymbol.getParents().clear();
ParentWrapper wrapper = null, newWrapper = null; ParentWrapper wrapper = null;
while( parents.hasNext() ){ while( parents.hasNext() ){
wrapper = (ParentWrapper) parents.next(); wrapper = (ParentWrapper) parents.next();
ISymbol parent = wrapper.getParent(); ISymbol parent = wrapper.getParent();
if( parent == null ) if( parent == null )
continue; continue;
newWrapper = new ParentWrapper( wrapper.getParent(), wrapper.isVirtual(), wrapper.getAccess(), wrapper.getOffset(), wrapper.getReferences() );
if( parent instanceof IDeferredTemplateInstance ){ if( parent instanceof IDeferredTemplateInstance ){
template.registerDeferredInstatiation( newSymbol, newWrapper, ITemplateSymbol.DeferredKind.PARENT, argMap ); template.registerDeferredInstatiation( newSymbol, parent, ITemplateSymbol.DeferredKind.PARENT, argMap );
} else if( parent.isType( TypeInfo.t_templateParameter ) && argMap.containsKey( parent ) ){ } else if( parent.isType( TypeInfo.t_templateParameter ) && argMap.containsKey( parent ) ){
TypeInfo info = (TypeInfo) argMap.get( parent ); TypeInfo info = (TypeInfo) argMap.get( parent );
newWrapper.setParent( info.getTypeSymbol() ); parent = info.getTypeSymbol();
} }
newSymbol.addParent( parent, wrapper.isVirtual(), wrapper.getAccess(), wrapper.getOffset(), wrapper.getReferences() );
newSymbol.getParents().add( newWrapper );
} }
//TODO: friends //TODO: friends
@ -87,20 +86,20 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
return newSymbol; return newSymbol;
} }
public void instantiateDeferredParent( ParentWrapper wrapper, ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{ public void instantiateDeferredParent( ISymbol parent, ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
Iterator parents = getParents().iterator(); Iterator parents = getParents().iterator();
ParentWrapper w = null; ParentWrapper w = null;
while( parents.hasNext() ) { while( parents.hasNext() ) {
w = (ParentWrapper) parents.next(); w = (ParentWrapper) parents.next();
if( w == wrapper ){ if( w.getParent() == parent ){
wrapper.setParent( wrapper.getParent().instantiate( template, argMap ) ); w.setParent( parent.instantiate( template, argMap ) );
} }
} }
} }
protected void collectInstantiatedConstructor( IParameterizedSymbol constructor ){ protected void collectInstantiatedConstructor( IParameterizedSymbol constructor ){
if( constructor.isType( TypeInfo.t_constructor ) ) if( constructor.isType( TypeInfo.t_constructor ) )
getConstructors().add( constructor ); addToConstructors( constructor );
} }
public void addSymbol(ISymbol symbol) throws ParserSymbolTableException { public void addSymbol(ISymbol symbol) throws ParserSymbolTableException {
@ -123,7 +122,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
* @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) * @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 ){ public void addParent( ISymbol parent, boolean virtual, ASTAccessVisibility visibility, int offset, List references ){
if( _parentScopes == null ){ if( _parentScopes == ParserSymbolTable.EMPTY_LIST ){
_parentScopes = new LinkedList(); _parentScopes = new LinkedList();
} }
@ -138,9 +137,6 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#getParents() * @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#getParents()
*/ */
public List getParents(){ public List getParents(){
if( _parentScopes == null ){
_parentScopes = new LinkedList();
}
return _parentScopes; return _parentScopes;
} }
@ -148,7 +144,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#hasParents() * @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#hasParents()
*/ */
public boolean hasParents(){ public boolean hasParents(){
return ( _parentScopes != null && !_parentScopes.isEmpty() ); return !_parentScopes.isEmpty();
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -161,7 +157,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
List constructors = getConstructors(); List constructors = getConstructors();
if( constructors.size() == 0 || ParserSymbolTable.isValidOverload( constructors, constructor ) ){ if( constructors.size() == 0 || ParserSymbolTable.isValidOverload( constructors, constructor ) ){
constructors.add( constructor ); addToConstructors( constructor );
} else { } else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidOverload ); throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidOverload );
} }
@ -171,7 +167,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
addThis( constructor ); addThis( constructor );
getContents().add( constructor ); addToContents( constructor );
Command command = new AddConstructorCommand( constructor, this ); Command command = new AddConstructorCommand( constructor, this );
getSymbolTable().pushCommand( command ); getSymbolTable().pushCommand( command );
@ -214,23 +210,27 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
LookupData data = new LookupData( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_constructor ); LookupData data = new LookupData( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_constructor );
data.parameters = parameters; data.parameters = parameters;
List constructors = new LinkedList(); List constructors = null;
if( !getConstructors().isEmpty() ) if( !getConstructors().isEmpty() ){
constructors.addAll( getConstructors() ); constructors = new LinkedList( getConstructors() );
}
if( constructors != null )
return ParserSymbolTable.resolveFunction( data, constructors ); return ParserSymbolTable.resolveFunction( data, constructors );
return null;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#getConstructors() * @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#getConstructors()
*/ */
public List getConstructors(){ public List getConstructors(){
if( _constructors == null ){
_constructors = new LinkedList();
}
return _constructors; return _constructors;
} }
private void addToConstructors( IParameterizedSymbol constructor ){
if( _constructors == ParserSymbolTable.EMPTY_LIST )
_constructors = new LinkedList();
_constructors.add( constructor );
}
/** /**
* *
* @param obj * @param obj
@ -259,7 +259,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
LookupData data = new LookupData( ParserSymbolTable.THIS, TypeInfo.t_any ); LookupData data = new LookupData( ParserSymbolTable.THIS, TypeInfo.t_any );
try { try {
Map map = ParserSymbolTable.lookupInContained( data, obj ); Map map = ParserSymbolTable.lookupInContained( data, obj );
foundThis = map.containsKey( data.name ); foundThis = ( map != null ) ? map.containsKey( data.name ) : false;
} catch (ParserSymbolTableException e) { } catch (ParserSymbolTableException e) {
return false; return false;
} }
@ -323,7 +323,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
} }
} }
getFriends().add( friend ); addToFriends( friend );
} }
/** /**
@ -375,10 +375,13 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
public List getFriends(){ public List getFriends(){
if( _friends == null ){ return _friends;
}
private void addToFriends( ISymbol friend ){
if( _friends == ParserSymbolTable.EMPTY_LIST ){
_friends = new LinkedList(); _friends = new LinkedList();
} }
return _friends; _friends.add( friend );
} }
static private class AddParentCommand extends Command{ static private class AddParentCommand extends Command{
@ -467,7 +470,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
private final List references; private final List references;
} }
private LinkedList _constructors; //constructor list private LinkedList _constructors = ParserSymbolTable.EMPTY_LIST; //constructor list
private LinkedList _parentScopes; //inherited scopes (is base classes) private LinkedList _parentScopes = ParserSymbolTable.EMPTY_LIST; //inherited scopes (is base classes)
private LinkedList _friends; private LinkedList _friends = ParserSymbolTable.EMPTY_LIST;
} }

View file

@ -48,12 +48,12 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
public Object clone(){ public Object clone(){
ParameterizedSymbol copy = (ParameterizedSymbol)super.clone(); ParameterizedSymbol copy = (ParameterizedSymbol)super.clone();
copy._parameterList = ( _parameterList != null ) ? (LinkedList) _parameterList.clone() : null; copy._parameterList = ( _parameterList != ParserSymbolTable.EMPTY_LIST ) ? (LinkedList) _parameterList.clone() : _parameterList;
if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE ) if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE )
copy._parameterMap = ( _parameterMap != null ) ? (Map) ((TreeMap) _parameterMap).clone() : null; copy._parameterMap = ( _parameterMap != ParserSymbolTable.EMPTY_MAP ) ? (Map) ((TreeMap) _parameterMap).clone() : _parameterMap;
else else
copy._parameterMap = ( _parameterMap != null ) ? (Map) ((HashMap) _parameterMap).clone() : null; copy._parameterMap = ( _parameterMap != ParserSymbolTable.EMPTY_MAP ) ? (Map) ((HashMap) _parameterMap).clone() : _parameterMap;
return copy; return copy;
} }
@ -93,10 +93,7 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
param = (ISymbol) iter.next(); param = (ISymbol) iter.next();
newParam = param.instantiate( template, argMap ); newParam = param.instantiate( template, argMap );
newParameterized.getParameterList().add( newParam ); newParameterized.addParameter( newParam );
if( !newParam.getName().equals( ParserSymbolTable.EMPTY_NAME ) ){
newParameterized.getParameterMap().put( newParam.getName(), newParam );
}
} }
} }
@ -111,17 +108,23 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol) * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/ */
public void addParameter( ISymbol param ){ public void addParameter( ISymbol param ){
List paramList = getParameterList(); if( _parameterList == ParserSymbolTable.EMPTY_LIST )
_parameterList = new LinkedList();
paramList.add( param ); _parameterList.add( param );
String name = param.getName(); String name = param.getName();
if( name != null && !name.equals(ParserSymbolTable.EMPTY_NAME) ) if( name != null && !name.equals(ParserSymbolTable.EMPTY_NAME) )
{ {
Map paramMap = getParameterMap(); if( _parameterMap == ParserSymbolTable.EMPTY_MAP ){
if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE )
_parameterMap = new TreeMap( new SymbolTableComparator() );
else
_parameterMap = new HashMap( );
}
if( !paramMap.containsKey( name ) ) if( !_parameterMap.containsKey( name ) )
paramMap.put( name, param ); _parameterMap.put( name, param );
} }
param.setContainingSymbol( this ); param.setContainingSymbol( this );
@ -166,12 +169,6 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterMap() * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterMap()
*/ */
public Map getParameterMap(){ public Map getParameterMap(){
if( _parameterMap == null ){
if( getSymbolTable().getParserMode() == ParserMode.COMPLETION_PARSE )
_parameterMap = new TreeMap( new SymbolTableComparator() );
else
_parameterMap = new HashMap( );
}
return _parameterMap; return _parameterMap;
} }
@ -179,9 +176,6 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterList() * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterList()
*/ */
public List getParameterList(){ public List getParameterList(){
if( _parameterList == null ){
_parameterList = new LinkedList();
}
return _parameterList; return _parameterList;
} }
@ -314,8 +308,8 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
} }
private LinkedList _parameterList; //have my cake private LinkedList _parameterList = ParserSymbolTable.EMPTY_LIST; //have my cake
private Map _parameterMap; //and eat it too private Map _parameterMap = ParserSymbolTable.EMPTY_MAP; //and eat it too
private ISymbol _returnType; private ISymbol _returnType;
private boolean _hasVarArgs = false; //whether or not this function has variable arguments private boolean _hasVarArgs = false; //whether or not this function has variable arguments
} }

View file

@ -41,6 +41,8 @@ public class ParserSymbolTable {
public static final int TYPE_LOOP_THRESHOLD = 50; public static final int TYPE_LOOP_THRESHOLD = 50;
public static final String EMPTY_NAME = ""; //$NON-NLS-1$ public static final String EMPTY_NAME = ""; //$NON-NLS-1$
public static final LinkedList EMPTY_LIST = new LinkedList();
public static final Map EMPTY_MAP = new HashMap();
public static final String THIS = "this"; //$NON-NLS-1$ public static final String THIS = "this"; //$NON-NLS-1$
/** /**
@ -122,7 +124,7 @@ public class ParserSymbolTable {
} }
} }
LinkedList transitives = new LinkedList(); //list of transitive using directives LinkedList transitives = null; //list of transitive using directives
//if this name define in this scope? //if this name define in this scope?
Map map = null; Map map = null;
@ -144,7 +146,7 @@ public class ParserSymbolTable {
data.visited.clear(); //each namesapce is searched at most once, so keep track data.visited.clear(); //each namesapce is searched at most once, so keep track
lookupInNominated( data, inSymbol, transitives ); transitives = lookupInNominated( data, inSymbol, transitives );
//if we are doing a qualified lookup, only process using directives if //if we are doing a qualified lookup, only process using directives if
//we haven't found the name yet (and if we aren't ignoring them). //we haven't found the name yet (and if we aren't ignoring them).
@ -156,9 +158,10 @@ public class ParserSymbolTable {
} }
while( data.usingDirectives != null && data.usingDirectives.get( inSymbol ) != null ){ while( data.usingDirectives != null && data.usingDirectives.get( inSymbol ) != null ){
if( transitives != null )
transitives.clear(); transitives.clear();
lookupInNominated( data, inSymbol, transitives ); transitives = lookupInNominated( data, inSymbol, transitives );
if( !data.qualified || data.foundItems == null ){ if( !data.qualified || data.foundItems == null ){
processDirectives( inSymbol, data, transitives ); processDirectives( inSymbol, data, transitives );
@ -167,7 +170,7 @@ public class ParserSymbolTable {
} }
} }
if( data.mode == LookupMode.NORMAL && ( !data.foundItems.isEmpty() || data.stopAt == inSymbol ) ){ if( data.mode == LookupMode.NORMAL && ( ( data.foundItems != null && !data.foundItems.isEmpty()) || data.stopAt == inSymbol ) ){
return; return;
} }
@ -221,10 +224,10 @@ public class ParserSymbolTable {
* directives, the effect is as if the using-directives from the second * directives, the effect is as if the using-directives from the second
* namespace also appeared in the first. * namespace also appeared in the first.
*/ */
static private void lookupInNominated( LookupData data, IContainerSymbol symbol, LinkedList transitiveDirectives ) throws ParserSymbolTableException{ static private LinkedList lookupInNominated( LookupData data, IContainerSymbol symbol, LinkedList transitiveDirectives ) throws ParserSymbolTableException{
//if the data.usingDirectives is empty, there is nothing to do. //if the data.usingDirectives is empty, there is nothing to do.
if( data.usingDirectives == null ){ if( data.usingDirectives == null ){
return; return transitiveDirectives;
} }
//local variables //local variables
@ -238,7 +241,7 @@ public class ParserSymbolTable {
directives = (LinkedList) data.usingDirectives.remove( symbol ); directives = (LinkedList) data.usingDirectives.remove( symbol );
if( directives == null ){ if( directives == null ){
return; return transitiveDirectives;
} }
iter = directives.iterator(); iter = directives.iterator();
@ -251,19 +254,26 @@ public class ParserSymbolTable {
data.visited.add( temp ); data.visited.add( temp );
Map map = lookupInContained( data, temp ); Map map = lookupInContained( data, temp );
foundSomething = !map.isEmpty(); foundSomething = ( map != null && !map.isEmpty() );
if( foundSomething ){
if( data.foundItems == null )
data.foundItems = map;
else
mergeResults( data, data.foundItems, map ); mergeResults( data, data.foundItems, map );
}
//only consider the transitive using directives if we are an unqualified //only consider the transitive using directives if we are an unqualified
//lookup, or we didn't find the name in decl //lookup, or we didn't find the name in decl
if( (!data.qualified || !foundSomething || data.mode == LookupMode.PREFIX ) && temp.hasUsingDirectives() ){ if( (!data.qualified || !foundSomething || data.mode == LookupMode.PREFIX ) && temp.hasUsingDirectives() ){
//name wasn't found, add transitive using directives for later consideration //name wasn't found, add transitive using directives for later consideration
if( transitiveDirectives == null )
transitiveDirectives = new LinkedList();
transitiveDirectives.addAll( temp.getUsingDirectives() ); transitiveDirectives.addAll( temp.getUsingDirectives() );
} }
} }
} }
return; return transitiveDirectives;
} }
/** /**
@ -306,7 +316,7 @@ public class ParserSymbolTable {
* Look for data.name in our collection _containedDeclarations * Look for data.name in our collection _containedDeclarations
*/ */
protected static Map lookupInContained( LookupData data, IContainerSymbol lookIn ) throws ParserSymbolTableException{ protected static Map lookupInContained( LookupData data, IContainerSymbol lookIn ) throws ParserSymbolTableException{
Map found = new LinkedHashMap(); Map found = null;
Object obj = null; Object obj = null;
@ -318,7 +328,7 @@ public class ParserSymbolTable {
Map declarations = lookIn.getContainedSymbols(); Map declarations = lookIn.getContainedSymbols();
Iterator iterator = null; Iterator iterator = null;
if( data.mode == LookupMode.PREFIX ){ if( data.mode == LookupMode.PREFIX && declarations != ParserSymbolTable.EMPTY_MAP ){
if( declarations instanceof SortedMap ){ if( declarations instanceof SortedMap ){
iterator = ((SortedMap)declarations).tailMap( data.name.toLowerCase() ).keySet().iterator(); iterator = ((SortedMap)declarations).tailMap( data.name.toLowerCase() ).keySet().iterator();
} else { } else {
@ -330,13 +340,16 @@ public class ParserSymbolTable {
while( name != null ) { while( name != null ) {
if( nameMatches( data, name ) ){ if( nameMatches( data, name ) ){
obj = ( declarations != null ) ? declarations.get( name ) : null; obj = ( !declarations.isEmpty() ) ? declarations.get( name ) : null;
if( obj != null ){ if( obj != null ){
obj = collectSymbol( data, obj ); obj = collectSymbol( data, obj );
if( obj != null ) if( obj != null ){
if( found == null )
found = new LinkedHashMap();
found.put( name, obj ); found.put( name, obj );
} }
}
} else { } else {
break; break;
} }
@ -348,12 +361,12 @@ public class ParserSymbolTable {
} }
} }
if( !found.isEmpty() && data.mode == LookupMode.NORMAL ){ if( found != null && data.mode == LookupMode.NORMAL ){
return found; return found;
} }
if( lookIn instanceof IParameterizedSymbol ){ if( lookIn instanceof IParameterizedSymbol ){
lookupInParameters(data, lookIn, found); found = lookupInParameters(data, lookIn, found);
} }
if( lookIn.isTemplateMember() && data.templateMember == null ){ if( lookIn.isTemplateMember() && data.templateMember == null ){
@ -375,12 +388,12 @@ public class ParserSymbolTable {
* @param found * @param found
* @throws ParserSymbolTableException * @throws ParserSymbolTableException
*/ */
private static void lookupInParameters(LookupData data, IContainerSymbol lookIn, Map found) throws ParserSymbolTableException { private static Map lookupInParameters(LookupData data, IContainerSymbol lookIn, Map found) throws ParserSymbolTableException {
Object obj; Object obj;
Iterator iterator; Iterator iterator;
String name; String name;
if( lookIn instanceof ITemplateSymbol && ((ITemplateSymbol)lookIn).getDefinitionParameterMap() != null ){ if( lookIn instanceof ITemplateSymbol && !((ITemplateSymbol)lookIn).getDefinitionParameterMap().isEmpty() ){
ITemplateSymbol template = (ITemplateSymbol) lookIn; ITemplateSymbol template = (ITemplateSymbol) lookIn;
if( data.templateMember != null && template.getDefinitionParameterMap().containsKey( data.templateMember ) ){ if( data.templateMember != null && template.getDefinitionParameterMap().containsKey( data.templateMember ) ){
Map map = (Map) template.getDefinitionParameterMap().get( data.templateMember ); Map map = (Map) template.getDefinitionParameterMap().get( data.templateMember );
@ -390,16 +403,18 @@ public class ParserSymbolTable {
if( nameMatches( data, symbol.getName() ) ){ if( nameMatches( data, symbol.getName() ) ){
obj = collectSymbol( data, symbol ); obj = collectSymbol( data, symbol );
if( obj != null ){ if( obj != null ){
if( found == null )
found = new LinkedHashMap();
found.put( symbol.getName(), obj ); found.put( symbol.getName(), obj );
} }
} }
} }
return; return found;
} }
} }
Map parameters = ((IParameterizedSymbol)lookIn).getParameterMap(); Map parameters = ((IParameterizedSymbol)lookIn).getParameterMap();
if( parameters != null ){ if( parameters != ParserSymbolTable.EMPTY_MAP ){
iterator = null; iterator = null;
if( data.mode == LookupMode.PREFIX ){ if( data.mode == LookupMode.PREFIX ){
if( parameters instanceof SortedMap ){ if( parameters instanceof SortedMap ){
@ -415,6 +430,8 @@ public class ParserSymbolTable {
obj = parameters.get( name ); obj = parameters.get( name );
obj = collectSymbol( data, obj ); obj = collectSymbol( data, obj );
if( obj != null ){ if( obj != null ){
if( found == null )
found = new LinkedHashMap();
found.put( name, obj ); found.put( name, obj );
} }
} else { } else {
@ -428,6 +445,7 @@ public class ParserSymbolTable {
} }
} }
} }
return found;
} }
private static boolean nameMatches( LookupData data, String name ){ private static boolean nameMatches( LookupData data, String name ){
@ -570,6 +588,7 @@ public class ParserSymbolTable {
if( numTemplateFunctions > 0 ){ if( numTemplateFunctions > 0 ){
if( data.parameters != null && ( !data.exactFunctionsOnly || data.templateParameters != null ) ){ if( data.parameters != null && ( !data.exactFunctionsOnly || data.templateParameters != null ) ){
List fns = TemplateEngine.selectTemplateFunctions( templateFunctionSet, data.parameters, data.templateParameters ); List fns = TemplateEngine.selectTemplateFunctions( templateFunctionSet, data.parameters, data.templateParameters );
if( fns != null )
functionSet.addAll( fns ); functionSet.addAll( fns );
numFunctions = functionSet.size(); numFunctions = functionSet.size();
} else { } else {
@ -666,8 +685,11 @@ public class ParserSymbolTable {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo ); throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
} }
if( temp.isEmpty() || data.mode == LookupMode.PREFIX ){ if( (temp == null || temp.isEmpty()) || data.mode == LookupMode.PREFIX ){
inherited = lookupInParents( data, parent ); inherited = lookupInParents( data, parent );
if( temp == null )
temp = inherited;
else
mergeInheritedResults( temp, inherited ); mergeInheritedResults( temp, inherited );
} }
} else { } else {
@ -924,13 +946,16 @@ public class ParserSymbolTable {
Object object = data.foundItems.get( data.name ); Object object = data.foundItems.get( data.name );
LinkedList functionList = new LinkedList(); LinkedList functionList = null;
if( object instanceof List ){ if( object instanceof List ){
//if we got this far with a list, they must all be functions
functionList = new LinkedList();
functionList.addAll( (List) object ); functionList.addAll( (List) object );
} else { } else {
ISymbol symbol = (ISymbol) object; ISymbol symbol = (ISymbol) object;
if( symbol.isType( TypeInfo.t_function ) ){ if( symbol.isType( TypeInfo.t_function ) ){
functionList = new LinkedList();
functionList.add( symbol ); functionList.add( symbol );
} else { } else {
if( symbol.isTemplateMember() && !symbol.isTemplateInstance() && if( symbol.isTemplateMember() && !symbol.isTemplateInstance() &&
@ -1268,6 +1293,9 @@ public class ParserSymbolTable {
IContainerSymbol enclosing = null; IContainerSymbol enclosing = null;
IContainerSymbol temp = null; IContainerSymbol temp = null;
if( directives == null )
return;
int size = directives.size(); int size = directives.size();
Iterator iter = directives.iterator(); Iterator iter = directives.iterator();
@ -1859,12 +1887,11 @@ public class ParserSymbolTable {
if( !name.equals(EMPTY_NAME) ){ if( !name.equals(EMPTY_NAME) ){
LookupData data = new LookupData( "operator " + name, TypeInfo.t_function ); //$NON-NLS-1$ LookupData data = new LookupData( "operator " + name, TypeInfo.t_function ); //$NON-NLS-1$
LinkedList params = new LinkedList(); data.parameters = ParserSymbolTable.EMPTY_LIST;
data.parameters = params;
data.forUserDefinedConversion = true; data.forUserDefinedConversion = true;
data.foundItems = lookupInContained( data, (IContainerSymbol) sourceDecl ); data.foundItems = lookupInContained( data, (IContainerSymbol) sourceDecl );
conversion = (IParameterizedSymbol)resolveAmbiguities( data ); conversion = (data.foundItems != null ) ? (IParameterizedSymbol)resolveAmbiguities( data ) : null;
} }
} }
} }

View file

@ -37,7 +37,7 @@ public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSym
public Object clone(){ public Object clone(){
SpecializedSymbol copy = (SpecializedSymbol)super.clone(); SpecializedSymbol copy = (SpecializedSymbol)super.clone();
copy._argumentList = ( _argumentList != null ) ? (LinkedList) _argumentList.clone() : null; copy._argumentList = ( _argumentList != ParserSymbolTable.EMPTY_LIST ) ? (LinkedList) _argumentList.clone() : _argumentList;
return copy; return copy;
} }
@ -123,9 +123,6 @@ public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSym
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getArgumentList() * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getArgumentList()
*/ */
public List getArgumentList(){ public List getArgumentList(){
if( _argumentList == null ){
_argumentList = new LinkedList();
}
return _argumentList; return _argumentList;
} }
@ -133,8 +130,10 @@ public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSym
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addArgument(org.eclipse.cdt.internal.core.parser.pst.ISymbol) * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addArgument(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/ */
public void addArgument(TypeInfo arg) { public void addArgument(TypeInfo arg) {
List argumentList = getArgumentList(); if( _argumentList == ParserSymbolTable.EMPTY_LIST )
argumentList.add( arg ); _argumentList = new LinkedList();
_argumentList.add( arg );
//arg.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template ); //arg.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
@ -155,6 +154,6 @@ public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSym
private TypeInfo _arg; private TypeInfo _arg;
} }
private LinkedList _argumentList; //template specialization arguments private LinkedList _argumentList = ParserSymbolTable.EMPTY_LIST; //template specialization arguments
private ITemplateSymbol _primaryTemplate; //our primary template private ITemplateSymbol _primaryTemplate; //our primary template
} }

View file

@ -664,7 +664,7 @@ public final class TemplateEngine {
* after substitution of the deduced values, compatible with A. * after substitution of the deduced values, compatible with A.
*/ */
static private Map deduceTemplateArguments( ITemplateSymbol template, List arguments ){ static private Map deduceTemplateArguments( ITemplateSymbol template, List arguments ){
if( template.getContainedSymbols() == null || template.getContainedSymbols().size() != 1 ){ if( template.getContainedSymbols() == ParserSymbolTable.EMPTY_MAP || template.getContainedSymbols().size() != 1 ){
return null; return null;
} }
@ -846,9 +846,8 @@ public final class TemplateEngine {
//we shouldn't get this because there aren't any other symbols in the template //we shouldn't get this because there aren't any other symbols in the template
} }
ISymbol param = specialization.getSymbolTable().newSymbol( "", TypeInfo.t_type ); //$NON-NLS-1$ ISymbol param = specialization.getSymbolTable().newSymbol( "", TypeInfo.t_type ); //$NON-NLS-1$
LinkedList args = new LinkedList( specialization.getArgumentList() );
param.setTypeSymbol( specialization.instantiate( args ) ); param.setTypeSymbol( specialization.instantiate( specialization.getArgumentList() ) );
function.addParameter( param ); function.addParameter( param );
@ -884,7 +883,7 @@ public final class TemplateEngine {
if( templates == null || templates.size() == 0 ) if( templates == null || templates.size() == 0 )
return null; return null;
List instances = new LinkedList(); List instances = null;
Iterator iter = templates.iterator(); Iterator iter = templates.iterator();
@ -919,6 +918,8 @@ public final class TemplateEngine {
IContainerSymbol instance = (IContainerSymbol) template.instantiate( instanceArgs ); IContainerSymbol instance = (IContainerSymbol) template.instantiate( instanceArgs );
if( instance != null ){ if( instance != null ){
if( instances == null )
instances = new LinkedList();
instances.add( instance ); instances.add( instance );
} }
} }
@ -1059,7 +1060,7 @@ public final class TemplateEngine {
} }
static protected ISymbol translateParameterForDefinition ( ISymbol templatedSymbol, ISymbol param, Map defnMap ){ static protected ISymbol translateParameterForDefinition ( ISymbol templatedSymbol, ISymbol param, Map defnMap ){
if( defnMap == null ){ if( defnMap == ParserSymbolTable.EMPTY_MAP ){
return param; return param;
} }

View file

@ -296,7 +296,7 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
defnMap.put( param, origParam ); defnMap.put( param, origParam );
} }
origTemplate.getDefinitionParameterMap().put( newSymbol, defnMap ); ((TemplateSymbol)origTemplate).addToDefinitionParameterMap( newSymbol, defnMap );
} }
} }

View file

@ -16,7 +16,6 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.internal.core.parser.pst.DerivableContainerSymbol.ParentWrapper;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp; import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
/** /**
@ -38,11 +37,8 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
public Object clone(){ public Object clone(){
TemplateSymbol copy = (TemplateSymbol)super.clone(); TemplateSymbol copy = (TemplateSymbol)super.clone();
//copy._specializations = ( _specializations != null ) ? (LinkedList) _specializations.clone() : null; copy._defnParameterMap = ( _defnParameterMap != ParserSymbolTable.EMPTY_MAP ) ? (HashMap)((HashMap) _defnParameterMap).clone() : _defnParameterMap;
copy._instantiations = ( _instantiations != null ) ? (HashMap)((HashMap) _instantiations).clone() : _instantiations;
copy._defnParameterMap = ( _defnParameterMap != null ) ? (HashMap) _defnParameterMap.clone() : null;
copy._instantiations = ( _instantiations != null ) ? (HashMap) _instantiations.clone() : null;
return copy; return copy;
} }
@ -253,19 +249,20 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasSpecializations() * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasSpecializations()
*/ */
public boolean hasSpecializations(){ public boolean hasSpecializations(){
return ( _specializations != null && !_specializations.isEmpty() ); return !_specializations.isEmpty();
} }
public void addExplicitSpecialization( ISymbol symbol, List args ) throws ParserSymbolTableException{ public void addExplicitSpecialization( ISymbol symbol, List args ) throws ParserSymbolTableException{
List actualArgs = TemplateEngine.verifyExplicitArguments( this, args, symbol ); List actualArgs = TemplateEngine.verifyExplicitArguments( this, args, symbol );
Map map = getExplicitSpecializations(); if( _explicitSpecializations == ParserSymbolTable.EMPTY_MAP )
_explicitSpecializations = new HashMap();
Map specs = null; Map specs = null;
List key = null; List key = null;
Iterator iter = map.keySet().iterator(); Iterator iter = _explicitSpecializations.keySet().iterator();
while( iter.hasNext() ){ while( iter.hasNext() ){
List list = (List) iter.next(); List list = (List) iter.next();
if( list.equals( args ) ){ if( list.equals( args ) ){
@ -275,10 +272,10 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
} }
if( key != null ){ if( key != null ){
specs = (Map) map.get( key ); specs = (Map) _explicitSpecializations.get( key );
} else { } else {
specs = new HashMap(); specs = new HashMap();
map.put( new LinkedList( actualArgs ), specs ); _explicitSpecializations.put( new LinkedList( actualArgs ), specs );
} }
ISymbol found = null; ISymbol found = null;
@ -329,8 +326,10 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addSpecialization(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol) * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addSpecialization(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
*/ */
public void addSpecialization( ISpecializedSymbol spec ){ public void addSpecialization( ISpecializedSymbol spec ){
List specializationList = getSpecializations(); if( _specializations == ParserSymbolTable.EMPTY_LIST )
specializationList.add( spec ); _specializations = new LinkedList();
_specializations.add( spec );
spec.setContainingSymbol( getContainingSymbol() ); spec.setContainingSymbol( getContainingSymbol() );
spec.setPrimaryTemplate( this ); spec.setPrimaryTemplate( this );
@ -340,22 +339,19 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getSpecializations() * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getSpecializations()
*/ */
public List getSpecializations() { public List getSpecializations() {
if( _specializations == null ){
_specializations = new LinkedList();
}
return _specializations; return _specializations;
} }
public void addInstantiation( IContainerSymbol instance, List args ){ public void addInstantiation( IContainerSymbol instance, List args ){
List key = new LinkedList( args ); List key = new LinkedList( args );
if( _instantiations == null ){ if( _instantiations == ParserSymbolTable.EMPTY_MAP ){
_instantiations = new HashMap(); _instantiations = new HashMap();
} }
_instantiations.put( key, instance ); _instantiations.put( key, instance );
} }
public IContainerSymbol findInstantiation( List arguments ){ public IContainerSymbol findInstantiation( List arguments ){
if( _instantiations == null ){ if( _instantiations == ParserSymbolTable.EMPTY_MAP ){
return null; return null;
} }
@ -399,20 +395,20 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
} }
public Map getDefinitionParameterMap(){ public Map getDefinitionParameterMap(){
if( _defnParameterMap == null ){
_defnParameterMap = new HashMap();
}
return _defnParameterMap; return _defnParameterMap;
} }
protected void addToDefinitionParameterMap( ISymbol newSymbol, Map defnMap ){
if( _defnParameterMap == ParserSymbolTable.EMPTY_MAP )
_defnParameterMap = new HashMap();
_defnParameterMap.put( newSymbol, defnMap );
}
public IDeferredTemplateInstance deferredInstance( List args ){ public IDeferredTemplateInstance deferredInstance( List args ){
return new DeferredTemplateInstance( getSymbolTable(), this, args ); return new DeferredTemplateInstance( getSymbolTable(), this, args );
} }
public Map getExplicitSpecializations() { public Map getExplicitSpecializations() {
if( _explicitSpecializations == null ){
_explicitSpecializations = new HashMap();
}
return _explicitSpecializations; return _explicitSpecializations;
} }
@ -420,7 +416,7 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
* @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#registerDeferredInstatiation(org.eclipse.cdt.internal.core.parser.pst.ParameterizedSymbol, org.eclipse.cdt.internal.core.parser.pst.ISymbol, org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol.DeferredKind) * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#registerDeferredInstatiation(org.eclipse.cdt.internal.core.parser.pst.ParameterizedSymbol, org.eclipse.cdt.internal.core.parser.pst.ISymbol, org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol.DeferredKind)
*/ */
public void registerDeferredInstatiation( Object obj0, Object obj1, DeferredKind kind, Map argMap ) { public void registerDeferredInstatiation( Object obj0, Object obj1, DeferredKind kind, Map argMap ) {
if( _deferredInstantiations == null ) if( _deferredInstantiations == ParserSymbolTable.EMPTY_LIST )
_deferredInstantiations = new LinkedList(); _deferredInstantiations = new LinkedList();
_deferredInstantiations.add( new Object [] { obj0, obj1, kind, argMap } ); _deferredInstantiations.add( new Object [] { obj0, obj1, kind, argMap } );
@ -428,7 +424,7 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
protected void processDeferredInstantiations() throws ParserSymbolTableException{ protected void processDeferredInstantiations() throws ParserSymbolTableException{
if( _deferredInstantiations == null ) if( _deferredInstantiations == ParserSymbolTable.EMPTY_LIST )
return; return;
Iterator iter = _deferredInstantiations.iterator(); Iterator iter = _deferredInstantiations.iterator();
@ -439,7 +435,7 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
if( kind == DeferredKind.PARENT ){ if( kind == DeferredKind.PARENT ){
DerivableContainerSymbol d = (DerivableContainerSymbol) objs[0]; DerivableContainerSymbol d = (DerivableContainerSymbol) objs[0];
d.instantiateDeferredParent( (ParentWrapper) objs[ 1 ], this, (Map) objs[3] ); d.instantiateDeferredParent( (ISymbol) objs[ 1 ], this, (Map) objs[3] );
} else if( kind == DeferredKind.RETURN_TYPE ){ } else if( kind == DeferredKind.RETURN_TYPE ){
ParameterizedSymbol p = (ParameterizedSymbol) objs[0]; ParameterizedSymbol p = (ParameterizedSymbol) objs[0];
p.instantiateDeferredReturnType( (ISymbol) objs[1], this, (Map) objs[3] ); p.instantiateDeferredReturnType( (ISymbol) objs[1], this, (Map) objs[3] );
@ -449,11 +445,11 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
} }
} }
private LinkedList _specializations; //template specializations private LinkedList _specializations = ParserSymbolTable.EMPTY_LIST; //template specializations
private HashMap _explicitSpecializations; //explicit specializations private Map _explicitSpecializations = ParserSymbolTable.EMPTY_MAP; //explicit specializations
private HashMap _defnParameterMap; //members could be defined with different template parameter names private Map _defnParameterMap = ParserSymbolTable.EMPTY_MAP; //members could be defined with different template parameter names
private HashMap _instantiations; private Map _instantiations = ParserSymbolTable.EMPTY_MAP;
private LinkedList _deferredInstantiations; //used to avoid recursive loop private LinkedList _deferredInstantiations = ParserSymbolTable.EMPTY_LIST; //used to avoid recursive loop
} }