]> granicus.if.org Git - clang/commitdiff
Simplified initializer semantic analysis by adding the following 2 methods:
authorSteve Naroff <snaroff@apple.com>
Tue, 4 Sep 2007 21:13:33 +0000 (21:13 +0000)
committerSteve Naroff <snaroff@apple.com>
Tue, 4 Sep 2007 21:13:33 +0000 (21:13 +0000)
- ArrayType::getBaseType(), and
- ConstantArrayType::getMaximumElements().

Wanted to do this cleanup before adding structure support, which will add more complexity.

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

Sema/SemaDecl.cpp
clang.xcodeproj/project.pbxproj
include/clang/AST/Type.h

index b178e099ba21b8a4d0b7789a73e547cf480c4789..f2a8f4d8ecc53867bc8bdae5f864532a25bf94cc 100644 (file)
@@ -313,15 +313,7 @@ void Sema::CheckVariableInitList(QualType DeclType, InitListExpr *IList,
     
     if (InitListExpr *InitList = dyn_cast<InitListExpr>(expr)) {
       if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {
-        QualType ElmtType = CAT->getElementType();
-        int maxElements = CAT->getSize().getZExtValue();
-        
-        // If we have a multi-dimensional array, navigate to the base type. Also
-        // compute the absolute array, so we can detect excess elements.
-        while ((CAT = ElmtType->getAsConstantArrayType())) {
-          ElmtType = CAT->getElementType();
-          maxElements *= CAT->getSize().getZExtValue();
-        }
+        int maxElements = CAT->getMaximumElements();
         CheckConstantInitList(DeclType, InitList, ElementType, isStatic, 
                               maxElements, hadError);
       }
@@ -342,19 +334,9 @@ void Sema::CheckConstantInitList(QualType DeclType, InitListExpr *IList,
 
   if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {
     // We have a constant array type, compute maxElements *at this level*.
-    QualType ElmtType = CAT->getElementType();
-    maxElementsAtThisLevel = CAT->getSize().getZExtValue();
-    
-    // Set DeclType, important for correctly handling multi-dimensional arrays.
-    DeclType = ElmtType;
-    
-    // If we have a multi-dimensional array, navigate to the base type. Also
-    // compute the absolute size of the array *at this level* array, so we can 
-    // detect excess elements.
-    while ((CAT = ElmtType->getAsConstantArrayType())) {
-      ElmtType = CAT->getElementType();
-      maxElementsAtThisLevel *= CAT->getSize().getZExtValue();
-    }
+    maxElementsAtThisLevel = CAT->getMaximumElements();
+    // Set DeclType, used below to recurse (for multi-dimensional arrays).
+    DeclType = CAT->getElementType();
   } else if (DeclType->isScalarType()) {
     Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init, 
          IList->getSourceRange());
@@ -410,22 +392,11 @@ bool Sema::CheckInitializer(Expr *&Init, QualType &DeclType, bool isStatic) {
       return Diag(expr->getLocStart(), diag::err_variable_object_no_init, 
                   expr->getSourceRange());
 
-    // We have a VariableArrayType with unknown size.
-    QualType ElmtType = VAT->getElementType();
-    
-    // Set DeclType, important for correctly handling multi-dimensional arrays.
-    DeclType = ElmtType;
-    
-    // If we have a multi-dimensional array, navigate to the base type.
-    // Use getAsArrayType(), since it is illegal for an array to have an 
-    // incomplete element type. For example, "int [][]" is illegal.
-    const ArrayType *ATY;
-    while ((ATY = ElmtType->getAsArrayType())) {
-      ElmtType = ATY->getElementType();
-    }
+    // We have a VariableArrayType with unknown size. Note that only the first
+    // array can have unknown size. For example, "int [][]" is illegal.
     int numInits = 0;
-    CheckVariableInitList(DeclType, InitList, ElmtType, isStatic, numInits
-                          hadError);
+    CheckVariableInitList(VAT->getElementType(), InitList, VAT->getBaseType()
+                          isStatic, numInits, hadError);
     if (!hadError) {
       // Return a new array type from the number of initializers (C99 6.7.8p22).
       llvm::APSInt ConstVal(32);
@@ -436,17 +407,9 @@ bool Sema::CheckInitializer(Expr *&Init, QualType &DeclType, bool isStatic) {
     return hadError;
   }
   if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {
-    QualType ElmtType = CAT->getElementType();
-    int maxElements = CAT->getSize().getZExtValue();
-    
-    // If we have a multi-dimensional array, navigate to the base type. Also
-    // compute the absolute size of the array, so we can detect excess elements.
-    while ((CAT = ElmtType->getAsConstantArrayType())) {
-      ElmtType = CAT->getElementType();
-      maxElements *= CAT->getSize().getZExtValue();
-    }
-    CheckConstantInitList(DeclType, InitList, ElmtType, isStatic, maxElements, 
-                          hadError);
+    int maxElements = CAT->getMaximumElements();
+    CheckConstantInitList(DeclType, InitList, CAT->getBaseType(), 
+                          isStatic, maxElements, hadError);
     return hadError;
   }
   if (DeclType->isScalarType()) { // C99 6.7.8p11: Allow "int x = { 1, 2 };"
index ceddc1fe51371dbe08b56dff9d93b2afa896c564..c793c5f0cf2a3fbdfcb910dad9548aff7af548f9 100644 (file)
                3547129D0C88881300B3E1D5 /* PrettyPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrettyPrinter.h; path = clang/AST/PrettyPrinter.h; sourceTree = "<group>"; };
                84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };
                84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; };
-               8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
+               8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
                DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };
                DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = "<group>"; };
                DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };
index c61cc69d6fc89fff933450054c7240e4d0b8d2b9..170580688bed7318a9c58871af3a9fcc5779e3fb 100644 (file)
@@ -471,6 +471,14 @@ public:
   ArraySizeModifier getSizeModifier() const { return SizeModifier; }
   unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
   
+  QualType getBaseType() const {
+    const ArrayType *AT;
+    QualType ElmtType = getElementType();
+    // If we have a multi-dimensional array, navigate to the base type.
+    while ((AT = ElmtType->getAsArrayType()))
+      ElmtType = AT->getElementType();
+    return ElmtType;
+  }
   static bool classof(const Type *T) {
     return T->getTypeClass() == ConstantArray ||
            T->getTypeClass() == VariableArray;
@@ -487,7 +495,18 @@ class ConstantArrayType : public ArrayType, public llvm::FoldingSetNode {
   friend class ASTContext;  // ASTContext creates these.
 public:
   llvm::APInt getSize() const { return Size; }
-
+  int getMaximumElements() const {
+    QualType ElmtType = getElementType();
+    int maxElements = getSize().getZExtValue();
+
+    const ConstantArrayType *CAT;
+    // If we have a multi-dimensional array, include it's elements.
+    while ((CAT = ElmtType->getAsConstantArrayType())) {
+      ElmtType = CAT->getElementType();
+      maxElements *= CAT->getSize().getZExtValue();
+    }
+    return maxElements;
+  }
   virtual void getAsStringInternal(std::string &InnerString) const;
   
   void Profile(llvm::FoldingSetNodeID &ID) {