mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-31 12:55:40 +02:00
Bug 408296 - [regression] ADL performed for qualified name
Change-Id: Ide4f592509bd0a7fff449db356a34507e4c5299c Reviewed-on: https://git.eclipse.org/r/12910 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
eecdf502d1
commit
807f937284
5 changed files with 62 additions and 19 deletions
|
@ -2277,4 +2277,28 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
public void testIntNullPointerConstant_407808() throws Exception {
|
public void testIntNullPointerConstant_407808() throws Exception {
|
||||||
checkBindings();
|
checkBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// namespace bar {
|
||||||
|
// template<class T>
|
||||||
|
// void join(T);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// namespace foo {
|
||||||
|
// template<typename T>
|
||||||
|
// void join(T);
|
||||||
|
//
|
||||||
|
// struct cat {};
|
||||||
|
// }
|
||||||
|
|
||||||
|
// template <typename T>
|
||||||
|
// auto waldo(T t) -> decltype(bar::join(t));
|
||||||
|
//
|
||||||
|
// int main() {
|
||||||
|
// waldo(foo::cat{});
|
||||||
|
// }
|
||||||
|
public void testADLForQualifiedName_408296() throws Exception {
|
||||||
|
checkBindings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
*/
|
*/
|
||||||
public class EvalFunctionSet extends CPPDependentEvaluation {
|
public class EvalFunctionSet extends CPPDependentEvaluation {
|
||||||
private final CPPFunctionSet fFunctionSet;
|
private final CPPFunctionSet fFunctionSet;
|
||||||
|
private final boolean fQualified;
|
||||||
private final boolean fAddressOf;
|
private final boolean fAddressOf;
|
||||||
|
|
||||||
// Where an EvalFunctionSet is created for an expression of the form 'obj.member_function',
|
// Where an EvalFunctionSet is created for an expression of the form 'obj.member_function',
|
||||||
|
@ -54,25 +55,29 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
||||||
// Exactly one of fFunctionSet and fName should be non-null.
|
// Exactly one of fFunctionSet and fName should be non-null.
|
||||||
private final char[] fName;
|
private final char[] fName;
|
||||||
|
|
||||||
public EvalFunctionSet(CPPFunctionSet set, boolean addressOf, IType impliedObjectType, IASTNode pointOfDefinition) {
|
public EvalFunctionSet(CPPFunctionSet set, boolean qualified, boolean addressOf, IType impliedObjectType,
|
||||||
this(set, addressOf, impliedObjectType, findEnclosingTemplate(pointOfDefinition));
|
IASTNode pointOfDefinition) {
|
||||||
|
this(set, qualified, addressOf, impliedObjectType, findEnclosingTemplate(pointOfDefinition));
|
||||||
}
|
}
|
||||||
|
|
||||||
public EvalFunctionSet(CPPFunctionSet set, boolean addressOf, IType impliedObjectType, IBinding templateDefinition) {
|
public EvalFunctionSet(CPPFunctionSet set, boolean qualified, boolean addressOf, IType impliedObjectType,
|
||||||
|
IBinding templateDefinition) {
|
||||||
super(templateDefinition);
|
super(templateDefinition);
|
||||||
fFunctionSet= set;
|
fFunctionSet= set;
|
||||||
|
fQualified= qualified;
|
||||||
fAddressOf= addressOf;
|
fAddressOf= addressOf;
|
||||||
fImpliedObjectType= impliedObjectType;
|
fImpliedObjectType= impliedObjectType;
|
||||||
fName= null;
|
fName= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EvalFunctionSet(char[] name, boolean addressOf, IASTNode pointOfDefinition) {
|
public EvalFunctionSet(char[] name, boolean qualified, boolean addressOf, IASTNode pointOfDefinition) {
|
||||||
this(name, addressOf, findEnclosingTemplate(pointOfDefinition));
|
this(name, qualified, addressOf, findEnclosingTemplate(pointOfDefinition));
|
||||||
}
|
}
|
||||||
|
|
||||||
public EvalFunctionSet(char[] name, boolean addressOf, IBinding templateDefinition) {
|
public EvalFunctionSet(char[] name, boolean qualified, boolean addressOf, IBinding templateDefinition) {
|
||||||
super(templateDefinition);
|
super(templateDefinition);
|
||||||
fFunctionSet= null;
|
fFunctionSet= null;
|
||||||
|
fQualified= qualified;
|
||||||
fAddressOf= addressOf;
|
fAddressOf= addressOf;
|
||||||
fImpliedObjectType= null;
|
fImpliedObjectType= null;
|
||||||
fName= name;
|
fName= name;
|
||||||
|
@ -82,6 +87,10 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
||||||
return fFunctionSet;
|
return fFunctionSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isQualified() {
|
||||||
|
return fQualified;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isAddressOf() {
|
public boolean isAddressOf() {
|
||||||
return fAddressOf;
|
return fAddressOf;
|
||||||
}
|
}
|
||||||
|
@ -142,10 +151,13 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
||||||
private final static short FLAG_ADDRESS_OF = ITypeMarshalBuffer.FLAG1;
|
private final static short FLAG_ADDRESS_OF = ITypeMarshalBuffer.FLAG1;
|
||||||
private final static short FLAG_HAS_FUNCTION_SET = ITypeMarshalBuffer.FLAG2;
|
private final static short FLAG_HAS_FUNCTION_SET = ITypeMarshalBuffer.FLAG2;
|
||||||
private final static short FLAG_HAS_TEMPLATE_ARGS = ITypeMarshalBuffer.FLAG3;
|
private final static short FLAG_HAS_TEMPLATE_ARGS = ITypeMarshalBuffer.FLAG3;
|
||||||
|
private final static short FLAG_QUALIFIED = ITypeMarshalBuffer.FLAG4;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
|
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
|
||||||
short firstBytes = ITypeMarshalBuffer.EVAL_FUNCTION_SET;
|
short firstBytes = ITypeMarshalBuffer.EVAL_FUNCTION_SET;
|
||||||
|
if (fQualified)
|
||||||
|
firstBytes |= FLAG_QUALIFIED;
|
||||||
if (fAddressOf)
|
if (fAddressOf)
|
||||||
firstBytes |= FLAG_ADDRESS_OF;
|
firstBytes |= FLAG_ADDRESS_OF;
|
||||||
if (fFunctionSet != null) {
|
if (fFunctionSet != null) {
|
||||||
|
@ -175,6 +187,7 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ISerializableEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
|
public static ISerializableEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
|
||||||
|
final boolean qualified= (firstBytes & FLAG_QUALIFIED) != 0;
|
||||||
final boolean addressOf= (firstBytes & FLAG_ADDRESS_OF) != 0;
|
final boolean addressOf= (firstBytes & FLAG_ADDRESS_OF) != 0;
|
||||||
if ((firstBytes & FLAG_HAS_FUNCTION_SET) != 0) {
|
if ((firstBytes & FLAG_HAS_FUNCTION_SET) != 0) {
|
||||||
int bindingCount= buffer.getInt();
|
int bindingCount= buffer.getInt();
|
||||||
|
@ -192,11 +205,12 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
IType impliedObjectType= buffer.unmarshalType();
|
IType impliedObjectType= buffer.unmarshalType();
|
||||||
IBinding templateDefinition= buffer.unmarshalBinding();
|
IBinding templateDefinition= buffer.unmarshalBinding();
|
||||||
return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), addressOf, impliedObjectType, templateDefinition);
|
return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), qualified, addressOf,
|
||||||
|
impliedObjectType, templateDefinition);
|
||||||
} else {
|
} else {
|
||||||
char[] name = buffer.getCharArray();
|
char[] name = buffer.getCharArray();
|
||||||
IBinding templateDefinition= buffer.unmarshalBinding();
|
IBinding templateDefinition= buffer.unmarshalBinding();
|
||||||
return new EvalFunctionSet(name, addressOf, templateDefinition);
|
return new EvalFunctionSet(name, qualified, addressOf, templateDefinition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +250,8 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
||||||
// with an implied object type when that type is not dependent.
|
// with an implied object type when that type is not dependent.
|
||||||
if (Arrays.equals(arguments, originalArguments) && functions == originalFunctions)
|
if (Arrays.equals(arguments, originalArguments) && functions == originalFunctions)
|
||||||
return this;
|
return this;
|
||||||
return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fAddressOf, fImpliedObjectType, getTemplateDefinition());
|
return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fQualified, fAddressOf,
|
||||||
|
fImpliedObjectType, getTemplateDefinition());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -271,7 +286,7 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Perform ADL if appropriate.
|
// Perform ADL if appropriate.
|
||||||
if (fImpliedObjectType == null && !data.hasTypeOrMemberFunctionOrVariableResult()) {
|
if (!fQualified && fImpliedObjectType == null && !data.hasTypeOrMemberFunctionOrVariableResult()) {
|
||||||
CPPSemantics.doKoenigLookup(data);
|
CPPSemantics.doKoenigLookup(data);
|
||||||
|
|
||||||
Object[] foundItems = (Object[]) data.foundItems;
|
Object[] foundItems = (Object[]) data.foundItems;
|
||||||
|
|
|
@ -189,10 +189,11 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
public static ICPPEvaluation create(IASTIdExpression expr) {
|
public static ICPPEvaluation create(IASTIdExpression expr) {
|
||||||
final IASTName name = expr.getName();
|
final IASTName name = expr.getName();
|
||||||
IBinding binding = name.resolvePreBinding();
|
IBinding binding = name.resolvePreBinding();
|
||||||
|
boolean qualified = name instanceof ICPPASTQualifiedName;
|
||||||
if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor)
|
if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor)
|
||||||
return EvalFixed.INCOMPLETE;
|
return EvalFixed.INCOMPLETE;
|
||||||
if (binding instanceof CPPFunctionSet) {
|
if (binding instanceof CPPFunctionSet) {
|
||||||
return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr), null, expr);
|
return new EvalFunctionSet((CPPFunctionSet) binding, qualified, isAddressOf(expr), null, expr);
|
||||||
}
|
}
|
||||||
if (binding instanceof ICPPUnknownBinding) {
|
if (binding instanceof ICPPUnknownBinding) {
|
||||||
ICPPTemplateArgument[] templateArgs = null;
|
ICPPTemplateArgument[] templateArgs = null;
|
||||||
|
@ -209,10 +210,10 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
ICPPFunction[] candidates = ((CPPDeferredFunction) binding).getCandidates();
|
ICPPFunction[] candidates = ((CPPDeferredFunction) binding).getCandidates();
|
||||||
if (candidates != null) {
|
if (candidates != null) {
|
||||||
CPPFunctionSet functionSet = new CPPFunctionSet(candidates, templateArgs, null);
|
CPPFunctionSet functionSet = new CPPFunctionSet(candidates, templateArgs, null);
|
||||||
return new EvalFunctionSet(functionSet, isAddressOf(expr), null, expr);
|
return new EvalFunctionSet(functionSet, qualified, isAddressOf(expr), null, expr);
|
||||||
} else {
|
} else {
|
||||||
// Just store the name. ADL at the time of instantiation might come up with bindings.
|
// Just store the name. ADL at the time of instantiation might come up with bindings.
|
||||||
return new EvalFunctionSet(name.getSimpleID(), isAddressOf(expr), expr);
|
return new EvalFunctionSet(name.getSimpleID(), qualified, isAddressOf(expr), expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +368,7 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
if (bindings.length > 1 && bindings[0] instanceof ICPPFunction) {
|
if (bindings.length > 1 && bindings[0] instanceof ICPPFunction) {
|
||||||
ICPPFunction[] functions = new ICPPFunction[bindings.length];
|
ICPPFunction[] functions = new ICPPFunction[bindings.length];
|
||||||
System.arraycopy(bindings, 0, functions, 0, bindings.length);
|
System.arraycopy(bindings, 0, functions, 0, bindings.length);
|
||||||
return new EvalFunctionSet(new CPPFunctionSet(functions, templateArgs, null), fAddressOf,
|
return new EvalFunctionSet(new CPPFunctionSet(functions, templateArgs, null), fQualified, fAddressOf,
|
||||||
impliedObjectType, getTemplateDefinition());
|
impliedObjectType, getTemplateDefinition());
|
||||||
}
|
}
|
||||||
IBinding binding = bindings.length == 1 ? bindings[0] : null;
|
IBinding binding = bindings.length == 1 ? bindings[0] : null;
|
||||||
|
@ -376,7 +377,8 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
} else if (binding instanceof ICPPMember) {
|
} else if (binding instanceof ICPPMember) {
|
||||||
return new EvalMemberAccess(nameOwner, ValueCategory.PRVALUE, binding, false, getTemplateDefinition());
|
return new EvalMemberAccess(nameOwner, ValueCategory.PRVALUE, binding, false, getTemplateDefinition());
|
||||||
} else if (binding instanceof CPPFunctionSet) {
|
} else if (binding instanceof CPPFunctionSet) {
|
||||||
return new EvalFunctionSet((CPPFunctionSet) binding, fAddressOf, impliedObjectType, getTemplateDefinition());
|
return new EvalFunctionSet((CPPFunctionSet) binding, fQualified, fAddressOf, impliedObjectType,
|
||||||
|
getTemplateDefinition());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,7 +339,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
|
||||||
ICPPTemplateArgument[] b2 = TemplateInstanceUtil.convert(this, b);
|
ICPPTemplateArgument[] b2 = TemplateInstanceUtil.convert(this, b);
|
||||||
IType c2 = getCompositeType(c);
|
IType c2 = getCompositeType(c);
|
||||||
if (a != a2 || b != b2 || c != c2 || templateDefinition != templateDefinition2)
|
if (a != a2 || b != b2 || c != c2 || templateDefinition != templateDefinition2)
|
||||||
e= new EvalFunctionSet(new CPPFunctionSet(a2, b2, null), e.isAddressOf(), c2, templateDefinition2);
|
e= new EvalFunctionSet(new CPPFunctionSet(a2, b2, null), e.isQualified(), e.isAddressOf(),
|
||||||
|
c2, templateDefinition2);
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,10 +238,11 @@ public class PDOM extends PlatformObject implements IPDOM {
|
||||||
* 144.0 - Add support for storing function sets with zero functions in EvalFunctionSet, bug 402498.
|
* 144.0 - Add support for storing function sets with zero functions in EvalFunctionSet, bug 402498.
|
||||||
* 145.0 - Changed marshalling of CPPBasicType to store the associated numerical value, bug 407808.
|
* 145.0 - Changed marshalling of CPPBasicType to store the associated numerical value, bug 407808.
|
||||||
* 146.0 - Added visibility support on class type level, bug 402878.
|
* 146.0 - Added visibility support on class type level, bug 402878.
|
||||||
|
* 147.0 - Store whether function name is qualified in EvalFunctionSet, bug 408296.
|
||||||
*/
|
*/
|
||||||
private static final int MIN_SUPPORTED_VERSION= version(145, 0);
|
private static final int MIN_SUPPORTED_VERSION= version(147, 0);
|
||||||
private static final int MAX_SUPPORTED_VERSION= version(145, Short.MAX_VALUE);
|
private static final int MAX_SUPPORTED_VERSION= version(147, Short.MAX_VALUE);
|
||||||
private static final int DEFAULT_VERSION = version(145, 0);
|
private static final int DEFAULT_VERSION = version(147, 0);
|
||||||
|
|
||||||
private static int version(int major, int minor) {
|
private static int version(int major, int minor) {
|
||||||
return (major << 16) + minor;
|
return (major << 16) + minor;
|
||||||
|
|
Loading…
Add table
Reference in a new issue