diff options
author | Vladimir Hirsl | 2004-09-30 19:45:57 +0000 |
---|---|---|
committer | Vladimir Hirsl | 2004-09-30 19:45:57 +0000 |
commit | 440ada9babc913469206db9535b0a47189a4bf9d (patch) | |
tree | 4f4a47f1032fdca2b20c9b574542119df96f12cb /core/org.eclipse.cdt.core | |
parent | 851bf3eea656671723fd5e3c064104bed01c3de0 (diff) | |
download | org.eclipse.cdt-440ada9babc913469206db9535b0a47189a4bf9d.tar.gz org.eclipse.cdt-440ada9babc913469206db9535b0a47189a4bf9d.tar.xz org.eclipse.cdt-440ada9babc913469206db9535b0a47189a4bf9d.zip |
Fix for PR 60307 [Templates] Template parameter qualified types not supported
Added new symbol type: UndefinedTemplateSymbol that represents template paramater
qualified types. At instantiation the unknown types are replaced with the real ones.
Diffstat (limited to 'core/org.eclipse.cdt.core')
11 files changed, 888 insertions, 76 deletions
diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index 668a5ec480e..3da8fc6931e 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,24 @@ +2004-09-30 Vladimir Hirsl + + Fix for PR 60307 [Templates] Template parameter qualified types not supported + Added new symbol type: UndefinedTemplateSymbol that represents template paramater + qualified types. At instantiation the unknown types are replaced with the real ones. + + * parser/org/eclipse/cdt/internal/core/parser/Parser.java + * parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTNode.java + * parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java + * parser/org/eclipse/cdt/internal/core/parser/ast/ContainerSymbol.java + * parser/org/eclipse/cdt/internal/core/parser/ast/IContainerSymbol.java + * parser/org/eclipse/cdt/internal/core/parser/ast/ParametrizedSymbol.java + * parser/org/eclipse/cdt/internal/core/parser/ast/ParserSymbolTable.java + * parser/org/eclipse/cdt/internal/core/parser/ast/TemplateEngine.java + * parser/org/eclipse/cdt/internal/core/parser/ast/TemplateFactory.java + + parser/org/eclipse/cdt/internal/core/parser/ast/UndefinedTemplateSymbol.java + + * failures/org/eclipse/cdt/core/parser/failedTests/FailedCompleteParseASTTest.java + * parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.java + * parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java + 2004-09-22 Chris Wiebe show warnings instead of errors for invalid filenames diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java index 03cfa4cfac6..fd6e66d8b08 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java @@ -503,12 +503,11 @@ public class Parser implements IParserData, IParser setCompletionValues(scope, kind, getCompliationUnit()); else if (prev != null) setCompletionValues(scope, kind, first, prev, - KeywordSetKey.EMPTY); + argumentList.getTemplateArgumentsList(), KeywordSetKey.EMPTY); else setCompletionValuesNoContext(scope, kind, key); - last = consumeTemplateArguments(scope, last, argumentList, - kind); + last = consumeTemplateArguments(scope, last, argumentList, kind); if (last.getType() == IToken.tGT) hasTemplateId = true; break; @@ -522,8 +521,8 @@ public class Parser implements IParserData, IParser while (LT(1) == IToken.tCOLONCOLON) { IToken prev = last; last = consume(IToken.tCOLONCOLON); - setCompletionValues(scope, kind, first, prev, - KeywordSetKey.EMPTY); + setCompletionValues(scope, kind, first, prev, + argumentList.getTemplateArgumentsList(), KeywordSetKey.EMPTY); if (queryLookaheadCapability() && LT(1) == IToken.t_template) consume(); @@ -539,8 +538,8 @@ public class Parser implements IParserData, IParser case IToken.tIDENTIFIER : prev = last; last = consume(); - setCompletionValues(scope, kind, first, prev, - KeywordSetKey.EMPTY); + setCompletionValues(scope, kind, first, prev, + argumentList.getTemplateArgumentsList(), KeywordSetKey.EMPTY); last = consumeTemplateArguments(scope, last, argumentList, kind); if (last.getType() == IToken.tGT) @@ -3997,8 +3996,7 @@ public class Parser implements IParserData, IParser Declarator declarator = null; if (LT(1) != IToken.tSEMI) { - declarator = initDeclarator(sdw, strategy, completionKindForDeclaration, constructInitializersInDeclarations - ); + declarator = initDeclarator(sdw, strategy, completionKindForDeclaration, constructInitializersInDeclarations); while (LT(1) == IToken.tCOMMA) { @@ -4654,19 +4652,10 @@ public class Parser implements IParserData, IParser sdw.setTypenamed(true); consume(IToken.t_typename); IToken first = LA(1); - IToken last = null; - last = name(sdw.getScope(), CompletionKind.TYPE_REFERENCE, - KeywordSetKey.EMPTY).getLastToken(); - if (LT(1) == IToken.t_template) { - consume(IToken.t_template); - last = templateId(sdw.getScope(), - CompletionKind.SINGLE_NAME_REFERENCE); - } - if (sdw.getName() != null) - first = sdw.getName().getFirstToken(); - ITokenDuple duple = TokenFactory.createTokenDuple(first, - last); + ITokenDuple duple = name(sdw.getScope(), CompletionKind.TYPE_REFERENCE, + KeywordSetKey.EMPTY); sdw.setTypeName(duple); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME); flags.setEncounteredTypename(true); break; case IToken.tCOLONCOLON : @@ -4694,8 +4683,7 @@ public class Parser implements IParserData, IParser setCompletionValues(sdw.getScope(), kind, key); ITokenDuple d = name(sdw.getScope(), kind, key); sdw.setTypeName(d); - sdw - .setSimpleType(IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME); flags.setEncounteredTypename(true); break; case IToken.t_class : @@ -6413,14 +6401,13 @@ public class Parser implements IParserData, IParser } - - protected void setCompletionValues( IASTScope scope, CompletionKind kind, IToken first, IToken last, KeywordSetKey key ) throws EndOfFileException{ + protected void setCompletionValues( IASTScope scope, CompletionKind kind, IToken first, IToken last, List arguments, KeywordSetKey key ) throws EndOfFileException{ if( mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE ) { setCompletionScope( scope ); setCompletionKind( kind ); setCompletionKeywords(key); - ITokenDuple duple = TokenFactory.createTokenDuple( first, last ); + ITokenDuple duple = TokenFactory.createTokenDuple( first, last, arguments ); try { setCompletionContext( astFactory.lookupSymbolInContext( scope, duple, null ) ); } catch (ASTNotImplementedException e) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTNode.java index aae921c6a81..3385b88985f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTNode.java @@ -49,6 +49,10 @@ public class ASTNode implements IASTNode { IContainerSymbol thisContainer = (IContainerSymbol) symbol; IContainerSymbol qualification = ( context != null ) ? ((ASTNode)context).getLookupQualificationSymbol() : null; + // trying to dereference a context of unknown type + if (context != null && qualification == null) + return null; + List parameters = createLookupParameterList( functionParameters ); int paramIndex = ( parameters != null ) ? parameters.size() : 0; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index b23f208e6b8..c7a024190b9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -98,6 +98,7 @@ 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.TemplateSymbolExtension; import org.eclipse.cdt.internal.core.parser.pst.TypeInfoProvider; +import org.eclipse.cdt.internal.core.parser.pst.UndefinedTemplateSymbol; import org.eclipse.cdt.internal.core.parser.pst.ISymbolASTExtension.ExtensionException; import org.eclipse.cdt.internal.core.parser.token.TokenFactory; import org.eclipse.cdt.internal.core.parser.util.TraceUtil; @@ -388,8 +389,19 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto try { - if( result instanceof IDeferredTemplateInstance ){ - result = ((IDeferredTemplateInstance)result).getTemplate().getTemplatedSymbol(); + while ( ! ( result instanceof IContainerSymbol ) ) { + if ( result.getTypeInfo().checkBit( ITypeInfo.isTypedef )) { + result = result.getTypeSymbol(); + } + else if( result instanceof IDeferredTemplateInstance ){ + result = ((IDeferredTemplateInstance)result).getTemplate().getTemplatedSymbol(); + } + else { + if (throwOnError) + handleProblem( IProblem.SEMANTIC_NAME_NOT_PROVIDED, image, t.getOffset(), t.getEndOffset(), t.getLineNumber(), true ); + else + return null; + } } args = ( templateArgLists != null ) ? getTemplateArgList( templateArgLists[ idx ] ) : null; if( t == last ) @@ -894,7 +906,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto //Its possible that the parent is not an IContainerSymbol if its a template parameter or some kinds of template instances ISymbol symbol = lookupQualifiedName( classSymbol, parentClassName, references, true ); - if( symbol instanceof ITemplateSymbol ) + if( symbol instanceof ITemplateSymbol && + ! ( symbol instanceof UndefinedTemplateSymbol ) ) handleProblem( IProblem.SEMANTIC_INVALID_TEMPLATE_ARGUMENT, parentClassName.toCharArray(), parentClassName.getStartOffset(), parentClassName.getEndOffset(), parentClassName.getLineNumber(), true); List [] templateArgumentLists = parentClassName.getTemplateIdArgLists(); @@ -2007,6 +2020,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto idx++; continue; } + if( current.getType() == IToken.t_template ){ + continue; + } char[] image = current.getCharImage(); int offset = current.getOffset(); @@ -2016,8 +2032,16 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto current = TokenFactory.consumeTemplateIdArguments( current.getNext(), last ); } - if( typeSymbol instanceof IDeferredTemplateInstance ){ - typeSymbol = ((IDeferredTemplateInstance)typeSymbol).getTemplate().getTemplatedSymbol(); + while ( ! ( typeSymbol instanceof IContainerSymbol ) ) { + if ( typeSymbol.getTypeInfo().checkBit( ITypeInfo.isTypedef )) { + typeSymbol = typeSymbol.getTypeSymbol(); + } + else if( typeSymbol instanceof IDeferredTemplateInstance ){ + typeSymbol = ((IDeferredTemplateInstance)typeSymbol).getTemplate().getTemplatedSymbol(); + } + else { + handleProblem( IProblem.SEMANTIC_INVALID_TYPE, image, current.getOffset(), current.getEndOffset(), current.getLineNumber(), true ); + } } try { @@ -2025,8 +2049,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto typeSymbol = ((IContainerSymbol)typeSymbol).lookupTemplateId( image, getTemplateArgList( argLists[idx] ) ); else if( current != last ) typeSymbol = ((IContainerSymbol)typeSymbol).lookupNestedNameSpecifier( image ); - else + else if ( typeName.getSegmentCount() == 1 ) // a single segment typeSymbol = ((IContainerSymbol)typeSymbol).lookup( image ); + else + typeSymbol = ((IContainerSymbol)typeSymbol).qualifiedLookup( image ); if( typeSymbol != null ) { @@ -3059,7 +3085,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto } else { if( kind == ParamKind.CLASS || kind == ParamKind.TYPENAME ){ - symbol = pst.newSymbol( identifier ); + // to allow for template parameter qualified typedefs + // i.e. typedef typename T::some_type some_type; + // symbol = pst.newSymbol( identifier ); + symbol = pst.newUndefinedTemplateSymbol( identifier ); provider.setType( ITypeInfo.t_templateParameter ); provider.setTemplateParameterType( ITypeInfo.t_typeName ); symbol.setTypeInfo( provider.completeConstruction() ); @@ -3638,8 +3667,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto } } } - if ( s == null ) return null; - return s.getASTExtension().getPrimaryDeclaration(); + if ( s != null && s.getASTExtension() != null) + return s.getASTExtension().getPrimaryDeclaration(); + return null; } public ISymbol lookupSymbolInNewExpression( IASTScope scope, ITokenDuple duple, ASTExpression expression ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java index 56b0a5c3d37..75dd08ac60d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java @@ -578,16 +578,19 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { * the ::, object, function and enumerator names are ignored. If the name * is not a class-name or namespace-name, the program is ill-formed */ - public IContainerSymbol lookupNestedNameSpecifier( char[] name ) throws ParserSymbolTableException { + public ISymbol lookupNestedNameSpecifier( char[] name ) throws ParserSymbolTableException { return lookupNestedNameSpecifier( name, this ); } - private IContainerSymbol lookupNestedNameSpecifier(char[] name, IContainerSymbol inSymbol ) throws ParserSymbolTableException{ + + private ISymbol lookupNestedNameSpecifier(char[] name, IContainerSymbol inSymbol ) throws ParserSymbolTableException{ ISymbol foundSymbol = null; final TypeFilter filter = new TypeFilter( ITypeInfo.t_namespace ); filter.addAcceptedType( ITypeInfo.t_class ); filter.addAcceptedType( ITypeInfo.t_struct ); filter.addAcceptedType( ITypeInfo.t_union ); + filter.addAcceptedType( ITypeInfo.t_templateParameter ); + filter.addAcceptedType( IASTNode.LookupKind.TYPEDEFS ); LookupData data = new LookupData( name ){ public TypeFilter getFilter() { return typeFilter; } @@ -600,10 +603,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { foundSymbol = getSymbolTable().resolveAmbiguities( data ); } - if( foundSymbol instanceof IContainerSymbol ) - return (IContainerSymbol) foundSymbol; - - return null; + return foundSymbol; } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java index d0b42b401bc..e9a13e99037 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java @@ -102,7 +102,7 @@ public interface IContainerSymbol extends ISymbol { public ISymbol lookup( char[] name ) throws ParserSymbolTableException; public ISymbol lookupMemberForDefinition( char[] name ) throws ParserSymbolTableException; public IParameterizedSymbol lookupMethodForDefinition( char[] name, List parameters ) throws ParserSymbolTableException; - public IContainerSymbol lookupNestedNameSpecifier( char[] name ) throws ParserSymbolTableException; + public ISymbol lookupNestedNameSpecifier( char[] name ) throws ParserSymbolTableException; public ISymbol qualifiedLookup( char[] name ) throws ParserSymbolTableException; public ISymbol qualifiedLookup( char[] name, ITypeInfo.eType t ) throws ParserSymbolTableException; public IParameterizedSymbol unqualifiedFunctionLookup( char[] name, List parameters ) throws ParserSymbolTableException; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java index e92c328723a..4838b3c2103 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java @@ -97,7 +97,7 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz * @param symbol2 * @param map */ - public void discardDeferredReturnType(ISymbol oldReturnType, TemplateSymbol template, ObjectMap map) { + public void discardDeferredReturnType(ISymbol oldReturnType, ITemplateSymbol template, ObjectMap map) { ISymbol returnType = getReturnType(); setReturnType( null ); template.removeInstantiation( (IContainerSymbol) returnType ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java index fbcf091abff..596da637555 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java @@ -102,6 +102,16 @@ public class ParserSymbolTable { return new TemplateFactory( this ); } + public ISymbol newUndefinedTemplateSymbol(char[] name) { + if( name == null ) name = EMPTY_NAME_ARRAY; + return new UndefinedTemplateSymbol( this, name ); + } + + public ISymbol newUndefinedTemplateSymbol(char[] name, ITypeInfo.eType type ){ + if( name == null ) name = EMPTY_NAME_ARRAY; + return new UndefinedTemplateSymbol( this, name, type ); + } + /** * Lookup the name from LookupData starting in the inDeclaration * @param data @@ -2142,7 +2152,8 @@ public class ParserSymbolTable { } } - if( info.isType( ITypeInfo.t_class, ITypeInfo.t_enumeration ) || info.isType( ITypeInfo.t_function ) ){ + if( info.isType( ITypeInfo.t_class, ITypeInfo.t_enumeration ) || info.isType( ITypeInfo.t_function ) || + ( info.isType( ITypeInfo.t_undef ) && typeSymbol instanceof UndefinedTemplateSymbol ) ) { returnInfo.setType( ITypeInfo.t_type ); returnInfo.setTypeSymbol( typeSymbol ); } else { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java index 81ec07d2eac..f6563fbef54 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java @@ -28,36 +28,46 @@ public final class TemplateEngine { static protected ITypeInfo instantiateTypeInfo( ITypeInfo info, ITemplateSymbol template, ObjectMap argMap ) throws ParserSymbolTableException{ if( argMap == null ) return info; - - if( info.isType( ITypeInfo.t_type ) && info.getTypeSymbol() == null ) - return info; - if( info.isType( ITypeInfo.t_type ) && info.getTypeSymbol() instanceof IDeferredTemplateInstance ){ - IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) info.getTypeSymbol(); - ITypeInfo newInfo = TypeInfoProvider.newTypeInfo( info ); - //newInfo.setTypeSymbol( deferred.instantiate( template, argMap ) ); - template.registerDeferredInstatiation( newInfo, deferred, ITemplateSymbol.DeferredKind.TYPE_SYMBOL, argMap ); - newInfo.setTypeSymbol( deferred ); - return newInfo; - } else if( info.isType( ITypeInfo.t_type ) && - info.getTypeSymbol().isType( ITypeInfo.t_templateParameter ) && - argMap.containsKey( info.getTypeSymbol() ) ) - { - ITypeInfo targetInfo = TypeInfoProvider.newTypeInfo( (ITypeInfo) argMap.get( info.getTypeSymbol() ) ); - if( info.hasPtrOperators() ){ - targetInfo.addPtrOperator( info.getPtrOperators() ); + ISymbol typeSymbol = info.getTypeSymbol(); + if( info.isType( ITypeInfo.t_type ) ) { + if ( info.getTypeSymbol() == null ) { + return info; + } + if( typeSymbol instanceof IDeferredTemplateInstance ){ + IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) info.getTypeSymbol(); + ITypeInfo newInfo = TypeInfoProvider.newTypeInfo( info ); + //newInfo.setTypeSymbol( deferred.instantiate( template, argMap ) ); + template.registerDeferredInstatiation( newInfo, deferred, ITemplateSymbol.DeferredKind.TYPE_SYMBOL, argMap ); + newInfo.setTypeSymbol( deferred ); + return newInfo; + } else if ( typeSymbol instanceof UndefinedTemplateSymbol && + ( typeSymbol.isType( ITypeInfo.t_template ) || + typeSymbol.isType( ITypeInfo.t_undef ) ) ) { + ITemplateSymbol deferred = (ITemplateSymbol) info.getTypeSymbol(); + ITypeInfo newInfo = TypeInfoProvider.newTypeInfo( info ); + template.registerDeferredInstatiation( newInfo, deferred, ITemplateSymbol.DeferredKind.TYPE_SYMBOL, argMap ); + newInfo.setTypeSymbol( deferred ); + return newInfo; + } else if( typeSymbol.isType( ITypeInfo.t_templateParameter ) && + argMap.containsKey( info.getTypeSymbol() ) ) + { + ITypeInfo targetInfo = TypeInfoProvider.newTypeInfo( (ITypeInfo) argMap.get( info.getTypeSymbol() ) ); + if( info.hasPtrOperators() ){ + targetInfo.addPtrOperator( info.getPtrOperators() ); + } + + if( info.checkBit( ITypeInfo.isConst ) ) + targetInfo.setBit( true, ITypeInfo.isConst ); + + if( info.checkBit( ITypeInfo.isVolatile ) ) + targetInfo.setBit( true, ITypeInfo.isVolatile ); + + return targetInfo; + } else if( typeSymbol.isType( ITypeInfo.t_function ) ){ + ITypeInfo newInfo = TypeInfoProvider.newTypeInfo( info ); + newInfo.setTypeSymbol( info.getTypeSymbol().instantiate( template, argMap ) ); + return newInfo; } - - if( info.checkBit( ITypeInfo.isConst ) ) - targetInfo.setBit( true, ITypeInfo.isConst ); - - if( info.checkBit( ITypeInfo.isVolatile ) ) - targetInfo.setBit( true, ITypeInfo.isVolatile ); - - return targetInfo; - } else if( info.isType( ITypeInfo.t_type ) && info.getTypeSymbol().isType( ITypeInfo.t_function ) ){ - ITypeInfo newInfo = TypeInfoProvider.newTypeInfo( info ); - newInfo.setTypeSymbol( info.getTypeSymbol().instantiate( template, argMap ) ); - return newInfo; } return info; @@ -72,7 +82,7 @@ public final class TemplateEngine { * @param symbol * @param map */ - public static void discardDeferredTypeInfo(ITypeInfo info, TemplateSymbol template, ObjectMap map) { + public static void discardDeferredTypeInfo(ITypeInfo info, ITemplateSymbol template, ObjectMap map) { ISymbol instance = info.getTypeSymbol(); if( !(instance instanceof IDeferredTemplateInstance ) ) template.removeInstantiation( (IContainerSymbol) instance ); @@ -1104,7 +1114,7 @@ public final class TemplateEngine { */ static protected ISymbol instantiateWithinTemplateScope( IContainerSymbol container, ITemplateSymbol symbol ) throws ParserSymbolTableException { - if( symbol.getTemplatedSymbol().isType( ITypeInfo.t_function ) ){ + if( symbol.getTemplatedSymbol() == null || symbol.getTemplatedSymbol().isType( ITypeInfo.t_function ) ){ return symbol; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java index ddb72fae18e..4b026f2c198 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java @@ -407,7 +407,7 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupNestedNameSpecifier(java.lang.String) */ - public IContainerSymbol lookupNestedNameSpecifier(char[] name) throws ParserSymbolTableException { + public ISymbol lookupNestedNameSpecifier(char[] name) throws ParserSymbolTableException { return getContainingSymbol().lookupNestedNameSpecifier( name ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/UndefinedTemplateSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/UndefinedTemplateSymbol.java new file mode 100644 index 00000000000..08e584e8e5c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/UndefinedTemplateSymbol.java @@ -0,0 +1,749 @@ +/********************************************************************** + * Copyright (c) 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 v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.internal.core.parser.pst; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.core.parser.ast.IASTNode; +import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; +import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.internal.core.parser.pst.ITypeInfo.PtrOp; +import org.eclipse.cdt.internal.core.parser.pst.ITypeInfo.eType; +import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.LookupData; + +/** + * A symbol type representing a template parameter as a scope + * example: <code> + * template <typename T> + * class A { + * typedef typename T::some_type some_type; + * }; + * </code> + * Actual template argument is expected to have type 'some_type' but + * that cannot be confirmed until the templated class is instantiated. + * A symbol that represents T requires some behaviour of IContainerSymbol. + * 'some_type' symbol will be added to this container as an unknown type + * so that at the time of instantiation it can be replaced with real type symbol. + * + * @author vhirsl + */ +public class UndefinedTemplateSymbol extends BasicSymbol implements ITemplateSymbol { + + // ContainerSymbol + private List _contents = Collections.EMPTY_LIST; //ordered list of all contents of this symbol + private CharArrayObjectMap _containedSymbols = CharArrayObjectMap.EMPTY_MAP; //declarations contained by us. +// private List _usingDirectives = Collections.EMPTY_LIST; //collection of nominated namespaces + // TemplateSymbol + // these are actually arguments in case of + // typedef typename T::template B<U, char>::some_type some_type; + // ^ ^^^^ + private List _argumentList = Collections.EMPTY_LIST; //list of template arguments + private ObjectMap _instantiations = ObjectMap.EMPTY_MAP; + + /** + * @param table + * @param name + */ + public UndefinedTemplateSymbol(ParserSymbolTable table, char[] name) { + super(table, name); + } + + /** + * @param table + * @param name + * @param typeInfo + */ + public UndefinedTemplateSymbol(ParserSymbolTable table, char[] name, eType typeInfo) { + super(table, name, typeInfo); + } + + public Object clone() { + UndefinedTemplateSymbol copy = (UndefinedTemplateSymbol) super.clone(); + + copy._containedSymbols = (CharArrayObjectMap) ( ( _containedSymbols != CharArrayObjectMap.EMPTY_MAP )? _containedSymbols.clone() : _containedSymbols ); + copy._contents = (_contents != Collections.EMPTY_LIST) ? (List) ((ArrayList)_contents).clone() : _contents; + + copy._instantiations = ( _instantiations != ObjectMap.EMPTY_MAP ) ? (ObjectMap)_instantiations.clone() : _instantiations; + copy._argumentList = ( _argumentList != Collections.EMPTY_LIST ) ? (List) ((ArrayList)_argumentList).clone() : _argumentList; + + return copy; + } + + /* + * IContainerSymbol -------------------------------------------------------- + */ + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol) + */ + public void addSymbol(ISymbol obj) throws ParserSymbolTableException { + IContainerSymbol containing = this; + + // We are expecting another UTS + if ( ! ( obj instanceof UndefinedTemplateSymbol) ) { + throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError ); + } + + obj.setContainingSymbol( containing ); + ((UndefinedTemplateSymbol)containing).putInContainedSymbols( obj.getName(), obj ); + obj.setIsTemplateMember( isTemplateMember() || getType() == ITypeInfo.t_template ); + + addToContents( obj ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addTemplateId(org.eclipse.cdt.internal.core.parser.pst.ISymbol, java.util.List) + */ + public void addTemplateId(ISymbol symbol, List args) throws ParserSymbolTableException { + throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#hasUsingDirectives() + */ + public boolean hasUsingDirectives() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getUsingDirectives() + */ + public List getUsingDirectives() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDirective(org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol) + */ + public IUsingDirectiveSymbol addUsingDirective(IContainerSymbol namespace) throws ParserSymbolTableException { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDeclaration(char[]) + */ + public IUsingDeclarationSymbol addUsingDeclaration(char[] name) + throws ParserSymbolTableException { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDeclaration(char[], org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol) + */ + public IUsingDeclarationSymbol addUsingDeclaration(char[] name, + IContainerSymbol declContext) throws ParserSymbolTableException { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getContainedSymbols() + */ + public CharArrayObjectMap getContainedSymbols() { + return _containedSymbols; + } + + protected void putInContainedSymbols( char[] key, Object obj ){ + if( _containedSymbols == CharArrayObjectMap.EMPTY_MAP ){ + _containedSymbols = new CharArrayObjectMap( 4 ); + } + _containedSymbols.put( key, obj ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#prefixLookup(org.eclipse.cdt.internal.core.parser.pst.TypeFilter, char[], boolean, java.util.List) + */ + public List prefixLookup(TypeFilter filter, char[] prefix, boolean qualified, List paramList) throws ParserSymbolTableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#elaboratedLookup(org.eclipse.cdt.internal.core.parser.pst.ITypeInfo.eType, char[]) + */ + public ISymbol elaboratedLookup(final eType type, char[] name) throws ParserSymbolTableException { + LookupData data = new LookupData( name ){ + public TypeFilter getFilter() { + if( t == ITypeInfo.t_any ) return ANY_FILTER; + if( filter == null ) filter = new TypeFilter( t ); + return filter; + } + private TypeFilter filter = null; + private final ITypeInfo.eType t = type; + }; + + ParserSymbolTable.lookup( data, this ); + + ISymbol found = getSymbolTable().resolveAmbiguities( data ); + + if( isTemplateMember() && found instanceof ITemplateSymbol ) { + boolean areWithinTemplate = false; + IContainerSymbol container = getContainingSymbol(); + while( container != null ){ + if( container == found ){ + areWithinTemplate = true; + break; + } + container = container.getContainingSymbol(); + } + if( areWithinTemplate ) + return TemplateEngine.instantiateWithinTemplateScope( this, (ITemplateSymbol) found ); + } + + return found; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookup(char[]) + */ + public ISymbol lookup(char[] name) throws ParserSymbolTableException { + LookupData data = new LookupData( name ); + + ParserSymbolTable.lookup( data, this ); + + ISymbol found = getSymbolTable().resolveAmbiguities( data ); + + if( isTemplateMember() && found instanceof ITemplateSymbol ) { + return TemplateEngine.instantiateWithinTemplateScope( this, (ITemplateSymbol) found ); + } + + if (found == null && getTypeInfo() instanceof TemplateParameterTypeInfo) { + // add a symbol as an expected type to a template parameter + found = getSymbolTable().newUndefinedTemplateSymbol(name, ITypeInfo.t_undef); + addSymbol(found); + } + + return found; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupMemberForDefinition(char[]) + */ + public ISymbol lookupMemberForDefinition(char[] name) throws ParserSymbolTableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupMethodForDefinition(char[], java.util.List) + */ + public IParameterizedSymbol lookupMethodForDefinition(char[] name, List parameters) throws ParserSymbolTableException { + // TODO Auto-generated method stub + return null; + } + + /** + * The name of a class or namespace member can be referred to after the :: + * scope resolution operator applied to a nested-name-specifier that + * nominates its class or namespace. During the lookup for a name preceding + * the ::, object, function and enumerator names are ignored. If the name + * is not a class-name or namespace-name, the program is ill-formed + */ + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupNestedNameSpecifier(char[]) + */ + public ISymbol lookupNestedNameSpecifier(char[] name) throws ParserSymbolTableException { + return lookupNestedNameSpecifier( name, this ); + } + + private ISymbol lookupNestedNameSpecifier(char[] name, IContainerSymbol inSymbol ) throws ParserSymbolTableException{ + ISymbol foundSymbol = null; + + final TypeFilter filter = new TypeFilter( ITypeInfo.t_namespace ); + filter.addAcceptedType( ITypeInfo.t_class ); + filter.addAcceptedType( ITypeInfo.t_struct ); + filter.addAcceptedType( ITypeInfo.t_union ); + filter.addAcceptedType( ITypeInfo.t_templateParameter ); + filter.addAcceptedType( IASTNode.LookupKind.TYPEDEFS ); + + LookupData data = new LookupData( name ){ + public TypeFilter getFilter() { return typeFilter; } + final private TypeFilter typeFilter = filter; + }; + data.qualified = true; + ParserSymbolTable.lookup( data, inSymbol ); + + if( data.foundItems != null ){ + foundSymbol = getSymbolTable().resolveAmbiguities( data ); + } + + // another undefined symbol i.e.: + // template <typename T> class A { + // typedef typename T::R::some_type some_type; + // }; ^ + if (foundSymbol == null && getTypeInfo() instanceof TemplateParameterTypeInfo) { + // add a symbol as an expected type to a template parameter + foundSymbol = getSymbolTable().newUndefinedTemplateSymbol(name, ITypeInfo.t_undef); + addSymbol(foundSymbol); + } + + return foundSymbol; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedLookup(char[]) + */ + public ISymbol qualifiedLookup(char[] name) throws ParserSymbolTableException { + LookupData data = new LookupData( name ); + data.qualified = true; + ParserSymbolTable.lookup( data, this ); + + ISymbol found = getSymbolTable().resolveAmbiguities( data ); + + if (found == null) { + // add a symbol as an expected type to a template parameter + found = getSymbolTable().newUndefinedTemplateSymbol(name, ITypeInfo.t_undef); + addSymbol(found); + } + return found; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedLookup(char[], org.eclipse.cdt.internal.core.parser.pst.ITypeInfo.eType) + */ + public ISymbol qualifiedLookup(char[] name, final ITypeInfo.eType t) throws ParserSymbolTableException { + LookupData data = new LookupData( name ){ + public TypeFilter getFilter() { + if( t == ITypeInfo.t_any ) return ANY_FILTER; + + if( filter == null ) + filter = new TypeFilter( t ); + return filter; + + } + private TypeFilter filter = null; + }; + data.qualified = true; + ParserSymbolTable.lookup( data, this ); + + ISymbol found = getSymbolTable().resolveAmbiguities( data ); + + if (found == null) { + // add a symbol as an expected type to a template parameter + found = getSymbolTable().newUndefinedTemplateSymbol(name, ITypeInfo.t_undef); + addSymbol(found); + } + return found; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#unqualifiedFunctionLookup(char[], java.util.List) + */ + public IParameterizedSymbol unqualifiedFunctionLookup(char[] name, List parameters) throws ParserSymbolTableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#memberFunctionLookup(char[], java.util.List) + */ + public IParameterizedSymbol memberFunctionLookup(char[] name, List parameters) throws ParserSymbolTableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedFunctionLookup(char[], java.util.List) + */ + public IParameterizedSymbol qualifiedFunctionLookup(char[] name, List parameters) throws ParserSymbolTableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupTemplateId(char[], java.util.List) + */ + public ISymbol lookupTemplateId(char[] name, List arguments) throws ParserSymbolTableException { + LookupData data = new LookupData( name ); + + ParserSymbolTable.lookup( data, this ); + ISymbol found = getSymbolTable().resolveAmbiguities( data ); + if (found == null) { + // VMIR { + // another undefined symbol i.e.: + // template <typename T> class A { + // typedef typename T::template R<T>::some_type some_type; + // }; ^^^^ + // add a symbol as an expected type to a template parameter + found = getSymbolTable().newUndefinedTemplateSymbol(name, ITypeInfo.t_template); + addSymbol(found); + } + if( found != null ){ + if( (found.isType( ITypeInfo.t_templateParameter ) && found.getTypeInfo().getTemplateParameterType() == ITypeInfo.t_template) || + found.isType( ITypeInfo.t_template ) ) + { + found = ((ITemplateSymbol) found).instantiate( arguments ); + } else if( found.getContainingSymbol().isType( ITypeInfo.t_template ) ){ + found = ((ITemplateSymbol) found.getContainingSymbol()).instantiate( arguments ); + } + } + + return found; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupFunctionTemplateId(char[], java.util.List, java.util.List, boolean) + */ + public ISymbol lookupFunctionTemplateId(char[] name, final List parameters, final List arguments, boolean forDefinition) + throws ParserSymbolTableException { + LookupData data = new LookupData( name ){ + public List getParameters() { return params; } + public List getTemplateParameters() { return templateParams; } + public TypeFilter getFilter() { return FUNCTION_FILTER; } + final private List params = ( parameters == null ) ? Collections.EMPTY_LIST : parameters; + final private List templateParams = arguments; + }; + data.exactFunctionsOnly = forDefinition; + + ParserSymbolTable.lookup( data, this ); + ISymbol found = getSymbolTable().resolveAmbiguities( data ); + + return found; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupTemplateIdForDefinition(char[], java.util.List) + */ + public IContainerSymbol lookupTemplateIdForDefinition(char[] name, List arguments) throws ParserSymbolTableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#isVisible(org.eclipse.cdt.internal.core.parser.pst.ISymbol, org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol) + */ + public boolean isVisible(ISymbol symbol, IContainerSymbol qualifyingSymbol) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getContentsIterator() + */ + public Iterator getContentsIterator() { + return getContents().iterator(); + } + + protected void addToContents( IExtensibleSymbol symbol ){ + if( _contents == Collections.EMPTY_LIST ){ + _contents = new ArrayList( 8 ); + } + _contents.add( symbol ); + } + + protected List getContents(){ + return _contents; + } + + + /* + * IParameterSymbol -------------------------------------------------------- + */ + + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol) + */ + public void addParameter(ISymbol param) { + throw new ParserSymbolTableError( ParserSymbolTableError.r_OperationNotSupported ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ITypeInfo.eType, int, org.eclipse.cdt.internal.core.parser.pst.ITypeInfo.PtrOp, boolean) + */ + public void addParameter(eType type, int info, PtrOp ptrOp, boolean hasDefault) { + throw new ParserSymbolTableError( ParserSymbolTableError.r_OperationNotSupported ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol, int, org.eclipse.cdt.internal.core.parser.pst.ITypeInfo.PtrOp, boolean) + */ + public void addParameter(ISymbol typeSymbol, int info, PtrOp ptrOp, boolean hasDefault) { + throw new ParserSymbolTableError( ParserSymbolTableError.r_OperationNotSupported ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterMap() + */ + public CharArrayObjectMap getParameterMap() { + return CharArrayObjectMap.EMPTY_MAP; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterList() + */ + public List getParameterList() { + return Collections.EMPTY_LIST; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasSameParameters(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol) + */ + public boolean hasSameParameters(IParameterizedSymbol newDecl) { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#setReturnType(org.eclipse.cdt.internal.core.parser.pst.ISymbol) + */ + public void setReturnType(ISymbol type) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getReturnType() + */ + public ISymbol getReturnType() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#setHasVariableArgs(boolean) + */ + public void setHasVariableArgs(boolean var) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasVariableArgs() + */ + public boolean hasVariableArgs() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#prepareForParameters(int) + */ + public void prepareForParameters(int numParams) { + } + + + /* + * ITemplateSymbol -------------------------------------------------------- + */ + + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#addTemplateParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol) + */ + public void addTemplateParameter(ISymbol param) throws ParserSymbolTableException { + throw new ParserSymbolTableError( ParserSymbolTableError.r_OperationNotSupported ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#hasSpecializations() + */ + public boolean hasSpecializations() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#addSpecialization(org.eclipse.cdt.internal.core.parser.pst.ISpecializedSymbol) + */ + public void addSpecialization(ISpecializedSymbol spec) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#getSpecializations() + */ + public List getSpecializations() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#getTemplatedSymbol() + */ + public IContainerSymbol getTemplatedSymbol() { + return this; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#getDefinitionParameterMap() + */ + public ObjectMap getDefinitionParameterMap() { + return ObjectMap.EMPTY_MAP; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#findInstantiation(java.util.List) + */ + public IContainerSymbol findInstantiation(List arguments) { + if( _instantiations == ObjectMap.EMPTY_MAP ){ + return null; + } + + //TODO: we could optimize this by doing something other than a linear search. + int size = _instantiations.size(); + List args = null; + for( int i = 0; i < size; i++ ){ + args = (List) _instantiations.keyAt(i); + + if( args.equals( arguments ) ){ + return (IContainerSymbol) _instantiations.get( args ); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#findArgumentsFor(org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol) + */ + public List findArgumentsFor(IContainerSymbol instance) { + if( instance == null || !instance.isTemplateInstance() ) + return null; + +// ITemplateSymbol template = (ITemplateSymbol) instance.getInstantiatedSymbol().getContainingSymbol(); +// if( template != this ) +// return null; + + int size = _instantiations.size(); + for( int i = 0; i < size; i++){ + List args = (List) _instantiations.keyAt( i ); + if( _instantiations.get( args ) == instance ){ + return args; + } + } + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#addInstantiation(org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol, java.util.List) + */ + public void addInstantiation(IContainerSymbol instance, List args) { + List key = new ArrayList( args ); + if( _instantiations == ObjectMap.EMPTY_MAP ){ + _instantiations = new ObjectMap(2); + } + _instantiations.put( key, instance ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#removeInstantiation(org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol) + */ + public void removeInstantiation(IContainerSymbol symbol) { + List args = findArgumentsFor( symbol ); + if( args != null ){ + _instantiations.remove( args ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#addExplicitSpecialization(org.eclipse.cdt.internal.core.parser.pst.ISymbol, java.util.List) + */ + public void addExplicitSpecialization(ISymbol symbol, List args) throws ParserSymbolTableException { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#instantiate(java.util.List) + */ + public ISymbol instantiate(List arguments) throws ParserSymbolTableException { + if( getType() != ITypeInfo.t_template && + ( getType() != ITypeInfo.t_templateParameter || + getTypeInfo().getTemplateParameterType() != ITypeInfo.t_template ) ) + { + return null; + } + + UndefinedTemplateSymbol instance = (UndefinedTemplateSymbol) findInstantiation( arguments ); + if (instance == null) { + // clone and store the arguments + instance = (UndefinedTemplateSymbol) getSymbolTable().newUndefinedTemplateSymbol(getName(), getType()); + instance.setArgumentList(arguments); + instance.setInstantiatedSymbol(this); + + addInstantiation(instance, arguments); + } + return instance; + } + + /** + * @return Returns the _argumentList. + */ + public List getArgumentList() { + return _argumentList; + } + /** + * @param list The _argumentList to set. + */ + protected void setArgumentList(List list) { + _argumentList = new ArrayList(list); + } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ISymbol#instantiate(org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol, org.eclipse.cdt.core.parser.util.ObjectMap) + */ + public ISymbol instantiate(ITemplateSymbol template, ObjectMap argMap) throws ParserSymbolTableException { + if( !isTemplateMember() || template == null ) { + return null; + } + if (getContainingSymbol() instanceof UndefinedTemplateSymbol) { + // instantiate containing symbol + ISymbol containingSymbol = ((UndefinedTemplateSymbol) getContainingSymbol()).instantiate( template, argMap ); + // now lookup for the symbol in containing symbol's list of contained symbols + if (containingSymbol instanceof IContainerSymbol) { + ISymbol symbol; + if (isType(ITypeInfo.t_template)) { + symbol = ((IContainerSymbol) containingSymbol).lookupTemplateId(getName(), getArgumentList()); + } + else { + symbol = ((IContainerSymbol) containingSymbol).lookup(getName()); + } + if (symbol instanceof IDeferredTemplateInstance) { + symbol = ((IDeferredTemplateInstance) symbol).getTemplate(); + } + if (symbol instanceof ITemplateSymbol) { + symbol = ((ITemplateSymbol) symbol).getTemplatedSymbol(); + } + return symbol; + } + else { + throw new ParserSymbolTableException(ParserSymbolTableException.r_BadTemplateArgument); + } + } + else if (isType(ITypeInfo.t_templateParameter) && argMap.containsKey(this)) { + return ((ITypeInfo)argMap.get(this)).getTypeSymbol(); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#deferredInstance(java.util.List) + */ + public IDeferredTemplateInstance deferredInstance(List args) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#getExplicitSpecializations() + */ + public ObjectMap getExplicitSpecializations() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#getNumberDeferredInstantiations() + */ + public int getNumberDeferredInstantiations() { + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#registerDeferredInstatiation(java.lang.Object, java.lang.Object, org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol.DeferredKind, org.eclipse.cdt.core.parser.util.ObjectMap) + */ + public void registerDeferredInstatiation(Object obj0, Object obj1, DeferredKind kind, ObjectMap argMap) { + } +} |