diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-14 21:51:42 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-14 21:51:42 +0000 |
commit | 4178b573b82449c2d888ea1f0957a478534e118c (patch) | |
tree | 938341c419040e09e3bdc1b1b8450d7cb91d9764 /lib/AST/ExprClassification.cpp | |
parent | c384636f9a405b687990564b204b98e360c81587 (diff) |
Eliminate the default case in the expression-classification code, so
that we're sure to keep it updated when new expression kinds
emerge. Also fixes a few little bugs in the classification of
expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113864 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprClassification.cpp')
-rw-r--r-- | lib/AST/ExprClassification.cpp | 72 |
1 files changed, 65 insertions, 7 deletions
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp index 8ec81943b3..6ca18a21dd 100644 --- a/lib/AST/ExprClassification.cpp +++ b/lib/AST/ExprClassification.cpp @@ -60,7 +60,12 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { switch (E->getStmtClass()) { // First come the expressions that are always lvalues, unconditionally. - + case Stmt::NoStmtClass: +#define STMT(Kind, Base) case Expr::Kind##Class: +#define EXPR(Kind, Base) +#include "clang/AST/StmtNodes.inc" + llvm_unreachable("cannot classify a statement"); + break; case Expr::ObjCIsaExprClass: // C++ [expr.prim.general]p1: A string literal is an lvalue. case Expr::StringLiteralClass: @@ -77,13 +82,49 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // FIXME: Is this wise? Should they get their own kind? case Expr::UnresolvedLookupExprClass: case Expr::UnresolvedMemberExprClass: + case Expr::CXXDependentScopeMemberExprClass: + case Expr::CXXUnresolvedConstructExprClass: + case Expr::DependentScopeDeclRefExprClass: // ObjC instance variables are lvalues // 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. - // FIXME: C++ might have a different opinion. + // In C++, they're class temporaries. case Expr::CompoundLiteralExprClass: - return Cl::CL_LValue; + return Ctx.getLangOptions().CPlusPlus? Cl::CL_ClassTemporary + : Cl::CL_LValue; + + // Expressions that are prvalues. + case Expr::CXXBoolLiteralExprClass: + case Expr::CXXPseudoDestructorExprClass: + case Expr::SizeOfAlignOfExprClass: + case Expr::CXXNewExprClass: + case Expr::CXXThisExprClass: + case Expr::CXXNullPtrLiteralExprClass: + case Expr::TypesCompatibleExprClass: + case Expr::ImaginaryLiteralClass: + case Expr::GNUNullExprClass: + case Expr::OffsetOfExprClass: + case Expr::CXXThrowExprClass: + case Expr::ShuffleVectorExprClass: + case Expr::IntegerLiteralClass: + case Expr::ObjCSuperExprClass: + case Expr::CharacterLiteralClass: + case Expr::AddrLabelExprClass: + case Expr::CXXDeleteExprClass: + case Expr::ImplicitValueInitExprClass: + case Expr::BlockExprClass: + case Expr::FloatingLiteralClass: + case Expr::CXXNoexceptExprClass: + case Expr::CXXScalarValueInitExprClass: + case Expr::UnaryTypeTraitExprClass: + case Expr::ObjCSelectorExprClass: + case Expr::ObjCProtocolExprClass: + case Expr::ObjCStringLiteralClass: + case Expr::ParenListExprClass: + case Expr::InitListExprClass: + return Cl::CL_PRValue; // Next come the complicated cases. @@ -207,17 +248,34 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { cast<ObjCMessageExpr>(E)->getMethodDecl()) { return ClassifyUnnamed(Ctx, Method->getResultType()); } - + return Cl::CL_PRValue; + // Some C++ expressions are always class temporaries. case Expr::CXXConstructExprClass: case Expr::CXXTemporaryObjectExprClass: - case Expr::CXXScalarValueInitExprClass: return Cl::CL_ClassTemporary; - // Everything we haven't handled is a prvalue. - default: + 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 ClassifyInternal(Ctx, LastExpr); return Cl::CL_PRValue; } + + case Expr::CXXUuidofExprClass: + // Assume that Microsoft's __uuidof returns an lvalue, like typeid does. + // FIXME: Is this really the case? + return Cl::CL_LValue; + } + + llvm_unreachable("unhandled expression kind in classification"); + return Cl::CL_LValue; } /// ClassifyDecl - Return the classification of an expression referencing the |