Finally fix PR2189.  This makes a fairly invasive but important change to
move getAsArrayType into ASTContext instead of being a method on type.
This is required because getAsArrayType(const AT), where AT is a typedef
for "int[10]" needs to return ArrayType(const int, 10).

Fixing this greatly simplifies getArrayDecayedType, which is a good sign.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54317 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index f8835ff..e9343e3 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -386,8 +386,8 @@
 /// definition that would be otherwise equivalent.
 static bool areEquivalentArrayTypes(QualType NewQType, QualType OldQType,
                                     ASTContext &Context) {
-  const ArrayType *NewAT = NewQType->getAsArrayType();
-  const ArrayType *OldAT = OldQType->getAsArrayType();
+  const ArrayType *NewAT = Context.getAsArrayType(NewQType);
+  const ArrayType *OldAT = Context.getAsArrayType(OldQType);
 
   if (!NewAT || !OldAT)
     return false;
@@ -549,7 +549,9 @@
 }
 
 bool Sema::CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT) {
-  if (const IncompleteArrayType *IAT = DeclT->getAsIncompleteArrayType()) {
+  const ArrayType *AT = Context.getAsArrayType(DeclT);
+  
+  if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
     // C99 6.7.8p14. We have an array of character type with unknown size 
     // being initialized to a string literal.
     llvm::APSInt ConstVal(32);
@@ -557,14 +559,14 @@
     // Return a new array type (C99 6.7.8p22).
     DeclT = Context.getConstantArrayType(IAT->getElementType(), ConstVal, 
                                          ArrayType::Normal, 0);
-  } else if (const ConstantArrayType *CAT = DeclT->getAsConstantArrayType()) {
+  } else {
+    const ConstantArrayType *CAT = cast<ConstantArrayType>(AT);
     // C99 6.7.8p14. We have an array of character type with known size.
-    if (strLiteral->getByteLength() > (unsigned)CAT->getMaximumElements())
+    // FIXME: Avoid truncation for 64-bit length strings.
+    if (strLiteral->getByteLength() > (unsigned)CAT->getSize().getZExtValue())
       Diag(strLiteral->getSourceRange().getBegin(),
            diag::warn_initializer_string_for_char_array_too_long,
            strLiteral->getSourceRange());
-  } else {
-    assert(0 && "HandleStringLiteralInit(): Invalid array type");
   }
   // Set type from "char *" to "constant array of char".
   strLiteral->setType(DeclT);
@@ -573,7 +575,7 @@
 }
 
 StringLiteral *Sema::IsStringLiteralInit(Expr *Init, QualType DeclType) {
-  const ArrayType *AT = DeclType->getAsArrayType();
+  const ArrayType *AT = Context.getAsArrayType(DeclType);
   if (AT && AT->getElementType()->isCharType()) {
     return dyn_cast<StringLiteral>(Init);
   }
@@ -583,7 +585,7 @@
 bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType) {  
   // C99 6.7.8p3: The type of the entity to be initialized shall be an array
   // of unknown size ("[]") or an object type that is not a variable array type.
-  if (const VariableArrayType *VAT = DeclType->getAsVariableArrayType())
+  if (const VariableArrayType *VAT = Context.getAsVariableArrayType(DeclType))
     return Diag(VAT->getSizeExpr()->getLocStart(), 
                 diag::err_variable_object_no_init, 
                 VAT->getSizeExpr()->getSourceRange());
@@ -1393,7 +1395,7 @@
     // static storage duration, it shall not have a variable length array.
     if ((IDecl->isFileVarDecl() || IDecl->isBlockVarDecl()) && 
         IDecl->getStorageClass() == VarDecl::Static) {
-      if (T->getAsVariableArrayType()) {
+      if (T->isVariableArrayType()) {
         Diag(IDecl->getLocation(), diag::err_typecheck_illegal_vla);
         IDecl->setInvalidDecl();
       }
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 56632d1..6c6d6e2 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1055,7 +1055,7 @@
   Expr *literalExpr = static_cast<Expr*>(InitExpr);
 
   if (literalType->isArrayType()) {
-    if (literalType->getAsVariableArrayType())
+    if (literalType->isVariableArrayType())
       return Diag(LParenLoc,
                   diag::err_variable_object_no_init,
                   SourceRange(LParenLoc,
@@ -2381,7 +2381,7 @@
     const OffsetOfComponent &OC = CompPtr[i];
     if (OC.isBrackets) {
       // Offset of an array sub-field.  TODO: Should we allow vector elements?
-      const ArrayType *AT = Res->getType()->getAsArrayType();
+      const ArrayType *AT = Context.getAsArrayType(Res->getType());
       if (!AT) {
         delete Res;
         return Diag(OC.LocEnd, diag::err_offsetof_array_type,
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 0078cc1..1889baf 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -30,7 +30,8 @@
 int InitListChecker::numArrayElements(QualType DeclType) {
   // FIXME: use a proper constant
   int maxElements = 0x7FFFFFFF;
-  if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {
+  if (const ConstantArrayType *CAT =
+        SemaRef->Context.getAsConstantArrayType(DeclType)) {
     maxElements = static_cast<int>(CAT->getSize().getZExtValue());
   }
   return maxElements;
@@ -231,7 +232,8 @@
       return;
     }
   }
-  if (const VariableArrayType *VAT = DeclType->getAsVariableArrayType()) {
+  if (const VariableArrayType *VAT =
+        SemaRef->Context.getAsVariableArrayType(DeclType)) {
     // Check for VLAs; in standard C it would be possible to check this
     // earlier, but I don't know where clang accepts VLAs (gcc accepts
     // them in all sorts of strange places).
@@ -243,7 +245,8 @@
   }
 
   int maxElements = numArrayElements(DeclType);
-  QualType elementType = DeclType->getAsArrayType()->getElementType();
+  QualType elementType = SemaRef->Context.getAsArrayType(DeclType)
+                             ->getElementType();
   int numElements = 0;
   for (int i = 0; i < maxElements; ++i, ++numElements) {
     // Don't attempt to go past the end of the init list