aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp51
1 files changed, 48 insertions, 3 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 2de72f392e..524afb11b6 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -484,6 +484,13 @@ public:
return Visit(E->getSubExpr());
}
}
+
+ bool VisitInitListExpr(const InitListExpr *E) {
+ if (Info.Ctx.getLangOptions().CPlusPlus0x && E->getNumInits() == 1)
+ return Visit(E->getInit(0));
+ return Error(E);
+ }
+
// FIXME: Missing: __real__, __imag__
};
@@ -1079,7 +1086,9 @@ public:
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E);
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
-
+
+ bool VisitInitListExpr(const InitListExpr *E);
+
private:
CharUnits GetAlignOfExpr(const Expr *E);
CharUnits GetAlignOfType(QualType T);
@@ -1932,6 +1941,17 @@ bool IntExprEvaluator::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
return Success(E->getValue(), E);
}
+bool IntExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
+ if (!Info.Ctx.getLangOptions().CPlusPlus0x)
+ return Error(E);
+
+ if (E->getNumInits() == 0)
+ return Success(0, E);
+
+ assert(E->getNumInits() == 1 && "Excess initializers for integer in C++11.");
+ return Visit(E->getInit(0));
+}
+
//===----------------------------------------------------------------------===//
// Float Evaluation
//===----------------------------------------------------------------------===//
@@ -1965,6 +1985,8 @@ public:
bool VisitDeclRefExpr(const DeclRefExpr *E);
+ bool VisitInitListExpr(const InitListExpr *E);
+
// FIXME: Missing: array subscript of vector, member of vector,
// ImplicitValueInitExpr
};
@@ -2233,6 +2255,19 @@ bool FloatExprEvaluator::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExp
return true;
}
+bool FloatExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
+ if (!Info.Ctx.getLangOptions().CPlusPlus0x)
+ return Error(E);
+
+ if (E->getNumInits() == 0) {
+ Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType()));
+ return true;
+ }
+
+ assert(E->getNumInits() == 1 && "Excess initializers for integer in C++11.");
+ return Visit(E->getInit(0));
+}
+
//===----------------------------------------------------------------------===//
// Complex Evaluation (for float and integer)
//===----------------------------------------------------------------------===//
@@ -2264,7 +2299,7 @@ public:
bool VisitBinaryOperator(const BinaryOperator *E);
bool VisitUnaryOperator(const UnaryOperator *E);
- // FIXME Missing: ImplicitValueInitExpr
+ // FIXME Missing: ImplicitValueInitExpr, InitListExpr
};
} // end anonymous namespace
@@ -2766,7 +2801,6 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
case Expr::CompoundAssignOperatorClass:
case Expr::CompoundLiteralExprClass:
case Expr::ExtVectorElementExprClass:
- case Expr::InitListExprClass:
case Expr::DesignatedInitExprClass:
case Expr::ImplicitValueInitExprClass:
case Expr::ParenListExprClass:
@@ -2813,6 +2847,17 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
case Expr::MaterializeTemporaryExprClass:
return ICEDiag(2, E->getLocStart());
+ case Expr::InitListExprClass:
+ if (Ctx.getLangOptions().CPlusPlus0x) {
+ const InitListExpr *ILE = cast<InitListExpr>(E);
+ if (ILE->getNumInits() == 0)
+ return NoDiag();
+ if (ILE->getNumInits() == 1)
+ return CheckICE(ILE->getInit(0), Ctx);
+ // Fall through for more than 1 expression.
+ }
+ return ICEDiag(2, E->getLocStart());
+
case Expr::SizeOfPackExprClass:
case Expr::GNUNullExprClass:
// GCC considers the GNU __null value to be an integral constant expression.