diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index e0461cbe3ca..c4148b80f2c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -53,6 +53,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPCompositeBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; @@ -2781,5 +2782,73 @@ public class AST2CPPTests extends AST2BaseTest { assertSame( bs[1], f1 ); assertSame( bs[2], f2 ); } + + public void testGets() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("class A { \n"); //$NON-NLS-1$ + buffer.append(" int a; \n"); //$NON-NLS-1$ + buffer.append(" void fa(); \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + buffer.append("class B : public A { \n"); //$NON-NLS-1$ + buffer.append(" int b; \n"); //$NON-NLS-1$ + buffer.append(" void fb(); \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept(col); + + ICPPClassType A = (ICPPClassType) col.getName(0).resolveBinding(); + ICPPClassType B = (ICPPClassType) col.getName(3).resolveBinding(); + ICPPField a = (ICPPField) col.getName(1).resolveBinding(); + ICPPMethod fa = (ICPPMethod) col.getName(2).resolveBinding(); + ICPPField b = (ICPPField) col.getName(5).resolveBinding(); + ICPPMethod fb = (ICPPMethod) col.getName(6).resolveBinding(); + + Object [] result = B.getDeclaredFields(); + assertEquals( result.length, 1 ); + assertSame( result[0], b ); + + result = B.getFields(); + assertEquals( result.length, 2 ); + assertSame( result[0], b ); + assertSame( result[1], a ); + + result = B.getDeclaredMethods(); + assertEquals( result.length, 1 ); + assertSame( result[0], fb ); + + result = B.getAllDeclaredMethods(); + assertEquals( result.length, 2 ); + assertSame( result[0], fb ); + assertSame( result[1], fa ); + + ICPPMethod [] B_implicit = ((ICPPClassScope)B.getCompositeScope()).getImplicitMethods(); + assertEquals( B_implicit.length, 4 ); + assertTrue( B_implicit[0].getName().equals( "B" ) ); //$NON-NLS-1$ + assertTrue( B_implicit[1].getName().equals( "B" ) ); //$NON-NLS-1$ + assertTrue( B_implicit[2].getName().equals( "operator =" ) ); //$NON-NLS-1$ + assertTrue( B_implicit[3].getName().equals( "~B" ) ); //$NON-NLS-1$ + + ICPPMethod [] A_implicit = ((ICPPClassScope)A.getCompositeScope()).getImplicitMethods(); + assertEquals( A_implicit.length, 4 ); + assertTrue( A_implicit[0].getName().equals( "A" ) ); //$NON-NLS-1$ + assertTrue( A_implicit[1].getName().equals( "A" ) ); //$NON-NLS-1$ + assertTrue( A_implicit[2].getName().equals( "operator =" ) ); //$NON-NLS-1$ + assertTrue( A_implicit[3].getName().equals( "~A" ) ); //$NON-NLS-1$ + + result = B.getMethods(); + assertEquals( result.length, 10 ); + assertSame( result[0], fb ); + assertSame( result[1], B_implicit[0] ); + assertSame( result[2], B_implicit[1] ); + assertSame( result[3], B_implicit[2] ); + assertSame( result[4], B_implicit[3] ); + assertSame( result[5], fa ); + assertSame( result[6], A_implicit[0] ); + assertSame( result[7], A_implicit[1] ); + assertSame( result[8], A_implicit[2] ); + assertSame( result[9], A_implicit[3] ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ICompositeType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ICompositeType.java index da95a604d44..c5936c85ce3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ICompositeType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ICompositeType.java @@ -40,5 +40,10 @@ public interface ICompositeType extends IBinding, IType { */ public IField findField( String name ) throws DOMException; + /** + * get the IScope object that is associated with this composite type + * @return + * @throws DOMException + */ public IScope getCompositeScope() throws DOMException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java index 7a3a286e037..60032ffc4bd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java @@ -35,80 +35,63 @@ public interface IProblemBinding extends IBinding, IScope, IType { /* * Parser Semantic Problems + * All Semantic problems take a char[] as an argument */ - - /** - * Attempt to add a unique symbol, yet the value was already defined. - * Require attributes: A_SYMBOL_NAME - * @see #A_SYMBOL_NAME - */ - public final static int SEMANTIC_UNIQUE_NAME_PREDEFINED = 0x001; - + /** * Attempt to use a symbol that was not found. * Require attributes: A_SYMBOL_NAME * @see #A_SYMBOL_NAME */ - public final static int SEMANTIC_NAME_NOT_FOUND = 0x002; - - /** - * Name not provided in context that it was required. - * Require attributes: none - */ - public final static int SEMANTIC_NAME_NOT_PROVIDED = 0x003; + public final static int SEMANTIC_NAME_NOT_FOUND = 0x001; /** * Invalid overload of a particular name. * Required attributes: A_SYMBOL_NAME * @see #A_SYMBOL_NAME */ - public static final int SEMANTIC_INVALID_OVERLOAD = 0x004; + public static final int SEMANTIC_INVALID_OVERLOAD = 0x002; /** * Invalid using directive. * Required attributes: A_NAMESPACE_NAME * @see #A_NAMESPACE_NAME */ - public static final int SEMANTIC_INVALID_USING = 0x005; + public static final int SEMANTIC_INVALID_USING = 0x003; /** * Ambiguous lookup for given name. * Required attributes: A_SYMBOL_NAME * @see #A_SYMBOL_NAME */ - public static final int SEMANTIC_AMBIGUOUS_LOOKUP = 0x006; + public static final int SEMANTIC_AMBIGUOUS_LOOKUP = 0x004; /** * Invalid type provided * Required attribugtes: A_TYPE_NAME * @see #A_TYPE_NAME */ - public static final int SEMANTIC_INVALID_TYPE = 0x007; + public static final int SEMANTIC_INVALID_TYPE = 0x005; - public static final int SEMANTIC_CIRCULAR_INHERITANCE = 0x008; + /** + * circular inheritance was detected for a class + */ + public static final int SEMANTIC_CIRCULAR_INHERITANCE = 0x006; - public static final int SEMANTIC_INVALID_TEMPLATE = 0x009; - - public static final int SEMANTIC_BAD_VISIBILITY = 0x00A; - - public static final int SEMANTIC_UNABLE_TO_RESOLVE_FUNCTION = 0x00B; - - public static final int SEMANTIC_INVALID_TEMPLATE_ARGUMENT = 0x00C; - - public static final int SEMANTIC_INVALID_TEMPLATE_PARAMETER = 0x00D; - - public static final int SEMANTIC_REDECLARED_TEMPLATE_PARAMETER = 0x00E; - - public static final int SEMANTIC_INVALID_CONVERSION_TYPE = 0x00F; - - public static final int SEMANTIC_MALFORMED_EXPRESSION = 0x010; - - public static final int SEMANTIC_ILLFORMED_FRIEND = 0x011; + /** + * the definition for the class/function can not be found + */ + public static final int SEMANTIC_DEFINITION_NOT_FOUND = 0x007; - public static final int SEMANTIC_RECURSIVE_TEMPLATE_INSTANTIATION = 0x012; + /** + * the declaration for the K&R style function parameter can not be found + */ + public static final int SEMANTIC_KNR_PARAMETER_DECLARATION_NOT_FOUND = 0x008; + + /** + * a label statement can not be found to match a goto statement + */ + public static final int SEMANTIC_LABEL_STATEMENT_NOT_FOUND = 0x009; - public static final int SEMANTIC_DEFINITION_NOT_FOUND = 0x013; - public static final int SEMANTIC_KNR_PARAMETER_DECLARATION_NOT_FOUND = 0x014; - public static final int SEMANTIC_LABEL_STATEMENT_NOT_FOUND = 0x015; public static final int LAST_PROBLEM = SEMANTIC_LABEL_STATEMENT_NOT_FOUND; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java index 70e20e062c9..f2efd9e5db5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java @@ -37,6 +37,7 @@ public interface IScope { public IBinding[] find(String name) throws DOMException; /** + * Return the physical IASTNode that this scope was created for * @return */ public IASTNode getPhysicalNode() throws DOMException; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICCompositeTypeScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICCompositeTypeScope.java index 9c5dcbd1cd5..8968ab87eca 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICCompositeTypeScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICCompositeTypeScope.java @@ -21,5 +21,12 @@ import org.eclipse.cdt.core.dom.ast.IBinding; * @author aniefer */ public interface ICCompositeTypeScope extends ICScope { + /** + * get the binding for the member that has been previous added to this scope + * and that matches the given name. + * @param name + * @return + * @throws DOMException + */ public IBinding getBinding( char[] name ) throws DOMException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionScope.java index 736a6d0c60d..f220815e076 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionScope.java @@ -22,7 +22,22 @@ import org.eclipse.cdt.core.dom.ast.IScope; * @author aniefer */ public interface ICFunctionScope extends ICScope { + + /** + * Get the scope representing the function body . + * returns null if there is no function definition + * @return + * @throws DOMException + */ public IScope getBodyScope() throws DOMException; + + /** + * return the ILabel binding in this scope that matches the given name + * + * @param name + * @return + * @throws DOMException + */ public IBinding getBinding( char[] name ) throws DOMException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICScope.java index aa96ea11b0d..25fd33a7381 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICScope.java @@ -22,10 +22,38 @@ import org.eclipse.cdt.core.dom.ast.IScope; * @author aniefer */ public interface ICScope extends IScope { + /** + * ISO C:99 6.2.3 + * there are seperate namespaces for various categories of identifiers: + * - label names ( labels have ICFunctionScope ) + * - tags of structures or unions : NAMESPACE_TYPE_TAG + * - members of structures or unions ( members have ICCompositeTypeScope ) + * - all other identifiers : NAMESPACE_TYPE_OTHER + */ public static final int NAMESPACE_TYPE_TAG = 0; public static final int NAMESPACE_TYPE_OTHER = 1; + /** + * add a binding to this scope + * @param binding + * @throws DOMException + */ void addBinding( IBinding binding ) throws DOMException; + + /** + * remove the given binding from this scope + * @param binding + * @throws DOMException + */ void removeBinding( IBinding binding ) throws DOMException; + + /** + * Get the binding that has previously been added to this scope that matches + * the given name and is in the appropriate namespace + * @param namespaceType : either NAMESPACE_TYPE_TAG or NAMESPACE_TYPE_OTHER + * @param name + * @return + * @throws DOMException + */ public IBinding getBinding( int namespaceType, char [] name ) throws DOMException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java index 72b620d1fd8..e390841a434 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java @@ -17,5 +17,18 @@ package org.eclipse.cdt.core.dom.ast.cpp; * @author aniefer */ public interface ICPPClassScope extends ICPPScope { + /** + * Get the binding for the class this scope is associated with + * @return + */ ICPPClassType getClassType(); + + /** + * Returns an array of methods that were implicitly added to this class scope. + * These methods may or may not have been explicitly declared in the code. + * The methods that will be implicitly declared are: the default constructor, + * copy constructor, copy assignment operator, and destructor + * @return + */ + public ICPPMethod [] getImplicitMethods(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassType.java index a4ce662db15..cb1b96d6ad6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassType.java @@ -10,8 +10,6 @@ **********************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; -import java.util.List; - import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; @@ -39,13 +37,23 @@ public interface ICPPClassType extends ICompositeType { */ public IField[] getFields() throws DOMException; + /** + * findField is restated here to point out that this method looks through the + * inheritance tree of this class while looking for a field with the given name + * If no field is found, null is returned, if the name is found to be ambiguous + * a IProblemBinding is returned. + * @param name + * @return + */ + public IField findField( String name ) throws DOMException; + /** * Returns a list of ICPPField objects representing fields declared in this * class. It does not include fields inherited from base classes. * * @return List of ICPPField */ - public List getDeclaredFields() throws DOMException; + public ICPPField[] getDeclaredFields() throws DOMException; /** * Returns a list of ICPPMethod objects representing all methods defined for @@ -54,7 +62,7 @@ public interface ICPPClassType extends ICompositeType { * * @return List of ICPPMethod */ - public List getMethods() throws DOMException; + public ICPPMethod[] getMethods() throws DOMException; /** * Returns a list of ICPPMethod objects representing all method explicitly @@ -63,7 +71,7 @@ public interface ICPPClassType extends ICompositeType { * * @return List of ICPPMethod */ - public List getAllDeclaredMethods() throws DOMException; + public ICPPMethod[] getAllDeclaredMethods() throws DOMException; /** * Returns a list of ICPPMethod objects representing all methods explicitly @@ -72,7 +80,7 @@ public interface ICPPClassType extends ICompositeType { * * @return List of ICPPMethod */ - public List getDeclaredMethods() throws DOMException; + public ICPPMethod[] getDeclaredMethods() throws DOMException; /** * @return diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionScope.java index 4d5af5e1261..8a63dedab25 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionScope.java @@ -13,9 +13,19 @@ */ package org.eclipse.cdt.core.dom.ast.cpp; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IScope; + /** * @author aniefer */ public interface ICPPFunctionScope extends ICPPScope { + /** + * Get the scope representing the function body. + * returns null if there is no function definition + * @return + * @throws DOMException + */ + public IScope getBodyScope() throws DOMException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectSet.java index 0a70bc1a195..0835399dbee 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectSet.java @@ -55,6 +55,15 @@ public class ObjectSet extends ObjectTable { add( set.keyAt( i ) ); } } + + public void addAll( Object[] objs ){ + if( objs == null ) + return; + + for (int i = 0; i < objs.length; i++) { + if( objs[i] != null ) add( objs[i] ); + } + } public boolean remove( Object key ) { int i = lookup(key); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java index 0eb5354acd8..a22b7a2fbdc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java @@ -43,31 +43,23 @@ public class ProblemBinding implements IProblemBinding, IType, IScope { protected static final String [] errorMessages; static { errorMessages = new String [ IProblemBinding.LAST_PROBLEM ]; - errorMessages[SEMANTIC_UNIQUE_NAME_PREDEFINED - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.uniqueNamePredefined"); //$NON-NLS-1$ errorMessages[SEMANTIC_NAME_NOT_FOUND - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.nameNotFound"); //$NON-NLS-1$ - errorMessages[SEMANTIC_NAME_NOT_PROVIDED - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.nameNotProvided"); //$NON-NLS-1$ - errorMessages[SEMANTIC_INVALID_CONVERSION_TYPE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.invalidConversionType"); //$NON-NLS-1$ - errorMessages[SEMANTIC_MALFORMED_EXPRESSION - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.malformedExpression"); //$NON-NLS-1$ errorMessages[SEMANTIC_AMBIGUOUS_LOOKUP - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.ambiguousLookup"); //$NON-NLS-1$ errorMessages[SEMANTIC_INVALID_TYPE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidType"); //$NON-NLS-1$ errorMessages[SEMANTIC_CIRCULAR_INHERITANCE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.circularInheritance"); //$NON-NLS-1$ errorMessages[SEMANTIC_INVALID_OVERLOAD - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidOverload"); //$NON-NLS-1$ - errorMessages[SEMANTIC_INVALID_TEMPLATE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidTemplate"); //$NON-NLS-1$ errorMessages[SEMANTIC_INVALID_USING - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidUsing"); //$NON-NLS-1$ - errorMessages[SEMANTIC_BAD_VISIBILITY - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.badVisibility"); //$NON-NLS-1$ - errorMessages[SEMANTIC_UNABLE_TO_RESOLVE_FUNCTION - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.unableToResolveFunction"); //$NON-NLS-1$ - errorMessages[SEMANTIC_INVALID_TEMPLATE_ARGUMENT - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidTemplateArgument"); //$NON-NLS-1$ - errorMessages[SEMANTIC_INVALID_TEMPLATE_PARAMETER - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidTemplateParameter"); //$NON-NLS-1$ - errorMessages[SEMANTIC_REDECLARED_TEMPLATE_PARAMETER - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.redeclaredTemplateParameter"); //$NON-NLS-1$ - errorMessages[SEMANTIC_RECURSIVE_TEMPLATE_INSTANTIATION - 1]= ParserMessages.getString("ASTProblemFactory.error.semantic.pst.recursiveTemplateInstantiation"); //$NON-NLS-1$ + errorMessages[SEMANTIC_DEFINITION_NOT_FOUND - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.definitionNotFound"); //$NON-NLS-1$ + errorMessages[SEMANTIC_KNR_PARAMETER_DECLARATION_NOT_FOUND - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.knrParameterDeclarationNotFound"); //$NON-NLS-1$ + errorMessages[SEMANTIC_LABEL_STATEMENT_NOT_FOUND - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.labelStatementNotFound"); //$NON-NLS-1$ } + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IProblemBinding#getID() */ public int getID() { return id; } - /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IProblemBinding#getMessage() diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 7f0c7b7864a..2ee5f033d51 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; @@ -29,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; @@ -40,6 +42,7 @@ import org.eclipse.cdt.core.parser.util.ObjectSet; public class CPPClassScope extends CPPScope implements ICPPClassScope { private ObjectSet constructorBindings = ObjectSet.EMPTY_SET; private ObjectSet constructorNames = ObjectSet.EMPTY_SET; + private ICPPMethod[] implicits = null; public CPPClassScope( ICPPASTCompositeTypeSpecifier physicalNode ) { super( physicalNode ); @@ -69,25 +72,35 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { IBinding binding = compTypeSpec.getName().resolveBinding(); if( !(binding instanceof ICPPClassType ) ) return; + + implicits = new ICPPMethod[4]; ICPPClassType clsType = (ICPPClassType) binding; char [] className = name.toCharArray(); //default constructor: A() - addBinding( new CPPImplicitConstructor( this, className, IParameter.EMPTY_PARAMETER_ARRAY ) ); + ICPPMethod m = new CPPImplicitConstructor( this, className, IParameter.EMPTY_PARAMETER_ARRAY ); + implicits[0] = m; + addBinding( m ); //copy constructor: A( const A & ) IType pType = new CPPReferenceType( new CPPQualifierType( clsType, true, false ) ); IParameter [] ps = new IParameter [] { new CPPParameter( pType ) }; - addBinding( new CPPImplicitConstructor( this, className, ps ) ); + m = new CPPImplicitConstructor( this, className, ps ); + implicits[1] = m; + addBinding( m ); //copy assignment operator: A& operator = ( const A & ) IType refType = new CPPReferenceType( clsType ); - addBinding( new CPPImplicitMethod( this, "operator =".toCharArray(), refType, ps ) ); //$NON-NLS-1$ + m = new CPPImplicitMethod( this, "operator =".toCharArray(), refType, ps ); //$NON-NLS-1$ + implicits[2] = m; + addBinding( m ); //destructor: ~A() char [] dtorName = CharArrayUtils.concat( "~".toCharArray(), className ); //$NON-NLS-1$ - addBinding( new CPPImplicitMethod( this, dtorName, new CPPBasicType( IBasicType.t_unspecified, 0 ), IParameter.EMPTY_PARAMETER_ARRAY ) ); + m = new CPPImplicitMethod( this, dtorName, new CPPBasicType( IBasicType.t_unspecified, 0 ), IParameter.EMPTY_PARAMETER_ARRAY ); + implicits[3] = m; + addBinding( m ); } /* (non-Javadoc) @@ -217,4 +230,13 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { return (ICPPClassType) compSpec.getName().resolveBinding(); } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope#getImplicitMethods() + */ + public ICPPMethod[] getImplicitMethods() { + if( implicits == null ) + implicits = new ICPPMethod[] { new CPPMethod.CPPMethodProblem( IProblemBinding.SEMANTIC_INVALID_TYPE, CPPSemantics.EMPTY_NAME_ARRAY ) }; + return implicits; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java index b291e9b7807..5064ea48cae 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java @@ -13,8 +13,6 @@ */ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import java.util.List; - import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; @@ -36,11 +34,15 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPCompositeBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -63,16 +65,16 @@ public class CPPClassType implements ICPPClassType, ICPPBinding { public IField[] getFields() throws DOMException { throw new DOMException( this ); } - public List getDeclaredFields() throws DOMException { + public ICPPField[] getDeclaredFields() throws DOMException { throw new DOMException( this ); } - public List getMethods() throws DOMException { + public ICPPMethod[] getMethods() throws DOMException { throw new DOMException( this ); } - public List getAllDeclaredMethods() throws DOMException { + public ICPPMethod[] getAllDeclaredMethods() throws DOMException { throw new DOMException( this ); } - public List getDeclaredMethods() throws DOMException { + public ICPPMethod[] getDeclaredMethods() throws DOMException { throw new DOMException( this ); } public ICPPConstructor[] getConstructors() throws DOMException { @@ -192,41 +194,37 @@ public class CPPClassType implements ICPPClassType, ICPPBinding { /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getFields() */ - public IField[] getFields() { + public IField[] getFields() throws DOMException { if( definition == null ){ checkForDefinition(); if( definition == null ) return new IField [] { new CPPField.CPPFieldProblem( IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; } - IASTDeclaration[] members = getCompositeTypeSpecifier().getMembers(); - int size = members.length; - IField[] fields = null; - if( size > 0 ){ - - for( int i = 0; i < size; i++ ){ - IASTNode node = members[i]; - if( node instanceof IASTSimpleDeclaration ){ - IASTDeclarator[] declarators = ((IASTSimpleDeclaration)node).getDeclarators(); - for( int j = 0; j < declarators.length; j++ ){ - IASTDeclarator declarator = declarators[i]; - IBinding binding = declarator.getName().resolveBinding(); - if( binding != null && binding instanceof IField ) - fields = (IField[]) ArrayUtil.append( IField.class, fields, binding ); - } - } - } - - } + IField[] fields = getDeclaredFields(); + ICPPBase [] bases = getBases(); + for ( int i = 0; i < bases.length; i++ ) { + fields = (IField[]) ArrayUtil.addAll( IField.class, fields, bases[i].getBaseClass().getFields() ); + } return (IField[]) ArrayUtil.trim( IField.class, fields ); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.ICompositeType#findField(java.lang.String) */ - public IField findField(String name) { - // TODO Auto-generated method stub - return null; + public IField findField(String name) throws DOMException { + IBinding [] bindings = CPPSemantics.findBindings( getCompositeScope(), name, true ); + IField field = null; + for ( int i = 0; i < bindings.length; i++ ) { + if( bindings[i] instanceof IField ){ + if( field == null ) + field = (IField) bindings[i]; + else { + return new CPPField.CPPFieldProblem( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, name.toCharArray() ); + } + } + } + return field; } /* (non-Javadoc) @@ -337,33 +335,120 @@ public class CPPClassType implements ICPPClassType, ICPPBinding { /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredFields() */ - public List getDeclaredFields() { - // TODO Auto-generated method stub - return null; + public ICPPField[] getDeclaredFields() throws DOMException { + if( definition == null ){ + checkForDefinition(); + if( definition == null ){ + return new ICPPField[] { new CPPField.CPPFieldProblem( IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; + } + } + IBinding binding = null; + ICPPField [] result = null; + + IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers(); + for ( int i = 0; i < decls.length; i++ ) { + if( decls[i] instanceof IASTSimpleDeclaration ){ + IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decls[i]).getDeclarators(); + for ( int j = 0; j < dtors.length; j++ ) { + binding = dtors[j].getName().resolveBinding(); + if( binding instanceof ICPPField ) + result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, binding ); + } + } else if( decls[i] instanceof ICPPASTUsingDeclaration ){ + IASTName n = ((ICPPASTUsingDeclaration)decls[i]).getName(); + binding = n.resolveBinding(); + if( binding instanceof ICPPCompositeBinding ){ + IBinding [] bs = ((ICPPCompositeBinding)binding).getBindings(); + for ( int j = 0; j < bs.length; j++ ) { + if( bs[j] instanceof ICPPField ) + result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, bs[j] ); + } + } else if( binding instanceof ICPPField ) { + result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, binding ); + } + } + } + return (ICPPField[]) ArrayUtil.trim( ICPPField.class, result ); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getMethods() */ - public List getMethods() { - // TODO Auto-generated method stub - return null; + public ICPPMethod[] getMethods() throws DOMException { + ObjectSet set = new ObjectSet(2); + ICPPMethod [] ms = getDeclaredMethods(); + set.addAll( ms ); + ICPPClassScope scope = (ICPPClassScope) getCompositeScope(); + set.addAll( scope.getImplicitMethods() ); + ICPPBase [] bases = getBases(); + for ( int i = 0; i < bases.length; i++ ) { + set.addAll( bases[i].getBaseClass().getMethods() ); + } + return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, set.keyArray(), true ); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getAllDeclaredMethods() */ - public List getAllDeclaredMethods() { - // TODO Auto-generated method stub - return null; + public ICPPMethod[] getAllDeclaredMethods() throws DOMException { + if( definition == null ){ + checkForDefinition(); + if( definition == null ) + return new ICPPMethod [] { new CPPMethod.CPPMethodProblem( IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; + } + + ICPPMethod[] methods = getDeclaredMethods(); + ICPPBase [] bases = getBases(); + for ( int i = 0; i < bases.length; i++ ) { + methods = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, methods, bases[i].getBaseClass().getAllDeclaredMethods() ); + } + return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, methods ); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredMethods() */ - public List getDeclaredMethods() { - // TODO Auto-generated method stub - return null; + public ICPPMethod[] getDeclaredMethods() throws DOMException { + if( definition == null ){ + checkForDefinition(); + if( definition == null ){ + return new ICPPMethod[] { new CPPMethod.CPPMethodProblem( IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; + } + } + IBinding binding = null; + ICPPMethod [] result = null; + + IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers(); + for ( int i = 0; i < decls.length; i++ ) { + if( decls[i] instanceof IASTSimpleDeclaration ){ + IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decls[i]).getDeclarators(); + for ( int j = 0; j < dtors.length; j++ ) { + binding = dtors[j].getName().resolveBinding(); + if( binding instanceof ICPPMethod) + result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); + } + } else if( decls[i] instanceof IASTFunctionDefinition ){ + IASTDeclarator dtor = ((IASTFunctionDefinition)decls[i]).getDeclarator(); + dtor = CPPVisitor.getMostNestedDeclarator( dtor ); + binding = dtor.getName().resolveBinding(); + if( binding instanceof ICPPMethod ){ + result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); + } + } else if( decls[i] instanceof ICPPASTUsingDeclaration ){ + IASTName n = ((ICPPASTUsingDeclaration)decls[i]).getName(); + binding = n.resolveBinding(); + if( binding instanceof ICPPCompositeBinding ){ + IBinding [] bs = ((ICPPCompositeBinding)binding).getBindings(); + for ( int j = 0; j < bs.length; j++ ) { + if( bs[j] instanceof ICPPMethod ) + result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, bs[j] ); + } + } else if( binding instanceof ICPPMethod ) { + result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); + } + } + } + return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, result ); } public Object clone(){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java index eb1d22698c9..4c4c7c0ab3c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java @@ -14,8 +14,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IScope; @@ -92,4 +96,19 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope { return CPPVisitor.getContainingScope( fdtor ); } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope#getBodyScope() + */ + public IScope getBodyScope() throws DOMException { + IASTFunctionDeclarator fnDtor = (IASTFunctionDeclarator) getPhysicalNode(); + IASTNode parent = fnDtor.getParent(); + if( parent instanceof IASTFunctionDefinition ){ + IASTStatement body = ((IASTFunctionDefinition)parent).getBody(); + if( body instanceof IASTCompoundStatement ) + return ((IASTCompoundStatement)body).getScope(); + } + return null; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java index ceb5160a84b..543d797006b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java @@ -159,6 +159,6 @@ abstract public class CPPScope implements ICPPScope{ * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) */ public IBinding[] find(String name) throws DOMException { - return CPPSemantics.findBindings( this, name ); + return CPPSemantics.findBindings( this, name, false ); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index a3d458b1b8f..30a767ed92f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -2275,13 +2275,14 @@ public class CPPSemantics { return -1; } - public static IBinding[] findBindings( IScope scope, String name ) throws DOMException{ + public static IBinding[] findBindings( IScope scope, String name, boolean qualified ) throws DOMException{ CPPASTName astName = new CPPASTName(); astName.setName( name.toCharArray() ); astName.setParent( scope.getPhysicalNode() ); astName.setPropertyInParent( STRING_LOOKUP_PROPERTY ); LookupData data = new LookupData( astName ); + data.forceQualified = qualified; try { lookup( data, scope ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index 86e029f5ad3..0afffc295eb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -1410,6 +1410,15 @@ public class CPPVisitor { return null; } + public static IASTDeclarator getMostNestedDeclarator( IASTDeclarator dtor ){ + if( dtor == null ) return null; + IASTDeclarator nested = null; + while( (nested = dtor.getNestedDeclarator()) != null ){ + dtor = nested; + } + return dtor; + } + public static IASTProblem[] getProblems(IASTTranslationUnit tu) { CollectProblemsAction action = new CollectProblemsAction(); tu.accept(action); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties index bbc76360e43..9c2bf825ae8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties @@ -76,3 +76,7 @@ ASTProblemFactory.error.semantic.pst.invalidTemplateArgument=Invalid template ar ASTProblemFactory.error.semantic.pst.invalidTemplateParameter=Invalid template parameter: {0} ASTProblemFactory.error.semantic.pst.redeclaredTemplateParameter=Redeclaration of template parameter: {0} ASTProblemFactory.error.semantic.pst.recursiveTemplateInstantiation=Possible infinite recursive loop encountered while instantiating {0} + +ASTProblemFactory.error.semantic.dom.definitionNotFound=A definition was not found for {0} +ASTProblemFactory.error.semantic.dom.knrParameterDeclarationNotFound=A declaration was not found for the k&r parameter {0} +ASTProblemFactory.error.semantic.dom.labelStatementNotFound=A label statement was not found for the name {0} \ No newline at end of file