diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2011-11-27 16:50:07 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2011-11-27 16:50:07 +0000 |
commit | 13dc8f98f6108dca8aaa9721567ed5a2d9911e0f (patch) | |
tree | c574193fb93fa87e8b2d568d1bf5cda53baa4b8a /lib/AST/ExprClassification.cpp | |
parent | 1376ba9dddccc02e8c187bbfa4c66f2c0938b0c0 (diff) |
Reference initialization with initializer lists.
This supports single-element initializer lists for references according to DR1288, as well as creating temporaries and binding to them for other initializer lists.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145186 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprClassification.cpp')
-rw-r--r-- | lib/AST/ExprClassification.cpp | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp index 1251b96fba..f5ee3e5dee 100644 --- a/lib/AST/ExprClassification.cpp +++ b/lib/AST/ExprClassification.cpp @@ -93,7 +93,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { const LangOptions &Lang = Ctx.getLangOptions(); switch (E->getStmtClass()) { - // First come the expressions that are always lvalues, unconditionally. case Stmt::NoStmtClass: #define ABSTRACT_STMT(Kind) #define STMT(Kind, Base) case Expr::Kind##Class: @@ -101,6 +100,8 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { #include "clang/AST/StmtNodes.inc" llvm_unreachable("cannot classify a statement"); break; + + // First come the expressions that are always lvalues, unconditionally. case Expr::ObjCIsaExprClass: // C++ [expr.prim.general]p1: A string literal is an lvalue. case Expr::StringLiteralClass: @@ -122,6 +123,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // FIXME: ObjC++0x might have different rules case Expr::ObjCIvarRefExprClass: return Cl::CL_LValue; + // C99 6.5.2.5p5 says that compound literals are lvalues. // In C++, they're class temporaries. case Expr::CompoundLiteralExprClass: @@ -157,7 +159,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::ObjCProtocolExprClass: case Expr::ObjCStringLiteralClass: case Expr::ParenListExprClass: - case Expr::InitListExprClass: case Expr::SizeOfPackExprClass: case Expr::SubstNonTypeTemplateParmPackExprClass: case Expr::AsTypeExprClass: @@ -229,8 +230,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { } case Expr::OpaqueValueExprClass: - return ClassifyExprValueKind(Lang, E, - cast<OpaqueValueExpr>(E)->getValueKind()); + return ClassifyExprValueKind(Lang, E, E->getValueKind()); // Pseudo-object expressions can produce l-values with reference magic. case Expr::PseudoObjectExprClass: @@ -240,8 +240,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // Implicit casts are lvalues if they're lvalue casts. Other than that, we // only specifically record class temporaries. case Expr::ImplicitCastExprClass: - return ClassifyExprValueKind(Lang, E, - cast<ImplicitCastExpr>(E)->getValueKind()); + return ClassifyExprValueKind(Lang, E, E->getValueKind()); // C++ [expr.prim.general]p4: The presence of parentheses does not affect // whether the expression is an lvalue. @@ -337,29 +336,40 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::VAArgExprClass: return ClassifyUnnamed(Ctx, E->getType()); - + case Expr::DesignatedInitExprClass: return ClassifyInternal(Ctx, cast<DesignatedInitExpr>(E)->getInit()); - + case Expr::StmtExprClass: { const CompoundStmt *S = cast<StmtExpr>(E)->getSubStmt(); if (const Expr *LastExpr = dyn_cast_or_null<Expr>(S->body_back())) return ClassifyUnnamed(Ctx, LastExpr->getType()); return Cl::CL_PRValue; } - + case Expr::CXXUuidofExprClass: return Cl::CL_LValue; - + case Expr::PackExpansionExprClass: return ClassifyInternal(Ctx, cast<PackExpansionExpr>(E)->getPattern()); - + case Expr::MaterializeTemporaryExprClass: return cast<MaterializeTemporaryExpr>(E)->isBoundToLvalueReference() ? Cl::CL_LValue : Cl::CL_XValue; + + case Expr::InitListExprClass: + // An init list can be an lvalue if it is bound to a reference and + // contains only one element. In that case, we look at that element + // for an exact classification. Init list creation takes care of the + // value kind for us, so we only need to fine-tune. + if (E->isRValue()) + return ClassifyExprValueKind(Lang, E, E->getValueKind()); + assert(cast<InitListExpr>(E)->getNumInits() == 1 && + "Only 1-element init lists can be glvalues."); + return ClassifyInternal(Ctx, cast<InitListExpr>(E)->getInit(0)); } - + llvm_unreachable("unhandled expression kind in classification"); return Cl::CL_LValue; } |