1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

parsing template-ids, enabling template instantiations & class template partial specializations & indirectly fixes bug 54778

This commit is contained in:
Andrew Niefer 2004-03-18 23:20:16 +00:00
parent 1aeedbdee2
commit 51131345db
19 changed files with 791 additions and 95 deletions

View file

@ -1,3 +1,13 @@
2003-03-18 Andrew Niefer
parsing template-ids
- added parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.test54778()
- modified parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTests.java
- modified parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testOverloadedFunctionTemplates()
- added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testOverloadedFunctionTemplates_2()
- added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTemplateClassPartialSpecialization()
- added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTemplateInstanceAsBaseClause()
- added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTemplateParameterAsBaseClause()
2004-03-18 Alain Magloire
Change in the hierarchy of the core Model:

View file

@ -1455,6 +1455,76 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
writer.write( " }" );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTTemplateDeclaration template1 = (IASTTemplateDeclaration) i.next();
IASTTemplateParameter T1 = (IASTTemplateParameter) template1.getTemplateParameters().next();
IASTFunction f1 = (IASTFunction) template1.getOwnedDeclaration();
IASTTemplateDeclaration template2 = (IASTTemplateDeclaration) i.next();
IASTFunction f2 = (IASTFunction) template2.getOwnedDeclaration();
IASTTemplateParameter T2 = (IASTTemplateParameter) template2.getTemplateParameters().next();
IASTVariable p = (IASTVariable) i.next();
IASTFunction main = (IASTFunction) i.next();
assertFalse( i.hasNext() );
assertAllReferences( 6, createTaskList( new Task( T1 ),
new Task( T2 ),
new Task( f1, 1, false, false ),
new Task( p, 2 ),
new Task( f2, 1, false, false ) ) );
}
public void testOverloadedFunctionTemplates_2() throws Exception
{
Writer writer = new StringWriter();
writer.write("template< class T > struct A { }; \n");
writer.write("template< class T > void h( const T & ); //#1 \n");
writer.write("template< class T > void h( A<T>& ); //#2 \n");
writer.write("void foo() { \n");
writer.write(" A<int> z; \n");
writer.write(" h( z ); //calls 2 \n");
writer.write(" const A<int> z2; \n");
writer.write(" h( z2 ); //calls 1 because 2 is not callable. \n");
writer.write( "} \n");
Iterator i = parse( writer.toString() ).getDeclarations();
IASTTemplateDeclaration templateA = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration templateh1 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration templateh2 = (IASTTemplateDeclaration) i.next();
IASTClassSpecifier A = (IASTClassSpecifier) templateA.getOwnedDeclaration();
IASTFunction h1 = (IASTFunction) templateh1.getOwnedDeclaration();
IASTFunction h2 = (IASTFunction) templateh2.getOwnedDeclaration();
IASTTemplateParameter T1 = (IASTTemplateParameter) templateA.getTemplateParameters().next();
IASTTemplateParameter T2 = (IASTTemplateParameter) templateh1.getTemplateParameters().next();
IASTTemplateParameter T3 = (IASTTemplateParameter) templateh2.getTemplateParameters().next();
IASTFunction foo = (IASTFunction) i.next();
assertFalse( i.hasNext() );
i = getDeclarations( foo );
IASTVariable z = (IASTVariable) i.next();
IASTVariable z2 = (IASTVariable) i.next();
assertFalse( i.hasNext() );
assertEquals( ((IASTSimpleTypeSpecifier)z.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A );
assertEquals( ((IASTSimpleTypeSpecifier)z2.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A );
assertAllReferences( 8 /*9*/, createTaskList( new Task( T2 ),
//new Task( T3 ),
new Task( A, 3 ),
new Task( z ),
new Task( z2 ),
new Task( h1, 1, false, false ),
new Task( h2, 1, false, false ) ) );
}
public void testBug54639() throws Exception
{
@ -1477,6 +1547,134 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
assertFalse( i.hasNext() );
}
public void testTemplateClassPartialSpecialization() throws Exception
{
Writer writer = new StringWriter();
writer.write( "template < class T1, class T2, int I > class A {}; //#1\n" );
writer.write( "template < class T, int I > class A < T, T*, I > {}; //#2\n");
writer.write( "template < class T1, class T2, int I > class A < T1*, T2, I > {}; //#3\n");
writer.write( "template < class T > class A < int, T*, 5 > {}; //#4\n");
writer.write( "template < class T1, class T2, int I > class A < T1, T2*, I > {}; //#5\n");
writer.write( "A <int, int, 1> a1; //uses #1 \n");
writer.write( "A <int, int*, 1> a2; //uses #2, T is int, I is 1 \n");
writer.write( "A <int, char*, 5> a4; //uses #4, T is char \n");
writer.write( "A <int, char*, 1> a5; //uses #5, T is int, T2 is char, I is1 \n");
Iterator i = parse( writer.toString() ).getDeclarations();
writer.write( " A <int*, int*, 2> amgiguous; //ambiguous, matches #3 & #5 \n");
try{
//we expect this parse to fail because of the ambiguity in the last line
parse( writer.toString() );
assertFalse( true );
} catch ( ParserException e ){
assertEquals( e.getMessage(), "FAILURE" );
}
IASTTemplateDeclaration template1 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration spec2 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration spec3 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration spec4 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration spec5 = (IASTTemplateDeclaration) i.next();
IASTVariable a1 = (IASTVariable) i.next();
IASTVariable a2 = (IASTVariable) i.next();
IASTVariable a4 = (IASTVariable) i.next();
IASTVariable a5 = (IASTVariable) i.next();
assertFalse( i.hasNext() );
IASTClassSpecifier A1 = (IASTClassSpecifier)template1.getOwnedDeclaration();
IASTClassSpecifier A2 = (IASTClassSpecifier)spec2.getOwnedDeclaration();
IASTClassSpecifier A3 = (IASTClassSpecifier)spec3.getOwnedDeclaration();
IASTClassSpecifier A4 = (IASTClassSpecifier)spec4.getOwnedDeclaration();
IASTClassSpecifier A5 = (IASTClassSpecifier)spec5.getOwnedDeclaration();
assertEquals( ((IASTSimpleTypeSpecifier)a1.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A1 );
assertEquals( ((IASTSimpleTypeSpecifier)a2.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A2 );
assertEquals( ((IASTSimpleTypeSpecifier)a4.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A4 );
assertEquals( ((IASTSimpleTypeSpecifier)a5.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A5 );
}
public void testTemplateInstanceAsBaseClause() throws Exception
{
Writer writer = new StringWriter();
writer.write( "template< class T > class A { T t; }; \n" );
writer.write( "class B : public A< int > {}; \n" );
writer.write( "void f( int ); \n" );
writer.write( "void main(){ \n" );
writer.write( " B b; \n" );
writer.write( " f( b.t ); \n" ); //if this function call is good, it implies that b.t is type int
writer.write( "} \n" );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next();
IASTTemplateParameter T = (IASTTemplateParameter) template.getTemplateParameters().next();
IASTClassSpecifier B = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTFunction f = (IASTFunction) i.next();
IASTFunction main = (IASTFunction) i.next();
assertFalse( i.hasNext() );
IASTClassSpecifier A = (IASTClassSpecifier) template.getOwnedDeclaration();
i = getDeclarations( A );
IASTField t = (IASTField) i.next();
assertFalse( i.hasNext() );
i = getDeclarations( main );
IASTVariable b = (IASTVariable) i.next();
assertFalse( i.hasNext() );
assertAllReferences( 6, createTaskList( new Task( T ),
new Task( A ),
new Task( B ),
new Task( b ),
new Task( t ),
new Task( f ) ) );
}
public void testTemplateParameterAsBaseClause() throws Exception
{
Writer writer = new StringWriter();
writer.write( "template < class T > class A : public T {}; \n" );
writer.write( "class B { int i; }; \n" );
writer.write( "void main() { \n" );
writer.write( " A<B> a; \n" );
writer.write( " a.i; \n" );
writer.write( "} \n" );
writer.write( "\n" );
Iterator iter = parse( writer.toString() ).getDeclarations();
IASTTemplateDeclaration template = (IASTTemplateDeclaration) iter.next();
IASTTemplateParameter T = (IASTTemplateParameter) template.getTemplateParameters().next();
IASTClassSpecifier B = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)iter.next()).getTypeSpecifier();
IASTFunction main = (IASTFunction) iter.next();
assertFalse( iter.hasNext() );
IASTClassSpecifier A = (IASTClassSpecifier) template.getOwnedDeclaration();
iter = getDeclarations( B );
IASTVariable i = (IASTVariable) iter.next();
iter = getDeclarations( main );
IASTVariable a = (IASTVariable) iter.next();
assertAllReferences( 4 /*5*/, createTaskList( new Task( T ),
new Task( A ),
//new Task( B ),
new Task( a ),
new Task( i ) ) );
}
public void testBug55163() throws Exception
{
Writer writer = new StringWriter();

View file

@ -733,7 +733,7 @@ public class CompleteParseBaseTest extends TestCase
protected void assertReferences(
ISourceElementCallbackDelegate element,
int expectedDistinctReferenceCount,
boolean allowDuplicates )
boolean allowDuplicates, boolean allowNameMatching )
{
Set matches = new HashSet();
Iterator allReferences = callback.getReferences().iterator();
@ -748,7 +748,8 @@ public class CompleteParseBaseTest extends TestCase
else
{
if( r.getReferencedElement() instanceof IASTQualifiedNameElement &&
element instanceof IASTQualifiedNameElement )
element instanceof IASTQualifiedNameElement &&
allowNameMatching )
{
if( qualifiedNamesEquals(
((IASTQualifiedNameElement)r.getReferencedElement()).getFullyQualifiedName(),
@ -770,16 +771,22 @@ public class CompleteParseBaseTest extends TestCase
protected static class Task
{
private final boolean allowNameMatching;
private final boolean unique;
private final int count;
private final ISourceElementCallbackDelegate element;
public Task( ISourceElementCallbackDelegate element, int referenceCount, boolean distinct, boolean matchNames ){
this.element = element;
this.count = referenceCount;
this.unique = distinct;
this.allowNameMatching = matchNames;
}
public Task( ISourceElementCallbackDelegate element, int referenceCount, boolean distinct )
{
this.element = element;
this.count = referenceCount;
this.unique = distinct;
this( element, referenceCount, distinct, true );
}
public Task( ISourceElementCallbackDelegate element, int referenceCount )
@ -815,12 +822,16 @@ public class CompleteParseBaseTest extends TestCase
{
return unique;
}
public boolean allowNameMatching(){
return allowNameMatching;
}
}
protected void assertReferenceTask( Task task )
{
assertReferences( task.getElement(), task.getCount(), task.isUnique() );
assertReferences( task.getElement(), task.getCount(), task.isUnique(), task.allowNameMatching() );
}
protected void assertAllReferences( int count, List tasks )

View file

@ -1564,4 +1564,17 @@ public class ScannerTestCase extends BaseScannerTest
validateIdentifier( "Lißä");
validateEOF();
}
public void test54778() throws ScannerException
{
initializeScanner("#if 1 || 0 < 3 \n printf \n #endif\n");
validateIdentifier("printf");
validateEOF();
initializeScanner("#if !defined FOO || FOO > 3\nprintf\n#endif\n");
validateIdentifier("printf");
validateEOF();
initializeScanner("#if !defined FOO || FOO < 3\nprintf\n#endif\n");
validateIdentifier("printf");
validateEOF();
}
}

View file

@ -184,7 +184,7 @@ public class Util implements ICLogConstants {
if (CCorePlugin.getDefault().isDebugging() && isActive(client)) {
// Time stamp
if (addTimeStamp)
message = MessageFormat.format("[{0}] {1}", new Object[]{
message = MessageFormat.format("[{0}] {1}", new Object[]{ //$NON-NLS-1$
new Long(System.currentTimeMillis()), message}); //$NON-NLS-1$
while (message.length() > 100) {
String partial = message.substring(0, 100);

View file

@ -1,3 +1,11 @@
2004-03-18 Andrew Niefer
parsing template-ids: enables clas template partial specializations and fixes 54778 indirectly
- add ITokenDuple.getTemplateIdArgLists
- Added ExpressionParser.templateArgumentList & ExpressionParser.consumeTemplateArguments
- modifications to ExpressionParser & Parser to parse template argument lists
- modified lookups to lookup with template-id if the token duple has argument lists
- modified TemplateFactory to handle partial specializations
2004-03-17 Andrew Niefer
fix bug 55163
- in for-init-statement, try expression-statement before simple-declaration since if it actually is a statement instead of a

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.core.parser;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.core.parser.ast.IASTFactory;
import org.eclipse.cdt.core.parser.ast.IASTNode;
@ -30,6 +31,7 @@ public interface ITokenDuple {
*/
public abstract IToken getLastToken();
public List [] getTemplateIdArgLists();
public abstract Iterator iterator();
public abstract String toString();

View file

@ -11,6 +11,8 @@
package org.eclipse.cdt.internal.core.parser;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import org.eclipse.cdt.core.parser.BacktrackException;
@ -52,6 +54,8 @@ public class ExpressionParser implements IExpressionParser {
protected boolean parsePassed = true;
protected ParserLanguage language = ParserLanguage.CPP;
protected IASTFactory astFactory = null;
private Stack templateIdScopes = null;
/**
* @param scanner2
@ -149,6 +153,85 @@ public class ExpressionParser implements IExpressionParser {
return last;
}
protected List templateArgumentList( IASTScope scope ) throws EndOfFileException, BacktrackException
{
IASTExpression expression = null;
List list = new LinkedList();
boolean completedArg = false;
boolean failed = false;
if( templateIdScopes == null ){
templateIdScopes = new Stack();
}
templateIdScopes.push( new Integer( IToken.tLT ) );
while( LT(1) != IToken.tGT ){
completedArg = false;
IToken mark = mark();
try{
IASTTypeId typeId = typeId( scope, false );
expression = astFactory.createExpression( scope, IASTExpression.Kind.POSTFIX_TYPEID_TYPEID,
null, null, null, typeId, null, "", null); //$NON-NLS-1$
list.add( expression );
completedArg = true;
} catch( BacktrackException e ){
backup( mark );
} catch (ASTSemanticException e) {
backup( mark );
}
if( ! completedArg ){
try{
expression = assignmentExpression( scope );
if( expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_EMPTY ){
throw backtrack;
}
list.add( expression );
completedArg = true;
} catch( BacktrackException e ){
backup( mark );
}
}
if( !completedArg ){
try{
ITokenDuple nameDuple = name( scope, null );
expression = astFactory.createExpression( scope, IASTExpression.Kind.ID_EXPRESSION,
null, null, null, null, nameDuple, "", null); //$NON-NLS-1$
list.add( expression );
continue;
} catch( ASTSemanticException e ){
failed = true;
break;
}catch( BacktrackException e ){
failed = true;
break;
}
}
if( LT(1) == IToken.tCOMMA ){
consume();
} else if( LT(1) != IToken.tGT ){
failed = true;
break;
}
}
templateIdScopes.pop();
if( templateIdScopes.size() == 0 ){
templateIdScopes = null;
}
if( failed ) {
throw backtrack;
}
return list;
}
/**
* Parse a template-id, according to the ANSI C++ spec.
*
@ -161,8 +244,8 @@ public class ExpressionParser implements IExpressionParser {
*/
protected IToken templateId(IASTScope scope, CompletionKind kind) throws EndOfFileException, BacktrackException {
ITokenDuple duple = name(scope, kind );
IToken last = consumeTemplateParameters(duple.getLastToken());
return last;
//IToken last = consumeTemplateParameters(duple.getLastToken());
return duple.getLastToken();//last;
}
/**
@ -189,21 +272,16 @@ public class ExpressionParser implements IExpressionParser {
if (LT(1) == IToken.tCOMPL)
consume();
List argumentList = new LinkedList();
boolean hasTemplateId = false;
switch (LT(1))
{
case IToken.tIDENTIFIER :
last = consume(IToken.tIDENTIFIER);
IToken secondMark = null;
secondMark = mark();
try
{
last = consumeTemplateParameters(last);
} catch( BacktrackException bt )
{
backup( secondMark );
}
last = consumeTemplateArguments(scope, last, argumentList);
if( last.getType() == IToken.tGT )
hasTemplateId = true;
break;
default :
@ -228,14 +306,44 @@ public class ExpressionParser implements IExpressionParser {
throw backtrack;
case IToken.tIDENTIFIER :
last = consume();
last = consumeTemplateParameters(last);
last = consumeTemplateArguments(scope, last, argumentList);
if( last.getType() == IToken.tGT )
hasTemplateId = true;
}
}
return new TokenDuple(first, last);
return new TokenDuple(first, last, ( hasTemplateId ? argumentList : null ) );
}
/**
* @param scope
* @param last
* @param argumentList
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IToken consumeTemplateArguments(IASTScope scope, IToken last, List argumentList) throws EndOfFileException, BacktrackException {
if( LT(1) == IToken.tLT ){
IToken secondMark = mark();
consume( IToken.tLT );
try
{
List list = templateArgumentList( scope );
argumentList.add( list );
last = consume( IToken.tGT );
} catch( BacktrackException bt )
{
argumentList.add( null );
backup( secondMark );
}
} else {
argumentList.add( null );
}
return last;
}
/**
* Parse a const-volatile qualifier.
*
@ -298,7 +406,7 @@ public class ExpressionParser implements IExpressionParser {
}
}
protected void operatorId(Declarator d, IToken originalToken) throws BacktrackException, EndOfFileException {
protected void operatorId(Declarator d, IToken originalToken, List templateArgs) throws BacktrackException, EndOfFileException {
// we know this is an operator
IToken operatorToken = consume(IToken.t_operator);
IToken toSend = null;
@ -337,10 +445,17 @@ public class ExpressionParser implements IExpressionParser {
typeId(d.getDeclarationWrapper().getScope(), true );
toSend = lastToken;
}
List args = ( templateArgs != null ) ? templateArgs : new LinkedList();
boolean hasTemplateId = ( templateArgs != null );
toSend = consumeTemplateArguments( d.getDeclarationWrapper().getScope(), toSend, args );
if( toSend.getType() == IToken.tGT ){
hasTemplateId = true;
}
ITokenDuple duple =
new TokenDuple(
originalToken == null ? operatorToken : originalToken,
toSend);
new TokenDuple( originalToken == null ? operatorToken : originalToken, toSend, (hasTemplateId ? args : null ) );
d.setName(duple);
}
@ -814,6 +929,9 @@ public class ExpressionParser implements IExpressionParser {
switch (LT(1))
{
case IToken.tGT :
if( templateIdScopes != null && ((Integer)templateIdScopes.peek()).intValue() == IToken.tLT ){
return firstExpression;
}
case IToken.tLT :
case IToken.tLTEQUAL :
case IToken.tGTEQUAL :
@ -1075,12 +1193,15 @@ public class ExpressionParser implements IExpressionParser {
{
IToken mark = mark();
consume();
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
boolean popped = false;
IASTTypeId typeId = null;
// If this isn't a type name, then we shouldn't be here
try
{
typeId = typeId(scope, false);
consume(IToken.tRPAREN);
if( templateIdScopes != null ){ templateIdScopes.pop(); popped = true;}
IASTExpression castExpression = castExpression(scope);
try
{
@ -1104,6 +1225,7 @@ public class ExpressionParser implements IExpressionParser {
catch (BacktrackException b)
{
backup(mark);
if( templateIdScopes != null && !popped ){ templateIdScopes.pop(); }
}
}
return unaryExpression(scope);
@ -1274,8 +1396,9 @@ public class ExpressionParser implements IExpressionParser {
TypeId id = new TypeId(scope);
IToken last = lastToken;
lastToken = consumeTemplateParameters( last );
if( lastToken == null ) lastToken = last;
//template parameters are consumed as part of name
//lastToken = consumeTemplateParameters( last );
//if( lastToken == null ) lastToken = last;
consumePointerOperators( id );
if( lastToken == null ) lastToken = last;
@ -1378,7 +1501,8 @@ public class ExpressionParser implements IExpressionParser {
if (LT(1) == IToken.tLPAREN)
{
consume(IToken.tLPAREN);
consume(IToken.tLPAREN);
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
try
{
// Try to consume placement list
@ -1386,11 +1510,13 @@ public class ExpressionParser implements IExpressionParser {
backtrackMarker = mark();
newPlacementExpressions.add(expression(scope));
consume(IToken.tRPAREN);
if( templateIdScopes != null ){ templateIdScopes.pop(); } //pop 1st Parent
placementParseFailure = false;
if (LT(1) == IToken.tLPAREN)
{
beforeSecondParen = mark();
consume(IToken.tLPAREN);
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); } //push 2nd Paren
typeIdInParen = true;
}
}
@ -1405,6 +1531,7 @@ public class ExpressionParser implements IExpressionParser {
// - then it has to be typeId
typeId = typeId(scope, true );
consume(IToken.tRPAREN);
if( templateIdScopes != null ){ templateIdScopes.pop(); } //pop 1st Paren
}
else
{
@ -1448,6 +1575,8 @@ public class ExpressionParser implements IExpressionParser {
{
typeId = typeId(scope, true);
consume(IToken.tRPAREN);
if( templateIdScopes != null ){ templateIdScopes.pop(); } //popping the 2nd Paren
if (LT(1) == IToken.tLPAREN
|| LT(1) == IToken.tLBRACKET)
{
@ -1485,6 +1614,7 @@ public class ExpressionParser implements IExpressionParser {
// CASE: new (typeid-looking-as-placement)(initializer-not-looking-as-typeid)
// Fallback to initializer processing
backup(beforeSecondParen);
if( templateIdScopes != null ){ templateIdScopes.pop(); }//pop that 2nd paren
}
}
}
@ -1500,16 +1630,25 @@ public class ExpressionParser implements IExpressionParser {
{
// array new
consume();
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLBRACKET ) ); }
newTypeIdExpressions.add(assignmentExpression(scope));
consume(IToken.tRBRACKET);
if( templateIdScopes != null ){ templateIdScopes.pop(); }
}
// newinitializer
if (LT(1) == IToken.tLPAREN)
{
consume(IToken.tLPAREN);
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
if (LT(1) != IToken.tRPAREN)
newInitializerExpressions.add(expression(scope));
consume(IToken.tRPAREN);
if( templateIdScopes != null ){ templateIdScopes.pop(); }
}
setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, Key.EMPTY);
try
@ -1673,8 +1812,7 @@ public class ExpressionParser implements IExpressionParser {
ITokenDuple templateId = null;
try
{
templateId = new TokenDuple( current, templateId(scope, CompletionKind.SINGLE_NAME_REFERENCE
) );
templateId = new TokenDuple( current, templateId(scope, CompletionKind.SINGLE_NAME_REFERENCE ) );
}
catch( BacktrackException bt )
{
@ -1683,8 +1821,10 @@ public class ExpressionParser implements IExpressionParser {
backup( current );
}
consume( IToken.tLPAREN );
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
IASTExpression expressionList = expression( scope );
consume( IToken.tRPAREN );
if( templateIdScopes != null ){ templateIdScopes.pop(); }
try {
firstExpression =
astFactory.createExpression( scope,
@ -1777,6 +1917,7 @@ public class ExpressionParser implements IExpressionParser {
case IToken.t_typeid :
consume();
consume(IToken.tLPAREN);
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
boolean isTypeId = true;
IASTExpression lhs = null;
IASTTypeId typeId = null;
@ -1790,6 +1931,7 @@ public class ExpressionParser implements IExpressionParser {
lhs = expression(scope);
}
consume(IToken.tRPAREN);
if( templateIdScopes != null ){ templateIdScopes.pop(); }
try
{
firstExpression =
@ -1824,8 +1966,10 @@ public class ExpressionParser implements IExpressionParser {
case IToken.tLBRACKET :
// array access
consume();
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLBRACKET ) ); }
secondExpression = expression(scope);
consume(IToken.tRBRACKET);
if( templateIdScopes != null ){ templateIdScopes.pop(); }
try
{
firstExpression =
@ -1850,8 +1994,10 @@ public class ExpressionParser implements IExpressionParser {
case IToken.tLPAREN :
// function call
consume(IToken.tLPAREN);
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
secondExpression = expression(scope);
consume(IToken.tRPAREN);
if( templateIdScopes != null ){ templateIdScopes.pop(); }
try
{
firstExpression =
@ -2189,8 +2335,10 @@ public class ExpressionParser implements IExpressionParser {
}
case IToken.tLPAREN :
consume();
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
IASTExpression lhs = expression(scope);
consume(IToken.tRPAREN);
if( templateIdScopes != null ){ templateIdScopes.pop(); }
try
{
return astFactory.createExpression(
@ -2236,7 +2384,7 @@ public class ExpressionParser implements IExpressionParser {
end = consumeTemplateParameters(end);
}
if (LT(1) == IToken.t_operator)
operatorId(d, start);
operatorId(d, start, null);
else
{
backup(mark);
@ -2244,7 +2392,7 @@ public class ExpressionParser implements IExpressionParser {
}
}
else if( LT(1) == IToken.t_operator )
operatorId( d, null);
operatorId( d, null, null);
duple = d.getNameDuple();
}

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.parser;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.core.parser.BacktrackException;
@ -1703,13 +1704,15 @@ public abstract class Parser extends ExpressionParser implements IParser
*/
protected ITokenDuple className(IASTScope scope) throws EndOfFileException, BacktrackException
{
ITokenDuple duple = name(scope, CompletionKind.USER_SPECIFIED_NAME );
IToken last = duple.getLastToken();
if (LT(1) == IToken.tLT) {
last = consumeTemplateParameters(duple.getLastToken());
}
return new TokenDuple(duple.getFirstToken(), last);
// ITokenDuple duple = name(scope, CompletionKind.USER_SPECIFIED_NAME );
// IToken last = duple.getLastToken();
// if (LT(1) == IToken.tLT) {
// last = consumeTemplateParameters(duple.getLastToken());
// //last = templateArgumentList( scope, duple.getLastToken() );
// }
//
// return new TokenDuple(duple.getFirstToken(), last);
return name( scope, CompletionKind.USER_SPECIFIED_NAME );
}
/**
@ -2196,7 +2199,7 @@ public abstract class Parser extends ExpressionParser implements IParser
throws EndOfFileException, BacktrackException
{
if (LT(1) == IToken.t_operator)
operatorId(d, null);
operatorId(d, null, null);
else
{
try
@ -2210,23 +2213,35 @@ public abstract class Parser extends ExpressionParser implements IParser
Declarator d1 = d;
Declarator d11 = d1;
IToken start = null;
List argumentList = new LinkedList();
boolean hasTemplateId = false;
IToken mark = mark();
if (LT(1) == IToken.tCOLONCOLON
|| LT(1) == IToken.tIDENTIFIER)
{
start = consume();
IToken end = null;
if (start.getType() == IToken.tIDENTIFIER)
end = consumeTemplateParameters(end);
while (LT(1) == IToken.tCOLONCOLON
|| LT(1) == IToken.tIDENTIFIER)
{
end = consume();
if (end.getType() == IToken.tIDENTIFIER)
end = consumeTemplateParameters(end);
if (start.getType() == IToken.tIDENTIFIER){
end = consumeTemplateArguments(d.getDeclarationWrapper().getScope(), end, argumentList);
if( end != null && end.getType() == IToken.tGT )
hasTemplateId = true;
}
while (LT(1) == IToken.tCOLONCOLON
|| LT(1) == IToken.tIDENTIFIER)
{
end = consume();
if (end.getType() == IToken.tIDENTIFIER){
end = consumeTemplateArguments(d.getDeclarationWrapper().getScope(), end, argumentList);
if( end.getType() == IToken.tGT )
hasTemplateId = true;
}
}
if (LT(1) == IToken.t_operator)
operatorId(d11, start);
operatorId(d11, start, ( hasTemplateId ? argumentList : null ) );
else
{
backup(mark);

View file

@ -15,6 +15,7 @@ import java.util.List;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.ast.ASTPointerOperator;
import org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTInitializerClause;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTTypeSpecifier;
@ -114,6 +115,11 @@ public class ASTParameterDeclaration extends ASTSymbol implements IASTParameterD
{
return abstractDeclaration.getTypeSpecifier();
}
public IASTAbstractDeclaration getAbstractDeclaration(){
return abstractDeclaration;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#acceptElement(org.eclipse.cdt.core.parser.ISourceElementRequestor)
*/

View file

@ -17,6 +17,7 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.StringTokenizer;
import org.eclipse.cdt.core.parser.Enum;
@ -91,6 +92,7 @@ import org.eclipse.cdt.internal.core.parser.pst.NamespaceSymbolExtension;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException;
import org.eclipse.cdt.internal.core.parser.pst.StandardSymbolExtension;
import org.eclipse.cdt.internal.core.parser.pst.TemplateSymbolExtension;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
import org.eclipse.cdt.internal.core.parser.pst.ISymbolASTExtension.ExtensionException;
@ -177,6 +179,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
}
private ISymbol lookupElement (IContainerSymbol startingScope, String name, TypeInfo.eType type, List parameters, LookupType lookupType ) throws ASTSemanticException {
return lookupElement( startingScope, name, type, parameters, null, lookupType );
}
private ISymbol lookupElement (IContainerSymbol startingScope, String name, TypeInfo.eType type, List parameters, List arguments, LookupType lookupType ) throws ASTSemanticException {
ISymbol result = null;
if( startingScope == null ) return null;
try {
@ -188,7 +194,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
result = startingDerivableScope.lookupConstructor( new LinkedList(parameters));
}
else {
if( lookupType == LookupType.QUALIFIED )
if( arguments != null )
result = startingScope.lookupFunctionTemplateId( name, new LinkedList( parameters), new LinkedList( arguments ) );
else if( lookupType == LookupType.QUALIFIED )
result = startingScope.qualifiedFunctionLookup(name, new LinkedList(parameters));
else if( lookupType == LookupType.UNQUALIFIED || lookupType == LookupType.FORPARENTSCOPE)
result = startingScope.unqualifiedFunctionLookup( name, new LinkedList( parameters ) );
@ -202,7 +210,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
result = null;
}else{
// looking for something else
if( lookupType == LookupType.QUALIFIED )
if( arguments != null )
result = startingScope.lookupTemplateId( name, arguments );
else if( lookupType == LookupType.QUALIFIED )
result = startingScope.qualifiedLookup(name, type);
else if( lookupType == LookupType.UNQUALIFIED || lookupType == LookupType.FORPARENTSCOPE )
result = startingScope.elaboratedLookup( type, name );
@ -264,6 +274,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
if( name == null && throwOnError ) handleProblem( IProblem.SEMANTIC_NAME_NOT_PROVIDED, null );
else if( name == null ) return null;
List [] templateArgLists = name.getTemplateIdArgLists();
int idx = 0;
switch( name.length() )
{
case 0:
@ -307,19 +319,37 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
while( iter.hasNext() )
{
IToken t = (IToken)iter.next();
if( t.getType() == IToken.tCOLONCOLON ) continue;
if( t.getType() == IToken.tCOLONCOLON ){
idx++;
continue;
}
if( t.isPointer() ) break;
String image = t.getImage();
int offset = t.getOffset();
if( templateArgLists != null && templateArgLists[ idx ] != null ){
t = consumeTemplateIdArguments( t, iter );
}
try
{
if( t == name.getLastToken() )
result = lookupElement((IContainerSymbol)result, t.getImage(), type, parameters, ( lookup == LookupType.FORDEFINITION ) ? lookup : LookupType.QUALIFIED );
if( templateArgLists != null )
result = lookupElement((IContainerSymbol)result, image, type, parameters, getTemplateArgList( templateArgLists[idx] ), ( lookup == LookupType.FORDEFINITION ) ? lookup : LookupType.QUALIFIED );
else
result = lookupElement((IContainerSymbol)result, image, type, parameters, ( lookup == LookupType.FORDEFINITION ) ? lookup : LookupType.QUALIFIED );
else
result = ((IContainerSymbol)result).lookupNestedNameSpecifier( t.getImage() );
if( templateArgLists != null )
result = ((IContainerSymbol)result).lookupTemplateId( image, getTemplateArgList( templateArgLists[idx] ) );
else
result = ((IContainerSymbol)result).lookupNestedNameSpecifier( image );
if( result != null ){
if( lookup == LookupType.FORPARENTSCOPE && startingScope instanceof ITemplateFactory ){
((ITemplateFactory)startingScope).pushSymbol( result );
}
addReference( references, createReference( result, t.getImage(), t.getOffset() ));
addReference( references, createReference( result, image, offset ));
}
else
break;
@ -327,7 +357,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
catch( ParserSymbolTableException pste )
{
if ( throwOnError )
handleProblem( pste.createProblemID(), t.getImage() );
handleProblem( pste.createProblemID(), image );
return null;
}
}
@ -335,7 +365,50 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
return result;
}
protected IToken consumeTemplateIdArguments( IToken name, Iterator iter ){
IToken token = name;
if( token.getNext().getType() == IToken.tLT )
{
token = (IToken) iter.next();
Stack scopes = new Stack();
scopes.push(new Integer(IToken.tLT));
while (!scopes.empty())
{
int top;
token = (IToken) iter.next();
switch( token.getType() ){
case IToken.tGT:
if (((Integer)scopes.peek()).intValue() == IToken.tLT) {
scopes.pop();
}
break;
case IToken.tRBRACKET :
do {
top = ((Integer)scopes.pop()).intValue();
} while (!scopes.empty() && (top == IToken.tGT || top == IToken.tLT));
//if (top != IToken.tLBRACKET) throw backtrack;
break;
case IToken.tRPAREN :
do {
top = ((Integer)scopes.pop()).intValue();
} while (!scopes.empty() && (top == IToken.tGT || top == IToken.tLT));
//if (top != IToken.tLPAREN) throw backtrack;
break;
case IToken.tLT :
case IToken.tLBRACKET:
case IToken.tLPAREN:
scopes.push(new Integer(token.getType()));
break;
}
}
}
return token;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createUsingDirective(org.eclipse.cdt.core.parser.ast.IASTScope, org.eclipse.cdt.core.parser.ITokenDuple, int, int)
*/
@ -525,7 +598,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
{
extension = new ForewardDeclaredSymbolExtension( symbol, astSymbol );
}
else
else if( astSymbol instanceof IASTTemplateDeclaration ){
extension = new TemplateSymbolExtension( symbol, astSymbol );
}
else
{
extension = new StandardSymbolExtension( symbol, astSymbol );
}
@ -569,23 +645,37 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
List references = new ArrayList();
String newSymbolName = ""; //$NON-NLS-1$
List templateIdArgList = null;
boolean isTemplateId = false;
if( name != null ){
IToken lastToken = name.getLastToken();
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, true);
if( currentScopeSymbol == null )
handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, containerSymbolName.toString(), containerSymbolName.getFirstToken().getOffset(), containerSymbolName.getLastToken().getEndOffset(), containerSymbolName.getLastToken().getLineNumber() );
int idx = name.findLastTokenType( IToken.tCOLONCOLON );
if( idx != -1 ){
ITokenDuple containerSymbolName =
name.getSubrange( 0, idx - 1 ); // -1 for index, -2 for last hop of qualified name
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);
}
}
newSymbolName = lastToken.getImage();
}
ISymbol classSymbol = null;
if( !newSymbolName.equals("") ){ //$NON-NLS-1$
if( !newSymbolName.equals("") && !isTemplateId ){ //$NON-NLS-1$
try
{
classSymbol = currentScopeSymbol.lookupMemberForDefinition(newSymbolName);
@ -607,9 +697,16 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
if( classSymbol != null )
classSymbol.setTypeSymbol( newSymbol );
List args = null;
if( isTemplateId ){
args = getTemplateArgList( templateIdArgList );
}
try
{
currentScopeSymbol.addSymbol( newSymbol );
if( !isTemplateId )
currentScopeSymbol.addSymbol( newSymbol );
else
currentScopeSymbol.addTemplateId( newSymbol, args );
}
catch (ParserSymbolTableException e2)
{
@ -621,6 +718,25 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
return classSpecifier;
}
private List getTemplateArgList( List args ){
if( args == null )
return null;
List list = new LinkedList();
Iterator iter = args.iterator();
ASTExpression exp;
while( iter.hasNext() )
{
exp = (ASTExpression) iter.next();
TypeInfo info = exp.getResultType().getResult();;
list.add( info );
}
return list;
}
protected void handleProblem( int id, String attribute ) throws ASTSemanticException
{
@ -692,8 +808,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
}
else
handleProblem( IProblem.SEMANTIC_NAME_NOT_PROVIDED, null );
IContainerSymbol symbol = (IContainerSymbol) lookupQualifiedName( classSymbol, parentClassName, references, true );
//Its possible that the parent is not an IContainerSymbol if its a template parameter or some kinds of template instances
ISymbol symbol = (ISymbol) lookupQualifiedName( classSymbol, parentClassName, references, true );
classSymbol.addParent( symbol, isVirtual, visibility, parentClassName.getFirstToken().getOffset(), references );
}
@ -840,7 +957,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
if( idExpression != null )
{
logMessage.append( " idexpression=" ); //$NON-NLS-1$
logMessage.append( "idExpression.toString()"); //$NON-NLS-1$
logMessage.append( idExpression.toString()); //$NON-NLS-1$
}
else if( literal != null && !literal.equals( "" )) //$NON-NLS-1$
{
@ -1091,7 +1208,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
ExpressionResult result = null;
TypeInfo info = new TypeInfo();
if( literal != null && !literal.equals("") ){ //$NON-NLS-1$
info.setDefault( literal );
}
// types that resolve to void
if ((kind == IASTExpression.Kind.PRIMARY_EMPTY)
|| (kind == IASTExpression.Kind.THROWEXPRESSION)
@ -1574,26 +1693,42 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
ISymbol typeSymbol = getScopeToSearchUpon( scope, first, i );
List [] argLists = typeName.getTemplateIdArgLists();
int idx = 0;
while( i.hasNext() )
{
IToken current = (IToken)i.next();
if( current.getType() == IToken.tCOLONCOLON ) continue;
if( current.getType() == IToken.tCOLONCOLON ){
idx++;
continue;
}
String image = current.getImage();
int offset = current.getOffset();
if( argLists != null && argLists[ idx ] != null ){
current = consumeTemplateIdArguments( current, i );
}
try
{
if( current != typeName.getLastToken() )
typeSymbol = ((IContainerSymbol)typeSymbol).lookupNestedNameSpecifier( current.getImage());
if( argLists != null && argLists[ idx ] != null )
typeSymbol = ((IContainerSymbol)typeSymbol).lookupTemplateId( image, getTemplateArgList( argLists[idx] ) );
else if( current != typeName.getLastToken() )
typeSymbol = ((IContainerSymbol)typeSymbol).lookupNestedNameSpecifier( image );
else
typeSymbol = ((IContainerSymbol)typeSymbol).lookup( current.getImage());
typeSymbol = ((IContainerSymbol)typeSymbol).lookup( image );
if( typeSymbol != null )
addReference( references, createReference( typeSymbol, current.getImage(), current.getOffset() ));
addReference( references, createReference( typeSymbol, image, offset ));
else
handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, current.getImage() );
handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, image );
}
catch (ParserSymbolTableException e)
{
handleProblem( e.createProblemID(), current.getImage() );
handleProblem( e.createProblemID(), image );
}
}
s.setTypeSymbol( typeSymbol );
@ -2472,7 +2607,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
try {
template.addTemplateParameter( param.getSymbol() );
} catch (ParserSymbolTableException e) {
handleProblem( e.createProblemID(), "", startingOffset, -1, startingLine );
handleProblem( e.createProblemID(), "", startingOffset, -1, startingLine ); //$NON-NLS-1$
}
}
@ -2492,21 +2627,23 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
IASTParameterDeclaration parameter,
List parms ) throws ASTSemanticException
{
ISymbol symbol = ( kind != ParamKind.PARAMETER ) ? pst.newSymbol( identifier, TypeInfo.t_templateParameter ) : null;
ISymbol symbol = pst.newSymbol( identifier, TypeInfo.t_templateParameter );
if( kind == ParamKind.CLASS || kind == ParamKind.TYPENAME ){
symbol.getTypeInfo().setTemplateParameterType( TypeInfo.t_typeName );
} else if ( kind == ParamKind.TEMPLATE_LIST ){
symbol.getTypeInfo().setTemplateParameterType( TypeInfo.t_template );
} else /*ParamKind.PARAMETER*/ {
symbol = ((ASTParameterDeclaration)parameter).getSymbol();
symbol.setName( parameter.getName() );
symbol.setTypeInfo( ((ASTSimpleTypeSpecifier)parameter.getTypeSpecifier()).getSymbol().getTypeInfo() );
symbol.getTypeInfo().setTemplateParameterType( symbol.getType() );
symbol.setType( TypeInfo.t_templateParameter );
setPointerOperators( symbol, parameter.getPointerOperators(), parameter.getArrayModifiers() );
}
ASTTemplateParameter ast = new ASTTemplateParameter( symbol, defaultValue, parameter, parms );
//TODO what if the symbol was ParamKind.PARAMETER?
attachSymbolExtension( symbol, ast, false );
attachSymbolExtension( symbol, ast, false );
return ast;
}
@ -2544,7 +2681,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
ISymbol newSymbol = pst.newSymbol( name, TypeInfo.t_type);
newSymbol.getTypeInfo().setBit( true,TypeInfo.isTypedef );
ISymbol typeSymbol = cloneSimpleTypeSymbol( "", mapping, new ArrayList() );
ISymbol typeSymbol = cloneSimpleTypeSymbol( "", mapping, new ArrayList() ); //$NON-NLS-1$
setPointerOperators( typeSymbol, mapping.getPointerOperators(), mapping.getArrayModifiers() );
newSymbol.setTypeSymbol( typeSymbol );

View file

@ -1063,6 +1063,21 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
private LinkedList _contents; //ordered list of all contents of this symbol
private LinkedList _usingDirectives; //collection of nominated namespaces
private Map _containedSymbols; //declarations contained by us.
/* (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 {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupFunctionTemplateId(java.lang.String, java.util.List, java.util.List)
*/
public ISymbol lookupFunctionTemplateId(String name, List parameters, List arguments) throws ParserSymbolTableException {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -69,6 +69,22 @@ public class DeferredTemplateInstance extends BasicSymbol implements IDeferredTe
return instance;
}
public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType ){
return _template.getTemplatedSymbol().isType( type, upperType );
}
public TypeInfo.eType getType(){
return _template.getTemplatedSymbol().getType();
}
public boolean isType( TypeInfo.eType type ){
return _template.getTemplatedSymbol().isType( type );
}
public ISymbolASTExtension getASTExtension() {
return _template.getTemplatedSymbol().getASTExtension();
}
private ITemplateSymbol _template;
private List _arguments;
}

View file

@ -79,13 +79,13 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
newSymbol.getParents().add( newWrapper );
}
Iterator constructors = getConstructors().iterator();
newSymbol.getConstructors().clear();
IParameterizedSymbol constructor = null;
while( constructors.hasNext() ){
constructor = (IParameterizedSymbol) constructors.next();
newSymbol.getConstructors().add( constructor.instantiate( template, argMap ) );
}
// Iterator constructors = getConstructors().iterator();
// newSymbol.getConstructors().clear();
// IParameterizedSymbol constructor = null;
// while( constructors.hasNext() ){
// constructor = (IParameterizedSymbol) constructors.next();
// newSymbol.getConstructors().add( constructor.instantiate( template, argMap ) );
// }
//TODO: friends
@ -156,6 +156,8 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
}
constructor.setContainingSymbol( this );
constructor.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
addThis( constructor );
getContents().add( constructor );

View file

@ -37,6 +37,8 @@ public interface IContainerSymbol extends ISymbol {
* hide the first symbol (3.3.7) or is not a valid function overload (3.4-1)
*/
public void addSymbol( ISymbol symbol ) throws ParserSymbolTableException;
public void addTemplateId( ISymbol symbol, List args ) throws ParserSymbolTableException;
public boolean removeSymbol( ISymbol symbol );
@ -117,6 +119,7 @@ public interface IContainerSymbol extends ISymbol {
* r_BadTemplateArgument if (14.3.1, 14.3.2) a template argument is invalid
*/
public ISymbol lookupTemplateId( String name, List arguments ) throws ParserSymbolTableException;
public ISymbol lookupFunctionTemplateId( String name, List parameters, List arguments ) throws ParserSymbolTableException;
public IContainerSymbol lookupTemplateIdForDefinition( String name, List arguments ) throws ParserSymbolTableException;

View file

@ -702,14 +702,13 @@ public final class TemplateEngine {
return -1;
}
Iterator iter = spec1.getContainedSymbols().keySet().iterator();
ISymbol decl = (ISymbol) spec1.getContainedSymbols().get( iter.next() );
ISymbol decl = (ISymbol) spec1.getTemplatedSymbol();
//to order class template specializations, we need to transform them into function templates
ITemplateSymbol template1 = spec1;
ITemplateSymbol template2 = spec2;
if( decl.isType( TypeInfo.t_class ) ) {
if( decl.isType( TypeInfo.t_class, TypeInfo.t_union ) ) {
template1 = classTemplateSpecializationToFunctionTemplate( spec1 );
template2 = classTemplateSpecializationToFunctionTemplate( spec2 );
}

View file

@ -51,6 +51,51 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
argMap.put( symbol, new LinkedList( args ) );
}
/* (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 {
ISymbol previous = findPreviousSymbol( symbol );
ITemplateSymbol origTemplate = (previous != null ) ? (ITemplateSymbol) previous.getContainingSymbol() : null;
if( origTemplate == null ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
}
ITemplateSymbol template = (ITemplateSymbol) templates.get( templates.size() - 1 );
List params = template.getParameterList();
if( params.size() == 0 ){
//explicit specialization
} else {
//partial speciailization
ISpecializedSymbol spec = template.getSymbolTable().newSpecializedSymbol( symbol.getName() );
Iterator iter = params.iterator();
while( iter.hasNext() ){
spec.addTemplateParameter( (ISymbol) iter.next() );
}
iter = args.iterator();
while( iter.hasNext() ){
spec.addArgument( (TypeInfo) iter.next() );
}
spec.addSymbol( symbol );
origTemplate.addSpecialization( spec );
//replace the symbol attached to the AST node.
if( getASTExtension() != null ){
TemplateSymbolExtension extension = (TemplateSymbolExtension) template.getASTExtension();
extension.replaceSymbol( spec );
ASTTemplateDeclaration templateDecl = (ASTTemplateDeclaration) getASTExtension().getPrimaryDeclaration();
templateDecl.releaseFactory();
templateDecl.setSymbol( spec );
}
}
}
public void addSymbol(ISymbol symbol) throws ParserSymbolTableException {
lastSymbol = (IContainerSymbol) (( symbols.size() > 0 ) ? symbols.get( symbols.size() - 1) : null);
@ -804,4 +849,11 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupFunctionTemplateId(java.lang.String, java.util.List, java.util.List)
*/
public ISymbol lookupFunctionTemplateId(String name, List parameters, List arguments) throws ParserSymbolTableException {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -0,0 +1,40 @@
/*
* Created on Mar 15, 2004
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package org.eclipse.cdt.internal.core.parser.pst;
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTSymbol;
/**
* @author aniefer
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class TemplateSymbolExtension extends StandardSymbolExtension {
protected ISymbol replacement = null;
/**
* @param symbol
* @param primaryDeclaration
*/
public TemplateSymbolExtension(ISymbol symbol, ASTSymbol primaryDeclaration) {
super(symbol, primaryDeclaration);
}
/**
* @param spec
*/
public void replaceSymbol(ISpecializedSymbol spec) {
replacement = spec;
spec.setASTExtension( this );
}
public ISymbol getSymbol(){
return ( replacement == null ) ? super.getSymbol() : replacement;
}
}

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.parser.token;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import org.eclipse.cdt.core.parser.IToken;
@ -31,8 +32,21 @@ public class TokenDuple implements ITokenDuple {
// assert ( first != null && last != null ) : this;
firstToken = first;
lastToken = last;
argLists = null;
}
protected final IToken firstToken, lastToken;
public TokenDuple( IToken first, IToken last, List templateArgLists ){
firstToken = first;
lastToken = last;
if( templateArgLists != null && !templateArgLists.isEmpty() ){
argLists = (List[]) templateArgLists.toArray( new List [templateArgLists.size()] );
} else {
argLists = null;
}
}
protected final IToken firstToken, lastToken;
protected final List [] argLists;
/**
* @return
*/
@ -209,4 +223,11 @@ public class TokenDuple implements ITokenDuple {
public int getStartOffset() {
return getFirstToken().getOffset();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getTemplateIdArgLists()
*/
public List[] getTemplateIdArgLists() {
return argLists;
}
}