1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-05 23:35:48 +02:00

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.
This commit is contained in:
Vladimir Hirsl 2004-09-30 19:45:57 +00:00
parent 851bf3eea6
commit 440ada9bab
14 changed files with 1007 additions and 115 deletions

View file

@ -10,11 +10,8 @@
***********************************************************************/
package org.eclipse.cdt.core.parser.failedTests;
import java.io.StringWriter;
import java.util.Iterator;
import junit.framework.AssertionFailedError;
import org.eclipse.cdt.core.parser.ast.IASTFunction;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.tests.CompleteParseBaseTest;
@ -162,28 +159,6 @@ public class FailedCompleteParseASTTest extends CompleteParseBaseTest
// assertFalse(j.hasNext());
}
public void testParametrizedTypeDefinition_bug69751() throws Exception {
try {
// a typedef refers to an unknown type in a template parameter
parse("template <typename T> \n class A { \n typedef typename T::size_type size_type; \n void foo() { size_type i; } \n }; \n");//$NON-NLS-1$
fail();
} catch (ParserException e) {
assertTrue( e.getMessage().equals( "FAILURE" ) ); //$NON-NLS-1$
}
// Iterator i = parse("template <typename T> \n class A { \n typedef typename T::size_type size_type; \n void foo() { size_type i; } \n }; \n").getDeclarations();//$NON-NLS-1$
// IASTTemplateDeclaration td = (IASTTemplateDeclaration)i.next();
// assertFalse(i.hasNext());
// IASTClassSpecifier cs = (IASTClassSpecifier) td.getOwnedDeclaration();
// Iterator j = cs.getDeclarations();
// IASTTypedefDeclaration tdd = (IASTTypedefDeclaration) j.next();
// IASTMethod m = (IASTMethod) j.next();
// assertFalse(j.hasNext());
// Iterator k = m.getDeclarations();
// IASTVariable v = (IASTVariable) k.next();
// assertFalse(k.hasNext());
}
public void testGNUExternalTemplate_bug71603() throws Exception {
try {

View file

@ -17,8 +17,7 @@ import java.io.StringWriter;
import java.io.Writer;
import java.util.Iterator;
import junit.framework.AssertionFailedError;
import org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTBaseSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
@ -1093,4 +1092,106 @@ public class CompleteParseASTTemplateTest extends CompleteParseBaseTest {
assertFalse(i.hasNext());
IASTMethod mdef = (IASTMethod) td3.getOwnedDeclaration();
}
public void testParametrizedTypeDefinition_bug69751() throws Exception {
// a typedef refers to an unknown type in a template parameter
Iterator i = parse("template <typename T> \n class A { \n typedef typename T::size_type size_type; \n void foo() { size_type i; } \n }; \n").getDeclarations();//$NON-NLS-1$
IASTTemplateDeclaration td = (IASTTemplateDeclaration)i.next();
assertFalse(i.hasNext());
IASTClassSpecifier cs = (IASTClassSpecifier) td.getOwnedDeclaration();
Iterator j = cs.getDeclarations();
IASTTypedefDeclaration tdd = (IASTTypedefDeclaration) j.next();
IASTMethod m = (IASTMethod) j.next();
assertFalse(j.hasNext());
Iterator k = m.getDeclarations();
IASTVariable v = (IASTVariable) k.next();
assertFalse(k.hasNext());
}
public void testParametrizedTypeDefinition_bug69751_2() throws Exception {
Writer writer = new StringWriter();
writer.write("template <typename T> class A { \n");
writer.write("void foo(); };\n");
writer.write("template <typename T> \n");
writer.write("void A<T>::foo() { \n");
writer.write("typedef typename T::B<char*>::s_type l_type; \n");
writer.write("typedef typename T::B<T>::s2_type l2_type; \n");
writer.write("l_type i; \n");
writer.write("l2_type j; } \n");
Iterator i = parse(writer.toString()).getDeclarations();//$NON-NLS-1$
IASTTemplateDeclaration td1 = (IASTTemplateDeclaration)i.next();
IASTTemplateDeclaration td2 = (IASTTemplateDeclaration)i.next();
assertFalse(i.hasNext());
IASTClassSpecifier cs = (IASTClassSpecifier) td1.getOwnedDeclaration();
Iterator j = cs.getDeclarations();
IASTMethod mdecl = (IASTMethod) j.next();
assertFalse(j.hasNext());
IASTMethod mdef = (IASTMethod) td2.getOwnedDeclaration();
Iterator k = mdef.getDeclarations();
IASTTypedefDeclaration tdd1 = (IASTTypedefDeclaration) k.next();
IASTTypedefDeclaration tdd2 = (IASTTypedefDeclaration) k.next();
IASTVariable v1 = (IASTVariable) k.next();
IASTVariable v2 = (IASTVariable) k.next();
assertFalse(k.hasNext());
}
public void testParametrizedTypeDefinition_bug69751_3() throws Exception {
Writer writer = new StringWriter();
writer.write("template <typename T, typename U> class A { \n");
// T::U is not the same as template parameter U
writer.write("typedef typename T::U::s_type l_type; \n");
writer.write("l_type m_l; \n");
writer.write("typename U::s_type m_s; } \n");
Iterator i = parse(writer.toString()).getDeclarations();//$NON-NLS-1$
IASTTemplateDeclaration td = (IASTTemplateDeclaration)i.next();
assertFalse(i.hasNext());
Iterator j = td.getTemplateParameters();
IASTTemplateParameter tpT = (IASTTemplateParameter) j.next();
IASTTemplateParameter tpU = (IASTTemplateParameter) j.next();
assertFalse(j.hasNext());
IASTClassSpecifier cs = (IASTClassSpecifier) td.getOwnedDeclaration();
Iterator k = cs.getDeclarations();
IASTTypedefDeclaration tdd = (IASTTypedefDeclaration) k.next();
IASTField f1 = (IASTField) k.next();
IASTField f2 = (IASTField) k.next();
assertFalse(k.hasNext());
assertAllReferences(3, createTaskList(new Task(tpT), new Task(tpU), new Task(tdd)));
}
public void testParametrizedTypeDefinition_bug69751_4() throws Exception {
Writer writer = new StringWriter();
writer.write("class B { typedef char size_type; };");
writer.write("template <typename T> class A { \n");
writer.write("typedef typename T::size_type size_type; };\n");
writer.write("A<B>::size_type c; \n");
writer.write("void f(char) {} \n");
writer.write("void f(int) {} \n");
writer.write("void main() { f(c); } \n");
Iterator i = parse(writer.toString()).getDeclarations();
IASTAbstractTypeSpecifierDeclaration ad = (IASTAbstractTypeSpecifierDeclaration)i.next();
IASTTemplateDeclaration td = (IASTTemplateDeclaration)i.next();
IASTVariable v = (IASTVariable)i.next();
IASTFunction fc = (IASTFunction) i.next();
IASTFunction fi = (IASTFunction) i.next();
IASTFunction fm = (IASTFunction) i.next();
assertFalse(i.hasNext());
assertReferenceTask(new Task(fc, 1, true, false));
}
public void testTemplateParametersInExpressions_bug72546() throws Exception {
Iterator i = parse("template <class T> \n int add(T * x, T * y) { \n return x->value + y->value; }; \n").getDeclarations();//$NON-NLS-1$
IASTTemplateDeclaration td = (IASTTemplateDeclaration)i.next();
assertFalse(i.hasNext());
Iterator j = td.getTemplateParameters();
IASTTemplateParameter tp = (IASTTemplateParameter) j.next();
assertFalse(j.hasNext());
IASTFunction f = (IASTFunction) td.getOwnedDeclaration();
Iterator k = f.getParameters();
IASTParameterDeclaration x = (IASTParameterDeclaration) k.next();
IASTParameterDeclaration y = (IASTParameterDeclaration) k.next();
assertFalse(k.hasNext());
IASTAbstractDeclaration ad = f.getReturnType();
assertTrue(ad != null);
assertAllReferences(4, createTaskList(new Task(tp, 2), new Task(x), new Task(y)));
}
}

View file

@ -844,20 +844,22 @@ public class ParserSymbolTableTest extends TestCase {
IParameterizedSymbol f = table.newParameterizedSymbol("f".toCharArray()); //$NON-NLS-1$
compUnit.addSymbol(f);
IContainerSymbol lookA = f.lookupNestedNameSpecifier("A".toCharArray()); //$NON-NLS-1$
ISymbol lookA = f.lookupNestedNameSpecifier("A".toCharArray()); //$NON-NLS-1$
assertEquals( lookA, nsA );
assertTrue( lookA instanceof IContainerSymbol);
ISymbol look = lookA.qualifiedLookup("a".toCharArray()); //$NON-NLS-1$
ISymbol look = ((IContainerSymbol) lookA).qualifiedLookup("a".toCharArray()); //$NON-NLS-1$
assertEquals( look, a );
look = lookA.qualifiedLookup("b".toCharArray()); //$NON-NLS-1$
look = ((IContainerSymbol) lookA).qualifiedLookup("b".toCharArray()); //$NON-NLS-1$
assertEquals( look, b );
IContainerSymbol lookB = f.lookupNestedNameSpecifier("B".toCharArray()); //$NON-NLS-1$
look = lookB.qualifiedLookup("a".toCharArray()); //$NON-NLS-1$
ISymbol lookB = f.lookupNestedNameSpecifier("B".toCharArray()); //$NON-NLS-1$
assertTrue( lookB instanceof IContainerSymbol);
look = ((IContainerSymbol) lookB).qualifiedLookup("a".toCharArray()); //$NON-NLS-1$
assertEquals( look, a );
look = lookB.qualifiedLookup("b".toCharArray()); //$NON-NLS-1$
look = ((IContainerSymbol) lookB).qualifiedLookup("b".toCharArray()); //$NON-NLS-1$
assertEquals( look, b );
assertEquals( table.getTypeInfoProvider().numAllocated(), 0 );
}
@ -1028,14 +1030,15 @@ public class ParserSymbolTableTest extends TestCase {
nsA.addUsingDirective( nsB );
IContainerSymbol lookA = compUnit.lookupNestedNameSpecifier( "A".toCharArray() ); //$NON-NLS-1$
ISymbol lookA = compUnit.lookupNestedNameSpecifier( "A".toCharArray() ); //$NON-NLS-1$
assertEquals( nsA, lookA );
assertTrue( lookA instanceof IContainerSymbol);
ISymbol look = lookA.lookupMemberForDefinition( "f1".toCharArray() ); //$NON-NLS-1$
ISymbol look = ((IContainerSymbol) lookA).lookupMemberForDefinition( "f1".toCharArray() ); //$NON-NLS-1$
assertEquals( look, null );
//but notice if you wanted to do A::f1 as a function call, it is ok
look = lookA.qualifiedLookup( "f1".toCharArray() ); //$NON-NLS-1$
look = ((IContainerSymbol) lookA).qualifiedLookup( "f1".toCharArray() ); //$NON-NLS-1$
assertEquals( look, f1 );
assertEquals( table.getTypeInfoProvider().numAllocated(), 0 );
}
@ -1105,11 +1108,12 @@ public class ParserSymbolTableTest extends TestCase {
compUnit.addSymbol( D );
IContainerSymbol lookB = D.lookupNestedNameSpecifier("B".toCharArray()); //$NON-NLS-1$
ISymbol lookB = D.lookupNestedNameSpecifier("B".toCharArray()); //$NON-NLS-1$
assertEquals( lookB, B );
assertTrue( lookB instanceof IContainerSymbol);
D.addUsingDeclaration( "f".toCharArray(), lookB ); //$NON-NLS-1$
D.addUsingDeclaration( "e".toCharArray(), lookB ); //$NON-NLS-1$
D.addUsingDeclaration( "f".toCharArray(), (IContainerSymbol)lookB ); //$NON-NLS-1$
D.addUsingDeclaration( "e".toCharArray(), (IContainerSymbol)lookB ); //$NON-NLS-1$
//TBD anonymous union
//D.addUsingDeclaration( "x".toCharArray(), lookB );

View file

@ -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

View file

@ -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) {

View file

@ -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;

View file

@ -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 ){

View file

@ -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)

View file

@ -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;

View file

@ -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 );

View file

@ -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 {

View file

@ -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;
}

View file

@ -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 );
}

View file

@ -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) {
}
}