1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 18:26:01 +02:00

Bug 442841 - Organize Includes adds an unnecessary include for the base

class of the type of a field
This commit is contained in:
Sergey Prigogin 2014-08-29 22:10:25 -07:00
parent e7cbbb7412
commit 096fae2b3e
3 changed files with 70 additions and 7 deletions

View file

@ -600,6 +600,23 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase {
assertDeclared(); assertDeclared();
} }
// struct A {
// void operator()();
// };
// struct B : public A {
// };
// struct C {
// B b;
// };
// void test(C* c) {
// c->b();
// }
public void testFieldAccess_442841() throws Exception {
assertDefined("C", "operator ()");
assertDeclared();
}
// struct A {}; // struct A {};
// struct B {}; // struct B {};
// struct C {}; // struct C {};

View file

@ -553,6 +553,34 @@ public class IncludeOrganizerTest extends IncludesTestBase {
assertExpectedResults(); assertExpectedResults();
} }
//h1.h
//struct A {
// void operator()();
//};
//struct B : public A {
//};
//h2.h
//#include "h1.h"
//
//struct C {
// B b;
//};
//source.cpp
//void test(C* c) {
// c->b();
//}
//====================
//#include "h2.h"
//
//void test(C* c) {
// c->b();
//}
public void testFieldAccess_442841() throws Exception {
assertExpectedResults();
}
//h1.h //h1.h
//namespace ns3 { //namespace ns3 {
//class C {}; //class C {};

View file

@ -142,7 +142,6 @@ public class BindingClassifier {
"unique_ptr", // 20.7.1 //$NON-NLS-1$ "unique_ptr", // 20.7.1 //$NON-NLS-1$
"weak_ptr" // 20.7.2.3 //$NON-NLS-1$ "weak_ptr" // 20.7.2.3 //$NON-NLS-1$
}; };
public enum InclusionType { DECLARATION, DEFINITION }
private class BindingCollector extends ASTVisitor { private class BindingCollector extends ASTVisitor {
BindingCollector() { BindingCollector() {
@ -399,7 +398,7 @@ public class BindingClassifier {
} }
} }
} else if (memberBinding instanceof ICPPConstructor) { } else if (memberBinding instanceof ICPPConstructor) {
// Class construction // Class construction.
ICPPConstructor constructor = (ICPPConstructor) memberBinding; ICPPConstructor constructor = (ICPPConstructor) memberBinding;
// We need to define the owning type of the constructor. // We need to define the owning type of the constructor.
@ -808,9 +807,24 @@ public class BindingClassifier {
} else { } else {
IBinding owner = binding.getOwner(); IBinding owner = binding.getOwner();
if (owner instanceof IType) { if (owner instanceof IType) {
defineBinding(owner); // Member access requires definition of the containing type. defineBinding(owner); // Member access requires definition of the containing type.
if (binding instanceof IProblemBinding) if (binding instanceof IProblemBinding)
declareBinding(binding); declareBinding(binding);
if (!isDefinedLocally(owner) &&
(!(binding instanceof ICPPMember) || !((ICPPMember) binding).isStatic())) {
// Record the fact that the header file defining the owner must also
// provide a definition of the type of this member (bug 442841).
IType type = null;
if (binding instanceof IVariable) {
type = ((IVariable) binding).getType();
} else if (binding instanceof IFunction) {
type = ((IFunction) binding).getType().getReturnType();
}
type = getNestedType(type, ALLCVQ);
if (type instanceof IBinding) {
markAsDefined((IBinding) type);
}
}
} else { } else {
declareBinding(binding); // Declare the binding of this name. declareBinding(binding); // Declare the binding of this name.
} }
@ -1051,8 +1065,8 @@ public class BindingClassifier {
} }
} }
} }
// Get the specialized binding - e.g. get the binding for X if the current binding is // Get the specialized binding - e.g. get the binding for X if the current binding
// for the template specialization X<Y>. // is for the template specialization X<Y>.
addRequiredBindings(((ICPPSpecialization) binding).getSpecializedBinding(), queue); addRequiredBindings(((ICPPSpecialization) binding).getSpecializedBinding(), queue);
} else { } else {
bindings.add(binding); bindings.add(binding);
@ -1217,7 +1231,7 @@ public class BindingClassifier {
private void defineBinding(IBinding binding) { private void defineBinding(IBinding binding) {
if (!markAsDefined(binding)) if (!markAsDefined(binding))
return; return;
if (binding instanceof CPPClosureType || fAst.getDefinitionsInAST(binding).length != 0) if (isDefinedLocally(binding))
return; // Defined locally. return; // Defined locally.
Collection<IBinding> requiredBindings = getRequiredBindings(binding); Collection<IBinding> requiredBindings = getRequiredBindings(binding);
@ -1226,13 +1240,17 @@ public class BindingClassifier {
if (requiredBinding != binding) { if (requiredBinding != binding) {
if (!markAsDefined(requiredBinding)) if (!markAsDefined(requiredBinding))
continue; continue;
if (fAst.getDefinitionsInAST(requiredBinding).length != 0) if (isDefinedLocally(requiredBinding))
continue; // Defined locally. continue; // Defined locally.
} }
fBindingsToDefine.add(requiredBinding); fBindingsToDefine.add(requiredBinding);
} }
} }
private boolean isDefinedLocally(IBinding binding) {
return binding instanceof CPPClosureType || fAst.getDefinitionsInAST(binding).length != 0;
}
private void defineBindingForName(IASTName name) { private void defineBindingForName(IASTName name) {
IBinding binding = name.resolveBinding(); IBinding binding = name.resolveBinding();
if (!isPartOfExternalMacroDefinition(name)) if (!isPartOfExternalMacroDefinition(name))