Keep track of the Expr used to describe the size of an array type,
from Enea Zaffanella!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74831 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index d1e8e21..6cbb1c3 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -282,8 +282,8 @@
         llvm::APInt One(Context.getTypeSize(Context.getSizeType()), 
                         true);
         QualType T 
-          = Context.getConstantArrayType(ArrayT->getElementType(),
-                                         One, ArrayType::Normal, 0);
+          = Context.getConstantArrayWithoutExprType(ArrayT->getElementType(),
+                                                    One, ArrayType::Normal, 0);
         VD->setType(T);
       }
     } else if (RequireCompleteType(VD->getLocation(), VD->getType(), 
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 7af80c0..4c213b6 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -378,7 +378,7 @@
                               SourceLocation Loc, DeclarationName Entity);
   QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
                           Expr *ArraySize, unsigned Quals,
-                          SourceLocation Loc, DeclarationName Entity);
+                          SourceRange Brackets, DeclarationName Entity);
   QualType BuildExtVectorType(QualType T, ExprArg ArraySize, 
                               SourceLocation AttrLoc);
   QualType BuildFunctionType(QualType T,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 1fd5697..f148e8d 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1568,9 +1568,18 @@
     return QualType();
 
   llvm::APSInt &Res = EvalResult.Val.getInt();
-  if (Res >= llvm::APSInt(Res.getBitWidth(), Res.isUnsigned()))
-    return Context.getConstantArrayType(VLATy->getElementType(),
-                                        Res, ArrayType::Normal, 0);
+  if (Res >= llvm::APSInt(Res.getBitWidth(), Res.isUnsigned())) {
+    Expr* ArySizeExpr = VLATy->getSizeExpr();
+    // FIXME: here we could "steal" (how?) ArySizeExpr from the VLA,
+    // so as to transfer ownership to the ConstantArrayWithExpr.
+    // Alternatively, we could "clone" it (how?).
+    // Since we don't know how to do things above, we just use the
+    // very same Expr*.
+    return Context.getConstantArrayWithExprType(VLATy->getElementType(),
+                                                Res, ArySizeExpr,
+                                                ArrayType::Normal, 0,
+                                                VLATy->getBracketsRange());
+  }
 
   SizeIsNegative = true;
   return QualType();
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index ecfdfd7..5be07e3 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -97,8 +97,9 @@
     llvm::APSInt ConstVal(32);
     ConstVal = StrLength;
     // Return a new array type (C99 6.7.8p22).
-    DeclT = S.Context.getConstantArrayType(IAT->getElementType(), ConstVal, 
-                                           ArrayType::Normal, 0);
+    DeclT = S.Context.getConstantArrayWithoutExprType(IAT->getElementType(),
+                                                      ConstVal,
+                                                      ArrayType::Normal, 0);
     return;
   }
   
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 6c2dc77..6ee50ab 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -421,7 +421,20 @@
   IntegerLiteral ArraySize(Size, SizeType, Loc);
   return SemaRef.BuildArrayType(ElementType, T->getSizeModifier(), 
                                 &ArraySize, T->getIndexTypeQualifier(), 
-                                Loc, Entity);
+                                SourceRange(), // FIXME: provide proper range?
+                                Entity);
+}
+
+QualType
+TemplateTypeInstantiator::InstantiateConstantArrayWithExprType
+(const ConstantArrayWithExprType *T) const {
+  return InstantiateConstantArrayType(T);
+}
+
+QualType
+TemplateTypeInstantiator::InstantiateConstantArrayWithoutExprType
+(const ConstantArrayWithoutExprType *T) const {
+  return InstantiateConstantArrayType(T);
 }
 
 QualType 
@@ -432,8 +445,9 @@
     return ElementType;
   
   return SemaRef.BuildArrayType(ElementType, T->getSizeModifier(), 
-                                0, T->getIndexTypeQualifier(), 
-                                Loc, Entity);
+                                0, T->getIndexTypeQualifier(),
+                                SourceRange(), // FIXME: provide proper range?
+                                Entity);
 }
 
 QualType
@@ -468,7 +482,9 @@
   
   return SemaRef.BuildArrayType(ElementType, T->getSizeModifier(),
                                 InstantiatedArraySize.takeAs<Expr>(),
-                                T->getIndexTypeQualifier(), Loc, Entity);
+                                T->getIndexTypeQualifier(),
+                                SourceRange(), // FIXME: provide proper range?
+                                Entity);
 }
 
 QualType 
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 3756df8..da61e6e 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -483,7 +483,8 @@
 /// returns a NULL type.
 QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
                               Expr *ArraySize, unsigned Quals,
-                              SourceLocation Loc, DeclarationName Entity) {
+                              SourceRange Brackets, DeclarationName Entity) {
+  SourceLocation Loc = Brackets.getBegin();
   // C99 6.7.5.2p1: If the element type is an incomplete or function type, 
   // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
   if (RequireCompleteType(Loc, T, 
@@ -530,16 +531,16 @@
   llvm::APSInt ConstVal(32);
   if (!ArraySize) {
     if (ASM == ArrayType::Star)
-      T = Context.getVariableArrayType(T, 0, ASM, Quals);
+      T = Context.getVariableArrayType(T, 0, ASM, Quals, Brackets);
     else
       T = Context.getIncompleteArrayType(T, ASM, Quals);
   } else if (ArraySize->isValueDependent()) {
-    T = Context.getDependentSizedArrayType(T, ArraySize, ASM, Quals);
+    T = Context.getDependentSizedArrayType(T, ArraySize, ASM, Quals, Brackets);
   } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context) ||
              (!T->isDependentType() && !T->isConstantSizeType())) {
     // Per C99, a variable array is an array with either a non-constant
     // size or an element type that has a non-constant-size
-    T = Context.getVariableArrayType(T, ArraySize, ASM, Quals);
+    T = Context.getVariableArrayType(T, ArraySize, ASM, Quals, Brackets);
   } else {
     // C99 6.7.5.2p1: If the expression is a constant expression, it shall
     // have a value greater than zero.
@@ -555,7 +556,8 @@
           << ArraySize->getSourceRange();
       }
     } 
-    T = Context.getConstantArrayType(T, ConstVal, ASM, Quals);
+    T = Context.getConstantArrayWithExprType(T, ConstVal, ArraySize,
+                                             ASM, Quals, Brackets);
   }
   // If this is not C99, extwarn about VLA's and C99 array size modifiers.
   if (!getLangOptions().C99) {
@@ -923,7 +925,8 @@
         ASM = ArrayType::Normal;
         D.setInvalidType(true);
       }
-      T = BuildArrayType(T, ASM, ArraySize, ATI.TypeQuals, DeclType.Loc, Name);
+      T = BuildArrayType(T, ASM, ArraySize, ATI.TypeQuals,
+                         SourceRange(DeclType.Loc, DeclType.EndLoc), Name);
       break;
     }
     case DeclaratorChunk::Function: {