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
|
2004-03-18 Alain Magloire
|
||||||
|
|
||||||
Change in the hierarchy of the core Model:
|
Change in the hierarchy of the core Model:
|
||||||
|
|
|
@ -1455,6 +1455,76 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
|
||||||
writer.write( " }" );
|
writer.write( " }" );
|
||||||
|
|
||||||
Iterator i = parse( writer.toString() ).getDeclarations();
|
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
|
public void testBug54639() throws Exception
|
||||||
{
|
{
|
||||||
|
@ -1477,6 +1547,134 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
|
||||||
assertFalse( i.hasNext() );
|
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
|
public void testBug55163() throws Exception
|
||||||
{
|
{
|
||||||
Writer writer = new StringWriter();
|
Writer writer = new StringWriter();
|
||||||
|
|
|
@ -733,7 +733,7 @@ public class CompleteParseBaseTest extends TestCase
|
||||||
protected void assertReferences(
|
protected void assertReferences(
|
||||||
ISourceElementCallbackDelegate element,
|
ISourceElementCallbackDelegate element,
|
||||||
int expectedDistinctReferenceCount,
|
int expectedDistinctReferenceCount,
|
||||||
boolean allowDuplicates )
|
boolean allowDuplicates, boolean allowNameMatching )
|
||||||
{
|
{
|
||||||
Set matches = new HashSet();
|
Set matches = new HashSet();
|
||||||
Iterator allReferences = callback.getReferences().iterator();
|
Iterator allReferences = callback.getReferences().iterator();
|
||||||
|
@ -748,7 +748,8 @@ public class CompleteParseBaseTest extends TestCase
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( r.getReferencedElement() instanceof IASTQualifiedNameElement &&
|
if( r.getReferencedElement() instanceof IASTQualifiedNameElement &&
|
||||||
element instanceof IASTQualifiedNameElement )
|
element instanceof IASTQualifiedNameElement &&
|
||||||
|
allowNameMatching )
|
||||||
{
|
{
|
||||||
if( qualifiedNamesEquals(
|
if( qualifiedNamesEquals(
|
||||||
((IASTQualifiedNameElement)r.getReferencedElement()).getFullyQualifiedName(),
|
((IASTQualifiedNameElement)r.getReferencedElement()).getFullyQualifiedName(),
|
||||||
|
@ -770,16 +771,22 @@ public class CompleteParseBaseTest extends TestCase
|
||||||
|
|
||||||
protected static class Task
|
protected static class Task
|
||||||
{
|
{
|
||||||
|
private final boolean allowNameMatching;
|
||||||
private final boolean unique;
|
private final boolean unique;
|
||||||
private final int count;
|
private final int count;
|
||||||
private final ISourceElementCallbackDelegate element;
|
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 )
|
public Task( ISourceElementCallbackDelegate element, int referenceCount, boolean distinct )
|
||||||
{
|
{
|
||||||
this.element = element;
|
this( element, referenceCount, distinct, true );
|
||||||
this.count = referenceCount;
|
|
||||||
this.unique = distinct;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task( ISourceElementCallbackDelegate element, int referenceCount )
|
public Task( ISourceElementCallbackDelegate element, int referenceCount )
|
||||||
|
@ -815,12 +822,16 @@ public class CompleteParseBaseTest extends TestCase
|
||||||
{
|
{
|
||||||
return unique;
|
return unique;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean allowNameMatching(){
|
||||||
|
return allowNameMatching;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void assertReferenceTask( Task task )
|
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 )
|
protected void assertAllReferences( int count, List tasks )
|
||||||
|
|
|
@ -1564,4 +1564,17 @@ public class ScannerTestCase extends BaseScannerTest
|
||||||
validateIdentifier( "Lißä");
|
validateIdentifier( "Lißä");
|
||||||
validateEOF();
|
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)) {
|
if (CCorePlugin.getDefault().isDebugging() && isActive(client)) {
|
||||||
// Time stamp
|
// Time stamp
|
||||||
if (addTimeStamp)
|
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$
|
new Long(System.currentTimeMillis()), message}); //$NON-NLS-1$
|
||||||
while (message.length() > 100) {
|
while (message.length() > 100) {
|
||||||
String partial = message.substring(0, 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
|
2004-03-17 Andrew Niefer
|
||||||
fix bug 55163
|
fix bug 55163
|
||||||
- in for-init-statement, try expression-statement before simple-declaration since if it actually is a statement instead of a
|
- 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;
|
package org.eclipse.cdt.core.parser;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTFactory;
|
import org.eclipse.cdt.core.parser.ast.IASTFactory;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTNode;
|
import org.eclipse.cdt.core.parser.ast.IASTNode;
|
||||||
|
@ -30,6 +31,7 @@ public interface ITokenDuple {
|
||||||
*/
|
*/
|
||||||
public abstract IToken getLastToken();
|
public abstract IToken getLastToken();
|
||||||
|
|
||||||
|
public List [] getTemplateIdArgLists();
|
||||||
|
|
||||||
public abstract Iterator iterator();
|
public abstract Iterator iterator();
|
||||||
public abstract String toString();
|
public abstract String toString();
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
package org.eclipse.cdt.internal.core.parser;
|
package org.eclipse.cdt.internal.core.parser;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.parser.BacktrackException;
|
import org.eclipse.cdt.core.parser.BacktrackException;
|
||||||
|
@ -52,6 +54,8 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
protected boolean parsePassed = true;
|
protected boolean parsePassed = true;
|
||||||
protected ParserLanguage language = ParserLanguage.CPP;
|
protected ParserLanguage language = ParserLanguage.CPP;
|
||||||
protected IASTFactory astFactory = null;
|
protected IASTFactory astFactory = null;
|
||||||
|
|
||||||
|
private Stack templateIdScopes = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param scanner2
|
* @param scanner2
|
||||||
|
@ -149,6 +153,85 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
return last;
|
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.
|
* 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 {
|
protected IToken templateId(IASTScope scope, CompletionKind kind) throws EndOfFileException, BacktrackException {
|
||||||
ITokenDuple duple = name(scope, kind );
|
ITokenDuple duple = name(scope, kind );
|
||||||
IToken last = consumeTemplateParameters(duple.getLastToken());
|
//IToken last = consumeTemplateParameters(duple.getLastToken());
|
||||||
return last;
|
return duple.getLastToken();//last;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,21 +272,16 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
if (LT(1) == IToken.tCOMPL)
|
if (LT(1) == IToken.tCOMPL)
|
||||||
consume();
|
consume();
|
||||||
|
|
||||||
|
List argumentList = new LinkedList();
|
||||||
|
boolean hasTemplateId = false;
|
||||||
|
|
||||||
switch (LT(1))
|
switch (LT(1))
|
||||||
{
|
{
|
||||||
case IToken.tIDENTIFIER :
|
case IToken.tIDENTIFIER :
|
||||||
last = consume(IToken.tIDENTIFIER);
|
last = consume(IToken.tIDENTIFIER);
|
||||||
IToken secondMark = null;
|
last = consumeTemplateArguments(scope, last, argumentList);
|
||||||
|
if( last.getType() == IToken.tGT )
|
||||||
secondMark = mark();
|
hasTemplateId = true;
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
last = consumeTemplateParameters(last);
|
|
||||||
} catch( BacktrackException bt )
|
|
||||||
{
|
|
||||||
backup( secondMark );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
|
@ -228,14 +306,44 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
throw backtrack;
|
throw backtrack;
|
||||||
case IToken.tIDENTIFIER :
|
case IToken.tIDENTIFIER :
|
||||||
last = consume();
|
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.
|
* 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
|
// we know this is an operator
|
||||||
IToken operatorToken = consume(IToken.t_operator);
|
IToken operatorToken = consume(IToken.t_operator);
|
||||||
IToken toSend = null;
|
IToken toSend = null;
|
||||||
|
@ -337,10 +445,17 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
typeId(d.getDeclarationWrapper().getScope(), true );
|
typeId(d.getDeclarationWrapper().getScope(), true );
|
||||||
toSend = lastToken;
|
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 =
|
ITokenDuple duple =
|
||||||
new TokenDuple(
|
new TokenDuple( originalToken == null ? operatorToken : originalToken, toSend, (hasTemplateId ? args : null ) );
|
||||||
originalToken == null ? operatorToken : originalToken,
|
|
||||||
toSend);
|
|
||||||
|
|
||||||
d.setName(duple);
|
d.setName(duple);
|
||||||
}
|
}
|
||||||
|
@ -814,6 +929,9 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
switch (LT(1))
|
switch (LT(1))
|
||||||
{
|
{
|
||||||
case IToken.tGT :
|
case IToken.tGT :
|
||||||
|
if( templateIdScopes != null && ((Integer)templateIdScopes.peek()).intValue() == IToken.tLT ){
|
||||||
|
return firstExpression;
|
||||||
|
}
|
||||||
case IToken.tLT :
|
case IToken.tLT :
|
||||||
case IToken.tLTEQUAL :
|
case IToken.tLTEQUAL :
|
||||||
case IToken.tGTEQUAL :
|
case IToken.tGTEQUAL :
|
||||||
|
@ -1075,12 +1193,15 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
{
|
{
|
||||||
IToken mark = mark();
|
IToken mark = mark();
|
||||||
consume();
|
consume();
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
|
||||||
|
boolean popped = false;
|
||||||
IASTTypeId typeId = null;
|
IASTTypeId typeId = null;
|
||||||
// If this isn't a type name, then we shouldn't be here
|
// If this isn't a type name, then we shouldn't be here
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
typeId = typeId(scope, false);
|
typeId = typeId(scope, false);
|
||||||
consume(IToken.tRPAREN);
|
consume(IToken.tRPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); popped = true;}
|
||||||
IASTExpression castExpression = castExpression(scope);
|
IASTExpression castExpression = castExpression(scope);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -1104,6 +1225,7 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
catch (BacktrackException b)
|
catch (BacktrackException b)
|
||||||
{
|
{
|
||||||
backup(mark);
|
backup(mark);
|
||||||
|
if( templateIdScopes != null && !popped ){ templateIdScopes.pop(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return unaryExpression(scope);
|
return unaryExpression(scope);
|
||||||
|
@ -1274,8 +1396,9 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
TypeId id = new TypeId(scope);
|
TypeId id = new TypeId(scope);
|
||||||
IToken last = lastToken;
|
IToken last = lastToken;
|
||||||
|
|
||||||
lastToken = consumeTemplateParameters( last );
|
//template parameters are consumed as part of name
|
||||||
if( lastToken == null ) lastToken = last;
|
//lastToken = consumeTemplateParameters( last );
|
||||||
|
//if( lastToken == null ) lastToken = last;
|
||||||
|
|
||||||
consumePointerOperators( id );
|
consumePointerOperators( id );
|
||||||
if( lastToken == null ) lastToken = last;
|
if( lastToken == null ) lastToken = last;
|
||||||
|
@ -1378,7 +1501,8 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
|
|
||||||
if (LT(1) == IToken.tLPAREN)
|
if (LT(1) == IToken.tLPAREN)
|
||||||
{
|
{
|
||||||
consume(IToken.tLPAREN);
|
consume(IToken.tLPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Try to consume placement list
|
// Try to consume placement list
|
||||||
|
@ -1386,11 +1510,13 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
backtrackMarker = mark();
|
backtrackMarker = mark();
|
||||||
newPlacementExpressions.add(expression(scope));
|
newPlacementExpressions.add(expression(scope));
|
||||||
consume(IToken.tRPAREN);
|
consume(IToken.tRPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); } //pop 1st Parent
|
||||||
placementParseFailure = false;
|
placementParseFailure = false;
|
||||||
if (LT(1) == IToken.tLPAREN)
|
if (LT(1) == IToken.tLPAREN)
|
||||||
{
|
{
|
||||||
beforeSecondParen = mark();
|
beforeSecondParen = mark();
|
||||||
consume(IToken.tLPAREN);
|
consume(IToken.tLPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); } //push 2nd Paren
|
||||||
typeIdInParen = true;
|
typeIdInParen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1405,6 +1531,7 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
// - then it has to be typeId
|
// - then it has to be typeId
|
||||||
typeId = typeId(scope, true );
|
typeId = typeId(scope, true );
|
||||||
consume(IToken.tRPAREN);
|
consume(IToken.tRPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); } //pop 1st Paren
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1448,6 +1575,8 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
{
|
{
|
||||||
typeId = typeId(scope, true);
|
typeId = typeId(scope, true);
|
||||||
consume(IToken.tRPAREN);
|
consume(IToken.tRPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); } //popping the 2nd Paren
|
||||||
|
|
||||||
if (LT(1) == IToken.tLPAREN
|
if (LT(1) == IToken.tLPAREN
|
||||||
|| LT(1) == IToken.tLBRACKET)
|
|| LT(1) == IToken.tLBRACKET)
|
||||||
{
|
{
|
||||||
|
@ -1485,6 +1614,7 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
// CASE: new (typeid-looking-as-placement)(initializer-not-looking-as-typeid)
|
// CASE: new (typeid-looking-as-placement)(initializer-not-looking-as-typeid)
|
||||||
// Fallback to initializer processing
|
// Fallback to initializer processing
|
||||||
backup(beforeSecondParen);
|
backup(beforeSecondParen);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); }//pop that 2nd paren
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1500,16 +1630,25 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
{
|
{
|
||||||
// array new
|
// array new
|
||||||
consume();
|
consume();
|
||||||
|
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLBRACKET ) ); }
|
||||||
|
|
||||||
newTypeIdExpressions.add(assignmentExpression(scope));
|
newTypeIdExpressions.add(assignmentExpression(scope));
|
||||||
consume(IToken.tRBRACKET);
|
consume(IToken.tRBRACKET);
|
||||||
|
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); }
|
||||||
}
|
}
|
||||||
// newinitializer
|
// newinitializer
|
||||||
if (LT(1) == IToken.tLPAREN)
|
if (LT(1) == IToken.tLPAREN)
|
||||||
{
|
{
|
||||||
consume(IToken.tLPAREN);
|
consume(IToken.tLPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
|
||||||
|
|
||||||
if (LT(1) != IToken.tRPAREN)
|
if (LT(1) != IToken.tRPAREN)
|
||||||
newInitializerExpressions.add(expression(scope));
|
newInitializerExpressions.add(expression(scope));
|
||||||
|
|
||||||
consume(IToken.tRPAREN);
|
consume(IToken.tRPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); }
|
||||||
}
|
}
|
||||||
setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, Key.EMPTY);
|
setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, Key.EMPTY);
|
||||||
try
|
try
|
||||||
|
@ -1673,8 +1812,7 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
ITokenDuple templateId = null;
|
ITokenDuple templateId = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
templateId = new TokenDuple( current, templateId(scope, CompletionKind.SINGLE_NAME_REFERENCE
|
templateId = new TokenDuple( current, templateId(scope, CompletionKind.SINGLE_NAME_REFERENCE ) );
|
||||||
) );
|
|
||||||
}
|
}
|
||||||
catch( BacktrackException bt )
|
catch( BacktrackException bt )
|
||||||
{
|
{
|
||||||
|
@ -1683,8 +1821,10 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
backup( current );
|
backup( current );
|
||||||
}
|
}
|
||||||
consume( IToken.tLPAREN );
|
consume( IToken.tLPAREN );
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
|
||||||
IASTExpression expressionList = expression( scope );
|
IASTExpression expressionList = expression( scope );
|
||||||
consume( IToken.tRPAREN );
|
consume( IToken.tRPAREN );
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); }
|
||||||
try {
|
try {
|
||||||
firstExpression =
|
firstExpression =
|
||||||
astFactory.createExpression( scope,
|
astFactory.createExpression( scope,
|
||||||
|
@ -1777,6 +1917,7 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
case IToken.t_typeid :
|
case IToken.t_typeid :
|
||||||
consume();
|
consume();
|
||||||
consume(IToken.tLPAREN);
|
consume(IToken.tLPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
|
||||||
boolean isTypeId = true;
|
boolean isTypeId = true;
|
||||||
IASTExpression lhs = null;
|
IASTExpression lhs = null;
|
||||||
IASTTypeId typeId = null;
|
IASTTypeId typeId = null;
|
||||||
|
@ -1790,6 +1931,7 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
lhs = expression(scope);
|
lhs = expression(scope);
|
||||||
}
|
}
|
||||||
consume(IToken.tRPAREN);
|
consume(IToken.tRPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); }
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
firstExpression =
|
firstExpression =
|
||||||
|
@ -1824,8 +1966,10 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
case IToken.tLBRACKET :
|
case IToken.tLBRACKET :
|
||||||
// array access
|
// array access
|
||||||
consume();
|
consume();
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLBRACKET ) ); }
|
||||||
secondExpression = expression(scope);
|
secondExpression = expression(scope);
|
||||||
consume(IToken.tRBRACKET);
|
consume(IToken.tRBRACKET);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); }
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
firstExpression =
|
firstExpression =
|
||||||
|
@ -1850,8 +1994,10 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
case IToken.tLPAREN :
|
case IToken.tLPAREN :
|
||||||
// function call
|
// function call
|
||||||
consume(IToken.tLPAREN);
|
consume(IToken.tLPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
|
||||||
secondExpression = expression(scope);
|
secondExpression = expression(scope);
|
||||||
consume(IToken.tRPAREN);
|
consume(IToken.tRPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); }
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
firstExpression =
|
firstExpression =
|
||||||
|
@ -2189,8 +2335,10 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
}
|
}
|
||||||
case IToken.tLPAREN :
|
case IToken.tLPAREN :
|
||||||
consume();
|
consume();
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); }
|
||||||
IASTExpression lhs = expression(scope);
|
IASTExpression lhs = expression(scope);
|
||||||
consume(IToken.tRPAREN);
|
consume(IToken.tRPAREN);
|
||||||
|
if( templateIdScopes != null ){ templateIdScopes.pop(); }
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return astFactory.createExpression(
|
return astFactory.createExpression(
|
||||||
|
@ -2236,7 +2384,7 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
end = consumeTemplateParameters(end);
|
end = consumeTemplateParameters(end);
|
||||||
}
|
}
|
||||||
if (LT(1) == IToken.t_operator)
|
if (LT(1) == IToken.t_operator)
|
||||||
operatorId(d, start);
|
operatorId(d, start, null);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
backup(mark);
|
backup(mark);
|
||||||
|
@ -2244,7 +2392,7 @@ public class ExpressionParser implements IExpressionParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( LT(1) == IToken.t_operator )
|
else if( LT(1) == IToken.t_operator )
|
||||||
operatorId( d, null);
|
operatorId( d, null, null);
|
||||||
|
|
||||||
duple = d.getNameDuple();
|
duple = d.getNameDuple();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
package org.eclipse.cdt.internal.core.parser;
|
package org.eclipse.cdt.internal.core.parser;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.parser.BacktrackException;
|
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
|
protected ITokenDuple className(IASTScope scope) throws EndOfFileException, BacktrackException
|
||||||
{
|
{
|
||||||
ITokenDuple duple = name(scope, CompletionKind.USER_SPECIFIED_NAME );
|
// ITokenDuple duple = name(scope, CompletionKind.USER_SPECIFIED_NAME );
|
||||||
IToken last = duple.getLastToken();
|
// IToken last = duple.getLastToken();
|
||||||
if (LT(1) == IToken.tLT) {
|
// if (LT(1) == IToken.tLT) {
|
||||||
last = consumeTemplateParameters(duple.getLastToken());
|
// last = consumeTemplateParameters(duple.getLastToken());
|
||||||
}
|
// //last = templateArgumentList( scope, duple.getLastToken() );
|
||||||
|
// }
|
||||||
return new TokenDuple(duple.getFirstToken(), last);
|
//
|
||||||
|
// 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
|
throws EndOfFileException, BacktrackException
|
||||||
{
|
{
|
||||||
if (LT(1) == IToken.t_operator)
|
if (LT(1) == IToken.t_operator)
|
||||||
operatorId(d, null);
|
operatorId(d, null, null);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -2210,23 +2213,35 @@ public abstract class Parser extends ExpressionParser implements IParser
|
||||||
Declarator d1 = d;
|
Declarator d1 = d;
|
||||||
Declarator d11 = d1;
|
Declarator d11 = d1;
|
||||||
IToken start = null;
|
IToken start = null;
|
||||||
|
|
||||||
|
List argumentList = new LinkedList();
|
||||||
|
boolean hasTemplateId = false;
|
||||||
|
|
||||||
IToken mark = mark();
|
IToken mark = mark();
|
||||||
if (LT(1) == IToken.tCOLONCOLON
|
if (LT(1) == IToken.tCOLONCOLON
|
||||||
|| LT(1) == IToken.tIDENTIFIER)
|
|| LT(1) == IToken.tIDENTIFIER)
|
||||||
{
|
{
|
||||||
start = consume();
|
start = consume();
|
||||||
IToken end = null;
|
IToken end = null;
|
||||||
if (start.getType() == IToken.tIDENTIFIER)
|
|
||||||
end = consumeTemplateParameters(end);
|
if (start.getType() == IToken.tIDENTIFIER){
|
||||||
while (LT(1) == IToken.tCOLONCOLON
|
end = consumeTemplateArguments(d.getDeclarationWrapper().getScope(), end, argumentList);
|
||||||
|| LT(1) == IToken.tIDENTIFIER)
|
if( end != null && end.getType() == IToken.tGT )
|
||||||
{
|
hasTemplateId = true;
|
||||||
end = consume();
|
}
|
||||||
if (end.getType() == IToken.tIDENTIFIER)
|
|
||||||
end = consumeTemplateParameters(end);
|
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)
|
if (LT(1) == IToken.t_operator)
|
||||||
operatorId(d11, start);
|
operatorId(d11, start, ( hasTemplateId ? argumentList : null ) );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
backup(mark);
|
backup(mark);
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
|
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
|
||||||
import org.eclipse.cdt.core.parser.ast.ASTPointerOperator;
|
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.IASTInitializerClause;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
|
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTTypeSpecifier;
|
import org.eclipse.cdt.core.parser.ast.IASTTypeSpecifier;
|
||||||
|
@ -114,6 +115,11 @@ public class ASTParameterDeclaration extends ASTSymbol implements IASTParameterD
|
||||||
{
|
{
|
||||||
return abstractDeclaration.getTypeSpecifier();
|
return abstractDeclaration.getTypeSpecifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IASTAbstractDeclaration getAbstractDeclaration(){
|
||||||
|
return abstractDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#acceptElement(org.eclipse.cdt.core.parser.ISourceElementRequestor)
|
* @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.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Stack;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.parser.Enum;
|
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.ParserSymbolTable;
|
||||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException;
|
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.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.TypeInfo;
|
||||||
import org.eclipse.cdt.internal.core.parser.pst.ISymbolASTExtension.ExtensionException;
|
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 {
|
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;
|
ISymbol result = null;
|
||||||
if( startingScope == null ) return null;
|
if( startingScope == null ) return null;
|
||||||
try {
|
try {
|
||||||
|
@ -188,7 +194,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
result = startingDerivableScope.lookupConstructor( new LinkedList(parameters));
|
result = startingDerivableScope.lookupConstructor( new LinkedList(parameters));
|
||||||
}
|
}
|
||||||
else {
|
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));
|
result = startingScope.qualifiedFunctionLookup(name, new LinkedList(parameters));
|
||||||
else if( lookupType == LookupType.UNQUALIFIED || lookupType == LookupType.FORPARENTSCOPE)
|
else if( lookupType == LookupType.UNQUALIFIED || lookupType == LookupType.FORPARENTSCOPE)
|
||||||
result = startingScope.unqualifiedFunctionLookup( name, new LinkedList( parameters ) );
|
result = startingScope.unqualifiedFunctionLookup( name, new LinkedList( parameters ) );
|
||||||
|
@ -202,7 +210,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
result = null;
|
result = null;
|
||||||
}else{
|
}else{
|
||||||
// looking for something 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);
|
result = startingScope.qualifiedLookup(name, type);
|
||||||
else if( lookupType == LookupType.UNQUALIFIED || lookupType == LookupType.FORPARENTSCOPE )
|
else if( lookupType == LookupType.UNQUALIFIED || lookupType == LookupType.FORPARENTSCOPE )
|
||||||
result = startingScope.elaboratedLookup( type, name );
|
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 );
|
if( name == null && throwOnError ) handleProblem( IProblem.SEMANTIC_NAME_NOT_PROVIDED, null );
|
||||||
else if( name == null ) return null;
|
else if( name == null ) return null;
|
||||||
|
|
||||||
|
List [] templateArgLists = name.getTemplateIdArgLists();
|
||||||
|
int idx = 0;
|
||||||
switch( name.length() )
|
switch( name.length() )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -307,19 +319,37 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
while( iter.hasNext() )
|
while( iter.hasNext() )
|
||||||
{
|
{
|
||||||
IToken t = (IToken)iter.next();
|
IToken t = (IToken)iter.next();
|
||||||
if( t.getType() == IToken.tCOLONCOLON ) continue;
|
if( t.getType() == IToken.tCOLONCOLON ){
|
||||||
|
idx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if( t.isPointer() ) break;
|
if( t.isPointer() ) break;
|
||||||
|
|
||||||
|
String image = t.getImage();
|
||||||
|
int offset = t.getOffset();
|
||||||
|
|
||||||
|
if( templateArgLists != null && templateArgLists[ idx ] != null ){
|
||||||
|
t = consumeTemplateIdArguments( t, iter );
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( t == name.getLastToken() )
|
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
|
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( result != null ){
|
||||||
if( lookup == LookupType.FORPARENTSCOPE && startingScope instanceof ITemplateFactory ){
|
if( lookup == LookupType.FORPARENTSCOPE && startingScope instanceof ITemplateFactory ){
|
||||||
((ITemplateFactory)startingScope).pushSymbol( result );
|
((ITemplateFactory)startingScope).pushSymbol( result );
|
||||||
}
|
}
|
||||||
addReference( references, createReference( result, t.getImage(), t.getOffset() ));
|
addReference( references, createReference( result, image, offset ));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -327,7 +357,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
catch( ParserSymbolTableException pste )
|
catch( ParserSymbolTableException pste )
|
||||||
{
|
{
|
||||||
if ( throwOnError )
|
if ( throwOnError )
|
||||||
handleProblem( pste.createProblemID(), t.getImage() );
|
handleProblem( pste.createProblemID(), image );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,7 +365,50 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
return result;
|
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)
|
/* (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)
|
* @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 );
|
extension = new ForewardDeclaredSymbolExtension( symbol, astSymbol );
|
||||||
}
|
}
|
||||||
else
|
else if( astSymbol instanceof IASTTemplateDeclaration ){
|
||||||
|
extension = new TemplateSymbolExtension( symbol, astSymbol );
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
extension = new StandardSymbolExtension( symbol, astSymbol );
|
extension = new StandardSymbolExtension( symbol, astSymbol );
|
||||||
}
|
}
|
||||||
|
@ -569,23 +645,37 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
List references = new ArrayList();
|
List references = new ArrayList();
|
||||||
|
|
||||||
String newSymbolName = ""; //$NON-NLS-1$
|
String newSymbolName = ""; //$NON-NLS-1$
|
||||||
|
List templateIdArgList = null;
|
||||||
|
boolean isTemplateId = false;
|
||||||
|
|
||||||
if( name != null ){
|
if( name != null ){
|
||||||
IToken lastToken = name.getLastToken();
|
IToken lastToken = name.getLastToken();
|
||||||
if( name.length() != 1 ) // qualified name
|
if( name.length() != 1 ) // qualified name
|
||||||
{
|
{
|
||||||
ITokenDuple containerSymbolName =
|
int idx = name.findLastTokenType( IToken.tCOLONCOLON );
|
||||||
name.getSubrange( 0, name.length() - 3 ); // -1 for index, -2 for last hop of qualified name
|
if( idx != -1 ){
|
||||||
currentScopeSymbol = (IContainerSymbol)lookupQualifiedName( currentScopeSymbol,
|
ITokenDuple containerSymbolName =
|
||||||
containerSymbolName, references, true);
|
name.getSubrange( 0, idx - 1 ); // -1 for index, -2 for last hop of qualified name
|
||||||
if( currentScopeSymbol == null )
|
currentScopeSymbol = (IContainerSymbol)lookupQualifiedName( currentScopeSymbol,
|
||||||
handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, containerSymbolName.toString(), containerSymbolName.getFirstToken().getOffset(), containerSymbolName.getLastToken().getEndOffset(), containerSymbolName.getLastToken().getLineNumber() );
|
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();
|
newSymbolName = lastToken.getImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ISymbol classSymbol = null;
|
ISymbol classSymbol = null;
|
||||||
if( !newSymbolName.equals("") ){ //$NON-NLS-1$
|
if( !newSymbolName.equals("") && !isTemplateId ){ //$NON-NLS-1$
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
classSymbol = currentScopeSymbol.lookupMemberForDefinition(newSymbolName);
|
classSymbol = currentScopeSymbol.lookupMemberForDefinition(newSymbolName);
|
||||||
|
@ -607,9 +697,16 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
if( classSymbol != null )
|
if( classSymbol != null )
|
||||||
classSymbol.setTypeSymbol( newSymbol );
|
classSymbol.setTypeSymbol( newSymbol );
|
||||||
|
|
||||||
|
List args = null;
|
||||||
|
if( isTemplateId ){
|
||||||
|
args = getTemplateArgList( templateIdArgList );
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
currentScopeSymbol.addSymbol( newSymbol );
|
if( !isTemplateId )
|
||||||
|
currentScopeSymbol.addSymbol( newSymbol );
|
||||||
|
else
|
||||||
|
currentScopeSymbol.addTemplateId( newSymbol, args );
|
||||||
}
|
}
|
||||||
catch (ParserSymbolTableException e2)
|
catch (ParserSymbolTableException e2)
|
||||||
{
|
{
|
||||||
|
@ -621,6 +718,25 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
return classSpecifier;
|
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
|
protected void handleProblem( int id, String attribute ) throws ASTSemanticException
|
||||||
{
|
{
|
||||||
|
@ -692,8 +808,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
handleProblem( IProblem.SEMANTIC_NAME_NOT_PROVIDED, null );
|
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 );
|
classSymbol.addParent( symbol, isVirtual, visibility, parentClassName.getFirstToken().getOffset(), references );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -840,7 +957,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
if( idExpression != null )
|
if( idExpression != null )
|
||||||
{
|
{
|
||||||
logMessage.append( " idexpression=" ); //$NON-NLS-1$
|
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$
|
else if( literal != null && !literal.equals( "" )) //$NON-NLS-1$
|
||||||
{
|
{
|
||||||
|
@ -1091,7 +1208,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
|
|
||||||
ExpressionResult result = null;
|
ExpressionResult result = null;
|
||||||
TypeInfo info = new TypeInfo();
|
TypeInfo info = new TypeInfo();
|
||||||
|
if( literal != null && !literal.equals("") ){ //$NON-NLS-1$
|
||||||
|
info.setDefault( literal );
|
||||||
|
}
|
||||||
// types that resolve to void
|
// types that resolve to void
|
||||||
if ((kind == IASTExpression.Kind.PRIMARY_EMPTY)
|
if ((kind == IASTExpression.Kind.PRIMARY_EMPTY)
|
||||||
|| (kind == IASTExpression.Kind.THROWEXPRESSION)
|
|| (kind == IASTExpression.Kind.THROWEXPRESSION)
|
||||||
|
@ -1574,26 +1693,42 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
|
|
||||||
ISymbol typeSymbol = getScopeToSearchUpon( scope, first, i );
|
ISymbol typeSymbol = getScopeToSearchUpon( scope, first, i );
|
||||||
|
|
||||||
|
List [] argLists = typeName.getTemplateIdArgLists();
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
while( i.hasNext() )
|
while( i.hasNext() )
|
||||||
{
|
{
|
||||||
IToken current = (IToken)i.next();
|
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
|
try
|
||||||
{
|
{
|
||||||
if( current != typeName.getLastToken() )
|
if( argLists != null && argLists[ idx ] != null )
|
||||||
typeSymbol = ((IContainerSymbol)typeSymbol).lookupNestedNameSpecifier( current.getImage());
|
typeSymbol = ((IContainerSymbol)typeSymbol).lookupTemplateId( image, getTemplateArgList( argLists[idx] ) );
|
||||||
|
else if( current != typeName.getLastToken() )
|
||||||
|
typeSymbol = ((IContainerSymbol)typeSymbol).lookupNestedNameSpecifier( image );
|
||||||
else
|
else
|
||||||
typeSymbol = ((IContainerSymbol)typeSymbol).lookup( current.getImage());
|
typeSymbol = ((IContainerSymbol)typeSymbol).lookup( image );
|
||||||
|
|
||||||
if( typeSymbol != null )
|
if( typeSymbol != null )
|
||||||
addReference( references, createReference( typeSymbol, current.getImage(), current.getOffset() ));
|
addReference( references, createReference( typeSymbol, image, offset ));
|
||||||
else
|
else
|
||||||
handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, current.getImage() );
|
handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, image );
|
||||||
}
|
}
|
||||||
catch (ParserSymbolTableException e)
|
catch (ParserSymbolTableException e)
|
||||||
{
|
{
|
||||||
handleProblem( e.createProblemID(), current.getImage() );
|
handleProblem( e.createProblemID(), image );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.setTypeSymbol( typeSymbol );
|
s.setTypeSymbol( typeSymbol );
|
||||||
|
@ -2472,7 +2607,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
try {
|
try {
|
||||||
template.addTemplateParameter( param.getSymbol() );
|
template.addTemplateParameter( param.getSymbol() );
|
||||||
} catch (ParserSymbolTableException e) {
|
} 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,
|
IASTParameterDeclaration parameter,
|
||||||
List parms ) throws ASTSemanticException
|
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 ){
|
if( kind == ParamKind.CLASS || kind == ParamKind.TYPENAME ){
|
||||||
symbol.getTypeInfo().setTemplateParameterType( TypeInfo.t_typeName );
|
symbol.getTypeInfo().setTemplateParameterType( TypeInfo.t_typeName );
|
||||||
} else if ( kind == ParamKind.TEMPLATE_LIST ){
|
} else if ( kind == ParamKind.TEMPLATE_LIST ){
|
||||||
symbol.getTypeInfo().setTemplateParameterType( TypeInfo.t_template );
|
symbol.getTypeInfo().setTemplateParameterType( TypeInfo.t_template );
|
||||||
} else /*ParamKind.PARAMETER*/ {
|
} else /*ParamKind.PARAMETER*/ {
|
||||||
symbol = ((ASTParameterDeclaration)parameter).getSymbol();
|
symbol.setName( parameter.getName() );
|
||||||
|
symbol.setTypeInfo( ((ASTSimpleTypeSpecifier)parameter.getTypeSpecifier()).getSymbol().getTypeInfo() );
|
||||||
symbol.getTypeInfo().setTemplateParameterType( symbol.getType() );
|
symbol.getTypeInfo().setTemplateParameterType( symbol.getType() );
|
||||||
symbol.setType( TypeInfo.t_templateParameter );
|
symbol.setType( TypeInfo.t_templateParameter );
|
||||||
|
|
||||||
|
setPointerOperators( symbol, parameter.getPointerOperators(), parameter.getArrayModifiers() );
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTTemplateParameter ast = new ASTTemplateParameter( symbol, defaultValue, parameter, parms );
|
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;
|
return ast;
|
||||||
}
|
}
|
||||||
|
@ -2544,7 +2681,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
ISymbol newSymbol = pst.newSymbol( name, TypeInfo.t_type);
|
ISymbol newSymbol = pst.newSymbol( name, TypeInfo.t_type);
|
||||||
newSymbol.getTypeInfo().setBit( true,TypeInfo.isTypedef );
|
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() );
|
setPointerOperators( typeSymbol, mapping.getPointerOperators(), mapping.getArrayModifiers() );
|
||||||
|
|
||||||
newSymbol.setTypeSymbol( typeSymbol );
|
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 _contents; //ordered list of all contents of this symbol
|
||||||
private LinkedList _usingDirectives; //collection of nominated namespaces
|
private LinkedList _usingDirectives; //collection of nominated namespaces
|
||||||
private Map _containedSymbols; //declarations contained by us.
|
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;
|
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 ITemplateSymbol _template;
|
||||||
private List _arguments;
|
private List _arguments;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,13 +79,13 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
|
||||||
newSymbol.getParents().add( newWrapper );
|
newSymbol.getParents().add( newWrapper );
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator constructors = getConstructors().iterator();
|
// Iterator constructors = getConstructors().iterator();
|
||||||
newSymbol.getConstructors().clear();
|
// newSymbol.getConstructors().clear();
|
||||||
IParameterizedSymbol constructor = null;
|
// IParameterizedSymbol constructor = null;
|
||||||
while( constructors.hasNext() ){
|
// while( constructors.hasNext() ){
|
||||||
constructor = (IParameterizedSymbol) constructors.next();
|
// constructor = (IParameterizedSymbol) constructors.next();
|
||||||
newSymbol.getConstructors().add( constructor.instantiate( template, argMap ) );
|
// newSymbol.getConstructors().add( constructor.instantiate( template, argMap ) );
|
||||||
}
|
// }
|
||||||
|
|
||||||
//TODO: friends
|
//TODO: friends
|
||||||
|
|
||||||
|
@ -156,6 +156,8 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor.setContainingSymbol( this );
|
constructor.setContainingSymbol( this );
|
||||||
|
constructor.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
|
||||||
|
|
||||||
addThis( constructor );
|
addThis( constructor );
|
||||||
|
|
||||||
getContents().add( 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)
|
* 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 addSymbol( ISymbol symbol ) throws ParserSymbolTableException;
|
||||||
|
|
||||||
|
public void addTemplateId( ISymbol symbol, List args ) throws ParserSymbolTableException;
|
||||||
|
|
||||||
public boolean removeSymbol( ISymbol symbol );
|
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
|
* 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 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;
|
public IContainerSymbol lookupTemplateIdForDefinition( String name, List arguments ) throws ParserSymbolTableException;
|
||||||
|
|
||||||
|
|
|
@ -702,14 +702,13 @@ public final class TemplateEngine {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator iter = spec1.getContainedSymbols().keySet().iterator();
|
ISymbol decl = (ISymbol) spec1.getTemplatedSymbol();
|
||||||
ISymbol decl = (ISymbol) spec1.getContainedSymbols().get( iter.next() );
|
|
||||||
|
|
||||||
//to order class template specializations, we need to transform them into function templates
|
//to order class template specializations, we need to transform them into function templates
|
||||||
ITemplateSymbol template1 = spec1;
|
ITemplateSymbol template1 = spec1;
|
||||||
ITemplateSymbol template2 = spec2;
|
ITemplateSymbol template2 = spec2;
|
||||||
|
|
||||||
if( decl.isType( TypeInfo.t_class ) ) {
|
if( decl.isType( TypeInfo.t_class, TypeInfo.t_union ) ) {
|
||||||
template1 = classTemplateSpecializationToFunctionTemplate( spec1 );
|
template1 = classTemplateSpecializationToFunctionTemplate( spec1 );
|
||||||
template2 = classTemplateSpecializationToFunctionTemplate( spec2 );
|
template2 = classTemplateSpecializationToFunctionTemplate( spec2 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,51 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
|
||||||
argMap.put( symbol, new LinkedList( args ) );
|
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 {
|
public void addSymbol(ISymbol symbol) throws ParserSymbolTableException {
|
||||||
lastSymbol = (IContainerSymbol) (( symbols.size() > 0 ) ? symbols.get( symbols.size() - 1) : null);
|
lastSymbol = (IContainerSymbol) (( symbols.size() > 0 ) ? symbols.get( symbols.size() - 1) : null);
|
||||||
|
|
||||||
|
@ -804,4 +849,11 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
|
||||||
return null;
|
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;
|
package org.eclipse.cdt.internal.core.parser.token;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.parser.IToken;
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
@ -31,8 +32,21 @@ public class TokenDuple implements ITokenDuple {
|
||||||
// assert ( first != null && last != null ) : this;
|
// assert ( first != null && last != null ) : this;
|
||||||
firstToken = first;
|
firstToken = first;
|
||||||
lastToken = last;
|
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
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -209,4 +223,11 @@ public class TokenDuple implements ITokenDuple {
|
||||||
public int getStartOffset() {
|
public int getStartOffset() {
|
||||||
return getFirstToken().getOffset();
|
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