From 7cedfa5e4825461d63046c288cbd162505f1ed39 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 4 Nov 2010 16:18:17 +0000 Subject: [PATCH] Bug 329172: Name lookup for default arguments within class bodies. --- .../core/parser/tests/ast2/AST2CPPTests.java | 13 ++- .../dom/parser/cpp/semantics/LookupData.java | 108 ++++++++++++------ 2 files changed, 81 insertions(+), 40 deletions(-) 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 48083ddbc42..e5c2a8f2c85 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 @@ -6422,7 +6422,7 @@ public class AST2CPPTests extends AST2BaseTest { // return b; // } // struct B {}; - // int& x = y; // y is not defined + // static int& x = y; // y is not defined // int y; // }; public void testScopeOfClassMember_259460() throws Exception { @@ -6439,7 +6439,7 @@ public class AST2CPPTests extends AST2BaseTest { // int method(int a = GREEN) { // return RED; // } - // int x = GREEN; // GREEN is not defined + // static int x = GREEN; // GREEN is not defined // enum Color { // RED, GREEN // }; @@ -9281,4 +9281,13 @@ public class AST2CPPTests extends AST2BaseTest { public void testOverrideUsingDeclaredMethod_328802() throws Exception { parseAndCheckBindings(); } + + // class A { + // A(int a = f()); // problem on f + // static int f(); + // }; + public void testFwdLookupForDefaultArgument() throws Exception { + parseAndCheckBindings(); + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index 1cf0b51b23d..1b07da002d3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -24,19 +24,22 @@ import java.util.Map; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; -import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; +import org.eclipse.cdt.core.dom.ast.IASTInitializerList; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IPointerType; @@ -271,48 +274,77 @@ public class LookupData { public static boolean checkWholeClassScope(IASTName name) { if (name == null) return false; - - ASTNodeProperty lastProp= name.getPropertyInParent(); - if (lastProp == CPPSemantics.STRING_LOOKUP_PROPERTY) + if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return true; - - boolean inInitializer= false; - IASTNode parent = name.getParent(); - while (parent instanceof IASTName) { - name= (IASTName) parent; - parent= name.getParent(); + + IASTNode node = name.getParent(); + while (node instanceof IASTName) { + name= (IASTName) node; + node= name.getParent(); } - while (parent != null && !(parent instanceof IASTFunctionDefinition)) { - if (parent instanceof IASTInitializer) { - inInitializer= true; - } - lastProp= parent.getPropertyInParent(); - parent = parent.getParent(); - } - if (parent instanceof IASTFunctionDefinition) { - if (lastProp == IASTFunctionDefinition.DECL_SPECIFIER || - lastProp == IASTFunctionDefinition.DECLARATOR) { - if (!inInitializer) + final ASTNodeProperty nameProp = name.getPropertyInParent(); + if (nameProp == IASTIdExpression.ID_NAME || + nameProp == IASTFieldReference.FIELD_NAME || + nameProp == ICASTFieldDesignator.FIELD_NAME || + nameProp == ICPPASTUsingDirective.QUALIFIED_NAME || + nameProp == ICPPASTUsingDeclaration.NAME || + nameProp == IASTFunctionCallExpression.FUNCTION_NAME || + nameProp == IASTNamedTypeSpecifier.NAME || + nameProp == ICPPASTConstructorChainInitializer.MEMBER_ID) { + // Potentially we need to consider the entire class scope + } else { + return false; + } + + + for (; node != null; node= node.getParent()) { + // 3.3.7-5 + if (node.getParent() instanceof IASTFunctionDefinition) { + // In a function body + final ASTNodeProperty prop = node.getPropertyInParent(); + if (prop == IASTFunctionDefinition.DECL_SPECIFIER || + prop == IASTFunctionDefinition.DECLARATOR) { return false; + } + IASTNode parent = node.getParent(); + while (parent != null) { + if (parent instanceof ICPPASTCompositeTypeSpecifier) + return true; + parent= parent.getParent(); + } + // No inline method. + return false; } - - while (parent.getParent() instanceof ICPPASTTemplateDeclaration) - parent = parent.getParent(); - if (parent.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION) - return false; - - ASTNodeProperty prop = name.getPropertyInParent(); - if (prop == IASTIdExpression.ID_NAME || - prop == IASTFieldReference.FIELD_NAME || - prop == ICASTFieldDesignator.FIELD_NAME || - prop == ICPPASTUsingDirective.QUALIFIED_NAME || - prop == ICPPASTUsingDeclaration.NAME || - prop == IASTFunctionCallExpression.FUNCTION_NAME || - prop == IASTNamedTypeSpecifier.NAME || - prop == ICPPASTConstructorChainInitializer.MEMBER_ID) { - return true; - } + if (node instanceof IASTInitializerList || node instanceof IASTEqualsInitializer) { + if (node.getPropertyInParent() == IASTDeclarator.INITIALIZER) { + IASTNode decl= node.getParent(); + while (decl instanceof IASTDeclarator) { + decl= decl.getParent(); + } + if (decl instanceof IASTParameterDeclaration) { + // Default argument + IASTNode parent = decl.getParent(); + while (parent != null) { + if (parent instanceof ICPPASTCompositeTypeSpecifier) + return true; + parent= parent.getParent(); + } + // Not within a class definition + return false; + } + + if (decl instanceof IASTSimpleDeclaration && + decl.getPropertyInParent() == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) { + // Initializer of non-static data member + IASTDeclSpecifier declSpec= ((IASTSimpleDeclaration) decl).getDeclSpecifier(); + if (declSpec.getStorageClass() != IASTDeclSpecifier.sc_static) { + return true; + } + // Continue search, we could still be in a method. + } + } + } } return false; }