diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog index 7e5c68b9853..df8284b70f8 100644 --- a/core/org.eclipse.cdt.core.tests/ChangeLog +++ b/core/org.eclipse.cdt.core.tests/ChangeLog @@ -1,3 +1,9 @@ +2003-03-22 Andrew Niefer + Typedefs & templates + - added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTypedefedTemplate() + - added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTypedefedTemplate_2() + - added parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.testCompletionInTypeDef() + 2003-03-18 Andrew Niefer parsing template-ids - added parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.test54778() diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java index 62b74b2db31..da468f8bf61 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java @@ -1696,4 +1696,78 @@ public class CompleteParseASTTest extends CompleteParseBaseTest assertAllReferences( 7, createTaskList( new Task( n ), new Task( i, 5 ), new Task( di ) ) ); } + public void testTypedefedTemplate() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "template < class T > class _A{ int x; }; \n" ); + writer.write( "typedef _A < char > A; \n" ); + writer.write( "void foo() { \n" ); + writer.write( " A a; \n" ); + writer.write( " a.x; \n" ); + writer.write( "} \n" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration _A = (IASTTemplateDeclaration) i.next(); + IASTTypedefDeclaration A = (IASTTypedefDeclaration) i.next(); + IASTFunction foo = (IASTFunction) i.next(); + + IASTClassSpecifier classA = (IASTClassSpecifier) _A.getOwnedDeclaration(); + IASTVariable x = (IASTVariable) getDeclarations( classA ).next(); + IASTVariable a = (IASTVariable) getDeclarations( foo ).next(); + + assertAllReferences( 4, createTaskList( new Task( classA ), new Task( A ), new Task( a ), new Task( x ) ) ); + } + + public void testTypedefedTemplate_2() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "template < class T > struct A { T x; }; \n" ); + writer.write( "template < class U > struct B { \n" ); + writer.write( " typedef A< U > AU; \n" ); + writer.write( " void f( U ); \n" ); + writer.write( " void f( char ); \n" ); + writer.write( " void g(){ \n" ); + writer.write( " AU au; \n" ); + writer.write( " f( au.x ); \n" ); + writer.write( " } \n" ); + writer.write( "}; \n" ); + writer.write( "void f2( int ); \n" ); + writer.write( "void f2( char ); \n" ); + writer.write( "void h(){ \n" ); + writer.write( " B< int >::AU b; \n" ); + writer.write( " f2( b.x ); \n" ); + writer.write( "} \n" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration tA = (IASTTemplateDeclaration) i.next(); + IASTTemplateParameter T = (IASTTemplateParameter) tA.getTemplateParameters().next(); + IASTClassSpecifier A = (IASTClassSpecifier) tA.getOwnedDeclaration(); + IASTField x = (IASTField) getDeclarations( A ).next(); + IASTTemplateDeclaration tB = (IASTTemplateDeclaration) i.next(); + IASTClassSpecifier B = (IASTClassSpecifier) tB.getOwnedDeclaration(); + IASTTemplateParameter U = (IASTTemplateParameter) tB.getTemplateParameters().next(); + IASTFunction f21 = (IASTFunction) i.next(); + IASTFunction f22 = (IASTFunction) i.next(); + IASTFunction h = (IASTFunction) i.next(); + + i = getDeclarations( B ); + IASTTypedefDeclaration AU = (IASTTypedefDeclaration) i.next(); + IASTMethod f11 = (IASTMethod) i.next(); + IASTMethod f12 = (IASTMethod) i.next(); + IASTMethod g = (IASTMethod) i.next(); + + IASTVariable au = (IASTVariable) getDeclarations( g ).next(); + IASTVariable b = (IASTVariable) getDeclarations( h ).next(); + + assertAllReferences( 12, createTaskList( new Task( A ), + new Task( T ), + new Task( U ), + new Task( AU, 2 ), + new Task( au ), + new Task( x, 2 ), + new Task( f11, 1, false, false ), + new Task( B ), + new Task( b ), + new Task( f21, 1, false, false ) ) ); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java index 38304da5aca..7adbb6d5391 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java @@ -916,6 +916,13 @@ public class CompleteParseBaseTest extends TestCase return result; } + protected List createTaskList(Task task, Task task2, Task task3, Task task4, Task task5, Task task6, Task task7, Task task8, Task task9, Task task10 ) + { + List result = createTaskList( task, task2, task3, task4, task5, task6, task7, task8, task9 ); + result.add( task10 ); + return result; + } + public boolean qualifiedNamesEquals( String [] fromAST, String [] theTruth) { if( fromAST == null || theTruth == null ) return false; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java index ae96080be0b..23574190639 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java @@ -662,4 +662,30 @@ public class CompletionParseTest extends CompleteParseBaseTest { assertFalse( iter.hasNext() ); } + public void testCompletionInTypeDef() throws Exception{ + StringWriter writer = new StringWriter(); + writer.write( "struct A { int name; }; \n" ); + writer.write( "typedef struct A * PA; \n" ); + writer.write( "int main() { \n" ); + writer.write( " PA a; \n" ); + writer.write( " a->SP \n" ); + writer.write( "} \n" ); + + String code = writer.toString(); + int index = code.indexOf( "SP" ); + + IASTCompletionNode node = parse( code, index ); + ILookupResult result = node.getCompletionScope().lookup( node.getCompletionPrefix(), + new IASTNode.LookupKind[]{ IASTNode.LookupKind.ALL }, + node.getCompletionContext() ); + + assertEquals( result.getResultsSize(), 1 ); + + Iterator iter = result.getNodes(); + IASTField name = (IASTField) iter.next(); + + assertEquals( name.getName(), "name" ); + assertFalse( iter.hasNext() ); + } + } diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog-parser b/core/org.eclipse.cdt.core/parser/ChangeLog-parser index 195d5aa1507..5ccc3d59c08 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog-parser +++ b/core/org.eclipse.cdt.core/parser/ChangeLog-parser @@ -1,3 +1,11 @@ +2004-03-22 Andrew Niefer + -handling of Typedefs + -handle unbalanced preprocessor condition in scanner + -fix concurrent modification exception while processing unresolved references in a Class Specifier + -report correct owner class for templated methods + -some work on template explicit specializations + -handle templated class forward declarations + 2004-03-18 Andrew Niefer parsing template-ids: enables clas template partial specializations and fixes 54778 indirectly - add ITokenDuple.getTemplateIdArgLists diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTTemplateSpecialization.java index 1c3f437f246..2684db0ded9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTTemplateSpecialization.java @@ -14,6 +14,6 @@ package org.eclipse.cdt.core.parser.ast; * @author jcamelon * */ -public interface IASTTemplateSpecialization extends IASTDeclaration, IASTTemplate, IASTOffsetableElement { +public interface IASTTemplateSpecialization extends IASTTemplateDeclaration { } 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 f5d5bf32651..e36e4bc57ac 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 @@ -469,7 +469,7 @@ public abstract class Parser extends ExpressionParser implements IParser throw backtrack; } templateSpecialization.enterScope(requestor); - declaration(scope, templateSpecialization, null); + declaration(templateSpecialization, templateSpecialization, null); templateSpecialization.setEndingOffsetAndLineNumber( lastToken.getEndOffset(), lastToken.getLineNumber()); templateSpecialization.exitScope(requestor); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTClassSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTClassSpecifier.java index 38deb5cca0b..3b0cb7be943 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTClassSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTClassSpecifier.java @@ -303,10 +303,13 @@ public class ASTClassSpecifier extends ASTScope implements IASTClassSpecifier } private List unresolvedCrossReferences = new ArrayList(); - + private boolean processingUnresolvedReferences = false; public void addUnresolvedReference( UnresolvedReferenceDuple duple) { - unresolvedCrossReferences.add( duple ); + //avoid a ConcurrentModificationException by not adding more references when we are + //in the middle of processing them + if( !processingUnresolvedReferences ) + unresolvedCrossReferences.add( duple ); } public Iterator getUnresolvedReferences() @@ -314,6 +317,10 @@ public class ASTClassSpecifier extends ASTScope implements IASTClassSpecifier return unresolvedCrossReferences.iterator(); } + public void setProcessingUnresolvedReferences( boolean processing ){ + processingUnresolvedReferences = processing; + } + private List resolvedCrossReferences = new ArrayList(); /** * @param references2 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTMethod.java index 3b6fde599f7..93b2850aedb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTMethod.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.core.parser.ast.IASTConstructorMemberInitializer; import org.eclipse.cdt.core.parser.ast.IASTExceptionSpecification; import org.eclipse.cdt.core.parser.ast.IASTMethod; import org.eclipse.cdt.core.parser.ast.IASTTemplate; +import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration; import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator; import org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol; import org.eclipse.cdt.internal.core.parser.pst.TypeInfo; @@ -197,6 +198,9 @@ public class ASTMethod extends ASTFunction implements IASTMethod * @see org.eclipse.cdt.core.parser.ast.IASTMethod#getOwnerClassSpecifier() */ public IASTClassSpecifier getOwnerClassSpecifier() { + if( getOwnerScope() instanceof IASTTemplateDeclaration ) + return (IASTClassSpecifier) ((IASTTemplateDeclaration)getOwnerScope()).getOwnerScope(); + return (IASTClassSpecifier) getOwnerScope(); } } 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 8cbb59542e4..467b6f6dc14 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 @@ -17,6 +17,8 @@ import java.util.ListIterator; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException; import org.eclipse.cdt.core.parser.ast.IASTNode; +import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration; +import org.eclipse.cdt.core.parser.ast.IASTNode.ILookupResult; import org.eclipse.cdt.internal.core.parser.ast.SymbolIterator; import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol; import org.eclipse.cdt.internal.core.parser.pst.IExtensibleSymbol; @@ -25,6 +27,7 @@ import org.eclipse.cdt.internal.core.parser.pst.ISymbolOwner; import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable; import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException; import org.eclipse.cdt.internal.core.parser.pst.TypeFilter; +import org.eclipse.cdt.internal.core.parser.pst.TypeInfo; /** * @author aniefer @@ -48,7 +51,15 @@ public class ASTNode implements IASTNode { } if( context != null ){ - ISymbol sym = (IContainerSymbol) ((ISymbolOwner)context).getSymbol(); + ISymbol sym = null; + if( context instanceof IASTTypedefDeclaration ){ + ISymbol typedef = (ISymbol) ((ISymbolOwner)context).getSymbol(); + TypeInfo info = typedef.getTypeInfo().getFinalType(); + sym = info.getTypeSymbol(); + } else { + sym = (IContainerSymbol) ((ISymbolOwner)context).getSymbol(); + } + if( sym == null || !(sym instanceof IContainerSymbol) ){ throw new LookupError(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateSpecialization.java index ca7e710da9a..5c282c8cb33 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateSpecialization.java @@ -10,111 +10,22 @@ ***********************************************************************/ package org.eclipse.cdt.internal.core.parser.ast.complete; -import org.eclipse.cdt.core.parser.ISourceElementRequestor; -import org.eclipse.cdt.core.parser.ast.IASTDeclaration; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization; +import org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol; /** * @author jcamelon * */ -public class ASTTemplateSpecialization extends ASTNode implements IASTTemplateSpecialization +public class ASTTemplateSpecialization extends ASTTemplateDeclaration implements IASTTemplateSpecialization { /** * */ - public ASTTemplateSpecialization() + public ASTTemplateSpecialization( ITemplateSymbol template, IASTScope scope ) { - super(); - // TODO Auto-generated constructor stub + super(template, scope, null); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTTemplate#getOwnedDeclaration() - */ - public IASTDeclaration getOwnedDeclaration() - { - // TODO Auto-generated method stub - return null; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTTemplate#setOwnedDeclaration(org.eclipse.cdt.core.parser.ast.IASTDeclaration) - */ - public void setOwnedDeclaration(IASTDeclaration declaration) - { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setStartingOffset(int) - */ - public void setStartingOffsetAndLineNumber(int offset, int lineNumber) - { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setEndingOffset(int) - */ - public void setEndingOffsetAndLineNumber(int offset, int lineNumber) - { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getStartingOffset() - */ - public int getStartingOffset() - { - // TODO Auto-generated method stub - return 0; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getEndingOffset() - */ - public int getEndingOffset() - { - // TODO Auto-generated method stub - return 0; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTScopedElement#getOwnerScope() - */ - public IASTScope getOwnerScope() - { - // TODO Auto-generated method stub - return null; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#acceptElement(org.eclipse.cdt.core.parser.ISourceElementRequestor) - */ - public void acceptElement(ISourceElementRequestor requestor) - { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#enterScope(org.eclipse.cdt.core.parser.ISourceElementRequestor) - */ - public void enterScope(ISourceElementRequestor requestor) - { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#exitScope(org.eclipse.cdt.core.parser.ISourceElementRequestor) - */ - public void exitScope(ISourceElementRequestor requestor) - { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getStartingLine() - */ - public int getStartingLine() { - // TODO Auto-generated method stub - return 0; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getEndingLine() - */ - public int getEndingLine() { - // TODO Auto-generated method stub - return 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 36f7c86ce40..9b7a4f52575 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 @@ -79,6 +79,7 @@ import org.eclipse.cdt.internal.core.parser.ast.BaseASTFactory; import org.eclipse.cdt.internal.core.parser.problem.IProblemFactory; import org.eclipse.cdt.internal.core.parser.pst.ForewardDeclaredSymbolExtension; import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol; +import org.eclipse.cdt.internal.core.parser.pst.IDeferredTemplateInstance; import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol; import org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol; import org.eclipse.cdt.internal.core.parser.pst.ISymbol; @@ -144,7 +145,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto * Overrides an existing reference if it has the same name and offset */ protected void addReference(List references, IASTReference reference){ - if( references == null ) return; + if( references == null || reference == null ) return; Iterator i = references.iterator(); while (i.hasNext()){ IASTReference ref = (IASTReference)i.next(); @@ -822,15 +823,15 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto protected IASTReference createReference(ISymbol symbol, String referenceElementName, int offset ) throws ASTSemanticException { // assert (symbol != null ) : "createReference cannot be called on null symbol "; - - if( symbol.getType() == TypeInfo.t_namespace ) + if( symbol.getTypeInfo().checkBit( TypeInfo.isTypedef ) || + symbol.getASTExtension().getPrimaryDeclaration() instanceof IASTTypedefDeclaration ) + return new ASTTypedefReference( offset, referenceElementName, (IASTTypedefDeclaration)symbol.getASTExtension().getPrimaryDeclaration()); + else if( symbol.getType() == TypeInfo.t_namespace ) return new ASTNamespaceReference( offset, referenceElementName, (IASTNamespaceDefinition)symbol.getASTExtension().getPrimaryDeclaration()); else if( symbol.getType() == TypeInfo.t_class || symbol.getType() == TypeInfo.t_struct || symbol.getType() == TypeInfo.t_union ) return new ASTClassReference( offset, referenceElementName, (IASTTypeSpecifier)symbol.getASTExtension().getPrimaryDeclaration() ); - else if( symbol.getTypeInfo().checkBit( TypeInfo.isTypedef )) - return new ASTTypedefReference( offset, referenceElementName, (IASTTypedefDeclaration)symbol.getASTExtension().getPrimaryDeclaration()); else if( symbol.getType() == TypeInfo.t_enumeration ) return new ASTEnumerationReference( offset, referenceElementName, (IASTEnumerationSpecifier)symbol.getASTExtension().getPrimaryDeclaration() ); else if( symbol.getType() == TypeInfo.t_enumerator ) @@ -1004,7 +1005,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto // If the expression is lookup symbol if it is in the scope of a type after a "." or an "->" IContainerSymbol searchScope = getSearchScope(kind, lhs, startingScope); - if (!searchScope.equals(startingScope)) + if ( searchScope != null && !searchScope.equals(startingScope)) symbol = lookupQualifiedName(searchScope, ((ASTExpression)rhs).getIdExpressionTokenDuple(), references, false, LookupType.QUALIFIED ); // get symbol if it is the "this" pointer @@ -1020,6 +1021,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if (kind == IASTExpression.Kind.POSTFIX_FUNCTIONCALL){ ITokenDuple functionId = getFunctionId(lhs); IContainerSymbol functionScope = getSearchScope(lhs.getExpressionKind(), lhs.getLHSExpression(), startingScope); + + if( functionScope == null ) + return null; + ExpressionResult expResult = ((ASTExpression)rhs).getResultType(); List parameters = null; if(expResult instanceof ExpressionResultList){ @@ -1058,18 +1063,12 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto ){ TypeInfo lhsInfo = ((ASTExpression)lhs).getResultType().getResult(); if(lhsInfo != null){ - ISymbol firstContainingScope = lhsInfo.getTypeSymbol(); - if(firstContainingScope != null){ - ISymbol containingScope = firstContainingScope.getTypeSymbol(); - if(containingScope != null){ - return (IContainerSymbol)containingScope; - } else { - return (IContainerSymbol)firstContainingScope; - } - } else { -// assert firstContainingScope != null : "Malformed Expression"; - return null; - } + TypeInfo info = lhsInfo.getFinalType(); + ISymbol containingScope = info.getTypeSymbol(); +// assert containingScope != null : "Malformed Expression"; + if( containingScope instanceof IDeferredTemplateInstance ) + return ((IDeferredTemplateInstance) containingScope).getTemplate().getTemplatedSymbol(); + return ( containingScope instanceof IContainerSymbol ) ? (IContainerSymbol)containingScope : null; } // assert lhsInfo != null : "Malformed Expression"; return null; @@ -2339,6 +2338,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto } ISymbol newSymbol = cloneSimpleTypeSymbol(name, abstractDeclaration, references); + if( newSymbol == null ) + handleProblem( IProblem.SEMANTICS_RELATED, name ); + setVariableTypeInfoBits( isAuto, abstractDeclaration, @@ -2545,6 +2547,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if(references == null) references = new ArrayList(); ISymbol newSymbol = cloneSimpleTypeSymbol(name, abstractDeclaration, references); + if( newSymbol == null ) + handleProblem( IProblem.SEMANTICS_RELATED, name ); + + setVariableTypeInfoBits( isAuto, abstractDeclaration, @@ -2664,8 +2670,13 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto IASTScope scope, int startingOffset, int startingLine) { - // TODO Auto-generated method stub - return new ASTTemplateSpecialization(); + ITemplateSymbol template = pst.newTemplateSymbol( ParserSymbolTable.EMPTY_NAME ); + + ASTTemplateSpecialization ast = new ASTTemplateSpecialization( template, scope ); + + attachSymbolExtension( template, ast, false ); + + return ast; } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTypedef(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, int, int) @@ -2725,43 +2736,68 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto List references = new ArrayList(); IToken lastToken = name.getLastToken(); + String newSymbolName = ""; //$NON-NLS-1$ + List templateIdArgList = null; + boolean isTemplateId = false; + if( name.length() != 1 ) // qualified name { - ITokenDuple containerSymbolName = - name.getSubrange( 0, name.length() - 3 ); // -1 for index, -2 for last hop of qualified name - currentScopeSymbol = (IContainerSymbol)lookupQualifiedName( currentScopeSymbol, - containerSymbolName, references, false); - if( currentScopeSymbol == null ) - handleProblem(IProblem.SEMANTIC_NAME_NOT_FOUND, containerSymbolName.toString(), containerSymbolName.getStartOffset(), containerSymbolName.getEndOffset(), containerSymbolName.getLineNumber() ); - } - - ISymbol checkSymbol = null; - try - { - if( isFriend ){ - checkSymbol = ((IDerivableContainerSymbol)currentScopeSymbol).lookupForFriendship( lastToken.getImage() ); - } else { - checkSymbol = currentScopeSymbol.elaboratedLookup( pstType, lastToken.getImage()); + int idx = name.findLastTokenType( IToken.tCOLONCOLON ); + if( idx != -1 ){ + ITokenDuple containerSymbolName = name.getSubrange( 0, idx - 1 ); + currentScopeSymbol = (IContainerSymbol)lookupQualifiedName( currentScopeSymbol, containerSymbolName, references, true); + if( currentScopeSymbol == null ) + handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, containerSymbolName.toString(), containerSymbolName.getFirstToken().getOffset(), containerSymbolName.getLastToken().getEndOffset(), containerSymbolName.getLastToken().getLineNumber() ); + } + + //template-id + List [] array = name.getTemplateIdArgLists(); + if( array != null ){ + isTemplateId = true; + templateIdArgList = array[ array.length - 1 ]; + lastToken = name.getToken( idx + 1); } } - catch (ParserSymbolTableException e) - { - handleProblem(e.createProblemID(),lastToken.getImage(), lastToken.getOffset(), lastToken.getEndOffset(), lastToken.getLineNumber() ); + + newSymbolName = lastToken.getImage(); + + ISymbol checkSymbol = null; + if( !isTemplateId ){ + try + { + if( isFriend ){ + checkSymbol = ((IDerivableContainerSymbol)currentScopeSymbol).lookupForFriendship( newSymbolName ); + } else { + checkSymbol = currentScopeSymbol.elaboratedLookup( pstType, newSymbolName); + } + } + catch (ParserSymbolTableException e) + { + handleProblem(e.createProblemID(),lastToken.getImage(), lastToken.getOffset(), lastToken.getEndOffset(), lastToken.getLineNumber() ); + + } } - + List args = null; + if( isTemplateId ){ + args = getTemplateArgList( templateIdArgList ); + } + if( isForewardDecl ) { if( checkSymbol == null ) { - checkSymbol = pst.newDerivableContainerSymbol( lastToken.getImage(), pstType ); + checkSymbol = pst.newDerivableContainerSymbol( newSymbolName, pstType ); checkSymbol.setIsForwardDeclaration( true ); try { if( isFriend ){ ((IDerivableContainerSymbol)currentScopeSymbol).addFriend( checkSymbol ); } else { - currentScopeSymbol.addSymbol( checkSymbol ); + if( !isTemplateId ) + currentScopeSymbol.addSymbol( checkSymbol ); + else + currentScopeSymbol.addTemplateId( checkSymbol, args ); } } catch (ParserSymbolTableException e1) @@ -2791,7 +2827,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if( checkSymbol.getASTExtension().getPrimaryDeclaration() instanceof IASTElaboratedTypeSpecifier ) return (IASTElaboratedTypeSpecifier)checkSymbol.getASTExtension().getPrimaryDeclaration(); } else { - handleProblem(IProblem.SEMANTIC_NAME_NOT_FOUND, lastToken.getImage(), lastToken.getOffset(), lastToken.getEndOffset(), lastToken.getLineNumber() ); + handleProblem(IProblem.SEMANTIC_NAME_NOT_FOUND, newSymbolName, lastToken.getOffset(), lastToken.getEndOffset(), lastToken.getLineNumber() ); } @@ -2937,7 +2973,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if( result.getType() == TypeInfo.t_type ) { ISymbol typeSymbol = lookupQualifiedName( scopeToSymbol(scope), typeId.getTokenDuple(), refs, true ); - if( typeSymbol.getType() == TypeInfo.t_type ) + if( typeSymbol == null || typeSymbol.getType() == TypeInfo.t_type ) handleProblem( IProblem.SEMANTIC_INVALID_TYPE, id.getTypeOrClassName() ); result.setTypeSymbol( typeSymbol ); typeId.addReferences( refs ); @@ -2962,6 +2998,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto // do nothing, this is best effort } + astImplementation.setProcessingUnresolvedReferences( true ); Iterator i = astImplementation.getUnresolvedReferences(); List references = new ArrayList(); while( i.hasNext() ) @@ -2984,6 +3021,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto } + astImplementation.setProcessingUnresolvedReferences( false ); + if( ! references.isEmpty() ) astImplementation.setExtraReferences( references ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateDeclaration.java index 76720087536..a8a71948bcd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateDeclaration.java @@ -47,7 +47,7 @@ public class ASTTemplateDeclaration extends ASTDeclaration implements IASTTempla */ public Iterator getTemplateParameters() { - return templateParameters.iterator(); + return ( templateParameters != null ) ? templateParameters.iterator() : new LinkedList().iterator(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration#getOwnedDeclaration() diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateSpecialization.java index e61cce2d0ce..85fd58fc940 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateSpecialization.java @@ -20,7 +20,7 @@ import org.eclipse.cdt.internal.core.parser.ast.Offsets; * @author jcamelon * */ -public class ASTTemplateSpecialization extends ASTDeclaration implements IASTTemplateSpecialization +public class ASTTemplateSpecialization extends ASTTemplateDeclaration implements IASTTemplateSpecialization { private Offsets offsets = new Offsets(); private IASTDeclaration ownedDeclaration; @@ -29,54 +29,10 @@ public class ASTTemplateSpecialization extends ASTDeclaration implements IASTTem */ public ASTTemplateSpecialization(IASTScope scope, int startingOffset, int startingLine ) { - super(scope); + super(scope, null, startingOffset, startingLine, false ); setStartingOffsetAndLineNumber(startingOffset, startingLine); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTTemplate#getOwnedDeclaration() - */ - public IASTDeclaration getOwnedDeclaration() - { - return ownedDeclaration; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setStartingOffset(int) - */ - public void setStartingOffsetAndLineNumber(int offset, int lineNumber) - { - offsets.setStartingOffsetAndLineNumber(offset, lineNumber); - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setEndingOffset(int) - */ - public void setEndingOffsetAndLineNumber(int offset, int lineNumber) - { - offsets.setEndingOffsetAndLineNumber(offset, lineNumber); - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getElementStartingOffset() - */ - public int getStartingOffset() - { - return offsets.getStartingOffset(); - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getElementEndingOffset() - */ - public int getEndingOffset() - { - return offsets.getEndingOffset(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTTemplate#setOwnedDeclaration(org.eclipse.cdt.core.parser.ast.IASTDeclaration) - */ - public void setOwnedDeclaration(IASTDeclaration declaration) - { - ownedDeclaration = declaration; - } - /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#accept(org.eclipse.cdt.core.parser.ISourceElementRequestor) */ @@ -112,20 +68,5 @@ public class ASTTemplateSpecialization extends ASTDeclaration implements IASTTem { /* do nothing */ } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getStartingLine() - */ - public int getStartingLine() { - return offsets.getStartingLine(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getEndingLine() - */ - public int getEndingLine() { - return offsets.getEndingLine(); - } - + } } 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 90aa02d5d8f..05ecb89500f 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 @@ -553,8 +553,8 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { if( foundSymbol instanceof IContainerSymbol ) return (IContainerSymbol) foundSymbol; - else - return null; + + return null; } /* (non-Javadoc) @@ -725,16 +725,17 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { ParserSymbolTable.lookup( data, this ); ISymbol found = ParserSymbolTable.resolveAmbiguities( data ); + if( found != null ){ + if( (found.isType( TypeInfo.t_templateParameter ) && found.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template) || + found.isType( TypeInfo.t_template ) ) + { + found = ((ITemplateSymbol) found).instantiate( arguments ); + } else if( found.getContainingSymbol().isType( TypeInfo.t_template ) ){ + found = ((ITemplateSymbol) found.getContainingSymbol()).instantiate( arguments ); + } + } - if( (found.isType( TypeInfo.t_templateParameter ) && found.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template) || - found.isType( TypeInfo.t_template ) ) - { - return ((ITemplateSymbol) found).instantiate( arguments ); - } else if( found.getContainingSymbol().isType( TypeInfo.t_template ) ){ - return ((ITemplateSymbol) found.getContainingSymbol()).instantiate( arguments ); - } - - return null; + return found; } /* (non-Javadoc) @@ -1067,8 +1068,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { * @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 { - // TODO Auto-generated method stub - + throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate ); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java index 80839cd78c1..9452129dde6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java @@ -29,6 +29,8 @@ public class DeferredTemplateInstance extends BasicSymbol implements IDeferredTe _arguments = new LinkedList( args ); setContainingSymbol( template ); + if( template.getTemplatedSymbol() != null ) + setASTExtension( template.getTemplatedSymbol().getASTExtension() ); } @@ -76,14 +78,14 @@ public class DeferredTemplateInstance extends BasicSymbol implements IDeferredTe public TypeInfo.eType getType(){ return _template.getTemplatedSymbol().getType(); } + + public TypeInfo getTypeInfo(){ + return _template.getTemplatedSymbol().getTypeInfo(); + } public boolean isType( TypeInfo.eType type ){ return _template.getTemplatedSymbol().isType( type ); } - - public ISymbolASTExtension getASTExtension() { - return _template.getTemplatedSymbol().getASTExtension(); - } private ITemplateSymbol _template; private List _arguments; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateFactory.java index f8be7228a97..d5cb02e366c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ITemplateFactory.java @@ -17,8 +17,6 @@ import java.util.List; **/ public interface ITemplateFactory extends IDerivableContainerSymbol { - public ITemplateSymbol getPrimaryTemplate(); - public void pushTemplate( ITemplateSymbol template ); public void pushSymbol( ISymbol symbol ); public void pushTemplateId( ISymbol symbol, List args ); 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 4eb9a5e5a15..81459490c97 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 @@ -437,7 +437,8 @@ public class ParserSymbolTable { return true; } - return data.filter.shouldAccept( symbol ); + TypeInfo typeInfo = ParserSymbolTable.getFlatTypeInfo( symbol.getTypeInfo() ); + return data.filter.shouldAccept( symbol, typeInfo ) || data.filter.shouldAccept( symbol ); } private static Object collectSymbol(LookupData data, Object object ) throws ParserSymbolTableException { @@ -903,6 +904,8 @@ public class ParserSymbolTable { * provided in data.parameters. */ static protected ISymbol resolveAmbiguities( LookupData data ) throws ParserSymbolTableException{ + ISymbol resolvedSymbol = null; + if( data.foundItems == null || data.foundItems.isEmpty() || data.mode == LookupMode.PREFIX ){ return null; } @@ -921,23 +924,45 @@ public class ParserSymbolTable { if( symbol.isTemplateMember() && !symbol.isTemplateInstance() && !symbol.isType( TypeInfo.t_templateParameter ) && symbol.getContainingSymbol().isType( TypeInfo.t_template )) { - return symbol.getContainingSymbol(); + resolvedSymbol = symbol.getContainingSymbol(); + } else { + resolvedSymbol = symbol; } - return symbol; } } - if( data.parameters == null ){ - //we have no parameter information, if we only have one function, return - //that, otherwise we can't decide between them - if( functionList.size() == 1){ - return (ISymbol) functionList.getFirst(); + if( resolvedSymbol == null ){ + if( data.parameters == null ){ + //we have no parameter information, if we only have one function, return + //that, otherwise we can't decide between them + if( functionList.size() == 1){ + resolvedSymbol = (ISymbol) functionList.getFirst(); + } else { + throw new ParserSymbolTableException( ParserSymbolTableException.r_UnableToResolveFunction ); + } } else { - throw new ParserSymbolTableException( ParserSymbolTableException.r_UnableToResolveFunction ); + resolvedSymbol = resolveFunction( data, functionList ); } - } else { - return resolveFunction( data, functionList ); } + if( resolvedSymbol != null && resolvedSymbol.getTypeInfo().checkBit( TypeInfo.isTypedef ) ){ + ISymbol symbol = resolvedSymbol.getTypeSymbol(); + TypeInfo info = ParserSymbolTable.getFlatTypeInfo( symbol.getTypeInfo() ); + + symbol = info.getTypeSymbol(); + ISymbol newSymbol = null; + if( symbol != null ){ + newSymbol = (ISymbol) symbol.clone(); + newSymbol.setName( resolvedSymbol.getName() ); + } else { + newSymbol = resolvedSymbol.getSymbolTable().newSymbol( resolvedSymbol.getName() ); + newSymbol.setTypeInfo( info ); + } + newSymbol.setASTExtension( resolvedSymbol.getASTExtension() ); + newSymbol.setContainingSymbol( resolvedSymbol.getContainingSymbol() ); + resolvedSymbol = newSymbol; + } + + return resolvedSymbol; } static protected IParameterizedSymbol resolveFunction( LookupData data, List functions ) throws ParserSymbolTableException{ @@ -1796,6 +1821,9 @@ public class ParserSymbolTable { data.parameters.add( source ); data.forUserDefinedConversion = true; + if( targetDecl instanceof IDeferredTemplateInstance ){ + targetDecl = ((IDeferredTemplateInstance)targetDecl).getTemplate().getTemplatedSymbol(); + } IDerivableContainerSymbol container = (IDerivableContainerSymbol) targetDecl; if( !container.getConstructors().isEmpty() ){ 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 322b0761f6a..c5ee8a16c42 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 @@ -58,6 +58,8 @@ public final class TemplateEngine { TypeInfo newInfo = new TypeInfo( info ); newInfo.setTypeSymbol( info.getTypeSymbol().instantiate( template, argMap ) ); return newInfo; + } else if( info.checkBit( TypeInfo.isTypedef ) && info.getTypeSymbol() != null ){ + return instantiateTypeInfo( info.getTypeSymbol().getTypeInfo(), template, argMap ); } return info; } @@ -1224,8 +1226,8 @@ public final class TemplateEngine { return false; } - ITemplateSymbol t1 = (ITemplateSymbol) p1.getContainingSymbol(); - ITemplateSymbol t2 = (ITemplateSymbol) p2.getContainingSymbol(); + ITemplateSymbol t1 = (ITemplateSymbol) getContainingTemplate( p1 );//.getContainingSymbol(); + ITemplateSymbol t2 = (ITemplateSymbol) getContainingTemplate( p2 );//.getContainingSymbol(); if( p1.getTypeInfo().getTemplateParameterType() == TypeInfo.t_typeName ) { @@ -1239,4 +1241,15 @@ public final class TemplateEngine { return p1.getTypeInfo().equals( p2.getTypeInfo() ); } } + + static protected ITemplateSymbol getContainingTemplate( ISymbol symbol ){ + if( ! symbol.isTemplateMember() ){ + return null; + } + + while( !( symbol.getContainingSymbol() instanceof ITemplateSymbol ) ){ + symbol = symbol.getContainingSymbol(); + } + return (ITemplateSymbol) symbol.getContainingSymbol(); + } } 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 0f7e934dc09..27d64b8cf03 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 @@ -16,7 +16,6 @@ import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Map; -import java.util.Set; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTemplateDeclaration; @@ -67,7 +66,7 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor List params = template.getParameterList(); if( params.size() == 0 ){ //explicit specialization - + addExplicitSpecialization( origTemplate, symbol, args ); } else { //partial speciailization ISpecializedSymbol spec = template.getSymbolTable().newSpecializedSymbol( symbol.getName() ); @@ -261,25 +260,25 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor } } - private void addExplicitSpecialization( ISymbol symbol ) throws ParserSymbolTableException { - Iterator templatesIter = getTemplatesList().iterator(); - Iterator argsIter = getArgumentsList().iterator(); + private void addExplicitSpecialization( ITemplateSymbol template, ISymbol symbol, List arguments ) throws ParserSymbolTableException { + Iterator templatesIter = templates.iterator(); + Iterator argsIter = arguments.iterator(); - while( templatesIter.hasNext() ){ - ITemplateSymbol template = (ITemplateSymbol)templatesIter.next(); +// while( templatesIter.hasNext() ){ +// ITemplateSymbol template = (ITemplateSymbol)templatesIter.next(); - template.addExplicitSpecialization( symbol, (List) argsIter.next() ); - } + template.addExplicitSpecialization( symbol, arguments ); + //} - if( getTemplateFunctions() != null && argsIter.hasNext() ){ - List args = (List) argsIter.next(); - ITemplateSymbol template = TemplateEngine.resolveTemplateFunctions( getTemplateFunctions(), args, symbol ); - if( template != null ){ - template.addExplicitSpecialization( symbol, args ); - } else { - throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate ); - } - } +// if( getTemplateFunctions() != null && argsIter.hasNext() ){ +// List args = (List) argsIter.next(); +// ITemplateSymbol template = TemplateEngine.resolveTemplateFunctions( getTemplateFunctions(), args, symbol ); +// if( template != null ){ +// template.addExplicitSpecialization( symbol, args ); +// } else { +// throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate ); +// } +// } } /* (non-Javadoc) @@ -300,31 +299,6 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor } } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#getPrimaryTemplate() - */ - public ITemplateSymbol getPrimaryTemplate() { - return (ITemplateSymbol) templatesList.get( 0 ); - } - - protected List getTemplatesList() { - return templatesList; - } - protected List getParametersList() { - return parametersList; - } - protected List getArgumentsList(){ - return argumentsList; - } - protected Set getTemplateFunctions(){ - return templateFunctions; - } - - private Set templateFunctions; - private List templatesList; - private List parametersList; - private List argumentsList; - /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#removeSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol) */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java index e827491185b..c2bd5dd2a1c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java @@ -104,10 +104,12 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb if( argIter.hasNext() ){ arg = (TypeInfo) argIter.next(); - //If the argument is a template parameter, we can't instantiate yet, defer for later - if( arg.isType( TypeInfo.t_type ) && arg.getTypeSymbol().isType( TypeInfo.t_templateParameter ) ){ - return deferredInstance( arguments ); + if( arg.isType( TypeInfo.t_type ) ){ + if( arg.getTypeSymbol() == null ) + throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument ); + else if( arg.getTypeSymbol().isType( TypeInfo.t_templateParameter ) ) + return deferredInstance( arguments ); } } else { Object obj = param.getTypeInfo().getDefault(); @@ -233,8 +235,19 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb Map map = getExplicitSpecializations(); Map specs = null; - if( map.containsKey( actualArgs ) ){ - specs = (Map) map.get( actualArgs ); + List key = null; + + Iterator iter = map.keySet().iterator(); + while( iter.hasNext() ){ + List list = (List) iter.next(); + if( list.equals( args ) ){ + key = list; + break; + } + } + + if( key != null ){ + specs = (Map) map.get( key ); } else { specs = new HashMap(); map.put( new LinkedList( actualArgs ), specs ); @@ -244,7 +257,7 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb try{ if( symbol.isType( TypeInfo.t_function ) || symbol.isType( TypeInfo.t_constructor ) ){ List fnArgs = new LinkedList(); - Iterator iter = ((IParameterizedSymbol)symbol).getParameterList().iterator(); + iter = ((IParameterizedSymbol)symbol).getParameterList().iterator(); while( iter.hasNext() ){ fnArgs.add( ((ISymbol)iter.next()).getTypeInfo() ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java index 341c25d28ff..3db351eb118 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java @@ -293,6 +293,9 @@ public class TypeInfo { _templateParameterType = type; } + public TypeInfo getFinalType(){ + return ParserSymbolTable.getFlatTypeInfo( this ); + } /** * * @param type diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/BranchTracker.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/BranchTracker.java index 34743c91871..d8a1d121765 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/BranchTracker.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/BranchTracker.java @@ -166,7 +166,7 @@ public class BranchTracker { } // taken only on an #endif - public boolean poundEndif( ) + public boolean poundEndif( ) throws EmptyStackException { if( ignore == branches.size() ) ignore = IGNORE_SENTINEL; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java index 0a1b2578d09..466d961b756 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java @@ -1306,7 +1306,16 @@ public class Scanner implements IScanner { buffer.append( restOfLine ); handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true ); } - passOnToClient = scannerData.getBranchTracker().poundEndif(); + try{ + passOnToClient = scannerData.getBranchTracker().poundEndif(); + } + catch( EmptyStackException ese ) + { + handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION, + token, + beginningOffset, + false, true ); + } return null; case PreprocessorDirectives.IFNDEF :