mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 06:05:24 +02:00
Patch for Andrew Niefer.
Refactor the symbol table by splitting the ParserSymbolTable.Declaration class in 4 classes and moving it to not be nested Tests have been updated and tested on windows & Linux
This commit is contained in:
parent
7e02ddb252
commit
fcfd56c2af
16 changed files with 1764 additions and 1441 deletions
|
@ -1,3 +1,6 @@
|
|||
2003-11-18 Andrew Niefer
|
||||
update ParserSymbolTableTest to reflect refactoring of Declaration into 4 separate classes.
|
||||
|
||||
2003-11-13 Hoda Amer
|
||||
Added CompleteParseASTTest::testBug44342(): Failure to dereference function calls after a . or an ->
|
||||
Moved testErrorHandling_1() to FailedCompleteParseASTTest
|
||||
|
|
|
@ -27,9 +27,9 @@ import org.eclipse.cdt.internal.core.parser.pst.ISymbolASTExtension;
|
|||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.StandardSymbolExtension;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.TemplateInstance;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Mark;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.OperatorExpression;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
|
||||
|
||||
|
@ -92,7 +92,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
public void testSimpleLookup() throws Exception{
|
||||
newTable(); //new symbol table
|
||||
|
||||
ISymbol x = table.new Declaration( "x" );
|
||||
ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
|
||||
table.getCompilationUnit().addSymbol( x );
|
||||
|
||||
ISymbol look = table.getCompilationUnit().lookup( "x" );
|
||||
|
@ -110,7 +110,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
public void testSimpleSetGetObject() throws Exception{
|
||||
newTable();
|
||||
|
||||
IContainerSymbol x = table.new Declaration("x");
|
||||
IContainerSymbol x = table.newContainerSymbol( "x", TypeInfo.t_namespace );
|
||||
|
||||
ISymbolASTExtension extension = new StandardSymbolExtension(x,null);
|
||||
|
||||
|
@ -188,7 +188,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
class1.setType( TypeInfo.t_class );
|
||||
class1.addParent( parent );
|
||||
|
||||
ISymbol decl = table.new Declaration("x");
|
||||
ISymbol decl = table.newSymbol( "x", TypeInfo.t_int );
|
||||
parent.addSymbol( decl );
|
||||
|
||||
table.getCompilationUnit().addSymbol( parent );
|
||||
|
@ -216,7 +216,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
IDerivableContainerSymbol class1 = (IDerivableContainerSymbol) table.getCompilationUnit().lookup( "class" );
|
||||
class1.addParent( parent2 );
|
||||
|
||||
ISymbol decl = table.new Declaration("x");
|
||||
ISymbol decl = table.newSymbol( "x", TypeInfo.t_int );
|
||||
parent2.addSymbol( decl );
|
||||
|
||||
try{
|
||||
|
@ -283,7 +283,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
IContainerSymbol compUnit = table.getCompilationUnit();
|
||||
compUnit.addSymbol( c );
|
||||
|
||||
ISymbol x = table.new Declaration( "x" );
|
||||
ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
|
||||
c.addSymbol( x );
|
||||
|
||||
compUnit.addSymbol( decl );
|
||||
|
@ -357,16 +357,14 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
compUnit.addSymbol( c );
|
||||
compUnit.addSymbol( d );
|
||||
|
||||
IContainerSymbol enum = table.new Declaration("enum");
|
||||
enum.setType( TypeInfo.t_enumeration );
|
||||
IContainerSymbol enum = table.newContainerSymbol( "enum", TypeInfo.t_enumeration );
|
||||
|
||||
ISymbol enumerator = table.new Declaration( "enumerator" );
|
||||
enumerator.setType( TypeInfo.t_enumerator );
|
||||
ISymbol enumerator = table.newSymbol( "enumerator", TypeInfo.t_enumerator );
|
||||
|
||||
ISymbol stat = table.new Declaration("static");
|
||||
ISymbol stat = table.newSymbol( "static", TypeInfo.t_int );
|
||||
stat.getTypeInfo().setBit( true, TypeInfo.isStatic );
|
||||
|
||||
ISymbol x = table.new Declaration("x");
|
||||
ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
|
||||
|
||||
d.addSymbol( enum );
|
||||
d.addSymbol( stat );
|
||||
|
@ -1110,12 +1108,10 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
|
||||
IContainerSymbol compUnit = table.getCompilationUnit();
|
||||
|
||||
ParserSymbolTable.Declaration A = table.new Declaration( "A" );
|
||||
A.setType( TypeInfo.t_namespace );
|
||||
IContainerSymbol A = table.newContainerSymbol( "A", TypeInfo.t_namespace );
|
||||
compUnit.addSymbol( A );
|
||||
|
||||
ParserSymbolTable.Declaration f1 = table.new Declaration( "f" );
|
||||
f1.setType( TypeInfo.t_function );
|
||||
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
|
||||
f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
|
||||
f1.addParameter( TypeInfo.t_int, 0, null, false );
|
||||
A.addSymbol( f1 );
|
||||
|
@ -1172,8 +1168,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
public void testThisPointer() throws Exception{
|
||||
newTable();
|
||||
|
||||
IContainerSymbol cls = table.newContainerSymbol("class");
|
||||
cls.setType( TypeInfo.t_class );
|
||||
IDerivableContainerSymbol cls = table.newDerivableContainerSymbol( "class", TypeInfo.t_class );
|
||||
|
||||
IParameterizedSymbol fn = table.newParameterizedSymbol("function");
|
||||
fn.setType( TypeInfo.t_function );
|
||||
|
@ -1319,8 +1314,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
|
||||
compUnit.addSymbol( NS1 );
|
||||
|
||||
ParserSymbolTable.Declaration f1 = table.new Declaration( "f" );
|
||||
f1.setType( TypeInfo.t_function );
|
||||
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
|
||||
f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
|
||||
f1.addParameter( TypeInfo.t_void, 0, new PtrOp( PtrOp.t_pointer ), false );
|
||||
NS1.addSymbol( f1 );
|
||||
|
@ -1992,7 +1986,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
LinkedList args = new LinkedList();
|
||||
args.add( type );
|
||||
|
||||
ParserSymbolTable.TemplateInstance instance = table.getCompilationUnit().templateLookup( "A", args );
|
||||
TemplateInstance instance = table.getCompilationUnit().templateLookup( "A", args );
|
||||
assertEquals( instance.getInstantiatedSymbol(), A );
|
||||
|
||||
ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
|
||||
|
@ -2047,7 +2041,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
args.add( type );
|
||||
|
||||
look = table.getCompilationUnit().templateLookup( "A", args );
|
||||
assertTrue( look instanceof ParserSymbolTable.TemplateInstance );
|
||||
assertTrue( look instanceof TemplateInstance );
|
||||
|
||||
B.addParent( look );
|
||||
table.getCompilationUnit().addSymbol( B );
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2003-11-18 Andrew Niefer
|
||||
Refactor PST: Split Declaration into 4 classes : ContainerSymbol, DerivableContainerSymbol, ParameterizedContainerSymbol,
|
||||
SpecializedSymbol. Move these along with BasicSymbol & TemplateInstance to no longer be nested in ParserSymbolTable.
|
||||
|
||||
2003-11-13 Hoda Amer
|
||||
Changed the getExpressionResultType() in the complete factory to return
|
||||
an object of type ExpressionResult.
|
||||
|
|
|
@ -24,8 +24,7 @@ import org.eclipse.cdt.internal.core.parser.ast.ASTQualifiedNamedElement;
|
|||
import org.eclipse.cdt.internal.core.parser.ast.NamedOffsets;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Declaration.ParentWrapper;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol.IParentSymbol;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -65,7 +64,7 @@ public class ASTClassSpecifier extends ASTScope implements IASTClassSpecifier
|
|||
if( ! hasNext() )
|
||||
throw new NoSuchElementException();
|
||||
|
||||
ParserSymbolTable.Declaration.ParentWrapper pw = (ParentWrapper)parents.next();
|
||||
IParentSymbol pw = (IParentSymbol)parents.next();
|
||||
|
||||
return new ASTBaseSpecifier( pw.getParent(), pw.isVirtual(), pw.getAccess(), pw.getOffset(), pw.getReferences() );
|
||||
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Created on Nov 4, 2003
|
||||
*
|
||||
* 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 java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
public class BasicSymbol implements Cloneable, ISymbol
|
||||
{
|
||||
private final ParserSymbolTable _table;
|
||||
public BasicSymbol( ParserSymbolTable table, String name ){
|
||||
super();
|
||||
this._table = table;
|
||||
_name = name;
|
||||
_typeInfo = new TypeInfo();
|
||||
}
|
||||
|
||||
public BasicSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
|
||||
super();
|
||||
this._table = table;
|
||||
_name = name;
|
||||
_object = obj;
|
||||
_typeInfo = new TypeInfo();
|
||||
}
|
||||
|
||||
public BasicSymbol( ParserSymbolTable table, String name, TypeInfo.eType typeInfo )
|
||||
{
|
||||
super();
|
||||
this._table = table;
|
||||
_name = name;
|
||||
_typeInfo = new TypeInfo( typeInfo, 0, null );
|
||||
}
|
||||
|
||||
public ParserSymbolTable getSymbolTable(){
|
||||
return _table;
|
||||
}
|
||||
|
||||
public Object clone(){
|
||||
BasicSymbol copy = null;
|
||||
try{
|
||||
copy = (BasicSymbol)super.clone();
|
||||
} catch ( CloneNotSupportedException e ){
|
||||
//should not happen
|
||||
return null;
|
||||
}
|
||||
copy._object = null;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public String getName() { return _name; }
|
||||
public void setName(String name) { _name = name; }
|
||||
|
||||
public ISymbolASTExtension getASTExtension() { return _object; }
|
||||
public void setASTExtension( ISymbolASTExtension obj ) { _object = obj; }
|
||||
|
||||
public IContainerSymbol getContainingSymbol() { return _containingScope; }
|
||||
public void setContainingSymbol( IContainerSymbol scope ){
|
||||
_containingScope = scope;
|
||||
_depth = scope.getDepth() + 1;
|
||||
}
|
||||
|
||||
public void setType(TypeInfo.eType t){
|
||||
getTypeInfo().setType( t );
|
||||
}
|
||||
|
||||
public TypeInfo.eType getType(){
|
||||
return getTypeInfo().getType();
|
||||
}
|
||||
|
||||
public boolean isType( TypeInfo.eType type ){
|
||||
return getTypeInfo().isType( type, TypeInfo.t_undef );
|
||||
}
|
||||
|
||||
public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType ){
|
||||
return getTypeInfo().isType( type, upperType );
|
||||
}
|
||||
|
||||
public ISymbol getTypeSymbol(){
|
||||
ISymbol symbol = getTypeInfo().getTypeSymbol();
|
||||
|
||||
if( symbol != null && symbol.getTypeInfo().isForwardDeclaration() && symbol.getTypeSymbol() != null ){
|
||||
return symbol.getTypeSymbol();
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setTypeSymbol( ISymbol type ){
|
||||
getTypeInfo().setTypeSymbol( type );
|
||||
}
|
||||
|
||||
public TypeInfo getTypeInfo(){
|
||||
return _typeInfo;
|
||||
}
|
||||
|
||||
public void setTypeInfo( TypeInfo info ) {
|
||||
_typeInfo = info;
|
||||
}
|
||||
|
||||
public boolean isForwardDeclaration(){
|
||||
return getTypeInfo().isForwardDeclaration();
|
||||
}
|
||||
|
||||
public void setIsForwardDeclaration( boolean forward ){
|
||||
getTypeInfo().setIsForwardDeclaration( forward );
|
||||
}
|
||||
|
||||
/**
|
||||
* returns 0 if same, non zero otherwise
|
||||
*/
|
||||
public int compareCVQualifiersTo( ISymbol symbol ){
|
||||
int size = symbol.getTypeInfo().hasPtrOperators() ? symbol.getTypeInfo().getPtrOperators().size() : 0;
|
||||
int size2 = getTypeInfo().hasPtrOperators() ? getTypeInfo().getPtrOperators().size() : 0;
|
||||
|
||||
if( size != size2 ){
|
||||
return size2 - size;
|
||||
} else if( size == 0 )
|
||||
return 0;
|
||||
else {
|
||||
|
||||
Iterator iter1 = symbol.getTypeInfo().getPtrOperators().iterator();
|
||||
Iterator iter2 = getTypeInfo().getPtrOperators().iterator();
|
||||
|
||||
TypeInfo.PtrOp op1 = null, op2 = null;
|
||||
|
||||
for( int i = size; i > 0; i-- ){
|
||||
op1 = (TypeInfo.PtrOp)iter1.next();
|
||||
op2 = (TypeInfo.PtrOp)iter2.next();
|
||||
|
||||
if( op1.compareCVTo( op2 ) != 0 ){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public List getPtrOperators(){
|
||||
return getTypeInfo().getPtrOperators();
|
||||
}
|
||||
public void addPtrOperator( TypeInfo.PtrOp ptrOp ){
|
||||
getTypeInfo().addPtrOperator( ptrOp );
|
||||
}
|
||||
|
||||
public int getDepth(){
|
||||
return _depth;
|
||||
}
|
||||
|
||||
public boolean isTemplateMember(){
|
||||
return _isTemplateMember;
|
||||
}
|
||||
public void setIsTemplateMember( boolean isMember ){
|
||||
_isTemplateMember = isMember;
|
||||
}
|
||||
public ISymbol getTemplateInstance(){
|
||||
return _templateInstance;
|
||||
}
|
||||
public void setTemplateInstance( TemplateInstance instance ){
|
||||
_templateInstance = instance;
|
||||
}
|
||||
public Map getArgumentMap(){
|
||||
return null;
|
||||
}
|
||||
private String _name; //our name
|
||||
private ISymbolASTExtension _object; //the object associated with us
|
||||
private TypeInfo _typeInfo; //our type info
|
||||
private IContainerSymbol _containingScope; //the scope that contains us
|
||||
private int _depth; //how far down the scope stack we are
|
||||
|
||||
private boolean _isTemplateMember = false;
|
||||
private TemplateInstance _templateInstance;
|
||||
}
|
|
@ -0,0 +1,650 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2003 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v0.5
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v05.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corp. - Rational Software - initial implementation
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Created on Nov 4, 2003
|
||||
*/
|
||||
|
||||
package org.eclipse.cdt.internal.core.parser.pst;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Command;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.LookupData;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*
|
||||
* To change the template for this generated type comment go to
|
||||
* Window>Preferences>Java>Code Generation>Code and Comments
|
||||
*/
|
||||
public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
|
||||
|
||||
protected ContainerSymbol( ParserSymbolTable table, String name ){
|
||||
super( table, name );
|
||||
}
|
||||
|
||||
protected ContainerSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
|
||||
super( table, name, obj );
|
||||
}
|
||||
|
||||
protected ContainerSymbol( ParserSymbolTable table, String name, TypeInfo.eType typeInfo ){
|
||||
super( table, name, typeInfo );
|
||||
}
|
||||
|
||||
public Object clone(){
|
||||
ContainerSymbol copy = (ContainerSymbol)super.clone();
|
||||
|
||||
copy._usingDirectives = ( _usingDirectives != null ) ? (LinkedList) _usingDirectives.clone() : null;
|
||||
copy._containedSymbols = ( _containedSymbols != null )? (HashMap) _containedSymbols.clone() : null;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
|
||||
*/
|
||||
public void addSymbol( ISymbol obj ) throws ParserSymbolTableException{
|
||||
IContainerSymbol containing = this;
|
||||
|
||||
//handle enumerators
|
||||
if( obj.getType() == TypeInfo.t_enumerator ){
|
||||
//a using declaration of an enumerator will not be contained in a
|
||||
//enumeration.
|
||||
if( containing.getType() == TypeInfo.t_enumeration ){
|
||||
//Following the closing brace of an enum-specifier, each enumerator has the type of its
|
||||
//enumeration
|
||||
obj.setTypeSymbol( containing );
|
||||
//Each enumerator is declared in the scope that immediately contains the enum-specifier
|
||||
containing = containing.getContainingSymbol();
|
||||
}
|
||||
}
|
||||
|
||||
//Templates contain 1 declaration
|
||||
if( getType() == TypeInfo.t_template ){
|
||||
//declaration must be a class or a function
|
||||
if( ( obj.getType() != TypeInfo.t_class && obj.getType() != TypeInfo.t_function ) ||
|
||||
( getContainedSymbols() != null && getContainedSymbols().size() == 1 ) )
|
||||
{
|
||||
//throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
|
||||
}
|
||||
}
|
||||
|
||||
Map declarations = containing.getContainedSymbols();
|
||||
|
||||
boolean unnamed = obj.getName().equals( ParserSymbolTable.EMPTY_NAME );
|
||||
|
||||
Object origObj = null;
|
||||
|
||||
obj.setContainingSymbol( containing );
|
||||
|
||||
//does this name exist already?
|
||||
origObj = declarations.get( obj.getName() );
|
||||
|
||||
if( origObj != null )
|
||||
{
|
||||
ISymbol origDecl = null;
|
||||
LinkedList origList = null;
|
||||
|
||||
if( origObj instanceof ISymbol ){
|
||||
origDecl = (ISymbol)origObj;
|
||||
} else if( origObj.getClass() == LinkedList.class ){
|
||||
origList = (LinkedList)origObj;
|
||||
} else {
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
|
||||
}
|
||||
|
||||
boolean validOverride = ((origList == null) ? ParserSymbolTable.isValidOverload( origDecl, obj ) : ParserSymbolTable.isValidOverload( origList, obj ) );
|
||||
if( unnamed || validOverride )
|
||||
{
|
||||
if( origList == null ){
|
||||
origList = new LinkedList();
|
||||
origList.add( origDecl );
|
||||
origList.add( obj );
|
||||
|
||||
declarations.remove( origDecl );
|
||||
declarations.put( obj.getName(), origList );
|
||||
} else {
|
||||
origList.add( obj );
|
||||
//origList is already in _containedDeclarations
|
||||
}
|
||||
} else {
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidOverload );
|
||||
}
|
||||
} else {
|
||||
declarations.put( obj.getName(), obj );
|
||||
}
|
||||
|
||||
obj.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
|
||||
|
||||
Command command = new AddSymbolCommand( (ISymbol) obj, containing );
|
||||
getSymbolTable().pushCommand( command );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#hasUsingDirectives()
|
||||
*/
|
||||
public boolean hasUsingDirectives(){
|
||||
return ( _usingDirectives != null && !_usingDirectives.isEmpty() );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getUsingDirectives()
|
||||
*/
|
||||
public List getUsingDirectives(){
|
||||
if( _usingDirectives == null ){
|
||||
_usingDirectives = new LinkedList();
|
||||
}
|
||||
|
||||
return _usingDirectives;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDirective(org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol)
|
||||
*/
|
||||
public void addUsingDirective( IContainerSymbol namespace ) throws ParserSymbolTableException{
|
||||
if( namespace.getType() != TypeInfo.t_namespace ){
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidUsing );
|
||||
}
|
||||
|
||||
//handle namespace aliasing
|
||||
ISymbol alias = namespace.getTypeSymbol();
|
||||
if( alias != null && alias.isType( TypeInfo.t_namespace ) ){
|
||||
namespace = (IContainerSymbol) alias;
|
||||
}
|
||||
|
||||
List usingDirectives = getUsingDirectives();
|
||||
|
||||
usingDirectives.add( namespace );
|
||||
|
||||
Command command = new AddUsingDirectiveCommand( this, namespace );
|
||||
getSymbolTable().pushCommand( command );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDeclaration(java.lang.String)
|
||||
*/
|
||||
/**
|
||||
* addUsingDeclaration
|
||||
* @param obj
|
||||
* @throws ParserSymbolTableException
|
||||
*
|
||||
* 7.3.3-9 The entity declared by a using-declaration shall be known in the
|
||||
* context using it according to its definition at the point of the using-
|
||||
* declaration. Definitions added to the namespace after the using-
|
||||
* declaration are not considered when a use of the name is made.
|
||||
*
|
||||
* 7.3.3-4 A using-declaration used as a member-declaration shall refer to a
|
||||
* member of a base class of the class being defined, shall refer to a
|
||||
* member of an anonymous union that is a member of a base class of the
|
||||
* class being defined, or shall refer to an enumerator for an enumeration
|
||||
* type that is a member of a base class of the class being defined.
|
||||
*/
|
||||
public ISymbol addUsingDeclaration( String name ) throws ParserSymbolTableException {
|
||||
return addUsingDeclaration( name, null );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addUsingDeclaration(java.lang.String, org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol)
|
||||
*/
|
||||
public ISymbol addUsingDeclaration( String name, IContainerSymbol declContext ) throws ParserSymbolTableException{
|
||||
LookupData data = new LookupData( name, TypeInfo.t_any, null );
|
||||
|
||||
if( declContext != null ){
|
||||
data.qualified = true;
|
||||
data.templateInstance = declContext.getTemplateInstance();
|
||||
ParserSymbolTable.lookup( data, declContext );
|
||||
} else {
|
||||
ParserSymbolTable.lookup( data, this );
|
||||
}
|
||||
|
||||
//figure out which declaration we are talking about, if it is a set of functions,
|
||||
//then they will be in data.foundItems (since we provided no parameter info);
|
||||
ISymbol obj = null;
|
||||
try{
|
||||
obj = ParserSymbolTable.resolveAmbiguities( data );
|
||||
} catch ( ParserSymbolTableException e ) {
|
||||
if( e.reason != ParserSymbolTableException.r_UnableToResolveFunction ){
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if( data.foundItems == null ){
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidUsing );
|
||||
}
|
||||
|
||||
ISymbol clone = null;
|
||||
|
||||
//if obj != null, then that is the only object to consider, so size is 1,
|
||||
//otherwise we consider the foundItems set
|
||||
int size = ( obj == null ) ? data.foundItems.size() : 1;
|
||||
Iterator iter = data.foundItems.iterator();
|
||||
for( int i = size; i > 0; i-- ){
|
||||
obj = ( obj != null && size == 1 ) ? obj : (ISymbol) iter.next();
|
||||
|
||||
if( ParserSymbolTable.okToAddUsingDeclaration( obj, this ) ){
|
||||
clone = (BasicSymbol) obj.clone(); //7.3.3-9
|
||||
addSymbol( clone );
|
||||
} else {
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidUsing );
|
||||
}
|
||||
}
|
||||
|
||||
return ( size == 1 ) ? clone : null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#getContainedSymbols()
|
||||
*/
|
||||
public Map getContainedSymbols(){
|
||||
if( _containedSymbols == null ){
|
||||
_containedSymbols = new HashMap();
|
||||
}
|
||||
return _containedSymbols;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#elaboratedLookup(org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType, java.lang.String)
|
||||
*/
|
||||
public ISymbol elaboratedLookup( TypeInfo.eType type, String name ) throws ParserSymbolTableException{
|
||||
LookupData data = new LookupData( name, type, getTemplateInstance() );
|
||||
|
||||
ParserSymbolTable.lookup( data, this );
|
||||
|
||||
return ParserSymbolTable.resolveAmbiguities( data );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookup(java.lang.String)
|
||||
*/
|
||||
public ISymbol lookup( String name ) throws ParserSymbolTableException {
|
||||
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
|
||||
|
||||
ParserSymbolTable.lookup( data, this );
|
||||
|
||||
return ParserSymbolTable.resolveAmbiguities( data );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupMemberForDefinition(java.lang.String)
|
||||
*/
|
||||
/**
|
||||
* LookupMemberForDefinition
|
||||
* @param name
|
||||
* @return Declaration
|
||||
* @throws ParserSymbolTableException
|
||||
*
|
||||
* In a definition for a namespace member in which the declarator-id is a
|
||||
* qualified-id, given that the qualified-id for the namespace member has
|
||||
* the form "nested-name-specifier unqualified-id", the unqualified-id shall
|
||||
* name a member of the namespace designated by the nested-name-specifier.
|
||||
*
|
||||
* ie:
|
||||
* you have this:
|
||||
* namespace A{
|
||||
* namespace B{
|
||||
* void f1(int);
|
||||
* }
|
||||
* using namespace B;
|
||||
* }
|
||||
*
|
||||
* if you then do this
|
||||
* void A::f1(int) { ... } //ill-formed, f1 is not a member of A
|
||||
* but, you can do this (Assuming f1 has been defined elsewhere)
|
||||
* A::f1( 1 ); //ok, finds B::f1
|
||||
*
|
||||
* ie, We need a seperate lookup function for looking up the member names
|
||||
* for a definition.
|
||||
*/
|
||||
public ISymbol lookupMemberForDefinition( String name ) throws ParserSymbolTableException{
|
||||
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
|
||||
data.qualified = true;
|
||||
|
||||
IContainerSymbol container = this;
|
||||
|
||||
//handle namespace aliases
|
||||
if( container.isType( TypeInfo.t_namespace ) ){
|
||||
ISymbol symbol = container.getTypeSymbol();
|
||||
if( symbol != null && symbol.isType( TypeInfo.t_namespace ) ){
|
||||
container = (IContainerSymbol) symbol;
|
||||
}
|
||||
}
|
||||
|
||||
ParserSymbolTable.lookupInContained( data, container );
|
||||
|
||||
return ParserSymbolTable.resolveAmbiguities( data );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupNestedNameSpecifier(java.lang.String)
|
||||
*/
|
||||
/**
|
||||
* Method LookupNestedNameSpecifier.
|
||||
* @param name
|
||||
* @return Declaration
|
||||
* The name of a class or namespace member can be referred to after the ::
|
||||
* scope resolution operator applied to a nested-name-specifier that
|
||||
* nominates its class or namespace. During the lookup for a name preceding
|
||||
* the ::, object, function and enumerator names are ignored. If the name
|
||||
* is not a class-name or namespace-name, the program is ill-formed
|
||||
*/
|
||||
public IContainerSymbol lookupNestedNameSpecifier( String name ) throws ParserSymbolTableException {
|
||||
return lookupNestedNameSpecifier( name, this );
|
||||
}
|
||||
private IContainerSymbol lookupNestedNameSpecifier(String name, IContainerSymbol inSymbol ) throws ParserSymbolTableException{
|
||||
ISymbol foundSymbol = null;
|
||||
|
||||
LookupData data = new LookupData( name, TypeInfo.t_namespace, getTemplateInstance() );
|
||||
data.upperType = TypeInfo.t_union;
|
||||
|
||||
ParserSymbolTable.lookupInContained( data, inSymbol );
|
||||
|
||||
if( data.foundItems != null ){
|
||||
foundSymbol = (ISymbol) ParserSymbolTable.resolveAmbiguities( data );//, data.foundItems );
|
||||
}
|
||||
|
||||
if( foundSymbol == null && inSymbol.getContainingSymbol() != null ){
|
||||
foundSymbol = lookupNestedNameSpecifier( name, inSymbol.getContainingSymbol() );
|
||||
}
|
||||
|
||||
if( foundSymbol instanceof IContainerSymbol )
|
||||
return (IContainerSymbol) foundSymbol;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedLookup(java.lang.String)
|
||||
*/
|
||||
public ISymbol qualifiedLookup( String name ) throws ParserSymbolTableException{
|
||||
|
||||
return qualifiedLookup(name, TypeInfo.t_any);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedLookup(java.lang.String, org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType)
|
||||
*/
|
||||
public ISymbol qualifiedLookup( String name, TypeInfo.eType t ) throws ParserSymbolTableException{
|
||||
LookupData data = new LookupData( name, t, getTemplateInstance() );
|
||||
data.qualified = true;
|
||||
ParserSymbolTable.lookup( data, this );
|
||||
|
||||
return ParserSymbolTable.resolveAmbiguities( data );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#unqualifiedFunctionLookup(java.lang.String, java.util.List)
|
||||
*/
|
||||
/**
|
||||
* UnqualifiedFunctionLookup
|
||||
* @param name
|
||||
* @param parameters
|
||||
* @return Declaration
|
||||
* @throws ParserSymbolTableException
|
||||
*
|
||||
* 3.4.2-1 When an unqualified name is used as the post-fix expression in a
|
||||
* function call, other namespaces not consdiered during the usual
|
||||
* unqualified lookup may be searched.
|
||||
*
|
||||
* 3.4.2-2 For each argument type T in the function call, there is a set of
|
||||
* zero or more associated namespaces and a set of zero or more associated
|
||||
* classes to be considered.
|
||||
*
|
||||
* If the ordinary unqualified lookup of the name find the declaration of a
|
||||
* class member function, the associated namespaces and classes are not
|
||||
* considered. Otherwise, the set of declarations found by the lookup of
|
||||
* the function name is the union of the set of declarations found using
|
||||
* ordinary unqualified lookup and the set of declarations found in the
|
||||
* namespaces and classes associated with the argument types.
|
||||
*/
|
||||
public IParameterizedSymbol unqualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{
|
||||
//figure out the set of associated scopes first, so we can remove those that are searched
|
||||
//during the normal lookup to avoid doing them twice
|
||||
HashSet associated = new HashSet();
|
||||
|
||||
//collect associated namespaces & classes.
|
||||
int size = ( parameters == null ) ? 0 : parameters.size();
|
||||
Iterator iter = ( parameters == null ) ? null : parameters.iterator();
|
||||
|
||||
TypeInfo param = null;
|
||||
ISymbol paramType = null;
|
||||
for( int i = size; i > 0; i-- ){
|
||||
param = (TypeInfo) iter.next();
|
||||
paramType = ParserSymbolTable.getFlatTypeInfo( param ).getTypeSymbol();
|
||||
|
||||
if( paramType == null ){
|
||||
continue;
|
||||
}
|
||||
|
||||
ParserSymbolTable.getAssociatedScopes( paramType, associated );
|
||||
|
||||
//if T is a pointer to a data member of class X, its associated namespaces and classes
|
||||
//are those associated with the member type together with those associated with X
|
||||
if( param.hasPtrOperators() && param.getPtrOperators().size() == 1 ){
|
||||
TypeInfo.PtrOp op = (TypeInfo.PtrOp)param.getPtrOperators().iterator().next();
|
||||
if( op.getType() == TypeInfo.PtrOp.t_pointer &&
|
||||
paramType.getContainingSymbol().isType( TypeInfo.t_class, TypeInfo.t_union ) )
|
||||
{
|
||||
ParserSymbolTable.getAssociatedScopes( paramType.getContainingSymbol(), associated );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
|
||||
//if parameters == null, thats no parameters, but we need to distinguish that from
|
||||
//no parameter information at all, so make an empty list.
|
||||
data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
|
||||
data.associated = associated;
|
||||
|
||||
ParserSymbolTable.lookup( data, this );
|
||||
|
||||
ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
|
||||
|
||||
//if we haven't found anything, or what we found is not a class member, consider the
|
||||
//associated scopes
|
||||
if( found == null || found.getContainingSymbol().getType() != TypeInfo.t_class ){
|
||||
if( found != null ){
|
||||
data.foundItems.add( found );
|
||||
}
|
||||
|
||||
IContainerSymbol associatedScope;
|
||||
//dump the hash to an array and iterate over the array because we
|
||||
//could be removing items from the collection as we go and we don't
|
||||
//want to get ConcurrentModificationExceptions
|
||||
Object [] scopes = associated.toArray();
|
||||
|
||||
size = associated.size();
|
||||
|
||||
for( int i = 0; i < size; i++ ){
|
||||
associatedScope = (IContainerSymbol) scopes[ i ];
|
||||
if( associated.contains( associatedScope ) ){
|
||||
data.qualified = true;
|
||||
data.ignoreUsingDirectives = true;
|
||||
ParserSymbolTable.lookup( data, associatedScope );
|
||||
}
|
||||
}
|
||||
|
||||
found = ParserSymbolTable.resolveAmbiguities( data );
|
||||
}
|
||||
|
||||
if( found instanceof IParameterizedSymbol )
|
||||
return (IParameterizedSymbol) found;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#memberFunctionLookup(java.lang.String, java.util.List)
|
||||
*/
|
||||
/**
|
||||
* MemberFunctionLookup
|
||||
* @param name
|
||||
* @param parameters
|
||||
* @return Declaration
|
||||
* @throws ParserSymbolTableException
|
||||
*
|
||||
* Member lookup really proceeds as an unqualified lookup, but doesn't
|
||||
* include argument dependant scopes
|
||||
*/
|
||||
public IParameterizedSymbol memberFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{
|
||||
LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
|
||||
//if parameters == null, thats no parameters, but we need to distinguish that from
|
||||
//no parameter information at all, so make an empty list.
|
||||
data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
|
||||
|
||||
ParserSymbolTable.lookup( data, (IContainerSymbol) this );
|
||||
return (IParameterizedSymbol) ParserSymbolTable.resolveAmbiguities( data );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#qualifiedFunctionLookup(java.lang.String, java.util.List)
|
||||
*/
|
||||
public IParameterizedSymbol qualifiedFunctionLookup( String name, List parameters ) throws ParserSymbolTableException{
|
||||
LookupData data = new LookupData( name, TypeInfo.t_function, getTemplateInstance() );
|
||||
data.qualified = true;
|
||||
//if parameters == null, thats no parameters, but we need to distinguish that from
|
||||
//no parameter information at all, so make an empty list.
|
||||
data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
|
||||
|
||||
ParserSymbolTable.lookup( data, (IContainerSymbol)this );
|
||||
|
||||
return (IParameterizedSymbol) ParserSymbolTable.resolveAmbiguities( data );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#templateLookup(java.lang.String, java.util.List)
|
||||
*/
|
||||
public TemplateInstance templateLookup( String name, List arguments ) throws ParserSymbolTableException
|
||||
{
|
||||
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
|
||||
data.parameters = arguments;
|
||||
|
||||
ParserSymbolTable.lookup( data, (IContainerSymbol) this );
|
||||
ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
|
||||
if( found.isType( TypeInfo.t_template ) ){
|
||||
return ((IParameterizedSymbol) found).instantiate( arguments );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#instantiate(java.util.List)
|
||||
*/
|
||||
public TemplateInstance instantiate( List arguments ) throws ParserSymbolTableException{
|
||||
if( getType() != TypeInfo.t_template ){
|
||||
return null;
|
||||
}
|
||||
|
||||
//TODO uncomment when template specialization matching & ordering is working
|
||||
//IParameterizedSymbol template = ParserSymbolTable.matchTemplatePartialSpecialization( this, arguments );
|
||||
IParameterizedSymbol template = null;
|
||||
|
||||
if( template == null ){
|
||||
template = (IParameterizedSymbol) this;
|
||||
}
|
||||
|
||||
List paramList = template.getParameterList();
|
||||
int numParams = ( paramList != null ) ? paramList.size() : 0;
|
||||
|
||||
if( numParams == 0 ){
|
||||
return null;
|
||||
}
|
||||
|
||||
HashMap map = new HashMap();
|
||||
Iterator paramIter = paramList.iterator();
|
||||
Iterator argIter = arguments.iterator();
|
||||
|
||||
ISymbol param = null;
|
||||
TypeInfo arg = null;
|
||||
for( int i = 0; i < numParams; i++ ){
|
||||
param = (ISymbol) paramIter.next();
|
||||
|
||||
if( argIter.hasNext() ){
|
||||
arg = (TypeInfo) argIter.next();
|
||||
map.put( param, arg );
|
||||
} else {
|
||||
Object obj = param.getTypeInfo().getDefault();
|
||||
if( obj != null && obj instanceof TypeInfo ){
|
||||
map.put( param, obj );
|
||||
} else {
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( template.getContainedSymbols().size() != 1 ){
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
|
||||
}
|
||||
|
||||
Iterator iter = template.getContainedSymbols().keySet().iterator();
|
||||
IContainerSymbol symbol = (IContainerSymbol) template.getContainedSymbols().get( iter.next() );
|
||||
|
||||
TemplateInstance instance = new TemplateInstance( getSymbolTable(), symbol, map );
|
||||
return instance;
|
||||
}
|
||||
|
||||
static private class AddSymbolCommand extends Command{
|
||||
AddSymbolCommand( ISymbol newDecl, IContainerSymbol context ){
|
||||
_symbol = newDecl;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public void undoIt(){
|
||||
Object obj = _context.getContainedSymbols().get( _symbol.getName() );
|
||||
|
||||
if( obj instanceof LinkedList ){
|
||||
LinkedList list = (LinkedList)obj;
|
||||
ListIterator iter = list.listIterator();
|
||||
int size = list.size();
|
||||
ISymbol item = null;
|
||||
for( int i = 0; i < size; i++ ){
|
||||
item = (ISymbol)iter.next();
|
||||
if( item == _symbol ){
|
||||
iter.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( list.size() == 1 ){
|
||||
_context.getContainedSymbols().remove( _symbol.getName() );
|
||||
_context.getContainedSymbols().put( _symbol.getName(), list.getFirst() );
|
||||
}
|
||||
} else if( obj instanceof BasicSymbol ){
|
||||
_context.getContainedSymbols().remove( _symbol.getName() );
|
||||
}
|
||||
// if( _removeThis && _symbol instanceof IParameterizedSymbol ){
|
||||
// ((IParameterizedSymbol)_symbol).getContainedSymbols().remove( ParserSymbolTable.THIS );
|
||||
// }
|
||||
}
|
||||
|
||||
private ISymbol _symbol;
|
||||
private IContainerSymbol _context;
|
||||
}
|
||||
|
||||
static private class AddUsingDirectiveCommand extends Command{
|
||||
public AddUsingDirectiveCommand( IContainerSymbol container, IContainerSymbol namespace ){
|
||||
_decl = container;
|
||||
_namespace = namespace;
|
||||
}
|
||||
public void undoIt(){
|
||||
_decl.getUsingDirectives().remove( _namespace );
|
||||
}
|
||||
private IContainerSymbol _decl;
|
||||
private IContainerSymbol _namespace;
|
||||
}
|
||||
|
||||
private LinkedList _usingDirectives; //collection of nominated namespaces
|
||||
private HashMap _containedSymbols; //declarations contained by us.
|
||||
|
||||
}
|
|
@ -0,0 +1,357 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2003 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v0.5
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v05.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corp. - Rational Software - initial implementation
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Created on Nov 6, 2003
|
||||
*/
|
||||
|
||||
package org.eclipse.cdt.internal.core.parser.pst;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Command;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.LookupData;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*
|
||||
* To change the template for this generated type comment go to
|
||||
* Window>Preferences>Java>Code Generation>Code and Comments
|
||||
*/
|
||||
public class DerivableContainerSymbol extends ContainerSymbol implements IDerivableContainerSymbol {
|
||||
|
||||
protected DerivableContainerSymbol( ParserSymbolTable table, String name ){
|
||||
super( table, name );
|
||||
}
|
||||
|
||||
protected DerivableContainerSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
|
||||
super( table, name, obj );
|
||||
}
|
||||
|
||||
protected DerivableContainerSymbol( ParserSymbolTable table, String name, TypeInfo.eType typeInfo ){
|
||||
super( table, name, typeInfo );
|
||||
}
|
||||
|
||||
|
||||
public Object clone(){
|
||||
DerivableContainerSymbol copy = (DerivableContainerSymbol)super.clone();
|
||||
|
||||
copy._parentScopes = ( _parentScopes != null ) ? (LinkedList) _parentScopes.clone() : null;
|
||||
copy._constructors = ( _constructors != null ) ? (LinkedList) _constructors.clone() : null;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
public void addSymbol(ISymbol symbol) throws ParserSymbolTableException {
|
||||
super.addSymbol( symbol );
|
||||
|
||||
//take care of the this pointer
|
||||
if( symbol instanceof IParameterizedSymbol ){
|
||||
addThis( (IParameterizedSymbol) symbol );
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#addParent(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
|
||||
*/
|
||||
public void addParent( ISymbol parent ){
|
||||
addParent( parent, false, ASTAccessVisibility.PUBLIC, -1, null );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#addParent(org.eclipse.cdt.internal.core.parser.pst.ISymbol, boolean, org.eclipse.cdt.core.parser.ast.ASTAccessVisibility, int, java.util.List)
|
||||
*/
|
||||
public void addParent( ISymbol parent, boolean virtual, ASTAccessVisibility visibility, int offset, List references ){
|
||||
if( _parentScopes == null ){
|
||||
_parentScopes = new LinkedList();
|
||||
}
|
||||
|
||||
ParentWrapper wrapper = new ParentWrapper( parent, virtual, visibility, offset, references );
|
||||
_parentScopes.add( wrapper );
|
||||
|
||||
Command command = new AddParentCommand( this, wrapper );
|
||||
getSymbolTable().pushCommand( command );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#getParents()
|
||||
*/
|
||||
public List getParents(){
|
||||
if( _parentScopes == null ){
|
||||
_parentScopes = new LinkedList();
|
||||
}
|
||||
return _parentScopes;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#hasParents()
|
||||
*/
|
||||
public boolean hasParents(){
|
||||
return ( _parentScopes != null && !_parentScopes.isEmpty() );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#addConstructor(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
|
||||
*/
|
||||
public void addConstructor(IParameterizedSymbol constructor) throws ParserSymbolTableException {
|
||||
if( !constructor.isType( TypeInfo.t_constructor ) )
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
|
||||
|
||||
List constructors = getConstructors();
|
||||
|
||||
if( constructors.size() == 0 || ParserSymbolTable.isValidOverload( constructors, constructor ) ){
|
||||
constructors.add( constructor );
|
||||
} else {
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidOverload );
|
||||
}
|
||||
|
||||
constructor.setContainingSymbol( this );
|
||||
addThis( constructor );
|
||||
|
||||
Command command = new AddConstructorCommand( constructor, this );
|
||||
getSymbolTable().pushCommand( command );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#addCopyConstructor()
|
||||
*/
|
||||
public void addCopyConstructor() throws ParserSymbolTableException{
|
||||
List parameters = new LinkedList();
|
||||
|
||||
TypeInfo param = new TypeInfo( TypeInfo.t_type, 0, this, new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference, true, false ), false );
|
||||
parameters.add( param );
|
||||
|
||||
IParameterizedSymbol constructor = lookupConstructor( parameters );
|
||||
|
||||
if( constructor == null ){
|
||||
constructor = getSymbolTable().newParameterizedSymbol( getName(), TypeInfo.t_constructor );
|
||||
constructor.addParameter( this, new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference, true, false ), false );
|
||||
addConstructor( constructor );
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#lookupConstructor(java.util.List)
|
||||
*/
|
||||
public IParameterizedSymbol lookupConstructor( List parameters ) throws ParserSymbolTableException
|
||||
{
|
||||
LookupData data = new LookupData( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_constructor, null );
|
||||
data.parameters = parameters;
|
||||
|
||||
List constructors = new LinkedList();
|
||||
if( !getConstructors().isEmpty() )
|
||||
constructors.addAll( getConstructors() );
|
||||
|
||||
return ParserSymbolTable.resolveFunction( data, constructors );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol#getConstructors()
|
||||
*/
|
||||
public List getConstructors(){
|
||||
if( _constructors == null ){
|
||||
_constructors = new LinkedList();
|
||||
}
|
||||
return _constructors;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param obj
|
||||
* @throws ParserSymbolTableException
|
||||
* 9.3.2-1 In the body of a nonstatic member function... the type of this of
|
||||
* a class X is X*. If the member function is declared const, the type of
|
||||
* this is const X*, if the member function is declared volatile, the type
|
||||
* of this is volatile X*....
|
||||
*/
|
||||
private boolean addThis( IParameterizedSymbol obj ){
|
||||
if( getSymbolTable().getLanguage() != ParserLanguage.CPP ){
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeInfo type = obj.getTypeInfo();
|
||||
if( ( !type.isType( TypeInfo.t_function ) && !type.isType( TypeInfo.t_constructor) ) ||
|
||||
type.checkBit( TypeInfo.isStatic ) ){
|
||||
return false;
|
||||
}
|
||||
|
||||
if( obj.getContainingSymbol().isType( TypeInfo.t_class, TypeInfo.t_union ) ){
|
||||
//check to see if there is already a this object, since using declarations
|
||||
//of function will have them from the original declaration
|
||||
LookupData data = new LookupData( ParserSymbolTable.THIS, TypeInfo.t_any, null );
|
||||
ParserSymbolTable.lookupInContained( data, obj );
|
||||
//if we didn't find "this" then foundItems will still be null, no need to actually
|
||||
//check its contents
|
||||
if( data.foundItems == null ){
|
||||
ISymbol thisObj = getSymbolTable().newSymbol( ParserSymbolTable.THIS, TypeInfo.t_type );
|
||||
thisObj.setTypeSymbol( obj.getContainingSymbol() );
|
||||
//thisObj.setCVQualifier( obj.getCVQualifier() );
|
||||
TypeInfo.PtrOp ptr = new TypeInfo.PtrOp();
|
||||
ptr.setType( TypeInfo.PtrOp.t_pointer );
|
||||
if( obj.getTypeInfo().hasPtrOperators() ){
|
||||
ptr.setConst( ((TypeInfo.PtrOp) obj.getPtrOperators().iterator().next()).isConst() );
|
||||
ptr.setVolatile( ((TypeInfo.PtrOp) obj.getPtrOperators().iterator().next()).isVolatile() );
|
||||
}
|
||||
|
||||
thisObj.addPtrOperator(ptr);
|
||||
|
||||
try{
|
||||
obj.addSymbol( thisObj );
|
||||
} catch ( ParserSymbolTableException e ) {
|
||||
//shouldn't happen because we checked that "this" didn't exist already
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name
|
||||
* @return Declaration
|
||||
* @throws ParserSymbolTableException
|
||||
*
|
||||
* 7.3.1.2-3 If a friend declaration in a non-local class first declares a
|
||||
* class or function, the friend class or function is a member of the
|
||||
* innermost enclosing namespace.
|
||||
*
|
||||
* TODO: if/when the parser symbol table starts caring about visibility
|
||||
* (public/protected/private) we will need to do more to record friendship.
|
||||
*/
|
||||
private ISymbol addFriend( String name ) throws ParserSymbolTableException{
|
||||
ISymbol friend = lookupForFriendship( name );
|
||||
|
||||
if( friend == null ){
|
||||
friend = getSymbolTable().newSymbol( name );
|
||||
friend.getTypeInfo().setIsForwardDeclaration( true );
|
||||
|
||||
IContainerSymbol containing = getContainingSymbol();
|
||||
//find innermost enclosing namespace
|
||||
while( containing != null && containing.getType() != TypeInfo.t_namespace ){
|
||||
containing = containing.getContainingSymbol();
|
||||
}
|
||||
|
||||
IContainerSymbol namespace = ( containing == null ) ? getSymbolTable().getCompilationUnit() : containing;
|
||||
namespace.addSymbol( friend );
|
||||
}
|
||||
|
||||
return friend;
|
||||
}
|
||||
|
||||
/**
|
||||
* LookupForFriendship
|
||||
* @param name
|
||||
* @return Declaration
|
||||
* 7.3.1.2-3 When looking for a prior declaration of a class or a function
|
||||
* declared as a friend, scopes outside the innermost enclosing namespace
|
||||
* scope are not considered.
|
||||
* 11.4-9 If a friend declaration appears in a local class and the name
|
||||
* specified is an unqualified name, a prior declaration is looked up
|
||||
* without considering scopes that are outside the innermost enclosing non-
|
||||
* class scope.
|
||||
*/
|
||||
private ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException{
|
||||
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
|
||||
|
||||
boolean inClass = ( getType() == TypeInfo.t_class);
|
||||
|
||||
IContainerSymbol enclosing = getContainingSymbol();
|
||||
while( enclosing != null && (inClass ? enclosing.getType() != TypeInfo.t_class
|
||||
: enclosing.getType() == TypeInfo.t_namespace) )
|
||||
{
|
||||
enclosing = enclosing.getContainingSymbol();
|
||||
}
|
||||
|
||||
data.stopAt = enclosing;
|
||||
|
||||
ParserSymbolTable.lookup( data, this );
|
||||
return ParserSymbolTable.resolveAmbiguities( data );
|
||||
}
|
||||
|
||||
|
||||
static private class AddParentCommand extends Command{
|
||||
public AddParentCommand( IDerivableContainerSymbol container, ParentWrapper wrapper ){
|
||||
_decl = container;
|
||||
_wrapper = wrapper;
|
||||
}
|
||||
|
||||
public void undoIt(){
|
||||
List parents = _decl.getParents();
|
||||
parents.remove( _wrapper );
|
||||
}
|
||||
|
||||
private IDerivableContainerSymbol _decl;
|
||||
private ParentWrapper _wrapper;
|
||||
}
|
||||
|
||||
static private class AddConstructorCommand extends Command{
|
||||
AddConstructorCommand( IParameterizedSymbol newConstr, IDerivableContainerSymbol context ){
|
||||
_constructor = newConstr;
|
||||
_context = context;
|
||||
}
|
||||
public void undoIt(){
|
||||
List constructors = _context.getConstructors();
|
||||
ListIterator iter = constructors.listIterator();
|
||||
|
||||
int size = constructors.size();
|
||||
IParameterizedSymbol item = null;
|
||||
for( int i = 0; i < size; i++ ){
|
||||
item = (IParameterizedSymbol)iter.next();
|
||||
if( item == _constructor ){
|
||||
iter.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IParameterizedSymbol _constructor;
|
||||
private IDerivableContainerSymbol _context;
|
||||
}
|
||||
|
||||
public class ParentWrapper implements IDerivableContainerSymbol.IParentSymbol
|
||||
{
|
||||
public ParentWrapper( ISymbol p, boolean v, ASTAccessVisibility s, int offset, List r ){
|
||||
parent = p;
|
||||
isVirtual = v;
|
||||
access = s;
|
||||
this.offset = offset;
|
||||
this.references = r;
|
||||
}
|
||||
|
||||
public void setParent( ISymbol parent ){ this.parent = parent; }
|
||||
|
||||
public ISymbol getParent() { return parent; }
|
||||
public boolean isVirtual() { return isVirtual; }
|
||||
|
||||
public void setVirtual( boolean virtual ){ isVirtual = virtual; }
|
||||
|
||||
public ASTAccessVisibility getVisibility(){ return access; }
|
||||
public ASTAccessVisibility getAccess() { return access; }
|
||||
|
||||
public int getOffset() { return offset; }
|
||||
public List getReferences() { return references; }
|
||||
|
||||
private boolean isVirtual = false;
|
||||
protected ISymbol parent = null;
|
||||
private final ASTAccessVisibility access;
|
||||
private final int offset;
|
||||
private final List references;
|
||||
}
|
||||
|
||||
private LinkedList _constructors; //constructor list
|
||||
private LinkedList _parentScopes; //inherited scopes (is base classes)
|
||||
}
|
|
@ -19,7 +19,6 @@ package org.eclipse.cdt.internal.core.parser.pst;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
|
|
|
@ -43,6 +43,10 @@ public interface IDerivableContainerSymbol extends IContainerSymbol {
|
|||
public ISymbol getParent();
|
||||
public boolean isVirtual();
|
||||
public void setVirtual( boolean virtual );
|
||||
|
||||
public ASTAccessVisibility getVisibility();
|
||||
public ASTAccessVisibility getAccess();
|
||||
public int getOffset();
|
||||
public List getReferences();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,11 +34,11 @@ public interface IParameterizedSymbol extends IContainerSymbol {
|
|||
|
||||
public void addArgument( ISymbol arg );
|
||||
public List getArgumentList();
|
||||
public void setArgumentList( List list );
|
||||
//public void setArgumentList( List list );
|
||||
|
||||
public Map getParameterMap();
|
||||
public List getParameterList();
|
||||
public void setParameterList( List list );
|
||||
//public void setParameterList( List list );
|
||||
|
||||
public boolean hasSameParameters(IParameterizedSymbol newDecl);
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.parser.pst;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
|
||||
/**
|
||||
* @author jcamelon
|
||||
*
|
||||
|
|
|
@ -0,0 +1,282 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2003 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v0.5
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v05.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corp. - Rational Software - initial implementation
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Created on Nov 6, 2003
|
||||
*/
|
||||
package org.eclipse.cdt.internal.core.parser.pst;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Command;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*
|
||||
* To change the template for this generated type comment go to
|
||||
* Window>Preferences>Java>Code Generation>Code and Comments
|
||||
*/
|
||||
public class ParameterizedSymbol extends ContainerSymbol implements IParameterizedSymbol {
|
||||
|
||||
protected ParameterizedSymbol( ParserSymbolTable table, String name ){
|
||||
super( table, name );
|
||||
}
|
||||
|
||||
protected ParameterizedSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
|
||||
super( table, name, obj );
|
||||
}
|
||||
|
||||
protected ParameterizedSymbol( ParserSymbolTable table, String name, TypeInfo.eType typeInfo ){
|
||||
super( table, name, typeInfo );
|
||||
}
|
||||
|
||||
public Object clone(){
|
||||
ParameterizedSymbol copy = (ParameterizedSymbol)super.clone();
|
||||
|
||||
copy._parameterList = ( _parameterList != null ) ? (LinkedList) _parameterList.clone() : null;
|
||||
copy._parameterMap = ( _parameterMap != null ) ? (HashMap) _parameterMap.clone() : null;
|
||||
|
||||
copy._argumentList = ( _argumentList != null ) ? (LinkedList) _argumentList.clone() : null;
|
||||
copy._specializations = ( _specializations != null ) ? (LinkedList) _specializations.clone() : null;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
|
||||
*/
|
||||
public void addParameter( ISymbol param ){
|
||||
List paramList = getParameterList();
|
||||
|
||||
paramList.add( param );
|
||||
|
||||
String name = param.getName();
|
||||
if( name != null && !name.equals(ParserSymbolTable.EMPTY_NAME) )
|
||||
{
|
||||
Map paramMap = getParameterMap();
|
||||
|
||||
if( !paramMap.containsKey( name ) )
|
||||
paramMap.put( name, param );
|
||||
}
|
||||
|
||||
param.setContainingSymbol( this );
|
||||
param.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
|
||||
|
||||
Command command = new AddParameterCommand( this, (BasicSymbol)param );
|
||||
getSymbolTable().pushCommand( command );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType, int, org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp, boolean)
|
||||
*/
|
||||
public void addParameter( TypeInfo.eType type, int info, TypeInfo.PtrOp ptrOp, boolean hasDefault ){
|
||||
BasicSymbol param = new BasicSymbol(getSymbolTable(), ParserSymbolTable.EMPTY_NAME);
|
||||
|
||||
TypeInfo t = param.getTypeInfo();
|
||||
t.setTypeInfo( info );
|
||||
t.setType( type );
|
||||
t.addPtrOperator( ptrOp );
|
||||
t.setHasDefault( hasDefault );
|
||||
|
||||
addParameter( param );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol, org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp, boolean)
|
||||
*/
|
||||
public void addParameter( ISymbol typeSymbol, TypeInfo.PtrOp ptrOp, boolean hasDefault ){
|
||||
BasicSymbol param = new BasicSymbol(getSymbolTable(), ParserSymbolTable.EMPTY_NAME);
|
||||
|
||||
TypeInfo info = param.getTypeInfo();
|
||||
info.setType( TypeInfo.t_type );
|
||||
info.setTypeSymbol( typeSymbol );
|
||||
info.addPtrOperator( ptrOp );
|
||||
info.setHasDefault( hasDefault );
|
||||
|
||||
addParameter( param );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addArgument(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
|
||||
*/
|
||||
public void addArgument( ISymbol arg ){
|
||||
List argumentList = getArgumentList();
|
||||
argumentList.add( arg );
|
||||
|
||||
arg.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
|
||||
|
||||
Command command = new AddArgumentCommand( this, (BasicSymbol) arg );
|
||||
getSymbolTable().pushCommand( command );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getArgumentList()
|
||||
*/
|
||||
public List getArgumentList(){
|
||||
if( _argumentList == null ){
|
||||
_argumentList = new LinkedList();
|
||||
}
|
||||
return _argumentList;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#setArgumentList(java.util.List)
|
||||
*/
|
||||
// public void setArgumentList( List list ){
|
||||
// _argumentList = new LinkedList( list );
|
||||
// }
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterMap()
|
||||
*/
|
||||
public Map getParameterMap(){
|
||||
if( _parameterMap == null ){
|
||||
_parameterMap = new HashMap();
|
||||
}
|
||||
return _parameterMap;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getParameterList()
|
||||
*/
|
||||
public List getParameterList(){
|
||||
if( _parameterList == null ){
|
||||
_parameterList = new LinkedList();
|
||||
}
|
||||
return _parameterList;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#setParameterList(java.util.List)
|
||||
*/
|
||||
// public void setParameterList( List list ){
|
||||
// _parameterList = new LinkedList( list );
|
||||
// }
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasSameParameters(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
|
||||
*/
|
||||
public boolean hasSameParameters( IParameterizedSymbol function ){
|
||||
if( function.getType() != getType() ){
|
||||
return false;
|
||||
}
|
||||
|
||||
int size = ( getParameterList() == null ) ? 0 : getParameterList().size();
|
||||
int fsize = ( function.getParameterList() == null ) ? 0 : function.getParameterList().size();
|
||||
if( fsize != size ){
|
||||
return false;
|
||||
}
|
||||
if( fsize == 0 )
|
||||
return true;
|
||||
|
||||
Iterator iter = getParameterList().iterator();
|
||||
Iterator fIter = function.getParameterList().iterator();
|
||||
|
||||
TypeInfo info = null;
|
||||
TypeInfo fInfo = null;
|
||||
|
||||
for( int i = size; i > 0; i-- ){
|
||||
info = ((BasicSymbol)iter.next()).getTypeInfo();
|
||||
fInfo = ((BasicSymbol) fIter.next()).getTypeInfo();
|
||||
|
||||
if( !info.equals( fInfo ) ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#setReturnType(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
|
||||
*/
|
||||
public void setReturnType( ISymbol type ){
|
||||
_returnType = type;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getReturnType()
|
||||
*/
|
||||
public ISymbol getReturnType(){
|
||||
return _returnType;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#hasSpecializations()
|
||||
*/
|
||||
public boolean hasSpecializations(){
|
||||
return ( _specializations != null && !_specializations.isEmpty() );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addSpecialization(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
|
||||
*/
|
||||
public void addSpecialization( IParameterizedSymbol spec ){
|
||||
List specializationList = getSpecializations();
|
||||
specializationList.add( spec );
|
||||
|
||||
spec.setContainingSymbol( getContainingSymbol() );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#getSpecializations()
|
||||
*/
|
||||
public List getSpecializations() {
|
||||
if( _specializations == null ){
|
||||
_specializations = new LinkedList();
|
||||
}
|
||||
return _specializations;
|
||||
}
|
||||
|
||||
|
||||
static private class AddParameterCommand extends Command{
|
||||
public AddParameterCommand( IParameterizedSymbol container, ISymbol parameter ){
|
||||
_decl = container;
|
||||
_param = parameter;
|
||||
}
|
||||
|
||||
public void undoIt(){
|
||||
_decl.getParameterList().remove( _param );
|
||||
|
||||
String name = _param.getName();
|
||||
if( name != null && !name.equals( ParserSymbolTable.EMPTY_NAME) )
|
||||
{
|
||||
_decl.getParameterMap().remove( name );
|
||||
}
|
||||
}
|
||||
|
||||
private IParameterizedSymbol _decl;
|
||||
private ISymbol _param;
|
||||
}
|
||||
|
||||
static private class AddArgumentCommand extends Command{
|
||||
public AddArgumentCommand( IParameterizedSymbol container, ISymbol arg ){
|
||||
_decl = container;
|
||||
_arg = arg;
|
||||
}
|
||||
public void undoIt(){
|
||||
_decl.getArgumentList().remove( _arg );
|
||||
}
|
||||
|
||||
private IParameterizedSymbol _decl;
|
||||
private ISymbol _arg;
|
||||
}
|
||||
|
||||
private LinkedList _parameterList; //have my cake
|
||||
private HashMap _parameterMap; //and eat it too
|
||||
private LinkedList _specializations; //template specializations
|
||||
private LinkedList _argumentList; //template specialization arguments
|
||||
private ISymbol _returnType;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2003 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v0.5
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v05.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corp. - Rational Software - initial implementation
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Created on Nov 6, 2003
|
||||
*/
|
||||
package org.eclipse.cdt.internal.core.parser.pst;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*
|
||||
* To change the template for this generated type comment go to
|
||||
* Window>Preferences>Java>Code Generation>Code and Comments
|
||||
*/
|
||||
public class SpecializedSymbol extends ParameterizedSymbol implements ISpecializedSymbol {
|
||||
protected SpecializedSymbol( ParserSymbolTable table, String name ){
|
||||
super( table, name, TypeInfo.t_template );
|
||||
}
|
||||
|
||||
protected SpecializedSymbol( ParserSymbolTable table, String name, ISymbolASTExtension obj ){
|
||||
super( table, name, obj );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2003 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v0.5
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v05.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corp. - Rational Software - initial implementation
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Created on Nov 6, 2003
|
||||
*/
|
||||
package org.eclipse.cdt.internal.core.parser.pst;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class TemplateInstance extends BasicSymbol
|
||||
{
|
||||
private final ParserSymbolTable _table;
|
||||
|
||||
protected TemplateInstance( ParserSymbolTable table, ISymbol symbol, Map argMap ){
|
||||
super(table, ParserSymbolTable.EMPTY_NAME );
|
||||
this._table = table;
|
||||
_instantiatedSymbol = symbol;
|
||||
symbol.setTemplateInstance( this );
|
||||
_argumentMap = argMap;
|
||||
}
|
||||
|
||||
public boolean equals( Object t ){
|
||||
if( t == null || !( t instanceof TemplateInstance ) ){
|
||||
return false;
|
||||
}
|
||||
|
||||
TemplateInstance instance = (TemplateInstance) t;
|
||||
|
||||
if( _instantiatedSymbol != instance._instantiatedSymbol ){
|
||||
return false;
|
||||
}
|
||||
|
||||
//check arg map
|
||||
Iterator iter1 = _argumentMap.keySet().iterator();
|
||||
Iterator iter2 = instance._argumentMap.keySet().iterator();
|
||||
int size = _argumentMap.size();
|
||||
int size2 = instance._argumentMap.size();
|
||||
ISymbol t1 = null, t2 = null;
|
||||
if( size == size2 ){
|
||||
for( int i = size; i > 0; i-- ){
|
||||
t1 = (ISymbol)iter1.next();
|
||||
t2 = (ISymbol)iter2.next();
|
||||
if( t1 != t2 || !_argumentMap.get(t1).equals( instance._argumentMap.get(t2) ) ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ISymbol getInstantiatedSymbol(){
|
||||
_instantiatedSymbol.setTemplateInstance( this );
|
||||
return _instantiatedSymbol;
|
||||
}
|
||||
|
||||
public TypeInfo.eType getType(){
|
||||
ISymbol symbol = _instantiatedSymbol;
|
||||
TypeInfo.eType returnType = _instantiatedSymbol.getType();
|
||||
if( returnType == TypeInfo.t_type ){
|
||||
symbol = symbol.getTypeSymbol();
|
||||
TypeInfo info = null;
|
||||
while( symbol != null && symbol.getType() == TypeInfo.t_undef && symbol.getContainingSymbol().getType() == TypeInfo.t_template ){
|
||||
info = (TypeInfo) _argumentMap.get( symbol );
|
||||
if( !info.isType( TypeInfo.t_type ) ){
|
||||
break;
|
||||
}
|
||||
symbol = info.getTypeSymbol();
|
||||
}
|
||||
|
||||
return ( info != null ) ? info.getType() : TypeInfo.t_type;
|
||||
}
|
||||
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public boolean isType( TypeInfo.eType type ){
|
||||
return ( type == TypeInfo.t_any || getType() == type );
|
||||
}
|
||||
|
||||
public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType ){
|
||||
if( type == TypeInfo.t_any )
|
||||
return true;
|
||||
|
||||
if( upperType == TypeInfo.t_undef ){
|
||||
return ( getType() == type );
|
||||
} else {
|
||||
return ( getType().compareTo( type ) >= 0 && getType().compareTo( upperType ) <= 0 );
|
||||
}
|
||||
}
|
||||
|
||||
public ISymbol getTypeSymbol(){
|
||||
ISymbol symbol = _instantiatedSymbol.getTypeSymbol();
|
||||
if( symbol != null && symbol.getType() == TypeInfo.t_undef &&
|
||||
symbol.getContainingSymbol().getType() == TypeInfo.t_template )
|
||||
{
|
||||
TypeInfo info = (TypeInfo) _argumentMap.get( symbol );
|
||||
return ( info != null ) ? info.getTypeSymbol() : null;
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public TypeInfo getTypeInfo(){
|
||||
ISymbol symbol = _instantiatedSymbol.getTypeSymbol();
|
||||
if( symbol != null && symbol.getType() == TypeInfo.t_undef &&
|
||||
symbol.getContainingSymbol().getType() == TypeInfo.t_template )
|
||||
{
|
||||
TypeInfo info = (TypeInfo) _argumentMap.get( symbol );
|
||||
return info;
|
||||
}
|
||||
|
||||
return _instantiatedSymbol.getTypeInfo();
|
||||
}
|
||||
|
||||
public Map getArgumentMap(){
|
||||
return _argumentMap;
|
||||
}
|
||||
|
||||
|
||||
private ISymbol _instantiatedSymbol;
|
||||
//private LinkedList _arguments;
|
||||
private Map _argumentMap;
|
||||
}
|
|
@ -16,7 +16,6 @@ import java.util.List;
|
|||
import java.util.ListIterator;
|
||||
|
||||
import org.eclipse.cdt.core.parser.Enum;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance;
|
||||
|
||||
|
||||
public class TypeInfo {
|
||||
|
@ -316,17 +315,38 @@ public class TypeInfo {
|
|||
}
|
||||
|
||||
public List getPtrOperators(){
|
||||
if( _ptrOperators == null ){
|
||||
_ptrOperators = new LinkedList();
|
||||
}
|
||||
return _ptrOperators;
|
||||
}
|
||||
|
||||
public boolean hasSamePtrs( TypeInfo type ){
|
||||
int size = hasPtrOperators() ? getPtrOperators().size() : 0;
|
||||
int size2 = type.hasPtrOperators() ? type.getPtrOperators().size() : 0;
|
||||
int size = getPtrOperators().size();
|
||||
int size2 = type.getPtrOperators().size();
|
||||
Iterator iter1 = getPtrOperators().iterator();
|
||||
Iterator iter2 = type.getPtrOperators().iterator();
|
||||
TypeInfo.PtrOp ptr1 = null, ptr2 = null;
|
||||
if( size2 < size ) {
|
||||
for( int i = size; i > size2; i-- ){
|
||||
ptr2 = (PtrOp) iter1.next();
|
||||
if( ptr2.getType() != PtrOp.t_undef ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
size = size2;
|
||||
} else if ( size < size2 ){
|
||||
for( int i = size2; i > size; i-- ){
|
||||
ptr1 = (PtrOp)iter2.next();
|
||||
if( ptr1.getType() != PtrOp.t_undef ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
size2 = size;
|
||||
}
|
||||
|
||||
if( size == size2 ){
|
||||
if( size > 0 ){
|
||||
Iterator iter1 = getPtrOperators().iterator();
|
||||
Iterator iter2 = type.getPtrOperators().iterator();
|
||||
TypeInfo.PtrOp ptr1 = null, ptr2 = null;
|
||||
for( int i = size; i > 0; i-- ){
|
||||
ptr1 = (TypeInfo.PtrOp)iter1.next();
|
||||
ptr2 = (TypeInfo.PtrOp)iter2.next();
|
||||
|
@ -336,11 +356,14 @@ public class TypeInfo {
|
|||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List getOperatorExpressions(){
|
||||
if( _operatorExpressions == null ){
|
||||
_operatorExpressions = new LinkedList();
|
||||
}
|
||||
return _operatorExpressions;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue