1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-05 07:15:39 +02:00

Bug 329172: Name lookup for default arguments within class bodies.

This commit is contained in:
Markus Schorn 2010-11-04 16:18:17 +00:00
parent ff18b15fdb
commit 7cedfa5e48
2 changed files with 81 additions and 40 deletions

View file

@ -6422,7 +6422,7 @@ public class AST2CPPTests extends AST2BaseTest {
// return b; // return b;
// } // }
// struct B {}; // struct B {};
// int& x = y; // y is not defined // static int& x = y; // y is not defined
// int y; // int y;
// }; // };
public void testScopeOfClassMember_259460() throws Exception { public void testScopeOfClassMember_259460() throws Exception {
@ -6439,7 +6439,7 @@ public class AST2CPPTests extends AST2BaseTest {
// int method(int a = GREEN) { // int method(int a = GREEN) {
// return RED; // return RED;
// } // }
// int x = GREEN; // GREEN is not defined // static int x = GREEN; // GREEN is not defined
// enum Color { // enum Color {
// RED, GREEN // RED, GREEN
// }; // };
@ -9281,4 +9281,13 @@ public class AST2CPPTests extends AST2BaseTest {
public void testOverrideUsingDeclaredMethod_328802() throws Exception { public void testOverrideUsingDeclaredMethod_328802() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// class A {
// A(int a = f()); // problem on f
// static int f();
// };
public void testFwdLookupForDefaultArgument() throws Exception {
parseAndCheckBindings();
}
} }

View file

@ -24,19 +24,22 @@ import java.util.Map;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; 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.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; 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;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; 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.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
@ -271,47 +274,76 @@ public class LookupData {
public static boolean checkWholeClassScope(IASTName name) { public static boolean checkWholeClassScope(IASTName name) {
if (name == null) if (name == null)
return false; return false;
if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY)
ASTNodeProperty lastProp= name.getPropertyInParent();
if (lastProp == CPPSemantics.STRING_LOOKUP_PROPERTY)
return true; return true;
boolean inInitializer= false; IASTNode node = name.getParent();
IASTNode parent = name.getParent(); while (node instanceof IASTName) {
while (parent instanceof IASTName) { name= (IASTName) node;
name= (IASTName) parent; node= name.getParent();
parent= name.getParent();
} }
while (parent != null && !(parent instanceof IASTFunctionDefinition)) { final ASTNodeProperty nameProp = name.getPropertyInParent();
if (parent instanceof IASTInitializer) { if (nameProp == IASTIdExpression.ID_NAME ||
inInitializer= true; nameProp == IASTFieldReference.FIELD_NAME ||
} nameProp == ICASTFieldDesignator.FIELD_NAME ||
lastProp= parent.getPropertyInParent(); nameProp == ICPPASTUsingDirective.QUALIFIED_NAME ||
parent = parent.getParent(); nameProp == ICPPASTUsingDeclaration.NAME ||
} nameProp == IASTFunctionCallExpression.FUNCTION_NAME ||
if (parent instanceof IASTFunctionDefinition) { nameProp == IASTNamedTypeSpecifier.NAME ||
if (lastProp == IASTFunctionDefinition.DECL_SPECIFIER || nameProp == ICPPASTConstructorChainInitializer.MEMBER_ID) {
lastProp == IASTFunctionDefinition.DECLARATOR) { // Potentially we need to consider the entire class scope
if (!inInitializer) } else {
return false; return false;
} }
while (parent.getParent() instanceof ICPPASTTemplateDeclaration)
parent = parent.getParent();
if (parent.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION)
return false;
ASTNodeProperty prop = name.getPropertyInParent(); for (; node != null; node= node.getParent()) {
if (prop == IASTIdExpression.ID_NAME || // 3.3.7-5
prop == IASTFieldReference.FIELD_NAME || if (node.getParent() instanceof IASTFunctionDefinition) {
prop == ICASTFieldDesignator.FIELD_NAME || // In a function body
prop == ICPPASTUsingDirective.QUALIFIED_NAME || final ASTNodeProperty prop = node.getPropertyInParent();
prop == ICPPASTUsingDeclaration.NAME || if (prop == IASTFunctionDefinition.DECL_SPECIFIER ||
prop == IASTFunctionCallExpression.FUNCTION_NAME || prop == IASTFunctionDefinition.DECLARATOR) {
prop == IASTNamedTypeSpecifier.NAME || return false;
prop == ICPPASTConstructorChainInitializer.MEMBER_ID) { }
IASTNode parent = node.getParent();
while (parent != null) {
if (parent instanceof ICPPASTCompositeTypeSpecifier)
return true; return true;
parent= parent.getParent();
}
// No inline method.
return false;
}
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; return false;