[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] Templates! (HEAD only)
|
This patch represents a couple of months work (off and on since the
summer) on Parser Symbol Table support for templates.
This is symbol table support only, not parser support (that still needs to
be done).
What does work:
- declarations, definitions & instantiations for class templates, function
templates, & template templates
- declarations, definitions & instantiations of class template partial
specializations
- template ordering & argument deduction (allows implicit template
function instatiation)
What doesn't (yet) work:
- Explicit specializations
- assorted smaller specific cases & bugs & things I havn't thought of yet
tested on windows & linux
-Andrew
Index: parser/ChangeLog-parser
===================================================================
retrieving revision 1.50
diff -u -r1.50 ChangeLog-parser
--- parser/ChangeLog-parser 10 Feb 2004 16:06:06 -0000 1.50
+++ parser/ChangeLog-parser 10 Feb 2004 19:17:54 -0000
@@ -1,3 +1,16 @@
+2004-02-10 Andrew Niefer
+ Templates in the symbol table (org.eclipse.cdt.internal.core.parser.pst)
+ ITemplateFactory.java
+ ITemplateSymbol.java
+ DeferredTemplateInstance.java
+ ParserSymbolTableError.java
+ TemplateEngine.java
+ TemplateFactory.java
+ TemplateSymbol.java
+ Most of the other main symbol table files (BasicSymbol, ContainerSymbol, etc) were modified
+
2004-02-10 John Camelon
Fixed Bug 51302 - Content Assist: No completion list available following namespace declaration.
Index: parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java
===================================================================
retrieving revision 1.2
diff -u -r1.2 BasicSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java 17 Dec 2003 20:51:39 -0000 1.2
+++ parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java 10 Feb 2004 19:17:57 -0000
@@ -1,8 +1,15 @@
+/**********************************************************************
+ * Copyright (c) 2003, 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
/*
* Created on Nov 4, 2003
- *
- * To change the template for this generated file go to
- * Window>Preferences>Java>Code Generation>Code and Comments
*/
package org.eclipse.cdt.internal.core.parser.pst;
@@ -54,6 +61,17 @@
return copy;
}
+ public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
+ if( !isTemplateMember() && !getContainingSymbol().isTemplateMember() ){
+ return null;
+ }
+ ISymbol newSymbol = (ISymbol) clone();
+ newSymbol.setTypeInfo( TemplateEngine.instantiateTypeInfo( newSymbol.getTypeInfo(), template, argMap ) );
+ newSymbol.setInstantiatedSymbol( this );
+
+ return newSymbol;
+ }
+
public String getName() { return _name; }
public void setName(String name) { _name = name; }
@@ -160,14 +178,14 @@
public void setIsTemplateMember( boolean isMember ){
_isTemplateMember = isMember;
}
- public ISymbol getTemplateInstance(){
- return _templateInstance;
+ public boolean isTemplateInstance(){
+ return ( _instantiatedSymbol != null );
}
- public void setTemplateInstance( TemplateInstance instance ){
- _templateInstance = instance;
+ public ISymbol getInstantiatedSymbol(){
+ return _instantiatedSymbol;
}
- public Map getArgumentMap(){
- return null;
+ public void setInstantiatedSymbol( ISymbol symbol ){
+ _instantiatedSymbol = symbol;
}
public boolean getIsInvisible(){
@@ -183,7 +201,8 @@
private IContainerSymbol _containingScope; //the scope that contains us
private int _depth; //how far down the scope stack we are
- private boolean _isInvisible = false; //used by friend declarations (11.4-9)
- private boolean _isTemplateMember = false;
- private TemplateInstance _templateInstance;
+ private boolean _isInvisible = false; //used by friend declarations (11.4-9)
+
+ private boolean _isTemplateMember = false;
+ private ISymbol _instantiatedSymbol = null;
}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java
===================================================================
retrieving revision 1.11
diff -u -r1.11 ContainerSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java 28 Jan 2004 19:23:43 -0000 1.11
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java 10 Feb 2004 19:17:58 -0000
@@ -60,10 +60,77 @@
copy._containedSymbols = ( _containedSymbols != null )? (Map)((TreeMap) _containedSymbols).clone() : null;
else
copy._containedSymbols = ( _containedSymbols != null )? (Map)((HashMap) _containedSymbols).clone() : null;
-
+
+ copy._contents = ( _contents != null )? (LinkedList) _contents.clone() : null;
+
return copy;
}
+ public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
+ if( !isTemplateMember() || template == null ){
+ return null;
+ }
+
+ ContainerSymbol newContainer = (ContainerSymbol) super.instantiate( template, argMap );
+
+ Iterator iter = getContentsIterator();
+
+ newContainer.getContainedSymbols().clear();
+ if( newContainer._contents != null ){
+ newContainer._contents.clear();
+
+ IExtensibleSymbol containedSymbol = null;
+ ISymbol newSymbol = null;
+
+ while( iter.hasNext() ){
+ containedSymbol = (IExtensibleSymbol) iter.next();
+
+ if( containedSymbol instanceof IUsingDirectiveSymbol ){
+ newContainer._contents.add( containedSymbol );
+ } else {
+ ISymbol symbol = (ISymbol) containedSymbol;
+ if( symbol.isForwardDeclaration() && symbol.getTypeSymbol() != null ){
+ continue;
+ }
+
+ Map instanceMap = argMap;
+ if( template.getDefinitionParameterMap() != null &&
+ template.getDefinitionParameterMap().containsKey( containedSymbol ) )
+ {
+ Map defMap = (Map) template.getDefinitionParameterMap().get( containedSymbol );
+ instanceMap = new HashMap();
+ Iterator i = defMap.keySet().iterator();
+ while( i.hasNext() ){
+ ISymbol p = (ISymbol) i.next();
+ instanceMap.put( p, argMap.get( defMap.get( p ) ) );
+ }
+ }
+
+ newSymbol = ((ISymbol)containedSymbol).instantiate( template, instanceMap );
+
+ newSymbol.setContainingSymbol( newContainer );
+ newContainer._contents.add( newSymbol );
+
+ if( newContainer.getContainedSymbols().containsKey( newSymbol.getName() ) ){
+ Object obj = newContainer.getContainedSymbols().get( newSymbol.getName() );
+ if( obj instanceof List ){
+ ((List) obj).add( obj );
+ } else {
+ List list = new LinkedList();
+ list.add( obj );
+ list.add( newSymbol );
+ newContainer.getContainedSymbols().put( newSymbol.getName(), list );
+ }
+ } else {
+ newContainer.getContainedSymbols().put( newSymbol.getName(), newSymbol );
+ }
+ }
+ }
+ }
+
+ return newContainer;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
@@ -83,13 +150,16 @@
}
}
- //Templates contain 1 declaration
- if( getType() == TypeInfo.t_template ){
- //declaration must be a class or a function
- if( ( obj.getType() != TypeInfo.t_class && obj.getType() != TypeInfo.t_function ) ||
- ( getContainedSymbols() != null && getContainedSymbols().size() == 1 ) )
- {
- //throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
+ if( obj.isType( TypeInfo.t_template ) ){
+ if( ! TemplateEngine.canAddTemplate( containing, (ITemplateSymbol) obj ) ) {
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
+ }
+ }
+
+ //14.6.1-4 A Template parameter shall not be redeclared within its scope.
+ if( isTemplateMember() || isType( TypeInfo.t_template ) ){
+ if( TemplateEngine.alreadyHasTemplateParameter( this, obj.getName() ) ){
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_RedeclaredTemplateParam );
}
}
@@ -114,7 +184,7 @@
} else if( origObj.getClass() == LinkedList.class ){
origList = (LinkedList)origObj;
} else {
- throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
+ throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
boolean validOverride = ((origList == null) ? ParserSymbolTable.isValidOverload( origDecl, obj ) : ParserSymbolTable.isValidOverload( origList, obj ) );
@@ -220,11 +290,10 @@
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDeclaration(java.lang.String, org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol)
*/
public ISymbol addUsingDeclaration( String name, IContainerSymbol declContext ) throws ParserSymbolTableException{
- LookupData data = new LookupData( name, TypeInfo.t_any, null );
+ LookupData data = new LookupData( name, TypeInfo.t_any );
if( declContext != null ){
data.qualified = true;
- data.templateInstance = declContext.getTemplateInstance();
ParserSymbolTable.lookup( data, declContext );
} else {
ParserSymbolTable.lookup( data, this );
@@ -291,22 +360,34 @@
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#elaboratedLookup(org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType, java.lang.String)
*/
public ISymbol elaboratedLookup( TypeInfo.eType type, String name ) throws ParserSymbolTableException{
- LookupData data = new LookupData( name, type, getTemplateInstance() );
+ LookupData data = new LookupData( name, type );
ParserSymbolTable.lookup( data, this );
- return ParserSymbolTable.resolveAmbiguities( data );
+ ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
+
+ if( isTemplateMember() && found instanceof ITemplateSymbol ) {
+ return TemplateEngine.instantiateWithinTemplateScope( this, (ITemplateSymbol) found );
+ }
+
+ return found;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookup(java.lang.String)
*/
public ISymbol lookup( String name ) throws ParserSymbolTableException {
- LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
+ LookupData data = new LookupData( name, TypeInfo.t_any );
ParserSymbolTable.lookup( data, this );
- return ParserSymbolTable.resolveAmbiguities( data );
+ ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
+
+ if( isTemplateMember() && found instanceof ITemplateSymbol ) {
+ return TemplateEngine.instantiateWithinTemplateScope( this, (ITemplateSymbol) found );
+ }
+
+ return found;
}
/* (non-Javadoc)
@@ -341,7 +422,7 @@
* for a definition.
*/
public ISymbol lookupMemberForDefinition( String name ) throws ParserSymbolTableException{
- LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
+ LookupData data = new LookupData( name, TypeInfo.t_any );
data.qualified = true;
IContainerSymbol container = this;
@@ -360,7 +441,7 @@
}
public IParameterizedSymbol lookupMethodForDefinition( String name, List parameters ) throws ParserSymbolTableException{
- LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
+ LookupData data = new LookupData( name, TypeInfo.t_any );
data.qualified = true;
data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
@@ -398,7 +479,7 @@
private IContainerSymbol lookupNestedNameSpecifier(String name, IContainerSymbol inSymbol ) throws ParserSymbolTableException{
ISymbol foundSymbol = null;
- LookupData data = new LookupData( name, TypeInfo.t_namespace, getTemplateInstance() );
+ LookupData data = new LookupData( name, TypeInfo.t_namespace );
data.filter.addAcceptedType( TypeInfo.t_class );
data.filter.addAcceptedType( TypeInfo.t_struct );
data.filter.addAcceptedType( TypeInfo.t_union );
@@ -406,7 +487,7 @@
data.foundItems = ParserSymbolTable.lookupInContained( data, inSymbol );
if( data.foundItems != null ){
- foundSymbol = ParserSymbolTable.resolveAmbiguities( data );//, data.foundItems );
+ foundSymbol = ParserSymbolTable.resolveAmbiguities( data );
}
if( foundSymbol == null && inSymbol.getContainingSymbol() != null ){
@@ -431,7 +512,7 @@
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedLookup(java.lang.String, org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType)
*/
public ISymbol qualifiedLookup( String name, TypeInfo.eType t ) throws ParserSymbolTableException{
- LookupData data = new LookupData( name, t, getTemplateInstance() );
+ LookupData data = new LookupData( name, t );
data.qualified = true;
ParserSymbolTable.lookup( data, this );
@@ -496,7 +577,7 @@
}
}
- LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
+ LookupData data = new LookupData( name, TypeInfo.t_function );
//if parameters == null, thats no parameters, but we need to distinguish that from
//no parameter information at all, so make an empty list.
data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
@@ -554,7 +635,7 @@
* include argument dependant scopes
*/
public IParameterizedSymbol memberFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{
- LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
+ LookupData data = new LookupData( name, TypeInfo.t_function );
//if parameters == null, thats no parameters, but we need to distinguish that from
//no parameter information at all, so make an empty list.
data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
@@ -567,7 +648,7 @@
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedFunctionLookup(java.lang.String, java.util.List)
*/
public IParameterizedSymbol qualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{
- LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
+ LookupData data = new LookupData( name, TypeInfo.t_function );
data.qualified = true;
//if parameters == null, thats no parameters, but we need to distinguish that from
//no parameter information at all, so make an empty list.
@@ -581,21 +662,42 @@
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#templateLookup(java.lang.String, java.util.List)
*/
- public TemplateInstance templateLookup( String name, List arguments ) throws ParserSymbolTableException
+ public ISymbol lookupTemplate( String name, List arguments ) throws ParserSymbolTableException
{
- LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
- data.parameters = arguments;
+ LookupData data = new LookupData( name, TypeInfo.t_any );
ParserSymbolTable.lookup( data, this );
ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
- if( found.isType( TypeInfo.t_template ) ){
- return ((IParameterizedSymbol) found).instantiate( arguments );
+
+ if( (found.isType( TypeInfo.t_templateParameter ) && found.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template) ||
+ found.isType( TypeInfo.t_template ) )
+ {
+ return ((ITemplateSymbol) found).instantiate( arguments );
+ } else if( found.getContainingSymbol().isType( TypeInfo.t_template ) ){
+ return ((ITemplateSymbol) found.getContainingSymbol()).instantiate( arguments );
}
+
+ return null;
+ }
+
+ public ITemplateFactory lookupTemplateForMemberDefinition( String name, List parameters, List arguments ) throws ParserSymbolTableException{
+ LookupData data = new LookupData( name, TypeInfo.t_any );
+
+ ParserSymbolTable.lookup( data, this );
+ ISymbol look = ParserSymbolTable.resolveAmbiguities( data );
+
+ if( look instanceof ITemplateSymbol ){
+ ITemplateSymbol template = TemplateEngine.selectTemplateOrSpecialization( (ITemplateSymbol) look, parameters, arguments );
+ if( template != null ){
+ return new TemplateFactory( template, parameters );
+ }
+ }
return null;
}
+
public List prefixLookup( TypeFilter filter, String prefix, boolean qualified ) throws ParserSymbolTableException{
- LookupData data = new LookupData( prefix, filter, getTemplateInstance() );
+ LookupData data = new LookupData( prefix, filter );
data.qualified = qualified;
data.mode = ParserSymbolTable.LookupMode.PREFIX;
@@ -640,11 +742,9 @@
if( node instanceof IASTMember ){
ASTAccessVisibility visibility;
- try {
- visibility = ParserSymbolTable.getVisibility( symbol, qualifyingSymbol );
- } catch (ParserSymbolTableException e) {
- return false;
- }
+
+ visibility = ParserSymbolTable.getVisibility( symbol, qualifyingSymbol );
+
if( visibility == ASTAccessVisibility.PUBLIC ){
return true;
}
@@ -704,61 +804,6 @@
return false;
}
- /* (non-Javadoc)
- * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#instantiate(java.util.List)
- */
- public TemplateInstance instantiate( List arguments ) throws ParserSymbolTableException{
- if( getType() != TypeInfo.t_template ){
- return null;
- }
-
- //TODO uncomment when template specialization matching & ordering is working
- //IParameterizedSymbol template = ParserSymbolTable.matchTemplatePartialSpecialization( this, arguments );
- IParameterizedSymbol template = null;
-
- if( template == null ){
- template = (IParameterizedSymbol) this;
- }
-
- List paramList = template.getParameterList();
- int numParams = ( paramList != null ) ? paramList.size() : 0;
-
- if( numParams == 0 ){
- return null;
- }
-
- HashMap map = new HashMap();
- Iterator paramIter = paramList.iterator();
- Iterator argIter = arguments.iterator();
-
- ISymbol param = null;
- TypeInfo arg = null;
- for( int i = 0; i < numParams; i++ ){
- param = (ISymbol) paramIter.next();
-
- if( argIter.hasNext() ){
- arg = (TypeInfo) argIter.next();
- map.put( param, arg );
- } else {
- Object obj = param.getTypeInfo().getDefault();
- if( obj != null && obj instanceof TypeInfo ){
- map.put( param, obj );
- } else {
- throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
- }
- }
- }
-
- if( template.getContainedSymbols().size() != 1 ){
- throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
- }
-
- Iterator iter = template.getContainedSymbols().keySet().iterator();
- IContainerSymbol symbol = (IContainerSymbol) template.getContainedSymbols().get( iter.next() );
-
- TemplateInstance instance = new TemplateInstance( getSymbolTable(), symbol, map );
- return instance;
- }
protected List getContents(){
if(_contents == null ){
Index: parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java
===================================================================
retrieving revision 1.5
diff -u -r1.5 DerivableContainerSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java 17 Jan 2004 00:18:24 -0000 1.5
+++ parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java 10 Feb 2004 19:17:58 -0000
@@ -54,6 +54,44 @@
return copy;
}
+ public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
+ if( !isTemplateMember() ){
+ return null;
+ }
+
+ DerivableContainerSymbol newSymbol = (DerivableContainerSymbol) super.instantiate( template, argMap );
+
+ Iterator parents = getParents().iterator();
+
+ newSymbol.getParents().clear();
+ ParentWrapper wrapper = null, newWrapper = null;
+ while( parents.hasNext() ){
+ wrapper = (ParentWrapper) parents.next();
+ newWrapper = new ParentWrapper( wrapper.getParent(), wrapper.isVirtual(), wrapper.getAccess(), wrapper.getOffset(), wrapper.getReferences() );
+ ISymbol parent = newWrapper.getParent();
+ if( parent instanceof IDeferredTemplateInstance ){
+ newWrapper.setParent( ((IDeferredTemplateInstance)parent).instantiate( template, argMap ) );
+ } else if( parent.isType( TypeInfo.t_templateParameter ) && argMap.containsKey( parent ) ){
+ TypeInfo info = (TypeInfo) argMap.get( parent );
+ newWrapper.setParent( info.getTypeSymbol() );
+ }
+
+ newSymbol.getParents().add( newWrapper );
+ }
+
+ Iterator constructors = getConstructors().iterator();
+ newSymbol.getConstructors().clear();
+ IParameterizedSymbol constructor = null;
+ while( constructors.hasNext() ){
+ constructor = (IParameterizedSymbol) constructors.next();
+ newSymbol.getConstructors().add( constructor.instantiate( template, argMap ) );
+ }
+
+ //TODO: friends
+
+ return newSymbol;
+ }
+
public void addSymbol(ISymbol symbol) throws ParserSymbolTableException {
super.addSymbol( symbol );
@@ -149,7 +187,7 @@
*/
public IParameterizedSymbol lookupConstructor( List parameters ) throws ParserSymbolTableException
{
- LookupData data = new LookupData( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_constructor, null );
+ LookupData data = new LookupData( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_constructor );
data.parameters = parameters;
List constructors = new LinkedList();
@@ -194,7 +232,7 @@
//of function will have them from the original declaration
boolean foundThis = false;
- LookupData data = new LookupData( ParserSymbolTable.THIS, TypeInfo.t_any, null );
+ LookupData data = new LookupData( ParserSymbolTable.THIS, TypeInfo.t_any );
try {
Map map = ParserSymbolTable.lookupInContained( data, obj );
foundThis = map.containsKey( data.name );
@@ -274,7 +312,7 @@
* class scope.
*/
public ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException{
- LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
+ LookupData data = new LookupData( name, TypeInfo.t_any );
IContainerSymbol enclosing = getContainingSymbol();
if( enclosing != null && enclosing.isType( TypeInfo.t_namespace, TypeInfo.t_union ) ){
@@ -290,7 +328,7 @@
}
public IParameterizedSymbol lookupFunctionForFriendship( String name, List parameters ) throws ParserSymbolTableException{
- LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
+ LookupData data = new LookupData( name, TypeInfo.t_any );
data.parameters = parameters;
@@ -373,6 +411,15 @@
this.references = r;
}
+ public Object clone(){
+ try{
+ return super.clone();
+ } catch ( CloneNotSupportedException e ){
+ //should not happen
+ return null;
+ }
+ }
+
public void setParent( ISymbol parent ){ this.parent = parent; }
public ISymbol getParent() { return parent; }
@@ -380,7 +427,6 @@
public void setVirtual( boolean virtual ){ isVirtual = virtual; }
- public ASTAccessVisibility getVisibility(){ return access; }
public ASTAccessVisibility getAccess() { return access; }
public int getOffset() { return offset; }
Index: parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java
===================================================================
retrieving revision 1.11
diff -u -r1.11 IContainerSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java 17 Jan 2004 00:18:24 -0000 1.11
+++ parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java 10 Feb 2004 19:17:58 -0000
@@ -10,9 +10,6 @@
******************************************************************************/
/*
* Created on May 9, 2003
- *
- * To change the template for this generated file go to
- * Window>Preferences>Java>Code Generation>Code and Comments
*/
package org.eclipse.cdt.internal.core.parser.pst;
@@ -52,8 +49,11 @@
public IParameterizedSymbol unqualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException;
public IParameterizedSymbol memberFunctionLookup( String name, List parameters ) throws ParserSymbolTableException;
public IParameterizedSymbol qualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException;
- public TemplateInstance templateLookup( String name, List arguments ) throws ParserSymbolTableException;
- public TemplateInstance instantiate( List arguments ) throws ParserSymbolTableException;
+
+ public ISymbol lookupTemplate( String name, List arguments ) throws ParserSymbolTableException;
+
+ public ITemplateFactory lookupTemplateForMemberDefinition( String name, List templateParameters,
+ List templateArguments ) throws ParserSymbolTableException;
public boolean isVisible( ISymbol symbol, IContainerSymbol qualifyingSymbol );
Index: parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java
===================================================================
retrieving revision 1.9
diff -u -r1.9 IDerivableContainerSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java 8 Jan 2004 16:57:48 -0000 1.9
+++ parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java 10 Feb 2004 19:17:58 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
+ * Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@@ -44,13 +44,13 @@
public List getFriends();
- public interface IParentSymbol{
+ public interface IParentSymbol extends Cloneable {
+ public Object clone();
public void setParent( ISymbol parent );
public ISymbol getParent();
public boolean isVirtual();
public void setVirtual( boolean virtual );
- public ASTAccessVisibility getVisibility();
public ASTAccessVisibility getAccess();
public int getOffset();
public List getReferences();
Index: parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java
===================================================================
retrieving revision 1.6
diff -u -r1.6 IParameterizedSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java 9 Jan 2004 16:59:25 -0000 1.6
+++ parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java 10 Feb 2004 19:17:58 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
+ * Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@@ -32,10 +32,6 @@
public void addParameter( TypeInfo.eType type, int info, TypeInfo.PtrOp ptrOp, boolean hasDefault );
public void addParameter( ISymbol typeSymbol, TypeInfo.PtrOp ptrOp, boolean hasDefault );
- public void addArgument( ISymbol arg );
- public List getArgumentList();
- //public void setArgumentList( List list );
-
public Map getParameterMap();
public List getParameterList();
//public void setParameterList( List list );
@@ -47,8 +43,4 @@
public void setHasVariableArgs( boolean var );
public boolean hasVariableArgs( );
-
- public boolean hasSpecializations();
- public void addSpecialization( IParameterizedSymbol spec );
- public List getSpecializations();
}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ISpecializedSymbol.java
===================================================================
retrieving revision 1.2
diff -u -r1.2 ISpecializedSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ISpecializedSymbol.java 13 Jun 2003 15:01:22 -0000 1.2
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ISpecializedSymbol.java 10 Feb 2004 19:17:58 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
+ * Copyright (c) 2003,2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@@ -16,12 +16,21 @@
*/
package org.eclipse.cdt.internal.core.parser.pst;
+import java.util.List;
+
/**
* @author aniefer
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
-public interface ISpecializedSymbol extends IParameterizedSymbol {
+public interface ISpecializedSymbol extends ITemplateSymbol {
+
+ public void addArgument( TypeInfo arg );
+
+ public List getArgumentList();
+
+ public ITemplateSymbol getPrimaryTemplate();
+ public void setPrimaryTemplate( ITemplateSymbol templateSymbol );
}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java
===================================================================
retrieving revision 1.11
diff -u -r1.11 ISymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java 17 Jan 2004 00:18:24 -0000 1.11
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java 10 Feb 2004 19:17:58 -0000
@@ -21,6 +21,8 @@
public Object clone();
+ public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException;
+
public void setName(String name);
public String getName();
@@ -43,12 +45,12 @@
public List getPtrOperators();
public void addPtrOperator( TypeInfo.PtrOp ptrOp );
+ public boolean isTemplateInstance();
+ public ISymbol getInstantiatedSymbol();
+ public void setInstantiatedSymbol( ISymbol symbol );
public boolean isTemplateMember();
public void setIsTemplateMember( boolean isMember );
- public ISymbol getTemplateInstance();
- public Map getArgumentMap();
- public void setTemplateInstance( TemplateInstance instance );
-
+
public int getDepth();
public boolean getIsInvisible();
public void setIsInvisible( boolean invisible );
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java
===================================================================
retrieving revision 1.4
diff -u -r1.4 ParameterizedSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java 15 Jan 2004 23:06:36 -0000 1.4
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java 10 Feb 2004 19:17:58 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
+ * Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@@ -53,12 +53,48 @@
else
copy._parameterMap = ( _parameterMap != null ) ? (Map) ((HashMap) _parameterMap).clone() : null;
- copy._argumentList = ( _argumentList != null ) ? (LinkedList) _argumentList.clone() : null;
- copy._specializations = ( _specializations != null ) ? (LinkedList) _specializations.clone() : null;
-
return copy;
}
+ public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
+ if( !isTemplateMember() ){
+ return null;
+ }
+
+ ParameterizedSymbol newParameterized = (ParameterizedSymbol) super.instantiate( template, argMap );
+
+ if( _returnType != null ){
+ if( _returnType.isType( TypeInfo.t_templateParameter ) ){
+ if( argMap.containsKey( _returnType ) ){
+ newParameterized.setReturnType( getSymbolTable().newSymbol( ParserSymbolTable.EMPTY_NAME ) );
+ newParameterized.getReturnType().setTypeInfo( (TypeInfo) argMap.get( _returnType ) );
+ newParameterized.getReturnType().setInstantiatedSymbol( _returnType );
+ }
+ } else {
+ newParameterized.setReturnType( _returnType.instantiate( template, argMap ) );
+ }
+ }
+
+ Iterator iter = getParameterList().iterator();
+
+ newParameterized.getParameterList().clear();
+ newParameterized.getParameterMap().clear();
+
+ ISymbol param = null, newParam = null;
+
+ while( iter.hasNext() ){
+ param = (ISymbol) iter.next();
+ newParam = param.instantiate( template, argMap );
+
+ newParameterized.getParameterList().add( newParam );
+ if( !newParam.getName().equals( ParserSymbolTable.EMPTY_NAME ) ){
+ newParameterized.getParameterMap().put( newParam.getName(), newParam );
+ }
+ }
+
+ return newParameterized;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/
@@ -114,36 +150,6 @@
}
/* (non-Javadoc)
- * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addArgument(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
- */
- public void addArgument( ISymbol arg ){
- List argumentList = getArgumentList();
- argumentList.add( arg );
-
- arg.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
-
- Command command = new AddArgumentCommand( this, arg );
- getSymbolTable().pushCommand( command );
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getArgumentList()
- */
- public List getArgumentList(){
- if( _argumentList == null ){
- _argumentList = new LinkedList();
- }
- return _argumentList;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#setArgumentList(java.util.List)
- */
-// public void setArgumentList( List list ){
-// _argumentList = new LinkedList( list );
-// }
-
- /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterMap()
*/
public Map getParameterMap(){
@@ -222,33 +228,6 @@
return _returnType;
}
- /* (non-Javadoc)
- * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasSpecializations()
- */
- public boolean hasSpecializations(){
- return ( _specializations != null && !_specializations.isEmpty() );
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addSpecialization(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
- */
- public void addSpecialization( IParameterizedSymbol spec ){
- List specializationList = getSpecializations();
- specializationList.add( spec );
-
- spec.setContainingSymbol( getContainingSymbol() );
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getSpecializations()
- */
- public List getSpecializations() {
- if( _specializations == null ){
- _specializations = new LinkedList();
- }
- return _specializations;
- }
-
public void setHasVariableArgs( boolean var ){
_hasVarArgs = var;
}
@@ -277,23 +256,9 @@
private ISymbol _param;
}
- static private class AddArgumentCommand extends Command{
- public AddArgumentCommand( IParameterizedSymbol container, ISymbol arg ){
- _decl = container;
- _arg = arg;
- }
- public void undoIt(){
- _decl.getArgumentList().remove( _arg );
- }
-
- private IParameterizedSymbol _decl;
- private ISymbol _arg;
- }
private LinkedList _parameterList; //have my cake
private Map _parameterMap; //and eat it too
- private LinkedList _specializations; //template specializations
- private LinkedList _argumentList; //template specialization arguments
private ISymbol _returnType;
private boolean _hasVarArgs = false; //whether or not this function has variable arguments
}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java
===================================================================
retrieving revision 1.38
diff -u -r1.38 ParserSymbolTable.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java 9 Feb 2004 16:31:45 -0000 1.38
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java 10 Feb 2004 19:17:59 -0000
@@ -82,6 +82,10 @@
public IParameterizedSymbol newParameterizedSymbol( String name, TypeInfo.eType type ){
return new ParameterizedSymbol( this, name, type );
}
+ public ITemplateSymbol newTemplateSymbol( String name ){
+ return new TemplateSymbol( this, name );
+ }
+
public ISpecializedSymbol newSpecializedSymbol( String name ){
return new SpecializedSymbol( this, name );
}
@@ -309,7 +313,7 @@
if( declarations instanceof SortedMap ){
iterator = ((SortedMap)declarations).tailMap( data.name.toLowerCase() ).keySet().iterator();
} else {
- throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
+ throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
}
@@ -339,41 +343,83 @@
}
if( lookIn instanceof IParameterizedSymbol ){
- Map parameters = ((IParameterizedSymbol)lookIn).getParameterMap();
- if( parameters != null ){
- iterator = null;
- if( data.mode == LookupMode.PREFIX ){
- if( parameters instanceof SortedMap ){
- iterator = ((SortedMap) parameters).tailMap( data.name.toLowerCase() ).keySet().iterator();
- } else {
- throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
- }
- }
- name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name;
- while( name != null ){
- if( nameMatches( data, name ) ){
- obj = parameters.get( name );
- obj = collectSymbol( data, obj );
+ lookupInParameters(data, lookIn, found);
+ }
+
+ if( lookIn.isTemplateMember() && data.templateMember == null ){
+ IContainerSymbol containing = lookIn.getContainingSymbol();
+ IContainerSymbol outer = (containing != null ) ? containing.getContainingSymbol() : null;
+ if( ( containing instanceof IDerivableContainerSymbol && outer instanceof ITemplateSymbol) ||
+ ( lookIn instanceof IParameterizedSymbol && containing instanceof ITemplateSymbol ) )
+ {
+ data.templateMember = lookIn;
+ }
+ }
+
+ return found;
+
+ }
+ /**
+ * @param data
+ * @param lookIn
+ * @param found
+ * @throws ParserSymbolTableException
+ */
+ private static void lookupInParameters(LookupData data, IContainerSymbol lookIn, Map found) throws ParserSymbolTableException {
+ Object obj;
+ Iterator iterator;
+ String name;
+
+ if( lookIn instanceof ITemplateSymbol && ((ITemplateSymbol)lookIn).getDefinitionParameterMap() != null ){
+ ITemplateSymbol template = (ITemplateSymbol) lookIn;
+ if( data.templateMember != null && template.getDefinitionParameterMap().containsKey( data.templateMember ) ){
+ Map map = (Map) template.getDefinitionParameterMap().get( data.templateMember );
+ iterator = map.keySet().iterator();
+ while( iterator.hasNext() ){
+ ISymbol symbol = (ISymbol) iterator.next();
+ if( nameMatches( data, symbol.getName() ) ){
+ obj = collectSymbol( data, symbol );
if( obj != null ){
- found.put( name, obj );
+ found.put( symbol.getName(), obj );
}
- } else {
- break;
}
-
- if( iterator != null && iterator.hasNext() ){
- name = (String) iterator.next();
- } else {
- name = null;
+ }
+ return;
+ }
+
+ }
+ Map parameters = ((IParameterizedSymbol)lookIn).getParameterMap();
+ if( parameters != null ){
+ iterator = null;
+ if( data.mode == LookupMode.PREFIX ){
+ if( parameters instanceof SortedMap ){
+ iterator = ((SortedMap) parameters).tailMap( data.name.toLowerCase() ).keySet().iterator();
+ } else {
+ throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
+ }
+ }
+
+ name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name;
+ while( name != null ){
+ if( nameMatches( data, name ) ){
+ obj = parameters.get( name );
+ obj = collectSymbol( data, obj );
+ if( obj != null ){
+ found.put( name, obj );
}
+ } else {
+ break;
}
+ if( iterator != null && iterator.hasNext() ){
+ name = (String) iterator.next();
+ } else {
+ name = null;
+ }
}
}
-
- return found;
}
-
+
private static boolean nameMatches( LookupData data, String name ){
if( data.mode == LookupMode.PREFIX ){
return name.regionMatches( true, 0, data.name, 0, data.name.length() );
@@ -386,15 +432,6 @@
return true;
}
- if( data.templateInstance != null && symbol.isTemplateMember() ){
- if( symbol.isType( TypeInfo.t_type ) ){
- symbol = symbol.getTypeSymbol();
- }
- if( symbol.isType( TypeInfo.t_undef ) && symbol.getContainingSymbol().isType( TypeInfo.t_template ) ){
- TypeInfo info = (TypeInfo) data.templateInstance.getArgumentMap().get( symbol );
- return data.filter.shouldAccept( symbol, info );
- }
- }
return data.filter.shouldAccept( symbol );
}
@@ -409,22 +446,30 @@
ISymbol symbol = ( iter != null ) ? (ISymbol) iter.next() : (ISymbol) object;
Set functionSet = new HashSet();
+ Set templateFunctionSet = new HashSet();
+
ISymbol obj = null;
IContainerSymbol cls = null;
while( symbol != null ){
+ if( symbol instanceof ITemplateSymbol ){
+ ISymbol temp = ((ITemplateSymbol)symbol).getTemplatedSymbol();
+ symbol = ( temp != null ) ? temp : symbol;
+ }
+
if( !symbol.getIsInvisible() && checkType( data, symbol ) ){//, data.type, data.upperType ) ){
- if( symbol.isTemplateMember() && data.templateInstance != null )
- foundSymbol = new TemplateInstance( symbol.getSymbolTable(), symbol, data.templateInstance.getArgumentMap() );
- else
- foundSymbol = symbol;
+ foundSymbol = symbol;
if( foundSymbol.isType( TypeInfo.t_function ) ){
if( foundSymbol.isForwardDeclaration() && foundSymbol.getTypeSymbol() != null ){
foundSymbol = foundSymbol.getTypeSymbol();
}
+ if( foundSymbol.getContainingSymbol().isType( TypeInfo.t_template ) ){
+ templateFunctionSet.add( foundSymbol );
+ } else {
+ functionSet.add( foundSymbol );
+ }
- functionSet.add( foundSymbol );
} else {
//if this is a class-name, other stuff hides it
if( foundSymbol.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
@@ -473,6 +518,7 @@
}
int numFunctions = functionSet.size();
+ int numTemplateFunctions = templateFunctionSet.size();
boolean ambiguous = false;
@@ -481,9 +527,23 @@
if( obj != null && cls.getContainingSymbol() != obj.getContainingSymbol()){
ambiguous = true;
}
+
+ Iterator fnIter = null;
+ IParameterizedSymbol fn = null;
+ if( !templateFunctionSet.isEmpty() ){
+ fnIter = templateFunctionSet.iterator();
+
+ for( int i = numTemplateFunctions; i > 0; i-- ){
+ fn = (IParameterizedSymbol) fnIter.next();
+ if( cls.getContainingSymbol()!= fn.getContainingSymbol()){
+ ambiguous = true;
+ break;
+ }
+ }
+ }
if( !functionSet.isEmpty() ){
- Iterator fnIter = functionSet.iterator();
- IParameterizedSymbol fn = null;
+ fnIter = functionSet.iterator();
+
for( int i = numFunctions; i > 0; i-- ){
fn = (IParameterizedSymbol) fnIter.next();
if( cls.getContainingSymbol()!= fn.getContainingSymbol()){
@@ -494,6 +554,17 @@
}
}
+ if( numTemplateFunctions > 0 ){
+ if( data.parameters != null ){
+ List fns = TemplateEngine.selectTemplateFunctions( templateFunctionSet, data.parameters );
+ functionSet.addAll( fns );
+ numFunctions = functionSet.size();
+ } else {
+ functionSet.addAll( templateFunctionSet );
+ numFunctions += numTemplateFunctions;
+ }
+ }
+
if( obj != null && !ambiguous ){
if( numFunctions > 0 ){
ambiguous = true;
@@ -526,13 +597,11 @@
*/
private static Map lookupInParents( LookupData data, ISymbol lookIn ) throws ParserSymbolTableException{
IDerivableContainerSymbol container = null;
- /*if( lookIn instanceof TemplateInstance ){
-
- } else*/
+
if( lookIn instanceof IDerivableContainerSymbol ){
container = (IDerivableContainerSymbol) lookIn;
} else{
- throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
+ throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
List scopes = container.getParents();
@@ -561,14 +630,7 @@
{
wrapper = (IDerivableContainerSymbol.IParentSymbol) iterator.next();
ISymbol parent = wrapper.getParent();
- if( parent.isType( TypeInfo.t_undef ) && parent.getContainingSymbol().isType( TypeInfo.t_template ) ){
- TypeInfo info = (TypeInfo) data.templateInstance.getArgumentMap().get( parent );
- if( info.getTypeSymbol() instanceof IDerivableContainerSymbol ){
- parent = (IDerivableContainerSymbol) info.getTypeSymbol();
- } else {
- throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
- }
- }
+
if( !wrapper.isVirtual() || !data.visited.contains( parent ) ){
if( wrapper.isVirtual() ){
data.visited.add( parent );
@@ -578,16 +640,7 @@
//is circular inheritance
if( ! data.inheritanceChain.contains( parent ) ){
//is this name define in this scope?
- if( parent instanceof TemplateInstance ){
- ISymbol tempInstance = data.templateInstance;
- data.templateInstance = (TemplateInstance) parent;
- ISymbol instance = ((TemplateInstance)parent).getInstantiatedSymbol();
- if( instance instanceof IContainerSymbol )
- temp = lookupInContained( data, (IContainerSymbol)instance );
- else
- throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
- data.templateInstance = tempInstance;
- } else if( parent instanceof IDerivableContainerSymbol ){
+ if( parent instanceof IDerivableContainerSymbol ){
temp = lookupInContained( data, (IDerivableContainerSymbol) parent );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
@@ -707,6 +760,24 @@
TypeInfo.eType origType = origSymbol.getType();
TypeInfo.eType newType = newSymbol.getType();
+ if( origType == TypeInfo.t_template ){
+ ITemplateSymbol template = (ITemplateSymbol) origSymbol;
+ origSymbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
+ if( origSymbol == null )
+ return true;
+ else
+ origType = origSymbol.getType();
+ }
+
+ if( newType == TypeInfo.t_template ){
+ ITemplateSymbol template = (ITemplateSymbol) newSymbol;
+ newSymbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
+ if( newSymbol == null )
+ return true;
+ else
+ newType = newSymbol.getType();
+ }
+
//handle forward decls
if( origSymbol.getTypeInfo().isForwardDeclaration() ){
if( origSymbol.getTypeSymbol() == newSymbol )
@@ -736,7 +807,11 @@
if( origList.size() == 1 ){
return isValidOverload( (ISymbol)origList.iterator().next(), newSymbol );
} else if ( origList.size() > 1 ){
-
+ if( newSymbol.isType( TypeInfo.t_template ) ){
+ ITemplateSymbol template = (ITemplateSymbol) newSymbol;
+ newSymbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
+ }
+
//the first thing can be a class-name or enumeration name, but the rest
//must be functions. So make sure the newDecl is a function before even
//considering the list
@@ -746,13 +821,20 @@
Iterator iter = origList.iterator();
ISymbol symbol = (ISymbol) iter.next();
- boolean valid = isValidOverload( symbol, newSymbol );//( (symbol.getType().compareTo( TypeInfo.t_class ) >= 0 ) && (symbol.getType().compareTo( TypeInfo.t_enumeration ) <= 0 ) );
+
+ if( symbol.isType( TypeInfo.t_template ) ){
+ IParameterizedSymbol template = (IParameterizedSymbol) symbol;
+ symbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
+ }
- if( !valid && (symbol instanceof IParameterizedSymbol) )
- valid = isValidFunctionOverload( (IParameterizedSymbol)symbol, (IParameterizedSymbol)newSymbol );
+ boolean valid = isValidOverload( symbol, newSymbol );
while( valid && iter.hasNext() ){
symbol = (ISymbol) iter.next();
+ if( symbol.isType( TypeInfo.t_template ) ){
+ IParameterizedSymbol template = (IParameterizedSymbol) symbol;
+ symbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
+ }
valid = ( symbol instanceof IParameterizedSymbol) && isValidFunctionOverload( (IParameterizedSymbol)symbol, (IParameterizedSymbol)newSymbol );
}
@@ -829,6 +911,11 @@
if( symbol.isType( TypeInfo.t_function ) ){
functionList.add( symbol );
} else {
+ if( symbol.isTemplateMember() && !symbol.isTemplateInstance() &&
+ !symbol.isType( TypeInfo.t_templateParameter ) && symbol.getContainingSymbol().isType( TypeInfo.t_template ))
+ {
+ return symbol.getContainingSymbol();
+ }
return symbol;
}
}
@@ -1010,6 +1097,17 @@
ambiguous |= ( hasWorse && hasBetter ) || ( !hasWorse && !hasBetter );
if( !hasWorse ){
+ if( !hasBetter ){
+ //if they are both template functions, we can order them that way
+ if( bestFn.isTemplateInstance() && currFn.isTemplateInstance() ){
+ ITemplateSymbol t1 = (ITemplateSymbol) bestFn.getInstantiatedSymbol().getContainingSymbol();
+ ITemplateSymbol t2 = (ITemplateSymbol) currFn.getInstantiatedSymbol().getContainingSymbol();
+ int order = TemplateEngine.orderTemplateFunctions( t1, t2 );
+ if ( order < 0 ){
+ hasBetter = true;
+ }
+ }
+ }
if( hasBetter ){
//the new best function.
ambiguous = false;
@@ -1177,16 +1275,8 @@
return 0;
}
IDerivableContainerSymbol symbol = null;
- TemplateInstance instance = null;
- if( obj instanceof TemplateInstance ){
- instance = (TemplateInstance) obj;
- ISymbol temp = instance.getInstantiatedSymbol();
- if( temp instanceof IDerivableContainerSymbol ){
- symbol = (IDerivableContainerSymbol) temp;
- } else {
- return -1;
- }
- } else if( obj instanceof IDerivableContainerSymbol ){
+
+ if( obj instanceof IDerivableContainerSymbol ){
symbol = (IDerivableContainerSymbol) obj;
} else {
return -1;
@@ -1203,48 +1293,23 @@
for( int i = size; i > 0; i-- ){
wrapper = (IDerivableContainerSymbol.IParentSymbol) iter.next();
temp = wrapper.getParent();
- boolean isVisible = ( wrapper.getVisibility() == ASTAccessVisibility.PUBLIC );
- if( temp instanceof TemplateInstance ){
- instance = (TemplateInstance) temp;
- if( instance.getInstantiatedSymbol() instanceof IDerivableContainerSymbol ){
- if( instance.getInstantiatedSymbol() == base ){
- if( throwIfNotVisible && !isVisible )
- throw new ParserSymbolTableException( ParserSymbolTableException.r_BadVisibility );
- else
- return 1;
- } else {
- int n = hasBaseClass( instance, base, throwIfNotVisible );
- if( n > 0 ){
- return n + 1;
- }
- }
- }
- } else {
- if( temp.isType( TypeInfo.t_undef ) && temp.getContainingSymbol().isType( TypeInfo.t_template ) ){
- if( instance == null ) continue;
- TypeInfo info = (TypeInfo) instance.getArgumentMap().get( temp );
- if( info == null || !info.isType( TypeInfo.t_class, TypeInfo.t_struct ) ){
- continue;
- }
- parent = (IDerivableContainerSymbol) info.getTypeSymbol();
- }
- else if ( temp instanceof IDerivableContainerSymbol ){
- parent = (IDerivableContainerSymbol)temp;
- } else {
- continue;
+ boolean isVisible = ( wrapper.getAccess() == ASTAccessVisibility.PUBLIC );
+ if ( temp instanceof IDerivableContainerSymbol ){
+ parent = (IDerivableContainerSymbol)temp;
+ } else {
+ continue;
+ }
+ if( parent == base ){
+ if( throwIfNotVisible && !isVisible )
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_BadVisibility );
+ else
+ return 1;
+ } else {
+ int n = hasBaseClass( parent, base, throwIfNotVisible );
+ if( n > 0 ){
+ return n + 1;
}
- if( parent == base ){
- if( throwIfNotVisible && !isVisible )
- throw new ParserSymbolTableException( ParserSymbolTableException.r_BadVisibility );
- else
- return 1;
- } else {
- int n = hasBaseClass( parent, base, throwIfNotVisible );
- if( n > 0 ){
- return n + 1;
- }
- }
- }
+ }
}
}
@@ -1285,13 +1350,17 @@
for( int i = size; i > 0; i-- ){
wrapper = (IDerivableContainerSymbol.IParentSymbol) iter.next();
- base = wrapper.getParent();
- classes.add( base );
- if( base.getContainingSymbol().getType() == TypeInfo.t_namespace ){
- classes.add( base.getContainingSymbol());
+ base = wrapper.getParent();
+ //TODO: what about IDeferredTemplateInstance parents?
+ if( base instanceof IDerivableContainerSymbol ){
+ classes.add( base );
+ if( base.getContainingSymbol().getType() == TypeInfo.t_namespace ){
+ classes.add( base.getContainingSymbol());
+ }
+
+ getBaseClassesAndContainingNamespaces( (IDerivableContainerSymbol) base, classes );
}
- getBaseClassesAndContainingNamespaces( (IDerivableContainerSymbol) base, classes );
}
}
}
@@ -1637,7 +1706,7 @@
}
}
- static private Cost checkStandardConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException{
+ static protected Cost checkStandardConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException{
Cost cost = lvalue_to_rvalue( source, target );
if( cost.source == null || cost.target == null ){
@@ -1699,18 +1768,13 @@
if( target.getType() == TypeInfo.t_type ){
targetDecl = target.getTypeSymbol();
if( targetDecl.isType( TypeInfo.t_class, TypeInfo.t_union ) ){
- LookupData data = new LookupData( EMPTY_NAME, TypeInfo.t_constructor, null );
+ LookupData data = new LookupData( EMPTY_NAME, TypeInfo.t_constructor);
data.parameters = new LinkedList();
data.parameters.add( source );
data.forUserDefinedConversion = true;
IDerivableContainerSymbol container = (IDerivableContainerSymbol) targetDecl;
- if( targetDecl instanceof TemplateInstance ){
- data.templateInstance = targetDecl;
- container = (IDerivableContainerSymbol)((TemplateInstance) targetDecl).getInstantiatedSymbol();
- }
-
if( !container.getConstructors().isEmpty() ){
LinkedList constructors = new LinkedList( container.getConstructors() );
constructor = resolveFunction( data, constructors );
@@ -1731,7 +1795,7 @@
String name = target.toString();
if( !name.equals(EMPTY_NAME) ){
- LookupData data = new LookupData( "operator " + name, TypeInfo.t_function, null ); //$NON-NLS-1$
+ LookupData data = new LookupData( "operator " + name, TypeInfo.t_function ); //$NON-NLS-1$
LinkedList params = new LinkedList();
data.parameters = params;
data.forUserDefinedConversion = true;
@@ -1853,7 +1917,7 @@
info = typeSymbol.getTypeInfo();
}
- if( info.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
+ if( info.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) || info.isType( TypeInfo.t_function ) ){
returnInfo.setType( TypeInfo.t_type );
returnInfo.setTypeSymbol( typeSymbol );
} else {
@@ -1868,7 +1932,7 @@
if( topInfo.hasPtrOperators() ){
TypeInfo.PtrOp topPtr = (PtrOp) topInfo.getPtrOperators().iterator().next();
TypeInfo.PtrOp ptr = null;
- if( returnInfo.hasPtrOperators() ){
+ if( returnInfo.hasPtrOperators() && topPtr.getType() == PtrOp.t_undef ){
ptr = (PtrOp)returnInfo.getPtrOperators().iterator().next();
} else {
ptr = new PtrOp();
@@ -1886,336 +1950,6 @@
return returnInfo;
}
- //TODO Andrew - This code is dead, I didn't cut it out as I assume you plan to make it live soon. Be forewarned.
- static private IParameterizedSymbol matchTemplatePartialSpecialization( IParameterizedSymbol template, List args ){
- if( template == null ){
- return null;
- }
-
- List specs = template.getSpecializations();
- int size = ( specs != null ) ? specs.size() : 0;
- if( size == 0 ){
- return template;
- }
-
- IParameterizedSymbol bestMatch = null;
- boolean bestMatchIsBest = true;
- Iterator iter = specs.iterator();
- IParameterizedSymbol spec = null;
- List specArgs = null;
- for( int i = size; i > 0; i-- ){
- spec = (IParameterizedSymbol) iter.next();
- specArgs = spec.getArgumentList();
- if( specArgs == null || specArgs.size() != args.size() ){
- continue;
- }
-
- ISymbol sym1 = null, sym2 = null;
- Iterator iter1 = specArgs.iterator();
- Iterator iter2 = args.iterator();
-
- HashMap map = new HashMap();
- //String name = null;
- boolean match = true;
- for( int j = specArgs.size(); j > 0; j-- ){
- sym1 = (ISymbol)iter1.next();
- TypeInfo info2 = (TypeInfo) iter2.next();
- if( info2.isType( TypeInfo.t_type ) ){
- sym2 = sym2.getTypeSymbol();
- } else {
- sym2 = template.getSymbolTable().newSymbol( EMPTY_NAME );
- sym2.setTypeInfo( info2 );
- }
-
- if( !deduceTemplateArgument( map, sym1, sym2, null ) ){
- match = false;
- break;
- }
- /*
- name = sym1.getName();
- if( name.equals( "" ) ){
- //no name, only type
- } else if( map.containsKey( name ) ) {
- ISymbol val = (ISymbol) map.get( name );
- if( val.getType() != sym2.getType() ){
- match = false;
- break;
- }
- } else {
- map.put( name, sym2 );
- }
- */
- }
- if( match ){
- int compare = orderSpecializations( bestMatch, spec );
- if( compare == 0 ){
- bestMatchIsBest = false;
- } else if( compare < 0 ) {
- bestMatch = spec;
- bestMatchIsBest = true;
- }
- }
- }
-
- return bestMatchIsBest ? bestMatch : null;
- }
-
- /**
- * Compare spec1 to spec2. Return > 0 if spec1 is more specialized, < 0 if spec2
- * is more specialized, = 0 otherwise.
- * @param spec1
- * @param spec2
- * @return
- */
- static private int orderSpecializations( IParameterizedSymbol spec1, IParameterizedSymbol spec2 ){
- if( spec1 == null ){
- return -1;
- }
-
- Iterator iter = spec1.getContainedSymbols().keySet().iterator();
- ISymbol decl = (ISymbol) spec1.getContainedSymbols().get( iter.next() );
-
- //to order class template specializations, we need to transform them into function templates
- if( decl.isType( TypeInfo.t_class ) ) {
- spec1 = classTemplateSpecializationToFunctionTemplate( spec1 );
- spec2 = classTemplateSpecializationToFunctionTemplate( spec2 );
- }
-
- TemplateInstance transformed1 = transformFunctionTemplateForOrdering( spec1 );
- TemplateInstance transformed2 = transformFunctionTemplateForOrdering( spec2 );
-
- //Using the transformed parameter list, perform argument deduction against the other
- //function template
- boolean d1 = deduceTemplateArguments( spec2, transformed1 );
- boolean d2 = deduceTemplateArguments( spec1, transformed2 );
-
- //The transformed template is at least as specialized as the other iff the deduction
- //succeeds and the deduced parameter types are an exact match
- //A template is more specialized than another iff it is at least as specialized as the
- //other template and that template is not at least as specialized as the first.
- if( d1 && d2 || !d1 && !d2 )
- return 0;
- else if( d1 && !d2 )
- return 1;
- else
- return -1;
- }
-
- /**
- *
- * @param template
- * @param args
- * @return
- *
- * A type that is specified in terms of template parameters (P) is compared with an actual
- * type (A), and an attempt is made to find template argument vaules that will make P,
- * after substitution of the deduced values, compatible with A.
- */
- static private boolean deduceTemplateArguments( IParameterizedSymbol template, TemplateInstance argSource ){
- if( template.getContainedSymbols() == null || template.getContainedSymbols().size() != 1 ){
- return false;
- }
- Iterator iter = template.getContainedSymbols().keySet().iterator();
- ISymbol templateSymbol = (ISymbol) template.getContainedSymbols().get( iter.next() );
- if( !templateSymbol.isType( TypeInfo.t_function ) ){
- return false;
- }
-
- IParameterizedSymbol argTemplate = (IParameterizedSymbol)argSource.getInstantiatedSymbol();
- iter = argTemplate.getContainedSymbols().keySet().iterator();
- ISymbol argFunction = (ISymbol) argTemplate.getContainedSymbols().get( iter.next() );
- if( !argFunction.isType( TypeInfo.t_function ) ){
- return false;
- }
-
- List args = ((IParameterizedSymbol) argFunction).getParameterList();
-
- IParameterizedSymbol function = (IParameterizedSymbol) templateSymbol;
-
- if( function.getParameterList() == null || function.getParameterList().size() != args.size() ){
- return false;
- }
-
- HashMap map = new HashMap();
-
- Iterator pIter = function.getParameterList().iterator();
- Iterator aIter = args.iterator();
- while( pIter.hasNext() ){
- if( !deduceTemplateArgument( map, (ISymbol) pIter.next(), (ISymbol) aIter.next(), argSource.getArgumentMap() ) ){
- return false;
- }
- }
-
- return true;
- }
-
- static private boolean deduceTemplateArgument( Map map, ISymbol p, ISymbol a, Map argumentMap ){
- if( argumentMap != null && argumentMap.containsKey( a ) ){
- a = (ISymbol) argumentMap.get( a );
- }
-
- ISymbol pSymbol = p, aSymbol = a;
-
- if( p.isType( TypeInfo.t_type ) ){
- pSymbol = p.getTypeSymbol();
- aSymbol = a.isType( TypeInfo.t_type ) ? a.getTypeSymbol() : a;
- return deduceTemplateArgument( map, pSymbol, aSymbol, argumentMap );
- } else {
- if( pSymbol.isTemplateMember() && pSymbol.isType( TypeInfo.t_undef ) ){
- //T* or T& or T[ const ]
- //also
- List pPtrs = pSymbol.getPtrOperators();
- List aPtrs = aSymbol.getPtrOperators();
-
- if( pPtrs != null ){
- TypeInfo.PtrOp pOp = (TypeInfo.PtrOp) pPtrs.iterator().next();
- TypeInfo.PtrOp aOp = ( aPtrs != null ) ? (TypeInfo.PtrOp)pPtrs.iterator().next() : null;
-
- if( pOp != null && aOp != null && pOp.getType() == aOp.getType() ){
- if( pOp.getType() == TypeInfo.PtrOp.t_memberPointer ){
-
- } else {
- TypeInfo type = new TypeInfo( aSymbol.getTypeInfo() );
- type.getPtrOperators().clear();
- map.put( pSymbol.getName(), type );
- return true;
- }
- } else {
- return false;
- }
- } else {
- //T
- map.put( pSymbol.getName(), a.getTypeInfo() );
- return true;
- }
-
-
- }
- //template-name<T> or template-name<i>
- else if( pSymbol.isType( TypeInfo.t_template ) && aSymbol.isType( TypeInfo.t_template ) ){
- List pArgs = ((IParameterizedSymbol)pSymbol).getArgumentList();
- List aArgs = ((IParameterizedSymbol)aSymbol).getArgumentList();
-
- if( pArgs == null || aArgs == null || pArgs.size() != aArgs.size()){
- return false;
- }
- Iterator pIter = pArgs.iterator();
- Iterator aIter = aArgs.iterator();
- while( pIter.hasNext() ){
- if( !deduceTemplateArgument( map, (ISymbol) pIter.next(), (ISymbol) aIter.next(), argumentMap ) ){
- return false;
- }
- }
- }
- //T (*) ( ), T ( T::* ) ( T ), & variations
- else if( pSymbol.isType( TypeInfo.t_function ) && aSymbol.isType( TypeInfo.t_function ) ){
- IParameterizedSymbol pFunction = (IParameterizedSymbol)pSymbol;
- IParameterizedSymbol aFunction = (IParameterizedSymbol)aSymbol;
-
- if( !deduceTemplateArgument( map, aFunction.getReturnType(), pFunction.getReturnType(), argumentMap ) ){
- return false;
- }
- if( pSymbol.getPtrOperators() != null ){
- List ptrs = pSymbol.getPtrOperators();
- TypeInfo.PtrOp op = (TypeInfo.PtrOp) ptrs.iterator().next();
- if( op.getType() == TypeInfo.PtrOp.t_memberPointer ){
- if( !deduceTemplateArgument( map, op.getMemberOf(), pFunction.getContainingSymbol(), argumentMap ) ){
- return false;
- }
- }
- }
-
- List pParams = pFunction.getParameterList();
- List aParams = aFunction.getParameterList();
- if( pParams.size() != aParams.size() ){
- return false;
- } else {
- Iterator pIter = pParams.iterator();
- Iterator aIter = aParams.iterator();
- while( pIter.hasNext() ){
- if( !deduceTemplateArgument( map, (ISymbol) pIter.next(), (ISymbol) aIter.next(), argumentMap ) ){
- return false;
- }
- }
- }
-
- } else if( pSymbol.getType() == aSymbol.getType() ){
- if( pSymbol.getTypeInfo().getHasDefault() ){
- if( !aSymbol.getTypeInfo().getHasDefault() ||
- aSymbol.getTypeInfo().getDefault().equals( pSymbol.getTypeInfo().getDefault() ) )
- {
- return false;
- }
- }
- //value
- map.put( pSymbol.getName(), aSymbol.getTypeInfo() );
- return true;
- }
- }
-
- return false;
- }
- /**
- * transform the class template to a function template as described in the spec
- * 14.5.4.2-1
- * @param template
- * @return IParameterizedSymbol
- * the function template has the same template parameters as the partial specialization and
- * has a single function parameter whose type is a class template specialization with the template
- * arguments of the partial specialization
- */
- static private IParameterizedSymbol classTemplateSpecializationToFunctionTemplate( IParameterizedSymbol template ){
- IParameterizedSymbol transformed = (IParameterizedSymbol) template.clone();
- transformed.getArgumentList().clear();
- transformed.getContainedSymbols().clear();
-
- IParameterizedSymbol function = template.getSymbolTable().newParameterizedSymbol( transformed.getName(), TypeInfo.t_function );
- try{
- transformed.addSymbol( function );
- } catch ( ParserSymbolTableException e ){
- //we shouldn't get this because there aren't any other symbols in the template
- }
-
- function.addParameter( template );
-
- return transformed;
- }
-
- /**
- * transform a function template for use in partial ordering, as described in the
- * spec 14.5.5.2-3
- * @param template
- * @return
- * -for each type template parameter, synthesize a unique type and substitute that for each
- * occurence of that parameter in the function parameter list
- * -for each non-type template parameter, synthesize a unique value of the appropriate type and
- * susbstitute that for each occurence of that parameter in the function parameter list
- * for each template template parameter, synthesize a unique class template and substitute that
- * for each occurence of that parameter in the function parameter list
- */
- static private TemplateInstance transformFunctionTemplateForOrdering( IParameterizedSymbol template ){
-
- List paramList = template.getParameterList();
-
- int size = ( paramList != null ) ? paramList.size() : 0;
- if( size == 0 ){
- return null;
- }
-
- HashMap map = new HashMap();
- for( Iterator iterator = paramList.iterator(); iterator.hasNext(); ) {
- ISymbol param = (ISymbol) iterator.next();
- ISymbol val = template.getSymbolTable().newSymbol( EMPTY_NAME, TypeInfo.t_type );
- if( false /* is value */ ){
- //val.getTypeInfo().setHasDefault()
- }
- map.put( param, val );
- }
-
- return new TemplateInstance( template.getSymbolTable(), template, map );
- }
-
- //private Stack _contextStack = new Stack();
private IContainerSymbol _compilationUnit;
private ParserLanguage _language;
private ParserMode _mode;
@@ -2302,10 +2036,11 @@
public HashSet inheritanceChain; //used to detect circular inheritance
- public List parameters; //parameter info for resolving functions
+ public List parameters; //parameter info for resolving functions
public HashSet associated; //associated namespaces for argument dependant lookup
public ISymbol stopAt; //stop looking along the stack once we hit this declaration
public TypeFilter filter = null;
+ public ISymbol templateMember; //to assit with template member defs
public boolean qualified = false;
public boolean ignoreUsingDirectives = false;
@@ -2314,22 +2049,19 @@
public Map foundItems = null;
- public ISymbol templateInstance = null;
public LookupMode mode = LookupMode.NORMAL;
- public LookupData( String n, TypeInfo.eType t, ISymbol i ){
+ public LookupData( String n, TypeInfo.eType t ){
name = n;
filter = new TypeFilter( t );
- templateInstance = i;
}
- public LookupData( String n, TypeFilter f, ISymbol i ){
+ public LookupData( String n, TypeFilter f ) {
name = n;
filter = ( f != null ) ? f : new TypeFilter( TypeInfo.t_any );
- templateInstance = i;
}
}
- static private class Cost
+ static protected class Cost
{
public Cost( TypeInfo s, TypeInfo t ){
@@ -2445,7 +2177,7 @@
* @param qualifyingSymbol
* @return
*/
- public static ASTAccessVisibility getVisibility(ISymbol symbol, IContainerSymbol qualifyingSymbol) throws ParserSymbolTableException {
+ public static ASTAccessVisibility getVisibility(ISymbol symbol, IContainerSymbol qualifyingSymbol){
IContainerSymbol container = symbol.getContainingSymbol();
if( qualifyingSymbol == null || container.equals( qualifyingSymbol ) ){
@@ -2454,12 +2186,12 @@
if( node != null && node instanceof IASTMember ){
return ((IASTMember)node).getVisiblity();
} else {
- throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
+ throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
}
if( ! (qualifyingSymbol instanceof IDerivableContainerSymbol) ){
- throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
+ throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
}
List parents = ((IDerivableContainerSymbol) qualifyingSymbol).getParents();
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTableException.java
===================================================================
retrieving revision 1.5
diff -u -r1.5 ParserSymbolTableException.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTableException.java 30 Sep 2003 18:03:15 -0000 1.5
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTableException.java 10 Feb 2004 19:17:59 -0000
@@ -1,5 +1,5 @@
/**********************************************************************
- * Copyright (c) 2002,2003 Rational Software Corporation and others.
+ * Copyright (c) 2002,2003, 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@@ -13,11 +13,6 @@
/**
* @author aniefer
- *
- * To change this generated comment edit the template variable "typecomment":
- * Window>Preferences>Java>Templates.
- * To enable and disable the creation of type comments go to
- * Window>Preferences>Java>Code Generation.
*/
public class ParserSymbolTableException extends Exception {
@@ -36,15 +31,18 @@
reason = r;
}
- public static final int r_InternalError = -1;
- public static final int r_Ambiguous = 0;
- public static final int r_BadTypeInfo = 1;
- public static final int r_CircularInheritance = 2;
- public static final int r_InvalidOverload = 3;
- public static final int r_BadTemplate = 4;
- public static final int r_InvalidUsing = 5;
- public static final int r_BadVisibility = 6;
- public static final int r_UnableToResolveFunction = 7;
-
+ public static final int r_InternalError = -1;
+ public static final int r_Ambiguous = 0;
+ public static final int r_BadTypeInfo = 1;
+ public static final int r_CircularInheritance = 2;
+ public static final int r_InvalidOverload = 3;
+ public static final int r_BadTemplate = 4;
+ public static final int r_InvalidUsing = 5;
+ public static final int r_BadVisibility = 6;
+ public static final int r_UnableToResolveFunction = 7;
+ public static final int r_BadTemplateArgument = 8;
+ public static final int r_BadTemplateParameter = 9;
+ public static final int r_RedeclaredTemplateParam = 10;
public int reason = -1;
+
}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java
===================================================================
retrieving revision 1.1
diff -u -r1.1 SpecializedSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java 20 Nov 2003 15:22:56 -0000 1.1
+++ parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java 10 Feb 2004 19:17:59 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
+ * Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@@ -13,18 +13,146 @@
*/
package org.eclipse.cdt.internal.core.parser.pst;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Command;
+
/**
- * @author aniefer
- *
- * To change the template for this generated type comment go to
- * Window>Preferences>Java>Code Generation>Code and Comments
+ * @author aniefe
*/
-public class SpecializedSymbol extends ParameterizedSymbol implements ISpecializedSymbol {
+
+public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSymbol {
protected SpecializedSymbol( ParserSymbolTable table, String name ){
- super( table, name, TypeInfo.t_template );
+ super( table, name );
}
protected SpecializedSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
super( table, name, obj );
}
+
+ public Object clone(){
+ SpecializedSymbol copy = (SpecializedSymbol)super.clone();
+
+ copy._argumentList = ( _argumentList != null ) ? (LinkedList) _argumentList.clone() : null;
+
+ return copy;
+ }
+
+
+ public ITemplateSymbol getPrimaryTemplate(){
+ return _primaryTemplate;
+ }
+
+ public void setPrimaryTemplate( ITemplateSymbol templateSymbol ){
+ _primaryTemplate = templateSymbol;
+ }
+
+ public ISymbol instantiate( List arguments ) throws ParserSymbolTableException{
+ Map argMap = new HashMap();
+
+ List specArgs = getArgumentList();
+ if( specArgs.size() != arguments.size() ){
+ return null;
+ }
+
+ List actualArgs = new LinkedList();
+
+ Iterator iter1 = specArgs.iterator();
+ Iterator iter2 = arguments.iterator();
+
+ ISymbol templatedSymbol = getTemplatedSymbol();
+ while( templatedSymbol.isTemplateInstance() ){
+ templatedSymbol = templatedSymbol.getInstantiatedSymbol();
+ }
+
+ while( iter1.hasNext() ){
+ TypeInfo info = (TypeInfo) iter1.next();
+ TypeInfo mappedInfo = (TypeInfo) iter2.next();
+
+ //If the argument is a template parameter, we can't instantiate yet, defer for later
+ if( mappedInfo.isType( TypeInfo.t_type ) && mappedInfo.getTypeSymbol().isType( TypeInfo.t_templateParameter ) ){
+ return deferredInstance( arguments );
+ }
+
+ actualArgs.add( mappedInfo );
+ if( info.isType( TypeInfo.t_type ) && info.getTypeSymbol().isType( TypeInfo.t_templateParameter )){
+ ISymbol param = info.getTypeSymbol();
+
+ param = TemplateEngine.translateParameterForDefinition ( templatedSymbol, param, getDefinitionParameterMap() );
+
+ if( !argMap.containsKey( param ) ){
+ argMap.put( param, mappedInfo );
+ }
+ }
+ }
+
+ //sanity check
+ if( getParameterList().size() != argMap.size() )
+ return null;
+
+ Iterator params = getParameterList().iterator();
+ while( params.hasNext() ){
+ if( !argMap.containsKey( params.next() ) )
+ return null;
+ }
+
+ IContainerSymbol instance = findInstantiation( actualArgs );
+ if( instance != null ){
+ return instance;
+ } else {
+ IContainerSymbol symbol = null;
+
+ if( getContainedSymbols().size() == 1 ){
+ Iterator iter = getContainedSymbols().keySet().iterator();
+ symbol = (IContainerSymbol)getContainedSymbols().get( iter.next() );
+ }
+
+ instance = (IContainerSymbol) symbol.instantiate( this, argMap );
+ addInstantiation( instance, actualArgs );
+ return instance;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getArgumentList()
+ */
+ public List getArgumentList(){
+ if( _argumentList == null ){
+ _argumentList = new LinkedList();
+ }
+ return _argumentList;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addArgument(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
+ */
+ public void addArgument(TypeInfo arg) {
+ List argumentList = getArgumentList();
+ argumentList.add( arg );
+
+ //arg.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
+
+ Command command = new AddArgumentCommand( this, arg );
+ getSymbolTable().pushCommand( command );
+ }
+
+ static private class AddArgumentCommand extends Command{
+ public AddArgumentCommand( ISpecializedSymbol container, TypeInfo arg ){
+ _decl = container;
+ _arg = arg;
+ }
+ public void undoIt(){
+ _decl.getArgumentList().remove( _arg );
+ }
+
+ private ISpecializedSymbol _decl;
+ private TypeInfo _arg;
+ }
+
+ private LinkedList _argumentList; //template specialization arguments
+ private ITemplateSymbol _primaryTemplate; //our primary template
}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/TemplateInstance.java
===================================================================
diff -N parser/org/eclipse/cdt/internal/core/parser/pst/TemplateInstance.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/TemplateInstance.java 15 Jan 2004 13:37:53 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,135 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- * IBM Corp. - Rational Software - initial implementation
- ******************************************************************************/
-/*
- * Created on Nov 6, 2003
- */
-package org.eclipse.cdt.internal.core.parser.pst;
-
-import java.util.Iterator;
-import java.util.Map;
-
-
-public class TemplateInstance extends BasicSymbol
-{
- //TODO ANDREW - this field is not read, is this a work in progress?
- //private final ParserSymbolTable _table;
-
- protected TemplateInstance( ParserSymbolTable table, ISymbol symbol, Map argMap ){
- super(table, ParserSymbolTable.EMPTY_NAME );
- //this._table = table;
- _instantiatedSymbol = symbol;
- symbol.setTemplateInstance( this );
- _argumentMap = argMap;
- }
-
- public boolean equals( Object t ){
- if( t == null || !( t instanceof TemplateInstance ) ){
- return false;
- }
-
- TemplateInstance instance = (TemplateInstance) t;
-
- if( _instantiatedSymbol != instance._instantiatedSymbol ){
- return false;
- }
-
- //check arg map
- Iterator iter1 = _argumentMap.keySet().iterator();
- Iterator iter2 = instance._argumentMap.keySet().iterator();
- int size = _argumentMap.size();
- int size2 = instance._argumentMap.size();
- ISymbol t1 = null, t2 = null;
- if( size == size2 ){
- for( int i = size; i > 0; i-- ){
- t1 = (ISymbol)iter1.next();
- t2 = (ISymbol)iter2.next();
- if( t1 != t2 || !_argumentMap.get(t1).equals( instance._argumentMap.get(t2) ) ){
- return false;
- }
- }
- }
-
- return true;
- }
-
- public ISymbol getInstantiatedSymbol(){
- _instantiatedSymbol.setTemplateInstance( this );
- return _instantiatedSymbol;
- }
-
- public TypeInfo.eType getType(){
- ISymbol symbol = _instantiatedSymbol;
- TypeInfo.eType returnType = _instantiatedSymbol.getType();
- if( returnType == TypeInfo.t_type ){
- symbol = symbol.getTypeSymbol();
- TypeInfo info = null;
- while( symbol != null && symbol.getType() == TypeInfo.t_undef && symbol.getContainingSymbol().getType() == TypeInfo.t_template ){
- info = (TypeInfo) _argumentMap.get( symbol );
- if( !info.isType( TypeInfo.t_type ) ){
- break;
- }
- symbol = info.getTypeSymbol();
- }
-
- return ( info != null ) ? info.getType() : TypeInfo.t_type;
- }
-
- return returnType;
- }
-
- public boolean isType( TypeInfo.eType type ){
- return ( type == TypeInfo.t_any || getType() == type );
- }
-
- public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType ){
- if( type == TypeInfo.t_any )
- return true;
-
- if( upperType == TypeInfo.t_undef ){
- return ( getType() == type );
- } else {
- return ( getType().compareTo( type ) >= 0 && getType().compareTo( upperType ) <= 0 );
- }
- }
-
- public ISymbol getTypeSymbol(){
- ISymbol symbol = _instantiatedSymbol.getTypeSymbol();
- if( symbol != null && symbol.getType() == TypeInfo.t_undef &&
- symbol.getContainingSymbol().getType() == TypeInfo.t_template )
- {
- TypeInfo info = (TypeInfo) _argumentMap.get( symbol );
- return ( info != null ) ? info.getTypeSymbol() : null;
- }
-
- return symbol;
- }
-
- public TypeInfo getTypeInfo(){
- ISymbol symbol = _instantiatedSymbol.getTypeSymbol();
- if( symbol != null && symbol.getType() == TypeInfo.t_undef &&
- symbol.getContainingSymbol().getType() == TypeInfo.t_template )
- {
- TypeInfo info = (TypeInfo) _argumentMap.get( symbol );
- return info;
- }
-
- return _instantiatedSymbol.getTypeInfo();
- }
-
- public Map getArgumentMap(){
- return _argumentMap;
- }
-
-
- private ISymbol _instantiatedSymbol;
- //private LinkedList _arguments;
- private Map _argumentMap;
-}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java
===================================================================
retrieving revision 1.11
diff -u -r1.11 TypeInfo.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java 10 Feb 2004 15:33:52 -0000 1.11
+++ parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java 10 Feb 2004 19:18:00 -0000
@@ -1,5 +1,5 @@
/**********************************************************************
- * Copyright (c) 2002,2003 Rational Software Corporation and others.
+ * Copyright (c) 2002,2003, 2004 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
@@ -67,6 +67,7 @@
_typeDeclaration = info._typeDeclaration;
_ptrOperators = ( info._ptrOperators == null ) ? null : (LinkedList)info._ptrOperators.clone();
_hasDefaultValue = info._hasDefaultValue;
+ _defaultValue = info._defaultValue;
}
public static final int typeMask = 0x001f;
@@ -117,6 +118,8 @@
public static final TypeInfo.eType t_template = new TypeInfo.eType( 19 );
public static final TypeInfo.eType t_asm = new TypeInfo.eType( 20 );
public static final TypeInfo.eType t_linkage = new TypeInfo.eType( 21 );
+ public static final TypeInfo.eType t_templateParameter = new TypeInfo.eType( 22 );
+ public static final TypeInfo.eType t_typeName = new TypeInfo.eType( 23 );
//public static final eType t_templateParameter = new eType( 18 );
@@ -282,6 +285,14 @@
_typeInfo = typeInfo;
}
+ public eType getTemplateParameterType(){
+ return _templateParameterType;
+ }
+
+ public void setTemplateParameterType( eType type ){
+ _templateParameterType = type;
+ }
+
/**
*
* @param type
@@ -476,19 +487,25 @@
boolean result = ( _typeInfo == type._typeInfo );
result &= ( _type == type._type );
- if( _typeDeclaration instanceof TemplateInstance ){
- result &= _typeDeclaration.equals( type._typeDeclaration );
+ if( _typeDeclaration != null && type._typeDeclaration != null &&
+ _typeDeclaration.isType( TypeInfo.t__Bool, TypeInfo.t_void ) &&
+ type._typeDeclaration.isType( TypeInfo.t__Bool, TypeInfo.t_void ) )
+ {
+ //if typeDeclaration is a basic type, then only need the types the same
+ result &= ( _typeDeclaration.getType() == type._typeDeclaration.getType() );
+ } else if( _typeDeclaration != null && type._typeDeclaration != null &&
+ _typeDeclaration.isType( TypeInfo.t_function ) &&
+ type._typeDeclaration.isType( TypeInfo.t_function ) )
+ {
+ //function pointers... functions must have same parameter lists and return types
+ IParameterizedSymbol f1 = (IParameterizedSymbol) _typeDeclaration;
+ IParameterizedSymbol f2 = (IParameterizedSymbol) type._typeDeclaration;
+
+ result &= f1.hasSameParameters( f2 );
+ result &= f1.getReturnType().getTypeInfo().equals( f2.getReturnType().getTypeInfo() );
} else {
- if( _typeDeclaration != null && type._typeDeclaration != null &&
- _typeDeclaration.isType( TypeInfo.t__Bool, TypeInfo.t_void ) &&
- type._typeDeclaration.isType( TypeInfo.t__Bool, TypeInfo.t_void ) )
- {
- //if typeDeclaration is a basic type, then only need the types the same
- result &= ( _typeDeclaration.getType() == type._typeDeclaration.getType() );
- } else {
- //otherwise, its a user defined type, need the decls the same
- result &= ( _typeDeclaration == type._typeDeclaration );
- }
+ //otherwise, its a user defined type, need the decls the same
+ result &= ( _typeDeclaration == type._typeDeclaration );
}
int size1 = (_ptrOperators == null) ? 0 : _ptrOperators.size();
@@ -524,7 +541,8 @@
}
private int _typeInfo = 0;
- private TypeInfo.eType _type = TypeInfo.t_undef;
+ private eType _type = TypeInfo.t_undef;
+ private eType _templateParameterType = t_typeName;
private ISymbol _typeDeclaration;
private boolean _hasDefaultValue = false;
Index: parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java
diff -N parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,74 @@
+/**********************************************************************
+ * Copyright (c) 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.internal.core.parser.pst;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author aniefer
+ *
+ * To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class DeferredTemplateInstance extends BasicSymbol implements IDeferredTemplateInstance {
+
+ public DeferredTemplateInstance( ParserSymbolTable table, ITemplateSymbol template, List args ){
+ super(table, ParserSymbolTable.EMPTY_NAME );
+ _template = template;
+ _arguments = new LinkedList( args );
+
+ setContainingSymbol( template );
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.IDeferredTemplateInstance#getTemplate()
+ */
+ public ITemplateSymbol getTemplate() {
+ return _template;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.IDeferredTemplateInstance#getArgumentMap()
+ */
+ public List getArguments() {
+ return _arguments;
+ }
+
+ public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
+ List args = getArguments();
+ List newArgs = new LinkedList();
+ Iterator iter = args.iterator();
+
+ while( iter.hasNext() ){
+ TypeInfo arg = (TypeInfo) iter.next();
+ newArgs.add( TemplateEngine.instantiateTypeInfo( arg, template, argMap ) );
+ }
+
+ ITemplateSymbol deferredTemplate = getTemplate();
+ if( deferredTemplate.isType( TypeInfo.t_templateParameter ) && argMap.containsKey( deferredTemplate ) ){
+ TypeInfo i = (TypeInfo) argMap.get( deferredTemplate );
+ deferredTemplate = (ITemplateSymbol) i.getTypeSymbol();
+ }
+
+ ISymbol instance = deferredTemplate.instantiate( newArgs );
+// if( !( instance instanceof IDeferredTemplateInstance ) )
+// return instance.instantiate( template, argMap );
+// else
+ return instance;
+ }
+
+ private ITemplateSymbol _template;
+ private List _arguments;
+}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/IDeferredTemplateInstance.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/parser/pst/IDeferredTemplateInstance.java
diff -N parser/org/eclipse/cdt/internal/core/parser/pst/IDeferredTemplateInstance.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/parser/pst/IDeferredTemplateInstance.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,24 @@
+/**********************************************************************
+ * Copyright (c) 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.internal.core.parser.pst;
+
+import java.util.List;
+
+/**
+ * @author aniefer
+ */
+
+public interface IDeferredTemplateInstance extends ISymbol {
+
+ public ITemplateSymbol getTemplate();
+
+ public List getArguments();
+}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateFactory.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateFactory.java
diff -N parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateFactory.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,31 @@
+/**********************************************************************
+ * Copyright (c) 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.internal.core.parser.pst;
+
+import java.util.List;
+
+/**
+ * @author aniefer
+ **/
+
+public interface ITemplateFactory {
+
+ public void addSymbol( ISymbol symbol ) throws ParserSymbolTableException;
+
+ public ISymbol lookupMemberForDefinition( String name ) throws ParserSymbolTableException;
+ public IParameterizedSymbol lookupMemberFunctionForDefinition( String name, List params ) throws ParserSymbolTableException;
+
+ public ITemplateFactory lookupTemplateForMemberDefinition( String name, List templateParameters,
+ List templateArguments ) throws ParserSymbolTableException;
+ public ITemplateSymbol getPrimaryTemplate();
+
+ public ISymbol lookupParam( String name ) throws ParserSymbolTableException;
+}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateSymbol.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateSymbol.java
diff -N parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateSymbol.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateSymbol.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,40 @@
+/**********************************************************************
+ * Copyright (c) 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.internal.core.parser.pst;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author aniefer
+ */
+
+public interface ITemplateSymbol extends IParameterizedSymbol {
+
+ public void addTemplateParameter( ISymbol param ) throws ParserSymbolTableException;
+
+ public boolean hasSpecializations();
+ public void addSpecialization( ISpecializedSymbol spec );
+ public List getSpecializations();
+
+ public IContainerSymbol getTemplatedSymbol();
+
+ public Map getDefinitionParameterMap();
+
+ public ISpecializedSymbol findSpecialization(List parameters, List arguments);
+ public IContainerSymbol findInstantiation( List arguments );
+ public List findArgumentsFor( IContainerSymbol instance );
+
+ public void addInstantiation( IContainerSymbol instance, List args );
+ public ISymbol instantiate( List args ) throws ParserSymbolTableException;
+ public IDeferredTemplateInstance deferredInstance( List args );
+
+}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTableError.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTableError.java
diff -N parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTableError.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTableError.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,36 @@
+/**********************************************************************
+ * Copyright (c) 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.internal.core.parser.pst;
+
+/**
+ * @author aniefer
+ */
+public class ParserSymbolTableError extends Error {
+ /**
+ * Constructor for ParserSymbolTableError.
+ */
+ public ParserSymbolTableError() {
+ super();
+ }
+
+ /**
+ * Constructor for ParserSymbolTableError.
+ * @param int r: reason
+ */
+ public ParserSymbolTableError( int r ) {
+ reason = r;
+ }
+
+ public static final int r_InternalError = -1;
+ public static final int r_OperationNotSupported = 0;
+ public int reason = -1;
+
+}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java
diff -N parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,1132 @@
+/**********************************************************************
+ * Copyright (c) 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.internal.core.parser.pst;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol.IParentSymbol;
+import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Cost;
+import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
+
+/**
+ * @author aniefer
+ */
+public final class TemplateEngine {
+
+ static protected TypeInfo instantiateTypeInfo( TypeInfo info, ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
+ if( argMap == null ){
+ return info;
+ } else {
+ if( info.isType( TypeInfo.t_type ) && info.getTypeSymbol() instanceof IDeferredTemplateInstance ){
+ IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) info.getTypeSymbol();
+
+ TypeInfo newInfo = new TypeInfo( info );
+ newInfo.setTypeSymbol( deferred.instantiate( template, argMap ) );
+ return newInfo;
+ } else if( info.isType( TypeInfo.t_type ) &&
+ info.getTypeSymbol().isType( TypeInfo.t_templateParameter ) &&
+ argMap.containsKey( info.getTypeSymbol() ) )
+ {
+ TypeInfo targetInfo = new TypeInfo( (TypeInfo) argMap.get( info.getTypeSymbol() ) );
+ if( info.hasPtrOperators() ){
+ List infoOperators = new LinkedList( info.getPtrOperators() );
+
+ if( targetInfo.hasPtrOperators() ){
+ List targetOperators = targetInfo.getPtrOperators();
+
+ PtrOp lastTargetOp = (PtrOp) targetOperators.get( targetOperators.size() - 1 );
+ if( lastTargetOp.getType() == PtrOp.t_undef ){
+ targetOperators.remove( targetOperators.size() - 1 );
+ PtrOp infoOp = (PtrOp) infoOperators.get( 0 );
+ infoOp = new PtrOp( infoOp.getType(), infoOp.isConst() || lastTargetOp.isConst(),
+ infoOp.isVolatile() || lastTargetOp.isVolatile() );
+ infoOperators.set( 0, infoOp );
+ }
+ }
+
+ targetInfo.addPtrOperator( infoOperators );
+ }
+ return targetInfo;
+ } else if( info.isType( TypeInfo.t_type ) && info.getTypeSymbol().isType( TypeInfo.t_function ) ){
+ TypeInfo newInfo = new TypeInfo( info );
+ newInfo.setTypeSymbol( info.getTypeSymbol().instantiate( template, argMap ) );
+ return newInfo;
+ }
+ return info;
+ }
+ }
+
+ static protected ITemplateSymbol matchTemplatePartialSpecialization( ITemplateSymbol template, List args ) throws ParserSymbolTableException{
+ if( template == null ){
+ return null;
+ }
+
+ List specs = template.getSpecializations();
+ int size = ( specs != null ) ? specs.size() : 0;
+ if( size == 0 ){
+ return template;
+ }
+
+ ISpecializedSymbol bestMatch = null;
+ boolean bestMatchIsBest = true;
+ Iterator iter = specs.iterator();
+ ISpecializedSymbol spec = null;
+ List specArgs = null;
+ for( int i = size; i > 0; i-- ){
+ spec = (ISpecializedSymbol) iter.next();
+ specArgs = spec.getArgumentList();
+ if( specArgs == null || specArgs.size() != args.size() ){
+ continue;
+ }
+
+ Iterator iter1 = specArgs.iterator();
+ Iterator iter2 = args.iterator();
+
+ HashMap map = new HashMap();
+ TypeInfo info1 = null, info2 = null;
+
+ boolean match = true;
+ for( int j = specArgs.size(); j > 0; j-- ){
+ info1 = (TypeInfo) iter1.next();
+ info2 = (TypeInfo) iter2.next();
+
+ ISymbol sym1 = template.getSymbolTable().newSymbol( ParserSymbolTable.EMPTY_NAME );
+ sym1.setTypeInfo( info1 );
+
+ if( !deduceTemplateArgument( map, sym1, info2 ) ){
+ match = false;
+ break;
+ }
+ }
+ if( match ){
+ int compare = orderSpecializations( bestMatch, spec );
+ if( compare == 0 ){
+ bestMatchIsBest = false;
+ } else if( compare < 0 ) {
+ bestMatch = spec;
+ bestMatchIsBest = true;
+ }
+ }
+ }
+
+ //14.5.4.1 If none of the specializations is more specialized than all the other matchnig
+ //specializations, then the use of the class template is ambiguous and the program is ill-formed.
+ if( !bestMatchIsBest ){
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
+ }
+
+ return bestMatch;
+ }
+
+ static protected boolean matchTemplateParameterAndArgument( ISymbol param, TypeInfo arg ){
+ if( !isValidArgument(param, arg) ){
+ return false;
+ }
+
+ if( param.getTypeInfo().getTemplateParameterType() == TypeInfo.t_typeName ){
+ return true;
+ } else if( param.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template ){
+
+ ISymbol symbol = arg.getTypeSymbol();
+ if( !arg.isType( TypeInfo.t_type ) || symbol == null || !symbol.isType( TypeInfo.t_template ) ){
+ return false;
+ }
+
+ IParameterizedSymbol p = (IParameterizedSymbol) param;
+ IParameterizedSymbol a = (IParameterizedSymbol) symbol;
+
+ List pList = p.getParameterList();
+ List aList = a.getParameterList();
+
+ if( pList.size() != aList.size() ){
+ return false;
+ }
+
+ Iterator pIter = pList.iterator();
+ Iterator aIter = aList.iterator();
+ while( pIter.hasNext() ){
+ ISymbol pParam = (ISymbol) pIter.next();
+ ISymbol aParam = (ISymbol) aIter.next();
+
+ if( pParam.getType() != aParam.getType() ||
+ pParam.getTypeInfo().getTemplateParameterType() != aParam.getTypeInfo().getTemplateParameterType() )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ } else {
+ Cost cost = null;
+ try {
+ cost = ParserSymbolTable.checkStandardConversionSequence( arg, param.getTypeInfo());
+ } catch (ParserSymbolTableException e) {
+ }
+
+ if( cost == null || cost.rank != Cost.NO_MATCH_RANK ){
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static private boolean isValidArgument(ISymbol param, TypeInfo arg) {
+ if( param.getTypeInfo().getTemplateParameterType() == TypeInfo.t_typeName ){
+ //14.3.1, local type, type with no name
+ if( arg.isType( TypeInfo.t_type ) && arg.getTypeSymbol() != null ){
+ ISymbol symbol = arg.getTypeSymbol();
+ if( symbol.getName().equals( ParserSymbolTable.EMPTY_NAME ) ){
+ return false;
+ } else if( hasNoLinkage( arg ) ){
+ return false;
+ }
+ }
+ } else if ( param.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template ){
+
+ } else {
+ List ptrs = param.getPtrOperators();
+ PtrOp op = ( ptrs.size() > 0 ) ? (PtrOp) ptrs.get(0) : null;
+
+ //if the parameter has reference type
+ if( op != null && op.getType() == PtrOp.t_reference ){
+ if( arg.isType( TypeInfo.t_type ) && arg.getTypeSymbol() != null ){
+ if( arg.getTypeSymbol().getName().equals( ParserSymbolTable.EMPTY_NAME ) ){
+ return false;
+ }
+ }
+ return hasExternalLinkage( arg );
+ }
+
+ List argPtrs = arg.getPtrOperators();
+ PtrOp argOp = (argPtrs.size() > 0 ) ? (PtrOp)argPtrs.get(0) : null;
+
+ //address of an object with external linkage exluding nonstatic class members
+ //name of an object with external linkage excluding nonstatic class members
+ if( (argOp != null && argOp.getType() == PtrOp.t_pointer ) ||
+ ( arg.isType( TypeInfo.t_type ) ) )
+ {
+ ISymbol symbol = arg.getTypeSymbol();
+ if ( symbol != null && symbol.getContainingSymbol().isType( TypeInfo.t_class, TypeInfo.t_union ) ){
+ if( !symbol.isType( TypeInfo.t_class, TypeInfo.t_union ) ){
+ if( !symbol.getTypeInfo().checkBit( TypeInfo.isStatic ) ){
+ return false;
+ }
+ }
+ }
+
+ return hasExternalLinkage( arg );
+ }
+
+ //integral or enumeration type
+ if( op == null && ( arg.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
+ arg.isType( TypeInfo.t_enumerator ) ) )
+ {
+ return true;
+ }
+
+ //name of a non-type template parameter
+ if( arg.isType( TypeInfo.t_templateParameter ) &&
+ arg.getTemplateParameterType() != TypeInfo.t_typeName &&
+ arg.getTemplateParameterType() != TypeInfo.t_template )
+ {
+ return true;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ static protected boolean hasExternalLinkage( TypeInfo type ){
+ if( ! type.isType( TypeInfo.t_type ) )
+ return false;
+
+ return !hasNoLinkage( type );
+ }
+
+ static protected boolean hasInternalLinkage( TypeInfo type ){
+ return !hasNoLinkage( type );
+ }
+
+ static protected boolean hasNoLinkage( TypeInfo type ){
+ if( type.isType( TypeInfo.t_type ) ){
+ ISymbol symbol = type.getTypeSymbol();
+ if( symbol.getContainingSymbol() == null ){
+ return true; //a temporary
+ }
+
+ return symbol.getContainingSymbol().isType( TypeInfo.t_function );
+ }
+
+ return false;
+ }
+
+ /**
+ * 14.8.2.1-2 If P is a cv-qualified type, the top level cv-qualifiers of P's type are ignored for type
+ * deduction. If P is a reference type, the type referred to by P is used for Type deduction.
+ * @param pSymbol
+ * @return
+ */
+ static private TypeInfo getParameterTypeForDeduction( ISymbol pSymbol ){
+ TypeInfo p = new TypeInfo( pSymbol.getTypeInfo () );
+ List pPtrs = p.getPtrOperators();
+ if( pPtrs.size() > 0 ){
+ PtrOp pOp = (PtrOp) pPtrs.get( 0 );
+ if( pOp.getType() == PtrOp.t_reference || pOp.getType() == PtrOp.t_undef ){
+ pPtrs.remove( 0 );
+ } else {
+ PtrOp newOp = new PtrOp( pOp.getType(), false, false );
+ pPtrs.set( 0, newOp );
+ }
+ }
+
+ return p;
+ }
+
+ /**
+ * 14.8.2.1-2
+ * - If A is an array type, the pointer type produced by the array-to-pointer conversion is used instead
+ * - If A is a function type, the pointer type produced by the function-to-pointer conversion is used instead
+ * - If A is a cv-qualified type, the top level cv-qualifiers are ignored for type deduction
+ * @param aInfo
+ * @return
+ */
+ static private TypeInfo getArgumentTypeForDeduction( TypeInfo aInfo ){
+
+ TypeInfo a = ParserSymbolTable.getFlatTypeInfo( aInfo );
+
+ List aPtrs = a.getPtrOperators();
+ ISymbol aSymbol = a.getTypeSymbol();
+
+ if( a.getType() == TypeInfo.t_type && aSymbol.isType( TypeInfo.t_function ) ){
+ if( aPtrs.size() == 0 ){
+ aPtrs.add( new PtrOp( PtrOp.t_pointer ) );
+ }
+ }
+ if( aPtrs.size() > 0 ){
+ PtrOp pOp = (PtrOp) aPtrs.get( 0 );
+
+ if( pOp.getType() == PtrOp.t_array ){
+ aPtrs.set( 0, new PtrOp( PtrOp.t_pointer, false, false ) );
+ } else if( pOp.getType() == PtrOp.t_undef ){
+ aPtrs.remove( 0 );
+ } else {
+ aPtrs.set( 0, new PtrOp( pOp.getType(), false, false ) );
+ }
+ }
+
+ return a;
+ }
+
+ static private List getSourceList( ISymbol symbol ){
+ ITemplateSymbol template = null;
+
+ if( symbol instanceof IDeferredTemplateInstance ){
+ IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) symbol;
+ return deferred.getArguments();
+ } else {
+ ISymbol instantiated = symbol.getInstantiatedSymbol();
+ template = (ITemplateSymbol) instantiated.getContainingSymbol();
+ }
+
+ if( template instanceof ISpecializedSymbol ){
+ return ((ISpecializedSymbol)template).getArgumentList();
+ } else {
+ return template.getParameterList();
+ }
+ }
+
+ static private List getTargetList( ISymbol symbol ){
+ if( symbol instanceof IDeferredTemplateInstance ){
+ IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) symbol;
+ return deferred.getArguments();
+ } else {
+ ISymbol instantiated = symbol.getInstantiatedSymbol();
+ ITemplateSymbol template = (ITemplateSymbol) instantiated.getContainingSymbol();
+ return template.findArgumentsFor( (IContainerSymbol) symbol );
+ }
+ }
+
+ /**
+ * @param aSymbol
+ * @param p
+ * @param derivable
+ * @return
+ */
+ private static ISymbol findMatchingBaseClass( ISymbol p, IDerivableContainerSymbol a ) {
+ ISymbol aSymbol = null;
+ ITemplateSymbol pTemplate = null;
+ ITemplateSymbol parentTemplate = null;
+
+ if( p instanceof IDeferredTemplateInstance ){
+ pTemplate = ((IDeferredTemplateInstance)p).getTemplate();
+ } else {
+ pTemplate = (ITemplateSymbol) p.getInstantiatedSymbol().getContainingSymbol();
+ }
+ if( pTemplate instanceof ISpecializedSymbol ){
+ pTemplate = ((ISpecializedSymbol)pTemplate).getPrimaryTemplate();
+ }
+ Iterator iter = a.getParents().iterator();
+ while( iter.hasNext() ){
+ IParentSymbol wrapper = (IParentSymbol) iter.next();
+ ISymbol parent = wrapper.getParent();
+ if( parent instanceof IDeferredTemplateInstance ){
+ IDeferredTemplateInstance parentInstance = (IDeferredTemplateInstance) parent;
+ parentTemplate = parentInstance.getTemplate();
+ if( parentTemplate instanceof ISpecializedSymbol ){
+ parentTemplate = ((ISpecializedSymbol)parentTemplate).getPrimaryTemplate();
+ }
+ if( pTemplate == parentTemplate ){
+ aSymbol = parent;
+ break;
+ }
+ //In general, we don't have enough information to proceed further down this branch
+ } else {
+ parentTemplate = (ITemplateSymbol) parent.getInstantiatedSymbol().getContainingSymbol();
+ if( parentTemplate instanceof ISpecializedSymbol ){
+ parentTemplate = ((ISpecializedSymbol)parentTemplate).getPrimaryTemplate();
+ }
+ if( pTemplate == parentTemplate ){
+ aSymbol = parent;
+ break;
+ }
+ aSymbol = findMatchingBaseClass( p, (IDerivableContainerSymbol) parent );
+ }
+ if( aSymbol != null )
+ return aSymbol;
+ }
+
+ return aSymbol;
+ }
+
+ static private boolean deduceTemplateArgument( Map map, ISymbol pSymbol, TypeInfo a ){//, Map argumentMap ){
+ ISymbol symbol;
+
+ TypeInfo p = getParameterTypeForDeduction( pSymbol );
+ a = getArgumentTypeForDeduction( a );
+
+ if( p.isType( TypeInfo.t_type ) ){
+ symbol = p.getTypeSymbol();
+ ISymbol aSymbol = a.getTypeSymbol();
+ if( symbol instanceof IDeferredTemplateInstance || symbol.isTemplateInstance() ){
+ return deduceFromTemplateTemplateArguments(map, symbol, aSymbol);
+ } else {
+ if( symbol.isType( TypeInfo.t_templateParameter ) ){
+ if( symbol.getTypeInfo().getTemplateParameterType() == TypeInfo.t_typeName ){
+ //a = getFlatTypeInfo( a );
+ List aPtrs = a.getPtrOperators();
+ List pPtrs = p.getPtrOperators();
+ //TODO cvlist T
+ if( pPtrs != null && pPtrs.size() > 0){
+ if( aPtrs == null ){
+ return false;
+ }
+
+ Iterator pIter = pPtrs.iterator();
+ ListIterator aIter = aPtrs.listIterator();
+ PtrOp pOp = null;
+ PtrOp aOp = null;
+ while( pIter.hasNext() ){
+ pOp = (PtrOp) pIter.next();
+ if( !aIter.hasNext() ){
+ return false;
+ } else {
+ aOp = (PtrOp) aIter.next();
+ if( pOp.getType() == aOp.getType() ){
+ if( !pOp.equals( aOp ) ){
+ if( pIter.hasNext() || pOp.compareCVTo( aOp ) > 0 ){
+ return false;
+ } else {
+ PtrOp newOp = new PtrOp( PtrOp.t_undef );
+ newOp.setConst( aOp.isConst() );
+ newOp.setVolatile( aOp.isVolatile() );
+ aIter.set( newOp );
+ }
+ } else {
+ aIter.remove();
+ }
+
+ } else {
+ return false;
+ }
+ }
+ }
+ return deduceArgument( map, symbol, a );
+ } else {
+ //T
+ return deduceArgument( map, symbol, a );
+ }
+ } else if ( symbol.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template ){
+
+ } else {
+ //non-type parameter
+ if( symbol.getTypeInfo().getTemplateParameterType() == a.getType() ){
+ return deduceArgument( map, symbol, a );
+ } else {
+ return false;
+ }
+
+ }
+ }
+ //T (*) ( ), T ( T::* ) ( T ), & variations
+ else if( symbol.isType( TypeInfo.t_function ) ){
+ if( !(aSymbol instanceof IParameterizedSymbol)||
+ !aSymbol.isType( TypeInfo.t_function ) )
+ {
+ return false;
+ }
+
+ IParameterizedSymbol pFunction = (IParameterizedSymbol)symbol;
+ IParameterizedSymbol aFunction = (IParameterizedSymbol)aSymbol;
+
+ if( !deduceTemplateArgument( map, pFunction.getReturnType(), aFunction.getReturnType().getTypeInfo() ) ){
+ return false;
+ }
+
+ List pPtrs = p.getPtrOperators();
+ if( pPtrs.size() != 0 ){
+ PtrOp op = (PtrOp) pPtrs.iterator().next();;
+ if( op.getType() == PtrOp.t_memberPointer ){
+ TypeInfo info = new TypeInfo( TypeInfo.t_type, 0, aFunction.getContainingSymbol() );
+ if( !deduceTemplateArgument( map, op.getMemberOf(), info ) ){
+ return false;
+ }
+ }
+ }
+
+ List pParams = pFunction.getParameterList();
+ List aParams = aFunction.getParameterList();
+ if( pParams.size() != aParams.size() ){
+ return false;
+ } else {
+ Iterator pIter = pParams.iterator();
+ Iterator aIter = aParams.iterator();
+ while( pIter.hasNext() ){
+ TypeInfo info = ((ISymbol)aIter.next()).getTypeInfo();
+ if( !deduceTemplateArgument( map, (ISymbol) pIter.next(), info ) ){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ }
+ } else {
+ if( p.isType( TypeInfo.t_templateParameter ) ){
+ return deduceArgument( map, pSymbol, a );
+ }
+ if( p.getType() == a.getType() ){
+ if( p.getDefault() != null ){
+ return ( p.getDefault().equals( a.getDefault() ) );
+ }
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @param map
+ * @param pSymbol
+ * @param transformationMap
+ * @param symbol
+ * @param aSymbol
+ * @return
+ */
+ private static boolean deduceFromTemplateTemplateArguments(Map map, ISymbol pSymbol, ISymbol aSymbol) {
+ //template-name<T> or template-name<i>, where template-name is a class template
+ ITemplateSymbol p = ( pSymbol instanceof IDeferredTemplateInstance ) ?
+ (ITemplateSymbol) ((IDeferredTemplateInstance) pSymbol ).getTemplate() :
+ (ITemplateSymbol) pSymbol.getInstantiatedSymbol().getContainingSymbol();
+
+ if( p instanceof ISpecializedSymbol )
+ p = ((ISpecializedSymbol)p).getPrimaryTemplate();
+
+ ISymbol a = ( aSymbol.isTemplateInstance() ) ? aSymbol.getInstantiatedSymbol().getContainingSymbol() :
+ aSymbol.getContainingSymbol();
+
+ if( a instanceof ISpecializedSymbol )
+ a = ((ISpecializedSymbol)a).getPrimaryTemplate();
+
+ if( p != a ){
+ if( aSymbol instanceof IDerivableContainerSymbol ){
+ aSymbol = findMatchingBaseClass( pSymbol, (IDerivableContainerSymbol) aSymbol );
+ } else {
+ aSymbol = null;
+ }
+ if( aSymbol == null ) {
+ return false;
+ }
+ }
+
+ List pList = getSourceList( pSymbol );
+ List aList = getTargetList( aSymbol );
+
+ //TODO: default args?
+ if( pList == null || aList == null || pList.size() != aList.size()){
+ return false;
+ }
+ Iterator pIter = pList.iterator();
+ Iterator aIter = aList.iterator();
+ while( pIter.hasNext() ){
+ Object obj = pIter.next();
+ ISymbol sym = null;
+ if( obj instanceof ISymbol ){
+ sym = (ISymbol) obj;
+ } else {
+ sym = pSymbol.getSymbolTable().newSymbol( ParserSymbolTable.EMPTY_NAME );
+ sym.setTypeInfo( (TypeInfo) obj );
+ }
+
+ TypeInfo arg = transformTypeInfo( aIter.next(), null );
+
+ if( !deduceTemplateArgument( map, sym, arg ) ){
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ *
+ * @param template
+ * @param argList - the arguments passed in the function call
+ * @return
+ *
+ * A type that is specified in terms of template parameters (P) is compared with an actual
+ * type (A), and an attempt is made to find template argument vaules that will make P,
+ * after substitution of the deduced values, compatible with A.
+ */
+ static private Map deduceTemplateArgumentsUsingParameterList( ITemplateSymbol template, IParameterizedSymbol function ){
+
+ List aList = function.getParameterList();
+ LinkedList args = new LinkedList();
+
+ Iterator iter = aList.iterator();
+ while( iter.hasNext() ){
+ ISymbol symbol = (ISymbol) iter.next();
+ args.add( symbol.getTypeInfo() );
+ }
+
+ return deduceTemplateArguments( template, args );
+ }
+ /**
+ *
+ * @param template
+ * @param args
+ * @return
+ *
+ * A type that is specified in terms of template parameters (P) is compared with an actual
+ * type (A), and an attempt is made to find template argument vaules that will make P,
+ * after substitution of the deduced values, compatible with A.
+ */
+ static private Map deduceTemplateArguments( IParameterizedSymbol template, List arguments ){
+ if( template.getContainedSymbols() == null || template.getContainedSymbols().size() != 1 ){
+ return null;
+ }
+ Iterator iter = template.getContainedSymbols().keySet().iterator();
+ ISymbol templateSymbol = (ISymbol) template.getContainedSymbols().get( iter.next() );
+ if( !templateSymbol.isType( TypeInfo.t_function ) ){
+ return null;
+ }
+
+ IParameterizedSymbol templateFunction = (IParameterizedSymbol) templateSymbol;
+
+ List pList = templateFunction.getParameterList();
+// TODO: ellipses?
+ if( pList == null || arguments == null || pList.size() != arguments.size() ){
+ return null;
+ }
+
+ HashMap map = new HashMap();
+
+ Iterator pIter = pList.iterator();
+ Iterator aIter = arguments.iterator();
+
+ ISymbol aSymbol = null;
+ while( pIter.hasNext() ){
+ if( !deduceTemplateArgument( map, (ISymbol) pIter.next(), (TypeInfo) aIter.next() ) ){
+ return null;
+ }
+ }
+
+ return map;
+ }
+
+ static private boolean deduceArgument( Map map, ISymbol p, TypeInfo a ){
+
+ a = ParserSymbolTable.getFlatTypeInfo( a );
+
+ if( map.containsKey( p ) ){
+ TypeInfo current = (TypeInfo)map.get( p );
+ return current.equals( a );
+ } else {
+ map.put( p, a );
+ return true;
+ }
+ }
+ /**
+ * Compare spec1 to spec2. Return > 0 if spec1 is more specialized, < 0 if spec2
+ * is more specialized, = 0 otherwise.
+ * @param spec1
+ * @param spec2
+ * @return
+ */
+ static private int orderSpecializations( ISpecializedSymbol spec1, ISpecializedSymbol spec2 ) throws ParserSymbolTableException{
+ if( spec1 == null ){
+ return -1;
+ }
+
+ Iterator iter = spec1.getContainedSymbols().keySet().iterator();
+ ISymbol decl = (ISymbol) spec1.getContainedSymbols().get( iter.next() );
+
+ //to order class template specializations, we need to transform them into function templates
+ ITemplateSymbol template1 = spec1;
+ ITemplateSymbol template2 = spec2;
+
+ if( decl.isType( TypeInfo.t_class ) ) {
+ template1 = classTemplateSpecializationToFunctionTemplate( spec1 );
+ template2 = classTemplateSpecializationToFunctionTemplate( spec2 );
+ }
+
+ return orderTemplateFunctions( template1, template2);
+ }
+
+ /**
+ * Compare spec1 to spec2. Return > 0 if spec1 is more specialized, < 0 if spec2
+ * is more specialized, = 0 otherwise.
+ *
+ * Both spec1 and spec2 are expected to be template functions
+ *
+ */
+ static protected int orderTemplateFunctions( ITemplateSymbol spec1, ITemplateSymbol spec2 ) throws ParserSymbolTableException{
+ //Using the transformed parameter list, perform argument deduction against the other
+ //function template
+ Map map = createMapForFunctionTemplateOrdering( spec1 );
+
+ IContainerSymbol templatedSymbol = spec1.getTemplatedSymbol();
+ if( !( templatedSymbol instanceof IParameterizedSymbol ) )
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
+
+ IParameterizedSymbol function = (IParameterizedSymbol)templatedSymbol;
+ function = (IParameterizedSymbol) function.instantiate( spec1, map );
+
+ Map m1 = deduceTemplateArgumentsUsingParameterList( spec2, function);
+
+ map = createMapForFunctionTemplateOrdering( spec2 );
+
+ templatedSymbol = spec2.getTemplatedSymbol();
+ if( !( templatedSymbol instanceof IParameterizedSymbol ) )
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
+
+ function = (IParameterizedSymbol)templatedSymbol;
+ function = (IParameterizedSymbol) function.instantiate( spec2, map );
+
+ Map m2 = deduceTemplateArgumentsUsingParameterList( spec1, function );
+
+ //The transformed template is at least as specialized as the other iff the deduction
+ //succeeds and the deduced parameter types are an exact match
+ //A template is more specialized than another iff it is at least as specialized as the
+ //other template and that template is not at least as specialized as the first.
+ boolean d1 = ( m1 != null );
+ boolean d2 = ( m2 != null );
+
+ if( d1 && d2 || !d1 && !d2 )
+ return 0;
+ else if( d1 && !d2 )
+ return 1;
+ else
+ return -1;
+ }
+
+ /**
+ * transform a function template for use in partial ordering, as described in the
+ * spec 14.5.5.2-3
+ * @param template
+ * @return
+ * -for each type template parameter, synthesize a unique type and substitute that for each
+ * occurence of that parameter in the function parameter list
+ * -for each non-type template parameter, synthesize a unique value of the appropriate type and
+ * susbstitute that for each occurence of that parameter in the function parameter list
+ * for each template template parameter, synthesize a unique class template and substitute that
+ * for each occurence of that parameter in the function parameter list
+ */
+
+ static private Map createMapForFunctionTemplateOrdering( ITemplateSymbol template ){
+ HashMap map = new HashMap();
+ TypeInfo val = null;
+ List paramList = template.getParameterList();
+ for( Iterator iterator = paramList.iterator(); iterator.hasNext(); ) {
+ ISymbol param = (ISymbol) iterator.next();
+ //template type parameter
+ if( param.getTypeInfo().getTemplateParameterType() == TypeInfo.t_typeName ){
+ val = new TypeInfo( TypeInfo.t_type, 0, template.getSymbolTable().newSymbol( "", TypeInfo.t_class ) );
+ }
+ //template parameter
+ else if ( param.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template ) {
+
+ }
+ //non type parameter
+ else {
+ val = new TypeInfo( param.getTypeInfo().getTemplateParameterType(), 0, null );
+ }
+ map.put( param, val );
+ }
+ return map;
+ }
+
+
+ /**
+ * transform the class template to a function template as described in the spec
+ * 14.5.4.2-1
+ * @param template
+ * @return IParameterizedSymbol
+ * the function template has the same template parameters as the partial specialization and
+ * has a single function parameter whose type is a class template specialization with the template
+ * arguments of the partial specialization
+ */
+ static private ITemplateSymbol classTemplateSpecializationToFunctionTemplate( ISpecializedSymbol specialization ) throws ParserSymbolTableException{
+ ISpecializedSymbol transformed = (ISpecializedSymbol) specialization.clone();
+ transformed.getArgumentList().clear();
+ transformed.getContainedSymbols().clear();
+ //TODO clean up this
+ ((ContainerSymbol)transformed).getContents().clear();
+
+ IParameterizedSymbol function = specialization.getSymbolTable().newParameterizedSymbol( transformed.getName(), TypeInfo.t_function );
+ try{
+ transformed.addSymbol( function );
+ } catch ( ParserSymbolTableException e ){
+ //we shouldn't get this because there aren't any other symbols in the template
+ }
+ ISymbol param = specialization.getSymbolTable().newSymbol( "", TypeInfo.t_type );
+ LinkedList args = new LinkedList( specialization.getArgumentList() );
+
+ param.setTypeSymbol( specialization.instantiate( args ) );
+
+ function.addParameter( param );
+
+ return transformed;
+ }
+
+ static private TypeInfo transformTypeInfo( Object obj, Map argumentMap ){
+ TypeInfo info = null;
+ if( obj instanceof ISymbol ){
+ info = new TypeInfo( TypeInfo.t_type, 0, (ISymbol) obj );
+ } else {
+ info = (TypeInfo) obj;
+ }
+
+ if( argumentMap == null )
+ return info;
+
+ if( info.isType( TypeInfo.t_type ) &&
+ info.getTypeSymbol().isType( TypeInfo.t_templateParameter ) &&
+ argumentMap.containsKey( info.getTypeSymbol() ) )
+ {
+ TypeInfo newType = new TypeInfo( (TypeInfo) argumentMap.get( info.getTypeSymbol() ) );
+ if( info.hasPtrOperators() )
+ newType.addPtrOperator( info.getPtrOperators() );
+
+ return newType;
+ }
+
+ return info;
+ }
+
+ static protected List selectTemplateFunctions( Set templates, List arguments ) throws ParserSymbolTableException{
+ if( templates == null || templates.size() == 0 )
+ return null;
+
+ List instances = new LinkedList();
+
+ Iterator iter = templates.iterator();
+
+ while( iter.hasNext() ){
+ IParameterizedSymbol fn = (IParameterizedSymbol) iter.next();
+ ITemplateSymbol template = (ITemplateSymbol) fn.getContainingSymbol();
+
+ Map map = deduceTemplateArguments( template, arguments );
+
+ if( map == null )
+ continue;
+
+ Iterator paramIter = template.getParameterList().iterator();
+ List instanceArgs = new LinkedList();
+ while( paramIter.hasNext() ){
+ instanceArgs.add( map.get( paramIter.next() ) );
+ }
+
+ IContainerSymbol instance = (IContainerSymbol) template.instantiate( instanceArgs );
+
+ if( instance != null ){
+ instances.add( instance );
+ }
+ }
+
+ return instances;
+ }
+
+ /**
+ * @param look
+ * @param parameters
+ * @param arguments
+ * @throws ParserSymbolTableException
+ */
+ static protected ITemplateSymbol selectTemplateOrSpecialization( ITemplateSymbol template, List parameters, List arguments ) throws ParserSymbolTableException {
+ if( template != null && template instanceof ITemplateSymbol ){
+ //primary definition or specialization?
+ boolean forPrimary = true;
+
+ if( arguments != null ){
+ if( !parameters.isEmpty() ){
+ if( arguments.size() != parameters.size() ){
+ forPrimary = false;
+ } else {
+ Iterator pIter = parameters.iterator();
+ Iterator aIter = arguments.iterator();
+ while( pIter.hasNext() ){
+ if( pIter.next() != ((TypeInfo) aIter.next()).getTypeSymbol() ){
+ forPrimary = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ ITemplateSymbol primary = (ITemplateSymbol) template;
+
+ if( forPrimary ){
+ //make sure parameters match up with found template
+ if( checkTemplateParameterListsAreEquivalent( primary.getParameterList(), parameters ) ){
+ return template;
+ } else {
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateParameter );
+ }
+ }
+
+ //specialization
+ if( parameters.isEmpty() && !arguments.isEmpty() ){
+ ISpecializedSymbol spec = primary.findSpecialization( parameters, arguments );
+
+ if( spec == null ){
+ spec = template.getSymbolTable().newSpecializedSymbol( primary.getName() );
+
+ Iterator iter = arguments.iterator();
+ while( iter.hasNext() ){
+ spec.addArgument( (TypeInfo) iter.next() );
+ }
+
+ primary.addSpecialization( spec );
+ }
+
+ return spec;
+ }
+
+ //partial specialization
+ ISpecializedSymbol spec = findPartialSpecialization( template, parameters, arguments );
+
+ if( spec != null )
+ return spec;
+
+ //TODO
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
+
+ }
+ return null;
+ }
+
+ static private boolean checkTemplateParameterListsAreEquivalent( List p1, List p2 ){
+ if( p1.size() != p2.size() ){
+ return false;
+ }
+
+ Iterator iter1 = p1.iterator();
+ Iterator iter2 = p2.iterator();
+ while( iter1.hasNext() ){
+ ISymbol param1 = (ISymbol) iter1.next();
+ ISymbol param2 = (ISymbol) iter2.next();
+ if( param1.getTypeInfo().getTemplateParameterType() != param2.getTypeInfo().getTemplateParameterType() ){
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static private boolean checkTemplateArgumentListsAreEquivalent( List p1, List p2, List a1, List a2 ){
+ if( a1.size() != a2.size() || p1.size() != p2.size() ){
+ return false;
+ }
+
+ Map m [] = { new HashMap(), new HashMap() };
+
+ for( List list = p1; list != null; list = p2 ){
+ Iterator i = list.iterator();
+ int index = 0;
+ while( i.hasNext() ){
+ m[ ( list == p2 )? 1 : 0 ].put( i.next(), new Integer( index++ ) );
+ }
+
+ if( list == p2 ){
+ break;
+ }
+ }
+
+ Iterator i1 = a1.iterator();
+ Iterator i2 = a2.iterator();
+ while( i1.hasNext() ){
+ TypeInfo t1 = (TypeInfo) i1.next();
+ TypeInfo t2 = (TypeInfo) i2.next();
+
+ if( t1.equals( t2 ) ){
+ continue;
+ } else if( t1.isType( TypeInfo.t_type ) && t2.isType( TypeInfo.t_type ) ) {
+ ISymbol s1 = t1.getTypeSymbol(), s2 = t2.getTypeSymbol();
+ if( m[0].containsKey( s1 ) && m[1].containsKey( s2 ) && m[0].get( s1 ).equals( m[1].get( s2 ) ) )
+ continue;
+ }
+
+ return false;
+ }
+ return true;
+ }
+
+ static private ISpecializedSymbol findPartialSpecialization( ITemplateSymbol template, List parameters, List arguments ){
+
+ Iterator iter = template.getSpecializations().iterator();
+ ISpecializedSymbol spec = null;
+ while( iter.hasNext() ){
+ spec = (ISpecializedSymbol) iter.next();
+
+ if( ! checkTemplateParameterListsAreEquivalent( spec.getParameterList(), parameters ) ){
+ continue;
+ }
+
+ if( checkTemplateArgumentListsAreEquivalent( spec.getParameterList(), parameters,
+ spec.getArgumentList(), arguments ) )
+ {
+ return spec;
+ }
+ }
+ return null;
+ }
+
+ static protected ISymbol translateParameterForDefinition ( ISymbol templatedSymbol, ISymbol param, Map defnMap ){
+ if( defnMap == null ){
+ return param;
+ }
+
+ ISymbol mappedParam = param;
+ while( mappedParam.isTemplateInstance() ){
+ mappedParam = mappedParam.getInstantiatedSymbol();
+ }
+
+ if( defnMap.containsKey( templatedSymbol ) ){
+ Map map = (Map) defnMap.get( templatedSymbol );
+
+ Iterator i = map.keySet().iterator();
+ while( i.hasNext() ){
+ ISymbol key = (ISymbol) i.next();
+ if( map.get( key ) == mappedParam ){
+ return key;
+ }
+ }
+ }
+
+ return param;
+ }
+
+ /**
+ * 14.6.1-1 (2) Within the scope of a class template (class template specialization or partial specialization), when
+ * the name of the template is neither qualified nor followed by <. it is equivalent to the name of the template
+ * followed by the template-parameters (template-arguments) enclosed in <>
+ *
+ * @param symbol
+ * @return
+ */
+ static protected ISymbol instantiateWithinTemplateScope( IContainerSymbol container, ITemplateSymbol symbol )
+ {
+ if( symbol.getTemplatedSymbol().isType( TypeInfo.t_function ) ){
+ return symbol;
+ }
+
+ IDeferredTemplateInstance instance = null;
+
+ IContainerSymbol containing = container.getContainingSymbol();
+ boolean instantiate = false;
+ while( containing != null ){
+ if( containing == symbol ){
+ instantiate = true;
+ break;
+ }
+
+ containing = containing.getContainingSymbol();
+ if( containing != null && !containing.isTemplateMember() || !containing.isType( TypeInfo.t_template ) ){
+ containing = null;
+ }
+ }
+
+ if( instantiate ){
+ if( symbol instanceof ISpecializedSymbol ){
+ ISpecializedSymbol spec = (ISpecializedSymbol) symbol;
+ instance = spec.deferredInstance( spec.getArgumentList() );
+ } else {
+ ITemplateSymbol template = (ITemplateSymbol) symbol;
+ Iterator iter = template.getParameterList().iterator();
+ List args = new LinkedList();
+ while( iter.hasNext() ){
+ args.add( new TypeInfo( TypeInfo.t_type, 0, (ISymbol) iter.next() ) );
+ }
+
+ instance = template.deferredInstance( args );
+ }
+ }
+
+ return ( instance != null ) ? instance : (ISymbol) symbol;
+ }
+
+ static protected boolean alreadyHasTemplateParameter( IContainerSymbol container, String name ){
+ while( container != null ){
+ if( container instanceof ITemplateSymbol ){
+ ITemplateSymbol template = (ITemplateSymbol) container;
+ if( template.getParameterMap().containsKey( name ) ){
+ return true;
+ }
+ }
+ container = container.getContainingSymbol();
+ }
+ return false;
+ }
+
+ static protected boolean canAddTemplate( IContainerSymbol containing, ITemplateSymbol template ){
+ //14-2 A template-declaration can appear only as a namespace scope or class scope declaration
+ if( !containing.isType( TypeInfo.t_namespace ) && !containing.isType( TypeInfo.t_class, TypeInfo.t_union ) ){
+ return false;
+ }
+
+ //14.5.2-3 A member function template shall not be virtual
+ if( containing.isTemplateMember() && containing.getContainingSymbol().isType( TypeInfo.t_template ) ){
+ ISymbol symbol = template.getTemplatedSymbol();
+ if( symbol != null && symbol.isType( TypeInfo.t_function ) && symbol.getTypeInfo().checkBit( TypeInfo.isVirtual ) ){
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java
diff -N parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,163 @@
+/**********************************************************************
+ * Copyright (c) 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.internal.core.parser.pst;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.LookupData;
+
+/**
+ * @author aniefer
+ */
+public class TemplateFactory implements ITemplateFactory {
+
+ protected TemplateFactory( ITemplateSymbol primary, List params ){
+ templatesList = new LinkedList();
+ templatesList.add( primary );
+
+ parametersList = new LinkedList();
+ parametersList.add( new LinkedList( params ) );
+ }
+
+ protected TemplateFactory( List templates, List params ){
+ templatesList = templates;
+ parametersList = params;
+ }
+
+ public ITemplateFactory lookupTemplateForMemberDefinition( String name, List parameters, List arguments ) throws ParserSymbolTableException{
+ if( templatesList == null || templatesList.isEmpty() ){
+ return null;
+ }
+
+ ITemplateSymbol template = (ITemplateSymbol) templatesList.get( 0 );
+ IContainerSymbol symbol = template.getTemplatedSymbol();
+ LookupData data = new LookupData( name, TypeInfo.t_any ); //, null );
+
+ ParserSymbolTable.lookup( data, symbol );
+
+ ISymbol look = ParserSymbolTable.resolveAmbiguities( data );
+
+ if( look.getContainingSymbol() instanceof ITemplateSymbol ){
+ template = TemplateEngine.selectTemplateOrSpecialization( (ITemplateSymbol) look.getContainingSymbol(), parameters, arguments );
+ if( template != null ){
+ List newTemplatesList = new LinkedList( templatesList );
+ List newParamsList = new LinkedList( parametersList );
+
+ newTemplatesList.add( template );
+ newParamsList.add( new LinkedList( parameters ) );
+
+ return new TemplateFactory( newTemplatesList, newParamsList );
+ }
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#addSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
+ */
+ public void addSymbol( ISymbol symbol ) throws ParserSymbolTableException {
+ Iterator templatesIter = getTemplatesList().iterator();
+ Iterator parametersIter = getParametersList().iterator();
+
+ while( templatesIter.hasNext() ){
+ Map defnMap = new HashMap();
+
+ ITemplateSymbol template = (ITemplateSymbol) templatesIter.next();
+
+ Iterator tempIter = template.getParameterList().iterator();
+
+ if( !parametersIter.hasNext() ){
+ throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError );
+ }
+
+ List params = (List) parametersIter.next();
+ Iterator iter = params.iterator();
+
+ while( iter.hasNext() ){
+ ISymbol param = (ISymbol) iter.next();
+ ISymbol tempParam = (ISymbol) tempIter.next();
+ defnMap.put( param, tempParam );
+ }
+
+ template.getDefinitionParameterMap().put( symbol, defnMap );
+ }
+
+ ITemplateSymbol template = (ITemplateSymbol) getTemplatesList().get( getTemplatesList().size() - 1 );
+ IContainerSymbol container = (IContainerSymbol) template.getTemplatedSymbol();
+
+ if( container.isForwardDeclaration() && container.getTypeSymbol() == symbol ){
+ template.addSymbol( symbol );
+ } else {
+ container.addSymbol( symbol );
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#lookupMemberForDefinition(java.lang.String)
+ */
+ public ISymbol lookupMemberForDefinition(String name) throws ParserSymbolTableException {
+ Set keys = getPrimaryTemplate().getContainedSymbols().keySet();
+ IContainerSymbol symbol = (IContainerSymbol) getPrimaryTemplate().getContainedSymbols().get( keys.iterator().next() );
+
+ return (ISymbol) symbol.lookupMemberForDefinition( name );
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#lookupMemberFunctionForDefinition(java.lang.String, java.util.List)
+ */
+ public IParameterizedSymbol lookupMemberFunctionForDefinition( String name, List params) throws ParserSymbolTableException {
+ Set keys = getPrimaryTemplate().getContainedSymbols().keySet();
+ IContainerSymbol symbol = (IContainerSymbol) getPrimaryTemplate().getContainedSymbols().get( keys.iterator().next() );
+
+ return (IParameterizedSymbol) symbol.lookupMethodForDefinition( name, params );
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#getPrimaryTemplate()
+ */
+ public ITemplateSymbol getPrimaryTemplate() {
+ return (ITemplateSymbol) templatesList.get( 0 );
+ }
+
+ public ISymbol lookupParam( String name ) throws ParserSymbolTableException{
+ Iterator iter = getParametersList().iterator();
+
+ while( iter.hasNext() ){
+ List list = (List) iter.next();
+ Iterator params = list.iterator();
+ while( params.hasNext() ){
+ ISymbol p = (ISymbol) params.next();
+ if( p.getName().equals( name ) ){
+ return p;
+ }
+ }
+ }
+
+ return getPrimaryTemplate().lookup( name );
+ }
+
+
+ protected List getTemplatesList() {
+ return templatesList;
+ }
+ protected List getParametersList() {
+ return parametersList;
+ }
+
+ private List templatesList;
+ private List parametersList;
+}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java
diff -N parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,318 @@
+/**********************************************************************
+ * Copyright (c) 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.internal.core.parser.pst;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
+
+/**
+ * @author aniefer
+ *
+ * To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymbol {
+
+ protected TemplateSymbol ( ParserSymbolTable table, String name ){
+ super( table, name, TypeInfo.t_template );
+ }
+
+ protected TemplateSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
+ super( table, name, obj );
+ }
+
+ public Object clone(){
+ TemplateSymbol copy = (TemplateSymbol)super.clone();
+
+ //copy._specializations = ( _specializations != null ) ? (LinkedList) _specializations.clone() : null;
+
+ copy._defnParameterMap = ( _defnParameterMap != null ) ? (HashMap) _defnParameterMap.clone() : null;
+ copy._instantiations = ( _instantiations != null ) ? (HashMap) _instantiations.clone() : null;
+
+
+ return copy;
+ }
+
+ public IContainerSymbol getTemplatedSymbol(){
+ Iterator iter = getContentsIterator();
+ if( iter.hasNext() ){
+ IContainerSymbol contained = (IContainerSymbol) iter.next();
+ if( contained.isForwardDeclaration() && contained.getTypeSymbol() != null ){
+ ISymbol symbol = contained.getTypeSymbol();
+ if( symbol.getContainingSymbol() == this )
+ return (IContainerSymbol) symbol;
+ }
+ return contained;
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#instantiate(java.util.List)
+ */
+ public ISymbol instantiate( List arguments ) throws ParserSymbolTableException{
+ if( getType() != TypeInfo.t_template &&
+ ( getType() != TypeInfo.t_templateParameter ||
+ getTypeInfo().getTemplateParameterType() != TypeInfo.t_template ) )
+ {
+ return null;
+ }
+
+ ITemplateSymbol template = TemplateEngine.matchTemplatePartialSpecialization( this, arguments );
+
+ if( template != null && template instanceof ISpecializedSymbol ){
+ return template.instantiate( arguments );
+ }
+
+ if( template == null ){
+ template = this;
+ }
+
+ List paramList = template.getParameterList();
+ int numParams = ( paramList != null ) ? paramList.size() : 0;
+
+ if( numParams == 0 ){
+ return null;
+ }
+
+ HashMap map = new HashMap();
+ Iterator paramIter = paramList.iterator();
+ Iterator argIter = arguments.iterator();
+
+ ISymbol param = null;
+ TypeInfo arg = null;
+
+ List actualArgs = new LinkedList();
+
+ ISymbol templatedSymbol = template.getTemplatedSymbol();
+ while( templatedSymbol != null && templatedSymbol.isTemplateInstance() ){
+ templatedSymbol = templatedSymbol.getInstantiatedSymbol();
+ }
+
+ for( int i = 0; i < numParams; i++ ){
+ param = (ISymbol) paramIter.next();
+
+ param = TemplateEngine.translateParameterForDefinition ( templatedSymbol, param, getDefinitionParameterMap() );
+
+ if( argIter.hasNext() ){
+ arg = (TypeInfo) argIter.next();
+
+ //If the argument is a template parameter, we can't instantiate yet, defer for later
+ if( arg.isType( TypeInfo.t_type ) && arg.getTypeSymbol().isType( TypeInfo.t_templateParameter ) ){
+ return deferredInstance( arguments );
+ }
+ } else {
+ Object obj = param.getTypeInfo().getDefault();
+ if( obj != null && obj instanceof TypeInfo ){
+ arg = (TypeInfo) obj;
+ if( arg.isType( TypeInfo.t_type ) && arg.getTypeSymbol().isType( TypeInfo.t_templateParameter ) ){
+ if( map.containsKey( arg.getTypeSymbol() ) ){
+ arg = (TypeInfo) map.get( arg.getTypeSymbol() );
+ } else {
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument );
+ }
+ }
+ } else {
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument );
+ }
+ }
+
+ if( TemplateEngine.matchTemplateParameterAndArgument( param, arg ) ){
+ map.put( param, arg );
+ actualArgs.add( arg );
+ } else {
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument );
+ }
+ }
+
+ IContainerSymbol instance = findInstantiation( actualArgs );
+ if( instance != null ){
+ return instance;
+ } else {
+ if( template.isType( TypeInfo.t_templateParameter ) ){
+ //template template parameter. must defer instantiation
+ return deferredInstance( arguments );
+ }
+
+ IContainerSymbol symbol = template.getTemplatedSymbol();
+ instance = (IContainerSymbol) symbol.instantiate( template, map );
+ addInstantiation( instance, actualArgs );
+ return instance;
+ }
+ }
+
+
+ public void addParameter( ISymbol param ) {
+ throw new ParserSymbolTableError( ParserSymbolTableError.r_OperationNotSupported );
+ }
+
+ public void addTemplateParameter( ISymbol param ) throws ParserSymbolTableException {
+ if( isType( TypeInfo.t_template ) ){
+ if( !isAllowableTemplateParameter( param ) ){
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateParameter );
+ }
+ modifyTemplateParameter( param );
+ }
+
+ super.addParameter( param );
+ }
+
+ private boolean isAllowableTemplateParameter( ISymbol param ) {
+ if( !param.isType( TypeInfo.t_templateParameter ) )
+ return false;
+
+ if( param.getName().equals( getName() ) ){
+ return false;
+ }
+
+ if( param.getTypeInfo().getTemplateParameterType() != TypeInfo.t_typeName &&
+ param.getTypeInfo().getTemplateParameterType() != TypeInfo.t_template )
+ {
+ if( param.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
+ param.isType( TypeInfo.t_enumerator ) )
+ {
+ return true;
+ }
+
+ //a non-tpye template parameter shall have one of the following:
+ //integral or enumeration type
+ //pointer to object or pointer to function
+ //reference to object or reference to function
+ //pointer to member
+
+ //A non-type template-parameter shall not be declared to have floating point, class or void type
+ if( param.isType( TypeInfo.t_float ) ||
+ param.isType( TypeInfo.t_double )||
+ param.isType( TypeInfo.t_class ) ||
+ param.isType( TypeInfo.t_void ) )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void modifyTemplateParameter( ISymbol param ){
+ List ptrs = param.getPtrOperators();
+ if( ptrs.size() > 0 ){
+ PtrOp op = (PtrOp) ptrs.get( 0 );
+ if( op.getType() == PtrOp.t_array ){
+ op.setType( PtrOp.t_pointer );
+ }
+ } else if ( param.isType( TypeInfo.t_type ) && param.getTypeSymbol().isType( TypeInfo.t_function ) ){
+ param.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
+ }
+ }
+
+
+
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasSpecializations()
+ */
+ public boolean hasSpecializations(){
+ return ( _specializations != null && !_specializations.isEmpty() );
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addSpecialization(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
+ */
+ public void addSpecialization( ISpecializedSymbol spec ){
+ List specializationList = getSpecializations();
+ specializationList.add( spec );
+
+ spec.setContainingSymbol( getContainingSymbol() );
+ spec.setPrimaryTemplate( this );
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getSpecializations()
+ */
+ public List getSpecializations() {
+ if( _specializations == null ){
+ _specializations = new LinkedList();
+ }
+ return _specializations;
+ }
+
+ public void addInstantiation( IContainerSymbol instance, List args ){
+ List key = new LinkedList( args );
+ if( _instantiations == null ){
+ _instantiations = new HashMap();
+ }
+ _instantiations.put( key, instance );
+ }
+
+ public IContainerSymbol findInstantiation( List arguments ){
+ if( _instantiations == null ){
+ return null;
+ }
+
+ //TODO: we could optimize this by doing something other than a linear search.
+ Iterator iter = _instantiations.keySet().iterator();
+ List args = null;
+ while( iter.hasNext() ){
+ args = (List) iter.next();
+
+ if( args.equals( arguments ) ){
+ return (IContainerSymbol) _instantiations.get( args );
+ }
+ }
+ return null;
+ }
+
+ public List findArgumentsFor( IContainerSymbol instance ){
+ if( instance == null || !instance.isTemplateInstance() )
+ return null;
+
+ ITemplateSymbol template = (ITemplateSymbol) instance.getInstantiatedSymbol().getContainingSymbol();
+ if( template != this )
+ return null;
+
+ Iterator iter = _instantiations.keySet().iterator();
+ while( iter.hasNext() ){
+ List args = (List) iter.next();
+ if( _instantiations.get( args ) == instance ){
+ return args;
+ }
+ }
+
+ return null;
+ }
+
+ public Map getDefinitionParameterMap(){
+ if( _defnParameterMap == null ){
+ _defnParameterMap = new HashMap();
+ }
+ return _defnParameterMap;
+ }
+
+ public IDeferredTemplateInstance deferredInstance( List args ){
+ return new DeferredTemplateInstance( getSymbolTable(), this, args );
+ }
+
+ public ISpecializedSymbol findSpecialization(List parameters, List arguments) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+ private LinkedList _specializations; //template specializations
+ private HashMap _defnParameterMap; //members could be defined with different template parameter names
+ private HashMap _instantiations;
+
+}
Index: ChangeLog
===================================================================
retrieving revision 1.182
diff -u -r1.182 ChangeLog
--- ChangeLog 10 Feb 2004 15:33:41 -0000 1.182
+++ ChangeLog 10 Feb 2004 19:18:33 -0000
@@ -1,3 +1,7 @@
+2004-02-10 Andrew Niefer
+ Added new File: ParserSymbolTableTemplateTests.java (contains 30 new tests)
+ Added new File: FailingTemplateTests.java (contains 5 test stubs for failing cases)
+
2004-02-10 John Camelon
Added testBug47682() to QuickParseASTTests.java.
Index: parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java
===================================================================
retrieving revision 1.34
diff -u -r1.34 ParserSymbolTableTest.java
--- parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java 27 Jan 2004 02:36:30 -0000 1.34
+++ parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java 10 Feb 2004 19:18:36 -0000
@@ -41,7 +41,6 @@
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException;
import org.eclipse.cdt.internal.core.parser.pst.StandardSymbolExtension;
-import org.eclipse.cdt.internal.core.parser.pst.TemplateInstance;
import org.eclipse.cdt.internal.core.parser.pst.TypeFilter;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Mark;
@@ -1968,391 +1967,6 @@
assertEquals( C.getUsingDirectives().size(), 1 );
table.rollBack( mark );
assertEquals( C.getUsingDirectives().size(), 0 );
- }
-
- /**
- *
- * @throws Exception
- *
- * template < class T > class A : public T {};
- *
- * class B
- * {
- * int i;
- * }
- *
- * A<B> a;
- * a.i; //finds B::i;
- */
- public void testTemplateParameterAsParent() throws Exception{
- newTable();
-
- IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template );
- ISymbol param = table.newSymbol( "T", TypeInfo.t_undef );
- template.addParameter( param );
-
- IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
- template.addSymbol( A );
- A.addParent( param );
-
- table.getCompilationUnit().addSymbol( template );
-
- IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
- ISymbol i = table.newSymbol( "i", TypeInfo.t_int );
- B.addSymbol( i );
-
- TypeInfo type = new TypeInfo( TypeInfo.t_class, 0, B );
- LinkedList args = new LinkedList();
- args.add( type );
-
- TemplateInstance instance = table.getCompilationUnit().templateLookup( "A", args );
- assertEquals( instance.getInstantiatedSymbol(), A );
-
- ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
- a.setTypeSymbol( instance );
-
- table.getCompilationUnit().addSymbol( a );
-
- ISymbol look = table.getCompilationUnit().lookup( "a" );
-
- assertEquals( look, a );
-
- ISymbol symbol = a.getTypeSymbol();
- assertEquals( symbol, instance );
-
- look = ((IContainerSymbol)instance.getInstantiatedSymbol()).lookup( "i" );
- assertEquals( look, i );
- }
-
- /**
- *
- * @throws Exception
- *
- * template < class T > class A { T t; }
- * class B : public A< int > { }
- *
- * B b;
- * b.t; //finds A::t, will be type int
- */
- public void testTemplateInstanceAsParent() throws Exception{
- newTable();
-
- IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template );
- ISymbol param = table.newSymbol( "T", TypeInfo.t_undef );
- template.addParameter( param );
-
- IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
- ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
-
- ISymbol look = template.lookup( "T" );
- assertEquals( look, param );
-
- t.setTypeSymbol( param );
-
- template.addSymbol( A );
- A.addSymbol( t );
- table.getCompilationUnit().addSymbol( template );
-
- IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
-
- TypeInfo type = new TypeInfo( TypeInfo.t_int, 0 , null );
- LinkedList args = new LinkedList();
- args.add( type );
-
- look = table.getCompilationUnit().templateLookup( "A", args );
- assertTrue( look instanceof TemplateInstance );
-
- B.addParent( look );
- table.getCompilationUnit().addSymbol( B );
-
- ISymbol b = table.newSymbol( "b", TypeInfo.t_type );
- b.setTypeSymbol( B );
- table.getCompilationUnit().addSymbol( b );
-
- look = table.getCompilationUnit().lookup( "b" );
- assertEquals( look, b );
-
- look = ((IDerivableContainerSymbol) b.getTypeSymbol()).lookup( "t" );
- assertTrue( look instanceof TemplateInstance );
-
- TemplateInstance instance = (TemplateInstance) look;
- assertEquals( instance.getInstantiatedSymbol(), t );
- assertTrue( instance.isType( TypeInfo.t_int ) );
-
- }
-
- /**
- * The scope of a template-parameter extends from its point of declaration
- * until the end of its template. In particular, a template parameter can be used
- * in the declaration of a subsequent template-parameter and its default arguments.
- * @throws Exception
- *
- * template< class T, class U = T > class X
- * {
- * T t;
- * U u;
- * };
- *
- * X< char > x;
- * x.t;
- * x.u;
- */
- public void testTemplateParameterDefaults() throws Exception{
- newTable();
-
- IParameterizedSymbol template = table.newParameterizedSymbol( "X", TypeInfo.t_template );
-
- ISymbol paramT = table.newSymbol( "T", TypeInfo.t_undef );
- template.addParameter( paramT );
-
- ISymbol look = template.lookup( "T" );
- assertEquals( look, paramT );
- ISymbol paramU = table.newSymbol( "U", TypeInfo.t_undef );
- paramU.getTypeInfo().setDefault( new TypeInfo( TypeInfo.t_type, 0, look ) );
- template.addParameter( paramU );
-
- IDerivableContainerSymbol X = table.newDerivableContainerSymbol( "X", TypeInfo.t_class );
- template.addSymbol( X );
-
- look = X.lookup( "T" );
- assertEquals( look, paramT );
- ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
- t.setTypeSymbol( look );
- X.addSymbol( t );
-
- look = X.lookup( "U" );
- assertEquals( look, paramU );
- ISymbol u = table.newSymbol( "u", TypeInfo.t_type );
- u.setTypeSymbol( look );
- X.addSymbol( u );
-
- table.getCompilationUnit().addSymbol( template );
-
- TypeInfo type = new TypeInfo( TypeInfo.t_char, 0, null );
- LinkedList args = new LinkedList();
- args.add( type );
- look = table.getCompilationUnit().templateLookup( "X", args );
- assertTrue( look instanceof TemplateInstance );
-
- TemplateInstance instance = (TemplateInstance) look;
- look = ((IDerivableContainerSymbol) instance.getInstantiatedSymbol()).lookup( "t" );
-
- assertTrue( look instanceof TemplateInstance );
- assertTrue( ((TemplateInstance) look).isType( TypeInfo.t_char ) );
-
- look = ((IDerivableContainerSymbol) instance.getInstantiatedSymbol()).lookup( "u" );
- assertTrue( look instanceof TemplateInstance );
- assertTrue( ((TemplateInstance) look).isType( TypeInfo.t_char ) );
- }
-
- /**
- *
- * @throws Exception
- * template < class T > class A {
- * T t;
- * };
- * class B {};
- * void f( char c ) {}
- * void f( A<B> b ) { ... }
- * void f( int i ) {}
- *
- * A<B> a;
- * f( a ); //calls f( A<B> )
- *
- */
- public void testTemplateParameterAsFunctionArgument() throws Exception{
- newTable();
-
- IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template );
- ISymbol paramT = table.newSymbol( "T", TypeInfo.t_undef );
- template.addParameter( paramT );
-
- IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
- template.addSymbol( A );
-
- ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
- t.setTypeSymbol( paramT );
- A.addSymbol( t );
-
- table.getCompilationUnit().addSymbol( template );
-
- IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
- table.getCompilationUnit().addSymbol( B );
-
- IParameterizedSymbol temp = (IParameterizedSymbol) table.getCompilationUnit().lookup( "A" );
- assertEquals( temp, template );
-
- LinkedList args = new LinkedList();
- TypeInfo arg = new TypeInfo( TypeInfo.t_type, 0, B );
- args.add( arg );
-
- IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
- f1.addParameter( TypeInfo.t_char, 0, null, false );
- table.getCompilationUnit().addSymbol( f1 );
-
- IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
- f2.addParameter( temp.instantiate( args ), null, false );
- table.getCompilationUnit().addSymbol( f2 );
-
- IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
- f3.addParameter( TypeInfo.t_int, 0, null, false );
- table.getCompilationUnit().addSymbol( f3 );
-
- ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
- a.setTypeSymbol( temp.instantiate( args ) );
- table.getCompilationUnit().addSymbol( a );
-
- LinkedList params = new LinkedList();
- params.add( new TypeInfo( TypeInfo.t_type, 0, a ) );
-
- ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", params );
- assertEquals( look, f2 );
-
- }
-
- /**
- *
- * template < class T1, class T2, int I > class A {} //#1
- * template < class T, int I > class A < T, T*, I > {} //#2
- * template < class T1, class T2, int I > class A < T1*, T2, I > {} //#3
- * template < class T > class A < int, T*, 5 > {} //#4
- * template < class T1, class T2, int I > class A < T1, T2*, I > {} //#5
- *
- * A <int, int, 1> a1; //uses #1
- * A <int, int*, 1> a2; //uses #2, T is int, I is 1
- * A <int, char*, 5> a3; //uses #4, T is char
- * A <int, char*, 1> a4; //uses #5, T is int, T2 is char, I is1
- * A <int*, int*, 2> a5; //ambiguous, matches #3 & #5.
- *
- * @throws Exception
- */
- //TODO
- public void incompletetestTemplateSpecialization() throws Exception{
- newTable();
-
- IDerivableContainerSymbol cls1 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
- IDerivableContainerSymbol cls2 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
- IDerivableContainerSymbol cls3 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
- IDerivableContainerSymbol cls4 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
- IDerivableContainerSymbol cls5 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
-
- IParameterizedSymbol template1 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
- ISymbol T1p1 = table.newSymbol( "T1", TypeInfo.t_undef );
- ISymbol T1p2 = table.newSymbol( "T2", TypeInfo.t_undef );
- ISymbol T1p3 = table.newSymbol( "I", TypeInfo.t_int );
- template1.addParameter( T1p1 );
- template1.addParameter( T1p2 );
- template1.addParameter( T1p3 );
- template1.addSymbol( cls1 );
- table.getCompilationUnit().addSymbol( template1 );
-
- IParameterizedSymbol template2 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
- ISymbol T2p1 = table.newSymbol( "T", TypeInfo.t_undef );
- ISymbol T2p2 = table.newSymbol( "I", TypeInfo.t_int );
- template2.addParameter( T2p1 );
- template2.addParameter( T2p2 );
- ISymbol T2a1 = table.newSymbol( "T", TypeInfo.t_undef );
- ISymbol T2a2 = table.newSymbol( "T", TypeInfo.t_undef );
- T2a2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
- ISymbol T2a3 = table.newSymbol( "I", TypeInfo.t_int );
- template2.addArgument( T2a1 );
- template2.addArgument( T2a2 );
- template2.addArgument( T2a3 );
- template2.addSymbol( cls2 );
- template1.addSpecialization( template2 );
-
- IParameterizedSymbol template3 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
- ISymbol T3p1 = table.newSymbol( "T1", TypeInfo.t_undef );
- ISymbol T3p2 = table.newSymbol( "T2", TypeInfo.t_undef );
- ISymbol T3p3 = table.newSymbol( "I", TypeInfo.t_int );
- template3.addParameter( T3p1 );
- template3.addParameter( T3p2 );
- template3.addParameter( T3p3 );
- ISymbol T3a1 = table.newSymbol( "T1", TypeInfo.t_undef );
- T3a1.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
- ISymbol T3a2 = table.newSymbol( "T2", TypeInfo.t_undef );
- ISymbol T3a3 = table.newSymbol( "I", TypeInfo.t_int );
- template3.addArgument( T3a1 );
- template3.addArgument( T3a2 );
- template3.addArgument( T3a3 );
- template3.addSymbol( cls3 );
- template1.addSpecialization( template3 );
-
- IParameterizedSymbol template4 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
- ISymbol T4p1 = table.newSymbol( "T", TypeInfo.t_undef );
- template4.addParameter( T4p1 );
-
- ISymbol T4a1 = table.newSymbol( "", TypeInfo.t_int );
- ISymbol T4a2 = table.newSymbol( "T", TypeInfo.t_undef );
- T4a2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
- ISymbol T4a3 = table.newSymbol( "", TypeInfo.t_int );
- T4a3.getTypeInfo().setDefault( new Integer(5) );
- template4.addArgument( T4a1 );
- template4.addArgument( T4a2 );
- template4.addArgument( T4a3 );
- template4.addSymbol( cls4 );
- template1.addSpecialization( template4 );
-
- IParameterizedSymbol template5 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
- ISymbol T5p1 = table.newSymbol( "T1", TypeInfo.t_undef );
- ISymbol T5p2 = table.newSymbol( "T2", TypeInfo.t_undef );
- ISymbol T5p3 = table.newSymbol( "I", TypeInfo.t_int );
- template5.addParameter( T5p1 );
- template5.addParameter( T5p2 );
- template5.addParameter( T5p3 );
- ISymbol T5a1 = table.newSymbol( "T1", TypeInfo.t_undef );
- ISymbol T5a2 = table.newSymbol( "T2", TypeInfo.t_undef );
- T5a1.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
- ISymbol T5a3 = table.newSymbol( "I", TypeInfo.t_int );
- template5.addArgument( T5a1 );
- template5.addArgument( T5a2 );
- template5.addArgument( T5a3 );
- template5.addSymbol( cls5 );
- template1.addSpecialization( template5 );
-
- IParameterizedSymbol a = (IParameterizedSymbol) table.getCompilationUnit().lookup( "A" );
-
- LinkedList args = new LinkedList();
-
- args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
- args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
- args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) );
-
- TemplateInstance a1 = a.instantiate( args );
- assertEquals( a1.getInstantiatedSymbol(), cls1 );
-
- args.clear();
- args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
- args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
- args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) );
-
- TemplateInstance a2 = a.instantiate( args );
- assertEquals( a2.getInstantiatedSymbol(), cls2 );
-
- args.clear();
- args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
- args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
- args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(5) ) );
- TemplateInstance a3 = a.instantiate( args );
- assertEquals( a3.getInstantiatedSymbol(), cls4 );
-
- args.clear();
- args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
- args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
- args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) );
- TemplateInstance a4 = a.instantiate( args );
- assertEquals( a4.getInstantiatedSymbol(), cls5 );
-
- args.clear();
- args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
- args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
- args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(2) ) );
-
- try{
- a.instantiate( args );
- } catch ( ParserSymbolTableException e ){
- assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
- }
}
/**
Index: parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java
===================================================================
retrieving revision 1.13
diff -u -r1.13 ParserTestSuite.java
--- parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java 5 Feb 2004 03:57:49 -0000 1.13
+++ parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java 10 Feb 2004 19:18:36 -0000
@@ -30,6 +30,7 @@
suite.addTestSuite(ExprEvalTest.class);
suite.addTestSuite(QuickParseASTTests.class);
suite.addTestSuite(ParserSymbolTableTest.class);
+ suite.addTestSuite(ParserSymbolTableTemplateTests.class );
suite.addTestSuite(CModelElementsTests.class);
suite.addTestSuite(CompletionParseTest.class);
// suite.addTestSuite(MacroTests.class);
Index: parser/org/eclipse/cdt/core/parser/tests/FailingTemplateTests.java
===================================================================
RCS file: parser/org/eclipse/cdt/core/parser/tests/FailingTemplateTests.java
diff -N parser/org/eclipse/cdt/core/parser/tests/FailingTemplateTests.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/core/parser/tests/FailingTemplateTests.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,278 @@
+/**********************************************************************
+ * Copyright (c) 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.core.parser.tests;
+
+import junit.framework.TestCase;
+
+import org.eclipse.cdt.core.parser.ParserLanguage;
+import org.eclipse.cdt.core.parser.ParserMode;
+import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
+
+/**
+ * @author aniefer
+ */
+public class FailingTemplateTests extends TestCase {
+
+ public ParserSymbolTable table = null;
+
+ public FailingTemplateTests( String arg )
+ {
+ super( arg );
+ }
+
+ public ParserSymbolTable newTable(){
+ return newTable( ParserLanguage.CPP );
+ }
+
+ public ParserSymbolTable newTable( ParserLanguage language ){
+ table = new ParserSymbolTable( language, ParserMode.COMPLETE_PARSE );
+ return table;
+ }
+
+ /**
+ * These tests represent code snippets from the ANSI C++ spec
+ */
+
+
+ /**
+ * template < class T > struct A {
+ * void f( int );
+ * template < class T2 > void f( T2 );
+ * };
+ *
+ * template <> void A<int>::f(int) {} //non-template member
+ * template <> template<> void A<int>::f<>( int ) {} //template member
+ *
+ * int main(){
+ * A< char > ac;
+ * ac.f( 1 ); //non-template
+ * ac.f( 'c' ); //template
+ * ac.f<>(1); //template
+ * }
+ * @throws Exception
+ */
+ public void test_14_5_2__2_MemberFunctionTemplates() throws Exception{
+
+ //This code snippet is misleading, the two definitions are actually
+ //explicit specializations for T = int, and so would not be used
+ //below or A< char >. This needs to be rewritten.
+
+
+// newTable();
+//
+// ITemplateSymbol templateA = table.newTemplateSymbol( "A" );
+// ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+// templateA.addParameter( T );
+//
+// table.getCompilationUnit().addSymbol( templateA );
+//
+// IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_struct );
+// templateA.addSymbol( A );
+//
+// IParameterizedSymbol f1 = table.newParameterizedSymbol("f", TypeInfo.t_function );
+// f1.addParameter( TypeInfo.t_int, 0, null, false );
+// f1.setIsForwardDeclaration( true );
+// A.addSymbol( f1 );
+//
+// ITemplateSymbol templateF = table.newTemplateSymbol( "f" );
+// ISymbol T2 = table.newSymbol( "T2", TypeInfo.t_templateParameter );
+//
+// IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+// f2.addParameter( T2, null, false );
+// f2.setIsForwardDeclaration( true );
+// templateF.addSymbol( f2 );
+//
+// A.addSymbol( templateF );
+//
+// List args = new LinkedList();
+// args.add( new TypeInfo( TypeInfo.t_int,0, null ) );
+// ITemplateFactory factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", new LinkedList(), args );
+//
+// LinkedList params = new LinkedList();
+// params.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+// ISymbol look = factory.lookupMemberFunctionForDefinition( "f", params );
+// assertEquals( look, f1 );
+//
+// IParameterizedSymbol f1Def = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+// f1Def.addParameter( TypeInfo.t_int, 0, null, false );
+// look.setTypeSymbol( f1Def );
+// factory.addSymbol( f1Def );
+//
+// factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", new LinkedList(), args );
+// assertNotNull( factory );
+//
+// args.clear();
+// args.add(table.newSymbol( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_int ) );
+// factory = factory.lookupTemplateForMemberDefinition( "f", new LinkedList(), new LinkedList(), args );
+ }
+
+ /**
+ * A specialization of a member function template does not override a virtual
+ * function from a base class.
+ *
+ * class B {
+ * virtual void f( int );
+ * };
+ *
+ * class D : public B{
+ * template < class T > void f( T );
+ * };
+ *
+ * template <> void D::f< int > ( int ) {} //does not override B::f( int );
+ *
+ * void main(){
+ * D d;
+ * d.f( 1 ); //calls B::f( int )
+ * d.f<>( 1 ); //calls D::f<int>( int );
+ * }
+ * @throws Exception
+ */
+ public void test_14_5_2__4_VirtualBaseClassFunctions() throws Exception{
+ //bug 51483 TBD
+ }
+
+ /**
+ * template < class T = int > struct A {
+ * static int x;
+ * };
+ *
+ * template <> struct A< double > {}; //specialize T == double
+ * template <> struct A<> {}; //specialize T == int
+ *
+ * template <> int A< char >::x = 0;
+ * template <> int A< float >::x = 0.5;
+ *
+ * @throws Exception
+ */
+ public void test_14_7__3_ExplicitSpecialization() throws Exception{
+ //bug 51485
+ }
+
+ /**
+ * Each class template specialization instantiated from a template has its own
+ * copy of any static members
+ *
+ * template < class T > class X {
+ * static T s;
+ * }
+ *
+ * template < class T > T X<T>::s = 0;
+ *
+ * X<int> a; //a.s has type int
+ * X<char *> b; //b.s has type char *
+ * @throws Exception
+ */
+ public void test_14_7__6_ExplicitSpecializationStaticMembers() throws Exception{
+ //bug 51485
+ }
+
+ /**
+ * template<class T> void f( void (*) (T, int) );
+ * template<class T> void foo( T, int );
+ *
+ * void g( int, int );
+ * void g( char, int );
+ *
+ * void h( int, int, int );
+ * void h( char, int );
+ *
+ * int m(){
+ * f( &g ); //error, ambiguous
+ * f( &h ); //ok, h(char, int) is a unique match
+ * f( &foo ); //error, foo is a template
+ * }
+ *
+ * @throws Exception
+ */
+ public void test_14_8_2_4__16_ArgumentDeduction() throws Exception{
+ //This test will require resolving the address of an overloaded function
+ //without arguments. bug 45764
+
+// newTable();
+//
+// ITemplateSymbol templateF = table.newTemplateSymbol( "f" );
+//
+// ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+// templateF.addParameter( T );
+//
+// IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+//
+// IParameterizedSymbol fParam = table.newParameterizedSymbol( "", TypeInfo.t_function );
+// fParam.setIsTemplateMember( true );
+// fParam.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
+// fParam.addParameter( T, null, false );
+// fParam.addParameter( TypeInfo.t_int, 0, null, false );
+// fParam.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
+//
+// f.addParameter( fParam );
+//
+// templateF.addSymbol( f );
+// table.getCompilationUnit().addSymbol( templateF );
+//
+// ITemplateSymbol templateFoo = table.newTemplateSymbol( "foo" );
+// T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+// templateFoo.addParameter( T );
+//
+// IParameterizedSymbol foo = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
+// foo.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
+// foo.addParameter( T, null, false );
+// foo.addParameter( TypeInfo.t_int, 0, null, false );
+//
+// templateFoo.addSymbol( foo );
+// table.getCompilationUnit().addSymbol( templateFoo );
+//
+// IParameterizedSymbol g1 = table.newParameterizedSymbol( "g", TypeInfo.t_function );
+// g1.addParameter( TypeInfo.t_int, 0, null, false );
+// g1.addParameter( TypeInfo.t_int, 0, null, false );
+// table.getCompilationUnit().addSymbol( g1 );
+//
+// IParameterizedSymbol g2 = table.newParameterizedSymbol( "g", TypeInfo.t_function );
+// g2.addParameter( TypeInfo.t_char, 0, null, false );
+// g2.addParameter( TypeInfo.t_int, 0, null, false );
+// table.getCompilationUnit().addSymbol( g2 );
+//
+// IParameterizedSymbol h1 = table.newParameterizedSymbol( "h", TypeInfo.t_function );
+// h1.addParameter( TypeInfo.t_int, 0, null, false );
+// h1.addParameter( TypeInfo.t_int, 0, null, false );
+// h1.addParameter( TypeInfo.t_int, 0, null, false );
+// table.getCompilationUnit().addSymbol( h1 );
+//
+// IParameterizedSymbol h2 = table.newParameterizedSymbol( "h", TypeInfo.t_function );
+// h2.addParameter( TypeInfo.t_char, 0, null, false );
+// h2.addParameter( TypeInfo.t_int, 0, null, false );
+// table.getCompilationUnit().addSymbol( h2 );
+//
+//
+//
+// List args = new LinkedList();
+//
+//
+// ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", args );
+// assertTrue( look != null );
+// assertTrue( look.isTemplateInstance() );
+// assertEquals( look.getInstantiatedSymbol(), f );
+//
+// look = table.getCompilationUnit().lookup( "foo" );
+// assertTrue( look != null );
+// args.clear();
+// TypeInfo arg = new TypeInfo( TypeInfo.t_type, 0, look );
+// arg.addOperatorExpression( TypeInfo.OperatorExpression.addressof );
+// args.add( arg );
+//
+// try{
+// look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", args );
+// assertTrue( false );
+// }catch ( ParserSymbolTableException e ){
+// assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateParameter );
+// }
+
+ }
+}
Index: parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTemplateTests.java
===================================================================
RCS file: parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTemplateTests.java
diff -N parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTemplateTests.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTemplateTests.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,2193 @@
+/**********************************************************************
+ * Copyright (c) 2004 Rational Software Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * IBM Rational Software - Initial API and implementation
+***********************************************************************/
+package org.eclipse.cdt.core.parser.tests;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.eclipse.cdt.core.parser.ParserLanguage;
+import org.eclipse.cdt.core.parser.ParserMode;
+import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol;
+import org.eclipse.cdt.internal.core.parser.pst.IDeferredTemplateInstance;
+import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol;
+import org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol;
+import org.eclipse.cdt.internal.core.parser.pst.ISpecializedSymbol;
+import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
+import org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory;
+import org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol;
+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.TypeInfo;
+import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
+
+/**
+ * @author aniefer
+ */
+
+public class ParserSymbolTableTemplateTests extends TestCase {
+
+ public ParserSymbolTable table = null;
+
+ public ParserSymbolTableTemplateTests( String arg )
+ {
+ super( arg );
+ }
+
+ public ParserSymbolTable newTable(){
+ return newTable( ParserLanguage.CPP );
+ }
+
+ public ParserSymbolTable newTable( ParserLanguage language ){
+ table = new ParserSymbolTable( language, ParserMode.COMPLETE_PARSE );
+ return table;
+ }
+
+ /**
+ *
+ * @throws Exception
+ *
+ * template < class T > class A : public T {};
+ *
+ * class B
+ * {
+ * int i;
+ * }
+ *
+ * A<B> a;
+ * a.i; //finds B::i;
+ */
+ public void testTemplateParameterAsParent() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "A" );
+ ISymbol param = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( param );
+
+ IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ template.addSymbol( A );
+ A.addParent( param );
+
+ table.getCompilationUnit().addSymbol( template );
+
+ IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
+ ISymbol i = table.newSymbol( "i", TypeInfo.t_int );
+ B.addSymbol( i );
+ table.getCompilationUnit().addSymbol( B );
+
+ TypeInfo type = new TypeInfo( TypeInfo.t_type, 0, B );
+ LinkedList args = new LinkedList();
+ args.add( type );
+
+ IContainerSymbol instance = (IContainerSymbol) table.getCompilationUnit().lookupTemplate( "A", args );
+ assertEquals( instance.getInstantiatedSymbol(), A );
+
+ ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
+ a.setTypeSymbol( instance );
+
+ table.getCompilationUnit().addSymbol( a );
+
+ ISymbol look = table.getCompilationUnit().lookup( "a" );
+
+ assertEquals( look, a );
+
+ ISymbol symbol = a.getTypeSymbol();
+ assertEquals( symbol, instance );
+
+ look = instance.lookup( "i" );
+ assertEquals( look, i );
+ }
+
+ /**
+ *
+ * @throws Exception
+ *
+ * template < class T > class A { T t; }
+ * class B : public A< int > { }
+ *
+ * B b;
+ * b.t; //finds A::t, will be type int
+ */
+ public void testTemplateInstanceAsParent() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "A" );
+
+ ISymbol param = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( param );
+
+ IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ template.addSymbol( A );
+ table.getCompilationUnit().addSymbol( template );
+
+ ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
+ ISymbol look = template.lookup( "T" );
+ assertEquals( look, param );
+ t.setTypeSymbol( param );
+ A.addSymbol( t );
+
+ IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
+ table.getCompilationUnit().addSymbol( B );
+
+ TypeInfo type = new TypeInfo( TypeInfo.t_int, 0 , null );
+ LinkedList args = new LinkedList();
+ args.add( type );
+
+ look = table.getCompilationUnit().lookupTemplate( "A", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), A );
+
+ B.addParent( look );
+
+ ISymbol b = table.newSymbol( "b", TypeInfo.t_type );
+ b.setTypeSymbol( B );
+ table.getCompilationUnit().addSymbol( b );
+
+ look = table.getCompilationUnit().lookup( "b" );
+ assertEquals( look, b );
+
+ look = ((IDerivableContainerSymbol) b.getTypeSymbol()).lookup( "t" );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), t );
+ assertTrue( look.isType( TypeInfo.t_int ) );
+ }
+
+ /**
+ * The scope of a template-parameter extends from its point of declaration
+ * until the end of its template. In particular, a template parameter can be used
+ * in the declaration of a subsequent template-parameter and its default arguments.
+ * @throws Exception
+ *
+ * template< class T, class U = T > class X
+ * {
+ * T t;
+ * U u;
+ * };
+ *
+ * X< char > x;
+ * x.t;
+ * x.u;
+ */
+ public void testTemplateParameterDefaults() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "X" );
+
+ ISymbol paramT = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( paramT );
+
+ ISymbol look = template.lookup( "T" );
+ assertEquals( look, paramT );
+ ISymbol paramU = table.newSymbol( "U", TypeInfo.t_templateParameter );
+ paramU.getTypeInfo().setDefault( new TypeInfo( TypeInfo.t_type, 0, look ) );
+ template.addTemplateParameter( paramU );
+
+ IDerivableContainerSymbol X = table.newDerivableContainerSymbol( "X", TypeInfo.t_class );
+ template.addSymbol( X );
+
+ look = X.lookup( "T" );
+ assertEquals( look, paramT );
+ ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
+ t.setTypeSymbol( look );
+ X.addSymbol( t );
+
+ look = X.lookup( "U" );
+ assertEquals( look, paramU );
+ ISymbol u = table.newSymbol( "u", TypeInfo.t_type );
+ u.setTypeSymbol( look );
+ X.addSymbol( u );
+
+ table.getCompilationUnit().addSymbol( template );
+
+ TypeInfo type = new TypeInfo( TypeInfo.t_char, 0, null );
+ LinkedList args = new LinkedList();
+ args.add( type );
+ IDerivableContainerSymbol lookX = (IDerivableContainerSymbol) table.getCompilationUnit().lookupTemplate( "X", args );
+ assertTrue( lookX.isTemplateInstance() );
+ assertEquals( lookX.getInstantiatedSymbol(), X );
+
+
+ look = lookX.lookup( "t" );
+
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), t );
+ assertTrue( look.isType( TypeInfo.t_char ) );
+
+ look = lookX.lookup( "u" );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), u );
+ assertTrue( look.isType( TypeInfo.t_char ) );
+ }
+
+ /**
+ *
+ * @throws Exception
+ * template < class T > class A {
+ * T t;
+ * };
+ * class B {};
+ * void f( char c ) {}
+ * void f( A<B> b ) { ... }
+ * void f( int i ) {}
+ *
+ * A<B> a;
+ * f( a ); //calls f( A<B> )
+ *
+ */
+ public void testTemplateParameterAsFunctionArgument() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "A" );
+ ISymbol paramT = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( paramT );
+
+ IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ template.addSymbol( A );
+ table.getCompilationUnit().addSymbol( template );
+
+ ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
+ t.setTypeSymbol( paramT );
+ A.addSymbol( t );
+
+ IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
+ table.getCompilationUnit().addSymbol( B );
+
+ LinkedList args = new LinkedList();
+ TypeInfo arg = new TypeInfo( TypeInfo.t_type, 0, B );
+ args.add( arg );
+
+ IDerivableContainerSymbol lookA = (IDerivableContainerSymbol) table.getCompilationUnit().lookupTemplate( "A", args );
+ assertTrue( lookA.isTemplateInstance() );
+ assertEquals( lookA.getInstantiatedSymbol(), A );
+
+ IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f1.addParameter( TypeInfo.t_char, 0, null, false );
+ table.getCompilationUnit().addSymbol( f1 );
+
+ IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f2.addParameter( lookA, null, false );
+ table.getCompilationUnit().addSymbol( f2 );
+
+ IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f3.addParameter( TypeInfo.t_int, 0, null, false );
+ table.getCompilationUnit().addSymbol( f3 );
+
+ args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, B ) );
+ IDerivableContainerSymbol lookA2 = (IDerivableContainerSymbol) table.getCompilationUnit().lookupTemplate( "A", args );
+ assertEquals( lookA2, lookA );
+
+
+ ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
+ a.setTypeSymbol( lookA );
+ table.getCompilationUnit().addSymbol( a );
+
+ LinkedList params = new LinkedList();
+ params.add( new TypeInfo( TypeInfo.t_type, 0, a ) );
+
+ ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", params );
+ assertEquals( look, f2 );
+ }
+
+
+ /**
+ * class T { };
+ * int i;
+ *
+ * template< class T, T i > void f( T t )
+ * {
+ * T t1 = i; //template parameters T & i
+ * }
+ */
+ public void test_14_1__3_ParameterLookup() throws Exception{
+ newTable();
+
+ IDerivableContainerSymbol T = table.newDerivableContainerSymbol( "T", TypeInfo.t_class );
+ table.getCompilationUnit().addSymbol( T );
+
+ ISymbol i = table.newSymbol( "i", TypeInfo.t_int );
+ table.getCompilationUnit().addSymbol( i );
+
+ ITemplateSymbol template = table.newTemplateSymbol( "f" );
+
+ ISymbol paramT = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( paramT );
+
+ ISymbol parami = table.newSymbol( "i", TypeInfo.t_templateParameter );
+ parami.getTypeInfo().setTemplateParameterType( TypeInfo.t_type );
+
+ ISymbol look = template.lookup( "T" );
+
+ assertEquals( look, paramT );
+ parami.setTypeSymbol( look );
+ template.addTemplateParameter( parami );
+
+ IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ ISymbol fParam = table.newSymbol( "t", TypeInfo.t_type );
+ fParam.setTypeSymbol( paramT );
+ f.addParameter( fParam );
+
+ template.addSymbol( f );
+ table.getCompilationUnit().addSymbol( template );
+
+ look = f.lookup( "T" );
+ assertEquals( look, paramT );
+
+ look = f.lookup( "i" );
+ assertEquals( look, parami );
+ }
+
+ /**
+ * A non-type template parameter of type "array of T" or "function returning T" is adjusted to
+ * be of type "pointer to T" or "pointer to function returning T" respectively
+ *
+ * template < int *a > struct R {};
+ * template < int b[5] > struct S {};
+ *
+ * int *p;
+ * R<p> w; //ok
+ * S<p> x; //ok due to parameter adjustment
+ * int v[5];
+ * R<v> y; //ok due to implicit argument conversion
+ * S<v> z; //ok due to adjustment and conversion
+ * @throws Exception
+ */
+ public void test_14_1__8_ParameterAdjustment() throws Exception{
+ newTable();
+
+ ITemplateSymbol templateR = table.newTemplateSymbol( "R" );
+ table.getCompilationUnit().addSymbol( templateR );
+
+ ISymbol paramA = table.newSymbol( "a", TypeInfo.t_templateParameter );
+ paramA.getTypeInfo().setTemplateParameterType( TypeInfo.t_int );
+ paramA.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
+ templateR.addTemplateParameter( paramA );
+
+ IDerivableContainerSymbol R = table.newDerivableContainerSymbol( "R", TypeInfo.t_struct );
+ templateR.addSymbol( R );
+
+ ITemplateSymbol templateS = table.newTemplateSymbol( "S" );
+ table.getCompilationUnit().addSymbol( templateS );
+
+ ISymbol paramB = table.newSymbol( "b", TypeInfo.t_templateParameter );
+ paramB.getTypeInfo().setTemplateParameterType( TypeInfo.t_int );
+ paramB.addPtrOperator( new PtrOp( PtrOp.t_array ) );
+ templateS.addTemplateParameter( paramB );
+
+ IDerivableContainerSymbol S = table.newDerivableContainerSymbol( "S", TypeInfo.t_struct );
+ templateS.addSymbol( S );
+
+ ISymbol look = table.getCompilationUnit().lookup( "S" );
+ assertEquals( look, templateS );
+
+ Iterator iter = templateS.getParameterList().iterator();
+ ISymbol param = (ISymbol) iter.next();
+ assertFalse( iter.hasNext() );
+ iter = param.getTypeInfo().getPtrOperators().iterator();
+ PtrOp ptr = (PtrOp) iter.next();
+ assertFalse( iter.hasNext() );
+ assertEquals( ptr.getType(), PtrOp.t_pointer );
+
+ ISymbol p = table.newSymbol( "p", TypeInfo.t_int );
+ p.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
+ table.getCompilationUnit().addSymbol( p );
+
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, p ) );
+
+ look = table.getCompilationUnit().lookupTemplate( "R", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), R );
+
+ look = table.getCompilationUnit().lookupTemplate( "S", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), S );
+
+ ISymbol v = table.newSymbol( "v", TypeInfo.t_int );
+ v.addPtrOperator( new PtrOp( PtrOp.t_array ) );
+ table.getCompilationUnit().addSymbol( v );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, v ) );
+
+ look = table.getCompilationUnit().lookupTemplate( "R", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), R );
+
+ look = table.getCompilationUnit().lookupTemplate( "S", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), S );
+ }
+
+ /**
+ * When default template-arguments are used, a template-argument list can be empty. In that
+ * case, the empty <> brackets shall still be used as the template-argument list
+ *
+ * template< class T = char > class String;
+ * String <> * p; //ok, T = char
+ *
+ * @throws Exception
+ */
+ public void test_14_3__4_ParameterDefaults() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "String" );
+ table.getCompilationUnit().addSymbol( template );
+
+ ISymbol param = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ param.getTypeInfo().setDefault( new TypeInfo( TypeInfo.t_char, 0, null ) );
+ template.addTemplateParameter( param );
+
+ IDerivableContainerSymbol string = table.newDerivableContainerSymbol( "String", TypeInfo.t_class );
+ template.addSymbol( string );
+
+ List args = new LinkedList();
+ ISymbol look = table.getCompilationUnit().lookupTemplate( "String", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), string );
+ }
+
+ /**
+ * A local type, a type with no linkage, an unnamed type or a type compounded from
+ * any of these type shall not be used as a template-argument for a template-parameter
+ *
+ * template <class T> class X { };
+ * void f(){
+ * struct S { };
+ *
+ * X<S> x; //error
+ * X<S*> y; //error
+ * }
+ * @throws Exception
+ */
+ public void test_14_3_1__2_TypeArgumentRestrictions() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "X" );
+ table.getCompilationUnit().addSymbol( template );
+
+ template.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+ template.addSymbol( table.newDerivableContainerSymbol( "X", TypeInfo.t_class ) );
+
+ IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ table.getCompilationUnit().addSymbol( f );
+
+ IDerivableContainerSymbol S = table.newDerivableContainerSymbol( "S", TypeInfo.t_struct );
+ f.addSymbol( S );
+
+ ISymbol look = null;
+
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, S ) );
+ try{
+ look = f.lookupTemplate( "X", args );
+ assertTrue( false );
+ } catch( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateArgument );
+ }
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, S, new PtrOp( PtrOp.t_pointer ), false ) );
+ try{
+ look = f.lookupTemplate( "X", args );
+ assertTrue( false );
+ } catch( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateArgument );
+ }
+ }
+
+ /**
+ * A String literal is not an acceptable template-argument for a non-type, non-template parameter
+ * because a string literal is an object with internal linkage
+ *
+ * template< class T, char* p> class X {};
+ *
+ * X< int, "Studebaker" > x1; //error
+ *
+ * char p [] = "Vivisectionist";
+ * X< int, p > x2; //ok
+ *
+ * @throws Exception
+ */
+ public void test_14_3_2__2_NonTypeArgumentRestrictions() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "X" );
+ table.getCompilationUnit().addSymbol( template );
+
+ template.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+
+ ISymbol param2 = table.newSymbol( "p", TypeInfo.t_templateParameter );
+ param2.getTypeInfo().setTemplateParameterType( TypeInfo.t_char );
+ param2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
+ template.addTemplateParameter( param2 );
+
+ IDerivableContainerSymbol X = table.newDerivableContainerSymbol( "X", TypeInfo.t_class );
+ template.addSymbol( X );
+
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), "Studebaker" ) );
+
+ try{
+ table.getCompilationUnit().lookupTemplate( "X", args );
+ assertTrue( false );
+ } catch( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateArgument );
+ }
+
+ ISymbol p = table.newSymbol( "p", TypeInfo.t_char );
+ p.addPtrOperator( new PtrOp( PtrOp.t_array ) );
+ table.getCompilationUnit().addSymbol( p );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_type, 0, p ) );
+
+ ISymbol look = table.getCompilationUnit().lookupTemplate( "X", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), X );
+ }
+
+ /**
+ * names or addresses of non-static class members are not acceptable non-type template arguments
+ *
+ * template < int * p > class X {};
+ *
+ * struct S
+ * {
+ * int m;
+ * static int s;
+ * int * t;
+ * } s;
+ *
+ * X<&s.m> x1; //error, address of non-static member
+ * X<s.t> x2; //error, name of non-static member
+ * X<&S::s> x3; //ok, address of static member
+ *
+ * @throws Exception
+ */
+ public void test_14_3_2__3_NonTypeArgumentRestrictions() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "X" );
+ table.getCompilationUnit().addSymbol( template );
+
+ ISymbol param = table.newSymbol( "p", TypeInfo.t_templateParameter );
+ param.getTypeInfo().setTemplateParameterType( TypeInfo.t_int );
+ param.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
+ template.addTemplateParameter( param );
+
+ IDerivableContainerSymbol X = table.newDerivableContainerSymbol( "X", TypeInfo.t_class );
+ template.addSymbol( X );
+
+ IDerivableContainerSymbol S = table.newDerivableContainerSymbol( "S", TypeInfo.t_struct );
+ table.getCompilationUnit().addSymbol( S );
+
+ ISymbol m = table.newSymbol( "m", TypeInfo.t_int );
+ S.addSymbol( m );
+ ISymbol s = table.newSymbol( "s", TypeInfo.t_int );
+ s.getTypeInfo().setBit( true, TypeInfo.isStatic );
+ S.addSymbol( s );
+ ISymbol t = table.newSymbol( "t", TypeInfo.t_int );
+ t.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
+ S.addSymbol( t );
+
+ List args = new LinkedList();
+ TypeInfo arg = new TypeInfo( TypeInfo.t_type, 0, m );
+ arg.addOperatorExpression( TypeInfo.OperatorExpression.addressof );
+ args.add( arg );
+
+ try
+ {
+ table.getCompilationUnit().lookupTemplate( "X", args );
+ assertTrue( false );
+ } catch ( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateArgument );
+ }
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, t ) );
+
+ try
+ {
+ table.getCompilationUnit().lookupTemplate( "X", args );
+ assertTrue( false );
+ } catch ( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateArgument );
+ }
+
+ args.clear();
+ arg = new TypeInfo( TypeInfo.t_type, 0, s );
+ arg.addOperatorExpression( TypeInfo.OperatorExpression.addressof );
+ args.add( arg );
+
+ assertNotNull( table.getCompilationUnit().lookupTemplate( "X", args ) );
+ }
+
+ /**
+ * Tempories, unnamed lvalues, and named lvalues that do not have external linkage are
+ * not acceptable template-arguments when the corresponding template-parameter has
+ * reference type
+ *
+ * template< const int & I > struct B {};
+ *
+ * B<1> b1; //error, temporary would be required
+ * int c = 1;
+ * B<c> b2; //ok
+ * @throws Exception
+ */
+ public void test_14_3_2__4_NonTypeArgumentRestrictions() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "B" );
+ table.getCompilationUnit().addSymbol( template );
+
+ ISymbol I = table.newSymbol( "I", TypeInfo.t_templateParameter );
+ I.getTypeInfo().setTemplateParameterType( TypeInfo.t_int );
+ I.addPtrOperator( new PtrOp( PtrOp.t_reference, true, false ) );
+ template.addTemplateParameter( I );
+
+ IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_struct );
+ template.addSymbol( B );
+
+ List args = new LinkedList( );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, "1" ) );
+
+ try{
+ table.getCompilationUnit().lookupTemplate( "B", args );
+ assertTrue( false );
+ } catch ( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateArgument );
+ }
+
+ ISymbol c = table.newSymbol( "c", TypeInfo.t_int );
+ table.getCompilationUnit().addSymbol( c );
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, c ) );
+
+ ISymbol look = table.getCompilationUnit().lookupTemplate( "B", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), B );
+ }
+
+ /**
+ * template< class T > class A {
+ * int x;
+ * };
+ *
+ * template < class T > class A < T * > {
+ * long x;
+ * };
+ *
+ * template< template< class U > class V > class C{
+ * V< int > y;
+ * V< int * > z;
+ * }
+ *
+ * C< A > c; //V<int> uses primary template, so C.y.x is type int
+ * //V<int*> uses partial specialization, so C.z.x is type long
+ *
+ * @throws Exception
+ */
+ public void test_14_3_3__2_PartialSpecialization_TemplateTemplateParameter() throws Exception{
+ newTable();
+
+ ITemplateSymbol templateA = table.newTemplateSymbol( "A" );
+ table.getCompilationUnit().addSymbol( templateA );
+
+ templateA.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+
+ IDerivableContainerSymbol A1 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ templateA.addSymbol( A1 );
+
+ ISymbol x1 = table.newSymbol( "x", TypeInfo.t_int );
+ A1.addSymbol( x1 );
+
+ ISpecializedSymbol specialization = table.newSpecializedSymbol( "A" );
+ templateA.addSpecialization( specialization );
+
+ ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ specialization.addTemplateParameter( T );
+ specialization.addArgument( new TypeInfo( TypeInfo.t_type, 0, T, new PtrOp( PtrOp.t_pointer ), false ) );
+
+ IDerivableContainerSymbol A2 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ specialization.addSymbol( A2 );
+
+ ISymbol x2 = table.newSymbol( "x", TypeInfo.t_int );
+ x2.getTypeInfo().setBit( true, TypeInfo.isLong );
+ A2.addSymbol( x2 );
+
+ ITemplateSymbol templateC = table.newTemplateSymbol( "C" );
+ table.getCompilationUnit().addSymbol( templateC );
+
+ ITemplateSymbol templateV = table.newTemplateSymbol( "V" );
+ templateV.setType( TypeInfo.t_templateParameter );
+ templateV.getTypeInfo().setTemplateParameterType( TypeInfo.t_template );
+ ISymbol U = table.newSymbol( "U", TypeInfo.t_templateParameter );
+ templateV.addTemplateParameter( U );
+
+ templateC.addTemplateParameter( templateV );
+
+ IDerivableContainerSymbol C = table.newDerivableContainerSymbol( "C", TypeInfo.t_class );
+ templateC.addSymbol( C );
+
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+
+ ISymbol look = templateC.lookupTemplate( "V", args );
+ assertTrue( look != null );
+ assertTrue( look instanceof IDeferredTemplateInstance );
+
+ ISymbol y = table.newSymbol( "y", TypeInfo.t_type );
+ y.setTypeSymbol( look );
+
+ C.addSymbol( y );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
+
+ look = templateC.lookupTemplate( "V", args );
+ assertTrue( look != null );
+ assertTrue( look instanceof IDeferredTemplateInstance );
+
+ ISymbol z = table.newSymbol( "z", TypeInfo.t_type );
+ z.setTypeSymbol( look );
+ C.addSymbol( z );
+
+ look = table.getCompilationUnit().lookup( "A" );
+ assertEquals( look, templateA );
+
+ args.clear();
+ args.add ( new TypeInfo( TypeInfo.t_type, 0, look ) );
+ look = table.getCompilationUnit().lookupTemplate( "C", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), C );
+
+ IDerivableContainerSymbol lookC = (IDerivableContainerSymbol)look;
+ look = lookC.lookup( "y" );
+
+ assertEquals( look.getType(), TypeInfo.t_type );
+ ISymbol symbol = look.getTypeSymbol();
+ assertTrue( symbol instanceof IContainerSymbol );
+ assertTrue( symbol.isTemplateInstance() );
+ assertEquals( symbol.getInstantiatedSymbol(), A1 );
+
+ look = ((IContainerSymbol) symbol).lookup( "x" );
+
+ assertEquals( look.getType(), TypeInfo.t_int );
+ assertEquals( look.getTypeInfo().checkBit( TypeInfo.isLong ), false );
+
+ look = lookC.lookup( "z" );
+ assertEquals( look.getType(), TypeInfo.t_type );
+ symbol = look.getTypeSymbol();
+ assertTrue( symbol instanceof IContainerSymbol );
+ assertTrue( symbol.isTemplateInstance() );
+ assertEquals( symbol.getInstantiatedSymbol(), A2 );
+ look = ((IContainerSymbol)symbol).lookup( "x" );
+
+ assertEquals( look.getType(), TypeInfo.t_int );
+ assertEquals( look.getTypeInfo().checkBit( TypeInfo.isLong ), true );
+ }
+
+ /**
+ * template< class T1, class T2 > struct A {
+ * T1 f1();
+ * void f2();
+ * };
+ *
+ * template<class U, class V> U A< U, V >::f1() {} //ok
+ *
+ * template<class X, class Y> void A< Y, X >::f2() {} //error
+ *
+ *
+ * @throws Exception
+ */
+ public void test_14_5_1__3_MemberFunctions() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "A" );
+ ISymbol primaryT1 = table.newSymbol( "T1", TypeInfo.t_templateParameter );
+ ISymbol primaryT2 = table.newSymbol( "T2", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( primaryT1 );
+ template.addTemplateParameter( primaryT2 );
+
+ table.getCompilationUnit().addSymbol( template );
+
+ IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+
+ template.addSymbol( A );
+
+ IParameterizedSymbol f1 = table.newParameterizedSymbol( "f1", TypeInfo.t_function );
+ f1.setIsForwardDeclaration( true );
+ f1.setReturnType( primaryT1 );
+
+ IParameterizedSymbol f2 = table.newParameterizedSymbol( "f2", TypeInfo.t_function );
+ f2.setIsForwardDeclaration( true );
+
+ A.addSymbol( f1 );
+ A.addSymbol( f2 );
+
+ ISymbol U = table.newSymbol( "U", TypeInfo.t_templateParameter );
+ ISymbol V = table.newSymbol( "V", TypeInfo.t_templateParameter );
+
+ List params = new LinkedList();
+ params.add( U );
+ params.add( V );
+
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, U ) );
+ args.add( new TypeInfo( TypeInfo.t_type, 0, V ) );
+
+ ITemplateFactory factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", params, args );
+ assertTrue( factory != null );
+ IParameterizedSymbol lookF = factory.lookupMemberFunctionForDefinition( "f1", new LinkedList() );
+ assertEquals( lookF, f1 );
+ assertTrue( lookF.isForwardDeclaration() );
+
+ IParameterizedSymbol defnd = table.newParameterizedSymbol( "f1", TypeInfo.t_function );
+ f1.setTypeSymbol( defnd );
+ factory.addSymbol( defnd );
+
+ ISymbol look = defnd.lookup( "U");
+ assertEquals( look, U );
+ defnd.setReturnType( look );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_char, 0, null ) );
+
+ IDerivableContainerSymbol lookA = (IDerivableContainerSymbol) table.getCompilationUnit().lookupTemplate( "A", args );
+ assertTrue( lookA.isTemplateInstance() );
+ assertEquals( lookA.getInstantiatedSymbol(), A );
+
+ params.clear();
+ look = lookA.qualifiedFunctionLookup( "f1", params );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), defnd );
+ assertTrue( ((IParameterizedSymbol)look).getReturnType().isType( TypeInfo.t_int ) );
+
+ params.clear();
+ args.clear();
+
+ ISymbol X = table.newSymbol( "X", TypeInfo.t_templateParameter );
+ ISymbol Y = table.newSymbol( "Y", TypeInfo.t_templateParameter );
+
+ params.add( X );
+ params.add( Y );
+
+ args.add( new TypeInfo( TypeInfo.t_type, 0, Y ) );
+ args.add( new TypeInfo( TypeInfo.t_type, 0, X ) );
+
+ try{
+ factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", params, args );
+ assertTrue( false );
+ } catch ( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_BadTemplate );
+ }
+ }
+
+ /**
+ * template<class T> struct A{
+ * class B;
+ * };
+ * template< class U > class A<U>::B { U i; };
+ * A<int>::B b;
+ *
+ * @throws Exception
+ */
+ public void test_14_5_1_2_MemberClass() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "A" );
+ ISymbol primaryT = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( primaryT );
+
+ IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_struct );
+ template.addSymbol( A );
+
+ table.getCompilationUnit().addSymbol( template );
+
+ IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
+ B.setIsForwardDeclaration( true );
+ A.addSymbol( B );
+
+ List params = new LinkedList();
+ ISymbol U = table.newSymbol( "U", TypeInfo.t_templateParameter );
+ params.add( U );
+
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, U ) );
+
+ ITemplateFactory factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", params, args );
+ assertTrue( factory != null );
+
+ ISymbol look = factory.lookupMemberForDefinition( "B" );
+ assertEquals( look, B );
+
+ IDerivableContainerSymbol newB = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
+ look.setTypeSymbol( newB );
+
+ factory.addSymbol( newB );
+
+ ISymbol i = table.newSymbol( "i", TypeInfo.t_type );
+ look = newB.lookup( "U" );
+ assertEquals( look, U );
+ i.setTypeSymbol( U );
+ newB.addSymbol( i );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+
+ look = table.getCompilationUnit().lookupTemplate( "A", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), A );
+
+ assertTrue( look instanceof IDerivableContainerSymbol );
+ IDerivableContainerSymbol lookA = (IDerivableContainerSymbol) look;
+ look = lookA.qualifiedLookup( "B" );
+
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), newB );
+
+ look = ((IDerivableContainerSymbol) look).lookup( "i" );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), i );
+ assertEquals( look.getType(), TypeInfo.t_int );
+ }
+
+ /**
+ * template< class T> class X{
+ * static T s;
+ * };
+ *
+ * template<class U> U X<U>::s = 0;
+ *
+ * @throws Exception
+ */
+ public void test_14_5_1_3_StaticDataMember() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "X" );
+ ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( T );
+
+ table.getCompilationUnit().addSymbol( template );
+
+ IDerivableContainerSymbol X = table.newDerivableContainerSymbol( "X", TypeInfo.t_class );
+ template.addSymbol( X );
+
+ ISymbol s = table.newSymbol( "s", TypeInfo.t_type );
+ s.setTypeSymbol( T );
+ s.getTypeInfo().setBit( true, TypeInfo.isStatic );
+ s.setIsForwardDeclaration( true );
+ X.addSymbol( s );
+
+ List params = new LinkedList();
+ ISymbol paramU = table.newSymbol( "U", TypeInfo.t_templateParameter );
+ params.add( paramU );
+
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, paramU ) );
+
+ ITemplateFactory factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "X", params, args );
+
+ assertTrue( factory != null );
+
+ ISymbol look = factory.lookupMemberForDefinition( "s" );
+
+ assertTrue( look.isForwardDeclaration() );
+
+ ISymbol newS = table.newSymbol( "s", TypeInfo.t_type );
+ newS.setTypeSymbol( paramU );
+
+ look.setTypeSymbol( newS );
+
+ factory.addSymbol( newS );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_float, 0, null ) );
+
+ look = table.getCompilationUnit().lookupTemplate( "X", args );
+
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), X );
+
+ look = ((IContainerSymbol)look).qualifiedLookup( "s" );
+
+ assertTrue( look.isType( TypeInfo.t_float ) );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), newS );
+
+ }
+
+ /**
+ * template< class T > class string{
+ * template< class T2 > T2 compare( const T2 & );
+ * };
+ *
+ * template< class U > template< class V > V string<U>::compare( const V & ) {
+ * U u;
+ * }
+ * @throws Exception
+ */
+ public void test_14_5_2__1_MemberTemplates() throws Exception{
+ newTable();
+
+ ITemplateSymbol template1 = table.newTemplateSymbol( "string" );
+ template1.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+
+ table.getCompilationUnit().addSymbol( template1 );
+
+ IDerivableContainerSymbol string = table.newDerivableContainerSymbol( "string", TypeInfo.t_class );
+ template1.addSymbol( string );
+
+ ITemplateSymbol template2 = table.newTemplateSymbol( "compare" );
+ ISymbol T2 = table.newSymbol( "T2", TypeInfo.t_templateParameter );
+ template2.addTemplateParameter( T2 );
+
+ string.addSymbol( template2 );
+
+ IParameterizedSymbol compare = table.newParameterizedSymbol( "compare", TypeInfo.t_function );
+ compare.setIsForwardDeclaration( true );
+ compare.addParameter( T2, new PtrOp( PtrOp.t_reference, true, false ), false );
+ compare.setReturnType( T2 );
+ template2.addSymbol( compare );
+
+
+ List params = new LinkedList();
+ ISymbol U = table.newSymbol( "U", TypeInfo.t_templateParameter );
+ params.add( U );
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, U ) );
+
+ ITemplateFactory factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "string", params, args );
+
+ params.clear();
+
+ ISymbol V = table.newSymbol( "V", TypeInfo.t_templateParameter );
+ params.add( V );
+
+ factory = factory.lookupTemplateForMemberDefinition( "compare", params, null );
+
+ IParameterizedSymbol compareDef = table.newParameterizedSymbol( "compare", TypeInfo.t_function );
+ ISymbol look = factory.lookupParam( "V" );
+ assertEquals( look, V );
+ compareDef.addParameter( look, new PtrOp( PtrOp.t_reference, true, false ), false );
+ compareDef.setReturnType( look );
+ compare.setTypeSymbol( compareDef );
+ factory.addSymbol( compareDef );
+
+ look = compareDef.lookup( "U" );
+ assertEquals( look, U );
+
+ ISymbol u = table.newSymbol( "u", TypeInfo.t_type );
+ u.setTypeSymbol( look );
+
+ compareDef.addSymbol( u );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+
+ look = table.getCompilationUnit().lookupTemplate( "string", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), string );
+
+ look = ((IDerivableContainerSymbol)look).lookupTemplate( "compare", args );
+ assertTrue( look.isTemplateInstance() );
+ assertTrue( look.getInstantiatedSymbol().isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol().getInstantiatedSymbol(), compareDef );
+
+ assertTrue( ((IParameterizedSymbol)look).getReturnType().isType( TypeInfo.t_int ) );
+
+ look = ((IContainerSymbol)look).lookup( "u" );
+ assertTrue( look.isTemplateInstance() );
+ assertTrue( look.getInstantiatedSymbol().isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol().getInstantiatedSymbol(), u );
+ assertTrue( look.isType( TypeInfo.t_int ) );
+ }
+
+ /**
+ * A member function template shall not be virtual
+ *
+ * template< class T > struct A {
+ * template < class C > virtual void g( C ); //error
+ * virtual void f(); //ok
+ * };
+ * @throws Exception
+ */
+ public void test_14_5_2__3_VirtualMemberFunctionTemplate() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "A" );
+ template.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+
+ IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_struct );
+ template.addSymbol( A );
+
+ table.getCompilationUnit().addSymbol( template );
+
+ ITemplateSymbol memberTemplate = table.newTemplateSymbol( "g" );
+ ISymbol C = table.newSymbol( "C", TypeInfo.t_templateParameter );
+ memberTemplate.addTemplateParameter( C );
+
+ IParameterizedSymbol g = table.newParameterizedSymbol( "g", TypeInfo.t_function );
+ g.addParameter( C, null, false );
+ g.getTypeInfo().setBit( true, TypeInfo.isVirtual );
+
+ memberTemplate.addSymbol( g );
+
+ try{
+ A.addSymbol( memberTemplate );
+ assertTrue( false );
+ } catch ( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_BadTemplate );
+ }
+
+ IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f.getTypeInfo().setBit( true, TypeInfo.isVirtual );
+
+ A.addSymbol( f );
+ }
+
+ /**
+ * Partial specialization declarations are not found by name lookup, Rather, when the primary
+ * template name is used, any previously declared partial template specializations of the
+ * primary template are also considered.
+ * One consequence is that a using-declaration which refers to a class template does not restrict
+ * the set of partial specializations which may be found through the using-declaration.
+ *
+ * namespace N{
+ * template< class T1, class T2 > class A {};
+ * }
+ *
+ * using N::A;
+ *
+ * namespace N{
+ * template< class T> class A < T, T * > {};
+ * }
+ *
+ * A< int, int * > a; //uses partial specialization
+ *
+ * @throws Exception
+ */
+ public void test_14_5_4__7_PartialSpecializationLookup() throws Exception{
+ newTable();
+
+ IContainerSymbol N = table.newContainerSymbol( "N", TypeInfo.t_namespace );
+
+ table.getCompilationUnit().addSymbol( N );
+
+ ITemplateSymbol template = table.newTemplateSymbol( "A" );
+
+ template.addTemplateParameter( table.newSymbol( "T1", TypeInfo.t_templateParameter ) );
+ template.addTemplateParameter( table.newSymbol( "T2", TypeInfo.t_templateParameter ) );
+
+ IDerivableContainerSymbol A1 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+
+ template.addSymbol( A1 );
+
+ N.addSymbol( template );
+
+ table.getCompilationUnit().addUsingDeclaration( "A", N );
+
+ ISpecializedSymbol spec = table.newSpecializedSymbol( "A" );
+ ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ spec.addTemplateParameter( T );
+ spec.addArgument( new TypeInfo( TypeInfo.t_type, 0, T ) );
+ spec.addArgument( new TypeInfo( TypeInfo.t_type, 0, T, new PtrOp( PtrOp.t_pointer ), false ) );
+
+ IDerivableContainerSymbol A2 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ spec.addSymbol( A2 );
+ template.addSpecialization( spec );
+
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
+
+ ISymbol look = table.getCompilationUnit().lookupTemplate( "A", args );
+ assertTrue( look != null );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), A2 );
+ }
+
+ /**
+ *
+ * template < class T1, class T2, int I > class A {} //#1
+ * template < class T, int I > class A < T, T*, I > {} //#2
+ * template < class T1, class T2, int I > class A < T1*, T2, I > {} //#3
+ * template < class T > class A < int, T*, 5 > {} //#4
+ * template < class T1, class T2, int I > class A < T1, T2*, I > {} //#5
+ *
+ * A <int, int, 1> a1; //uses #1
+ * A <int, int*, 1> a2; //uses #2, T is int, I is 1
+ * A <int, char*, 5> a3; //uses #4, T is char
+ * A <int, char*, 1> a4; //uses #5, T is int, T2 is char, I is1
+ * A <int*, int*, 2> a5; //ambiguous, matches #3 & #5.
+ *
+ * @throws Exception
+ */
+ public void test_14_5_4_1__2_MatchingTemplateSpecializations() throws Exception{
+ newTable();
+
+ IDerivableContainerSymbol cls1 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ IDerivableContainerSymbol cls2 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ IDerivableContainerSymbol cls3 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ IDerivableContainerSymbol cls4 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ IDerivableContainerSymbol cls5 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+
+ ITemplateSymbol template1 = table.newTemplateSymbol( "A" );
+ ISymbol T1p1 = table.newSymbol( "T1", TypeInfo.t_templateParameter );
+ ISymbol T1p2 = table.newSymbol( "T2", TypeInfo.t_templateParameter );
+ ISymbol T1p3 = table.newSymbol( "I", TypeInfo.t_templateParameter );
+ T1p3.getTypeInfo().setTemplateParameterType( TypeInfo.t_int );
+
+ template1.addTemplateParameter( T1p1 );
+ template1.addTemplateParameter( T1p2 );
+ template1.addTemplateParameter( T1p3 );
+ template1.addSymbol( cls1 );
+ table.getCompilationUnit().addSymbol( template1 );
+
+ ISpecializedSymbol template2 = table.newSpecializedSymbol( "A" );
+ ISymbol T2p1 = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ ISymbol T2p2 = table.newSymbol( "I", TypeInfo.t_templateParameter );
+ T2p2.getTypeInfo().setTemplateParameterType( TypeInfo.t_int );
+
+ template2.addTemplateParameter( T2p1 );
+ template2.addTemplateParameter( T2p2 );
+
+ TypeInfo T2a1 = new TypeInfo( TypeInfo.t_type, 0, T2p1 );
+ TypeInfo T2a2 = new TypeInfo( TypeInfo.t_type, 0, T2p1, new PtrOp( PtrOp.t_pointer ), false );
+ TypeInfo T2a3 = new TypeInfo( TypeInfo.t_type, 0, T2p2 );
+
+ template2.addArgument( T2a1 );
+ template2.addArgument( T2a2 );
+ template2.addArgument( T2a3 );
+ template2.addSymbol( cls2 );
+ template1.addSpecialization( template2 );
+
+ ISpecializedSymbol template3 = table.newSpecializedSymbol( "A" );
+ ISymbol T3p1 = table.newSymbol( "T1", TypeInfo.t_templateParameter );
+ ISymbol T3p2 = table.newSymbol( "T2", TypeInfo.t_templateParameter );
+ ISymbol T3p3 = table.newSymbol( "I", TypeInfo.t_templateParameter );
+ T3p3.getTypeInfo().setTemplateParameterType( TypeInfo.t_int );
+
+ template3.addTemplateParameter( T3p1 );
+ template3.addTemplateParameter( T3p2 );
+ template3.addTemplateParameter( T3p3 );
+
+ TypeInfo T3a1 = new TypeInfo( TypeInfo.t_type, 0, T3p1, new PtrOp( PtrOp.t_pointer ), false );
+ TypeInfo T3a2 = new TypeInfo( TypeInfo.t_type, 0, T3p2 );
+ TypeInfo T3a3 = new TypeInfo( TypeInfo.t_type, 0, T3p3 );
+
+ template3.addArgument( T3a1 );
+ template3.addArgument( T3a2 );
+ template3.addArgument( T3a3 );
+ template3.addSymbol( cls3 );
+ template1.addSpecialization( template3 );
+
+ ISpecializedSymbol template4 = table.newSpecializedSymbol( "A" );
+ ISymbol T4p1 = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template4.addTemplateParameter( T4p1 );
+
+ TypeInfo T4a1 = new TypeInfo( TypeInfo.t_int, 0, null );
+ TypeInfo T4a2 = new TypeInfo( TypeInfo.t_type, 0, T4p1, new PtrOp( PtrOp.t_pointer ), false );
+ TypeInfo T4a3 = new TypeInfo( TypeInfo.t_int, 0, null, null, "5" );
+ //T4a3.setDefault( new Integer(5) );
+
+ template4.addArgument( T4a1 );
+ template4.addArgument( T4a2 );
+ template4.addArgument( T4a3 );
+ template4.addSymbol( cls4 );
+ template1.addSpecialization( template4 );
+
+ ISpecializedSymbol template5 = table.newSpecializedSymbol( "A" );
+ ISymbol T5p1 = table.newSymbol( "T1", TypeInfo.t_templateParameter );
+ ISymbol T5p2 = table.newSymbol( "T2", TypeInfo.t_templateParameter );
+ ISymbol T5p3 = table.newSymbol( "I", TypeInfo.t_templateParameter );
+ T5p3.getTypeInfo().setTemplateParameterType( TypeInfo.t_int );
+
+ template5.addTemplateParameter( T5p1 );
+ template5.addTemplateParameter( T5p2 );
+ template5.addTemplateParameter( T5p3 );
+
+ TypeInfo T5a1 = new TypeInfo( TypeInfo.t_type, 0, T5p1 );
+ TypeInfo T5a2 = new TypeInfo( TypeInfo.t_type, 0, T5p2, new PtrOp( PtrOp.t_pointer ), false );
+ TypeInfo T5a3 = new TypeInfo( TypeInfo.t_type, 0, T5p3 );
+
+ template5.addArgument( T5a1 );
+ template5.addArgument( T5a2 );
+ template5.addArgument( T5a3 );
+ template5.addSymbol( cls5 );
+ template1.addSpecialization( template5 );
+
+ ITemplateSymbol a = (ITemplateSymbol) table.getCompilationUnit().lookup( "A" );
+ assertEquals( a, template1 );
+
+ LinkedList args = new LinkedList();
+
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) );
+
+ IContainerSymbol a1 = (IContainerSymbol) a.instantiate( args );
+ assertTrue( a1.isTemplateInstance() );
+ assertEquals( a1.getInstantiatedSymbol(), cls1 );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, "1" ) );
+
+ IContainerSymbol a2 = (IContainerSymbol) a.instantiate( args );
+ assertTrue( a2.isTemplateInstance() );
+ assertEquals( a2.getInstantiatedSymbol(), cls2 );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, "5" ) );
+ IContainerSymbol a3 = (IContainerSymbol) a.instantiate( args );
+ assertTrue( a3.isTemplateInstance() );
+ assertEquals( a3.getInstantiatedSymbol(), cls4 );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, "1" ) );
+ IContainerSymbol a4 = (IContainerSymbol) a.instantiate( args );
+ assertTrue( a4.isTemplateInstance() );
+ assertEquals( a4.getInstantiatedSymbol(), cls5 );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, "2" ) );
+
+ try{
+ a.instantiate( args );
+ assertTrue( false );
+ } catch ( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
+ }
+ }
+
+ /**
+ * template< class T > void f( T ); //#1
+ * template< class T > void f( T* ); //#2
+ * template< class T > void f( const T* ); //#3
+ *
+ * const int *p;
+ * f( p ); //calls f( const T * ) , 3 is more specialized than 1 or 2
+ *
+ * @throws Exception
+ *
+ */
+ public void test_14_5_5_2__5_OrderingFunctionTemplates_1() throws Exception{
+ newTable();
+
+ ITemplateSymbol template1 = table.newTemplateSymbol( "f" );
+ template1.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+ ISymbol T = template1.lookup( "T" );
+ IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f1.addParameter( T, null, false );
+ template1.addSymbol( f1 );
+ table.getCompilationUnit().addSymbol( template1 );
+
+ ITemplateSymbol template2 = table.newTemplateSymbol( "f" );
+ template2.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+ T = template2.lookup( "T" );
+ IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f2.addParameter( T, new PtrOp( PtrOp.t_pointer ), false );
+ template2.addSymbol( f2 );
+ table.getCompilationUnit().addSymbol( template2 );
+
+
+ ITemplateSymbol template3 = table.newTemplateSymbol( "f" );
+ template3.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+ T = template3.lookup( "T" );
+ IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f3.addParameter( T, new PtrOp( PtrOp.t_pointer, true, false ), false );
+ template3.addSymbol( f3 );
+ table.getCompilationUnit().addSymbol( template3 );
+
+ ISymbol p = table.newSymbol( "p", TypeInfo.t_int );
+ p.addPtrOperator( new PtrOp( PtrOp.t_pointer, true, false ) );
+ table.getCompilationUnit().addSymbol( p );
+
+ List params = new LinkedList();
+ params.add( new TypeInfo( TypeInfo.t_type, 0, p ) );
+
+ ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", params );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), f3 );
+ }
+
+ /**
+ * template< class T > void g( T ); //#1
+ * template< class T > void g( T& ); //#2
+
+ * float x;
+ * g( x ); //ambiguous 1 or 2
+ *
+ * @throws Exception
+ */
+ public void test_14_5_5_2__5_OrderingFunctionTemplates_2() throws Exception{
+ newTable();
+
+ ITemplateSymbol template1 = table.newTemplateSymbol( "g" );
+ template1.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+ ISymbol T = template1.lookup( "T" );
+ IParameterizedSymbol g1 = table.newParameterizedSymbol( "g", TypeInfo.t_function );
+ g1.addParameter( T, null, false );
+ template1.addSymbol( g1 );
+ table.getCompilationUnit().addSymbol( template1 );
+
+ ITemplateSymbol template2 = table.newTemplateSymbol( "g" );
+ template2.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+ T = template2.lookup( "T" );
+ IParameterizedSymbol g2 = table.newParameterizedSymbol( "g", TypeInfo.t_function );
+ g2.addParameter( T, new PtrOp( PtrOp.t_reference ), false );
+ template2.addSymbol( g2 );
+ table.getCompilationUnit().addSymbol( template2 );
+
+ ISymbol x = table.newSymbol( "x", TypeInfo.t_float );
+ List params = new LinkedList();
+ params.add( new TypeInfo( TypeInfo.t_type, 0, x ) );
+ try{
+ ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "g", params );
+ assertTrue( false );
+ } catch( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
+ }
+ }
+
+ /**
+ * template< class T > struct A { };
+ *
+ * template< class T > void h( const T & ); //#1
+ * template< class T > void h( A<T>& ); //#2
+ *
+ * A<int> z;
+ * h( z ); //calls 2
+ *
+ * const A<int> z2;
+ * h( z2 ); //calls 1 because 2 is not callable.
+ * @throws Exception
+ */
+ public void test_14_5_5_2__5_OrderingFunctionTemplates_3() throws Exception{
+ newTable();
+
+ ITemplateSymbol templateA = table.newTemplateSymbol( "A" );
+ templateA.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+
+ IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_struct );
+ templateA.addSymbol( A );
+
+ table.getCompilationUnit().addSymbol( templateA );
+
+ ITemplateSymbol template1 = table.newTemplateSymbol( "h" );
+ template1.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+ ISymbol T = template1.lookup( "T" );
+ IParameterizedSymbol h1 = table.newParameterizedSymbol( "h", TypeInfo.t_function );
+ h1.addParameter( T, new PtrOp( PtrOp.t_reference, true, false ), false );
+ template1.addSymbol( h1 );
+ table.getCompilationUnit().addSymbol( template1 );
+
+ ITemplateSymbol template2 = table.newTemplateSymbol( "h" );
+ template2.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+ T = template2.lookup( "T" );
+
+ IParameterizedSymbol h2 = table.newParameterizedSymbol( "h", TypeInfo.t_function );
+ List argList = new LinkedList();
+ argList.add( new TypeInfo( TypeInfo.t_type, 0, T ) );
+ h2.addParameter( templateA.instantiate( argList ), new PtrOp( PtrOp.t_reference ), false );
+
+ template2.addSymbol( h2 );
+ table.getCompilationUnit().addSymbol( template2 );
+
+ ISymbol z = table.newSymbol( "z", TypeInfo.t_type );
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ ISymbol look = table.getCompilationUnit().lookupTemplate( "A", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), A );
+ z.setTypeSymbol( look );
+
+ List params = new LinkedList();
+ params.add( new TypeInfo( TypeInfo.t_type, 0, z ) );
+ look = table.getCompilationUnit().unqualifiedFunctionLookup( "h", params );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), h2 );
+
+ ISymbol z2 = table.newSymbol( "z2", TypeInfo.t_type );
+ look = table.getCompilationUnit().lookupTemplate( "A", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), A );
+ z2.setTypeSymbol( look );
+ z2.addPtrOperator( new PtrOp( PtrOp.t_undef, true, false ) );
+
+ params.clear();
+ params.add( new TypeInfo( TypeInfo.t_type, 0, z2 ) );
+ look = table.getCompilationUnit().unqualifiedFunctionLookup( "h", params );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), h1 );
+ }
+
+ /**
+ * Within the scope of a class template, when the name of the template is neither qualified
+ * nor followed by <, it is equivalent to the name of the template followed by the template-parameters
+ * enclosed in <>.
+ *
+ * template < class T > class X {
+ * X* p; //meaning X< T >
+ * };
+ *
+ * @throws Exception
+ */
+ public void test_14_6_1__1_TemplateName() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "X" );
+ ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( T );
+ IDerivableContainerSymbol X = table.newDerivableContainerSymbol( "X", TypeInfo.t_class );
+ template.addSymbol( X );
+ table.getCompilationUnit().addSymbol( template );
+
+ ISymbol look = X.lookup( "X" );
+
+ assertTrue( look != null );
+ assertTrue( look instanceof IDeferredTemplateInstance );
+ IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) look;
+ assertEquals( deferred.getTemplate(), template );
+
+ Iterator iter = deferred.getArguments().iterator();
+ TypeInfo type = (TypeInfo) iter.next();
+ assertTrue( type.isType( TypeInfo.t_type ) );
+ assertEquals( type.getTypeSymbol(), T );
+ }
+
+ /**
+ * Within the scope of a class template specialization or partial specialization, when the name of the
+ * template is neither qualified nor followed by <, it is equivalent to the name of the template
+ * followed by the template-arguments enclosed in <>
+ *
+ * template< class T > class Y;
+ *
+ * template<> class Y< int > {
+ * Y* p; //meaning Y<int>
+ * }
+ * @throws Exception
+ */
+ public void test_14_6_1__2_SpecializationName() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "Y" );
+ ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( T );
+ IDerivableContainerSymbol Y1 = table.newDerivableContainerSymbol( "Y", TypeInfo.t_class );
+ template.addSymbol( Y1 );
+
+ table.getCompilationUnit().addSymbol( template );
+
+ ISpecializedSymbol spec = table.newSpecializedSymbol( "Y" );
+ spec.addArgument( new TypeInfo( TypeInfo.t_int, 0, null ) );
+
+ template.addSpecialization( spec );
+
+ IDerivableContainerSymbol Y2 = table.newDerivableContainerSymbol( "Y", TypeInfo.t_class );
+ spec.addSymbol( Y2 );
+
+ ISymbol look = Y2.lookup( "Y" );
+ assertTrue( look != null );
+ assertTrue( look instanceof IDeferredTemplateInstance );
+ IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) look;
+ assertEquals( deferred.getTemplate(), spec );
+
+ Iterator iter = deferred.getArguments().iterator();
+ TypeInfo type = (TypeInfo) iter.next();
+ assertTrue( type.isType( TypeInfo.t_int ) );
+ }
+
+ /**
+ * A template-parameter shall not be redeclared within its scope. A template-parameter shall
+ * not have the same name as the template name.
+ *
+ * template< class T, int i > class Y {
+ * int T; //error
+ * void f(){
+ * char T; //error
+ * }
+ * };
+ *
+ * template <class X> class X {}; //error
+ *
+ * @throws Exception
+ */
+ public void test_14_6_1__4_ParameterRedeclaration() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "Y" );
+ template.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+
+ ISymbol i = table.newSymbol( "i", TypeInfo.t_templateParameter );
+ i.getTypeInfo().setTemplateParameterType( TypeInfo.t_int );
+
+ template.addTemplateParameter( i );
+
+ IDerivableContainerSymbol Y = table.newDerivableContainerSymbol( "Y", TypeInfo.t_class );
+ template.addSymbol( Y );
+
+ ISymbol T = table.newSymbol( "T", TypeInfo.t_int );
+ try{
+ Y.addSymbol( T );
+ assertTrue( false );
+ } catch ( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_RedeclaredTemplateParam );
+ }
+
+ IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ Y.addSymbol( f );
+
+ try{
+ f.addSymbol( table.newSymbol( "T", TypeInfo.t_char ) );
+ assertTrue( false );
+ } catch ( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_RedeclaredTemplateParam );
+ }
+
+ ITemplateSymbol template2 = table.newTemplateSymbol( "X" );
+ try{
+ template2.addTemplateParameter( table.newSymbol( "X", TypeInfo.t_templateParameter ) );
+ assertTrue( false );
+ } catch( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateParameter );
+ }
+ }
+
+
+
+ /**
+ * template < class T > void f( T x, T y ) { }
+ * struct A {};
+ * struct B : A {};
+ *
+ * A a;
+ * B b;
+ *
+ * f( a, b ); //error, T could be A or B
+ * f( b, a ); //error, T could be A or B
+ * f( a, a ); //ok, T is A
+ * f( b, b ); //ok, T is B
+ * @throws Exception
+ */
+ public void test_14_8_2_4__5_ArgumentDeduction() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "f" );
+ ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( T );
+
+ IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+
+ ISymbol lookT = template.lookup( "T" );
+ assertEquals( lookT, T );
+
+ ISymbol paramX = table.newSymbol( "x", TypeInfo.t_type );
+ paramX.setTypeSymbol( lookT );
+
+ ISymbol paramY = table.newSymbol( "y", TypeInfo.t_type );
+ paramY.setTypeSymbol( lookT );
+
+ f.addParameter( paramX );
+ f.addParameter( paramY );
+
+ template.addSymbol( f );
+ table.getCompilationUnit().addSymbol( template );
+
+ IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_struct );
+ table.getCompilationUnit().addSymbol( A );
+
+ IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_struct );
+ B.addParent( A );
+ table.getCompilationUnit().addSymbol( B );
+
+ ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
+ a.setTypeSymbol( A );
+
+ ISymbol b = table.newSymbol( "b", TypeInfo.t_type );
+ b.setTypeSymbol( B );
+
+ table.getCompilationUnit().addSymbol( a );
+ table.getCompilationUnit().addSymbol( b );
+
+ List argList = new LinkedList();
+ TypeInfo aParam = new TypeInfo( TypeInfo.t_type, 0, a );
+ TypeInfo bParam = new TypeInfo( TypeInfo.t_type, 0, b );
+
+ argList.add( aParam );
+ argList.add( bParam );
+ ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", argList );
+ assertEquals( look, null );
+
+ argList.clear();
+ argList.add( bParam );
+ argList.add( aParam );
+ look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", argList );
+ assertEquals( look, null );
+
+ argList.clear();
+ argList.add( aParam );
+ argList.add( aParam );
+ look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", argList );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), f );
+
+ argList.clear();
+ argList.add( bParam );
+ argList.add( bParam );
+ look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", argList );
+ assertTrue( look.isTemplateInstance());
+ assertEquals( look.getInstantiatedSymbol(), f );
+ }
+
+ /**
+ * template< class T, class U > void f( T (*)( T, U, U ) );
+ * int g1( int, float, float );
+ * char g2( int, float, float );
+ * int g3( int, char, float );
+ *
+ * f( g1 ); //OK, T is int and U is float
+ * f( g2 ); //error, T could be char or int
+ * f( g3 ); //error, U could be char or float
+ *
+ * @throws Exception
+ */
+ public void test_14_8_2_4__6_ArgumentDeduction() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "f" );
+
+ template.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+ template.addTemplateParameter( table.newSymbol( "U", TypeInfo.t_templateParameter ) );
+
+ IParameterizedSymbol paramFunction = table.newParameterizedSymbol( "", TypeInfo.t_function );
+ paramFunction.setIsTemplateMember( true );
+
+ ISymbol T = template.lookup( "T" );
+ ISymbol U = template.lookup( "U" );
+
+ paramFunction.setReturnType( T );
+ paramFunction.addParameter( T, null, false );
+ paramFunction.addParameter( U, null, false );
+ paramFunction.addParameter( U, null, false );
+
+ IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f.addParameter( paramFunction, null, false );
+
+ template.addSymbol( f );
+
+ table.getCompilationUnit().addSymbol( template );
+
+ IParameterizedSymbol g1 = table.newParameterizedSymbol( "g1", TypeInfo.t_function );
+ g1.setReturnType( table.newSymbol( "", TypeInfo.t_int ) );
+ g1.addParameter( TypeInfo.t_int, 0, null, false );
+ g1.addParameter( TypeInfo.t_float, 0, null, false );
+ g1.addParameter( TypeInfo.t_float, 0, null, false );
+
+ table.getCompilationUnit().addSymbol( g1 );
+
+ IParameterizedSymbol g2 = table.newParameterizedSymbol( "g2", TypeInfo.t_function );
+ g2.setReturnType( table.newSymbol( "", TypeInfo.t_char ) );
+ g2.addParameter( TypeInfo.t_int, 0, null, false );
+ g2.addParameter( TypeInfo.t_float, 0, null, false );
+ g2.addParameter( TypeInfo.t_float, 0, null, false );
+
+ table.getCompilationUnit().addSymbol( g2);
+
+ IParameterizedSymbol g3 = table.newParameterizedSymbol( "g3", TypeInfo.t_function );
+ g3.setReturnType( table.newSymbol( "", TypeInfo.t_int ) );
+ g3.addParameter( TypeInfo.t_int, 0, null, false );
+ g3.addParameter( TypeInfo.t_char, 0, null, false );
+ g3.addParameter( TypeInfo.t_float, 0, null, false );
+
+ table.getCompilationUnit().addSymbol( g3);
+
+ TypeInfo arg = new TypeInfo( TypeInfo.t_type, 0, g1 );
+ List argList = new LinkedList();
+ argList.add( arg );
+
+ ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", argList );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), f );
+
+ arg.setTypeSymbol( g2 );
+ look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", argList );
+ assertEquals( look, null );
+
+ arg.setTypeSymbol( g3 );
+ look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", argList );
+ assertEquals( look, null );
+ }
+ /**
+ * template< class T > void f( const T * ){}
+ *
+ * int *p;
+ *
+ * f( p ); //f ( const int * )
+ *
+ * @throws Exception
+ */
+ public void test_14_8_2_4__7_ArgumentDeduction() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "f" );
+ ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( T );
+
+ IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f.addParameter( T, new PtrOp( PtrOp.t_pointer, true, false ), false );
+ template.addSymbol( f );
+
+ table.getCompilationUnit().addSymbol( template );
+
+ ISymbol p = table.newSymbol( "p", TypeInfo.t_int );
+ p.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
+
+ List params = new LinkedList();
+ params.add( new TypeInfo( TypeInfo.t_type, 0, p ) );
+ ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", params );
+
+ assertTrue( look != null );
+ assertTrue( look.isTemplateInstance() );
+
+ assertEquals( look.getInstantiatedSymbol(), f );
+
+ IParameterizedSymbol fn = (IParameterizedSymbol) look;
+ Iterator iter = fn.getParameterList().iterator();
+ ISymbol param = (ISymbol) iter.next();
+ assertTrue( param.isType( TypeInfo.t_int ) );
+
+ assertFalse( iter.hasNext() );
+
+ iter = param.getTypeInfo().getPtrOperators().iterator();
+ PtrOp op = (PtrOp) iter.next();
+ assertTrue( op.isConst() );
+ assertEquals( op.getType(), PtrOp.t_pointer );
+ assertFalse( iter.hasNext() );
+ }
+
+ /**
+ * template< class T > struct B {};
+ *
+ * template< class T > struct D : public B< T > {};
+ *
+ * struct D2 : public B< int > {};
+ *
+ * template< class T > void f( B<T> & ) {}
+ *
+ * D<int> d;
+ * D2 d2;
+ *
+ * f( d ); //f( B<int> & )
+ * f( d2 ); //f( B<int> & )
+ * @throws Exception
+ */
+ public void test_14_8_2_4__8_ArgumentDeduction() throws Exception{
+ newTable();
+
+ ITemplateSymbol templateB = table.newTemplateSymbol( "B" );
+ templateB.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+
+ IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_struct );
+ templateB.addSymbol( B );
+
+ table.getCompilationUnit().addSymbol( templateB );
+
+ ITemplateSymbol templateD = table.newTemplateSymbol( "D" );
+ templateD.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
+
+ IDerivableContainerSymbol D = table.newDerivableContainerSymbol( "D", TypeInfo.t_struct );
+ templateD.addSymbol( D );
+
+ ISymbol T = templateD.lookup( "T" );
+ List args = new LinkedList ();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, T ) );
+ ISymbol look = table.getCompilationUnit().lookupTemplate( "B", args );
+ assertTrue( look instanceof IDeferredTemplateInstance );
+ assertEquals( ((IDeferredTemplateInstance)look).getTemplate(), templateB );
+
+ D.addParent( look );
+
+ table.getCompilationUnit().addSymbol( templateD );
+
+ IDerivableContainerSymbol D2 = table.newDerivableContainerSymbol( "D2", TypeInfo.t_struct );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ look = table.getCompilationUnit().lookupTemplate( "B", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), B );
+
+ D2.addParent( look );
+
+ table.getCompilationUnit().addSymbol( D2 );
+
+ ITemplateSymbol templatef = table.newTemplateSymbol( "f" );
+ T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+ templatef.addTemplateParameter( T );
+ IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, T ) );
+
+ look = table.getCompilationUnit().lookupTemplate( "B", args );
+ assertTrue( look instanceof IDeferredTemplateInstance );
+ assertEquals( ((IDeferredTemplateInstance)look).getTemplate(), templateB );
+
+ ISymbol param = table.newSymbol( "", TypeInfo.t_type );
+ param.setTypeSymbol( look );
+ param.addPtrOperator( new PtrOp( PtrOp.t_reference ) );
+ f.addParameter( param );
+
+ templatef.addSymbol( f );
+ table.getCompilationUnit().addSymbol( templatef );
+
+ ISymbol d = table.newSymbol( "d", TypeInfo.t_type );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ look = table.getCompilationUnit().lookupTemplate( "D", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), D );
+
+ d.setTypeSymbol( look );
+ table.getCompilationUnit().addSymbol( d );
+
+ ISymbol d2 = table.newSymbol( "d2", TypeInfo.t_type );
+ d2.setTypeSymbol( D2 );
+ table.getCompilationUnit().addSymbol( d2 );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, d ) );
+ look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", args );
+ assertTrue( look != null );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), f );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, d2 ) );
+ ISymbol look2 = table.getCompilationUnit().unqualifiedFunctionLookup( "f", args );
+ assertTrue( look2 != null );
+ assertTrue( look2.isTemplateInstance() );
+ assertEquals( look2.getInstantiatedSymbol(), f );
+
+ //both are the template function instantiated with int, should be the same instance.
+ assertEquals( look, look2 );
+ }
+
+
+
+
+ /**
+ * template < class T1, class T2 > class A { void f(); }; //#1
+ *
+ * template < class T > class A < T, T > { void f(); }; //#2
+ * template < class T > class A < char, T > { void f(); }; //#3
+ *
+ * template < class U, class V > void A<U, V>::f(){
+ * int c;
+ * }
+ *
+ * template < class W > void A < W, W >::f(){
+ * char c;
+ * }
+ *
+ * template < class X > void < char, X >::f(){
+ * float c;
+ * }
+ *
+ * A< int, char > a1; //#1
+ * A< int, int > a2; //#2
+ * A< char, int > a3; //#3
+ *
+ * a1.f(); //#1
+ * a2.f(); //#2
+ * a3.f(); //#3
+ *
+ * @throws Exception
+ */
+ public void testPartialSpecializationDefinitions() throws Exception{
+ newTable();
+
+ ITemplateSymbol template = table.newTemplateSymbol( "A" );
+ ISymbol T1 = table.newSymbol( "T1", TypeInfo.t_templateParameter );
+ ISymbol T2 = table.newSymbol( "T2", TypeInfo.t_templateParameter );
+ template.addTemplateParameter( T1 );
+ template.addTemplateParameter( T2 );
+ IDerivableContainerSymbol A1 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+ template.addSymbol( A1 );
+
+ table.getCompilationUnit().addSymbol( template );
+
+ IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f1.setIsForwardDeclaration( true );
+ A1.addSymbol( f1 );
+
+ ISpecializedSymbol spec1 = table.newSpecializedSymbol( "A" );
+ ISymbol spec1_T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+
+ spec1.addTemplateParameter( spec1_T );
+ spec1.addArgument( new TypeInfo( TypeInfo.t_type, 0, spec1_T ) );
+ spec1.addArgument( new TypeInfo( TypeInfo.t_type, 0, spec1_T ) );
+
+ IDerivableContainerSymbol A2 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+
+ spec1.addSymbol( A2 );
+ template.addSpecialization( spec1 );
+
+ IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f2.setIsForwardDeclaration( true );
+ A2.addSymbol( f2 );
+
+ ISpecializedSymbol spec2 = table.newSpecializedSymbol( "A" );
+ ISymbol spec2_T = table.newSymbol( "T", TypeInfo.t_templateParameter );
+
+ spec2.addTemplateParameter( spec2_T );
+ spec2.addArgument( new TypeInfo( TypeInfo.t_char, 0, null ) );
+ spec2.addArgument( new TypeInfo( TypeInfo.t_type, 0, spec2_T ) );
+
+ IDerivableContainerSymbol A3 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+
+ spec2.addSymbol( A3 );
+ template.addSpecialization( spec2 );
+
+ IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f3.setIsForwardDeclaration( true );
+ A3.addSymbol( f3 );
+
+ ISymbol U = table.newSymbol( "U", TypeInfo.t_templateParameter );
+ ISymbol V = table.newSymbol( "V", TypeInfo.t_templateParameter );
+
+ List params = new LinkedList();
+ params.add( U );
+ params.add( V );
+
+ List args = new LinkedList();
+ args.add( new TypeInfo( TypeInfo.t_type, 0, U ) );
+ args.add( new TypeInfo( TypeInfo.t_type, 0, V ) );
+
+ ITemplateFactory factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", params, args );
+
+ ISymbol look = factory.lookupMemberFunctionForDefinition( "f", new LinkedList() );
+ assertEquals( look, f1 );
+ IParameterizedSymbol f1Def = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f1.setTypeSymbol( f1Def );
+ factory.addSymbol( f1Def );
+
+ ISymbol c1 = table.newSymbol( "c", TypeInfo.t_int );
+ f1Def.addSymbol( c1 );
+
+ params.clear();
+ args.clear();
+
+ ISymbol W = table.newSymbol( "W", TypeInfo.t_templateParameter );
+
+ params.add( W );
+ args.add( new TypeInfo( TypeInfo.t_type, 0, W ) );
+ args.add( new TypeInfo( TypeInfo.t_type, 0, W ) );
+
+ factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", params, args );
+
+ look = factory.lookupMemberFunctionForDefinition( "f", new LinkedList() );
+ assertEquals( look, f2 );
+ IParameterizedSymbol f2Def = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f2.setTypeSymbol( f2Def );
+ factory.addSymbol( f2Def );
+
+ ISymbol c2 = table.newSymbol( "c", TypeInfo.t_char );
+ f2Def.addSymbol( c2 );
+
+ params.clear();
+ args.clear();
+
+ ISymbol X = table.newSymbol( "X", TypeInfo.t_templateParameter );
+
+ params.add( X );
+ args.add( new TypeInfo( TypeInfo.t_char, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_type, 0, X ) );
+
+ factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", params, args );
+
+ look = factory.lookupMemberFunctionForDefinition( "f", new LinkedList() );
+ assertEquals( look, f3 );
+ IParameterizedSymbol f3Def = table.newParameterizedSymbol( "f", TypeInfo.t_function );
+ f3.setTypeSymbol( f3Def );
+ factory.addSymbol( f3Def );
+
+ ISymbol c3 = table.newSymbol( "c", TypeInfo.t_float );
+ f3Def.addSymbol( c3 );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_char, 0, null ) );
+
+ look = table.getCompilationUnit().lookupTemplate( "A", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), A1 );
+
+ look = ((IContainerSymbol)look).qualifiedFunctionLookup( "f", new LinkedList() );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), f1Def );
+
+ look = ((IContainerSymbol)look).qualifiedLookup( "c" );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), c1 );
+ assertTrue( look.isType( TypeInfo.t_int ) );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+
+ look = table.getCompilationUnit().lookupTemplate( "A", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), A2 );
+
+ look = ((IContainerSymbol)look).qualifiedFunctionLookup( "f", new LinkedList() );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), f2Def );
+
+ look = ((IContainerSymbol)look).qualifiedLookup( "c" );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), c2 );
+ assertTrue( look.isType( TypeInfo.t_char ) );
+
+ args.clear();
+ args.add( new TypeInfo( TypeInfo.t_char, 0, null ) );
+ args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
+
+ look = table.getCompilationUnit().lookupTemplate( "A", args );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), A3 );
+
+ look = ((IContainerSymbol)look).qualifiedFunctionLookup( "f", new LinkedList() );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), f3Def );
+
+ look = ((IContainerSymbol)look).qualifiedLookup( "c" );
+ assertTrue( look.isTemplateInstance() );
+ assertEquals( look.getInstantiatedSymbol(), c3 );
+ assertTrue( look.isType( TypeInfo.t_float ) );
+ }
+}