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:
parent
1aeedbdee2
commit
51131345db
19 changed files with 791 additions and 95 deletions
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue