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

Better handling of typedefs & fix various problems encountered while parsing templates

This commit is contained in:
Andrew Niefer 2004-03-22 18:23:22 +00:00
parent 717a507bae
commit 5fdc4f5c05
24 changed files with 362 additions and 288 deletions

View file

@ -1,3 +1,9 @@
2003-03-22 Andrew Niefer
Typedefs & templates
- added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTypedefedTemplate()
- added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTypedefedTemplate_2()
- added parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.testCompletionInTypeDef()
2003-03-18 Andrew Niefer
parsing template-ids
- added parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.test54778()

View file

@ -1696,4 +1696,78 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
assertAllReferences( 7, createTaskList( new Task( n ), new Task( i, 5 ), new Task( di ) ) );
}
public void testTypedefedTemplate() throws Exception{
Writer writer = new StringWriter();
writer.write( "template < class T > class _A{ int x; }; \n" );
writer.write( "typedef _A < char > A; \n" );
writer.write( "void foo() { \n" );
writer.write( " A a; \n" );
writer.write( " a.x; \n" );
writer.write( "} \n" );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTTemplateDeclaration _A = (IASTTemplateDeclaration) i.next();
IASTTypedefDeclaration A = (IASTTypedefDeclaration) i.next();
IASTFunction foo = (IASTFunction) i.next();
IASTClassSpecifier classA = (IASTClassSpecifier) _A.getOwnedDeclaration();
IASTVariable x = (IASTVariable) getDeclarations( classA ).next();
IASTVariable a = (IASTVariable) getDeclarations( foo ).next();
assertAllReferences( 4, createTaskList( new Task( classA ), new Task( A ), new Task( a ), new Task( x ) ) );
}
public void testTypedefedTemplate_2() throws Exception{
Writer writer = new StringWriter();
writer.write( "template < class T > struct A { T x; }; \n" );
writer.write( "template < class U > struct B { \n" );
writer.write( " typedef A< U > AU; \n" );
writer.write( " void f( U ); \n" );
writer.write( " void f( char ); \n" );
writer.write( " void g(){ \n" );
writer.write( " AU au; \n" );
writer.write( " f( au.x ); \n" );
writer.write( " } \n" );
writer.write( "}; \n" );
writer.write( "void f2( int ); \n" );
writer.write( "void f2( char ); \n" );
writer.write( "void h(){ \n" );
writer.write( " B< int >::AU b; \n" );
writer.write( " f2( b.x ); \n" );
writer.write( "} \n" );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTTemplateDeclaration tA = (IASTTemplateDeclaration) i.next();
IASTTemplateParameter T = (IASTTemplateParameter) tA.getTemplateParameters().next();
IASTClassSpecifier A = (IASTClassSpecifier) tA.getOwnedDeclaration();
IASTField x = (IASTField) getDeclarations( A ).next();
IASTTemplateDeclaration tB = (IASTTemplateDeclaration) i.next();
IASTClassSpecifier B = (IASTClassSpecifier) tB.getOwnedDeclaration();
IASTTemplateParameter U = (IASTTemplateParameter) tB.getTemplateParameters().next();
IASTFunction f21 = (IASTFunction) i.next();
IASTFunction f22 = (IASTFunction) i.next();
IASTFunction h = (IASTFunction) i.next();
i = getDeclarations( B );
IASTTypedefDeclaration AU = (IASTTypedefDeclaration) i.next();
IASTMethod f11 = (IASTMethod) i.next();
IASTMethod f12 = (IASTMethod) i.next();
IASTMethod g = (IASTMethod) i.next();
IASTVariable au = (IASTVariable) getDeclarations( g ).next();
IASTVariable b = (IASTVariable) getDeclarations( h ).next();
assertAllReferences( 12, createTaskList( new Task( A ),
new Task( T ),
new Task( U ),
new Task( AU, 2 ),
new Task( au ),
new Task( x, 2 ),
new Task( f11, 1, false, false ),
new Task( B ),
new Task( b ),
new Task( f21, 1, false, false ) ) );
}
}

View file

@ -916,6 +916,13 @@ public class CompleteParseBaseTest extends TestCase
return result;
}
protected List createTaskList(Task task, Task task2, Task task3, Task task4, Task task5, Task task6, Task task7, Task task8, Task task9, Task task10 )
{
List result = createTaskList( task, task2, task3, task4, task5, task6, task7, task8, task9 );
result.add( task10 );
return result;
}
public boolean qualifiedNamesEquals( String [] fromAST, String [] theTruth)
{
if( fromAST == null || theTruth == null ) return false;

View file

@ -662,4 +662,30 @@ public class CompletionParseTest extends CompleteParseBaseTest {
assertFalse( iter.hasNext() );
}
public void testCompletionInTypeDef() throws Exception{
StringWriter writer = new StringWriter();
writer.write( "struct A { int name; }; \n" );
writer.write( "typedef struct A * PA; \n" );
writer.write( "int main() { \n" );
writer.write( " PA a; \n" );
writer.write( " a->SP \n" );
writer.write( "} \n" );
String code = writer.toString();
int index = code.indexOf( "SP" );
IASTCompletionNode node = parse( code, index );
ILookupResult result = node.getCompletionScope().lookup( node.getCompletionPrefix(),
new IASTNode.LookupKind[]{ IASTNode.LookupKind.ALL },
node.getCompletionContext() );
assertEquals( result.getResultsSize(), 1 );
Iterator iter = result.getNodes();
IASTField name = (IASTField) iter.next();
assertEquals( name.getName(), "name" );
assertFalse( iter.hasNext() );
}
}

View file

@ -1,3 +1,11 @@
2004-03-22 Andrew Niefer
-handling of Typedefs
-handle unbalanced preprocessor condition in scanner
-fix concurrent modification exception while processing unresolved references in a Class Specifier
-report correct owner class for templated methods
-some work on template explicit specializations
-handle templated class forward declarations
2004-03-18 Andrew Niefer
parsing template-ids: enables clas template partial specializations and fixes 54778 indirectly
- add ITokenDuple.getTemplateIdArgLists

View file

@ -14,6 +14,6 @@ package org.eclipse.cdt.core.parser.ast;
* @author jcamelon
*
*/
public interface IASTTemplateSpecialization extends IASTDeclaration, IASTTemplate, IASTOffsetableElement {
public interface IASTTemplateSpecialization extends IASTTemplateDeclaration {
}

View file

@ -469,7 +469,7 @@ public abstract class Parser extends ExpressionParser implements IParser
throw backtrack;
}
templateSpecialization.enterScope(requestor);
declaration(scope, templateSpecialization, null);
declaration(templateSpecialization, templateSpecialization, null);
templateSpecialization.setEndingOffsetAndLineNumber(
lastToken.getEndOffset(), lastToken.getLineNumber());
templateSpecialization.exitScope(requestor);

View file

@ -303,10 +303,13 @@ public class ASTClassSpecifier extends ASTScope implements IASTClassSpecifier
}
private List unresolvedCrossReferences = new ArrayList();
private boolean processingUnresolvedReferences = false;
public void addUnresolvedReference( UnresolvedReferenceDuple duple)
{
unresolvedCrossReferences.add( duple );
//avoid a ConcurrentModificationException by not adding more references when we are
//in the middle of processing them
if( !processingUnresolvedReferences )
unresolvedCrossReferences.add( duple );
}
public Iterator getUnresolvedReferences()
@ -314,6 +317,10 @@ public class ASTClassSpecifier extends ASTScope implements IASTClassSpecifier
return unresolvedCrossReferences.iterator();
}
public void setProcessingUnresolvedReferences( boolean processing ){
processingUnresolvedReferences = processing;
}
private List resolvedCrossReferences = new ArrayList();
/**
* @param references2

View file

@ -21,6 +21,7 @@ import org.eclipse.cdt.core.parser.ast.IASTConstructorMemberInitializer;
import org.eclipse.cdt.core.parser.ast.IASTExceptionSpecification;
import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTTemplate;
import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator;
import org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
@ -197,6 +198,9 @@ public class ASTMethod extends ASTFunction implements IASTMethod
* @see org.eclipse.cdt.core.parser.ast.IASTMethod#getOwnerClassSpecifier()
*/
public IASTClassSpecifier getOwnerClassSpecifier() {
if( getOwnerScope() instanceof IASTTemplateDeclaration )
return (IASTClassSpecifier) ((IASTTemplateDeclaration)getOwnerScope()).getOwnerScope();
return (IASTClassSpecifier) getOwnerScope();
}
}

View file

