mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
- fixed up CompleteParseASTFactory.lookupQualifiedName in the case where the
tokenDuple has 1 segement - fixed CompleteParseASTFactory.createMethod to handle template ids - fixed instantiation of member templates - fixed up handling of explicit specializations
This commit is contained in:
parent
f0f5aa93c3
commit
63bc5b00d2
14 changed files with 246 additions and 178 deletions
|
@ -889,4 +889,38 @@ public class CompleteParseASTTemplateTest extends CompleteParseBaseTest {
|
|||
assertReferenceTask( new Task( f2, 1, false, false ) );
|
||||
assertReferenceTask( new Task( f3, 1, false, false ) );
|
||||
}
|
||||
|
||||
public void test_14_5_2__2_MemberFunctionTemplates() throws Exception{
|
||||
Writer writer = new StringWriter();
|
||||
writer.write("template < class T > struct A { ");
|
||||
writer.write(" void f( int ); ");
|
||||
writer.write(" template < class T2 > void f( T2 ); ");
|
||||
writer.write("}; ");
|
||||
|
||||
writer.write("template <> void A<int>::f(int) {} //non-template member \n");
|
||||
writer.write("template <> template<> void A<int>::f<>( int ) {} //template member \n");
|
||||
|
||||
writer.write("int main(){ ");
|
||||
writer.write(" A< int > ac; ");
|
||||
writer.write(" ac.f( 1 ); //non-template \n");
|
||||
writer.write(" ac.f( 'c' ); //template \n");
|
||||
writer.write(" ac.f<>(1); //template \n");
|
||||
writer.write("} ");
|
||||
|
||||
Iterator i = parse( writer.toString() ).getDeclarations();
|
||||
|
||||
IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next();
|
||||
IASTTemplateDeclaration spec1 = (IASTTemplateDeclaration) i.next();
|
||||
IASTTemplateDeclaration spec2 = (IASTTemplateDeclaration) i.next();
|
||||
|
||||
IASTMethod f1 = (IASTMethod) spec1.getOwnedDeclaration();
|
||||
IASTMethod f2 = (IASTMethod) spec2.getOwnedDeclaration();;
|
||||
|
||||
IASTFunction main = (IASTFunction) i.next();
|
||||
assertFalse( i.hasNext() );
|
||||
|
||||
assertReferenceTask( new Task( f1, 1, false, false ) );
|
||||
//we aren't going to be completely correct about references to explicit specializations
|
||||
//due to limitations in the implementation, see bug 59811
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,78 +42,6 @@ public class FailingTemplateTests extends TestCase {
|
|||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2004-04-23 Andrew Niefer
|
||||
- fixed up CompleteParseASTFactory.lookupQualifiedName in the case where the
|
||||
tokenDuple has 1 segement
|
||||
- fixed CompleteParseASTFactory.createMethod to handle template ids
|
||||
- fixed instantiation of member templates
|
||||
- fixed up handling of explicit specializations
|
||||
|
||||
2004-04-22 John Camelon
|
||||
Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=47926
|
||||
|
||||
|
|
|
@ -56,4 +56,6 @@ public interface ITokenDuple {
|
|||
* @return
|
||||
*/
|
||||
public abstract boolean syntaxOfName();
|
||||
|
||||
public String extractNameFromTemplateId();
|
||||
}
|
|
@ -297,8 +297,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
else if( name == null ) return null;
|
||||
|
||||
List [] templateArgLists = name.getTemplateIdArgLists();
|
||||
List args = null;
|
||||
int idx = 0;
|
||||
switch( name.length() )
|
||||
String image = null;
|
||||
switch( name.getSegmentCount() )
|
||||
{
|
||||
case 0:
|
||||
if( throwOnError )
|
||||
|
@ -306,14 +308,21 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
else
|
||||
return null;
|
||||
case 1:
|
||||
firstSymbol = name.getFirstToken();
|
||||
result = lookupElement(startingScope, firstSymbol.getImage(), type, parameters, lookup );
|
||||
image = name.extractNameFromTemplateId();
|
||||
args = ( templateArgLists != null ) ? getTemplateArgList( templateArgLists[ 0 ] ) : null;
|
||||
result = lookupElement(startingScope, image, type, parameters, args, lookup );
|
||||
|
||||
if( result != null )
|
||||
{
|
||||
if( lookup == LookupType.FORPARENTSCOPE && startingScope instanceof ITemplateFactory ){
|
||||
((ITemplateFactory)startingScope).pushSymbol( result );
|
||||
if( args != null )
|
||||
((ITemplateFactory)startingScope).pushTemplateId( result, args );
|
||||
else
|
||||
((ITemplateFactory)startingScope).pushSymbol( result );
|
||||
}
|
||||
addReference( references, createReference( result, firstSymbol.getImage(), firstSymbol.getOffset() ));
|
||||
addReference( references, createReference( result, image, name.getStartOffset() ));
|
||||
if( args != null )
|
||||
addTemplateIdReferences( references, templateArgLists[0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -328,7 +337,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
}
|
||||
}
|
||||
if ( throwOnError )
|
||||
handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, firstSymbol.getImage(), -1, -1, firstSymbol.getLineNumber() );
|
||||
handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, image, -1, -1, name.getLineNumber() );
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
|
@ -348,7 +357,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
}
|
||||
if( t.isPointer() ) break;
|
||||
|
||||
String image = t.getImage();
|
||||
image = t.getImage();
|
||||
int offset = t.getOffset();
|
||||
|
||||
if( templateArgLists != null && templateArgLists[ idx ] != null ){
|
||||
|
@ -361,22 +370,19 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
if( result instanceof IDeferredTemplateInstance ){
|
||||
result = ((IDeferredTemplateInstance)result).getTemplate().getTemplatedSymbol();
|
||||
}
|
||||
|
||||
args = ( templateArgLists != null ) ? getTemplateArgList( templateArgLists[ idx ] ) : null;
|
||||
if( t == name.getLastToken() )
|
||||
if( templateArgLists != null )
|
||||
result = lookupElement((IContainerSymbol)result, image, type, parameters, getTemplateArgList( templateArgLists[idx] ), ( lookup == LookupType.FORDEFINITION ) ? lookup : LookupType.QUALIFIED );
|
||||
else
|
||||
result = lookupElement((IContainerSymbol)result, image, type, parameters, ( lookup == LookupType.FORDEFINITION ) ? lookup : LookupType.QUALIFIED );
|
||||
result = lookupElement((IContainerSymbol)result, image, type, parameters, args, ( lookup == LookupType.FORDEFINITION ) ? lookup : LookupType.QUALIFIED );
|
||||
else
|
||||
if( templateArgLists != null && templateArgLists[idx] != null )
|
||||
result = ((IContainerSymbol)result).lookupTemplateId( image, getTemplateArgList( templateArgLists[idx] ) );
|
||||
result = ((IContainerSymbol)result).lookupTemplateId( image, args );
|
||||
else
|
||||
result = ((IContainerSymbol)result).lookupNestedNameSpecifier( image );
|
||||
|
||||
if( result != null ){
|
||||
if( lookup == LookupType.FORPARENTSCOPE && startingScope instanceof ITemplateFactory ){
|
||||
if( templateArgLists != null && templateArgLists[idx] != null )
|
||||
((ITemplateFactory)startingScope).pushTemplateId( result, getTemplateArgList( templateArgLists[idx] ) );
|
||||
((ITemplateFactory)startingScope).pushTemplateId( result, args );
|
||||
else
|
||||
((ITemplateFactory)startingScope).pushSymbol( result );
|
||||
}
|
||||
|
@ -2269,7 +2275,17 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
nameDuple = nameDuple.getLastSegment();
|
||||
}
|
||||
}
|
||||
symbol = pst.newParameterizedSymbol( nameDuple.toString(), TypeInfo.t_function );
|
||||
String methodName = null;
|
||||
List templateIdArgList = null;
|
||||
//template-id?
|
||||
if( nameDuple.getTemplateIdArgLists() != null ){
|
||||
templateIdArgList = nameDuple.getTemplateIdArgLists()[ 0 ];
|
||||
methodName = nameDuple.extractNameFromTemplateId();
|
||||
} else {
|
||||
methodName = nameDuple.toString();
|
||||
}
|
||||
|
||||
symbol = pst.newParameterizedSymbol( methodName, TypeInfo.t_function );
|
||||
setFunctionTypeInfoBits(isInline, isFriend, isStatic, symbol);
|
||||
setMethodTypeInfoBits( symbol, isConst, isVolatile, isVirtual, isExplicit );
|
||||
symbol.setHasVariableArgs( hasVariableArguments );
|
||||
|
@ -2291,9 +2307,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
if(parentName.indexOf(DOUBLE_COLON) != -1){
|
||||
parentName = parentName.substring(parentName.lastIndexOf(DOUBLE_COLON) + DOUBLE_COLON.length());
|
||||
}
|
||||
if( parentName.equals(nameDuple.toString()) ){
|
||||
if( parentName.equals(methodName) ){
|
||||
isConstructor = true;
|
||||
} else if(nameDuple.getFirstToken().getType() == IToken.tCOMPL && parentName.equals(nameDuple.getLastToken().getImage())){
|
||||
} else if(methodName.equals( "~" + parentName )){ //$NON-NLS-1$
|
||||
isDestructor = true;
|
||||
}
|
||||
}
|
||||
|
@ -2318,14 +2334,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
|
||||
List functionReferences = new ArrayList();
|
||||
|
||||
if( isFriend )
|
||||
{
|
||||
functionDeclaration =
|
||||
(IParameterizedSymbol) lookupQualifiedName(ownerScope, nameDuple, isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, functionReferences, false, LookupType.FORFRIENDSHIP );
|
||||
} else {
|
||||
functionDeclaration =
|
||||
(IParameterizedSymbol) lookupQualifiedName(ownerScope, nameDuple.toString(), isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, 0, functionReferences, false, LookupType.FORDEFINITION );
|
||||
}
|
||||
functionDeclaration = (IParameterizedSymbol) lookupQualifiedName( ownerScope, nameDuple,
|
||||
isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function,
|
||||
functionParameters, functionReferences, false,
|
||||
isFriend ? LookupType.FORFRIENDSHIP : LookupType.FORDEFINITION );
|
||||
|
||||
previouslyDeclared = ( functionDeclaration != null ) && functionDeclaration.isType( isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function );
|
||||
|
||||
|
@ -2361,8 +2373,12 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
((IDerivableContainerSymbol)ownerScope).addFriend( functionDeclaration );
|
||||
else
|
||||
((IDerivableContainerSymbol)ownerScope).addFriend( symbol );
|
||||
} else if( !isConstructor )
|
||||
ownerScope.addSymbol( symbol );
|
||||
} else if( !isConstructor ){
|
||||
if( templateIdArgList == null )
|
||||
ownerScope.addSymbol( symbol );
|
||||
else
|
||||
ownerScope.addTemplateId( symbol, getTemplateArgList( templateIdArgList ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol.setType( TypeInfo.t_constructor );
|
||||
|
@ -2380,6 +2396,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
attachSymbolExtension( symbol, method, isFunctionDefinition );
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param symbol
|
||||
* @param constructorChain
|
||||
|
|
|
@ -99,14 +99,21 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
|
|||
|
||||
if( !template.getExplicitSpecializations().isEmpty() ){
|
||||
List argList = new LinkedList();
|
||||
boolean hasAllParams = true;
|
||||
Iterator templateParams = template.getParameterList().iterator();
|
||||
while( templateParams.hasNext() ){
|
||||
argList.add( argMap.get( templateParams.next() ) );
|
||||
Object obj = argMap.get( templateParams.next() );
|
||||
if( obj == null ){
|
||||
hasAllParams = false;
|
||||
break;
|
||||
}
|
||||
argList.add( obj );
|
||||
}
|
||||
if( hasAllParams){
|
||||
ISymbol temp = TemplateEngine.checkForTemplateExplicitSpecialization( template, symbol, argList );
|
||||
if( temp != null )
|
||||
containedSymbol = temp;
|
||||
}
|
||||
|
||||
ISymbol temp = TemplateEngine.checkForTemplateExplicitSpecialization( template, symbol, argList );
|
||||
if( temp != null )
|
||||
containedSymbol = temp;
|
||||
}
|
||||
|
||||
Map instanceMap = argMap;
|
||||
|
@ -797,49 +804,6 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
|
|||
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 );
|
||||
//
|
||||
// Object look = null;
|
||||
// try{
|
||||
// look = ParserSymbolTable.resolveAmbiguities( data );
|
||||
// } catch ( ParserSymbolTableException e ){
|
||||
// if( e.reason != ParserSymbolTableException.r_UnableToResolveFunction ){
|
||||
// throw e;
|
||||
// }
|
||||
// if( !data.foundItems.isEmpty() ){
|
||||
// look = data.foundItems.get( name );
|
||||
// if(!( look instanceof List ) ){
|
||||
// throw new ParserSymbolTableError();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// ITemplateSymbol template = (ITemplateSymbol) (( look instanceof ITemplateSymbol ) ? look : null);
|
||||
// if( template == null ){
|
||||
// if( look instanceof ISymbol ){
|
||||
// ISymbol symbol = (ISymbol) look;
|
||||
// if( symbol.isTemplateMember() && symbol.getContainingSymbol().isType( TypeInfo.t_template ) ){
|
||||
// template = (ITemplateSymbol) symbol.getContainingSymbol();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// if( template != null ){
|
||||
// template = TemplateEngine.selectTemplateOrSpecialization( template, parameters, arguments );
|
||||
// if( template != null ){
|
||||
// return new TemplateFactory( template, parameters, arguments );
|
||||
// }
|
||||
// } else if ( look instanceof List ){
|
||||
// return new TemplateFactory( new HashSet( (List)look ), parameters, arguments );
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
|
||||
|
||||
public List prefixLookup( TypeFilter filter, String prefix, boolean qualified ) throws ParserSymbolTableException{
|
||||
LookupData data = new LookupData( prefix, filter );
|
||||
data.qualified = qualified;
|
||||
|
|
|
@ -42,6 +42,7 @@ public interface ITemplateSymbol extends IParameterizedSymbol {
|
|||
public List findArgumentsFor( IContainerSymbol instance );
|
||||
|
||||
public void addInstantiation( IContainerSymbol instance, List args );
|
||||
public void removeInstantiation( IContainerSymbol symbol );
|
||||
|
||||
public void addExplicitSpecialization( ISymbol symbol, List args ) throws ParserSymbolTableException;
|
||||
|
||||
|
@ -77,8 +78,4 @@ public interface ITemplateSymbol extends IParameterizedSymbol {
|
|||
public static final DeferredKind PARENT = new DeferredKind( 2 );
|
||||
public static final DeferredKind TYPE_SYMBOL = new DeferredKind( 3 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -80,21 +80,24 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
|
|||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
//handle template parameter lists in TemplateSymbol, only do function parameter lists here.
|
||||
if( !isType( TypeInfo.t_template ) ){
|
||||
Iterator iter = getParameterList().iterator();
|
||||
|
||||
newParameterized.getParameterList().add( newParam );
|
||||
if( !newParam.getName().equals( ParserSymbolTable.EMPTY_NAME ) ){
|
||||
newParameterized.getParameterMap().put( newParam.getName(), newParam );
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -565,7 +565,7 @@ public class ParserSymbolTable {
|
|||
}
|
||||
|
||||
if( numTemplateFunctions > 0 ){
|
||||
if( data.parameters != null && !data.exactFunctionsOnly ){
|
||||
if( data.parameters != null && ( !data.exactFunctionsOnly || data.templateParameters != null ) ){
|
||||
List fns = TemplateEngine.selectTemplateFunctions( templateFunctionSet, data.parameters, data.templateParameters );
|
||||
functionSet.addAll( fns );
|
||||
numFunctions = functionSet.size();
|
||||
|
@ -984,7 +984,7 @@ public class ParserSymbolTable {
|
|||
|
||||
reduceToViable( data, functions );
|
||||
|
||||
if( data.exactFunctionsOnly ){
|
||||
if( data.exactFunctionsOnly && data.templateParameters == null ){
|
||||
if( functions.size() == 1 ){
|
||||
return (IParameterizedSymbol) functions.get( 0 );
|
||||
} else if( functions.size() == 0 ){
|
||||
|
@ -1153,7 +1153,10 @@ public class ParserSymbolTable {
|
|||
if( !hasWorse ){
|
||||
if( !hasBetter ){
|
||||
//if they are both template functions, we can order them that way
|
||||
if( bestFn.isTemplateInstance() && currFn.isTemplateInstance() ){
|
||||
boolean bestIsTemplate = bestFn.getContainingSymbol() instanceof ITemplateSymbol;
|
||||
boolean currIsTemplate = currFn.getContainingSymbol() instanceof ITemplateSymbol;
|
||||
if( bestIsTemplate && currIsTemplate )
|
||||
{
|
||||
ITemplateSymbol t1 = (ITemplateSymbol) bestFn.getInstantiatedSymbol().getContainingSymbol();
|
||||
ITemplateSymbol t2 = (ITemplateSymbol) currFn.getInstantiatedSymbol().getContainingSymbol();
|
||||
int order = TemplateEngine.orderTemplateFunctions( t1, t2 );
|
||||
|
@ -1163,13 +1166,13 @@ public class ParserSymbolTable {
|
|||
ambiguous = false;
|
||||
}
|
||||
}
|
||||
//we prefer normal functions over template functions, unless the specified template arguments
|
||||
else if( bestFn.isTemplateInstance() && !currFn.isTemplateInstance() ){
|
||||
//we prefer normal functions over template functions, unless we specified template arguments
|
||||
else if( bestIsTemplate && !currIsTemplate ){
|
||||
if( data.templateParameters == null )
|
||||
hasBetter = true;
|
||||
else
|
||||
ambiguous = false;
|
||||
} else if( !bestFn.isTemplateInstance() && currFn.isTemplateInstance() ){
|
||||
} else if( !bestIsTemplate && currIsTemplate ){
|
||||
if( data.templateParameters == null )
|
||||
ambiguous = false;
|
||||
else
|
||||
|
|
|
@ -1297,8 +1297,8 @@ public final class TemplateEngine {
|
|||
return false;
|
||||
}
|
||||
|
||||
ITemplateSymbol t1 = (ITemplateSymbol) getContainingTemplate( p1 );//.getContainingSymbol();
|
||||
ITemplateSymbol t2 = (ITemplateSymbol) getContainingTemplate( p2 );//.getContainingSymbol();
|
||||
ITemplateSymbol t1 = getContainingTemplate( p1 );
|
||||
ITemplateSymbol t2 = getContainingTemplate( p2 );
|
||||
|
||||
if( p1.getTypeInfo().getTemplateParameterType() == TypeInfo.t_typeName )
|
||||
{
|
||||
|
|
|
@ -57,7 +57,8 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
|
|||
*/
|
||||
public void addTemplateId(ISymbol symbol, List args) throws ParserSymbolTableException {
|
||||
ISymbol previous = findPreviousSymbol( symbol, args );
|
||||
ITemplateSymbol origTemplate = (previous != null ) ? (ITemplateSymbol) previous.getContainingSymbol() : null;
|
||||
ITemplateSymbol origTemplate = (previous != null && previous.getContainingSymbol() instanceof ITemplateSymbol )
|
||||
? (ITemplateSymbol) previous.getContainingSymbol() : null;
|
||||
|
||||
if( origTemplate == null ){
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
|
||||
|
@ -131,7 +132,6 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
|
|||
int numSymbols = symbols.size();
|
||||
|
||||
if( templateParamState ){
|
||||
ITemplateSymbol template = (ITemplateSymbol) container.getContainingSymbol();
|
||||
List args = (List) argMap.get( container );
|
||||
addExplicitSpecialization( (ITemplateSymbol) container.getContainingSymbol(), symbol, args );
|
||||
return;
|
||||
|
@ -311,6 +311,19 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
|
|||
private void addExplicitSpecialization( ITemplateSymbol template, ISymbol symbol, List arguments ) throws ParserSymbolTableException {
|
||||
template.addExplicitSpecialization( symbol, arguments );
|
||||
|
||||
Iterator i = symbols.iterator();
|
||||
while( i.hasNext() ){
|
||||
IContainerSymbol sym = (IContainerSymbol) i.next();
|
||||
ISymbol instantiated = sym.getInstantiatedSymbol();
|
||||
if( instantiated != null ){
|
||||
IContainerSymbol container = instantiated.getContainingSymbol();
|
||||
if( container.isType( TypeInfo.t_template ) ){
|
||||
((ITemplateSymbol) container ).removeInstantiation( sym );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( getASTExtension() != null ){
|
||||
ASTTemplateSpecialization spec = (ASTTemplateSpecialization) getASTExtension().getPrimaryDeclaration();
|
||||
spec.setOwnedDeclaration( symbol );
|
||||
|
@ -527,7 +540,7 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
|
|||
|
||||
if( look instanceof ITemplateSymbol ){
|
||||
ITemplateSymbol t = TemplateEngine.selectTemplateOrSpecialization( (ITemplateSymbol) look, getNextAvailableTemplate().getParameterList(), arguments );
|
||||
look = ((ITemplateSymbol) look).getTemplatedSymbol();
|
||||
look = t.getTemplatedSymbol();
|
||||
}
|
||||
return (IContainerSymbol) (( look instanceof IContainerSymbol) ? look : null);
|
||||
}
|
||||
|
|
|
@ -162,6 +162,26 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
|||
}
|
||||
}
|
||||
|
||||
public ISymbol instantiate( ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
|
||||
if( !isTemplateMember() ){
|
||||
return null;
|
||||
}
|
||||
|
||||
TemplateSymbol newTemplate = (TemplateSymbol) super.instantiate( template, argMap );
|
||||
|
||||
//we don't want to instantiate the template parameters, just the defaults if there are any
|
||||
Iterator iter = newTemplate.getParameterList().iterator();
|
||||
ISymbol param = null;
|
||||
while( iter.hasNext() ){
|
||||
param = (ISymbol) iter.next();
|
||||
Object obj = param.getTypeInfo().getDefault();
|
||||
if( obj instanceof TypeInfo ){
|
||||
param.getTypeInfo().setDefault( TemplateEngine.instantiateTypeInfo( (TypeInfo) obj, template, argMap ) );
|
||||
}
|
||||
}
|
||||
|
||||
return newTemplate;
|
||||
}
|
||||
|
||||
public void addParameter( ISymbol param ) {
|
||||
throw new ParserSymbolTableError( ParserSymbolTableError.r_OperationNotSupported );
|
||||
|
@ -278,11 +298,24 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
|||
if( found == null && getTemplatedSymbol().getName().equals( symbol.getName() ) ){
|
||||
found = getTemplatedSymbol();
|
||||
|
||||
IContainerSymbol instance = findInstantiation( args );
|
||||
IContainerSymbol instance = findInstantiation( actualArgs );
|
||||
if( instance != null ){
|
||||
_instantiations.remove( findArgumentsFor( instance ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( found != null && found.getTypeInfo().isForwardDeclaration() && found.getTypeSymbol() == symbol ){
|
||||
//in defining the explicit specialization for a member function, the factory would have set
|
||||
//the specialization as the definition of the original declaration, which it is not
|
||||
found.setTypeSymbol( null );
|
||||
}
|
||||
|
||||
//TODO, once we can instantiate members as we need them instead of at the same time as the class
|
||||
//then found should stay as the instance, for now though, we need the original (not 100% correct
|
||||
//but the best we can do for now)
|
||||
while( found.isTemplateInstance() ){
|
||||
found = found.getInstantiatedSymbol();
|
||||
}
|
||||
|
||||
if( found != null ){
|
||||
symbol.setIsTemplateMember( true );
|
||||
|
@ -357,6 +390,13 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
|||
return null;
|
||||
}
|
||||
|
||||
public void removeInstantiation( IContainerSymbol symbol ){
|
||||
List args = findArgumentsFor( symbol );
|
||||
if( args != null ){
|
||||
_instantiations.remove( args );
|
||||
}
|
||||
}
|
||||
|
||||
public Map getDefinitionParameterMap(){
|
||||
if( _defnParameterMap == null ){
|
||||
_defnParameterMap = new HashMap();
|
||||
|
|
|
@ -229,6 +229,7 @@ public class TypeInfo {
|
|||
"enum", //$NON-NLS-1$ t_enumeration
|
||||
"", //$NON-NLS-1$ t_constructor
|
||||
"", //$NON-NLS-1$ t_function
|
||||
"_Bool", //$NON-NLS-1$ t__Bool
|
||||
"bool", //$NON-NLS-1$ t_bool
|
||||
"char", //$NON-NLS-1$ t_char
|
||||
"wchar_t", //$NON-NLS-1$ t_wchar_t
|
||||
|
@ -240,7 +241,9 @@ public class TypeInfo {
|
|||
"", //$NON-NLS-1$ t_block
|
||||
"template", //$NON-NLS-1$ t_template
|
||||
"", //$NON-NLS-1$ t_asm
|
||||
"" //$NON-NLS-1$ t_linkage
|
||||
"", //$NON-NLS-1$ t_linkage
|
||||
"", //$NON-NLS-1$ t_templateParameter
|
||||
"typename" //$NON-NLS-1$ t_typeName
|
||||
};
|
||||
//Partial ordering :
|
||||
// none < const
|
||||
|
|
|
@ -437,4 +437,59 @@ public class TokenDuple implements ITokenDuple {
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public String extractNameFromTemplateId(){
|
||||
ITokenDuple nameDuple = getLastSegment();
|
||||
|
||||
Iterator i = nameDuple.iterator();
|
||||
|
||||
if( !i.hasNext() )
|
||||
return "";//$NON-NLS-1$
|
||||
|
||||
StringBuffer nameBuffer = new StringBuffer();
|
||||
IToken token = (IToken) i.next();
|
||||
nameBuffer.append( token.getImage() );
|
||||
|
||||
if( !i.hasNext() )
|
||||
return nameBuffer.toString();
|
||||
|
||||
//appending of spaces needs to be the same as in toString()
|
||||
|
||||
//destructors
|
||||
if( token.getType() == IToken.tCOMPL ){
|
||||
token = (IToken) i.next();
|
||||
nameBuffer.append( token.getImage() );
|
||||
}
|
||||
//operators
|
||||
else if( token.getType() == IToken.t_operator ){
|
||||
token = (IToken) i.next();
|
||||
nameBuffer.append( ' ' );
|
||||
nameBuffer.append( token.getImage() );
|
||||
|
||||
if( !i.hasNext() )
|
||||
return nameBuffer.toString();
|
||||
|
||||
//operator new [] and operator delete []
|
||||
if( (token.getType() == IToken.t_new || token.getType() == IToken.t_delete) &&
|
||||
(token.getNext().getType() == IToken.tLBRACKET ) )
|
||||
{
|
||||
nameBuffer.append( ' ' );
|
||||
nameBuffer.append( ((IToken)i.next()).getImage() );
|
||||
nameBuffer.append( ((IToken)i.next()).getImage() );
|
||||
}
|
||||
//operator []
|
||||
else if( token.getType() == IToken.tLBRACKET )
|
||||
{
|
||||
nameBuffer.append( ((IToken)i.next()).getImage() );
|
||||
}
|
||||
//operator ( )
|
||||
else if( token.getType() == IToken.tLBRACE )
|
||||
{
|
||||
nameBuffer.append( ' ' );
|
||||
nameBuffer.append( ((IToken)i.next()).getImage() );
|
||||
}
|
||||
}
|
||||
|
||||
return nameBuffer.toString();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue