[cfe-commits] r45840 - in /cfe/trunk: AST/Expr.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp

Steve Naroff snaroff at apple.com
Thu Jan 10 14:15:17 PST 2008


Author: snaroff
Date: Thu Jan 10 16:15:12 2008
New Revision: 45840

URL: http://llvm.org/viewvc/llvm-project?rev=45840&view=rev
Log:

- Teach Expr::isConstantExpr() about InitListExpr's (and offsetof, since I noticed it was missing).
- Rename CheckInitializer() to CheckInitializerTypes().
- Removed the isStatic argument to CheckInitializerTypes() and all of it's subroutines. Checking for constant expressions is now done separately.
- Added CheckForConstantInitializer().


Modified:
    cfe/trunk/AST/Expr.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/Sema/SemaExpr.cpp

Modified: cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Expr.cpp?rev=45840&r1=45839&r2=45840&view=diff

==============================================================================
--- cfe/trunk/AST/Expr.cpp (original)
+++ cfe/trunk/AST/Expr.cpp Thu Jan 10 16:15:12 2008
@@ -487,7 +487,8 @@
 
     // Get the operand value.  If this is sizeof/alignof, do not evalute the
     // operand.  This affects C99 6.6p3.
-    if (!Exp->isSizeOfAlignOfOp() &&
+    if (!Exp->isSizeOfAlignOfOp() && 
+        Exp->getOpcode() != UnaryOperator::OffsetOf &&
         !Exp->getSubExpr()->isConstantExpr(Ctx, Loc))
       return false;
   
@@ -501,6 +502,7 @@
       return true;  // FIXME: this is wrong.
     case UnaryOperator::SizeOf:
     case UnaryOperator::AlignOf:
+    case UnaryOperator::OffsetOf:
       // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
       if (!Exp->getSubExpr()->getType()->isConstantSizeType(Ctx)) {
         if (Loc) *Loc = Exp->getOperatorLoc();
@@ -560,9 +562,18 @@
       return false;
     return true;
   }
+  case InitListExprClass: {
+    const InitListExpr *Exp = cast<InitListExpr>(this);
+    unsigned numInits = Exp->getNumInits();
+    for (unsigned i = 0; i < numInits; i++) {
+      if (!Exp->getInit(i)->isConstantExpr(Ctx, Loc)) {
+        if (Loc) *Loc = Exp->getInit(i)->getLocStart();
+        return false;
+      }
+    }
+    return true;
+  }
   }
-
-  return true;
 }
 
 /// isIntegerConstantExpr - this recursive routine will test if an expression is

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

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Thu Jan 10 16:15:12 2008
@@ -722,21 +722,21 @@
                                    IdentifierInfo &Comp, SourceLocation CmpLoc);
   
   /// type checking declaration initializers (C99 6.7.8)
-  bool CheckInitializer(Expr *&simpleInit_or_initList, QualType &declType,
-                        bool isStatic);
-  bool CheckSingleInitializer(Expr *&simpleInit, bool isStatic, 
-                              QualType declType);
+  bool CheckInitializerTypes(Expr *&simpleInit_or_initList, QualType &declType);
+  bool CheckSingleInitializer(Expr *&simpleInit, QualType declType);
   bool CheckInitExpr(Expr *expr, InitListExpr *IList, unsigned slot,
-                     bool isStatic, QualType ElementType);
+                     QualType ElementType);
+                     
   void CheckVariableInitList(QualType DeclType, InitListExpr *IList, 
-                             QualType ElementType, bool isStatic, 
+                             QualType ElementType,
                              int &nInitializers, bool &hadError);
   void CheckConstantInitList(QualType DeclType, InitListExpr *IList, 
-                             QualType ElementType, bool isStatic, 
+                             QualType ElementType,
                              int &nInitializers, bool &hadError);
   bool CheckForCharArrayInitializer(InitListExpr *IList, QualType ElementType,
                                     int &nInitializers, bool isConstant,
                                     bool &hadError);
+  bool CheckForConstantInitializer(Expr *e, QualType t);
   
   // CheckVectorCast - check type constraints for vectors. 
   // Since vectors are an extension, there are no C standard reference for this.

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Thu Jan 10 16:15:12 2008
@@ -354,18 +354,7 @@
   return dyn_cast_or_null<TagDecl>(static_cast<Decl *>(DS.getTypeRep()));
 }
 
