1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Bug 327328: Overload resolution and restrict pointers.

This commit is contained in:
Markus Schorn 2010-10-13 12:56:56 +00:00
parent 4473ddf01f
commit 64778c5409
15 changed files with 192 additions and 165 deletions

View file

@ -9207,4 +9207,43 @@ public class AST2CPPTests extends AST2BaseTest {
assertSame(ctor2, dtor.getImplicitNames()[0].resolveBinding());
}
// void g(int * __restrict a);
// void g(int * a) {}
//
// void test1() {
// int number = 5;
// g(&number);
// }
public void testTopLevelRestrictQualifier_327328() throws Exception {
String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
IFunction g= bh.assertNonProblem("g(int * __restrict a)", 1);
IFunction ref;
ref= bh.assertNonProblem("g(int * a)", 1);
assertSame(g, ref);
ref= bh.assertNonProblem("g(&number)", 1);
assertSame(g, ref);
}
// void f(int * __restrict* a) {}
// void f(int ** a) {} // different function
//
// void test2() {
// int* __restrict rnumber= 0;
// int* number = 0;
// f(&rnumber); // calls f(int* __restrict* a)
// f(&number); // calls f(int** a)
// }
public void testOverloadingWithRestrictQualifier_327328() throws Exception {
String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
IFunction f1= bh.assertNonProblem("f(int * __restrict* a)", 1);
IFunction f2= bh.assertNonProblem("f(int ** a)", 1);
IFunction ref;
ref= bh.assertNonProblem("f(&rnumber)", 1);
assertSame(f1, ref);
ref= bh.assertNonProblem("f(&number)", 1);
assertSame(f2, ref);
}
}

View file

