[cfe-commits] r142812 - /cfe/trunk/lib/AST/ExprConstant.cpp

Richard Smith richard-llvm at metafoo.co.uk
Mon Oct 24 10:54:19 PDT 2011


Author: rsmith
Date: Mon Oct 24 12:54:18 2011
New Revision: 142812

URL: http://llvm.org/viewvc/llvm-project?rev=142812&view=rev
Log:
Constant expression evaluation: factor out VarDecl initializer evaluation and
caching.

Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=142812&r1=142811&r2=142812&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Oct 24 12:54:18 2011
@@ -261,6 +261,39 @@
   return Result;
 }
 
+/// Try to evaluate the initializer for a variable declaration.
+static APValue *EvaluateVarDeclInit(EvalInfo &Info, const VarDecl *VD) {
+  if (isa<ParmVarDecl>(VD))
+    return 0;
+
+  const Expr *Init = VD->getAnyInitializer();
+  if (!Init)
+    return 0;
+
+  if (APValue *V = VD->getEvaluatedValue())
+    return V;
+
+  if (VD->isEvaluatingValue())
+    return 0;
+
+  VD->setEvaluatingValue();
+
+  // FIXME: If the initializer isn't a constant expression, propagate up any
+  // diagnostic explaining why not.
+  Expr::EvalResult EResult;
+  if (Init->Evaluate(EResult, Info.Ctx) && !EResult.HasSideEffects)
+    VD->setEvaluatedValue(EResult.Val);
+  else
+    VD->setEvaluatedValue(APValue());
+
+  return VD->getEvaluatedValue();
+}
+
+bool IsConstNonVolatile(QualType T) {
+  Qualifiers Quals = T.getQualifiers();
+  return Quals.hasConst() && !Quals.hasVolatile();
+}
+
 namespace {
 class HasSideEffect
   : public ConstStmtVisitor<HasSideEffect, bool> {
@@ -1163,38 +1196,11 @@
 
   // In C++, const, non-volatile integers initialized with ICEs are ICEs.
   // In C, they can also be folded, although they are not ICEs.
-  if (Info.Ctx.getCanonicalType(E->getType()).getCVRQualifiers() 
-                                                        == Qualifiers::Const) {
-
-    if (isa<ParmVarDecl>(D))
-      return false;
-
+  if (IsConstNonVolatile(E->getType())) {
     if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
-      if (const Expr *Init = VD->getAnyInitializer()) {
-        if (APValue *V = VD->getEvaluatedValue()) {
-          if (V->isInt())
-            return Success(V->getInt(), E);
-          return false;
-        }
-
-        if (VD->isEvaluatingValue())
-          return false;
-
-        VD->setEvaluatingValue();
-
-        Expr::EvalResult EResult;
-        // FIXME: Produce a diagnostic if the initializer isn't a constant
-        // expression.
-        if (Init->Evaluate(EResult, Info.Ctx) && !EResult.HasSideEffects &&
-            EResult.Val.isInt()) {
-          // Cache the evaluated value in the variable declaration.
-          Result = EResult.Val;
-          VD->setEvaluatedValue(Result);
-          return true;
-        }
-
-        VD->setEvaluatedValue(APValue());
-      }
+      APValue *V = EvaluateVarDeclInit(Info, VD);
+      if (V && V->isInt())
+        return Success(V->getInt(), E);
     }
   }
 
@@ -2145,41 +2151,14 @@
   if (ExprEvaluatorBaseTy::VisitDeclRefExpr(E))
     return true;
 
-  const Decl *D = E->getDecl();
-  if (!isa<VarDecl>(D) || isa<ParmVarDecl>(D)) return false;
-  const VarDecl *VD = cast<VarDecl>(D);
-
-  // Require the qualifiers to be const and not volatile.
-  CanQualType T = Info.Ctx.getCanonicalType(E->getType());
-  if (!T.isConstQualified() || T.isVolatileQualified())
-    return false;
-
-  const Expr *Init = VD->getAnyInitializer();
-  if (!Init) return false;
-
-  if (APValue *V = VD->getEvaluatedValue()) {
-    if (V->isFloat()) {
+  const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
+  if (VD && IsConstNonVolatile(VD->getType())) {
+    APValue *V = EvaluateVarDeclInit(Info, VD);
+    if (V && V->isFloat()) {
       Result = V->getFloat();
       return true;
     }
-    return false;
   }
-
-  if (VD->isEvaluatingValue())
-    return false;
-
-  VD->setEvaluatingValue();
-
-  Expr::EvalResult InitResult;
-  if (Init->Evaluate(InitResult, Info.Ctx) && !InitResult.HasSideEffects &&
-      InitResult.Val.isFloat()) {
-    // Cache the evaluated value in the variable declaration.
-    Result = InitResult.Val.getFloat();
-    VD->setEvaluatedValue(InitResult.Val);
-    return true;
-  }
-
-  VD->setEvaluatedValue(APValue());
   return false;
 }
 
@@ -2947,8 +2926,7 @@
   case Expr::DeclRefExprClass:
     if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
       return NoDiag();
-    if (Ctx.getLangOptions().CPlusPlus &&
-        E->getType().getCVRQualifiers() == Qualifiers::Const) {
+    if (Ctx.getLangOptions().CPlusPlus && IsConstNonVolatile(E->getType())) {
       const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl();
 
       // Parameter variables are never constants.  Without this check,
@@ -2961,10 +2939,6 @@
       //   A variable of non-volatile const-qualified integral or enumeration
       //   type initialized by an ICE can be used in ICEs.
       if (const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
-        Qualifiers Quals = Ctx.getCanonicalType(Dcl->getType()).getQualifiers();
-        if (Quals.hasVolatile() || !Quals.hasConst())
-          return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
-        
         // Look for a declaration of this variable that has an initializer.
         const VarDecl *ID = 0;
         const Expr *Init = Dcl->getAnyInitializer(ID);





More information about the cfe-commits mailing list