mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-04 07:35:24 +02:00
Bug 417050 - Organize Includes adds includes for template parameters of
unique_ptr.
This commit is contained in:
parent
7372e983a1
commit
0df9d9c211
4 changed files with 94 additions and 13 deletions
|
@ -830,7 +830,7 @@ public class ClassTypeHelper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ICPPMethod getMethodInClass(ICPPClassType ct, MethodKind kind, IASTNode point) {
|
public static ICPPMethod getMethodInClass(ICPPClassType ct, MethodKind kind, IASTNode point) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case DEFAULT_CTOR:
|
case DEFAULT_CTOR:
|
||||||
case COPY_CTOR:
|
case COPY_CTOR:
|
||||||
|
|
|
@ -22,6 +22,13 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
@ -207,13 +214,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexScope;
|
import org.eclipse.cdt.internal.core.index.IIndexScope;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collection of methods to extract information from a C++ translation unit.
|
* Collection of methods to extract information from a C++ translation unit.
|
||||||
*/
|
*/
|
||||||
|
@ -225,7 +225,7 @@ public class CPPVisitor extends ASTQueries {
|
||||||
public static final String BEGIN_STR = "begin"; //$NON-NLS-1$
|
public static final String BEGIN_STR = "begin"; //$NON-NLS-1$
|
||||||
public static final char[] BEGIN = BEGIN_STR.toCharArray();
|
public static final char[] BEGIN = BEGIN_STR.toCharArray();
|
||||||
public static final char[] END = "end".toCharArray(); //$NON-NLS-1$
|
public static final char[] END = "end".toCharArray(); //$NON-NLS-1$
|
||||||
static final String STD = "std"; //$NON-NLS-1$
|
public static final String STD = "std"; //$NON-NLS-1$
|
||||||
private static final char[] SIZE_T = "size_t".toCharArray(); //$NON-NLS-1$
|
private static final char[] SIZE_T = "size_t".toCharArray(); //$NON-NLS-1$
|
||||||
private static final char[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$
|
private static final char[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$
|
||||||
private static final char[] TYPE_INFO = "type_info".toCharArray(); //$NON-NLS-1$
|
private static final char[] TYPE_INFO = "type_info".toCharArray(); //$NON-NLS-1$
|
||||||
|
|
|
@ -395,6 +395,38 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase {
|
||||||
assertDeclared();
|
assertDeclared();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// namespace std {
|
||||||
|
// template<typename T> class shared_ptr {};
|
||||||
|
// template<typename T> class unique_ptr {};
|
||||||
|
// }
|
||||||
|
// class A {};
|
||||||
|
// class B {};
|
||||||
|
// class C {};
|
||||||
|
|
||||||
|
// using std::unique_ptr;
|
||||||
|
// using std::shared_ptr;
|
||||||
|
//
|
||||||
|
// struct P {
|
||||||
|
// ~P();
|
||||||
|
// shared_ptr<A> x;
|
||||||
|
// unique_ptr<A> y;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// struct Q {
|
||||||
|
// ~Q() {}
|
||||||
|
// shared_ptr<B> x;
|
||||||
|
// unique_ptr<B> y;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// void test() {
|
||||||
|
// shared_ptr<C> x;
|
||||||
|
// unique_ptr<C> y;
|
||||||
|
// }
|
||||||
|
public void testTemplatesAllowingIncompleteParameterType() throws Exception {
|
||||||
|
assertDefined("B", "C", "shared_ptr", "unique_ptr");
|
||||||
|
assertDeclared("A");
|
||||||
|
}
|
||||||
|
|
||||||
// struct A {};
|
// struct A {};
|
||||||
// struct B {};
|
// struct B {};
|
||||||
// struct C {};
|
// struct C {};
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.includes;
|
package org.eclipse.cdt.internal.ui.refactoring.includes;
|
||||||
|
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor.STD;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ARRAY;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ARRAY;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.PTR;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.PTR;
|
||||||
|
@ -18,6 +19,8 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -76,14 +79,17 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
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.ICPPASTNamedTypeSpecifier;
|
||||||
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.ICPPASTTemplateId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
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;
|
||||||
|
@ -98,12 +104,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
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.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.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.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions;
|
||||||
|
@ -126,6 +134,15 @@ public class BindingClassifier {
|
||||||
private final BindingCollector fBindingCollector;
|
private final BindingCollector fBindingCollector;
|
||||||
private final Set<IBinding> fProcessedDefinedBindings;
|
private final Set<IBinding> fProcessedDefinedBindings;
|
||||||
private final Set<IBinding> fProcessedDeclaredBindings;
|
private final Set<IBinding> fProcessedDeclaredBindings;
|
||||||
|
private static final Set<String> templatesAllowingIncompleteArgumentType =
|
||||||
|
Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(new String[] {
|
||||||
|
"enable_shared_from_this", // 20.7.2.4 //$NON-NLS-1$
|
||||||
|
"declval", // 20.2.4 //$NON-NLS-1$
|
||||||
|
"default_delete", // 20.7.1.1 //$NON-NLS-1$
|
||||||
|
"shared_ptr", // 20.7.2.2 //$NON-NLS-1$
|
||||||
|
"unique_ptr", // 20.7.1 //$NON-NLS-1$
|
||||||
|
"weak_ptr" // 20.7.2.3 //$NON-NLS-1$
|
||||||
|
})));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param context the context for binding classification
|
* @param context the context for binding classification
|
||||||
|
@ -1122,7 +1139,7 @@ public class BindingClassifier {
|
||||||
|
|
||||||
IBinding binding = name.resolveBinding();
|
IBinding binding = name.resolveBinding();
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
if (isInTemplateArgument(name)) {
|
if (isTemplateArgumentRequiringCompleteType(name)) {
|
||||||
// The name is part of a template argument - define the corresponding binding.
|
// The name is part of a template argument - define the corresponding binding.
|
||||||
defineBinding(binding);
|
defineBinding(binding);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1171,9 +1188,41 @@ public class BindingClassifier {
|
||||||
/**
|
/**
|
||||||
* Checks if the given name is part of a template argument.
|
* Checks if the given name is part of a template argument.
|
||||||
*/
|
*/
|
||||||
public boolean isInTemplateArgument(IASTName name) {
|
public boolean isTemplateArgumentRequiringCompleteType(IASTName name) {
|
||||||
ICPPASTTypeId typeId = CPPVisitor.findAncestorWithType(name, ICPPASTTypeId.class);
|
ICPPASTTypeId typeId = CPPVisitor.findAncestorWithType(name, ICPPASTTypeId.class);
|
||||||
return typeId != null && typeId.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT;
|
if (typeId == null || typeId.getPropertyInParent() != ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT)
|
||||||
|
return false;
|
||||||
|
ICPPASTTemplateId templateId = (ICPPASTTemplateId) typeId.getParent();
|
||||||
|
IBinding template = templateId.resolveBinding();
|
||||||
|
if (template instanceof IProblemBinding)
|
||||||
|
return true;
|
||||||
|
IBinding owner = template.getOwner();
|
||||||
|
if (!(owner instanceof ICPPNamespace) ||
|
||||||
|
!CharArrayUtils.equals(owner.getNameCharArray(), STD) || owner.getOwner() != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String templateName = template.getName();
|
||||||
|
if (!templatesAllowingIncompleteArgumentType.contains(templateName))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// For most templates allowing incomplete argument type a full definition of the argument
|
||||||
|
// type is required if the destructor is called. Since the AST doen't contain all destructor
|
||||||
|
// calling points, we have to use an indirect approach by examining the containing scope.
|
||||||
|
IASTNode parent = templateId.getParent();
|
||||||
|
if (!(parent instanceof ICPPASTNamedTypeSpecifier))
|
||||||
|
return false;
|
||||||
|
parent = parent.getParent();
|
||||||
|
if (!(parent instanceof IASTSimpleDeclaration))
|
||||||
|
return true;
|
||||||
|
parent = parent.getParent();
|
||||||
|
if (!(parent instanceof ICPPASTCompositeTypeSpecifier))
|
||||||
|
return true;
|
||||||
|
ICPPClassScope classScope = ((ICPPASTCompositeTypeSpecifier) parent).getScope();
|
||||||
|
ICPPClassType classType = classScope.getClassType();
|
||||||
|
ICPPMethod destructor = ClassTypeHelper.getMethodInClass(classType, MethodKind.DTOR, parent);
|
||||||
|
if (fAst.getDefinitionsInAST(destructor).length != 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isEnumerationWithoutFixedUnderlyingType(IBinding typeBinding) {
|
private static boolean isEnumerationWithoutFixedUnderlyingType(IBinding typeBinding) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue