mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Test case for bug 259872.
This commit is contained in:
parent
f9c0ac30d7
commit
a27a1df93d
6 changed files with 69 additions and 33 deletions
|
@ -3552,4 +3552,26 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
bh.assertNonProblem("func(p)", 4, ICPPFunction.class);
|
bh.assertNonProblem("func(p)", 4, ICPPFunction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <typename CL, typename T>
|
||||||
|
// struct A {
|
||||||
|
// template<typename U> struct C {
|
||||||
|
// typedef T (U::*method1)() const;
|
||||||
|
// };
|
||||||
|
// typedef typename C<CL>::method1 method2;
|
||||||
|
//
|
||||||
|
// A(method2 p);
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// struct B {
|
||||||
|
// int m() const;
|
||||||
|
//
|
||||||
|
// void test() {
|
||||||
|
// new A<B, int>(&B::m);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
public void _testNestedTemplates_259872() throws Exception {
|
||||||
|
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
bh.assertNonProblem("A<B, int>", 9, ICPPConstructor.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
@ -22,11 +23,11 @@ import org.eclipse.cdt.internal.core.index.IIndexType;
|
||||||
* @author aniefer
|
* @author aniefer
|
||||||
*/
|
*/
|
||||||
public class CPPQualifierType implements IQualifierType, ITypeContainer {
|
public class CPPQualifierType implements IQualifierType, ITypeContainer {
|
||||||
private boolean isConst = false;
|
private final boolean isConst;
|
||||||
private boolean isVolatile = false;
|
private final boolean isVolatile;
|
||||||
private IType type = null;
|
private IType type;
|
||||||
|
|
||||||
public CPPQualifierType( IType type, boolean isConst, boolean isVolatile ){
|
public CPPQualifierType(IType type, boolean isConst, boolean isVolatile) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.isConst = isConst;
|
this.isConst = isConst;
|
||||||
this.isVolatile = isVolatile;
|
this.isVolatile = isVolatile;
|
||||||
|
@ -68,18 +69,23 @@ public class CPPQualifierType implements IQualifierType, ITypeContainer {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType( IType t ){
|
public void setType(IType t) {
|
||||||
type = t;
|
type = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object clone(){
|
public Object clone() {
|
||||||
IType t = null;
|
IType t = null;
|
||||||
try {
|
try {
|
||||||
t = (IType) super.clone();
|
t = (IType) super.clone();
|
||||||
} catch ( CloneNotSupportedException e ) {
|
} catch (CloneNotSupportedException e) {
|
||||||
//not going to happen
|
//not going to happen
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ASTTypeUtil.getType(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType
|
||||||
if (CharArrayUtils.equals(td.getNameCharArray(), getNameCharArray())) {
|
if (CharArrayUtils.equals(td.getNameCharArray(), getNameCharArray())) {
|
||||||
IBinding owner= ((ICPPSpecialization) type).getOwner();
|
IBinding owner= ((ICPPSpecialization) type).getOwner();
|
||||||
if (owner instanceof IType) {
|
if (owner instanceof IType) {
|
||||||
if (((IType)owner).isSameType((ICPPClassType) getOwner())) {
|
if (((IType) owner).isSameType((ICPPClassType) getOwner())) {
|
||||||
type = new RecursionResolvingBinding(getDefinition(), getNameCharArray());
|
type = new RecursionResolvingBinding(getDefinition(), getNameCharArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,15 +90,15 @@ public class CPPUnknownClass extends CPPUnknownBinding implements ICPPUnknownCla
|
||||||
return type.isSameType(this);
|
return type.isSameType(this);
|
||||||
|
|
||||||
if (type instanceof ICPPUnknownClassType
|
if (type instanceof ICPPUnknownClassType
|
||||||
&& type instanceof ICPPUnknownClassInstance == false
|
&& !(type instanceof ICPPUnknownClassInstance)
|
||||||
&& type instanceof ICPPDeferredClassInstance == false) {
|
&& !(type instanceof ICPPDeferredClassInstance)) {
|
||||||
ICPPUnknownClassType rhs= (ICPPUnknownClassType) type;
|
ICPPUnknownClassType rhs= (ICPPUnknownClassType) type;
|
||||||
if (CharArrayUtils.equals(getNameCharArray(), rhs.getNameCharArray())) {
|
if (CharArrayUtils.equals(getNameCharArray(), rhs.getNameCharArray())) {
|
||||||
try {
|
try {
|
||||||
final IBinding lhsContainer = getOwner();
|
final IBinding lhsContainer = getOwner();
|
||||||
final IBinding rhsContainer = rhs.getOwner();
|
final IBinding rhsContainer = rhs.getOwner();
|
||||||
if (lhsContainer instanceof IType && rhsContainer instanceof IType) {
|
if (lhsContainer instanceof IType && rhsContainer instanceof IType) {
|
||||||
return ((IType)lhsContainer).isSameType((IType) rhsContainer);
|
return ((IType) lhsContainer).isSameType((IType) rhsContainer);
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,15 +314,16 @@ public class CPPSemantics {
|
||||||
ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName;
|
ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName;
|
||||||
ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id);
|
ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id);
|
||||||
IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args);
|
IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args);
|
||||||
cls = inst instanceof ICPPClassType && !(inst instanceof ICPPDeferredClassInstance) ? (ICPPClassType)inst : cls;
|
cls = inst instanceof ICPPClassType && !(inst instanceof ICPPDeferredClassInstance) ?
|
||||||
|
(ICPPClassType) inst : cls;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cls != null) {
|
if (cls != null) {
|
||||||
//force resolution of constructor bindings
|
// Force resolution of constructor bindings
|
||||||
IBinding[] ctors = cls.getConstructors();
|
IBinding[] ctors = cls.getConstructors();
|
||||||
if (ctors.length > 0 && !(ctors[0] instanceof IProblemBinding)) {
|
if (ctors.length > 0 && !(ctors[0] instanceof IProblemBinding)) {
|
||||||
//then use the class scope to resolve which one.
|
// then use the class scope to resolve which one.
|
||||||
binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding(data.astName, true);
|
binding = ((ICPPClassScope) cls.getCompositeScope()).getBinding(data.astName, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
|
@ -2109,7 +2110,8 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isImpliedObject && ASTInternal.isStatic(currFn, false)) {
|
if (isImpliedObject && ASTInternal.isStatic(currFn, false)) {
|
||||||
// 13.3.1-4 for static member functions, the implicit object parameter is considered to match any object
|
// 13.3.1-4 for static member functions, the implicit object parameter is
|
||||||
|
// considered to match any object
|
||||||
cost = new Cost(source, target);
|
cost = new Cost(source, target);
|
||||||
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
|
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
|
||||||
} else if (source == null) {
|
} else if (source == null) {
|
||||||
|
@ -2121,7 +2123,8 @@ public class CPPSemantics {
|
||||||
cost = new Cost(source, target);
|
cost = new Cost(source, target);
|
||||||
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
|
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
|
||||||
} else {
|
} else {
|
||||||
cost= Conversions.checkImplicitConversionSequence(!data.forUserDefinedConversion, sourceExp, source, target, isImpliedObject);
|
cost= Conversions.checkImplicitConversionSequence(!data.forUserDefinedConversion,
|
||||||
|
sourceExp, source, target, isImpliedObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
currFnCost[j] = cost;
|
currFnCost[j] = cost;
|
||||||
|
|
|
@ -481,7 +481,7 @@ public class Conversions {
|
||||||
|
|
||||||
tbase= getUltimateTypeViaTypedefs(tbase);
|
tbase= getUltimateTypeViaTypedefs(tbase);
|
||||||
if (tbase instanceof ICPPClassType) {
|
if (tbase instanceof ICPPClassType) {
|
||||||
int n= calculateInheritanceDepth(maxdepth-1, tbase, ancestorToFind);
|
int n= calculateInheritanceDepth(maxdepth - 1, tbase, ancestorToFind);
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
return n + 1;
|
return n + 1;
|
||||||
}
|
}
|
||||||
|
@ -531,9 +531,9 @@ public class Conversions {
|
||||||
|
|
||||||
//4.1 if T is a non-class type, the type of the rvalue is the cv-unqualified version of T
|
//4.1 if T is a non-class type, the type of the rvalue is the cv-unqualified version of T
|
||||||
if (source instanceof IQualifierType) {
|
if (source instanceof IQualifierType) {
|
||||||
IType t = ((IQualifierType)source).getType();
|
IType t = ((IQualifierType) source).getType();
|
||||||
while (t instanceof ITypedef)
|
while (t instanceof ITypedef)
|
||||||
t = ((ITypedef)t).getType();
|
t = ((ITypedef) t).getType();
|
||||||
if (!(t instanceof ICPPClassType)) {
|
if (!(t instanceof ICPPClassType)) {
|
||||||
source = t;
|
source = t;
|
||||||
}
|
}
|
||||||
|
@ -562,7 +562,8 @@ public class Conversions {
|
||||||
boolean canConvert = true;
|
boolean canConvert = true;
|
||||||
int requiredConversion = Cost.IDENTITY_RANK;
|
int requiredConversion = Cost.IDENTITY_RANK;
|
||||||
|
|
||||||
IType s = cost.source, t = cost.target;
|
IType s = cost.source;
|
||||||
|
IType t = cost.target;
|
||||||
boolean constInEveryCV2k = true;
|
boolean constInEveryCV2k = true;
|
||||||
boolean firstPointer= true;
|
boolean firstPointer= true;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -575,7 +576,7 @@ public class Conversions {
|
||||||
if (!sourceIsPointer)
|
if (!sourceIsPointer)
|
||||||
break;
|
break;
|
||||||
if (t instanceof ICPPBasicType) {
|
if (t instanceof ICPPBasicType) {
|
||||||
if (((ICPPBasicType)t).getType() == ICPPBasicType.t_bool) {
|
if (((ICPPBasicType) t).getType() == ICPPBasicType.t_bool) {
|
||||||
canConvert= true;
|
canConvert= true;
|
||||||
requiredConversion = Cost.CONVERSION_RANK;
|
requiredConversion = Cost.CONVERSION_RANK;
|
||||||
break;
|
break;
|
||||||
|
@ -702,8 +703,8 @@ public class Conversions {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (src instanceof IBasicType && trg instanceof IBasicType) {
|
if (src instanceof IBasicType && trg instanceof IBasicType) {
|
||||||
int sType = ((IBasicType)src).getType();
|
int sType = ((IBasicType) src).getType();
|
||||||
int tType = ((IBasicType)trg).getType();
|
int tType = ((IBasicType) trg).getType();
|
||||||
if ((tType == IBasicType.t_int && (sType == IBasicType.t_int || //short, long , unsigned etc
|
if ((tType == IBasicType.t_int && (sType == IBasicType.t_int || //short, long , unsigned etc
|
||||||
sType == IBasicType.t_char ||
|
sType == IBasicType.t_char ||
|
||||||
sType == ICPPBasicType.t_bool ||
|
sType == ICPPBasicType.t_bool ||
|
||||||
|
@ -713,8 +714,8 @@ public class Conversions {
|
||||||
cost.promotion = 1;
|
cost.promotion = 1;
|
||||||
}
|
}
|
||||||
} else if (src instanceof IEnumeration && trg instanceof IBasicType &&
|
} else if (src instanceof IEnumeration && trg instanceof IBasicType &&
|
||||||
(((IBasicType)trg).getType() == IBasicType.t_int ||
|
(((IBasicType) trg).getType() == IBasicType.t_int ||
|
||||||
((IBasicType)trg).getType() == IBasicType.t_unspecified)) {
|
((IBasicType) trg).getType() == IBasicType.t_unspecified)) {
|
||||||
cost.promotion = 1;
|
cost.promotion = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,8 +744,9 @@ public class Conversions {
|
||||||
IType sPrev= sHolder[0], tPrev= tHolder[0];
|
IType sPrev= sHolder[0], tPrev= tHolder[0];
|
||||||
|
|
||||||
if (src instanceof CPPBasicType && trg instanceof IPointerType) {
|
if (src instanceof CPPBasicType && trg instanceof IPointerType) {
|
||||||
//4.10-1 an integral constant expression of integer type that evaluates to 0 can be converted to a pointer type
|
// 4.10-1 an integral constant expression of integer type that evaluates to 0 can
|
||||||
IASTExpression exp = ((CPPBasicType)src).getCreatedFromExpression();
|
// be converted to a pointer type
|
||||||
|
IASTExpression exp = ((CPPBasicType) src).getCreatedFromExpression();
|
||||||
if (exp != null) {
|
if (exp != null) {
|
||||||
Long val= Value.create(exp, Value.MAX_RECURSION_DEPTH).numericalValue();
|
Long val= Value.create(exp, Value.MAX_RECURSION_DEPTH).numericalValue();
|
||||||
if (val != null && val == 0) {
|
if (val != null && val == 0) {
|
||||||
|
@ -755,7 +757,8 @@ public class Conversions {
|
||||||
} else if (sPrev instanceof IPointerType) {
|
} else if (sPrev instanceof IPointerType) {
|
||||||
//4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be
|
//4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be
|
||||||
//converted to an rvalue of type "pointer to cv void"
|
//converted to an rvalue of type "pointer to cv void"
|
||||||
if (tPrev instanceof IPointerType && t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_void) {
|
if (tPrev instanceof IPointerType && t instanceof IBasicType &&
|
||||||
|
((IBasicType)t).getType() == IBasicType.t_void) {
|
||||||
cost.rank = Cost.CONVERSION_RANK;
|
cost.rank = Cost.CONVERSION_RANK;
|
||||||
cost.conversion = 1;
|
cost.conversion = 1;
|
||||||
cost.detail = 2;
|
cost.detail = 2;
|
||||||
|
@ -781,7 +784,8 @@ public class Conversions {
|
||||||
//An rvalue of an enumeration type can be converted to an rvalue of an integer type.
|
//An rvalue of an enumeration type can be converted to an rvalue of an integer type.
|
||||||
cost.rank = Cost.CONVERSION_RANK;
|
cost.rank = Cost.CONVERSION_RANK;
|
||||||
cost.conversion = 1;
|
cost.conversion = 1;
|
||||||
} else if (trg instanceof IBasicType && ((IBasicType)trg).getType() == ICPPBasicType.t_bool && s instanceof IPointerType) {
|
} else if (trg instanceof IBasicType && ((IBasicType)trg).getType() == ICPPBasicType.t_bool &&
|
||||||
|
s instanceof IPointerType) {
|
||||||
//4.12 pointer or pointer to member type can be converted to an rvalue of type bool
|
//4.12 pointer or pointer to member type can be converted to an rvalue of type bool
|
||||||
cost.rank = Cost.CONVERSION_RANK;
|
cost.rank = Cost.CONVERSION_RANK;
|
||||||
cost.conversion = 1;
|
cost.conversion = 1;
|
||||||
|
@ -794,7 +798,8 @@ public class Conversions {
|
||||||
IType st = spm.getType();
|
IType st = spm.getType();
|
||||||
IType tt = tpm.getType();
|
IType tt = tpm.getType();
|
||||||
if (st != null && tt != null && st.isSameType(tt)) {
|
if (st != null && tt != null && st.isSameType(tt)) {
|
||||||
int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, tpm.getMemberOfClass(), spm.getMemberOfClass());
|
int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH,
|
||||||
|
tpm.getMemberOfClass(), spm.getMemberOfClass());
|
||||||
cost.rank= (depth > -1) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
|
cost.rank= (depth > -1) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
|
||||||
cost.conversion= (depth > -1) ? depth : 0;
|
cost.conversion= (depth > -1) ? depth : 0;
|
||||||
cost.detail= 1;
|
cost.detail= 1;
|
||||||
|
@ -828,11 +833,11 @@ public class Conversions {
|
||||||
type= getUltimateType(type, false);
|
type= getUltimateType(type, false);
|
||||||
if (type instanceof ICPPClassType) {
|
if (type instanceof ICPPClassType) {
|
||||||
if (type instanceof ICPPInternalBinding) {
|
if (type instanceof ICPPInternalBinding) {
|
||||||
return (((ICPPInternalBinding)type).getDefinition() != null);
|
return (((ICPPInternalBinding) type).getDefinition() != null);
|
||||||
}
|
}
|
||||||
if (type instanceof IIndexFragmentBinding) {
|
if (type instanceof IIndexFragmentBinding) {
|
||||||
try {
|
try {
|
||||||
return ((IIndexFragmentBinding)type).hasDefinition();
|
return ((IIndexFragmentBinding) type).hasDefinition();
|
||||||
} catch(CoreException ce) {
|
} catch(CoreException ce) {
|
||||||
CCorePlugin.log(ce);
|
CCorePlugin.log(ce);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue