mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 10:16:03 +02:00
Bug 45203. Don't include headers defining superclasses if the header
defining a subclass is included.
This commit is contained in:
parent
56a7de8fa8
commit
4726136341
3 changed files with 35 additions and 12 deletions
|
@ -22,7 +22,6 @@ import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
|
@ -279,7 +278,7 @@ public class ClassTypeHelper {
|
||||||
/**
|
/**
|
||||||
* Returns all direct and indirect base classes.
|
* Returns all direct and indirect base classes.
|
||||||
* @param classType a class
|
* @param classType a class
|
||||||
* @return An array of visible base classes in arbitrary order.
|
* @return An array of base classes in arbitrary order.
|
||||||
*/
|
*/
|
||||||
public static ICPPClassType[] getAllBases(ICPPClassType classType, IASTNode point) {
|
public static ICPPClassType[] getAllBases(ICPPClassType classType, IASTNode point) {
|
||||||
HashSet<ICPPClassType> result= new HashSet<ICPPClassType>();
|
HashSet<ICPPClassType> result= new HashSet<ICPPClassType>();
|
||||||
|
|
|
@ -146,7 +146,7 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase {
|
||||||
assertDeclared();
|
assertDeclared();
|
||||||
}
|
}
|
||||||
|
|
||||||
// class A { int x; };
|
// struct A { int x; };
|
||||||
// typedef A* td;
|
// typedef A* td;
|
||||||
// td f();
|
// td f();
|
||||||
|
|
||||||
|
@ -156,6 +156,18 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase {
|
||||||
assertDeclared();
|
assertDeclared();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct A { void m(); };
|
||||||
|
// class B : public A {};
|
||||||
|
// B b;
|
||||||
|
|
||||||
|
// void test() {
|
||||||
|
// b.m();
|
||||||
|
// }
|
||||||
|
public void testClassHierarchy() throws Exception {
|
||||||
|
assertDefined("b", "B");
|
||||||
|
assertDeclared();
|
||||||
|
}
|
||||||
|
|
||||||
// class A { void m(); };
|
// class A { void m(); };
|
||||||
|
|
||||||
// void test(A* a) {
|
// void test(A* a) {
|
||||||
|
|
|
@ -82,6 +82,7 @@ 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.ICPPASTNewExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
|
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.ICPPConstructor;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
|
||||||
|
@ -93,6 +94,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
|
||||||
import org.eclipse.cdt.core.index.IIndexMacro;
|
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||||
import org.eclipse.cdt.core.index.IndexFilter;
|
import org.eclipse.cdt.core.index.IndexFilter;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -377,6 +379,15 @@ public class BindingClassifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void defineBindingForName(IASTName name) {
|
||||||
|
IBinding binding = name.resolveBinding();
|
||||||
|
if (isPartOfExternalMacroDefinition(name)) {
|
||||||
|
markAsDefined(binding);
|
||||||
|
} else {
|
||||||
|
defineBinding(binding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the given binding as defined.
|
* Marks the given binding as defined.
|
||||||
*
|
*
|
||||||
|
@ -393,7 +404,13 @@ public class BindingClassifier {
|
||||||
type = SemanticUtil.getNestedType(type, ALLCVQ);
|
type = SemanticUtil.getNestedType(type, ALLCVQ);
|
||||||
if (type instanceof IBinding) {
|
if (type instanceof IBinding) {
|
||||||
// Record the fact that we also have a definition of the typedef's target type.
|
// Record the fact that we also have a definition of the typedef's target type.
|
||||||
fProcessedDefinedBindings.add((IBinding) type);
|
markAsDefined((IBinding) type);
|
||||||
|
}
|
||||||
|
} else if (binding instanceof ICPPClassType) {
|
||||||
|
// The header that defines a class must provide definitions of all its base classes.
|
||||||
|
ICPPClassType[] bases = ClassTypeHelper.getAllBases((ICPPClassType) binding, fAst);
|
||||||
|
for (ICPPClassType base : bases) {
|
||||||
|
fProcessedDefinedBindings.add(base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,12 +487,7 @@ public class BindingClassifier {
|
||||||
|
|
||||||
if (!canBeDeclared) {
|
if (!canBeDeclared) {
|
||||||
IASTName name = ((IASTNamedTypeSpecifier) declSpecifier).getName();
|
IASTName name = ((IASTNamedTypeSpecifier) declSpecifier).getName();
|
||||||
IBinding binding = name.resolveBinding();
|
defineBindingForName(name);
|
||||||
if (isPartOfExternalMacroDefinition(name)) {
|
|
||||||
markAsDefined(binding);
|
|
||||||
} else {
|
|
||||||
defineBinding(binding);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (declaration instanceof IASTFunctionDefinition) {
|
} else if (declaration instanceof IASTFunctionDefinition) {
|
||||||
|
@ -519,7 +531,7 @@ public class BindingClassifier {
|
||||||
* Example:
|
* Example:
|
||||||
* class Y : X {}; // definition of X is required here
|
* class Y : X {}; // definition of X is required here
|
||||||
*/
|
*/
|
||||||
defineBinding(baseSpecifier.getName().resolveBinding());
|
defineBindingForName(baseSpecifier.getName());
|
||||||
return PROCESS_CONTINUE;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -711,7 +723,7 @@ public class BindingClassifier {
|
||||||
IASTDeclSpecifier declSpecifier = simpleDeclaration.getDeclSpecifier();
|
IASTDeclSpecifier declSpecifier = simpleDeclaration.getDeclSpecifier();
|
||||||
if (declSpecifier instanceof IASTNamedTypeSpecifier) {
|
if (declSpecifier instanceof IASTNamedTypeSpecifier) {
|
||||||
IASTNamedTypeSpecifier namedTypeSpecifier = (IASTNamedTypeSpecifier) declSpecifier;
|
IASTNamedTypeSpecifier namedTypeSpecifier = (IASTNamedTypeSpecifier) declSpecifier;
|
||||||
defineBinding(namedTypeSpecifier.getName().resolveBinding());
|
defineBindingForName(namedTypeSpecifier.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue