1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

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>
This commit is contained in:
Nathan Ridge 2014-10-22 04:16:59 -04:00 committed by Sergey Prigogin
parent 8e5a31e714
commit f9f0d4c3da
10 changed files with 154 additions and 10 deletions

View file

@ -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());
}
}

View file

@ -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());
}
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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;
@ -1344,6 +1346,18 @@ public class CPPTemplates {
}
}
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);
if (unwound instanceof ICPPClassType && unwound.isSameType(getSpecializedType(within))) {

View file

@ -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;
}
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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$