Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Prigogin2013-09-11 23:29:13 -0400
committerSergey Prigogin2013-09-11 23:29:13 -0400
commit0df9d9c211f0b32a7c758e29631fd68d55eba5bd (patch)
tree9cf9abbf589191c0c2651e3c2fa6a6df27559672
parent7372e983a16e7593835f108d1544e625e4e223b8 (diff)
downloadorg.eclipse.cdt-0df9d9c211f0b32a7c758e29631fd68d55eba5bd.tar.gz
org.eclipse.cdt-0df9d9c211f0b32a7c758e29631fd68d55eba5bd.tar.xz
org.eclipse.cdt-0df9d9c211f0b32a7c758e29631fd68d55eba5bd.zip
Bug 417050 - Organize Includes adds includes for template parameters of
unique_ptr.
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java16
-rw-r--r--core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/BindingClassifierTest.java32
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java57
4 files changed, 94 insertions, 13 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java
index d4a07c025c..83ee0dbb26 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java
@@ -830,7 +830,7 @@ public class ClassTypeHelper {
return null;
}
- private static ICPPMethod getMethodInClass(ICPPClassType ct, MethodKind kind, IASTNode point) {
+ public static ICPPMethod getMethodInClass(ICPPClassType ct, MethodKind kind, IASTNode point) {
switch (kind) {
case DEFAULT_CTOR:
case COPY_CTOR:
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index 20fb23c30a..e5c95a92a0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -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.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.ASTNodeProperty;
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.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.
*/
@@ -225,7 +225,7 @@ public class CPPVisitor extends ASTQueries {
public static final String BEGIN_STR = "begin"; //$NON-NLS-1$
public static final char[] BEGIN = BEGIN_STR.toCharArray();
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[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$
private static final char[] TYPE_INFO = "type_info".toCharArray(); //$NON-NLS-1$
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/BindingClassifierTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/BindingClassifierTest.java
index dad5e16e52..56ca50d774 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/BindingClassifierTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/BindingClassifierTest.java
@@ -395,6 +395,38 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase {
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 B {};
// struct C {};
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java
index 9fedffccac..e07f016b1d 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java
@@ -11,6 +11,7 @@
*******************************************************************************/
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.ARRAY;
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 java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
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.IVariable;
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.ICPPASTConstructorChainInitializer;
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.ICPPASTNamedTypeSpecifier;
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.ICPPASTTemplateId;
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.ICPPConstructor;
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.index.IIndexMacro;
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.cpp.CPPASTIdExpression;
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.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.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions;
@@ -126,6 +134,15 @@ public class BindingClassifier {
private final BindingCollector fBindingCollector;
private final Set<IBinding> fProcessedDefinedBindings;
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
@@ -1122,7 +1139,7 @@ public class BindingClassifier {
IBinding binding = name.resolveBinding();
if (binding != null) {
- if (isInTemplateArgument(name)) {
+ if (isTemplateArgumentRequiringCompleteType(name)) {
// The name is part of a template argument - define the corresponding binding.
defineBinding(binding);
} else {
@@ -1171,9 +1188,41 @@ public class BindingClassifier {
/**
* 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);
- 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) {
@@ -1197,4 +1246,4 @@ public class BindingClassifier {
}
return true;
}
-} \ No newline at end of file
+}

Back to the top