diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 30 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 23 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 54 |
4 files changed, 64 insertions, 59 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 4bfea2421cb..fe962806091 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2372,6 +2372,36 @@ CanQualType ASTContext::getCanonicalType(QualType T) { VAT->getBracketsRange())); } +QualType ASTContext::getUnqualifiedArrayType(QualType T, + Qualifiers &Quals) { + assert(T.isCanonical() && "Only operates on canonical types"); + if (!isa<ArrayType>(T)) { + Quals = T.getLocalQualifiers(); + return T.getLocalUnqualifiedType(); + } + + assert(!T.hasQualifiers() && "canonical array type has qualifiers!"); + const ArrayType *AT = cast<ArrayType>(T); + QualType Elt = AT->getElementType(); + QualType UnqualElt = getUnqualifiedArrayType(Elt, Quals); + if (Elt == UnqualElt) + return T; + + if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T)) { + return getConstantArrayType(UnqualElt, CAT->getSize(), + CAT->getSizeModifier(), 0); + } + + if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(T)) { + return getIncompleteArrayType(UnqualElt, IAT->getSizeModifier(), 0); + } + + const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(T); + return getDependentSizedArrayType(UnqualElt, DSAT->getSizeExpr()->Retain(), + DSAT->getSizeModifier(), 0, + SourceRange()); +} + DeclarationName ASTContext::getNameForTemplate(TemplateName Name) { if (TemplateDecl *TD = Name.getAsTemplateDecl()) return TD->getDeclName(); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index a1800755bdc..ab90a80cabb 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4206,7 +4206,7 @@ Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, /// type, and the first type (T1) is the pointee type of the reference /// type being initialized. Sema::ReferenceCompareResult -Sema::CompareReferenceRelationship(SourceLocation Loc, +Sema::CompareReferenceRelationship(SourceLocation Loc, QualType OrigT1, QualType OrigT2, bool& DerivedToBase) { assert(!OrigT1->isReferenceType() && @@ -4215,8 +4215,9 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, QualType T1 = Context.getCanonicalType(OrigT1); QualType T2 = Context.getCanonicalType(OrigT2); - QualType UnqualT1 = T1.getLocalUnqualifiedType(); - QualType UnqualT2 = T2.getLocalUnqualifiedType(); + Qualifiers T1Quals, T2Quals; + QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals); + QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals); // C++ [dcl.init.ref]p4: // Given types "cv1 T1" and "cv2 T2," "cv1 T1" is @@ -4234,6 +4235,13 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, // At this point, we know that T1 and T2 are reference-related (at // least). + // If the type is an array type, promote the element qualifiers to the type + // for comparison. + if (isa<ArrayType>(T1) && T1Quals) + T1 = Context.getQualifiedType(UnqualT1, T1Quals); + if (isa<ArrayType>(T2) && T2Quals) + T2 = Context.getQualifiedType(UnqualT2, T2Quals); + // C++ [dcl.init.ref]p4: // "cv1 T1" is reference-compatible with "cv2 T2" if T1 is // reference-related to T2 and cv1 is the same cv-qualification @@ -4241,7 +4249,7 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, // overload resolution, cases for which cv1 is greater // cv-qualification than cv2 are identified as // reference-compatible with added qualification (see 13.3.3.2). - if (T1.getCVRQualifiers() == T2.getCVRQualifiers()) + if (T1Quals.getCVRQualifiers() == T2Quals.getCVRQualifiers()) return Ref_Compatible; else if (T1.isMoreQualifiedThan(T2)) return Ref_Compatible_With_Added_Qualification; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 72a85cc968d..99dbaba37be 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1802,7 +1802,16 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1, QualType T2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr); T1 = Context.getCanonicalType(T1); T2 = Context.getCanonicalType(T2); - if (Context.hasSameUnqualifiedType(T1, T2)) { + Qualifiers T1Quals, T2Quals; + QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals); + QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals); + if (UnqualT1 == UnqualT2) { + // If the type is an array type, promote the element qualifiers to the type + // for comparison. + if (isa<ArrayType>(T1) && T1Quals) + T1 = Context.getQualifiedType(UnqualT1, T1Quals); + if (isa<ArrayType>(T2) && T2Quals) + T2 = Context.getQualifiedType(UnqualT2, T2Quals); if (T2.isMoreQualifiedThan(T1)) return ImplicitConversionSequence::Better; else if (T1.isMoreQualifiedThan(T2)) @@ -1835,12 +1844,22 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1, QualType T2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr); T1 = Context.getCanonicalType(T1); T2 = Context.getCanonicalType(T2); + Qualifiers T1Quals, T2Quals; + QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals); + QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals); // If the types are the same, we won't learn anything by unwrapped // them. - if (Context.hasSameUnqualifiedType(T1, T2)) + if (UnqualT1 == UnqualT2) return ImplicitConversionSequence::Indistinguishable; + // If the type is an array type, promote the element qualifiers to the type + // for comparison. + if (isa<ArrayType>(T1) && T1Quals) + T1 = Context.getQualifiedType(UnqualT1, T1Quals); + if (isa<ArrayType>(T2) && T2Quals) + T2 = Context.getQualifiedType(UnqualT2, T2Quals); + ImplicitConversionSequence::CompareKind Result = ImplicitConversionSequence::Indistinguishable; while (UnwrapSimilarPointerTypes(T1, T2)) { diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 590a75174bf..e31c05cf2af 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -337,58 +337,6 @@ DeduceTemplateArguments(ASTContext &Context, return Sema::TDK_Success; } -/// \brief Returns a completely-unqualified array type, capturing the -/// qualifiers in Quals. -/// -/// \param Context the AST context in which the array type was built. -/// -/// \param T a canonical type that may be an array type. -/// -/// \param Quals will receive the full set of qualifiers that were -/// applied to the element type of the array. -/// -/// \returns if \p T is an array type, the completely unqualified array type -/// that corresponds to T. Otherwise, returns T. -static QualType getUnqualifiedArrayType(ASTContext &Context, QualType T, - Qualifiers &Quals) { - assert(T.isCanonical() && "Only operates on canonical types"); - if (!isa<ArrayType>(T)) { - Quals = T.getLocalQualifiers(); - return T.getLocalUnqualifiedType(); - } - - assert(!T.hasQualifiers() && "canonical array type has qualifiers!"); - - if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T)) { - QualType Elt = getUnqualifiedArrayType(Context, CAT->getElementType(), - Quals); - if (Elt == CAT->getElementType()) - return T; - - return Context.getConstantArrayType(Elt, CAT->getSize(), - CAT->getSizeModifier(), 0); - } - - if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(T)) { - QualType Elt = getUnqualifiedArrayType(Context, IAT->getElementType(), - Quals); - if (Elt == IAT->getElementType()) - return T; - - return Context.getIncompleteArrayType(Elt, IAT->getSizeModifier(), 0); - } - - const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(T); - QualType Elt = getUnqualifiedArrayType(Context, DSAT->getElementType(), - Quals); - if (Elt == DSAT->getElementType()) - return T; - - return Context.getDependentSizedArrayType(Elt, DSAT->getSizeExpr()->Retain(), - DSAT->getSizeModifier(), 0, - SourceRange()); -} - /// \brief Deduce the template arguments by comparing the parameter type and /// the argument type (C++ [temp.deduct.type]). /// @@ -459,7 +407,7 @@ DeduceTemplateArguments(ASTContext &Context, // FIXME: address spaces, ObjC GC qualifiers if (isa<ArrayType>(Arg)) { Qualifiers Quals; - Arg = getUnqualifiedArrayType(Context, Arg, Quals); + Arg = Context.getUnqualifiedArrayType(Arg, Quals); if (Quals) { Arg = Context.getQualifiedType(Arg, Quals); RecanonicalizeArg = true; |