@ -18,7 +18,6 @@ import java.util.List;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
import org.eclipse.cdt.core.dom.ast.c.ICPointerType;
import org.eclipse.cdt.core.dom.ast.c.ICQualifierType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
@ -32,7 +31,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPPointerType;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPQualifierType;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
@ -368,7 +366,7 @@ public class ASTTypeUtil {
}
if (type instanceof ICPPFunctionType) {
ICPPFunctionType ft= (ICPPFunctionType) type;
needSpace= appendCVQ(result, needSpace, ft.isConst(), ft.isVolatile());
needSpace= appendCVQ(result, needSpace, ft.isConst(), ft.isVolatile(), false);
}
} else if (type instanceof IPointerType) {
if (type instanceof ICPPPointerToMemberType) {
@ -376,25 +374,8 @@ public class ASTTypeUtil {
result.append(Keywords.cpCOLONCOLON);
}
result.append(Keywords.cpSTAR); needSpace = true;
if (type instanceof IGPPPointerType) {
if (((IGPPPointerType) type).isRestrict()) {
if (needSpace) {
result.append(SPACE); needSpace = false;
}
result.append(Keywords.RESTRICT); needSpace = true;
}
} else if (type instanceof ICPointerType) {
if (((ICPointerType) type).isRestrict()) {
if (needSpace) {
result.append(SPACE); needSpace = false;
}
result.append(Keywords.RESTRICT); needSpace = true;
}
}
IPointerType pt= (IPointerType) type;
needSpace= appendCVQ(result, needSpace, pt.isConst(), pt.isVolatile());
needSpace= appendCVQ(result, needSpace, pt.isConst(), pt.isVolatile(), pt.isRestrict());
} else if (type instanceof IQualifierType) {
if (type instanceof ICQualifierType) {
if (((ICQualifierType) type).isRestrict()) {
@ -407,7 +388,7 @@ public class ASTTypeUtil {
}
IQualifierType qt= (IQualifierType) type;
needSpace= appendCVQ(result, needSpace, qt.isConst(), qt.isVolatile());
needSpace= appendCVQ(result, needSpace, qt.isConst(), qt.isVolatile(), false);
} else if (type instanceof ITypedef) {
result.append(((ITypedef) type).getNameCharArray());
} else if (type instanceof ISemanticProblem) {
@ -420,18 +401,27 @@ public class ASTTypeUtil {
}
private static boolean appendCVQ(StringBuilder target, boolean needSpace, final boolean isConst,
final boolean isVolatile) {
final boolean isVolatile, final boolean isRestrict) {
if (isConst) {
if (needSpace) {
target.append(SPACE); needSpace = false;
target.append(SPACE);
}
target.append(Keywords.CONST); needSpace = true;
target.append(Keywords.CONST);
needSpace = true;
}
if (isVolatile) {
if (needSpace) {
target.append(SPACE); needSpace = false;
target.append(SPACE);
}
target.append(Keywords.VOLATILE); needSpace = true;
target.append(Keywords.VOLATILE);
needSpace = true;
}
if (isRestrict) {
if (needSpace) {
target.append(SPACE);
}
target.append(Keywords.RESTRICT);
needSpace = true;
}
return needSpace;
}
@ -492,7 +482,7 @@ public class ASTTypeUtil {
if (cvq != null) {
// merge cv qualifiers
if (type instanceof IQualifierType || type instanceof IPointerType) {
type= SemanticUtil.addQualifiers(type, cvq.isConst(), cvq.isVolatile());
type= SemanticUtil.addQualifiers(type, cvq.isConst(), cvq.isVolatile(), false);
cvq= null;
}
}

View file

@ -248,15 +248,15 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen
public static IType addQualifiersForAccess(ICPPField field, IType fieldType, IType ownerType) {
CVQualifier cvq1 = SemanticUtil.getCVQualifier(ownerType);
CVQualifier cvq2 = SemanticUtil.getCVQualifier(fieldType);
if (field.isMutable()) {
// Remove const, add union of volatile.
CVQualifier cvq2 = SemanticUtil.getCVQualifier(fieldType);
if (cvq2.isConst()) {
fieldType= SemanticUtil.getNestedType(fieldType, ALLCVQ | TDEF | REF);
}
fieldType= SemanticUtil.addQualifiers(fieldType, false, cvq1.isVolatile() || cvq2.isVolatile());
fieldType= SemanticUtil.addQualifiers(fieldType, false, cvq1.isVolatile() || cvq2.isVolatile(), cvq2.isRestrict());
} else {
fieldType= SemanticUtil.addQualifiers(fieldType, cvq1.isConst(), cvq1.isVolatile());
fieldType= SemanticUtil.addQualifiers(fieldType, cvq1.isConst(), cvq1.isVolatile(), cvq2.isRestrict());
}
return fieldType;
}

View file

@ -100,7 +100,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
char[] className = name.getLookupKey();
ICPPParameter[] voidPs = new ICPPParameter[] { new CPPParameter(CPPSemantics.VOID_TYPE, 0) };
IType pType = new CPPReferenceType(SemanticUtil.addQualifiers(clsType, true, false), false);
IType pType = new CPPReferenceType(SemanticUtil.constQualify(clsType), false);
ICPPParameter[] ps = new ICPPParameter[] { new CPPParameter(pType, 0) };
int i= 0;

View file

@ -80,7 +80,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
result[0]= ctor;
// Copy constructor: A(const A &)
IType pType = new CPPReferenceType(SemanticUtil.addQualifiers(this, true, false), false);
IType pType = new CPPReferenceType(SemanticUtil.constQualify(this), false);
ICPPParameter[] ps = new ICPPParameter[] { new CPPParameter(pType, 0) };
ctor = new CPPImplicitConstructor(scope, CharArrayUtils.EMPTY, ps);
result[1]= ctor;

View file

@ -359,7 +359,7 @@ class BuiltinOperators {
if (SemanticUtil.calculateInheritanceDepth(c1, c2) >= 0) {
IType cvt= SemanticUtil.getNestedType(memPtr.getType(), TDEF);
IType rt= new CPPReferenceType(
SemanticUtil.addQualifiers(cvt, cv1.isConst(), cv1.isVolatile()), false);
SemanticUtil.addQualifiers(cvt, cv1.isConst(), cv1.isVolatile(), cv1.isRestrict()), false);
addFunction(rt, clsPtr, memPtr);
}
}

View file

@ -761,7 +761,6 @@ public class CPPSemantics {
if (scope instanceof ICPPScope) {
return (ICPPScope) scope;
} else if (scope instanceof IProblemBinding) {
// mstodo scope problems
return new CPPScope.CPPScopeProblem(((IProblemBinding) scope).getASTNode(),
IProblemBinding.SEMANTIC_BAD_SCOPE, ((IProblemBinding) scope).getNameCharArray());
}
@ -2527,7 +2526,7 @@ public class CPPSemantics {
IType impliedObjectType= null;
final IType[] paramTypes= ftype.getParameterTypes();
if (fn instanceof ICPPMethod && !(fn instanceof ICPPConstructor)) {
implicitParameterType = getImplicitParameterType((ICPPMethod) fn, ftype.isConst(), ftype.isVolatile());
implicitParameterType = getImplicitParameterType((ICPPMethod) fn);
if (data.argsContainImpliedObject) {
impliedObjectType= argTypes[0];
skipArg= 1;
@ -2623,16 +2622,15 @@ public class CPPSemantics {
return result;
}
static IType getImplicitParameterType(ICPPMethod m, final boolean isConst, final boolean isVolatile)
throws DOMException {
static IType getImplicitParameterType(ICPPMethod m) throws DOMException {
IType implicitType;
ICPPClassType owner= m.getClassOwner();
if (owner instanceof ICPPClassTemplate) {
owner= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) owner);
}
implicitType= SemanticUtil.addQualifiers(owner, isConst, isVolatile);
implicitType= new CPPReferenceType(implicitType, false);
return implicitType;
ICPPFunctionType ft= m.getType();
implicitType= SemanticUtil.addQualifiers(owner, ft.isConst(), ft.isVolatile(), false);
return new CPPReferenceType(implicitType, false);
}
private static IBinding resolveUserDefinedConversion(LookupData data, IFunction[] fns) {
@ -2907,14 +2905,6 @@ public class CPPSemantics {
return foundOperator ? type : null;
}
private static ICPPVariable createVariable(IASTName name, final IType type, final boolean isConst, final boolean isVolatile) {
return new CPPVariable(name) {
@Override public IType getType() {
return SemanticUtil.addQualifiers(type, isConst, isVolatile);
}
};
}
public static ICPPFunction findOverloadedOperator(IASTArraySubscriptExpression exp) {
final IASTExpression arrayExpression = exp.getArrayExpression();
IASTInitializerClause[] args = {arrayExpression, exp.getArgument()};
@ -3118,9 +3108,13 @@ public class CPPSemantics {
return null;
}
public static IASTExpression createArgForType(IASTNode node, IType type) {
public static IASTExpression createArgForType(IASTNode node, final IType type) {
CPPASTName x= new CPPASTName();
x.setBinding(createVariable(x, type, false, false));
x.setBinding(new CPPVariable(x) {
@Override public IType getType() {
return type;
}
});
final CPPASTIdExpression idExpression = new CPPASTIdExpression(x);
idExpression.setParent(node);
return idExpression;

View file

@ -14,7 +14,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.addQualifiers;
import java.util.ArrayList;
import java.util.Collections;
@ -121,7 +120,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplateSpecializat
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeParameter;
@ -1759,9 +1757,9 @@ public class CPPTemplates {
boolean nonStaticMember2= isNonStaticMember(f2);
if (nonStaticMember1 != nonStaticMember2) {
if (nonStaticMember1) {
args= addImplicitObjectType(args, (ICPPMethod) f1);
args= addImplicitParameterType(args, (ICPPMethod) f1);
} else {
pars= addImplicitObjectType(pars, (ICPPMethod) f2);
pars= addImplicitParameterType(pars, (ICPPMethod) f2);
}
}
break;
@ -1773,14 +1771,13 @@ public class CPPTemplates {
return (f instanceof ICPPMethod) && !((ICPPMethod) f).isStatic();
}
private static IType[] addImplicitObjectType(IType[] types, ICPPMethod f1) {
ICPPClassType ct = f1.getClassOwner();
if (ct != null) {
ICPPFunctionType ft = f1.getType();
final CPPReferenceType t = new CPPReferenceType(addQualifiers(ct, ft.isConst(), ft.isVolatile()), false);
private static IType[] addImplicitParameterType(IType[] types, ICPPMethod m) {
try {
IType t= CPPSemantics.getImplicitParameterType(m);
return concat(t, types);
} catch (DOMException e) {
return types;
}
return types;
}
private static IType[] concat(final IType t, IType[] types) {

View file

@ -1670,7 +1670,7 @@ public class CPPVisitor extends ASTQueries {
// 8.3.5-3
// Any cv-qualifier modifying a parameter type is deleted. The parameter type remains
// to be qualified.
if (forFunctionType && SemanticUtil.getCVQualifier(t) != CVQualifier._) {
if (forFunctionType && SemanticUtil.getCVQualifier(t) != CVQualifier.NONE) {
return SemanticUtil.getNestedType(t, TDEF | ALLCVQ);
}
return pt;
@ -1879,7 +1879,7 @@ public class CPPVisitor extends ASTQueries {
}
private static IType qualifyType(IType type, IASTDeclSpecifier declSpec) {
return SemanticUtil.addQualifiers(type, declSpec.isConst(), declSpec.isVolatile());
return SemanticUtil.addQualifiers(type, declSpec.isConst(), declSpec.isVolatile(), declSpec.isRestrict());
}
private static IType createType(IType baseType, IASTDeclarator declarator) {
@ -1977,7 +1977,7 @@ public class CPPVisitor extends ASTQueries {
if (type instanceof ICPPClassTemplate) {
type= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) type);
}
return SemanticUtil.addQualifiers(type, dtor.isConst(), dtor.isVolatile());
return SemanticUtil.addQualifiers(type, dtor.isConst(), dtor.isVolatile(), false);
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others.
* Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* 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
@ -10,49 +10,85 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
/**
* Represents the possible cv-qualification of a type.
*/
public enum CVQualifier {
cv(true, true), c(true, false), v(false, true), _(false, false);
CONST_VOLATILE_RESTRICT(1 | 2 | 4), CONST_VOLATILE(1 | 2), CONST_RESTRICT(1 | 4), CONST(1),
VOLATILE_RESTRICT(2 | 4), VOLATILE(2), RESTRICT(4), NONE(0);
final private boolean fConst;
final private boolean fVolatile;
private CVQualifier(boolean c, boolean v) {
fConst= c;
fVolatile= v;
private static final int C = 1;
private static final int V = 2;
private static final int R = 4;
final private int fQualifiers;
private CVQualifier(int qualifiers) {
fQualifiers= qualifiers;
}
public boolean isConst() {
return fConst;
return (fQualifiers & C) != 0;
}
public boolean isVolatile() {
return fVolatile;
return (fQualifiers & V) != 0;
}
public boolean isRestrict() {
return (fQualifiers & R) != 0;
}
public boolean isAtLeastAsQualifiedAs(CVQualifier other) {
return other == _ || this == other || this == cv;
return (fQualifiers | other.fQualifiers) == fQualifiers;
}
public boolean isMoreQualifiedThan(CVQualifier other) {
return this != other && (other == _ || this == cv);
return this != other && isAtLeastAsQualifiedAs(other);
}
public CVQualifier remove(CVQualifier arg) {
if (this == arg)
return _;
switch (arg) {
case _:
return this;
case c:
return isVolatile() ? v : _;
case v:
return isConst() ? c : _;
case cv:
return _;
public CVQualifier add(CVQualifier cvq) {
return fromQualifier(fQualifiers | cvq.fQualifiers);
}
public CVQualifier remove(CVQualifier cvq) {
return fromQualifier(fQualifiers & ~cvq.fQualifiers);
}
private CVQualifier fromQualifier(final int q) {
switch(q) {
case C|V|R: return CONST_VOLATILE_RESTRICT;
case V|R: return VOLATILE_RESTRICT;
case C|R: return CONST_RESTRICT;
case R: return RESTRICT;
case C|V: return CONST_VOLATILE;
case V: return VOLATILE;
case C: return CONST;
case 0: default: return NONE;
}
return _;
}
/**
* [3.9.3-4] Implements cv-qualification (partial) comparison. There is a (partial)
* ordering on cv-qualifiers, so that a type can be said to be more
* cv-qualified than another.
* @return <ul>
* <li>7 if cv1 == const volatile restrict cv2
* <li>6 if cv1 == volatile restrict cv2
* <li>5 if cv1 == const restrict cv2
* <li>4 if cv1 == restrict cv2
* <li>3 if cv1 == const volatile cv2
* <li>2 if cv1 == volatile cv2
* <li>1 if cv1 == const cv2
* <li>EQ 0 if cv1 == cv2
* <li>LT -1 if cv1 is less qualified than cv2 or not comparable
* </ul>
*/
public int partialComparison(CVQualifier cv2) {
// same qualifications
if (this == cv2)
return 0;
if (!isAtLeastAsQualifiedAs(cv2))
return -1;
return fQualifiers-cv2.fQualifiers;
}
}

View file

@ -15,7 +15,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CVQualifier._;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
@ -113,7 +112,7 @@ public class Conversions {
}
if (exprType instanceof InitializerListType) {
if (isLValueRef && getCVQualifier(cv1T1) != CVQualifier.c)
if (isLValueRef && getCVQualifier(cv1T1) != CVQualifier.CONST)
return Cost.NO_CONVERSION;
Cost cost= listInitializationSequence(((InitializerListType) exprType), T1, udc, false);
@ -157,7 +156,7 @@ public class Conversions {
// shall be an rvalue or have function type.
boolean ok;
if (isLValueRef) {
ok = getCVQualifier(cv1T1) == CVQualifier.c;
ok = getCVQualifier(cv1T1) == CVQualifier.CONST;
} else {
ok= valueCat.isRValue() || T2 instanceof IFunctionType;
}
@ -272,7 +271,7 @@ public class Conversions {
IType t= getNestedType(ft.getReturnType(), TDEF);
final boolean isLValueRef= t instanceof ICPPReferenceType && !((ICPPReferenceType) t).isRValueReference();
if (isLValueRef == needLValue) { // require an lvalue or rvalue
IType implicitParameterType= CPPSemantics.getImplicitParameterType(op, ft.isConst(), ft.isVolatile());
IType implicitParameterType= CPPSemantics.getImplicitParameterType(op);
Cost udcCost= isReferenceCompatible(getNestedType(implicitParameterType, TDEF | REF), cv2T2, true); // expression type to implicit object type
if (udcCost != null) {
// Make sure top-level cv-qualifiers are compared
@ -429,30 +428,7 @@ public class Conversions {
* </ul>
*/
private static final int compareQualifications(IType t1, IType t2) {
CVQualifier cv1= getCVQualifier(t1);
CVQualifier cv2= getCVQualifier(t2);
// same qualifications
if (cv1 == cv2)
return 0;
switch (cv1) {
case cv:
switch (cv2) {
case _: return 3;
case c: return 2;
case v: return 1;
case cv: return 0;
}
break;
case c:
return cv2 == _ ? 1 : -1;
case v:
return cv2 == _ ? 2 : -1;
case _:
return -1;
}
return -1;
return getCVQualifier(t1).partialComparison(getCVQualifier(t2));
}
/**
@ -723,8 +699,7 @@ public class Conversions {
final IType uqReturnType= getNestedType(returnType, REF | TDEF | CVTYPE);
final int dist = SemanticUtil.calculateInheritanceDepth(uqReturnType, t);
if (dist >= 0) {
final ICPPFunctionType ft = op.getType();
IType implicitType= CPPSemantics.getImplicitParameterType(op, ft.isConst(), ft.isVolatile());
IType implicitType= CPPSemantics.getImplicitParameterType(op);
final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true);
if (udcCost != null) {
// Make sure top-level cv-qualifiers are compared
@ -779,8 +754,7 @@ public class Conversions {
if (c2.converts()) {
if (isExplicitConversion && c2.getRank() != Rank.IDENTITY)
continue;
ICPPFunctionType ftype = op.getType();
IType implicitType= CPPSemantics.getImplicitParameterType(op, ftype.isConst(), ftype.isVolatile());
IType implicitType= CPPSemantics.getImplicitParameterType(op);
final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true);
if (udcCost != null) {
// Make sure top-level cv-qualifiers are compared
@ -870,7 +844,8 @@ public class Conversions {
IASTLiteralExpression lit= (IASTLiteralExpression) val;
if (lit.getKind() == IASTLiteralExpression.lk_string_literal) {
source= new CPPPointerType(srcTarget, false, false, false);
cost.setQualificationAdjustment((getCVQualifier(targetPtrTgt).isVolatile() ? 2 : 1) << 2);
CVQualifier cvqTarget = getCVQualifier(targetPtrTgt).add(CVQualifier.CONST);
cost.setQualificationAdjustment(cvqTarget.partialComparison(CVQualifier.NONE) << 3);
}
}
}
@ -907,7 +882,7 @@ public class Conversions {
t= tPtr.getType();
firstPointer= false;
adjustments |= (cmp << shift);
shift+= 2;
shift+= 3;
} else {
break;
}
@ -1092,7 +1067,7 @@ public class Conversions {
cost.setRank(Rank.CONVERSION);
cost.setInheritanceDistance(Short.MAX_VALUE);
CVQualifier cv= getCVQualifier(srcPtr.getType());
cost.source= new CPPPointerType(addQualifiers(CPPSemantics.VOID_TYPE, cv.isConst(), cv.isVolatile()));
cost.source= new CPPPointerType(addQualifiers(CPPSemantics.VOID_TYPE, cv.isConst(), cv.isVolatile(), cv.isRestrict()));
return false;
}
@ -1114,7 +1089,7 @@ public class Conversions {
cost.setInheritanceDistance(depth);
}
CVQualifier cv= getCVQualifier(srcPtr.getType());
cost.source= new CPPPointerType(addQualifiers(tgtPtrTgt, cv.isConst(), cv.isVolatile()));
cost.source= new CPPPointerType(addQualifiers(tgtPtrTgt, cv.isConst(), cv.isVolatile(), cv.isRestrict()));
}
return false;
}
@ -1205,11 +1180,11 @@ public class Conversions {
final IType target1 = p1.getType();
if (isVoidType(target1)) {
return addQualifiers(p1, p2.isConst(), p2.isVolatile());
return addQualifiers(p1, p2.isConst(), p2.isVolatile(), p2.isRestrict());
}
final IType target2 = p2.getType();
if (isVoidType(target2)) {
return addQualifiers(p2, p1.isConst(), p1.isVolatile());
return addQualifiers(p2, p1.isConst(), p1.isVolatile(), p1.isRestrict());
}
IType t= mergePointers(target1, target2, true);

View file

@ -210,7 +210,7 @@ public class Cost {
// Top level cv-qualifiers are compared only for reference bindings.
int qdiff= fQualificationAdjustments ^ other.fQualificationAdjustments;
if (fReferenceBinding == ReferenceBinding.NO_REF || other.fReferenceBinding == ReferenceBinding.NO_REF)
qdiff &= ~3;
qdiff &= ~7;
if (qdiff != 0) {
if ((fQualificationAdjustments & qdiff) == 0)

View file

@ -168,38 +168,27 @@ public class SemanticUtil {
return false;
}
/**
* Returns 0 for no qualifier, 1 for const, 2 for volatile and 3 for const volatile.
*/
public static CVQualifier getCVQualifier(IType t) {
if (t instanceof IQualifierType) {
IQualifierType qt= (IQualifierType) t;
if (qt.isConst()) {
if (qt.isVolatile()) {
return cv;
}
return c;
}
if (qt.isVolatile())
return v;
return _;
return qt.isConst()
? qt.isVolatile() ? CONST_VOLATILE : CONST
: qt.isVolatile() ? VOLATILE : NONE;
}
if (t instanceof IPointerType) {
IPointerType pt= (IPointerType) t;
if (pt.isConst()) {
if (pt.isVolatile()) {
return cv;
}
return c;
}
if (pt.isVolatile())
return v;
return _;
return pt.isConst()
? pt.isVolatile()
? pt.isRestrict() ? CONST_VOLATILE_RESTRICT : CONST_VOLATILE
: pt.isRestrict() ? CONST_RESTRICT : CONST
: pt.isVolatile()
? pt.isRestrict() ? VOLATILE_RESTRICT : VOLATILE
: pt.isRestrict() ? RESTRICT : NONE;
}
if (t instanceof IArrayType) {
return getCVQualifier(((IArrayType) t).getType());
}
return _;
return NONE;
}
/**
@ -263,7 +252,7 @@ public class SemanticUtil {
t= getNestedType(qttgt, options);
if (t == qttgt)
return qt;
return addQualifiers(t, qt.isConst(), qt.isVolatile());
return addQualifiers(t, qt.isConst(), qt.isVolatile(), false);
}
} else if (type instanceof IArrayType) {
final IArrayType atype= (IArrayType) type;
@ -365,7 +354,7 @@ public class SemanticUtil {
// bug 249085 make sure not to add unnecessary qualifications
if (type instanceof IQualifierType) {
IQualifierType qt= (IQualifierType) type;
return addQualifiers(newNestedType, qt.isConst(), qt.isVolatile());
return addQualifiers(newNestedType, qt.isConst(), qt.isVolatile(), false);
}
type = (ITypeContainer) type.clone();
@ -455,8 +444,12 @@ public class SemanticUtil {
return arg;
}
public static IType addQualifiers(IType baseType, boolean cnst, boolean vol) {
if (cnst || vol) {
public static IType constQualify(IType baseType) {
return addQualifiers(baseType, true, false, false);
}
public static IType addQualifiers(IType baseType, boolean cnst, boolean vol, boolean restrict) {
if (cnst || vol || restrict) {
if (baseType instanceof IQualifierType) {
IQualifierType qt= (IQualifierType) baseType;
if ((cnst && !qt.isConst()) || (vol && !qt.isVolatile())) {
@ -465,21 +458,24 @@ public class SemanticUtil {
return baseType;
} else if (baseType instanceof ICPPPointerToMemberType) {
ICPPPointerToMemberType pt= (ICPPPointerToMemberType) baseType;
if ((cnst && !pt.isConst()) || (vol && !pt.isVolatile())) {
return new CPPPointerToMemberType(pt.getType(), pt.getMemberOfClass(), cnst
|| pt.isConst(), vol || pt.isVolatile(), pt.isRestrict());
if ((cnst && !pt.isConst()) || (vol && !pt.isVolatile())
|| (restrict && !pt.isRestrict())) {
return new CPPPointerToMemberType(pt.getType(), pt.getMemberOfClass(),
cnst || pt.isConst(), vol || pt.isVolatile(), restrict || pt.isRestrict());
}
return baseType;
} else if (baseType instanceof IPointerType) {
IPointerType pt= (IPointerType) baseType;
if ((cnst && !pt.isConst()) || (vol && !pt.isVolatile())) {
return new CPPPointerType(pt.getType(), cnst || pt.isConst(), vol || pt.isVolatile(), pt.isRestrict());
if ((cnst && !pt.isConst()) || (vol && !pt.isVolatile())
|| (restrict && !pt.isRestrict())) {
return new CPPPointerType(pt.getType(),
cnst || pt.isConst(), vol || pt.isVolatile(), restrict || pt.isRestrict());
}
return baseType;
} else if (baseType instanceof IArrayType) {
IArrayType at= (IArrayType) baseType;
IType nested= at.getType();
IType newNested= addQualifiers(nested, cnst, vol);
IType newNested= addQualifiers(nested, cnst, vol, restrict);
if (newNested != nested && at instanceof ITypeContainer) {
return replaceNestedType((ITypeContainer) at, newNested);
}

View file

@ -697,7 +697,7 @@ public class TemplateArgumentDeduction {
} else if (p instanceof IQualifierType) {
final CVQualifier cvqP = SemanticUtil.getCVQualifier(p);
final CVQualifier cvqA = SemanticUtil.getCVQualifier(a);
CVQualifier remaining= CVQualifier._;
CVQualifier remaining= CVQualifier.NONE;
if (cvqP != cvqA) {
if (!allowCVQConversion && !cvqA.isAtLeastAsQualifiedAs(cvqP))
return false;
@ -707,8 +707,8 @@ public class TemplateArgumentDeduction {
a = SemanticUtil.getNestedType(a, ALLCVQ);
if (p instanceof IQualifierType)
return false;
if (remaining != CVQualifier._) {
a= SemanticUtil.addQualifiers(a, remaining.isConst(), remaining.isVolatile());
if (remaining != CVQualifier.NONE) {
a= SemanticUtil.addQualifiers(a, remaining.isConst(), remaining.isVolatile(), remaining.isRestrict());
}
} else if (p instanceof IFunctionType) {
if (!(a instanceof IFunctionType))

View file

@ -565,7 +565,7 @@ public class ASTManager {
if (t2 instanceof IPointerType) {
IPointerType a1= (IPointerType) t1;
IPointerType a2= (IPointerType) t2;
if (a1.isConst() != a2.isConst() || a1.isVolatile() != a2.isVolatile()) {
if (a1.isConst() != a2.isConst() || a1.isVolatile() != a2.isVolatile() || a1.isRestrict() != a2.isRestrict()) {
return FALSE;
}
return isSameType(a1.getType(), a2.getType());