mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 00:45:28 +02:00
Bug 395243 - Error involving dependent expressions
Change-Id: Iabd115b40d0b7b633c416171a19a981f1e51dee8 Reviewed-on: https://git.eclipse.org/r/9211 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
parent
67ac152401
commit
f0e663e7cf
10 changed files with 150 additions and 49 deletions
|
@ -6938,7 +6938,70 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
// static const int value = sizeof(waldo(f));
|
||||
// };
|
||||
// typedef identity<Int<S<>::value>>::type reference;
|
||||
public void _testDependentExpressions_395243() throws Exception {
|
||||
public void testDependentExpressions_395243a() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// typedef char one;
|
||||
// typedef struct {
|
||||
// char arr[2];
|
||||
// } two;
|
||||
// template <typename T>
|
||||
// struct has_foo_type {
|
||||
// template <typename _Up>
|
||||
// struct wrap_type { };
|
||||
// template <typename U>
|
||||
// static one test(wrap_type<typename U::foo_type>*);
|
||||
// template <typename U>
|
||||
// static two test(...);
|
||||
// static const bool value = sizeof(test<T>(0)) == 1;
|
||||
// };
|
||||
// template <bool>
|
||||
// struct traits;
|
||||
// template <>
|
||||
// struct traits<true> {
|
||||
// typedef int bar_type;
|
||||
// };
|
||||
// struct S {
|
||||
// typedef int foo_type;
|
||||
// };
|
||||
// traits<has_foo_type<S>::value>::bar_type a;
|
||||
public void testDependentExpressions_395243b() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// template <typename U> U bar(U);
|
||||
// template <typename T> auto waldo(T t) -> decltype(bar(t));
|
||||
// struct S {
|
||||
// void foo() const;
|
||||
// };
|
||||
// struct V {
|
||||
// S arr[5];
|
||||
// };
|
||||
// int main() {
|
||||
// V e;
|
||||
// auto v = waldo(e);
|
||||
// for (auto s : v.arr)
|
||||
// s.foo();
|
||||
// }
|
||||
public void testDependentExpressions_395243c() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// template <typename> class C {};
|
||||
// template <typename T> int begin(C<T>);
|
||||
// template <typename>
|
||||
// struct A {
|
||||
// class B {
|
||||
// void m();
|
||||
// };
|
||||
// void test() {
|
||||
// B* v[5];
|
||||
// for (auto x : v)
|
||||
// x->m();
|
||||
// }
|
||||
// };
|
||||
public void testDependentExpressions_395243d() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,12 +8,11 @@
|
|||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
* Nathan Ridge
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
|
@ -30,19 +29,32 @@ public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPFuncti
|
|||
private static final ICPPFunctionType FUNCTION_TYPE=
|
||||
new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY);
|
||||
|
||||
public static ICPPFunction createForSample(IFunction sample) throws DOMException {
|
||||
if (sample instanceof ICPPConstructor)
|
||||
return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner());
|
||||
/**
|
||||
* Creates a CPPDeferredFunction given a set of overloaded functions
|
||||
* (some of which may be templates) that the function might resolve to.
|
||||
* At least one candidate must be provided.
|
||||
* @param candidates a set of overloaded functions, some of which may be templates
|
||||
* @return the constructed CPPDeferredFunction
|
||||
*/
|
||||
public static ICPPFunction createForCandidates(ICPPFunction... candidates) {
|
||||
if (candidates[0] instanceof ICPPConstructor)
|
||||
return new CPPUnknownConstructor(((ICPPConstructor) candidates[0]).getClassOwner(), candidates);
|
||||
|
||||
final IBinding owner = sample.getOwner();
|
||||
return new CPPDeferredFunction(owner, sample.getNameCharArray());
|
||||
final IBinding owner = candidates[0].getOwner();
|
||||
return new CPPDeferredFunction(owner, candidates[0].getNameCharArray(), candidates);
|
||||
}
|
||||
|
||||
private final IBinding fOwner;
|
||||
private final ICPPFunction[] fCandidates;
|
||||
|
||||
public CPPDeferredFunction(IBinding owner, char[] name) {
|
||||
public CPPDeferredFunction(IBinding owner, char[] name, ICPPFunction[] candidates) {
|
||||
super(name);
|
||||
fOwner= owner;
|
||||
fCandidates = candidates;
|
||||
}
|
||||
|
||||
public ICPPFunction[] getCandidates() {
|
||||
return fCandidates;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Thomas Corbat (IFS)
|
||||
* Nathan Ridge
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
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.ICPPFunction;
|
||||
|
||||
/**
|
||||
* Represents a reference to a constructor (instance), which cannot be resolved because
|
||||
|
@ -21,7 +23,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
|||
public class CPPUnknownConstructor extends CPPDeferredFunction implements ICPPConstructor {
|
||||
|
||||
public CPPUnknownConstructor(ICPPClassType owner) {
|
||||
super(owner, owner.getNameCharArray());
|
||||
super(owner, owner.getNameCharArray(), null);
|
||||
}
|
||||
|
||||
public CPPUnknownConstructor(ICPPClassType owner, ICPPFunction[] candidates) {
|
||||
super(owner, owner.getNameCharArray(), candidates);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -92,7 +92,7 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding {
|
|||
|
||||
public void setToUnknown() {
|
||||
if (fName != null) {
|
||||
fName.setBinding(new CPPDeferredFunction(null, fName.toCharArray()));
|
||||
fName.setBinding(new CPPDeferredFunction(null, fName.toCharArray(), fBindings));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* Sergey Prigogin (Google)
|
||||
* Mike Kucera (IBM)
|
||||
* Thomas Corbat (IFS)
|
||||
* Nathan Ridge
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||
|
||||
|
@ -451,7 +452,7 @@ public class CPPSemantics {
|
|||
final ASTNodeProperty namePropertyInParent = name.getPropertyInParent();
|
||||
if (binding == null && data.skippedScope != null) {
|
||||
if (data.hasFunctionArguments()) {
|
||||
binding= new CPPDeferredFunction(data.skippedScope, name.getSimpleID());
|
||||
binding= new CPPDeferredFunction(data.skippedScope, name.getSimpleID(), null);
|
||||
} else {
|
||||
if (namePropertyInParent == IASTNamedTypeSpecifier.NAME) {
|
||||
binding= new CPPUnknownMemberClass(data.skippedScope, name.getSimpleID());
|
||||
|
@ -2395,7 +2396,7 @@ public class CPPSemantics {
|
|||
if (viableCount == 1)
|
||||
return fns[0];
|
||||
setTargetedFunctionsToUnknown(argTypes);
|
||||
return CPPDeferredFunction.createForSample(fns[0]);
|
||||
return CPPDeferredFunction.createForCandidates(fns);
|
||||
}
|
||||
|
||||
IFunction[] ambiguousFunctions= null; // ambiguity, 2 functions are equally good
|
||||
|
@ -2403,7 +2404,7 @@ public class CPPSemantics {
|
|||
|
||||
// Loop over all functions
|
||||
List<FunctionCost> potentialCosts= null;
|
||||
IFunction unknownFunction= null;
|
||||
ICPPFunction unknownFunction= null;
|
||||
final CPPASTTranslationUnit tu = data.getTranslationUnit();
|
||||
for (ICPPFunction fn : fns) {
|
||||
if (fn == null)
|
||||
|
@ -2455,7 +2456,7 @@ public class CPPSemantics {
|
|||
return null;
|
||||
|
||||
setTargetedFunctionsToUnknown(argTypes);
|
||||
return CPPDeferredFunction.createForSample(unknownFunction);
|
||||
return CPPDeferredFunction.createForCandidates(fns);
|
||||
}
|
||||
|
||||
if (ambiguousFunctions != null) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
* Thomas Corbat (IFS)
|
||||
* Nathan Ridge
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||
|
||||
|
@ -163,7 +164,6 @@ public class CPPTemplates {
|
|||
static final int PACK_SIZE_DEFER = -1;
|
||||
static final int PACK_SIZE_FAIL = -2;
|
||||
static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
|
||||
private static final ICPPFunction[] NO_FUNCTIONS = {};
|
||||
static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE }
|
||||
|
||||
/**
|
||||
|
@ -1750,18 +1750,12 @@ public class CPPTemplates {
|
|||
requireTemplate= false;
|
||||
|
||||
if (func instanceof ICPPFunctionTemplate) {
|
||||
ICPPFunctionTemplate template= (ICPPFunctionTemplate) func;
|
||||
try {
|
||||
if (containsDependentType(fnArgs))
|
||||
return new ICPPFunction[] {CPPDeferredFunction.createForSample(template)};
|
||||
if (containsDependentType(fnArgs))
|
||||
return new ICPPFunction[] {CPPDeferredFunction.createForCandidates(fns)};
|
||||
|
||||
if (requireTemplate && hasDependentArgument(tmplArgs))
|
||||
return new ICPPFunction[] {CPPDeferredFunction.createForCandidates(fns)};
|
||||
|
||||
if (requireTemplate) {
|
||||
if (hasDependentArgument(tmplArgs))
|
||||
return new ICPPFunction[] {CPPDeferredFunction.createForSample(template)};
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
return NO_FUNCTIONS;
|
||||
}
|
||||
haveTemplate= true;
|
||||
break;
|
||||
}
|
||||
|
@ -1827,15 +1821,11 @@ public class CPPTemplates {
|
|||
|
||||
// Extract template arguments and parameter types.
|
||||
if (!checkedForDependentType) {
|
||||
try {
|
||||
if (isDependentType(conversionType)) {
|
||||
inst= CPPDeferredFunction.createForSample(template);
|
||||
done= true;
|
||||
}
|
||||
checkedForDependentType= true;
|
||||
} catch (DOMException e) {
|
||||
return functions;
|
||||
if (isDependentType(conversionType)) {
|
||||
inst= CPPDeferredFunction.createForCandidates(functions);
|
||||
done= true;
|
||||
}
|
||||
checkedForDependentType= true;
|
||||
}
|
||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
|
||||
try {
|
||||
|
@ -1893,7 +1883,7 @@ public class CPPTemplates {
|
|||
ICPPTemplateArgument[] args, IASTNode point) {
|
||||
try {
|
||||
if (target != null && isDependentType(target)) {
|
||||
return CPPDeferredFunction.createForSample(template);
|
||||
return CPPDeferredFunction.createForCandidates(template);
|
||||
}
|
||||
|
||||
if (template instanceof ICPPConstructor || args == null)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
* Thomas Corbat (IFS)
|
||||
* Nathan Ridge
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||
|
||||
|
@ -2017,11 +2018,13 @@ public class CPPVisitor extends ASTQueries {
|
|||
IBinding b= implicits[0].getBinding();
|
||||
CPPASTName name= new CPPASTName();
|
||||
name.setBinding(b);
|
||||
IASTInitializerClause[] beginCallArguments = new IASTInitializerClause[] { forInit.copy() };
|
||||
if (b instanceof ICPPMethod && forInit instanceof IASTExpression) {
|
||||
beginExpr= new CPPASTFunctionCallExpression(
|
||||
new CPPASTFieldReference(name, (IASTExpression) forInit.copy()), NO_ARGS);
|
||||
new CPPASTFieldReference(name, (IASTExpression) forInit.copy()),
|
||||
beginCallArguments);
|
||||
} else {
|
||||
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), NO_ARGS);
|
||||
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), beginCallArguments);
|
||||
}
|
||||
} else {
|
||||
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
* Nathan Ridge
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||
|
||||
|
@ -362,6 +363,13 @@ public class EvalBinding extends CPPEvaluation {
|
|||
binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner,
|
||||
binding, point);
|
||||
}
|
||||
} else if (binding instanceof ICPPParameter) {
|
||||
ICPPParameter parameter = (ICPPParameter) binding;
|
||||
IType originalType = parameter.getType();
|
||||
IType type = CPPTemplates.instantiateType(originalType, tpMap, packOffset, within, point);
|
||||
if (originalType != type) {
|
||||
return new EvalFixed(type, ValueCategory.LVALUE, Value.create(this));
|
||||
}
|
||||
}
|
||||
if (binding == fBinding)
|
||||
return this;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
* Nathan Ridge
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||
|
||||
|
@ -23,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
|||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||
|
@ -145,12 +147,16 @@ public class EvalFunctionSet extends CPPEvaluation {
|
|||
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
|
||||
ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments();
|
||||
ICPPTemplateArgument[] arguments = originalArguments;
|
||||
arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point);
|
||||
if (originalArguments != null)
|
||||
arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point);
|
||||
|
||||
IBinding originalOwner = fFunctionSet.getOwner();
|
||||
IBinding owner = originalOwner;
|
||||
if (originalOwner instanceof ICPPUnknownBinding) {
|
||||
if (owner instanceof ICPPUnknownBinding) {
|
||||
owner = resolveUnknown((ICPPUnknownBinding) owner, tpMap, packOffset, within, point);
|
||||
} else if (owner instanceof ICPPClassTemplate) {
|
||||
owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner),
|
||||
tpMap, packOffset, within, point);
|
||||
} else if (owner instanceof IType) {
|
||||
IType type = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point);
|
||||
if (type instanceof IBinding)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
* Nathan Ridge
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||
|
||||
|
@ -48,6 +49,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.Value;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -184,15 +186,6 @@ public class EvalID extends CPPEvaluation {
|
|||
return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr));
|
||||
}
|
||||
if (binding instanceof ICPPUnknownBinding) {
|
||||
IBinding owner = binding.getOwner();
|
||||
if (owner instanceof IProblemBinding)
|
||||
return EvalFixed.INCOMPLETE;
|
||||
|
||||
ICPPEvaluation fieldOwner= null;
|
||||
IType fieldOwnerType= withinNonStaticMethod(expr);
|
||||
if (fieldOwnerType != null) {
|
||||
fieldOwner= new EvalFixed(fieldOwnerType, ValueCategory.LVALUE, Value.UNKNOWN);
|
||||
}
|
||||
ICPPTemplateArgument[] templateArgs = null;
|
||||
final IASTName lastName = name.getLastName();
|
||||
if (lastName instanceof ICPPASTTemplateId) {
|
||||
|
@ -202,6 +195,25 @@ public class EvalID extends CPPEvaluation {
|
|||
return EvalFixed.INCOMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
if (binding instanceof CPPDeferredFunction) {
|
||||
CPPDeferredFunction deferredFunction = (CPPDeferredFunction) binding;
|
||||
if (deferredFunction.getCandidates() != null) {
|
||||
CPPFunctionSet functionSet = new CPPFunctionSet(deferredFunction.getCandidates(), templateArgs, null);
|
||||
return new EvalFunctionSet(functionSet, isAddressOf(expr));
|
||||
}
|
||||
}
|
||||
|
||||
IBinding owner = binding.getOwner();
|
||||
if (owner instanceof IProblemBinding)
|
||||
return EvalFixed.INCOMPLETE;
|
||||
|
||||
ICPPEvaluation fieldOwner= null;
|
||||
IType fieldOwnerType= withinNonStaticMethod(expr);
|
||||
if (fieldOwnerType != null) {
|
||||
fieldOwner= new EvalFixed(fieldOwnerType, ValueCategory.LVALUE, Value.UNKNOWN);
|
||||
}
|
||||
|
||||
return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr),
|
||||
name instanceof ICPPASTQualifiedName, templateArgs);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue