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

Richard Smith richard-llvm at metafoo.co.uk
Thu Nov 3 22:33:44 PDT 2011


Author: rsmith
Date: Fri Nov  4 00:33:44 2011
New Revision: 143680

URL: http://llvm.org/viewvc/llvm-project?rev=143680&view=rev
Log:
Constant expression evaluation: refactor to start the groundwork for coping with
initializations which refer indirectly to elements of the object being
initialized.

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=143680&r1=143679&r2=143680&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Nov  4 00:33:44 2011
@@ -302,6 +302,8 @@
 }
 
 static bool Evaluate(CCValue &Result, EvalInfo &Info, const Expr *E);
+static bool EvaluateConstantExpression(APValue &Result, EvalInfo &Info,
+                                       const Expr *E);
 static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info);
 static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info);
 static bool EvaluateInteger(const Expr *E, APSInt  &Result, EvalInfo &Info);
@@ -335,9 +337,14 @@
 }
 
 /// Check that this core constant expression value is a valid value for a
-/// constant expression.
-static bool CheckConstantExpression(const CCValue &Value) {
-  return !Value.isLValue() || IsGlobalLValue(Value.getLValueBase());
+/// constant expression, and if it is, produce the corresponding constant value.
+static bool CheckConstantExpression(const CCValue &CCValue, APValue &Value) {
+  if (CCValue.isLValue() && !IsGlobalLValue(CCValue.getLValueBase()))
+    return false;
+
+  // Slice off the extra bits.
+  Value = CCValue;
+  return true;
 }
 
 const ValueDecl *GetLValueBaseDecl(const LValue &LVal) {
@@ -512,12 +519,14 @@
   EvalInfo InitInfo(Info.Ctx, EStatus);
   // FIXME: The caller will need to know whether the value was a constant
   // expression. If not, we should propagate up a diagnostic.
-  if (!Evaluate(Result, InitInfo, Init) || !CheckConstantExpression(Result)) {
+  APValue EvalResult;
+  if (!EvaluateConstantExpression(EvalResult, InitInfo, Init)) {
     VD->setEvaluatedValue(APValue());
     return false;
   }
 
-  VD->setEvaluatedValue(Result);
+  VD->setEvaluatedValue(EvalResult);
+  Result = CCValue(EvalResult, CCValue::GlobalValue());
   return true;
 }
 
@@ -900,13 +909,14 @@
 
     const FunctionDecl *Definition;
     Stmt *Body = FD->getBody(Definition);
-    CCValue Result;
+    CCValue CCResult;
+    APValue Result;
     llvm::ArrayRef<const Expr*> Args(E->getArgs(), E->getNumArgs());
 
     if (Body && Definition->isConstexpr() && !Definition->isInvalidDecl() &&
-        HandleFunctionCall(Args, Body, Info, Result) &&
-        CheckConstantExpression(Result))
-      return DerivedSuccess(Result, E);
+        HandleFunctionCall(Args, Body, Info, CCResult) &&
+        CheckConstantExpression(CCResult, Result))
+      return DerivedSuccess(CCValue(Result, CCValue::GlobalValue()), E);
 
     return DerivedError(E);
   }
@@ -1372,7 +1382,8 @@
       Result = APValue(V.data(), V.size());
       return true;
     }
-    bool Success(const APValue &V, const Expr *E) {
+    bool Success(const CCValue &V, const Expr *E) {
+      assert(V.isVector());
       Result = V;
       return true;
     }
@@ -3197,12 +3208,44 @@
     if (!EvaluateComplex(E, C, Info))
       return false;
     C.moveInto(Result);
+  } else if (E->getType()->isMemberPointerType()) {
+    // FIXME: Implement evaluation of pointer-to-member types.
+    return false;
+  } else if (E->getType()->isArrayType() && E->getType()->isLiteralType()) {
+    // FIXME: Implement evaluation of array rvalues.
+    return false;
+  } else if (E->getType()->isRecordType() && E->getType()->isLiteralType()) {
+    // FIXME: Implement evaluation of record rvalues.
+    return false;
   } else
     return false;
 
   return true;
 }
 
+/// EvaluateConstantExpression - Evaluate an expression as a constant expression
+/// in-place in an APValue. In some cases, the in-place evaluation is essential,
+/// since later initializers for an object can indirectly refer to subobjects
+/// which were initialized earlier.
+static bool EvaluateConstantExpression(APValue &Result, EvalInfo &Info,
+                                       const Expr *E) {
+  if (E->isRValue() && E->getType()->isLiteralType()) {
+    // Evaluate arrays and record types in-place, so that later initializers can
+    // refer to earlier-initialized members of the object.
+    if (E->getType()->isArrayType())
+      // FIXME: Implement evaluation of array rvalues.
+      return false;
+    else if (E->getType()->isRecordType())
+      // FIXME: Implement evaluation of record rvalues.
+      return false;
+  }
+
+  // For any other type, in-place evaluation is unimportant.
+  CCValue CoreConstResult;
+  return Evaluate(CoreConstResult, Info, E) &&
+         CheckConstantExpression(CoreConstResult, Result);
+}
+
 
 /// EvaluateAsRValue - Return true if this is a constant which we can fold using
 /// any crazy technique (that has nothing to do with language standards) that
@@ -3224,11 +3267,8 @@
   }
 
   // Check this core constant expression is a constant expression, and if so,
-  // slice it down to one.
-  if (!CheckConstantExpression(Value))
-    return false;
-  Result.Val = Value;
-  return true;
+  // convert it to one.
+  return CheckConstantExpression(Value, Result.Val);
 }
 
 bool Expr::EvaluateAsBooleanCondition(bool &Result,





More information about the cfe-commits mailing list