[cfe-commits] r74831 - in /cfe/trunk: include/clang/AST/ include/clang/Frontend/ include/clang/Parse/ lib/AST/ lib/CodeGen/ lib/Frontend/ lib/Parse/ lib/Sema/

Douglas Gregor dgregor at apple.com
Mon Jul 6 08:59:41 PDT 2009


Author: dgregor
Date: Mon Jul  6 10:59:29 2009
New Revision: 74831

URL: http://llvm.org/viewvc/llvm-project?rev=74831&view=rev
Log:
Keep track of the Expr used to describe the size of an array type,
from Enea Zaffanella!

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/PrettyPrinter.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/AST/TypeNodes.def
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/include/clang/Parse/DeclSpec.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Jul  6 10:59:29 2009
@@ -274,7 +274,8 @@
   /// variable array of the specified element type.
   QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
                                 ArrayType::ArraySizeModifier ASM,
-                                unsigned EltTypeQuals);
+                                unsigned EltTypeQuals,
+                                SourceRange Brackets);
   
   /// getDependentSizedArrayType - Returns a non-unique reference to
   /// the type for a dependently-sized array of the specified element
@@ -282,7 +283,8 @@
   /// comparable, at some point.
   QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
                                       ArrayType::ArraySizeModifier ASM,
-                                      unsigned EltTypeQuals);
+                                      unsigned EltTypeQuals,
+                                      SourceRange Brackets);
 
   /// getIncompleteArrayType - Returns a unique reference to the type for a
   /// incomplete array of the specified element type.
@@ -295,7 +297,23 @@
   QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
                                 ArrayType::ArraySizeModifier ASM,
                                 unsigned EltTypeQuals);
-                        
+
+  /// getConstantArrayWithExprType - Return a reference to the type for a
+  /// constant array of the specified element type.
+  QualType getConstantArrayWithExprType(QualType EltTy,
+                                        const llvm::APInt &ArySize,
+                                        Expr *ArySizeExpr,
+                                        ArrayType::ArraySizeModifier ASM,
+                                        unsigned EltTypeQuals,
+                                        SourceRange Brackets);
+
+  /// getConstantArrayWithoutExprType - Return a reference to the type
+  /// for a constant array of the specified element type.
+  QualType getConstantArrayWithoutExprType(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.
   QualType getVectorType(QualType VectorType, unsigned NumElts);

Modified: cfe/trunk/include/clang/AST/PrettyPrinter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/PrettyPrinter.h?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/PrettyPrinter.h (original)
+++ cfe/trunk/include/clang/AST/PrettyPrinter.h Mon Jul  6 10:59:29 2009
@@ -79,6 +79,24 @@
   /// and pretty-printing involves printing something similar to
   /// source code.
   bool Dump : 1;
+
+  /// \brief Whether we should print the sizes of constant array expressions
+  /// as written in the sources.
+  ///
+  /// This flag is determines whether arrays types declared as
+  ///
+  /// \code
+  /// int a[4+10*10];
+  /// char a[] = "A string";
+  /// \endcode
+  ///
+  /// will be printed as written or as follows:
+  ///
+  /// \code
+  /// int a[104];
+  /// char a[9] = "A string";
+  /// \endcode
+  bool ConstantArraySizeAsWritten : 1;
 };
 
 } // end namespace clang

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Jul  6 10:59:29 2009
@@ -291,7 +291,7 @@
   /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
   /// Note that this should stay at the end of the ivars for Type so that
   /// subclasses can pack their bitfields into the same word.
-  unsigned TC : 5;
+  unsigned TC : 6;
 
   Type(const Type&);           // DO NOT IMPLEMENT.
   void operator=(const Type&); // DO NOT IMPLEMENT.
@@ -839,6 +839,8 @@
   
   static bool classof(const Type *T) {
     return T->getTypeClass() == ConstantArray ||
+           T->getTypeClass() == ConstantArrayWithExpr ||
+           T->getTypeClass() == ConstantArrayWithoutExpr ||
            T->getTypeClass() == VariableArray ||
            T->getTypeClass() == IncompleteArray ||
            T->getTypeClass() == DependentSizedArray;
@@ -846,15 +848,21 @@
   static bool classof(const ArrayType *) { return true; }
 };
 
