Correctly refer to element CVR qualifications when determining if a type is
more or less cv-qualified than another during implicit conversion and overload
resolution ([basic.type.qualifier] p5). Factors the logic out of template
deduction and into the ASTContext so it can be shared.

This fixes several aspects of PR5542, but not all of them.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92248 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 4bfea24..fe96280 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2372,6 +2372,36 @@
                                                      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();