Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2014-10-22 08:16:59 +0000
committerSergey Prigogin2014-10-23 18:35:49 +0000
commitf9f0d4c3dabae48ef37619a751b1f72d638dcb75 (patch)
tree1d64103aa6305c966c98f2df4efc6b75e3110c36
parent8e5a31e714d28d2760b36168d48aa01bf828e211 (diff)
downloadorg.eclipse.cdt-f9f0d4c3dabae48ef37619a751b1f72d638dcb75.tar.gz
org.eclipse.cdt-f9f0d4c3dabae48ef37619a751b1f72d638dcb75.tar.xz
org.eclipse.cdt-f9f0d4c3dabae48ef37619a751b1f72d638dcb75.zip
Bug 447728 - Support for types of unkown fields
Change-Id: Id8ccc110930b86a762a847ff50a8659c87318a4b Signed-off-by: Nathan Ridge <zeratul976@hotmail.com> Reviewed-on: https://git.eclipse.org/r/35302 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java24
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java25
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownField.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMethod.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java14
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfUnknownMember.java63
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java21
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java3
10 files changed, 154 insertions, 10 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index ae43ce1fd74..1b9dbcd3b9b 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -8594,4 +8594,28 @@ public class AST2TemplateTests extends AST2TestBase {
public void testLocalTypeAsTemplateArgument_442832() throws Exception {
parseAndCheckBindings();
}
+
+ // template <typename T>
+ // struct Bar {};
+ //
+ // template <typename T>
+ // auto foo(T t) -> Bar<decltype(t.foo)> {
+ // Bar<decltype(t.foo)> bar; // bogus `invalid template arguments` error here
+ // return bar;
+ // }
+ //
+ // struct S {
+ // int foo;
+ // };
+ //
+ // int main() {
+ // Bar<int> var1;
+ // auto var2 = foo(S());
+ // }
+ public void testTypeOfUnknownMember_447728() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+ IVariable var1 = helper.assertNonProblem("var1");
+ IVariable var2 = helper.assertNonProblem("var2");
+ assertSameType(var1.getType(), var2.getType());
+ }
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java
index b00711fe5ec..2b743335d6d 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java
@@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue;
+import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
@@ -2606,4 +2607,28 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
public void testInfiniteRecursionMarshallingTemplateDefinition_439923() throws Exception {
checkBindings();
}
+
+
+ // template <typename T>
+ // struct Bar {};
+ //
+ // template <typename T>
+ // auto foo(T t) -> Bar<decltype(t.foo)> {
+ // Bar<decltype(t.foo)> bar; // bogus `invalid template arguments` error here
+ // return bar;
+ // }
+ //
+ // struct S {
+ // int foo;
+ // };
+
+ // int main() {
+ // Bar<int> var1;
+ // auto var2 = foo(S());
+ // }
+ public void testTypeOfUnknownMember_447728() throws Exception {
+ IVariable var1 = getBindingFromASTName("var1", 4);
+ IVariable var2 = getBindingFromASTName("var2", 4);
+ assertSameType(var1.getType(), var2.getType());
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java
index d6f37f32af1..62b74fd409d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java
@@ -39,6 +39,7 @@ public interface ITypeMarshalBuffer {
final static byte DEFERRED_CLASS_INSTANCE = 0x0E;
final static byte ALIAS_TEMPLATE = 0x0F;
final static byte TYPE_TRANSFORMATION = 0x10;
+ final static byte UNKNOWN_MEMBER_TYPE = 0x11;
// Can add more types up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
final static byte
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownField.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownField.java
index 7d6fde70206..4bdae24ed21 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownField.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownField.java
@@ -15,7 +15,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
-import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfUnknownMember;
/**
* Represents a reference to a field, which cannot be resolved because the owner is
@@ -78,7 +78,7 @@ public class CPPUnknownField extends CPPUnknownMember implements ICPPField {
@Override
public IType getType() {
- return ProblemType.UNKNOWN_FOR_EXPRESSION;
+ return new TypeOfUnknownMember(this);
}
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMethod.java
index 0219cb9c5b0..aad4047ed4d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMethod.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMethod.java
@@ -67,6 +67,10 @@ public class CPPUnknownMethod extends CPPUnknownMember implements ICPPMethod {
@Override
public ICPPFunctionType getType() {
+ // TODO(nathanridge): We'd like to return a TypeOfUnknownMember here,
+ // but that doesn't implement ICPPFuncionType. We'll probably have
+ // to write an implementation of ICPPFunctionType that stores the
+ // CPPUnknownMethod and resolves it upon instantiation.
return FUNCTION_TYPE;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
index 8ba60494cb3..25d840b2119 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
@@ -44,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
+import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
@@ -52,6 +53,7 @@ import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue;
+import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAliasDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
@@ -1343,6 +1345,18 @@ public class CPPTemplates {
return type;
}
}
+
+ if (type instanceof TypeOfUnknownMember) {
+ IBinding binding = resolveUnknown(((TypeOfUnknownMember) type).getUnknownMember(), tpMap, packOffset, within, point);
+ if (binding instanceof IType) {
+ return (IType) binding;
+ } else if (binding instanceof IVariable) {
+ return ((IVariable) binding).getType();
+ } else if (binding instanceof IFunction) {
+ return ((IFunction) binding).getType();
+ }
+ return type;
+ }
if (within != null && type instanceof IBinding) {
IType unwound= getNestedType(type, TDEF);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfUnknownMember.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfUnknownMember.java
new file mode 100644
index 00000000000..5f9fcbbe07b
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfUnknownMember.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Nathan Ridge.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Nathan Ridge - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
+import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMember;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
+import org.eclipse.cdt.internal.core.index.IIndexFragment;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * Represents the type of an unknown member.
+ */
+public class TypeOfUnknownMember implements ICPPUnknownType, ISerializableType {
+ private final CPPUnknownMember fMember;
+
+ public TypeOfUnknownMember(CPPUnknownMember member) {
+ fMember = member;
+ }
+
+ public CPPUnknownMember getUnknownMember() {
+ return fMember;
+ }
+
+ @Override
+ public boolean isSameType(IType type) {
+ return type instanceof TypeOfUnknownMember
+ && fMember == ((TypeOfUnknownMember) type).fMember;
+ }
+
+ @Override
+ public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
+ buffer.putShort(ITypeMarshalBuffer.UNKNOWN_MEMBER_TYPE);
+ fMember.marshal(buffer);
+ }
+
+ public static IType unmarshal(IIndexFragment fragment, short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
+ short firstBytesForMember = buffer.getShort();
+ if ((firstBytesForMember & ITypeMarshalBuffer.KIND_MASK) != ITypeMarshalBuffer.UNKNOWN_MEMBER)
+ throw new CoreException(CCorePlugin.createStatus("Expected an unknown memebr, first bytes=" + firstBytesForMember)); //$NON-NLS-1$;
+ return new TypeOfUnknownMember((CPPUnknownMember) CPPUnknownMember.unmarshal(fragment, firstBytesForMember, buffer));
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java
index 20c9c4e816d..09e8ed830f4 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java
@@ -70,6 +70,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMember;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
@@ -96,6 +97,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnaryTypeID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfDependentExpression;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfUnknownMember;
import org.eclipse.cdt.internal.core.index.CIndex;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.IIndexScope;
@@ -236,6 +238,13 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
return new TypeOfDependentExpression(e2);
return type;
}
+ if (rtype instanceof TypeOfUnknownMember) {
+ CPPUnknownMember member = ((TypeOfUnknownMember) rtype).getUnknownMember();
+ if (member instanceof IIndexFragmentBinding)
+ member = (CPPUnknownMember) getCompositeBinding((IIndexFragmentBinding) member);
+ return new TypeOfUnknownMember(member);
+
+ }
if (rtype instanceof ICPPUnaryTypeTransformation) {
ICPPUnaryTypeTransformation typeTransformation= (ICPPUnaryTypeTransformation) rtype;
IType operand = getCompositeType(typeTransformation.getOperand());
@@ -611,12 +620,6 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
} else {
throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$
}
- } else if (binding instanceof ICPPParameter) {
- result = new CompositeCPPParameter(this, (ICPPParameter) binding);
- } else if (binding instanceof ICPPField) {
- result = new CompositeCPPField(this, (ICPPField) binding);
- } else if (binding instanceof ICPPVariable) {
- result = new CompositeCPPVariable(this, (ICPPVariable) binding);
} else if (binding instanceof ICPPUnknownBinding) {
if (binding instanceof ICPPUnknownMember) {
ICPPUnknownMember def= (ICPPUnknownMember) binding;
@@ -636,6 +639,12 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
}
}
throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$
+ } else if (binding instanceof ICPPParameter) {
+ result = new CompositeCPPParameter(this, (ICPPParameter) binding);
+ } else if (binding instanceof ICPPField) {
+ result = new CompositeCPPField(this, (ICPPField) binding);
+ } else if (binding instanceof ICPPVariable) {
+ result = new CompositeCPPVariable(this, (ICPPVariable) binding);
} else if (binding instanceof ICPPClassType) {
ICPPClassType def = (ICPPClassType) findOneBinding(binding);
result = def == null ? null : new CompositeCPPClassType(this, def);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index a5edefd302b..5c0e2fe5814 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -255,10 +255,11 @@ public class PDOM extends PlatformObject implements IPDOM {
*
* CDT 8.6 development (versions not supported on the 8.5.x branch)
* 180.0 - Internal types of enumerators, bug 446711.
+ * 180.1 - Storing types of unknown members, bug 447728.
*/
- private static final int MIN_SUPPORTED_VERSION= version(180, 0);
+ private static final int MIN_SUPPORTED_VERSION= version(180, 1);
private static final int MAX_SUPPORTED_VERSION= version(180, Short.MAX_VALUE);
- private static final int DEFAULT_VERSION = version(180, 0);
+ private static final int DEFAULT_VERSION = version(180, 1);
private static int version(int major, int minor) {
return (major << 16) + minor;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
index 3a4af863c8b..ca8e4f6e4e7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
@@ -121,6 +121,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnaryTypeID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfDependentExpression;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfUnknownMember;
import org.eclipse.cdt.internal.core.index.IIndexBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.index.composite.CompositeIndexBinding;
@@ -1267,6 +1268,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
return CPPAliasTemplateInstance.unmarshal(firstBytes, buffer);
case ITypeMarshalBuffer.TYPE_TRANSFORMATION:
return CPPUnaryTypeTransformation.unmarshal(firstBytes, buffer);
+ case ITypeMarshalBuffer.UNKNOWN_MEMBER_TYPE:
+ return TypeOfUnknownMember.unmarshal(getPDOM(), firstBytes, buffer);
}
throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal a type, first bytes=" + firstBytes)); //$NON-NLS-1$

Back to the top