1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-31 21:05:37 +02:00

Bug 437630 - NPE in Organize Includes with a lambda expression

This commit is contained in:
Sergey Prigogin 2014-06-17 14:33:48 -07:00
parent 2163d2af4c
commit 852659fa1d
2 changed files with 20 additions and 7 deletions

View file

@ -579,6 +579,14 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase {
assertDeclared(); assertDeclared();
} }
// struct A {};
// auto lambda = [](A* a) { return *a; };
public void testLambdaExpression() throws Exception {
assertDefined("A");
assertDeclared();
}
// struct A {}; // struct A {};
// struct B {}; // struct B {};
// struct C {}; // struct C {};

View file

@ -87,6 +87,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBas
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
@ -116,6 +117,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper.MethodKind; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper.MethodKind;
@ -216,7 +218,7 @@ public class BindingClassifier {
if (declarator instanceof IASTFunctionDeclarator) { if (declarator instanceof IASTFunctionDeclarator) {
/* /*
* The type specifier of a function definition doesn't need to be defined if it is * The type specifier of a function definition doesn't need to be defined if it is
* a pointer or reference type. * a pointer or a reference type.
* *
* Example 1: * Example 1:
* X *foo() { } // definition of X is not required here * X *foo() { } // definition of X is not required here
@ -224,12 +226,16 @@ public class BindingClassifier {
* Example 2: * Example 2:
* X& foo() { } // definition of X is not required here * X& foo() { } // definition of X is not required here
*/ */
IBinding binding = declarator.getName().resolveBinding(); IASTName name = declarator.getPropertyInParent() == ICPPASTLambdaExpression.DECLARATOR ?
((ICPPASTLambdaExpression) declarator.getParent()).getFunctionCallOperatorName() :
declarator.getName();
IBinding binding = name.resolveBinding();
if (binding instanceof IFunction) { if (binding instanceof IFunction) {
IFunction function = (IFunction) binding; IFunction function = (IFunction) binding;
IFunctionType functionType = function.getType(); IFunctionType functionType = function.getType();
if (declarator.getPropertyInParent() == IASTFunctionDefinition.DECLARATOR) { if (declarator.getPropertyInParent() == IASTFunctionDefinition.DECLARATOR ||
declarator.getPropertyInParent() == ICPPASTLambdaExpression.DECLARATOR) {
// Define the return type if necessary. // Define the return type if necessary.
IType returnType = functionType.getReturnType(); IType returnType = functionType.getReturnType();
if (!(returnType instanceof IPointerType || returnType instanceof ICPPReferenceType)) { if (!(returnType instanceof IPointerType || returnType instanceof ICPPReferenceType)) {
@ -248,8 +254,8 @@ public class BindingClassifier {
} }
} else { } else {
// As a matter of policy, a function declaration is responsible for // As a matter of policy, a function declaration is responsible for
// providing definitions of parameter types that have implicit converting // providing definitions of parameter types that have implicit
// constructors. // converting constructors.
IType[] parameterTypes = functionType.getParameterTypes(); IType[] parameterTypes = functionType.getParameterTypes();
for (IType type : parameterTypes) { for (IType type : parameterTypes) {
if (!(type instanceof IPointerType)) { if (!(type instanceof IPointerType)) {
@ -260,7 +266,6 @@ public class BindingClassifier {
} }
} }
} }
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
@ -1209,7 +1214,7 @@ public class BindingClassifier {
private void defineBinding(IBinding binding) { private void defineBinding(IBinding binding) {
if (!markAsDefined(binding)) if (!markAsDefined(binding))
return; return;
if (fAst.getDefinitionsInAST(binding).length != 0) if (binding instanceof CPPClosureType || fAst.getDefinitionsInAST(binding).length != 0)
return; // Defined locally. return; // Defined locally.
Collection<IBinding> requiredBindings = getRequiredBindings(binding); Collection<IBinding> requiredBindings = getRequiredBindings(binding);