@ -17,6 +17,8 @@ import java.util.ListIterator;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTNode.ILookupResult;
import org.eclipse.cdt.internal.core.parser.ast.SymbolIterator;
import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.IExtensibleSymbol;
@ -25,6 +27,7 @@ import org.eclipse.cdt.internal.core.parser.pst.ISymbolOwner;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException;
import org.eclipse.cdt.internal.core.parser.pst.TypeFilter;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
/**
* @author aniefer
@ -48,7 +51,15 @@ public class ASTNode implements IASTNode {
}
if( context != null ){
ISymbol sym = (IContainerSymbol) ((ISymbolOwner)context).getSymbol();
ISymbol sym = null;
if( context instanceof IASTTypedefDeclaration ){
ISymbol typedef = (ISymbol) ((ISymbolOwner)context).getSymbol();
TypeInfo info = typedef.getTypeInfo().getFinalType();
sym = info.getTypeSymbol();
} else {
sym = (IContainerSymbol) ((ISymbolOwner)context).getSymbol();
}
if( sym == null || !(sym instanceof IContainerSymbol) ){
throw new LookupError();
}

View file

@ -10,111 +10,22 @@
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.ast.complete;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.ast.IASTDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTScope;
import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
import org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol;
/**
* @author jcamelon
*
*/
public class ASTTemplateSpecialization extends ASTNode implements IASTTemplateSpecialization
public class ASTTemplateSpecialization extends ASTTemplateDeclaration implements IASTTemplateSpecialization
{
/**
*
*/
public ASTTemplateSpecialization()
public ASTTemplateSpecialization( ITemplateSymbol template, IASTScope scope )
{
super();
// TODO Auto-generated constructor stub
super(template, scope, null);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTTemplate#getOwnedDeclaration()
*/
public IASTDeclaration getOwnedDeclaration()
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTTemplate#setOwnedDeclaration(org.eclipse.cdt.core.parser.ast.IASTDeclaration)
*/
public void setOwnedDeclaration(IASTDeclaration declaration)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setStartingOffset(int)
*/
public void setStartingOffsetAndLineNumber(int offset, int lineNumber)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setEndingOffset(int)
*/
public void setEndingOffsetAndLineNumber(int offset, int lineNumber)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getStartingOffset()
*/
public int getStartingOffset()
{
// TODO Auto-generated method stub
return 0;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getEndingOffset()
*/
public int getEndingOffset()
{
// TODO Auto-generated method stub
return 0;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTScopedElement#getOwnerScope()
*/
public IASTScope getOwnerScope()
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#acceptElement(org.eclipse.cdt.core.parser.ISourceElementRequestor)
*/
public void acceptElement(ISourceElementRequestor requestor)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#enterScope(org.eclipse.cdt.core.parser.ISourceElementRequestor)
*/
public void enterScope(ISourceElementRequestor requestor)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#exitScope(org.eclipse.cdt.core.parser.ISourceElementRequestor)
*/
public void exitScope(ISourceElementRequestor requestor)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getStartingLine()
*/
public int getStartingLine() {
// TODO Auto-generated method stub
return 0;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getEndingLine()
*/
public int getEndingLine() {
// TODO Auto-generated method stub
return 0;
}
}

View file

@ -79,6 +79,7 @@ import org.eclipse.cdt.internal.core.parser.ast.BaseASTFactory;
import org.eclipse.cdt.internal.core.parser.problem.IProblemFactory;
import org.eclipse.cdt.internal.core.parser.pst.ForewardDeclaredSymbolExtension;
import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.IDeferredTemplateInstance;
import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol;
import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
@ -144,7 +145,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
* Overrides an existing reference if it has the same name and offset
*/
protected void addReference(List references, IASTReference reference){
if( references == null ) return;
if( references == null || reference == null ) return;
Iterator i = references.iterator();
while (i.hasNext()){
IASTReference ref = (IASTReference)i.next();
@ -822,15 +823,15 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
protected IASTReference createReference(ISymbol symbol, String referenceElementName, int offset ) throws ASTSemanticException
{
// assert (symbol != null ) : "createReference cannot be called on null symbol ";
if( symbol.getType() == TypeInfo.t_namespace )
if( symbol.getTypeInfo().checkBit( TypeInfo.isTypedef ) ||
symbol.getASTExtension().getPrimaryDeclaration() instanceof IASTTypedefDeclaration )
return new ASTTypedefReference( offset, referenceElementName, (IASTTypedefDeclaration)symbol.getASTExtension().getPrimaryDeclaration());
else if( symbol.getType() == TypeInfo.t_namespace )
return new ASTNamespaceReference( offset, referenceElementName, (IASTNamespaceDefinition)symbol.getASTExtension().getPrimaryDeclaration());
else if( symbol.getType() == TypeInfo.t_class ||
symbol.getType() == TypeInfo.t_struct ||
symbol.getType() == TypeInfo.t_union )
return new ASTClassReference( offset, referenceElementName, (IASTTypeSpecifier)symbol.getASTExtension().getPrimaryDeclaration() );
else if( symbol.getTypeInfo().checkBit( TypeInfo.isTypedef ))
return new ASTTypedefReference( offset, referenceElementName, (IASTTypedefDeclaration)symbol.getASTExtension().getPrimaryDeclaration());
else if( symbol.getType() == TypeInfo.t_enumeration )
return new ASTEnumerationReference( offset, referenceElementName, (IASTEnumerationSpecifier)symbol.getASTExtension().getPrimaryDeclaration() );
else if( symbol.getType() == TypeInfo.t_enumerator )
@ -1004,7 +1005,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
// If the expression is lookup symbol if it is in the scope of a type after a "." or an "->"
IContainerSymbol searchScope = getSearchScope(kind, lhs, startingScope);
if (!searchScope.equals(startingScope))
if ( searchScope != null && !searchScope.equals(startingScope))
symbol = lookupQualifiedName(searchScope, ((ASTExpression)rhs).getIdExpressionTokenDuple(), references, false, LookupType.QUALIFIED );
// get symbol if it is the "this" pointer
@ -1020,6 +1021,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
if (kind == IASTExpression.Kind.POSTFIX_FUNCTIONCALL){
ITokenDuple functionId = getFunctionId(lhs);
IContainerSymbol functionScope = getSearchScope(lhs.getExpressionKind(), lhs.getLHSExpression(), startingScope);
if( functionScope == null )
return null;
ExpressionResult expResult = ((ASTExpression)rhs).getResultType();
List parameters = null;
if(expResult instanceof ExpressionResultList){
@ -1058,18 +1063,12 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
){
TypeInfo lhsInfo = ((ASTExpression)lhs).getResultType().getResult();
if(lhsInfo != null){
ISymbol firstContainingScope = lhsInfo.getTypeSymbol();
if(firstContainingScope != null){
ISymbol containingScope = firstContainingScope.getTypeSymbol();
if(containingScope != null){
return (IContainerSymbol)containingScope;
} else {
return (IContainerSymbol)firstContainingScope;
}
} else {
// assert firstContainingScope != null : "Malformed Expression";
return null;
}
TypeInfo info = lhsInfo.getFinalType();
ISymbol containingScope = info.getTypeSymbol();
// assert containingScope != null : "Malformed Expression";
if( containingScope instanceof IDeferredTemplateInstance )
return ((IDeferredTemplateInstance) containingScope).getTemplate().getTemplatedSymbol();
return ( containingScope instanceof IContainerSymbol ) ? (IContainerSymbol)containingScope : null;
}
// assert lhsInfo != null : "Malformed Expression";
return null;
@ -2339,6 +2338,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
}
ISymbol newSymbol = cloneSimpleTypeSymbol(name, abstractDeclaration, references);
if( newSymbol == null )
handleProblem( IProblem.SEMANTICS_RELATED, name );
setVariableTypeInfoBits(
isAuto,
abstractDeclaration,
@ -2545,6 +2547,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
if(references == null)
references = new ArrayList();
ISymbol newSymbol = cloneSimpleTypeSymbol(name, abstractDeclaration, references);
if( newSymbol == null )
handleProblem( IProblem.SEMANTICS_RELATED, name );
setVariableTypeInfoBits(
isAuto,
abstractDeclaration,
@ -2664,8 +2670,13 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
IASTScope scope,
int startingOffset, int startingLine)
{
// TODO Auto-generated method stub
return new ASTTemplateSpecialization();
ITemplateSymbol template = pst.newTemplateSymbol( ParserSymbolTable.EMPTY_NAME );
ASTTemplateSpecialization ast = new ASTTemplateSpecialization( template, scope );
attachSymbolExtension( template, ast, false );
return ast;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTypedef(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, int, int)
@ -2725,43 +2736,68 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
List references = new ArrayList();
IToken lastToken = name.getLastToken();
String newSymbolName = ""; //$NON-NLS-1$
List templateIdArgList = null;
boolean isTemplateId = false;
if( name.length() != 1 ) // qualified name
{
ITokenDuple containerSymbolName =
name.getSubrange( 0, name.length() - 3 ); // -1 for index, -2 for last hop of qualified name
currentScopeSymbol = (IContainerSymbol)lookupQualifiedName( currentScopeSymbol,
containerSymbolName, references, false);
if( currentScopeSymbol == null )
handleProblem(IProblem.SEMANTIC_NAME_NOT_FOUND, containerSymbolName.toString(), containerSymbolName.getStartOffset(), containerSymbolName.getEndOffset(), containerSymbolName.getLineNumber() );
}
ISymbol checkSymbol = null;
try
{
if( isFriend ){
checkSymbol = ((IDerivableContainerSymbol)currentScopeSymbol).lookupForFriendship( lastToken.getImage() );
} else {
checkSymbol = currentScopeSymbol.elaboratedLookup( pstType, lastToken.getImage());
int idx = name.findLastTokenType( IToken.tCOLONCOLON );
if( idx != -1 ){
ITokenDuple containerSymbolName = name.getSubrange( 0, idx - 1 );
currentScopeSymbol = (IContainerSymbol)lookupQualifiedName( currentScopeSymbol, containerSymbolName, references, true);
if( currentScopeSymbol == null )
handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, containerSymbolName.toString(), containerSymbolName.getFirstToken().getOffset(), containerSymbolName.getLastToken().getEndOffset(), containerSymbolName.getLastToken().getLineNumber() );
}
//template-id
List [] array = name.getTemplateIdArgLists();
if( array != null ){
isTemplateId = true;
templateIdArgList = array[ array.length - 1 ];
lastToken = name.getToken( idx + 1);
}
}
catch (ParserSymbolTableException e)
{
handleProblem(e.createProblemID(),lastToken.getImage(), lastToken.getOffset(), lastToken.getEndOffset(), lastToken.getLineNumber() );
newSymbolName = lastToken.getImage();
ISymbol checkSymbol = null;
if( !isTemplateId ){
try
{
if( isFriend ){
checkSymbol = ((IDerivableContainerSymbol)currentScopeSymbol).lookupForFriendship( newSymbolName );
} else {
checkSymbol = currentScopeSymbol.elaboratedLookup( pstType, newSymbolName);
}
}
catch (ParserSymbolTableException e)
{
handleProblem(e.createProblemID(),lastToken.getImage(), lastToken.getOffset(), lastToken.getEndOffset(), lastToken.getLineNumber() );
}
}
List args = null;
if( isTemplateId ){
args = getTemplateArgList( templateIdArgList );
}
if( isForewardDecl )
{
if( checkSymbol == null )
{
checkSymbol = pst.newDerivableContainerSymbol( lastToken.getImage(), pstType );
checkSymbol = pst.newDerivableContainerSymbol( newSymbolName, pstType );
checkSymbol.setIsForwardDeclaration( true );
try
{
if( isFriend ){
((IDerivableContainerSymbol)currentScopeSymbol).addFriend( checkSymbol );
} else {
currentScopeSymbol.addSymbol( checkSymbol );
if( !isTemplateId )
currentScopeSymbol.addSymbol( checkSymbol );
else
currentScopeSymbol.addTemplateId( checkSymbol, args );
}
}
catch (ParserSymbolTableException e1)
@ -2791,7 +2827,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
if( checkSymbol.getASTExtension().getPrimaryDeclaration() instanceof IASTElaboratedTypeSpecifier )
return (IASTElaboratedTypeSpecifier)checkSymbol.getASTExtension().getPrimaryDeclaration();
} else {
handleProblem(IProblem.SEMANTIC_NAME_NOT_FOUND, lastToken.getImage(), lastToken.getOffset(), lastToken.getEndOffset(), lastToken.getLineNumber() );
handleProblem(IProblem.SEMANTIC_NAME_NOT_FOUND, newSymbolName, lastToken.getOffset(), lastToken.getEndOffset(), lastToken.getLineNumber() );
}
@ -2937,7 +2973,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
if( result.getType() == TypeInfo.t_type )
{
ISymbol typeSymbol = lookupQualifiedName( scopeToSymbol(scope), typeId.getTokenDuple(), refs, true );
if( typeSymbol.getType() == TypeInfo.t_type )
if( typeSymbol == null || typeSymbol.getType() == TypeInfo.t_type )
handleProblem( IProblem.SEMANTIC_INVALID_TYPE, id.getTypeOrClassName() );
result.setTypeSymbol( typeSymbol );
typeId.addReferences( refs );
@ -2962,6 +2998,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
// do nothing, this is best effort
}
astImplementation.setProcessingUnresolvedReferences( true );
Iterator i = astImplementation.getUnresolvedReferences();
List references = new ArrayList();
while( i.hasNext() )
@ -2984,6 +3021,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
}
astImplementation.setProcessingUnresolvedReferences( false );
if( ! references.isEmpty() )
astImplementation.setExtraReferences( references );

View file

@ -47,7 +47,7 @@ public class ASTTemplateDeclaration extends ASTDeclaration implements IASTTempla
*/
public Iterator getTemplateParameters()
{
return templateParameters.iterator();
return ( templateParameters != null ) ? templateParameters.iterator() : new LinkedList().iterator();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration#getOwnedDeclaration()

View file

@ -20,7 +20,7 @@ import org.eclipse.cdt.internal.core.parser.ast.Offsets;
* @author jcamelon
*
*/
public class ASTTemplateSpecialization extends ASTDeclaration implements IASTTemplateSpecialization
public class ASTTemplateSpecialization extends ASTTemplateDeclaration implements IASTTemplateSpecialization
{
private Offsets offsets = new Offsets();
private IASTDeclaration ownedDeclaration;
@ -29,54 +29,10 @@ public class ASTTemplateSpecialization extends ASTDeclaration implements IASTTem
*/
public ASTTemplateSpecialization(IASTScope scope, int startingOffset, int startingLine )
{
super(scope);
super(scope, null, startingOffset, startingLine, false );
setStartingOffsetAndLineNumber(startingOffset, startingLine);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTTemplate#getOwnedDeclaration()
*/
public IASTDeclaration getOwnedDeclaration()
{
return ownedDeclaration;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setStartingOffset(int)
*/
public void setStartingOffsetAndLineNumber(int offset, int lineNumber)
{
offsets.setStartingOffsetAndLineNumber(offset, lineNumber);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setEndingOffset(int)
*/
public void setEndingOffsetAndLineNumber(int offset, int lineNumber)
{
offsets.setEndingOffsetAndLineNumber(offset, lineNumber);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getElementStartingOffset()
*/
public int getStartingOffset()
{
return offsets.getStartingOffset();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getElementEndingOffset()
*/
public int getEndingOffset()
{
return offsets.getEndingOffset();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTTemplate#setOwnedDeclaration(org.eclipse.cdt.core.parser.ast.IASTDeclaration)
*/
public void setOwnedDeclaration(IASTDeclaration declaration)
{
ownedDeclaration = declaration;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#accept(org.eclipse.cdt.core.parser.ISourceElementRequestor)
*/
@ -112,20 +68,5 @@ public class ASTTemplateSpecialization extends ASTDeclaration implements IASTTem
{
/* do nothing */
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getStartingLine()
*/
public int getStartingLine() {
return offsets.getStartingLine();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getEndingLine()
*/
public int getEndingLine() {
return offsets.getEndingLine();
}
}
}

View file

@ -553,8 +553,8 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
if( foundSymbol instanceof IContainerSymbol )
return (IContainerSymbol) foundSymbol;
else
return null;
return null;
}
/* (non-Javadoc)
@ -725,16 +725,17 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
ParserSymbolTable.lookup( data, this );
ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
if( found != null ){
if( (found.isType( TypeInfo.t_templateParameter ) && found.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template) ||
found.isType( TypeInfo.t_template ) )
{
found = ((ITemplateSymbol) found).instantiate( arguments );
} else if( found.getContainingSymbol().isType( TypeInfo.t_template ) ){
found = ((ITemplateSymbol) found.getContainingSymbol()).instantiate( arguments );
}
}
if( (found.isType( TypeInfo.t_templateParameter ) && found.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template) ||
found.isType( TypeInfo.t_template ) )
{
return ((ITemplateSymbol) found).instantiate( arguments );
} else if( found.getContainingSymbol().isType( TypeInfo.t_template ) ){
return ((ITemplateSymbol) found.getContainingSymbol()).instantiate( arguments );
}
return null;
return found;
}
/* (non-Javadoc)
@ -1067,8 +1068,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addTemplateId(org.eclipse.cdt.internal.core.parser.pst.ISymbol, java.util.List)
*/
public void addTemplateId(ISymbol symbol, List args) throws ParserSymbolTableException {
// TODO Auto-generated method stub
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
}
/* (non-Javadoc)

View file

@ -29,6 +29,8 @@ public class DeferredTemplateInstance extends BasicSymbol implements IDeferredTe
_arguments = new LinkedList( args );
setContainingSymbol( template );
if( template.getTemplatedSymbol() != null )
setASTExtension( template.getTemplatedSymbol().getASTExtension() );
}
@ -76,14 +78,14 @@ public class DeferredTemplateInstance extends BasicSymbol implements IDeferredTe
public TypeInfo.eType getType(){
return _template.getTemplatedSymbol().getType();
}
public TypeInfo getTypeInfo(){
return _template.getTemplatedSymbol().getTypeInfo();
}
public boolean isType( TypeInfo.eType type ){
return _template.getTemplatedSymbol().isType( type );
}
public ISymbolASTExtension getASTExtension() {
return _template.getTemplatedSymbol().getASTExtension();
}
private ITemplateSymbol _template;
private List _arguments;

View file

@ -17,8 +17,6 @@ import java.util.List;
**/
public interface ITemplateFactory extends IDerivableContainerSymbol {
public ITemplateSymbol getPrimaryTemplate();
public void pushTemplate( ITemplateSymbol template );
public void pushSymbol( ISymbol symbol );
public void pushTemplateId( ISymbol symbol, List args );

View file

@ -437,7 +437,8 @@ public class ParserSymbolTable {
return true;
}
return data.filter.shouldAccept( symbol );
TypeInfo typeInfo = ParserSymbolTable.getFlatTypeInfo( symbol.getTypeInfo() );
return data.filter.shouldAccept( symbol, typeInfo ) || data.filter.shouldAccept( symbol );
}
private static Object collectSymbol(LookupData data, Object object ) throws ParserSymbolTableException {
@ -903,6 +904,8 @@ public class ParserSymbolTable {
* provided in data.parameters.
*/
static protected ISymbol resolveAmbiguities( LookupData data ) throws ParserSymbolTableException{
ISymbol resolvedSymbol = null;
if( data.foundItems == null || data.foundItems.isEmpty() || data.mode == LookupMode.PREFIX ){
return null;
}
@ -921,23 +924,45 @@ public class ParserSymbolTable {
if( symbol.isTemplateMember() && !symbol.isTemplateInstance() &&
!symbol.isType( TypeInfo.t_templateParameter ) && symbol.getContainingSymbol().isType( TypeInfo.t_template ))
{
return symbol.getContainingSymbol();
resolvedSymbol = symbol.getContainingSymbol();
} else {
resolvedSymbol = symbol;
}
return symbol;
}
}
if( data.parameters == null ){
//we have no parameter information, if we only have one function, return
//that, otherwise we can't decide between them
if( functionList.size() == 1){
return (ISymbol) functionList.getFirst();
if( resolvedSymbol == null ){
if( data.parameters == null ){
//we have no parameter information, if we only have one function, return
//that, otherwise we can't decide between them
if( functionList.size() == 1){
resolvedSymbol = (ISymbol) functionList.getFirst();
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_UnableToResolveFunction );
}
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_UnableToResolveFunction );
resolvedSymbol = resolveFunction( data, functionList );
}
} else {
return resolveFunction( data, functionList );
}
if( resolvedSymbol != null && resolvedSymbol.getTypeInfo().checkBit( TypeInfo.isTypedef ) ){
ISymbol symbol = resolvedSymbol.getTypeSymbol();
TypeInfo info = ParserSymbolTable.getFlatTypeInfo( symbol.getTypeInfo() );
symbol = info.getTypeSymbol();
ISymbol newSymbol = null;
if( symbol != null ){
newSymbol = (ISymbol) symbol.clone();
newSymbol.setName( resolvedSymbol.getName() );
} else {
newSymbol = resolvedSymbol.getSymbolTable().newSymbol( resolvedSymbol.getName() );
newSymbol.setTypeInfo( info );
}
newSymbol.setASTExtension( resolvedSymbol.getASTExtension() );
newSymbol.setContainingSymbol( resolvedSymbol.getContainingSymbol() );
resolvedSymbol = newSymbol;
}
return resolvedSymbol;
}
static protected IParameterizedSymbol resolveFunction( LookupData data, List functions ) throws ParserSymbolTableException{
@ -1796,6 +1821,9 @@ public class ParserSymbolTable {
data.parameters.add( source );
data.forUserDefinedConversion = true;
if( targetDecl instanceof IDeferredTemplateInstance ){
targetDecl = ((IDeferredTemplateInstance)targetDecl).getTemplate().getTemplatedSymbol();
}
IDerivableContainerSymbol container = (IDerivableContainerSymbol) targetDecl;
if( !container.getConstructors().isEmpty() ){

View file

@ -58,6 +58,8 @@ public final class TemplateEngine {
TypeInfo newInfo = new TypeInfo( info );
newInfo.setTypeSymbol( info.getTypeSymbol().instantiate( template, argMap ) );
return newInfo;
} else if( info.checkBit( TypeInfo.isTypedef ) && info.getTypeSymbol() != null ){
return instantiateTypeInfo( info.getTypeSymbol().getTypeInfo(), template, argMap );
}
return info;
}
@ -1224,8 +1226,8 @@ public final class TemplateEngine {
return false;
}
ITemplateSymbol t1 = (ITemplateSymbol) p1.getContainingSymbol();
ITemplateSymbol t2 = (ITemplateSymbol) p2.getContainingSymbol();
ITemplateSymbol t1 = (ITemplateSymbol) getContainingTemplate( p1 );//.getContainingSymbol();
ITemplateSymbol t2 = (ITemplateSymbol) getContainingTemplate( p2 );//.getContainingSymbol();
if( p1.getTypeInfo().getTemplateParameterType() == TypeInfo.t_typeName )
{
@ -1239,4 +1241,15 @@ public final class TemplateEngine {
return p1.getTypeInfo().equals( p2.getTypeInfo() );
}
}
static protected ITemplateSymbol getContainingTemplate( ISymbol symbol ){
if( ! symbol.isTemplateMember() ){
return null;
}
while( !( symbol.getContainingSymbol() instanceof ITemplateSymbol ) ){
symbol = symbol.getContainingSymbol();
}
return (ITemplateSymbol) symbol.getContainingSymbol();
}
}

View file

@ -16,7 +16,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTemplateDeclaration;
@ -67,7 +66,7 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
List params = template.getParameterList();
if( params.size() == 0 ){
//explicit specialization
addExplicitSpecialization( origTemplate, symbol, args );
} else {
//partial speciailization
ISpecializedSymbol spec = template.getSymbolTable().newSpecializedSymbol( symbol.getName() );
@ -261,25 +260,25 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
}
}
private void addExplicitSpecialization( ISymbol symbol ) throws ParserSymbolTableException {
Iterator templatesIter = getTemplatesList().iterator();
Iterator argsIter = getArgumentsList().iterator();
private void addExplicitSpecialization( ITemplateSymbol template, ISymbol symbol, List arguments ) throws ParserSymbolTableException {
Iterator templatesIter = templates.iterator();
Iterator argsIter = arguments.iterator();
while( templatesIter.hasNext() ){
ITemplateSymbol template = (ITemplateSymbol)templatesIter.next();
// while( templatesIter.hasNext() ){
// ITemplateSymbol template = (ITemplateSymbol)templatesIter.next();
template.addExplicitSpecialization( symbol, (List) argsIter.next() );
}
template.addExplicitSpecialization( symbol, arguments );
//}
if( getTemplateFunctions() != null && argsIter.hasNext() ){
List args = (List) argsIter.next();
ITemplateSymbol template = TemplateEngine.resolveTemplateFunctions( getTemplateFunctions(), args, symbol );
if( template != null ){
template.addExplicitSpecialization( symbol, args );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
}
}
// if( getTemplateFunctions() != null && argsIter.hasNext() ){
// List args = (List) argsIter.next();
// ITemplateSymbol template = TemplateEngine.resolveTemplateFunctions( getTemplateFunctions(), args, symbol );
// if( template != null ){
// template.addExplicitSpecialization( symbol, args );
// } else {
// throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
// }
// }
}
/* (non-Javadoc)
@ -300,31 +299,6 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#getPrimaryTemplate()
*/
public ITemplateSymbol getPrimaryTemplate() {
return (ITemplateSymbol) templatesList.get( 0 );
}
protected List getTemplatesList() {
return templatesList;
}
protected List getParametersList() {
return parametersList;
}
protected List getArgumentsList(){
return argumentsList;
}
protected Set getTemplateFunctions(){
return templateFunctions;
}
private Set templateFunctions;
private List templatesList;
private List parametersList;
private List argumentsList;
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#removeSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/

View file

@ -104,10 +104,12 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
if( argIter.hasNext() ){
arg = (TypeInfo) argIter.next();
//If the argument is a template parameter, we can't instantiate yet, defer for later
if( arg.isType( TypeInfo.t_type ) && arg.getTypeSymbol().isType( TypeInfo.t_templateParameter ) ){
return deferredInstance( arguments );
if( arg.isType( TypeInfo.t_type ) ){
if( arg.getTypeSymbol() == null )
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument );
else if( arg.getTypeSymbol().isType( TypeInfo.t_templateParameter ) )
return deferredInstance( arguments );
}
} else {
Object obj = param.getTypeInfo().getDefault();
@ -233,8 +235,19 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
Map map = getExplicitSpecializations();
Map specs = null;
if( map.containsKey( actualArgs ) ){
specs = (Map) map.get( actualArgs );
List key = null;
Iterator iter = map.keySet().iterator();
while( iter.hasNext() ){
List list = (List) iter.next();
if( list.equals( args ) ){
key = list;
break;
}
}
if( key != null ){
specs = (Map) map.get( key );
} else {
specs = new HashMap();
map.put( new LinkedList( actualArgs ), specs );
@ -244,7 +257,7 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
try{
if( symbol.isType( TypeInfo.t_function ) || symbol.isType( TypeInfo.t_constructor ) ){
List fnArgs = new LinkedList();
Iterator iter = ((IParameterizedSymbol)symbol).getParameterList().iterator();
iter = ((IParameterizedSymbol)symbol).getParameterList().iterator();
while( iter.hasNext() ){
fnArgs.add( ((ISymbol)iter.next()).getTypeInfo() );
}

View file

@ -293,6 +293,9 @@ public class TypeInfo {
_templateParameterType = type;
}
public TypeInfo getFinalType(){
return ParserSymbolTable.getFlatTypeInfo( this );
}
/**
*
* @param type

View file

@ -166,7 +166,7 @@ public class BranchTracker {
}
// taken only on an #endif
public boolean poundEndif( )
public boolean poundEndif( ) throws EmptyStackException
{
if( ignore == branches.size() )
ignore = IGNORE_SENTINEL;

View file

@ -1306,7 +1306,16 @@ public class Scanner implements IScanner {
buffer.append( restOfLine );
handleProblem( IProblem.PREPROCESSOR_INVALID_DIRECTIVE, buffer.toString(), beginningOffset, false, true );
}
passOnToClient = scannerData.getBranchTracker().poundEndif();
try{
passOnToClient = scannerData.getBranchTracker().poundEndif();
}
catch( EmptyStackException ese )
{
handleProblem( IProblem.PREPROCESSOR_UNBALANCE_CONDITION,
token,
beginningOffset,
false, true );
}
return null;
case PreprocessorDirectives.IFNDEF :