-/// ConstantArrayType - This class represents C arrays with a specified constant
-/// size.  For example 'int A[100]' has ConstantArrayType where the element type
-/// is 'int' and the size is 100.
+/// ConstantArrayType - This class represents the canonical version of
+/// C arrays with a specified constant size.  For example, the canonical
+/// type for 'int A[4 + 4*100]' is a ConstantArrayType where the element
+/// type is 'int' and the size is 404.
 class ConstantArrayType : public ArrayType {
   llvm::APInt Size; // Allows us to unique the type.
   
   ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
                     ArraySizeModifier sm, unsigned tq)
-    : ArrayType(ConstantArray, et, can, sm, tq), Size(size) {}
+    : ArrayType(ConstantArray, et, can, sm, tq),
+      Size(size) {}
+protected:
+  ConstantArrayType(TypeClass tc, QualType et, QualType can,
+                    const llvm::APInt &size, ArraySizeModifier sm, unsigned tq)
+    : ArrayType(tc, et, can, sm, tq), Size(size) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
   const llvm::APInt &getSize() const { return Size; }
@@ -872,22 +880,91 @@
     ID.AddInteger(SizeMod);
     ID.AddInteger(TypeQuals);
   }
-  static bool classof(const Type *T) { 
-    return T->getTypeClass() == ConstantArray; 
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ConstantArray ||
+           T->getTypeClass() == ConstantArrayWithExpr ||
+           T->getTypeClass() == ConstantArrayWithoutExpr;
   }
   static bool classof(const ConstantArrayType *) { return true; }
 };
 
+/// ConstantArrayWithExprType - This class represents C arrays with a
+/// constant size specified by means of an integer constant expression.
+/// For example 'int A[sizeof(int)]' has ConstantArrayWithExprType where
+/// the element type is 'int' and the size expression is 'sizeof(int)'.
+/// These types are non-canonical.
+class ConstantArrayWithExprType : public ConstantArrayType {
+  /// SizeExpr - The ICE occurring in the concrete syntax.
+  Expr *SizeExpr;
+  /// Brackets - The left and right array brackets.
+  SourceRange Brackets;
+
+  ConstantArrayWithExprType(QualType et, QualType can,
+                            const llvm::APInt &size, Expr *e,
+                            ArraySizeModifier sm, unsigned tq,
+                            SourceRange brackets)
+    : ConstantArrayType(ConstantArrayWithExpr, et, can, size, sm, tq),
+      SizeExpr(e), Brackets(brackets) {}
+  friend class ASTContext;  // ASTContext creates these.
+  virtual void Destroy(ASTContext& C);
+
+public:
+  Expr *getSizeExpr() const { return SizeExpr; }
+  SourceRange getBracketsRange() const { return Brackets; }
+  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
+  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
+
+  virtual void getAsStringInternal(std::string &InnerString,
+                                   const PrintingPolicy &Policy) const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ConstantArrayWithExpr;
+  }
+  static bool classof(const ConstantArrayWithExprType *) { return true; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    assert(0 && "Cannot unique ConstantArrayWithExprTypes.");
+  }
+};
+
+/// ConstantArrayWithoutExprType - This class represents C arrays with a
+/// constant size that was not specified by an integer constant expression,
+/// but inferred by static semantics.
+/// For example 'int A[] = { 0, 1, 2 }' has ConstantArrayWithoutExprType.
+/// These types are non-canonical: the corresponding canonical type,
+/// having the size specified in an APInt object, is a ConstantArrayType.
+class ConstantArrayWithoutExprType : public ConstantArrayType {
+
+  ConstantArrayWithoutExprType(QualType et, QualType can,
+                               const llvm::APInt &size,
+                               ArraySizeModifier sm, unsigned tq)
+    : ConstantArrayType(ConstantArrayWithoutExpr, et, can, size, sm, tq) {}
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  virtual void getAsStringInternal(std::string &InnerString,
+                                   const PrintingPolicy &Policy) const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ConstantArrayWithoutExpr;
+  }
+  static bool classof(const ConstantArrayWithoutExprType *) { return true; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    assert(0 && "Cannot unique ConstantArrayWithoutExprTypes.");
+  }
+};
+
 /// IncompleteArrayType - This class represents C arrays with an unspecified
 /// size.  For example 'int A[]' has an IncompleteArrayType where the element
 /// type is 'int' and the size is unspecified.
 class IncompleteArrayType : public ArrayType {
+
   IncompleteArrayType(QualType et, QualType can,
-                    ArraySizeModifier sm, unsigned tq)
+                      ArraySizeModifier sm, unsigned tq)
     : ArrayType(IncompleteArray, et, can, sm, tq) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
