[cfe-commits] r39355 - in /cfe/cfe/trunk: AST/ASTContext.cpp AST/Type.cpp Parse/ParseExpr.cpp include/clang/AST/Type.h include/clang/Parse/DeclSpec.h

snaroff at cs.uiuc.edu snaroff at cs.uiuc.edu
Wed Jul 11 09:43:32 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:43:31 2007
New Revision: 39355

URL: http://llvm.org/viewvc/llvm-project?rev=39355&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Added size expression to ArrayType. This was needed to implement
Type::isIncompleteType(). At the moment, there is no support for
determining if we have a constant expression (which won't be too
difficult now that we have support for literal parsing/ast's).
Nevertheless, the parser will allow "struct foo { int a[b]; }"
(which is illegal). There is still significant work to fully analyze
array types. The good news is "carbon.h" goes from 288 bogus errors
down to 26!

Modified:
    cfe/cfe/trunk/AST/ASTContext.cpp
    cfe/cfe/trunk/AST/Type.cpp
    cfe/cfe/trunk/Parse/ParseExpr.cpp
    cfe/cfe/trunk/include/clang/AST/Type.h
    cfe/cfe/trunk/include/clang/Parse/DeclSpec.h

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

==============================================================================
--- cfe/cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/cfe/trunk/AST/ASTContext.cpp Wed Jul 11 11:43:31 2007
@@ -155,12 +155,10 @@
 /// specified element type.
 TypeRef ASTContext::getArrayType(TypeRef EltTy,ArrayType::ArraySizeModifier ASM,
                                  unsigned EltTypeQuals, Expr *NumElts) {
-#warning "IGNORING SIZE"
-  
   // Unique array types, to guarantee there is only one array of a particular
   // structure.
   FoldingSetNodeID ID;
-  ArrayType::Profile(ID, ASM, EltTypeQuals, EltTy);
+  ArrayType::Profile(ID, ASM, EltTypeQuals, EltTy, NumElts);
       
   void *InsertPos = 0;
   if (ArrayType *ATP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
@@ -178,7 +176,7 @@
     assert(NewIP == 0 && "Shouldn't be in the map!");
   }
   
-  ArrayType *New = new ArrayType(EltTy, ASM, EltTypeQuals, Canonical);
+  ArrayType *New = new ArrayType(EltTy, ASM, EltTypeQuals, Canonical, NumElts);
   ArrayTypes.InsertNode(New, InsertPos);
   Types.push_back(New);
   return New;

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

==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:43:31 2007
@@ -41,11 +41,16 @@
     // A tagged type (struct/union/enum/class) is incomplete if the decl is a
     // forward declaration, but not a full definition (C99 6.2.5p22).
     return !cast<TaggedType>(this)->getDecl()->isDefinition();
-    
   case Array:
     // An array of unknown size is an incomplete type (C99 6.2.5p22).
-    // FIXME: Implement this.
-    return true; // cast<ArrayType>(this)-> blah.
+    // In C99, an unknown size is permitted in 4 instances:
+    // - The array being declared is a formal parameter of a function.
+    // - The declarator is accompanied by an initializer from which the array 
+    //   can be deduced (char foo[] = "whatever").
+    // - Forward declarations (extern int matrix[][7]).
+    // - The last component of a structure (flexible array idiom).
+    // Clients of this routine will need to determine if the size is required.
+    return cast<ArrayType>(this)->getSizeExpression() == 0;
   }
 }
 

Modified: cfe/cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=39355&r1=39354&r2=39355&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:43:31 2007
@@ -473,7 +473,7 @@
     // constant: integer-constant
     // constant: floating-constant
     
-    Actions.ParseNumericConstant(Tok);
+    Res = Actions.ParseNumericConstant(Tok);
     ConsumeToken();
     
     // These can be followed by postfix-expr pieces.

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:43:31 2007
@@ -25,6 +25,7 @@
   class TagDecl;
   class RecordDecl;
   class EnumDecl;
+  class Expr;
   
 /// TypeRef - For efficiency, we don't store CVR-qualified types as nodes on
 /// their own: instead each reference to a type stores the qualifiers.  This
@@ -267,29 +268,34 @@
   /// ElementType - The element type of the array.
   TypeRef ElementType;
   
-  /// FIXME: Capture size for VLA or constant size.
-  /// FIXME: Update Profile()!
-  /// Use this to implement Type::isIncompleteType.
-
-  ArrayType(TypeRef et, ArraySizeModifier sm, unsigned tq, Type *can)
-    : Type(Array, can), SizeModifier(sm), IndexTypeQuals(tq), ElementType(et) {}
+  /// SizeExpr - The size is either a constant or assignment expression (for 
+  /// Variable Length Arrays). VLA's are only permitted within a function block. 
+  Expr *SizeExpr;
+  
+  ArrayType(TypeRef et, ArraySizeModifier sm, unsigned tq, Type *can, Expr *e)
+    : Type(Array, can), SizeModifier(sm), IndexTypeQuals(tq), ElementType(et),
+      SizeExpr(e) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
     
   TypeRef getElementType() const { return ElementType; }
   ArraySizeModifier getSizeModifier() const { return SizeModifier; }
   unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
+  Expr *getSizeExpression() const { return SizeExpr; }
   
   virtual void getAsString(std::string &InnerString) const;
   
   void Profile(FoldingSetNodeID &ID) {
-    Profile(ID, getSizeModifier(), getIndexTypeQualifier(), getElementType());
+    Profile(ID, getSizeModifier(), getIndexTypeQualifier(), getElementType(),
+            getSizeExpression());
   }
   static void Profile(FoldingSetNodeID &ID, ArraySizeModifier SizeModifier,
-                      unsigned IndexTypeQuals, TypeRef ElementType) {
+                      unsigned IndexTypeQuals, TypeRef ElementType,
+                      Expr *SizeExpr) {
     ID.AddInteger(SizeModifier);
     ID.AddInteger(IndexTypeQuals);
     ID.AddPointer(ElementType.getAsOpaquePtr());
+    ID.AddPointer(SizeExpr);
   }
   
   static bool classof(const Type *T) { return T->getTypeClass() == Array; }

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jul 11 11:43:31 2007
@@ -253,7 +253,8 @@
     bool isStar : 1;
     
     /// This is the size of the array, or null if [] or [*] was specified.
-    /// FIXME: make this be an expression* when we have expressions.
+    /// Since the parser is multi-purpose, and we don't want to impose a root
+    /// expression class on all clients, NumElts is untyped.
     void *NumElts;
     void destroy() {}
   };





More information about the cfe-commits mailing list