-bool Sema::CheckSingleInitializer(Expr *&Init, bool isStatic, 
-                                  QualType DeclType) {
-  // FIXME: Remove the isReferenceType check and handle assignment
-  // to a reference.
-  SourceLocation loc;
-  if (isStatic && !DeclType->isReferenceType() &&
-      !Init->isConstantExpr(Context, &loc)) { // C99 6.7.8p4.
-    assert(loc.isValid() && "isConstantExpr didn't return a loc!");
-    Diag(loc, diag::err_init_element_not_constant, Init->getSourceRange());
-    return true;
-  }
-  
+bool Sema::CheckSingleInitializer(Expr *&Init, QualType DeclType) {  
   // Get the type before calling CheckSingleAssignmentConstraints(), since
   // it can promote the expression.
   QualType InitType = Init->getType(); 
@@ -376,16 +365,9 @@
 }
 
 bool Sema::CheckInitExpr(Expr *expr, InitListExpr *IList, unsigned slot,
-                         bool isStatic, QualType ElementType) {
-  SourceLocation loc;
-  if (isStatic && !expr->isConstantExpr(Context, &loc)) { // C99 6.7.8p4.
-    assert(loc.isValid() && "isConstantExpr didn't return a loc!");
-    Diag(loc, diag::err_init_element_not_constant, expr->getSourceRange());
-    return true;
-  }
-    
+                         QualType ElementType) {
   Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
-  if (CheckSingleInitializer(expr, isStatic, ElementType))
+  if (CheckSingleInitializer(expr, ElementType))
     return true; // types weren't compatible.
   
   if (savExpr != expr) // The type was promoted, update initializer list.
@@ -394,7 +376,7 @@
 }
 
 void Sema::CheckVariableInitList(QualType DeclType, InitListExpr *IList, 
-                                 QualType ElementType, bool isStatic, 
+                                 QualType ElementType,
                                  int &nInitializers, bool &hadError) {
   unsigned numInits = IList->getNumInits();
 
@@ -409,11 +391,11 @@
       if (InitListExpr *InitList = dyn_cast<InitListExpr>(expr)) {
         if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {
           int maxElements = CAT->getMaximumElements();
-          CheckConstantInitList(DeclType, InitList, ElementType, isStatic, 
+          CheckConstantInitList(DeclType, InitList, ElementType,
                                 maxElements, hadError);
         }
       } else {
-        hadError = CheckInitExpr(expr, IList, i, isStatic, ElementType);
+        hadError = CheckInitExpr(expr, IList, i, ElementType);
       }
       nInitializers++;
     }
@@ -469,7 +451,7 @@
 
 // FIXME: Doesn't deal with arrays of structures yet.
 void Sema::CheckConstantInitList(QualType DeclType, InitListExpr *IList, 
-                                 QualType ElementType, bool isStatic,
+                                 QualType ElementType,
                                  int &totalInits, bool &hadError) {
   int maxElementsAtThisLevel = 0;
   int nInitsAtLevel = 0;
@@ -503,10 +485,10 @@
       Expr *expr = IList->getInit(i);
       
       if (InitListExpr *InitList = dyn_cast<InitListExpr>(expr)) {
-        CheckConstantInitList(DeclType, InitList, ElementType, isStatic, 
+        CheckConstantInitList(DeclType, InitList, ElementType, 
                               totalInits, hadError);
       } else {
-        hadError = CheckInitExpr(expr, IList, i, isStatic, ElementType);
+        hadError = CheckInitExpr(expr, IList, i, ElementType);
         nInitsAtLevel++; // increment the number of initializers at this level.
         totalInits--;    // decrement the total number of initializers.
         
@@ -527,7 +509,7 @@
   }
 }
 
-bool Sema::CheckInitializer(Expr *&Init, QualType &DeclType, bool isStatic) {
+bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType) {
   bool hadError = false;
   
   InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
@@ -560,7 +542,7 @@
         return hadError;
       }
     }
-    return CheckSingleInitializer(Init, isStatic, DeclType);
+    return CheckSingleInitializer(Init, DeclType);
   }
   // We have an InitListExpr, make sure we set the type.
   Init->setType(DeclType);
@@ -576,7 +558,7 @@
     // array can have unknown size. For example, "int [][]" is illegal.
     int numInits = 0;
     CheckVariableInitList(VAT->getElementType(), InitList, VAT->getBaseType(), 
-                          isStatic, numInits, hadError);
+                          numInits, hadError);
     llvm::APSInt ConstVal(32);
     
     if (!hadError)