-
   virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const;
 
   static bool classof(const Type *T) { 
@@ -928,10 +1005,14 @@
   /// SizeExpr - An assignment expression. VLA's are only permitted within 
   /// a function block. 
   Stmt *SizeExpr;
-  
+  /// Brackets - The left and right array brackets.
+  SourceRange Brackets;
+
   VariableArrayType(QualType et, QualType can, Expr *e,
-                    ArraySizeModifier sm, unsigned tq)
-    : ArrayType(VariableArray, et, can, sm, tq), SizeExpr((Stmt*) e) {}
+                    ArraySizeModifier sm, unsigned tq,
+                    SourceRange brackets)
+    : ArrayType(VariableArray, et, can, sm, tq),
+      SizeExpr((Stmt*) e), Brackets(brackets) {}
   friend class ASTContext;  // ASTContext creates these.
   virtual void Destroy(ASTContext& C);
 
@@ -941,6 +1022,9 @@
     // to have a dependency of Type.h on Stmt.h/Expr.h.
     return (Expr*) SizeExpr;
   }
+  SourceRange getBracketsRange() const { return Brackets; }
+  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
+  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
   
   virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const;
   
@@ -971,10 +1055,14 @@
   /// SizeExpr - An assignment expression that will instantiate to the
   /// size of the array.
   Stmt *SizeExpr;
+  /// Brackets - The left and right array brackets.
+  SourceRange Brackets;
   
   DependentSizedArrayType(QualType et, QualType can, Expr *e,
-			  ArraySizeModifier sm, unsigned tq)
-    : ArrayType(DependentSizedArray, et, can, sm, tq), SizeExpr((Stmt*) e) {}
+			  ArraySizeModifier sm, unsigned tq,
+                          SourceRange brackets)
+    : ArrayType(DependentSizedArray, et, can, sm, tq),
+      SizeExpr((Stmt*) e), Brackets(brackets) {}
   friend class ASTContext;  // ASTContext creates these.
   virtual void Destroy(ASTContext& C);
 
@@ -984,6 +1072,9 @@
     // to have a dependency of Type.h on Stmt.h/Expr.h.
     return (Expr*) SizeExpr;
   }
+  SourceRange getBracketsRange() const { return Brackets; }
+  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
+  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
   
   virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const;
   

Modified: cfe/trunk/include/clang/AST/TypeNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)
+++ cfe/trunk/include/clang/AST/TypeNodes.def Mon Jul  6 10:59:29 2009
@@ -57,6 +57,8 @@
 TYPE(MemberPointer, Type)
 ABSTRACT_TYPE(Array, Type)
 TYPE(ConstantArray, ArrayType)
+NON_CANONICAL_TYPE(ConstantArrayWithExpr, ConstantArrayType)
+NON_CANONICAL_TYPE(ConstantArrayWithoutExpr, ConstantArrayType)
 TYPE(IncompleteArray, ArrayType)
 TYPE(VariableArray, ArrayType)
 DEPENDENT_TYPE(DependentSizedArray, ArrayType)

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Mon Jul  6 10:59:29 2009
@@ -393,7 +393,11 @@
       /// \brief An ObjCObjectPointerType record.
       TYPE_OBJC_OBJECT_POINTER      = 23,
       /// \brief a DecltypeType record.
-      TYPE_DECLTYPE                 = 24
+      TYPE_DECLTYPE                 = 24,
+      /// \brief A ConstantArrayWithExprType record.
+      TYPE_CONSTANT_ARRAY_WITH_EXPR = 25,
+      /// \brief A ConstantArrayWithoutExprType record.
+      TYPE_CONSTANT_ARRAY_WITHOUT_EXPR = 26
     };
 
     /// \brief The type IDs for special types constructed by semantic

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Mon Jul  6 10:59:29 2009
@@ -457,6 +457,8 @@
 
   /// Loc - The place where this type was defined.
   SourceLocation Loc;
