More fixes to the handling of CVR-comparisons on array types. Adds a method to

QualType to get CVR-qualifiers through array types, and switches the primary
comparison methods to use it. This may allow simplifying some of the callers of
getUnqualifiedArrayType.

Also fix the normalizing of CV-qualification during template deduction to
normalize through arrays and allow a more qualified deduced array type. This
fixes PR5911.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92289 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2009-12-30 04:10:01 +00:00
Родитель beb8019429
Коммит e724246b9f
3 изменённых файлов: 34 добавлений и 9 удалений

Просмотреть файл

@ -531,7 +531,12 @@ public:
/// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
/// applied to this type.
unsigned getCVRQualifiers() const;
/// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
/// applied to this type, looking through any number of unqualified array
/// types to their element types' qualifiers.
unsigned getCVRQualifiersThroughArrayTypes() const;
bool isConstant(ASTContext& Ctx) const {
return QualType::isConstant(*this, Ctx);
}
@ -2686,7 +2691,20 @@ inline unsigned QualType::getCVRQualifiers() const {
return getLocalCVRQualifiers() |
getTypePtr()->getCanonicalTypeInternal().getLocalCVRQualifiers();
}
/// getCVRQualifiersThroughArrayTypes - If there are CVR qualifiers for this
/// type, returns them. Otherwise, if this is an array type, recurses
/// on the element type until some qualifiers have been found or a non-array
/// type reached.
inline unsigned QualType::getCVRQualifiersThroughArrayTypes() const {
if (unsigned Quals = getCVRQualifiers())
return Quals;
QualType CT = getTypePtr()->getCanonicalTypeInternal();
if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
return AT->getElementType().getCVRQualifiersThroughArrayTypes();
return 0;
}
inline void QualType::removeConst() {
removeFastQualifiers(Qualifiers::Const);
}
@ -2786,8 +2804,8 @@ inline bool QualType::getNoReturnAttr() const {
/// int".
inline bool QualType::isMoreQualifiedThan(QualType Other) const {
// FIXME: work on arbitrary qualifiers
unsigned MyQuals = this->getCVRQualifiers();
unsigned OtherQuals = Other.getCVRQualifiers();
unsigned MyQuals = this->getCVRQualifiersThroughArrayTypes();
unsigned OtherQuals = Other.getCVRQualifiersThroughArrayTypes();
if (getAddressSpace() != Other.getAddressSpace())
return false;
return MyQuals != OtherQuals && (MyQuals | OtherQuals) == MyQuals;
@ -2799,8 +2817,8 @@ inline bool QualType::isMoreQualifiedThan(QualType Other) const {
/// "int", and "const volatile int".
inline bool QualType::isAtLeastAsQualifiedAs(QualType Other) const {
// FIXME: work on arbitrary qualifiers
unsigned MyQuals = this->getCVRQualifiers();
unsigned OtherQuals = Other.getCVRQualifiers();
unsigned MyQuals = this->getCVRQualifiersThroughArrayTypes();
unsigned OtherQuals = Other.getCVRQualifiersThroughArrayTypes();
if (getAddressSpace() != Other.getAddressSpace())
return false;
return (MyQuals | OtherQuals) == MyQuals;

Просмотреть файл

@ -375,9 +375,11 @@ DeduceTemplateArguments(ASTContext &Context,
// referred to by the reference) can be more cv-qualified than the
// transformed A.
if (TDF & TDF_ParamWithReferenceType) {
Qualifiers Quals = Param.getQualifiers();
Quals.setCVRQualifiers(Quals.getCVRQualifiers() & Arg.getCVRQualifiers());
Param = Context.getQualifiedType(Param.getUnqualifiedType(), Quals);
Qualifiers Quals;
QualType UnqualParam = Context.getUnqualifiedArrayType(Param, Quals);
Quals.setCVRQualifiers(Quals.getCVRQualifiers() &
Arg.getCVRQualifiersThroughArrayTypes());
Param = Context.getQualifiedType(UnqualParam, Quals);
}
// If the parameter type is not dependent, there is nothing to deduce.

Просмотреть файл

@ -81,3 +81,8 @@ int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -
int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
// PR5911
template <typename T, int N> void f(const T (&a)[N]);
int iarr[] = { 1 };
void test_PR5911() { f(iarr); }