@@ -595,19 +577,18 @@
   if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {
     int maxElements = CAT->getMaximumElements();
     CheckConstantInitList(DeclType, InitList, CAT->getBaseType(), 
-                          isStatic, maxElements, hadError);
+                          maxElements, hadError);
     return hadError;
   }
   if (const VectorType *VT = DeclType->getAsVectorType()) {
     int maxElements = VT->getNumElements();
     CheckConstantInitList(DeclType, InitList, VT->getElementType(),
-                          isStatic, maxElements, hadError);
+                          maxElements, hadError);
     return hadError;
   }
   if (DeclType->isScalarType()) { // C99 6.7.8p11: Allow "int x = { 1, 2 };"
     int maxElements = 1;
-    CheckConstantInitList(DeclType, InitList, DeclType, isStatic, maxElements, 
-                          hadError);
+    CheckConstantInitList(DeclType, InitList, DeclType, maxElements, hadError);
     return hadError;
   }
   // FIXME: Handle struct/union types, including those appearing in a 
@@ -752,6 +733,17 @@
   return New;
 }
 
+bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
+  SourceLocation loc;
+  // FIXME: Remove the isReference check and handle assignment to a reference.
+  if (!DclT->isReferenceType() && !Init->isConstantExpr(Context, &loc)) { 
+    assert(loc.isValid() && "isConstantExpr didn't return a loc!");
+    Diag(loc, diag::err_init_element_not_constant, Init->getSourceRange());
+    return true;
+  }
+  return false;
+}
+
 void Sema::AddInitializerToDecl(DeclTy *dcl, ExprTy *init) {
   Decl *RealDecl = static_cast<Decl *>(dcl);
   Expr *Init = static_cast<Expr *>(init);
@@ -772,7 +764,7 @@
     return;
   }  
   // Get the decls type and save a reference for later, since
-  // CheckInitializer may change it.
+  // CheckInitializerTypes may change it.
   QualType DclT = VDecl->getType(), SavT = DclT;
   if (BlockVarDecl *BVD = dyn_cast<BlockVarDecl>(VDecl)) {
     VarDecl::StorageClass SC = BVD->getStorageClass();
@@ -780,13 +772,18 @@
       Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
       BVD->setInvalidDecl();
     } else if (!BVD->isInvalidDecl()) {
-      CheckInitializer(Init, DclT, SC == VarDecl::Static);
+      CheckInitializerTypes(Init, DclT);
+      if (SC == VarDecl::Static) // C99 6.7.8p4.
+        CheckForConstantInitializer(Init, DclT);
     }
   } else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(VDecl)) {
     if (FVD->getStorageClass() == VarDecl::Extern)
       Diag(VDecl->getLocation(), diag::warn_extern_init);
     if (!FVD->isInvalidDecl())
-      CheckInitializer(Init, DclT, true);
+      CheckInitializerTypes(Init, DclT);
+    
+    // C99 6.7.8p4. All file scoped initializers need to be constant.
+    CheckForConstantInitializer(Init, DclT);
   }
   // If the type changed, it means we had an incomplete type that was
   // completed by the initializer. For example: 

Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=45840&r1=45839&r2=45840&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Thu Jan 10 16:15:12 2008
@@ -664,10 +664,13 @@
   Expr *literalExpr = static_cast<Expr*>(InitExpr);
 
   // FIXME: add more semantic analysis (C99 6.5.2.5).
-  bool requireConstantExprs = !CurFunctionDecl && !CurMethodDecl;
-  if (CheckInitializer(literalExpr, literalType, requireConstantExprs))
+  if (CheckInitializerTypes(literalExpr, literalType))
     return true;
-
+    
+  if (!CurFunctionDecl && !CurMethodDecl) { // 6.5.2.5p3
+    if (CheckForConstantInitializer(literalExpr, literalType))
+      return true;
+  }
   return new CompoundLiteralExpr(LParenLoc, literalType, literalExpr);
 }
 





More information about the cfe-commits mailing list