+  /// EndLoc - If valid, the place where this chunck ends.
+  SourceLocation EndLoc;
   
   struct PointerTypeInfo {
     /// The type qualifiers: const/volatile/restrict.
@@ -696,10 +698,11 @@
   ///
   static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic,
                                   bool isStar, void *NumElts,
-                                  SourceLocation Loc) {
+                                  SourceLocation LBLoc, SourceLocation RBLoc) {
     DeclaratorChunk I;
     I.Kind          = Array;
-    I.Loc           = Loc;
+    I.Loc           = LBLoc;
+    I.EndLoc        = RBLoc;
     I.Arr.TypeQuals = TypeQuals;
     I.Arr.hasStatic = isStatic;
     I.Arr.isStar    = isStar;

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Jul  6 10:59:29 2009
@@ -475,6 +475,8 @@
     Align = getTypeAlign(cast<ArrayType>(T)->getElementType());
     break;
 
+  case Type::ConstantArrayWithExpr:
+  case Type::ConstantArrayWithoutExpr:
   case Type::ConstantArray: {
     const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
     
@@ -1344,16 +1346,68 @@
   return QualType(New, 0);
 }
 
+/// getConstantArrayWithExprType - Return a reference to the type for
+/// an array of the specified element type.
+QualType
+ASTContext::getConstantArrayWithExprType(QualType EltTy,
+                                         const llvm::APInt &ArySizeIn,
+                                         Expr *ArySizeExpr,
+                                         ArrayType::ArraySizeModifier ASM,
+                                         unsigned EltTypeQuals,
+                                         SourceRange Brackets) {
+  // Convert the array size into a canonical width matching the pointer
+  // size for the target.
+  llvm::APInt ArySize(ArySizeIn);
+  ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace()));
+
+  // Compute the canonical ConstantArrayType.
+  QualType Canonical = getConstantArrayType(getCanonicalType(EltTy),
+                                            ArySize, ASM, EltTypeQuals);
+  // Since we don't unique expressions, it isn't possible to unique VLA's
+  // that have an expression provided for their size.
+  ConstantArrayWithExprType *New =
+    new(*this,8)ConstantArrayWithExprType(EltTy, Canonical,
+                                          ArySize, ArySizeExpr,
+                                          ASM, EltTypeQuals, Brackets);
+  Types.push_back(New);
+  return QualType(New, 0);
+}
+
+/// getConstantArrayWithoutExprType - Return a reference to the type for
+/// an array of the specified element type.
+QualType
+ASTContext::getConstantArrayWithoutExprType(QualType EltTy,
+                                            const llvm::APInt &ArySizeIn,
+                                            ArrayType::ArraySizeModifier ASM,
+                                            unsigned EltTypeQuals) {
+  // Convert the array size into a canonical width matching the pointer
+  // size for the target.
+  llvm::APInt ArySize(ArySizeIn);
+  ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace()));
+
+  // Compute the canonical ConstantArrayType.
+  QualType Canonical = getConstantArrayType(getCanonicalType(EltTy),
+                                            ArySize, ASM, EltTypeQuals);
+  ConstantArrayWithoutExprType *New =
+    new(*this,8)ConstantArrayWithoutExprType(EltTy, Canonical,
+                                             ArySize, ASM, EltTypeQuals);
+  Types.push_back(New);
+  return QualType(New, 0);
+}
+
 /// getVariableArrayType - Returns a non-unique reference to the type for a
 /// variable array of the specified element type.
-QualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts,
+QualType ASTContext::getVariableArrayType(QualType EltTy,
+                                          Expr *NumElts,
                                           ArrayType::ArraySizeModifier ASM,
-                                          unsigned EltTypeQuals) {
+                                          unsigned EltTypeQuals,
+                                          SourceRange Brackets) {
   // Since we don't unique expressions, it isn't possible to unique VLA's
   // that have an expression provided for their size.
 
   VariableArrayType *New =
-    new(*this,8)VariableArrayType(EltTy,QualType(), NumElts, ASM, EltTypeQuals);
+    new(*this,8)VariableArrayType(EltTy, QualType(),
+                                  NumElts, ASM, EltTypeQuals, Brackets);
 
   VariableArrayTypes.push_back(New);
   Types.push_back(New);
@@ -1364,9 +1418,11 @@
 /// the type for a dependently-sized array of the specified element
 /// type. FIXME: We will need these to be uniqued, or at least
 /// comparable, at some point.
-QualType ASTContext::getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
+QualType ASTContext::getDependentSizedArrayType(QualType EltTy,
+                                                Expr *NumElts,
                                                 ArrayType::ArraySizeModifier ASM,
-                                                unsigned EltTypeQuals) {
+                                                unsigned EltTypeQuals,
+                                                SourceRange Brackets) {
   assert((NumElts->isTypeDependent() || NumElts->isValueDependent()) && 
          "Size must be type- or value-dependent!");
 
@@ -1374,8 +1430,9 @@
   // dependently-sized array types.
 
   DependentSizedArrayType *New =
-      new (*this,8) DependentSizedArrayType(EltTy, QualType(), NumElts, 
-                                            ASM, EltTypeQuals);
+    new (*this,8) DependentSizedArrayType(EltTy, QualType(),
+                                          NumElts, ASM, EltTypeQuals,
+                                          Brackets);
 
   DependentSizedArrayTypes.push_back(New);
   Types.push_back(New);
@@ -1407,8 +1464,9 @@
     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
   }
 
-  IncompleteArrayType *New = new (*this,8) IncompleteArrayType(EltTy, Canonical,
-                                                           ASM, EltTypeQuals);
+  IncompleteArrayType *New
+    = new (*this,8) IncompleteArrayType(EltTy, Canonical,
+                                        ASM, EltTypeQuals);
 
   IncompleteArrayTypes.InsertNode(New, InsertPos);
   Types.push_back(New);
@@ -1974,14 +2032,18 @@
                                   IAT->getIndexTypeQualifier());
   
   if (DependentSizedArrayType *DSAT = dyn_cast<DependentSizedArrayType>(AT))
-    return getDependentSizedArrayType(NewEltTy, DSAT->getSizeExpr(),
+    return getDependentSizedArrayType(NewEltTy,
+                                      DSAT->getSizeExpr(),
                                       DSAT->getSizeModifier(),
-                                      DSAT->getIndexTypeQualifier());    
+                                      DSAT->getIndexTypeQualifier(),
+                                      DSAT->getBracketsRange());
 
   VariableArrayType *VAT = cast<VariableArrayType>(AT);
-  return getVariableArrayType(NewEltTy, VAT->getSizeExpr(),
+  return getVariableArrayType(NewEltTy,
+                              VAT->getSizeExpr(),
                               VAT->getSizeModifier(),
-                              VAT->getIndexTypeQualifier());
+                              VAT->getIndexTypeQualifier(),
+                              VAT->getBracketsRange());
 }
 
 Decl *ASTContext::getCanonicalDecl(Decl *D) {
@@ -2136,7 +2198,7 @@
   if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(ATy))
     return cast<ArrayType>(getIncompleteArrayType(NewEltTy,
                                                   IAT->getSizeModifier(),
-                                                 IAT->getIndexTypeQualifier()));
+                                                  IAT->getIndexTypeQualifier()));
 
   if (const DependentSizedArrayType *DSAT 
         = dyn_cast<DependentSizedArrayType>(ATy))
@@ -2144,12 +2206,15 @@
                      getDependentSizedArrayType(NewEltTy, 
                                                 DSAT->getSizeExpr(),
                                                 DSAT->getSizeModifier(),
-                                                DSAT->getIndexTypeQualifier()));
+                                                DSAT->getIndexTypeQualifier(),
+                                                DSAT->getBracketsRange()));
   
   const VariableArrayType *VAT = cast<VariableArrayType>(ATy);
-  return cast<ArrayType>(getVariableArrayType(NewEltTy, VAT->getSizeExpr(),
+  return cast<ArrayType>(getVariableArrayType(NewEltTy,
+                                              VAT->getSizeExpr(),
                                               VAT->getSizeModifier(),
-                                              VAT->getIndexTypeQualifier()));
+                                              VAT->getIndexTypeQualifier(),
+                                              VAT->getBracketsRange()));
 }
 
 
@@ -3528,7 +3593,8 @@
     }
     if (getCanonicalType(LHSElem) == getCanonicalType(ResultType)) return LHS;
     if (getCanonicalType(RHSElem) == getCanonicalType(ResultType)) return RHS;
-    return getIncompleteArrayType(ResultType, ArrayType::ArraySizeModifier(),0);
+    return getIncompleteArrayType(ResultType,
+                                  ArrayType::ArraySizeModifier(), 0);
   }
   case Type::FunctionNoProto:
     return mergeFunctionTypes(LHS, RHS);

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Mon Jul  6 10:59:29 2009
@@ -37,6 +37,18 @@
   C.Deallocate(this);
 }
 
+void ConstantArrayWithExprType::Destroy(ASTContext& C) {
+  // FIXME: destruction of SizeExpr commented out due to resource contention.
+  // SizeExpr->Destroy(C);
+  // See FIXME in SemaDecl.cpp:1536: if we were able to either steal
+  // or clone the SizeExpr there, then here we could freely delete it.
+  // Since we do not know how to steal or clone, we keep a pointer to
+  // a shared resource, but we cannot free it.
+  // (There probably is a trivial solution ... for people knowing clang!).
+  this->~ConstantArrayWithExprType();
+  C.Deallocate(this);
+}
+
 void VariableArrayType::Destroy(ASTContext& C) {
   if (SizeExpr)
     SizeExpr->Destroy(C);
@@ -163,6 +175,8 @@
   case Pointer:
   case VariableArray:
   case ConstantArray:
+  case ConstantArrayWithExpr:
+  case ConstantArrayWithoutExpr:
   case IncompleteArray:
   case FunctionProto:
   case FunctionNoProto:
@@ -1339,6 +1353,29 @@
   getElementType().getAsStringInternal(S, Policy);
 }
 
+void ConstantArrayWithExprType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
+  if (Policy.ConstantArraySizeAsWritten) {
+    std::string SStr;
+    llvm::raw_string_ostream s(SStr);
+    getSizeExpr()->printPretty(s, 0, Policy);
+    S += '[';
+    S += s.str();
+    S += ']';
+    getElementType().getAsStringInternal(S, Policy);
+  }
+  else
+    ConstantArrayType::getAsStringInternal(S, Policy);
+}
+
+void ConstantArrayWithoutExprType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
+  if (Policy.ConstantArraySizeAsWritten) {
+    S += "[]";
+    getElementType().getAsStringInternal(S, Policy);
+  }
+  else
+    ConstantArrayType::getAsStringInternal(S, Policy);
+}
+
 void IncompleteArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
   S += "[]";
 

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Jul  6 10:59:29 2009
@@ -780,6 +780,8 @@
     return Slot = CreateType(cast<FunctionType>(Ty), Unit);
     
   case Type::ConstantArray:
+  case Type::ConstantArrayWithExpr:
+  case Type::ConstantArrayWithoutExpr:
   case Type::VariableArray:
   case Type::IncompleteArray:
     return Slot = CreateType(cast<ArrayType>(Ty), Unit);

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Mon Jul  6 10:59:29 2009
@@ -1753,7 +1753,32 @@
     unsigned IndexTypeQuals = Record[2];
     unsigned Idx = 3;
     llvm::APInt Size = ReadAPInt(Record, Idx);
