diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 24e735ebc4a..7690a4352a0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -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); + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java index 8fecfc23bec..2f3ac17d414 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java @@ -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; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index 041adf1130b..2202a950138 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index ed3e7f777e7..62ba554c14c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java index cc2253c27b3..554407c43a4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java index 12b114d67cc..a5b3a16fe5d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java @@ -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); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 63a1bbc40b9..701aaeb49bc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index e4859c9e437..152a373b7ec 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 7d4e36bccb8..83171bc1303 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -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); } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CVQualifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CVQualifier.java index 0a16bce192b..cd3f8035b3b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CVQualifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CVQualifier.java @@ -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 + */ + public int partialComparison(CVQualifier cv2) { + // same qualifications + if (this == cv2) + return 0; + + if (!isAtLeastAsQualifiedAs(cv2)) + return -1; + return fQualifiers-cv2.fQualifiers; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index 8c8c7ddc2b5..78fd02c82b6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -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 { * */ 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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java index 6b0a00d4612..4052e7fc714 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java @@ -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) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 6c934a77d94..98a9c508939 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index a7fd66ad305..36ba86ba72c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -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)) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java index 04453b03e84..c844a579d34 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java @@ -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());