]> granicus.if.org Git - clang/commitdiff
Polish yesterday's Array/ConstantArray/VariableArray rewrite, removing a couple FIXME's.
authorSteve Naroff <snaroff@apple.com>
Thu, 30 Aug 2007 18:10:14 +0000 (18:10 +0000)
committerSteve Naroff <snaroff@apple.com>
Thu, 30 Aug 2007 18:10:14 +0000 (18:10 +0000)
Refactored Array/VariableArray, moving SizeModifier/IndexTypeQuals back up to Array. These
attributes are not specific to VLA's. Most of them are specific to array parameter types.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41616 91177308-0d34-0410-b5e6-96231b3b80d8

AST/ASTContext.cpp
AST/Type.cpp
Sema/SemaType.cpp
include/clang/AST/ASTContext.h
include/clang/AST/Type.h

index 57c1c44dbe31cb7d3807914d05baa39215f45860..6a852950a70620e6542888a16d15f3b2d68d239d 100644 (file)
@@ -404,7 +404,9 @@ QualType ASTContext::getReferenceType(QualType T) {
 /// getConstantArrayType - Return the unique reference to the type for an 
 /// array of the specified element type.
 QualType ASTContext::getConstantArrayType(QualType EltTy, 
-                                          const llvm::APInt &ArySize) {
+                                          const llvm::APInt &ArySize,
+                                          ArrayType::ArraySizeModifier ASM,
+                                          unsigned EltTypeQuals) {
   llvm::FoldingSetNodeID ID;
   ConstantArrayType::Profile(ID, EltTy, ArySize);
       
@@ -416,14 +418,15 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
   // so fill in the canonical type field.
   QualType Canonical;
   if (!EltTy->isCanonical()) {
-    Canonical = getConstantArrayType(EltTy.getCanonicalType(), ArySize);
-    
+    Canonical = getConstantArrayType(EltTy.getCanonicalType(), ArySize
+                                     ASM, EltTypeQuals);
     // Get the new insert position for the node we care about.
     ConstantArrayType *NewIP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
     assert(NewIP == 0 && "Shouldn't be in the map!");
   }
   
-  ConstantArrayType *New = new ConstantArrayType(EltTy, Canonical, ArySize);
+  ConstantArrayType *New = new ConstantArrayType(EltTy, Canonical, ArySize,
+                                                 ASM, EltTypeQuals);
   ArrayTypes.InsertNode(New, InsertPos);
   Types.push_back(New);
   return QualType(New, 0);
@@ -432,22 +435,14 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
 /// getArrayType - If NumElts is a constant expression, we return a unique
 /// reference to an AST node of type ConstantArrayType. If NumElts is not
 /// a constant expression, we return an instance of VaribleLengthArrayType.
-QualType ASTContext::getArrayType(QualType EltTy,
-                                  ArrayType::ArraySizeModifier ASM,
-                                  unsigned EltTypeQuals, Expr *NumElts) {
-  llvm::APSInt ArySize(32);
-  // If no expression was provided, we consider it a VLA.
-  if (!NumElts || !NumElts->isIntegerConstantExpr(ArySize, *this)) {
-    // Since we don't unique expressions, it isn't possible to unique VLA's.
-    ArrayType *New = new VariableArrayType(EltTy, ASM, EltTypeQuals, 
-                                           QualType(), NumElts);
-    Types.push_back(New);
-    return QualType(New, 0);
-  }
-  // Unique constant array types, to guarantee there is only one array of a
-  // particular structure.
-  // FIXME: should we warn if ASM != ArrayType::Normal or EltTypeQuals != 0?
-  return getConstantArrayType(EltTy, ArySize);
+QualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts,
+                                          ArrayType::ArraySizeModifier ASM,
+                                          unsigned EltTypeQuals) {
+  // Since we don't unique expressions, it isn't possible to unique VLA's.
+  ArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts, 
+                                         ASM, EltTypeQuals);
+  Types.push_back(New);
+  return QualType(New, 0);
 }
 
 /// getVectorType - Return the unique reference to a vector type of
index c0c278d19ec2e5fd8f9ff8e07609a31cdf2067e1..126f3d5db98f6e68722f619b2bb22dfe2295f899 100644 (file)
@@ -700,14 +700,14 @@ void ConstantArrayType::getAsStringInternal(std::string &S) const {
 void VariableArrayType::getAsStringInternal(std::string &S) const {
   S += '[';
   
-  if (IndexTypeQuals) {
-    AppendTypeQualList(S, IndexTypeQuals);
+  if (getIndexTypeQualifier()) {
+    AppendTypeQualList(S, getIndexTypeQualifier());
     S += ' ';
   }
   
-  if (SizeModifier == Static)
+  if (getSizeModifier() == Static)
     S += "static";
-  else if (SizeModifier == Star)
+  else if (getSizeModifier() == Star)
     S += '*';
   
   if (getSizeExpr()) {
index 3bc0e760ba9fb59e13223fdd24fe2aa28fa0257b..d1d62a6ea207757f1305fa2e95fc37b4757d85b9 100644 (file)
@@ -202,8 +202,13 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
           D.setInvalidType(true);
         }
       }
-      T = Context.getArrayType(T, ASM, ATI.TypeQuals, ArraySize);
-      
+      llvm::APSInt ConstVal(32);
+      // If no expression was provided, we consider it a VLA.
+      if (!ArraySize || !ArraySize->isIntegerConstantExpr(ConstVal, Context))
+        T = Context.getVariableArrayType(T, ArraySize, ASM, ATI.TypeQuals);
+      else
+        T = Context.getConstantArrayType(T, ConstVal, ASM, ATI.TypeQuals);
+        
       // If this is not C99, extwarn about VLA's and C99 array size modifiers.
       if (!getLangOptions().C99 && 
           (ASM != ArrayType::Normal ||
index 372109a8f82a80c688bddfb7d9a45adb4d56aa30..b1c71ac98c8dc6ac602a660f9fd9dad366002839 100644 (file)
@@ -80,12 +80,15 @@ public:
   /// getArrayType - If NumElts is a constant expression, we return a unique
   /// reference to an AST node of type ConstantArrayType. If NumElts is not
   /// a constant expression, we return an instance of VaribleLengthArrayType.
-  QualType getArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM,
-                        unsigned EltTypeQuals, Expr *NumElts);
+  QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
+                                ArrayType::ArraySizeModifier ASM,
+                                unsigned EltTypeQuals);
 
   /// getConstantArrayType - Return the unique reference to the type for an 
   /// array of the specified element type.
-  QualType getConstantArrayType(QualType EltTy, const llvm::APInt &Sz);
+  QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
+                                ArrayType::ArraySizeModifier ASM,
+                                unsigned EltTypeQuals);
                         
   /// getVectorType - Return the unique reference to a vector type of
   /// the specified element type and size. VectorType must be a built-in type.
index 58b3f4af51388a295a577a8eed4072f0e89f49e4..a8fb40699bc2d28de41dedcf4a050ab7cb7ba933 100644 (file)
@@ -437,19 +437,30 @@ class ArrayType : public Type {
 public:
   /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
   /// an array with a static size (e.g. int X[static 4]), or with a star size
-  /// (e.g. int X[*]). FIXME: consider moving this down to VLAArayType.
+  /// (e.g. int X[*]). 'static' is only allowed on function parameters.
   enum ArraySizeModifier {
     Normal, Static, Star
   };
 private:
   /// ElementType - The element type of the array.
   QualType ElementType;
+  
+  /// NOTE: These fields are packed into the bitfields space in the Type class.
+  ArraySizeModifier SizeModifier : 2;
+  
+  /// IndexTypeQuals - Capture qualifiers in declarations like:
+  /// 'int X[static restrict 4]'. For function parameters only.
+  unsigned IndexTypeQuals : 3;
+  
 protected:
-  ArrayType(TypeClass tc, QualType et, QualType can)
-    : Type(tc, can), ElementType(et) {}
+  ArrayType(TypeClass tc, QualType et, QualType can,
+            ArraySizeModifier sm, unsigned tq)
+    : Type(tc, can), ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
   QualType getElementType() const { return ElementType; }
+  ArraySizeModifier getSizeModifier() const { return SizeModifier; }
+  unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
   
   static bool classof(const Type *T) {
     return T->getTypeClass() == ConstantArray ||
@@ -461,8 +472,9 @@ public:
 class ConstantArrayType : public ArrayType, public llvm::FoldingSetNode {
   llvm::APInt Size; // Allows us to unique the type.
   
-  ConstantArrayType(QualType et, QualType can, llvm::APInt sz)
-    : ArrayType(ConstantArray, et, can), Size(sz) {}
+  ConstantArrayType(QualType et, QualType can, llvm::APInt sz,
+                    ArraySizeModifier sm, unsigned tq)
+    : ArrayType(ConstantArray, et, can, sm, tq), Size(sz) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
   llvm::APInt getSize() const { return Size; }
@@ -485,25 +497,15 @@ public:
 
 // FIXME: VariableArrayType's aren't uniqued (since expressions aren't).
 class VariableArrayType : public ArrayType {
-  /// NOTE: These fields are packed into the bitfields space in the Type class.
-  ArraySizeModifier SizeModifier : 2;
-  
-  /// IndexTypeQuals - Capture qualifiers in declarations like:
-  /// 'int X[static restrict 4]'.
-  unsigned IndexTypeQuals : 3;
-  
   /// SizeExpr - An assignment expression. VLA's are only permitted within 
   /// a function block. 
   Expr *SizeExpr;
   
-  VariableArrayType(QualType et, ArraySizeModifier sm, unsigned tq, 
-                          QualType can, Expr *e)
-    : ArrayType(VariableArray, et, can), 
-      SizeModifier(sm), IndexTypeQuals(tq), SizeExpr(e) {}
+  VariableArrayType(QualType et, QualType can, Expr *e,
+                    ArraySizeModifier sm, unsigned tq)
+    : ArrayType(VariableArray, et, can, sm, tq), SizeExpr(e) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
-  ArraySizeModifier getSizeModifier() const { return SizeModifier; }
-  unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
   Expr *getSizeExpr() const { return SizeExpr; }
   
   virtual void getAsStringInternal(std::string &InnerString) const;