-    return Context->getConstantArrayType(ElementType, Size, ASM,IndexTypeQuals);
+    return Context->getConstantArrayType(ElementType, Size,
+                                         ASM, IndexTypeQuals);
+  }
+
+  case pch::TYPE_CONSTANT_ARRAY_WITH_EXPR: {
+    QualType ElementType = GetType(Record[0]);
+    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
+    unsigned IndexTypeQuals = Record[2];
+    SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
+    SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
+    unsigned Idx = 5;
+    llvm::APInt Size = ReadAPInt(Record, Idx);
+    return Context->getConstantArrayWithExprType(ElementType,
+                                                 Size, ReadTypeExpr(),
+                                                 ASM, IndexTypeQuals,
+                                                 SourceRange(LBLoc, RBLoc));
+  }
+
+  case pch::TYPE_CONSTANT_ARRAY_WITHOUT_EXPR: {
+    QualType ElementType = GetType(Record[0]);
+    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
+    unsigned IndexTypeQuals = Record[2];
+    unsigned Idx = 3;
+    llvm::APInt Size = ReadAPInt(Record, Idx);
+    return Context->getConstantArrayWithoutExprType(ElementType, Size,
+                                                    ASM, IndexTypeQuals);
   }
 
   case pch::TYPE_INCOMPLETE_ARRAY: {
@@ -1767,8 +1792,11 @@
     QualType ElementType = GetType(Record[0]);
     ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
     unsigned IndexTypeQuals = Record[2];
+    SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
+    SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
     return Context->getVariableArrayType(ElementType, ReadTypeExpr(),
-                                         ASM, IndexTypeQuals);
+                                         ASM, IndexTypeQuals,
+                                         SourceRange(LBLoc, RBLoc));
   }
 
   case pch::TYPE_VECTOR: {

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Mon Jul  6 10:59:29 2009
@@ -124,6 +124,23 @@
   Code = pch::TYPE_CONSTANT_ARRAY;
 }
 
+void PCHTypeWriter
+::VisitConstantArrayWithExprType(const ConstantArrayWithExprType *T) {
+  VisitArrayType(T);
+  Writer.AddSourceLocation(T->getLBracketLoc(), Record);
+  Writer.AddSourceLocation(T->getRBracketLoc(), Record);
+  Writer.AddAPInt(T->getSize(), Record);
+  Writer.AddStmt(T->getSizeExpr());
+  Code = pch::TYPE_CONSTANT_ARRAY_WITH_EXPR;
+}
+
+void PCHTypeWriter
+::VisitConstantArrayWithoutExprType(const ConstantArrayWithoutExprType *T) {
+  VisitArrayType(T);
+  Writer.AddAPInt(T->getSize(), Record);
+  Code = pch::TYPE_CONSTANT_ARRAY_WITHOUT_EXPR;
+}
+
 void PCHTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
   VisitArrayType(T);
   Code = pch::TYPE_INCOMPLETE_ARRAY;
@@ -131,6 +148,8 @@
 
 void PCHTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
   VisitArrayType(T);
+  Writer.AddSourceLocation(T->getLBracketLoc(), Record);
+  Writer.AddSourceLocation(T->getRBracketLoc(), Record);
   Writer.AddStmt(T->getSizeExpr());
   Code = pch::TYPE_VARIABLE_ARRAY;
 }

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Jul  6 10:59:29 2009
@@ -2690,7 +2690,8 @@
     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
     // Remember that we parsed the empty array type.
     OwningExprResult NumElements(Actions);
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0, StartLoc),
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
+                                            StartLoc, EndLoc),
                   EndLoc);
     return;
   } else if (Tok.getKind() == tok::numeric_constant &&
@@ -2706,8 +2707,8 @@
       ExprRes.release();  // Deallocate expr, just use [].
     
     // Remember that we parsed a array type, and remember its features.
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
-                                            ExprRes.release(), StartLoc),
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0, ExprRes.release(),
+                                            StartLoc, EndLoc),
                   EndLoc);
     return;
   }
@@ -2770,7 +2771,8 @@
   // Remember that we parsed a array type, and remember its features.
   D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
                                           StaticLoc.isValid(), isStar,
-                                          NumElements.release(), StartLoc),
+                                          NumElements.release(),
+                                          StartLoc, EndLoc),
                 EndLoc);
 }
 

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Jul  6 10:59:29 2009
@@ -966,7 +966,7 @@
 
     SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
     D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
-                                            Size.release(), LLoc),
+                                            Size.release(), LLoc, RLoc),
                   RLoc);
 
     if (RLoc.isInvalid())

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Mon Jul  6 10:59:29 2009
@@ -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(), 

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Jul  6 10:59:29 2009
@@ -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,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jul  6 10:59:29 2009
@@ -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();

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Jul  6 10:59:29 2009
@@ -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;
   }
   

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Jul  6 10:59:29 2009
@@ -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 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=74831&r1=74830&r2=74831&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Mon Jul  6 10:59:29 2009
@@ -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: {





More information about the cfe-commits mailing list