Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Camelon2003-11-20 15:23:01 +0000
committerJohn Camelon2003-11-20 15:23:01 +0000
commitfcfd56c2af24613a689a181b6b7415395c7aa968 (patch)
tree9055c24af706aa4718d9f13fac4f3a6b06138dbc
parent7e02ddb2527544a92a005eb139517855234767ae (diff)
downloadorg.eclipse.cdt-fcfd56c2af24613a689a181b6b7415395c7aa968.tar.gz
org.eclipse.cdt-fcfd56c2af24613a689a181b6b7415395c7aa968.tar.xz
org.eclipse.cdt-fcfd56c2af24613a689a181b6b7415395c7aa968.zip
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
-rw-r--r--core/org.eclipse.cdt.core.tests/ChangeLog3
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java38
-rw-r--r--core/org.eclipse.cdt.core/parser/ChangeLog4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTClassSpecifier.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java180
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java650
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java357
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java282
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java1475
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java30
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateInstance.java134
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java37
16 files changed, 1764 insertions, 1441 deletions
diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog
index 30a2e3b954..cdc5146251 100644
--- a/core/org.eclipse.cdt.core.tests/ChangeLog
+++ b/core/org.eclipse.cdt.core.tests/ChangeLog
@@ -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
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java
index f5e0783362..8e5bb3dd9c 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java
@@ -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 );
diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog b/core/org.eclipse.cdt.core/parser/ChangeLog
index 3ab7bf77eb..f90db02543 100644
--- a/core/org.eclipse.cdt.core/parser/ChangeLog
+++ b/core/org.eclipse.cdt.core/parser/ChangeLog
@@ -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.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTClassSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTClassSpecifier.java
index 2943d6e9a0..a8bbde33d7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTClassSpecifier.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTClassSpecifier.java
@@ -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() );
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java
new file mode 100644
index 0000000000..bee66f4f8a
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java
@@ -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;
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java
new file mode 100644
index 0000000000..53cfd567b8
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java
@@ -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.
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java
new file mode 100644
index 0000000000..27982b5f20
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java
@@ -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&gt;Preferences&gt;Java&gt;Code Generation&gt;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)
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java
index 0707f50bec..d4324a9a22 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java
@@ -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
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java
index 85a09aebcc..fab40fe569 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java
@@ -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();
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java
index 3a56a42a1a..9132d1c775 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java
@@ -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);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java
index 046c402003..7522c0decb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java
@@ -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
*
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java
new file mode 100644
index 0000000000..8b9e5f81cc
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java
@@ -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&gt;Preferences&gt;Java&gt;Code Generation&gt;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;
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java
index 02568ae3c6..a1574795cf 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java
@@ -40,8 +40,7 @@ public class ParserSymbolTable {
*/
public ParserSymbolTable( ParserLanguage language ) {
super();
- _compilationUnit = new Declaration(EMPTY_NAME);
- _compilationUnit.setType( TypeInfo.t_namespace );
+ _compilationUnit = newContainerSymbol( EMPTY_NAME, TypeInfo.t_namespace );
_language = language;
}
@@ -50,37 +49,37 @@ public class ParserSymbolTable {
}
public IContainerSymbol newContainerSymbol( String name ){
- return new Declaration( name );
+ return new ContainerSymbol( this, name );
}
public IContainerSymbol newContainerSymbol( String name, TypeInfo.eType type ){
- return new Declaration( name, type );
+ return new ContainerSymbol( this, name, type );
}
public ISymbol newSymbol( String name ){
- return new BasicSymbol( name );
+ return new BasicSymbol( this, name );
}
public ISymbol newSymbol( String name, TypeInfo.eType type ){
- return new BasicSymbol( name, type );
+ return new BasicSymbol( this, name, type );
}
public IDerivableContainerSymbol newDerivableContainerSymbol( String name ){
- return new Declaration( name );
+ return new DerivableContainerSymbol( this, name );
}
public IDerivableContainerSymbol newDerivableContainerSymbol( String name, TypeInfo.eType type ){
- return new Declaration( name, type );
+ return new DerivableContainerSymbol( this, name, type );
}
public IParameterizedSymbol newParameterizedSymbol( String name ){
- return new Declaration( name );
+ return new ParameterizedSymbol( this, name );
}
public IParameterizedSymbol newParameterizedSymbol( String name, TypeInfo.eType type ){
- return new Declaration( name, type );
+ return new ParameterizedSymbol( this, name, type );
}
public ISpecializedSymbol newSpecializedSymbol( String name ){
- return new Declaration( name );
+ return new SpecializedSymbol( this, name );
}
- public ISpecializedSymbol newSpecializedSymbol( String name, TypeInfo.eType type ){
- return new Declaration( name, type );
- }
+// public ISpecializedSymbol newSpecializedSymbol( String name, TypeInfo.eType type ){
+// return new Declaration( this, name, type );
+// }
/**
* Lookup the name from LookupData starting in the inDeclaration
* @param data
@@ -260,7 +259,7 @@ public class ParserSymbolTable {
data.foundItems = new HashSet();
}
if( temp.isTemplateMember() )
- data.foundItems.add( temp.getSymbolTable().new TemplateInstance( temp, data.templateInstance.getArgumentMap() ) );
+ data.foundItems.add( new TemplateInstance( temp.getSymbolTable(), temp, data.templateInstance.getArgumentMap() ) );
else
data.foundItems.add( temp );
@@ -281,7 +280,7 @@ public class ParserSymbolTable {
data.foundItems = new HashSet();
}
if( temp.isTemplateMember() )
- data.foundItems.add( temp.getSymbolTable().new TemplateInstance( temp, data.templateInstance.getArgumentMap() ) );
+ data.foundItems.add( new TemplateInstance( temp.getSymbolTable(), temp, data.templateInstance.getArgumentMap() ) );
else
data.foundItems.add(temp);
foundSomething = true;
@@ -306,7 +305,7 @@ public class ParserSymbolTable {
ISymbol symbol = (ISymbol) obj;
if( symbol.isTemplateMember() && data.templateInstance != null ){
- data.foundItems.add( symbol.getSymbolTable().new TemplateInstance( symbol, data.templateInstance.getArgumentMap() ) );
+ data.foundItems.add( new TemplateInstance( symbol.getSymbolTable(), symbol, data.templateInstance.getArgumentMap() ) );
} else {
data.foundItems.add( symbol );
}
@@ -341,9 +340,10 @@ public class ParserSymbolTable {
*/
private static ISymbol lookupInParents( LookupData data, ISymbol lookIn ) throws ParserSymbolTableException{
IDerivableContainerSymbol container = null;
- if( lookIn instanceof TemplateInstance ){
+ /*if( lookIn instanceof TemplateInstance ){
- } else if( lookIn instanceof IDerivableContainerSymbol ){
+ } else*/
+ if( lookIn instanceof IDerivableContainerSymbol ){
container = (IDerivableContainerSymbol) lookIn;
} else{
throw new ParserSymbolTableException( ParserSymbolTableException.r_InternalError );
@@ -749,7 +749,7 @@ public class ParserSymbolTable {
sourceParams = data.parameters.iterator();
List parameterList = null;
- if( currFn.getParameterList() == null ){
+ if( currFn.getParameterList().isEmpty() ){
//the only way we get here and have no parameters, is if we are looking
//for a function that takes void parameters ie f( void )
parameterList = new LinkedList();
@@ -1093,18 +1093,18 @@ public class ParserSymbolTable {
Iterator iter = obj.getParents().iterator();
int size = obj.getParents().size();
- Declaration.ParentWrapper wrapper;
- IDerivableContainerSymbol base;
+ IDerivableContainerSymbol.IParentSymbol wrapper;
+ ISymbol base;
for( int i = size; i > 0; i-- ){
- wrapper = (Declaration.ParentWrapper) iter.next();
- base = (Declaration) wrapper.parent;
+ wrapper = (IDerivableContainerSymbol.IParentSymbol) iter.next();
+ base = wrapper.getParent();
classes.add( base );
if( base.getContainingSymbol().getType() == TypeInfo.t_namespace ){
classes.add( base.getContainingSymbol());
}
- getBaseClassesAndContainingNamespaces( base, classes );
+ getBaseClassesAndContainingNamespaces( (IDerivableContainerSymbol) base, classes );
}
}
}
@@ -1195,11 +1195,15 @@ public class ParserSymbolTable {
if( cost.target.hasPtrOperators() ){
List targetPtrs = cost.target.getPtrOperators();
- Iterator iterator = targetPtrs.iterator();
+ ListIterator iterator = targetPtrs.listIterator();
TypeInfo.PtrOp ptr = (TypeInfo.PtrOp)iterator.next();
if( ptr.getType() == TypeInfo.PtrOp.t_reference ){
- iterator.remove();
+ if( ptr.isConst() || ptr.isVolatile() ){
+ iterator.set( new PtrOp( PtrOp.t_undef, ptr.isConst(), ptr.isVolatile() ) );
+ } else {
+ iterator.remove();
+ }
cost.targetHadReference = true;
}
int size = targetPtrs.size();
@@ -1223,18 +1227,26 @@ public class ParserSymbolTable {
* see spec section 4.4 regarding qualification conversions
*/
static private void qualificationConversion( Cost cost ){
- int size = cost.source.hasPtrOperators() ? cost.source.getPtrOperators().size() : 0;
- int size2 = cost.target.hasPtrOperators() ? cost.target.getPtrOperators().size() : 0;
+ int size = cost.source.getPtrOperators().size();
+ int size2 = cost.target.getPtrOperators().size();
TypeInfo.PtrOp op1 = null, op2 = null;
boolean canConvert = true;
- Iterator iter1 = cost.source.hasPtrOperators() ? cost.source.getPtrOperators().iterator() : null;
- Iterator iter2 = cost.target.hasPtrOperators() ? cost.target.getPtrOperators().iterator() : null;
+ Iterator iter1 = cost.source.getPtrOperators().iterator();
+ Iterator iter2 = cost.target.getPtrOperators().iterator();
if( size != size2 ){
- cost.qualification = 0;
- return;
+ if( size2 - size == 1 ){
+ op2 = (PtrOp) iter2.next();
+ if( op2.isConst() || op2.isVolatile() ){
+ canConvert = true;
+ } else {
+ canConvert = false;
+ }
+ } else {
+ canConvert = false;
+ }
} else if ( size == 1 ){
op1 = (TypeInfo.PtrOp) iter1.next();
op2 = (TypeInfo.PtrOp) iter2.next();
@@ -1457,6 +1469,20 @@ public class ParserSymbolTable {
return cost;
}
+ //was the qualification conversion enough?
+ if( cost.source.isType( TypeInfo.t_type ) && cost.target.isType( TypeInfo.t_type ) ){
+ if( cost.target.hasSamePtrs( cost.source ) ){
+ ISymbol srcSymbol = cost.source.getTypeSymbol();
+ ISymbol trgSymbol = cost.target.getTypeSymbol();
+ if( srcSymbol != null && trgSymbol != null ){
+ if( srcSymbol.equals( trgSymbol ) )
+ {
+ return cost;
+ }
+ }
+ }
+ }
+
promotion( cost );
if( cost.promotion > 0 || cost.rank > -1 ){
return cost;
@@ -1498,7 +1524,7 @@ public class ParserSymbolTable {
container = (IDerivableContainerSymbol)((TemplateInstance) targetDecl).getInstantiatedSymbol();
}
- if( container.getConstructors() != null ){
+ if( !container.getConstructors().isEmpty() ){
LinkedList constructors = new LinkedList( container.getConstructors() );
constructor = resolveFunction( data, constructors );
}
@@ -1659,12 +1685,15 @@ public class ParserSymbolTable {
ptr = (PtrOp)returnInfo.getPtrOperators().iterator().next();
} else {
ptr = new PtrOp();
- returnInfo.addPtrOperator( ptr );
+ returnInfo.addPtrOperator( ptr );
+ ptr.setType( topPtr.getType() );
}
ptr.setConst( topPtr.isConst() );
ptr.setVolatile( topPtr.isVolatile() );
}
+ } else {
+ returnInfo = new TypeInfo( topInfo );
}
return returnInfo;
@@ -1949,7 +1978,7 @@ public class ParserSymbolTable {
*/
static private IParameterizedSymbol classTemplateSpecializationToFunctionTemplate( IParameterizedSymbol template ){
IParameterizedSymbol transformed = (IParameterizedSymbol) template.clone();
- transformed.setArgumentList( null );
+ transformed.getArgumentList().clear();
transformed.getContainedSymbols().clear();
IParameterizedSymbol function = template.getSymbolTable().newParameterizedSymbol( transformed.getName(), TypeInfo.t_function );
@@ -1995,11 +2024,11 @@ public class ParserSymbolTable {
map.put( param, val );
}
- return template.getSymbolTable().new TemplateInstance( template, map );
+ return new TemplateInstance( template.getSymbolTable(), template, map );
}
//private Stack _contextStack = new Stack();
- private Declaration _compilationUnit;
+ private IContainerSymbol _compilationUnit;
private ParserLanguage _language;
private LinkedList undoList = new LinkedList();
private HashSet markSet = new HashSet();
@@ -2051,7 +2080,7 @@ public class ParserSymbolTable {
return false;
}
- static abstract private class Command{
+ static abstract protected class Command{
abstract public void undoIt();
}
@@ -2059,135 +2088,11 @@ public class ParserSymbolTable {
public void undoIt(){ };
}
- static private class AddDeclarationCommand extends Command{
- AddDeclarationCommand( BasicSymbol newDecl, Declaration context, boolean removeThis ){
- _decl = newDecl;
- _context = context;
- _removeThis = removeThis;
- }
- public void undoIt(){
- Object obj = _context.getContainedSymbols().get( _decl.getName() );
-
- if( obj instanceof LinkedList ){
- LinkedList list = (LinkedList)obj;
- ListIterator iter = list.listIterator();
- int size = list.size();
- Declaration item = null;
- for( int i = 0; i < size; i++ ){
- item = (Declaration)iter.next();
- if( item == _decl ){
- iter.remove();
- break;
- }
- }
- if( list.size() == 1 ){
- _context.getContainedSymbols().remove( _decl.getName() );
- _context.getContainedSymbols().put( _decl.getName(), list.getFirst() );
- }
- } else if( obj instanceof BasicSymbol ){
- _context.getContainedSymbols().remove( _decl.getName() );
- }
- if( _removeThis && _decl instanceof IParameterizedSymbol ){
- ((IParameterizedSymbol)_decl).getContainedSymbols().remove( THIS );
- }
- }
-
- private BasicSymbol _decl;
- private Declaration _context;
- private boolean _removeThis;
- }
-
- static private class AddConstructorCommand extends Command{
- AddConstructorCommand( Declaration newConstr, Declaration context, boolean removeThis ){
- _constructor = newConstr;
- _context = context;
- _removeThis = removeThis;
- }
- public void undoIt(){
- List constructors = _context.getConstructors();
- ListIterator iter = constructors.listIterator();
-
- int size = constructors.size();
- Declaration item = null;
- for( int i = 0; i < size; i++ ){
- item = (Declaration)iter.next();
- if( item == _constructor ){
- iter.remove();
- break;
- }
- }
-
- if( _removeThis ){
- _constructor.getContainedSymbols().remove( THIS );
- }
- }
-
- private Declaration _constructor;
- private Declaration _context;
- private boolean _removeThis;
- }
-
- static private class AddParentCommand extends Command{
- public AddParentCommand( Declaration container, Declaration.ParentWrapper wrapper ){
- _decl = container;
- _wrapper = wrapper;
- }
-
- public void undoIt(){
- List parents = _decl.getParents();
- parents.remove( _wrapper );
- }
-
- private Declaration _decl;
- private Declaration.ParentWrapper _wrapper;
- }
-
- static private class AddParameterCommand extends Command{
- public AddParameterCommand( Declaration container, BasicSymbol parameter ){
- _decl = container;
- _param = parameter;
- }
-
- public void undoIt(){
- _decl.getParameterList().remove( _param );
-
- String name = _param.getName();
- if( name != null && !name.equals(EMPTY_NAME) )
- {
- _decl.getParameterMap().remove( name );
- }
- }
-
- private Declaration _decl;
- private BasicSymbol _param;
- }
-
- static private class AddArgumentCommand extends Command{
- public AddArgumentCommand( Declaration container, BasicSymbol arg ){
- _decl = container;
- _arg = arg;
- }
- public void undoIt(){
- _decl.getArgumentList().remove( _arg );
- }
- private Declaration _decl;
- private BasicSymbol _arg;
- }
- static private class AddUsingDirectiveCommand extends Command{
- public AddUsingDirectiveCommand( Declaration container, Declaration namespace ){
- _decl = container;
- _namespace = namespace;
- }
- public void undoIt(){
- _decl.getUsingDirectives().remove( _namespace );
- }
- private Declaration _decl;
- private Declaration _namespace;
- }
+
- static private class LookupData
+ static protected class LookupData
{
public String name;
@@ -2327,1244 +2232,4 @@ public class ParserSymbolTable {
}
}
- public class BasicSymbol implements Cloneable, ISymbol
- {
- public BasicSymbol( String name ){
- super();
- _name = name;
- _typeInfo = new TypeInfo();
- }
-
- public BasicSymbol( String name, ISymbolASTExtension obj ){
- super();
- _name = name;
- _object = obj;
- _typeInfo = new TypeInfo();
- }
-
- public BasicSymbol( String name, TypeInfo.eType typeInfo )
- {
- super();
- _name = name;
- _typeInfo = new TypeInfo( typeInfo, 0, null );
- }
-
- public ParserSymbolTable getSymbolTable(){
- return ParserSymbolTable.this;
- }
-
- 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 = ( Declaration )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 Declaration _containingScope; //the scope that contains us
- private int _depth; //how far down the scope stack we are
-
- private boolean _isTemplateMember = false;
- private TemplateInstance _templateInstance;
- }
-
- public class TemplateInstance extends BasicSymbol
- {
- protected TemplateInstance( ISymbol symbol, Map argMap ){
- super(EMPTY_NAME);
- _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;
- }
-
- public class Declaration extends BasicSymbol implements Cloneable,
- IContainerSymbol,
- IDerivableContainerSymbol,
- IParameterizedSymbol,
- ISpecializedSymbol
- {
-
- public Declaration( String name ){
- super( name );
- }
-
- public Declaration( String name, ISymbolASTExtension obj ){
- super( name, obj );
- }
-
- public Declaration( String name, TypeInfo.eType typeInfo )
- {
- super( name, typeInfo );
- }
-
- /**
- * clone
- * @see java.lang.Object#clone()
- *
- * implement clone for the purposes of using declarations.
- * int _typeInfo; //by assignment
- * String _name; //by assignment
- * Object _object; //null this out
- * Declaration _typeDeclaration; //by assignment
- * Declaration _containingScope; //by assignment
- * LinkedList _parentScopes; //shallow copy
- * LinkedList _usingDirectives; //shallow copy
- * HashMap _containedDeclarations; //shallow copy
- * int _depth; //by assignment
- */
- public Object clone(){
- Declaration copy = (Declaration)super.clone();
-
- copy._parentScopes = ( _parentScopes != null ) ? (LinkedList) _parentScopes.clone() : null;
- copy._usingDirectives = ( _usingDirectives != null ) ? (LinkedList) _usingDirectives.clone() : null;
- copy._containedDeclarations = ( _containedDeclarations != null ) ? (HashMap) _containedDeclarations.clone() : null;
- copy._parameterList = ( _parameterList != null ) ? (LinkedList) _parameterList.clone() : null;
- copy._parameterHash = ( _parameterHash != null ) ? (HashMap) _parameterHash.clone() : null;
-
- return copy;
- }
-
- public void addParent( ISymbol parent ){
- addParent( parent, false, ASTAccessVisibility.PUBLIC, -1, null );
- }
- 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 );
- pushCommand( command );
- }
-
- public void addParent( IDerivableContainerSymbol.IParentSymbol wrapper ){
- if( _parentScopes == null ){
- _parentScopes = new LinkedList();
- }
-
- //ParentWrapper wrapper = new ParentWrapper( parent, virtual );
- _parentScopes.add( wrapper );
-
- Command command = new AddParentCommand( this, (ParentWrapper) wrapper );
- pushCommand( command );
- }
-
- public Map getContainedSymbols(){
- return _containedDeclarations;
- }
-
- public Map createContained(){
- if( _containedDeclarations == null )
- _containedDeclarations = new HashMap();
-
- return _containedDeclarations;
- }
-
- public List getConstructors(){
- return _constructors;
- }
-
- public List createConstructors(){
- if( _constructors == null )
- _constructors = new LinkedList();
-
- return _constructors;
- }
- public boolean hasParents(){
- return ( _parentScopes != null && !_parentScopes.isEmpty() );
- }
-
- public List getParents(){
- return _parentScopes;
- }
-
- public boolean needsDefinition(){
- return _needsDefinition;
- }
- public void setNeedsDefinition( boolean need ) {
- _needsDefinition = need;
- }
-
- public ISymbol getReturnType(){
- return _returnType;
- }
-
- public void setReturnType( ISymbol type ){
- _returnType = type;
- }
-
- public List getParameterList(){
- return _parameterList;
- }
-
- public void setParameterList( List list ){
- _parameterList = new LinkedList( list );
- }
-
- public Map getParameterMap(){
- return _parameterHash;
- }
-
- public List getArgumentList(){
- return _argumentList;
- }
- public void setArgumentList( List list ){
- _argumentList = new LinkedList( list );
- }
- public void addArgument( ISymbol arg ){
- if( _argumentList == null ){
- _argumentList = new LinkedList();
- }
- _argumentList.addLast( arg );
-
- arg.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
-
- Command command = new AddArgumentCommand( this, (BasicSymbol) arg );
- pushCommand( command );
- }
-
- public void addParameter( ISymbol param ){
- if( _parameterList == null )
- _parameterList = new LinkedList();
-
- _parameterList.addLast( param );
- String name = param.getName();
- if( name != null && !name.equals(EMPTY_NAME) )
- {
- if( _parameterHash == null )
- _parameterHash = new HashMap();
-
- if( !_parameterHash.containsKey( name ) )
- _parameterHash.put( name, param );
- }
- param.setContainingSymbol( this );
- param.setIsTemplateMember( isTemplateMember() || getType() == TypeInfo.t_template );
-
- Command command = new AddParameterCommand( this, (BasicSymbol)param );
- pushCommand( command );
- }
-
- public void addParameter( ISymbol typeSymbol, TypeInfo.PtrOp ptrOp, boolean hasDefault ){
- BasicSymbol param = new BasicSymbol(EMPTY_NAME);
-
- TypeInfo info = param.getTypeInfo();
- info.setType( TypeInfo.t_type );
- info.setTypeSymbol( typeSymbol );
- info.addPtrOperator( ptrOp );
- info.setHasDefault( hasDefault );
-
- addParameter( param );
- }
-
- public void addParameter( TypeInfo.eType type, int info, TypeInfo.PtrOp ptrOp, boolean hasDefault ){
- BasicSymbol param = new BasicSymbol(EMPTY_NAME);
-
- TypeInfo t = param.getTypeInfo();
- t.setTypeInfo( info );
- t.setType( type );
- t.addPtrOperator( ptrOp );
- t.setHasDefault( hasDefault );
-
- addParameter( param );
- }
-
- 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;
- }
-
- public void addSymbol( ISymbol obj ) throws ParserSymbolTableException{
- Declaration 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 = (Declaration) 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( EMPTY_NAME );
-
- Object origObj = null;
-
- obj.setContainingSymbol( containing );
-
- if( declarations == null ){
- declarations = containing.createContained();
- } else {
- //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) ? isValidOverload( origDecl, obj ) : 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 );
-
- //take care of the this pointer
- TypeInfo type = obj.getTypeInfo();
- boolean addedThis = false;
- if( type.isType( TypeInfo.t_function ) && !type.checkBit( TypeInfo.isStatic ) ){
- addedThis = addThis( (Declaration) obj );
- }
-
- Command command = new AddDeclarationCommand( (BasicSymbol) obj, containing, addedThis );
- pushCommand( command );
- }
-
- public void addConstructor(IParameterizedSymbol constructor) throws ParserSymbolTableException {
- if( !constructor.isType( TypeInfo.t_constructor ) )
- throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
-
- List constructors = getConstructors();
-
- if( constructors == null )
- constructors = createConstructors();
-
- if( constructors.size() == 0 || isValidOverload( constructors, constructor ) ){
- constructors.add( constructor );
- } else {
- throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidOverload );
- }
-
- constructor.setContainingSymbol( this );
- boolean addedThis = addThis( (Declaration) constructor );
-
- Command command = new AddConstructorCommand( (Declaration)constructor, this, addedThis );
- pushCommand( command );
- }
-
- 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 );
- }
- }
- /**
- *
- * @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( Declaration 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( THIS, TypeInfo.t_any, null );
- 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 ){
- Declaration thisObj = new Declaration( THIS );
- thisObj.setType( 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.
- */
- public Declaration addFriend( String name ) throws ParserSymbolTableException{
- Declaration friend = lookupForFriendship( name );
-
- if( friend == null ){
- friend = new Declaration( name );
- friend.setNeedsDefinition( true );
-
- Declaration containing = (Declaration)getContainingSymbol();
- //find innermost enclosing namespace
- while( containing != null && containing.getType() != TypeInfo.t_namespace ){
- containing = (Declaration)containing.getContainingSymbol();
- }
-
- Declaration namespace = ( containing == null ) ? (Declaration)ParserSymbolTable.this.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 Declaration lookupForFriendship( String name ) throws ParserSymbolTableException{
- LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
-
- boolean inClass = ( getType() == TypeInfo.t_class);
-
- Declaration enclosing = (Declaration) getContainingSymbol();
- while( enclosing != null && (inClass ? enclosing.getType() != TypeInfo.t_class
- : enclosing.getType() == TypeInfo.t_namespace) )
- {
- enclosing = (Declaration) enclosing.getContainingSymbol();
- }
-
- data.stopAt = enclosing;
-
- ParserSymbolTable.lookup( data, this );
- return (Declaration)ParserSymbolTable.resolveAmbiguities( data );
- }
-
- /**
- * 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 );
- }
-
- 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);
- BasicSymbol obj = null;
- try{
- obj = (BasicSymbol)ParserSymbolTable.resolveAmbiguities( data );
- } catch ( ParserSymbolTableException e ) {
- if( e.reason != ParserSymbolTableException.r_UnableToResolveFunction ){
- throw e;
- }
- }
-
- if( data.foundItems == null ){
- throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidUsing );
- }
-
- BasicSymbol 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 : (Declaration) 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;
- }
-
- 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;
- }
-
- if( _usingDirectives == null ){
- _usingDirectives = new LinkedList();
- }
-
- _usingDirectives.add( namespace );
-
- Command command = new AddUsingDirectiveCommand( this, (Declaration)namespace );
- pushCommand( command );
- }
-
- public boolean hasUsingDirectives(){
- return ( _usingDirectives != null && !_usingDirectives.isEmpty() );
- }
-
- public List getUsingDirectives(){
- return _usingDirectives;
- }
-
- 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 );
- }
-
- public ISymbol lookup( String name ) throws ParserSymbolTableException {
- LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
-
- ParserSymbolTable.lookup( data, this );
-
- return ParserSymbolTable.resolveAmbiguities( data );
- }
-
- /**
- * 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 );
- }
-
- /**
- * 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 Declaration lookupNestedNameSpecifier(String name, Declaration inDeclaration ) throws ParserSymbolTableException{
- Declaration foundDeclaration = null;
-
- LookupData data = new LookupData( name, TypeInfo.t_namespace, getTemplateInstance() );
- data.upperType = TypeInfo.t_union;
-
- ParserSymbolTable.lookupInContained( data, inDeclaration );
-
- if( data.foundItems != null ){
- foundDeclaration = (Declaration) ParserSymbolTable.resolveAmbiguities( data );//, data.foundItems );
- }
-
- if( foundDeclaration == null && inDeclaration.getContainingSymbol() != null ){
- foundDeclaration = lookupNestedNameSpecifier( name, (Declaration)inDeclaration.getContainingSymbol() );
- }
-
- return foundDeclaration;
- }
-
- /**
- * 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 );
- }
-
- 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 );
- }
-
- public ISymbol qualifiedLookup( String name ) throws ParserSymbolTableException{
-
- return qualifiedLookup(name, TypeInfo.t_any);
- }
-
- 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 );
- }
-
- 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;
- }
-
- public IParameterizedSymbol lookupConstructor( List parameters ) throws ParserSymbolTableException
- {
- LookupData data = new LookupData( EMPTY_NAME, TypeInfo.t_constructor, null );
- data.parameters = parameters;
-
- List constructors = new LinkedList();
- if( getConstructors() != null )
- constructors.addAll( getConstructors() );
-
- return ParserSymbolTable.resolveFunction( data, constructors );
- }
-
- /**
- * 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 );
-
- Declaration found = (Declaration)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 );
- }
-
- Declaration decl;
- //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++ ){
- decl = (Declaration) scopes[ i ];
- if( associated.contains( decl ) ){
- data.qualified = true;
- data.ignoreUsingDirectives = true;
- ParserSymbolTable.lookup( data, decl );
- }
- }
-
- found = (Declaration)ParserSymbolTable.resolveAmbiguities( data );
- }
-
- return found;
- }
-
- public boolean hasSpecializations(){
- return ( _specializations != null && !_specializations.isEmpty() );
- }
-
- public List getSpecializations(){
- return _specializations;
- }
-
- public void addSpecialization( IParameterizedSymbol spec ){
- if( _specializations == null ){
- _specializations = new LinkedList();
- }
- _specializations.add( spec );
- }
-
- 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 = 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( symbol, map );
- return instance;
- }
-
- private boolean _needsDefinition; //this name still needs to be defined
-
- private LinkedList _parentScopes; //inherited scopes (is base classes)
- private LinkedList _usingDirectives; //collection of nominated namespaces
- private HashMap _containedDeclarations; //declarations contained by us.
-
- private LinkedList _specializations; //template specializations
- private LinkedList _argumentList; //template specialization arguments
-
- private LinkedList _parameterList; //have my cake
- private HashMap _parameterHash; //and eat it too
-
- private LinkedList _constructors; //constructor list
-
- private ISymbol _returnType;
-
- 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 = (Declaration) parent;
- }
-
- public ISymbol getParent(){
- return parent;
- }
-
- public boolean isVirtual(){
- return isVirtual;
- }
-
- public void setVirtual( boolean virtual ){
- isVirtual = virtual;
- }
-
- public ASTAccessVisibility getVisibility(){
- return access;
- }
-
- private boolean isVirtual = false;
- protected ISymbol parent = null;
- private final ASTAccessVisibility access;
- private final int offset;
- private final List references;
- /**
- * @return
- */
- public ASTAccessVisibility getAccess() {
- return access;
- }
-
- /**
- *
- */
- public int getOffset()
- {
- return offset;
- }
-
- /**
- *
- */
- public List getReferences()
- {
- return references;
- }
-
- }
- }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java
new file mode 100644
index 0000000000..f6b6c331cb
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/SpecializedSymbol.java
@@ -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&gt;Preferences&gt;Java&gt;Code Generation&gt;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 );
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateInstance.java
new file mode 100644
index 0000000000..277463169d
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateInstance.java
@@ -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;
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java
index 99c6df16cf..cf09aa166b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java
@@ -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;
}

Back to the top