10b57cec5SDimitry Andric //===- ExprClassification.cpp - Expression AST Node Implementation --------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements Expr::classify.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/AST/Expr.h"
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
150b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
160b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
180b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
190b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h"
200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric using namespace clang;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric using Cl = Expr::Classification;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E);
270b57cec5SDimitry Andric static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D);
280b57cec5SDimitry Andric static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T);
290b57cec5SDimitry Andric static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E);
300b57cec5SDimitry Andric static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E);
310b57cec5SDimitry Andric static Cl::Kinds ClassifyConditional(ASTContext &Ctx,
320b57cec5SDimitry Andric                                      const Expr *trueExpr,
330b57cec5SDimitry Andric                                      const Expr *falseExpr);
340b57cec5SDimitry Andric static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
350b57cec5SDimitry Andric                                        Cl::Kinds Kind, SourceLocation &Loc);
360b57cec5SDimitry Andric 
ClassifyImpl(ASTContext & Ctx,SourceLocation * Loc) const370b57cec5SDimitry Andric Cl Expr::ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const {
380b57cec5SDimitry Andric   assert(!TR->isReferenceType() && "Expressions can't have reference type.");
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   Cl::Kinds kind = ClassifyInternal(Ctx, this);
410b57cec5SDimitry Andric   // C99 6.3.2.1: An lvalue is an expression with an object type or an
420b57cec5SDimitry Andric   //   incomplete type other than void.
430b57cec5SDimitry Andric   if (!Ctx.getLangOpts().CPlusPlus) {
440b57cec5SDimitry Andric     // Thus, no functions.
450b57cec5SDimitry Andric     if (TR->isFunctionType() || TR == Ctx.OverloadTy)
460b57cec5SDimitry Andric       kind = Cl::CL_Function;
470b57cec5SDimitry Andric     // No void either, but qualified void is OK because it is "other than void".
480b57cec5SDimitry Andric     // Void "lvalues" are classified as addressable void values, which are void
490b57cec5SDimitry Andric     // expressions whose address can be taken.
500b57cec5SDimitry Andric     else if (TR->isVoidType() && !TR.hasQualifiers())
510b57cec5SDimitry Andric       kind = (kind == Cl::CL_LValue ? Cl::CL_AddressableVoid : Cl::CL_Void);
520b57cec5SDimitry Andric   }
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   // Enable this assertion for testing.
550b57cec5SDimitry Andric   switch (kind) {
56fe6060f1SDimitry Andric   case Cl::CL_LValue:
57fe6060f1SDimitry Andric     assert(isLValue());
58fe6060f1SDimitry Andric     break;
59fe6060f1SDimitry Andric   case Cl::CL_XValue:
60fe6060f1SDimitry Andric     assert(isXValue());
61fe6060f1SDimitry Andric     break;
620b57cec5SDimitry Andric   case Cl::CL_Function:
630b57cec5SDimitry Andric   case Cl::CL_Void:
640b57cec5SDimitry Andric   case Cl::CL_AddressableVoid:
650b57cec5SDimitry Andric   case Cl::CL_DuplicateVectorComponents:
660b57cec5SDimitry Andric   case Cl::CL_MemberFunction:
670b57cec5SDimitry Andric   case Cl::CL_SubObjCPropertySetting:
680b57cec5SDimitry Andric   case Cl::CL_ClassTemporary:
690b57cec5SDimitry Andric   case Cl::CL_ArrayTemporary:
700b57cec5SDimitry Andric   case Cl::CL_ObjCMessageRValue:
71fe6060f1SDimitry Andric   case Cl::CL_PRValue:
72fe6060f1SDimitry Andric     assert(isPRValue());
73fe6060f1SDimitry Andric     break;
740b57cec5SDimitry Andric   }
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   Cl::ModifiableType modifiable = Cl::CM_Untested;
770b57cec5SDimitry Andric   if (Loc)
780b57cec5SDimitry Andric     modifiable = IsModifiable(Ctx, this, kind, *Loc);
790b57cec5SDimitry Andric   return Classification(kind, modifiable);
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric /// Classify an expression which creates a temporary, based on its type.
ClassifyTemporary(QualType T)830b57cec5SDimitry Andric static Cl::Kinds ClassifyTemporary(QualType T) {
840b57cec5SDimitry Andric   if (T->isRecordType())
850b57cec5SDimitry Andric     return Cl::CL_ClassTemporary;
860b57cec5SDimitry Andric   if (T->isArrayType())
870b57cec5SDimitry Andric     return Cl::CL_ArrayTemporary;
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   // No special classification: these don't behave differently from normal
900b57cec5SDimitry Andric   // prvalues.
910b57cec5SDimitry Andric   return Cl::CL_PRValue;
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric 
ClassifyExprValueKind(const LangOptions & Lang,const Expr * E,ExprValueKind Kind)940b57cec5SDimitry Andric static Cl::Kinds ClassifyExprValueKind(const LangOptions &Lang,
950b57cec5SDimitry Andric                                        const Expr *E,
960b57cec5SDimitry Andric                                        ExprValueKind Kind) {
970b57cec5SDimitry Andric   switch (Kind) {
98fe6060f1SDimitry Andric   case VK_PRValue:
990b57cec5SDimitry Andric     return Lang.CPlusPlus ? ClassifyTemporary(E->getType()) : Cl::CL_PRValue;
1000b57cec5SDimitry Andric   case VK_LValue:
1010b57cec5SDimitry Andric     return Cl::CL_LValue;
1020b57cec5SDimitry Andric   case VK_XValue:
1030b57cec5SDimitry Andric     return Cl::CL_XValue;
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric   llvm_unreachable("Invalid value category of implicit cast.");
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
ClassifyInternal(ASTContext & Ctx,const Expr * E)1080b57cec5SDimitry Andric static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
1090b57cec5SDimitry Andric   // This function takes the first stab at classifying expressions.
1100b57cec5SDimitry Andric   const LangOptions &Lang = Ctx.getLangOpts();
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   switch (E->getStmtClass()) {
1130b57cec5SDimitry Andric   case Stmt::NoStmtClass:
1140b57cec5SDimitry Andric #define ABSTRACT_STMT(Kind)
1150b57cec5SDimitry Andric #define STMT(Kind, Base) case Expr::Kind##Class:
1160b57cec5SDimitry Andric #define EXPR(Kind, Base)
1170b57cec5SDimitry Andric #include "clang/AST/StmtNodes.inc"
1180b57cec5SDimitry Andric     llvm_unreachable("cannot classify a statement");
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric     // First come the expressions that are always lvalues, unconditionally.
1210b57cec5SDimitry Andric   case Expr::ObjCIsaExprClass:
1220b57cec5SDimitry Andric     // C++ [expr.prim.general]p1: A string literal is an lvalue.
1230b57cec5SDimitry Andric   case Expr::StringLiteralClass:
1240b57cec5SDimitry Andric     // @encode is equivalent to its string
1250b57cec5SDimitry Andric   case Expr::ObjCEncodeExprClass:
1260b57cec5SDimitry Andric     // __func__ and friends are too.
1270b57cec5SDimitry Andric   case Expr::PredefinedExprClass:
1280b57cec5SDimitry Andric     // Property references are lvalues
1290b57cec5SDimitry Andric   case Expr::ObjCSubscriptRefExprClass:
1300b57cec5SDimitry Andric   case Expr::ObjCPropertyRefExprClass:
1310b57cec5SDimitry Andric     // C++ [expr.typeid]p1: The result of a typeid expression is an lvalue of...
1320b57cec5SDimitry Andric   case Expr::CXXTypeidExprClass:
1335ffd83dbSDimitry Andric   case Expr::CXXUuidofExprClass:
1340b57cec5SDimitry Andric     // Unresolved lookups and uncorrected typos get classified as lvalues.
1350b57cec5SDimitry Andric     // FIXME: Is this wise? Should they get their own kind?
1360b57cec5SDimitry Andric   case Expr::UnresolvedLookupExprClass:
1370b57cec5SDimitry Andric   case Expr::UnresolvedMemberExprClass:
1380b57cec5SDimitry Andric   case Expr::TypoExprClass:
1390b57cec5SDimitry Andric   case Expr::DependentCoawaitExprClass:
1400b57cec5SDimitry Andric   case Expr::CXXDependentScopeMemberExprClass:
1410b57cec5SDimitry Andric   case Expr::DependentScopeDeclRefExprClass:
1420b57cec5SDimitry Andric     // ObjC instance variables are lvalues
1430b57cec5SDimitry Andric     // FIXME: ObjC++0x might have different rules
1440b57cec5SDimitry Andric   case Expr::ObjCIvarRefExprClass:
1450b57cec5SDimitry Andric   case Expr::FunctionParmPackExprClass:
1460b57cec5SDimitry Andric   case Expr::MSPropertyRefExprClass:
1470b57cec5SDimitry Andric   case Expr::MSPropertySubscriptExprClass:
1480b57cec5SDimitry Andric   case Expr::OMPArraySectionExprClass:
1495ffd83dbSDimitry Andric   case Expr::OMPArrayShapingExprClass:
1505ffd83dbSDimitry Andric   case Expr::OMPIteratorExprClass:
1510b57cec5SDimitry Andric     return Cl::CL_LValue;
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric     // C99 6.5.2.5p5 says that compound literals are lvalues.
1540b57cec5SDimitry Andric     // In C++, they're prvalue temporaries, except for file-scope arrays.
1550b57cec5SDimitry Andric   case Expr::CompoundLiteralExprClass:
1560b57cec5SDimitry Andric     return !E->isLValue() ? ClassifyTemporary(E->getType()) : Cl::CL_LValue;
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric     // Expressions that are prvalues.
1590b57cec5SDimitry Andric   case Expr::CXXBoolLiteralExprClass:
1600b57cec5SDimitry Andric   case Expr::CXXPseudoDestructorExprClass:
1610b57cec5SDimitry Andric   case Expr::UnaryExprOrTypeTraitExprClass:
1620b57cec5SDimitry Andric   case Expr::CXXNewExprClass:
1630b57cec5SDimitry Andric   case Expr::CXXNullPtrLiteralExprClass:
1640b57cec5SDimitry Andric   case Expr::ImaginaryLiteralClass:
1650b57cec5SDimitry Andric   case Expr::GNUNullExprClass:
1660b57cec5SDimitry Andric   case Expr::OffsetOfExprClass:
1670b57cec5SDimitry Andric   case Expr::CXXThrowExprClass:
1680b57cec5SDimitry Andric   case Expr::ShuffleVectorExprClass:
1690b57cec5SDimitry Andric   case Expr::ConvertVectorExprClass:
1700b57cec5SDimitry Andric   case Expr::IntegerLiteralClass:
1710b57cec5SDimitry Andric   case Expr::FixedPointLiteralClass:
1720b57cec5SDimitry Andric   case Expr::CharacterLiteralClass:
1730b57cec5SDimitry Andric   case Expr::AddrLabelExprClass:
1740b57cec5SDimitry Andric   case Expr::CXXDeleteExprClass:
1750b57cec5SDimitry Andric   case Expr::ImplicitValueInitExprClass:
1760b57cec5SDimitry Andric   case Expr::BlockExprClass:
1770b57cec5SDimitry Andric   case Expr::FloatingLiteralClass:
1780b57cec5SDimitry Andric   case Expr::CXXNoexceptExprClass:
1790b57cec5SDimitry Andric   case Expr::CXXScalarValueInitExprClass:
1800b57cec5SDimitry Andric   case Expr::TypeTraitExprClass:
1810b57cec5SDimitry Andric   case Expr::ArrayTypeTraitExprClass:
1820b57cec5SDimitry Andric   case Expr::ExpressionTraitExprClass:
1830b57cec5SDimitry Andric   case Expr::ObjCSelectorExprClass:
1840b57cec5SDimitry Andric   case Expr::ObjCProtocolExprClass:
1850b57cec5SDimitry Andric   case Expr::ObjCStringLiteralClass:
1860b57cec5SDimitry Andric   case Expr::ObjCBoxedExprClass:
1870b57cec5SDimitry Andric   case Expr::ObjCArrayLiteralClass:
1880b57cec5SDimitry Andric   case Expr::ObjCDictionaryLiteralClass:
1890b57cec5SDimitry Andric   case Expr::ObjCBoolLiteralExprClass:
1900b57cec5SDimitry Andric   case Expr::ObjCAvailabilityCheckExprClass:
1910b57cec5SDimitry Andric   case Expr::ParenListExprClass:
1920b57cec5SDimitry Andric   case Expr::SizeOfPackExprClass:
1930b57cec5SDimitry Andric   case Expr::SubstNonTypeTemplateParmPackExprClass:
1940b57cec5SDimitry Andric   case Expr::AsTypeExprClass:
1950b57cec5SDimitry Andric   case Expr::ObjCIndirectCopyRestoreExprClass:
1960b57cec5SDimitry Andric   case Expr::AtomicExprClass:
1970b57cec5SDimitry Andric   case Expr::CXXFoldExprClass:
1980b57cec5SDimitry Andric   case Expr::ArrayInitLoopExprClass:
1990b57cec5SDimitry Andric   case Expr::ArrayInitIndexExprClass:
2000b57cec5SDimitry Andric   case Expr::NoInitExprClass:
2010b57cec5SDimitry Andric   case Expr::DesignatedInitUpdateExprClass:
2020b57cec5SDimitry Andric   case Expr::SourceLocExprClass:
203a7dea167SDimitry Andric   case Expr::ConceptSpecializationExprClass:
20455e4f9d5SDimitry Andric   case Expr::RequiresExprClass:
2050b57cec5SDimitry Andric     return Cl::CL_PRValue;
2060b57cec5SDimitry Andric 
207bdd1243dSDimitry Andric   // Make HLSL this reference-like
208bdd1243dSDimitry Andric   case Expr::CXXThisExprClass:
209bdd1243dSDimitry Andric     return Lang.HLSL ? Cl::CL_LValue : Cl::CL_PRValue;
210bdd1243dSDimitry Andric 
2110b57cec5SDimitry Andric   case Expr::ConstantExprClass:
2120b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<ConstantExpr>(E)->getSubExpr());
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric     // Next come the complicated cases.
2150b57cec5SDimitry Andric   case Expr::SubstNonTypeTemplateParmExprClass:
2160b57cec5SDimitry Andric     return ClassifyInternal(Ctx,
2170b57cec5SDimitry Andric                  cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement());
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric     // C, C++98 [expr.sub]p1: The result is an lvalue of type "T".
2200b57cec5SDimitry Andric     // C++11 (DR1213): in the case of an array operand, the result is an lvalue
2210b57cec5SDimitry Andric     //                 if that operand is an lvalue and an xvalue otherwise.
2220b57cec5SDimitry Andric     // Subscripting vector types is more like member access.
2230b57cec5SDimitry Andric   case Expr::ArraySubscriptExprClass:
2240b57cec5SDimitry Andric     if (cast<ArraySubscriptExpr>(E)->getBase()->getType()->isVectorType())
2250b57cec5SDimitry Andric       return ClassifyInternal(Ctx, cast<ArraySubscriptExpr>(E)->getBase());
2260b57cec5SDimitry Andric     if (Lang.CPlusPlus11) {
2270b57cec5SDimitry Andric       // Step over the array-to-pointer decay if present, but not over the
2280b57cec5SDimitry Andric       // temporary materialization.
2290b57cec5SDimitry Andric       auto *Base = cast<ArraySubscriptExpr>(E)->getBase()->IgnoreImpCasts();
2300b57cec5SDimitry Andric       if (Base->getType()->isArrayType())
2310b57cec5SDimitry Andric         return ClassifyInternal(Ctx, Base);
2320b57cec5SDimitry Andric     }
2330b57cec5SDimitry Andric     return Cl::CL_LValue;
2340b57cec5SDimitry Andric 
2355ffd83dbSDimitry Andric   // Subscripting matrix types behaves like member accesses.
2365ffd83dbSDimitry Andric   case Expr::MatrixSubscriptExprClass:
2375ffd83dbSDimitry Andric     return ClassifyInternal(Ctx, cast<MatrixSubscriptExpr>(E)->getBase());
2385ffd83dbSDimitry Andric 
2390b57cec5SDimitry Andric     // C++ [expr.prim.general]p3: The result is an lvalue if the entity is a
2400b57cec5SDimitry Andric     //   function or variable and a prvalue otherwise.
2410b57cec5SDimitry Andric   case Expr::DeclRefExprClass:
2420b57cec5SDimitry Andric     if (E->getType() == Ctx.UnknownAnyTy)
2430b57cec5SDimitry Andric       return isa<FunctionDecl>(cast<DeclRefExpr>(E)->getDecl())
2440b57cec5SDimitry Andric                ? Cl::CL_PRValue : Cl::CL_LValue;
2450b57cec5SDimitry Andric     return ClassifyDecl(Ctx, cast<DeclRefExpr>(E)->getDecl());
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric     // Member access is complex.
2480b57cec5SDimitry Andric   case Expr::MemberExprClass:
2490b57cec5SDimitry Andric     return ClassifyMemberExpr(Ctx, cast<MemberExpr>(E));
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   case Expr::UnaryOperatorClass:
2520b57cec5SDimitry Andric     switch (cast<UnaryOperator>(E)->getOpcode()) {
2530b57cec5SDimitry Andric       // C++ [expr.unary.op]p1: The unary * operator performs indirection:
2540b57cec5SDimitry Andric       //   [...] the result is an lvalue referring to the object or function
2550b57cec5SDimitry Andric       //   to which the expression points.
2560b57cec5SDimitry Andric     case UO_Deref:
2570b57cec5SDimitry Andric       return Cl::CL_LValue;
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric       // GNU extensions, simply look through them.
2600b57cec5SDimitry Andric     case UO_Extension:
2610b57cec5SDimitry Andric       return ClassifyInternal(Ctx, cast<UnaryOperator>(E)->getSubExpr());
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric     // Treat _Real and _Imag basically as if they were member
2640b57cec5SDimitry Andric     // expressions:  l-value only if the operand is a true l-value.
2650b57cec5SDimitry Andric     case UO_Real:
2660b57cec5SDimitry Andric     case UO_Imag: {
2670b57cec5SDimitry Andric       const Expr *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
2680b57cec5SDimitry Andric       Cl::Kinds K = ClassifyInternal(Ctx, Op);
2690b57cec5SDimitry Andric       if (K != Cl::CL_LValue) return K;
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric       if (isa<ObjCPropertyRefExpr>(Op))
2720b57cec5SDimitry Andric         return Cl::CL_SubObjCPropertySetting;
2730b57cec5SDimitry Andric       return Cl::CL_LValue;
2740b57cec5SDimitry Andric     }
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric       // C++ [expr.pre.incr]p1: The result is the updated operand; it is an
2770b57cec5SDimitry Andric       //   lvalue, [...]
2780b57cec5SDimitry Andric       // Not so in C.
2790b57cec5SDimitry Andric     case UO_PreInc:
2800b57cec5SDimitry Andric     case UO_PreDec:
2810b57cec5SDimitry Andric       return Lang.CPlusPlus ? Cl::CL_LValue : Cl::CL_PRValue;
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric     default:
2840b57cec5SDimitry Andric       return Cl::CL_PRValue;
2850b57cec5SDimitry Andric     }
2860b57cec5SDimitry Andric 
2875ffd83dbSDimitry Andric   case Expr::RecoveryExprClass:
2880b57cec5SDimitry Andric   case Expr::OpaqueValueExprClass:
2890b57cec5SDimitry Andric     return ClassifyExprValueKind(Lang, E, E->getValueKind());
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric     // Pseudo-object expressions can produce l-values with reference magic.
2920b57cec5SDimitry Andric   case Expr::PseudoObjectExprClass:
2930b57cec5SDimitry Andric     return ClassifyExprValueKind(Lang, E,
2940b57cec5SDimitry Andric                                  cast<PseudoObjectExpr>(E)->getValueKind());
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric     // Implicit casts are lvalues if they're lvalue casts. Other than that, we
2970b57cec5SDimitry Andric     // only specifically record class temporaries.
2980b57cec5SDimitry Andric   case Expr::ImplicitCastExprClass:
2990b57cec5SDimitry Andric     return ClassifyExprValueKind(Lang, E, E->getValueKind());
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric     // C++ [expr.prim.general]p4: The presence of parentheses does not affect
3020b57cec5SDimitry Andric     //   whether the expression is an lvalue.
3030b57cec5SDimitry Andric   case Expr::ParenExprClass:
3040b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<ParenExpr>(E)->getSubExpr());
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric     // C11 6.5.1.1p4: [A generic selection] is an lvalue, a function designator,
3070b57cec5SDimitry Andric     // or a void expression if its result expression is, respectively, an
3080b57cec5SDimitry Andric     // lvalue, a function designator, or a void expression.
3090b57cec5SDimitry Andric   case Expr::GenericSelectionExprClass:
3100b57cec5SDimitry Andric     if (cast<GenericSelectionExpr>(E)->isResultDependent())
3110b57cec5SDimitry Andric       return Cl::CL_PRValue;
3120b57cec5SDimitry Andric     return ClassifyInternal(Ctx,cast<GenericSelectionExpr>(E)->getResultExpr());
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   case Expr::BinaryOperatorClass:
3150b57cec5SDimitry Andric   case Expr::CompoundAssignOperatorClass:
3160b57cec5SDimitry Andric     // C doesn't have any binary expressions that are lvalues.
3170b57cec5SDimitry Andric     if (Lang.CPlusPlus)
3180b57cec5SDimitry Andric       return ClassifyBinaryOp(Ctx, cast<BinaryOperator>(E));
3190b57cec5SDimitry Andric     return Cl::CL_PRValue;
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   case Expr::CallExprClass:
3220b57cec5SDimitry Andric   case Expr::CXXOperatorCallExprClass:
3230b57cec5SDimitry Andric   case Expr::CXXMemberCallExprClass:
3240b57cec5SDimitry Andric   case Expr::UserDefinedLiteralClass:
3250b57cec5SDimitry Andric   case Expr::CUDAKernelCallExprClass:
3260b57cec5SDimitry Andric     return ClassifyUnnamed(Ctx, cast<CallExpr>(E)->getCallReturnType(Ctx));
3270b57cec5SDimitry Andric 
328a7dea167SDimitry Andric   case Expr::CXXRewrittenBinaryOperatorClass:
329a7dea167SDimitry Andric     return ClassifyInternal(
330a7dea167SDimitry Andric         Ctx, cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm());
331a7dea167SDimitry Andric 
3320b57cec5SDimitry Andric     // __builtin_choose_expr is equivalent to the chosen expression.
3330b57cec5SDimitry Andric   case Expr::ChooseExprClass:
3340b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<ChooseExpr>(E)->getChosenSubExpr());
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric     // Extended vector element access is an lvalue unless there are duplicates
3370b57cec5SDimitry Andric     // in the shuffle expression.
3380b57cec5SDimitry Andric   case Expr::ExtVectorElementExprClass:
3390b57cec5SDimitry Andric     if (cast<ExtVectorElementExpr>(E)->containsDuplicateElements())
3400b57cec5SDimitry Andric       return Cl::CL_DuplicateVectorComponents;
3410b57cec5SDimitry Andric     if (cast<ExtVectorElementExpr>(E)->isArrow())
3420b57cec5SDimitry Andric       return Cl::CL_LValue;
3430b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<ExtVectorElementExpr>(E)->getBase());
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric     // Simply look at the actual default argument.
3460b57cec5SDimitry Andric   case Expr::CXXDefaultArgExprClass:
3470b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<CXXDefaultArgExpr>(E)->getExpr());
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric     // Same idea for default initializers.
3500b57cec5SDimitry Andric   case Expr::CXXDefaultInitExprClass:
3510b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<CXXDefaultInitExpr>(E)->getExpr());
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric     // Same idea for temporary binding.
3540b57cec5SDimitry Andric   case Expr::CXXBindTemporaryExprClass:
3550b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<CXXBindTemporaryExpr>(E)->getSubExpr());
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric     // And the cleanups guard.
3580b57cec5SDimitry Andric   case Expr::ExprWithCleanupsClass:
3590b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<ExprWithCleanups>(E)->getSubExpr());
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric     // Casts depend completely on the target type. All casts work the same.
3620b57cec5SDimitry Andric   case Expr::CStyleCastExprClass:
3630b57cec5SDimitry Andric   case Expr::CXXFunctionalCastExprClass:
3640b57cec5SDimitry Andric   case Expr::CXXStaticCastExprClass:
3650b57cec5SDimitry Andric   case Expr::CXXDynamicCastExprClass:
3660b57cec5SDimitry Andric   case Expr::CXXReinterpretCastExprClass:
3670b57cec5SDimitry Andric   case Expr::CXXConstCastExprClass:
3685ffd83dbSDimitry Andric   case Expr::CXXAddrspaceCastExprClass:
3690b57cec5SDimitry Andric   case Expr::ObjCBridgedCastExprClass:
3700b57cec5SDimitry Andric   case Expr::BuiltinBitCastExprClass:
3710b57cec5SDimitry Andric     // Only in C++ can casts be interesting at all.
3720b57cec5SDimitry Andric     if (!Lang.CPlusPlus) return Cl::CL_PRValue;
3730b57cec5SDimitry Andric     return ClassifyUnnamed(Ctx, cast<ExplicitCastExpr>(E)->getTypeAsWritten());
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric   case Expr::CXXUnresolvedConstructExprClass:
3760b57cec5SDimitry Andric     return ClassifyUnnamed(Ctx,
3770b57cec5SDimitry Andric                       cast<CXXUnresolvedConstructExpr>(E)->getTypeAsWritten());
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric   case Expr::BinaryConditionalOperatorClass: {
3800b57cec5SDimitry Andric     if (!Lang.CPlusPlus) return Cl::CL_PRValue;
3810b57cec5SDimitry Andric     const auto *co = cast<BinaryConditionalOperator>(E);
3820b57cec5SDimitry Andric     return ClassifyConditional(Ctx, co->getTrueExpr(), co->getFalseExpr());
3830b57cec5SDimitry Andric   }
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric   case Expr::ConditionalOperatorClass: {
3860b57cec5SDimitry Andric     // Once again, only C++ is interesting.
3870b57cec5SDimitry Andric     if (!Lang.CPlusPlus) return Cl::CL_PRValue;
3880b57cec5SDimitry Andric     const auto *co = cast<ConditionalOperator>(E);
3890b57cec5SDimitry Andric     return ClassifyConditional(Ctx, co->getTrueExpr(), co->getFalseExpr());
3900b57cec5SDimitry Andric   }
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric     // ObjC message sends are effectively function calls, if the target function
3930b57cec5SDimitry Andric     // is known.
3940b57cec5SDimitry Andric   case Expr::ObjCMessageExprClass:
3950b57cec5SDimitry Andric     if (const ObjCMethodDecl *Method =
3960b57cec5SDimitry Andric           cast<ObjCMessageExpr>(E)->getMethodDecl()) {
3970b57cec5SDimitry Andric       Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getReturnType());
3980b57cec5SDimitry Andric       return (kind == Cl::CL_PRValue) ? Cl::CL_ObjCMessageRValue : kind;
3990b57cec5SDimitry Andric     }
4000b57cec5SDimitry Andric     return Cl::CL_PRValue;
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric     // Some C++ expressions are always class temporaries.
4030b57cec5SDimitry Andric   case Expr::CXXConstructExprClass:
4040b57cec5SDimitry Andric   case Expr::CXXInheritedCtorInitExprClass:
4050b57cec5SDimitry Andric   case Expr::CXXTemporaryObjectExprClass:
4060b57cec5SDimitry Andric   case Expr::LambdaExprClass:
4070b57cec5SDimitry Andric   case Expr::CXXStdInitializerListExprClass:
4080b57cec5SDimitry Andric     return Cl::CL_ClassTemporary;
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric   case Expr::VAArgExprClass:
4110b57cec5SDimitry Andric     return ClassifyUnnamed(Ctx, E->getType());
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric   case Expr::DesignatedInitExprClass:
4140b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<DesignatedInitExpr>(E)->getInit());
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   case Expr::StmtExprClass: {
4170b57cec5SDimitry Andric     const CompoundStmt *S = cast<StmtExpr>(E)->getSubStmt();
4180b57cec5SDimitry Andric     if (const auto *LastExpr = dyn_cast_or_null<Expr>(S->body_back()))
4190b57cec5SDimitry Andric       return ClassifyUnnamed(Ctx, LastExpr->getType());
4200b57cec5SDimitry Andric     return Cl::CL_PRValue;
4210b57cec5SDimitry Andric   }
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   case Expr::PackExpansionExprClass:
4240b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<PackExpansionExpr>(E)->getPattern());
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric   case Expr::MaterializeTemporaryExprClass:
4270b57cec5SDimitry Andric     return cast<MaterializeTemporaryExpr>(E)->isBoundToLvalueReference()
4280b57cec5SDimitry Andric               ? Cl::CL_LValue
4290b57cec5SDimitry Andric               : Cl::CL_XValue;
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   case Expr::InitListExprClass:
4320b57cec5SDimitry Andric     // An init list can be an lvalue if it is bound to a reference and
4330b57cec5SDimitry Andric     // contains only one element. In that case, we look at that element
4340b57cec5SDimitry Andric     // for an exact classification. Init list creation takes care of the
4350b57cec5SDimitry Andric     // value kind for us, so we only need to fine-tune.
436fe6060f1SDimitry Andric     if (E->isPRValue())
4370b57cec5SDimitry Andric       return ClassifyExprValueKind(Lang, E, E->getValueKind());
4380b57cec5SDimitry Andric     assert(cast<InitListExpr>(E)->getNumInits() == 1 &&
4390b57cec5SDimitry Andric            "Only 1-element init lists can be glvalues.");
4400b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<InitListExpr>(E)->getInit(0));
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   case Expr::CoawaitExprClass:
4430b57cec5SDimitry Andric   case Expr::CoyieldExprClass:
4440b57cec5SDimitry Andric     return ClassifyInternal(Ctx, cast<CoroutineSuspendExpr>(E)->getResumeExpr());
445fe6060f1SDimitry Andric   case Expr::SYCLUniqueStableNameExprClass:
446fe6060f1SDimitry Andric     return Cl::CL_PRValue;
447fe6060f1SDimitry Andric     break;
448bdd1243dSDimitry Andric 
449bdd1243dSDimitry Andric   case Expr::CXXParenListInitExprClass:
450bdd1243dSDimitry Andric     if (isa<ArrayType>(E->getType()))
451bdd1243dSDimitry Andric       return Cl::CL_ArrayTemporary;
452bdd1243dSDimitry Andric     return Cl::CL_ClassTemporary;
4530b57cec5SDimitry Andric   }
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   llvm_unreachable("unhandled expression kind in classification");
4560b57cec5SDimitry Andric }
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric /// ClassifyDecl - Return the classification of an expression referencing the
4590b57cec5SDimitry Andric /// given declaration.
ClassifyDecl(ASTContext & Ctx,const Decl * D)4600b57cec5SDimitry Andric static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D) {
4610b57cec5SDimitry Andric   // C++ [expr.prim.general]p6: The result is an lvalue if the entity is a
4620b57cec5SDimitry Andric   //   function, variable, or data member and a prvalue otherwise.
4630b57cec5SDimitry Andric   // In C, functions are not lvalues.
4640b57cec5SDimitry Andric   // In addition, NonTypeTemplateParmDecl derives from VarDecl but isn't an
4650b57cec5SDimitry Andric   // lvalue unless it's a reference type (C++ [temp.param]p6), so we need to
4660b57cec5SDimitry Andric   // special-case this.
4670b57cec5SDimitry Andric 
4685f757f3fSDimitry Andric   if (const auto *M = dyn_cast<CXXMethodDecl>(D)) {
4695f757f3fSDimitry Andric     if (M->isImplicitObjectMemberFunction())
4700b57cec5SDimitry Andric       return Cl::CL_MemberFunction;
4715f757f3fSDimitry Andric     if (M->isStatic())
4725f757f3fSDimitry Andric       return Cl::CL_LValue;
4735f757f3fSDimitry Andric     return Cl::CL_PRValue;
4745f757f3fSDimitry Andric   }
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric   bool islvalue;
4770b57cec5SDimitry Andric   if (const auto *NTTParm = dyn_cast<NonTypeTemplateParmDecl>(D))
478e8d8bef9SDimitry Andric     islvalue = NTTParm->getType()->isReferenceType() ||
479e8d8bef9SDimitry Andric                NTTParm->getType()->isRecordType();
4800b57cec5SDimitry Andric   else
48181ad6265SDimitry Andric     islvalue =
48281ad6265SDimitry Andric         isa<VarDecl, FieldDecl, IndirectFieldDecl, BindingDecl, MSGuidDecl,
48381ad6265SDimitry Andric             UnnamedGlobalConstantDecl, TemplateParamObjectDecl>(D) ||
4840b57cec5SDimitry Andric         (Ctx.getLangOpts().CPlusPlus &&
48581ad6265SDimitry Andric          (isa<FunctionDecl, MSPropertyDecl, FunctionTemplateDecl>(D)));
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric   return islvalue ? Cl::CL_LValue : Cl::CL_PRValue;
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric /// ClassifyUnnamed - Return the classification of an expression yielding an
4910b57cec5SDimitry Andric /// unnamed value of the given type. This applies in particular to function
4920b57cec5SDimitry Andric /// calls and casts.
ClassifyUnnamed(ASTContext & Ctx,QualType T)4930b57cec5SDimitry Andric static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T) {
4940b57cec5SDimitry Andric   // In C, function calls are always rvalues.
4950b57cec5SDimitry Andric   if (!Ctx.getLangOpts().CPlusPlus) return Cl::CL_PRValue;
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric   // C++ [expr.call]p10: A function call is an lvalue if the result type is an
4980b57cec5SDimitry Andric   //   lvalue reference type or an rvalue reference to function type, an xvalue
4990b57cec5SDimitry Andric   //   if the result type is an rvalue reference to object type, and a prvalue
5000b57cec5SDimitry Andric   //   otherwise.
5010b57cec5SDimitry Andric   if (T->isLValueReferenceType())
5020b57cec5SDimitry Andric     return Cl::CL_LValue;
5030b57cec5SDimitry Andric   const auto *RV = T->getAs<RValueReferenceType>();
5040b57cec5SDimitry Andric   if (!RV) // Could still be a class temporary, though.
5050b57cec5SDimitry Andric     return ClassifyTemporary(T);
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric   return RV->getPointeeType()->isFunctionType() ? Cl::CL_LValue : Cl::CL_XValue;
5080b57cec5SDimitry Andric }
5090b57cec5SDimitry Andric 
ClassifyMemberExpr(ASTContext & Ctx,const MemberExpr * E)5100b57cec5SDimitry Andric static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E) {
5110b57cec5SDimitry Andric   if (E->getType() == Ctx.UnknownAnyTy)
5120b57cec5SDimitry Andric     return (isa<FunctionDecl>(E->getMemberDecl())
5130b57cec5SDimitry Andric               ? Cl::CL_PRValue : Cl::CL_LValue);
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric   // Handle C first, it's easier.
5160b57cec5SDimitry Andric   if (!Ctx.getLangOpts().CPlusPlus) {
5170b57cec5SDimitry Andric     // C99 6.5.2.3p3
5180b57cec5SDimitry Andric     // For dot access, the expression is an lvalue if the first part is. For
5190b57cec5SDimitry Andric     // arrow access, it always is an lvalue.
5200b57cec5SDimitry Andric     if (E->isArrow())
5210b57cec5SDimitry Andric       return Cl::CL_LValue;
5220b57cec5SDimitry Andric     // ObjC property accesses are not lvalues, but get special treatment.
5230b57cec5SDimitry Andric     Expr *Base = E->getBase()->IgnoreParens();
5240b57cec5SDimitry Andric     if (isa<ObjCPropertyRefExpr>(Base))
5250b57cec5SDimitry Andric       return Cl::CL_SubObjCPropertySetting;
5260b57cec5SDimitry Andric     return ClassifyInternal(Ctx, Base);
5270b57cec5SDimitry Andric   }
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric   NamedDecl *Member = E->getMemberDecl();
5300b57cec5SDimitry Andric   // C++ [expr.ref]p3: E1->E2 is converted to the equivalent form (*(E1)).E2.
5310b57cec5SDimitry Andric   // C++ [expr.ref]p4: If E2 is declared to have type "reference to T", then
5320b57cec5SDimitry Andric   //   E1.E2 is an lvalue.
5330b57cec5SDimitry Andric   if (const auto *Value = dyn_cast<ValueDecl>(Member))
5340b57cec5SDimitry Andric     if (Value->getType()->isReferenceType())
5350b57cec5SDimitry Andric       return Cl::CL_LValue;
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric   //   Otherwise, one of the following rules applies.
5380b57cec5SDimitry Andric   //   -- If E2 is a static member [...] then E1.E2 is an lvalue.
5390b57cec5SDimitry Andric   if (isa<VarDecl>(Member) && Member->getDeclContext()->isRecord())
5400b57cec5SDimitry Andric     return Cl::CL_LValue;
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric   //   -- If E2 is a non-static data member [...]. If E1 is an lvalue, then
5430b57cec5SDimitry Andric   //      E1.E2 is an lvalue; if E1 is an xvalue, then E1.E2 is an xvalue;
5440b57cec5SDimitry Andric   //      otherwise, it is a prvalue.
5450b57cec5SDimitry Andric   if (isa<FieldDecl>(Member)) {
5460b57cec5SDimitry Andric     // *E1 is an lvalue
5470b57cec5SDimitry Andric     if (E->isArrow())
5480b57cec5SDimitry Andric       return Cl::CL_LValue;
5490b57cec5SDimitry Andric     Expr *Base = E->getBase()->IgnoreParenImpCasts();
5500b57cec5SDimitry Andric     if (isa<ObjCPropertyRefExpr>(Base))
5510b57cec5SDimitry Andric       return Cl::CL_SubObjCPropertySetting;
5520b57cec5SDimitry Andric     return ClassifyInternal(Ctx, E->getBase());
5530b57cec5SDimitry Andric   }
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric   //   -- If E2 is a [...] member function, [...]
5560b57cec5SDimitry Andric   //      -- If it refers to a static member function [...], then E1.E2 is an
5570b57cec5SDimitry Andric   //         lvalue; [...]
5580b57cec5SDimitry Andric   //      -- Otherwise [...] E1.E2 is a prvalue.
5595f757f3fSDimitry Andric   if (const auto *Method = dyn_cast<CXXMethodDecl>(Member)) {
5605f757f3fSDimitry Andric     if (Method->isStatic())
5615f757f3fSDimitry Andric       return Cl::CL_LValue;
5625f757f3fSDimitry Andric     if (Method->isImplicitObjectMemberFunction())
5635f757f3fSDimitry Andric       return Cl::CL_MemberFunction;
5645f757f3fSDimitry Andric     return Cl::CL_PRValue;
5655f757f3fSDimitry Andric   }
5660b57cec5SDimitry Andric 
5670b57cec5SDimitry Andric   //   -- If E2 is a member enumerator [...], the expression E1.E2 is a prvalue.
5680b57cec5SDimitry Andric   // So is everything else we haven't handled yet.
5690b57cec5SDimitry Andric   return Cl::CL_PRValue;
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric 
ClassifyBinaryOp(ASTContext & Ctx,const BinaryOperator * E)5720b57cec5SDimitry Andric static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E) {
5730b57cec5SDimitry Andric   assert(Ctx.getLangOpts().CPlusPlus &&
5740b57cec5SDimitry Andric          "This is only relevant for C++.");
5750b57cec5SDimitry Andric   // C++ [expr.ass]p1: All [...] return an lvalue referring to the left operand.
5760b57cec5SDimitry Andric   // Except we override this for writes to ObjC properties.
5770b57cec5SDimitry Andric   if (E->isAssignmentOp())
5780b57cec5SDimitry Andric     return (E->getLHS()->getObjectKind() == OK_ObjCProperty
5790b57cec5SDimitry Andric               ? Cl::CL_PRValue : Cl::CL_LValue);
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric   // C++ [expr.comma]p1: the result is of the same value category as its right
5820b57cec5SDimitry Andric   //   operand, [...].
5830b57cec5SDimitry Andric   if (E->getOpcode() == BO_Comma)
5840b57cec5SDimitry Andric     return ClassifyInternal(Ctx, E->getRHS());
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric   // C++ [expr.mptr.oper]p6: The result of a .* expression whose second operand
5870b57cec5SDimitry Andric   //   is a pointer to a data member is of the same value category as its first
5880b57cec5SDimitry Andric   //   operand.
5890b57cec5SDimitry Andric   if (E->getOpcode() == BO_PtrMemD)
5900b57cec5SDimitry Andric     return (E->getType()->isFunctionType() ||
5910b57cec5SDimitry Andric             E->hasPlaceholderType(BuiltinType::BoundMember))
5920b57cec5SDimitry Andric              ? Cl::CL_MemberFunction
5930b57cec5SDimitry Andric              : ClassifyInternal(Ctx, E->getLHS());
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric   // C++ [expr.mptr.oper]p6: The result of an ->* expression is an lvalue if its
5960b57cec5SDimitry Andric   //   second operand is a pointer to data member and a prvalue otherwise.
5970b57cec5SDimitry Andric   if (E->getOpcode() == BO_PtrMemI)
5980b57cec5SDimitry Andric     return (E->getType()->isFunctionType() ||
5990b57cec5SDimitry Andric             E->hasPlaceholderType(BuiltinType::BoundMember))
6000b57cec5SDimitry Andric              ? Cl::CL_MemberFunction
6010b57cec5SDimitry Andric              : Cl::CL_LValue;
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric   // All other binary operations are prvalues.
6040b57cec5SDimitry Andric   return Cl::CL_PRValue;
6050b57cec5SDimitry Andric }
6060b57cec5SDimitry Andric 
ClassifyConditional(ASTContext & Ctx,const Expr * True,const Expr * False)6070b57cec5SDimitry Andric static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *True,
6080b57cec5SDimitry Andric                                      const Expr *False) {
6090b57cec5SDimitry Andric   assert(Ctx.getLangOpts().CPlusPlus &&
6100b57cec5SDimitry Andric          "This is only relevant for C++.");
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric   // C++ [expr.cond]p2
6130b57cec5SDimitry Andric   //   If either the second or the third operand has type (cv) void,
6140b57cec5SDimitry Andric   //   one of the following shall hold:
6150b57cec5SDimitry Andric   if (True->getType()->isVoidType() || False->getType()->isVoidType()) {
6160b57cec5SDimitry Andric     // The second or the third operand (but not both) is a (possibly
6170b57cec5SDimitry Andric     // parenthesized) throw-expression; the result is of the [...] value
6180b57cec5SDimitry Andric     // category of the other.
6190b57cec5SDimitry Andric     bool TrueIsThrow = isa<CXXThrowExpr>(True->IgnoreParenImpCasts());
6200b57cec5SDimitry Andric     bool FalseIsThrow = isa<CXXThrowExpr>(False->IgnoreParenImpCasts());
6210b57cec5SDimitry Andric     if (const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ? nullptr : False)
6220b57cec5SDimitry Andric                                            : (FalseIsThrow ? True : nullptr))
6230b57cec5SDimitry Andric       return ClassifyInternal(Ctx, NonThrow);
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric     //   [Otherwise] the result [...] is a prvalue.
6260b57cec5SDimitry Andric     return Cl::CL_PRValue;
6270b57cec5SDimitry Andric   }
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric   // Note that at this point, we have already performed all conversions
6300b57cec5SDimitry Andric   // according to [expr.cond]p3.
6310b57cec5SDimitry Andric   // C++ [expr.cond]p4: If the second and third operands are glvalues of the
6320b57cec5SDimitry Andric   //   same value category [...], the result is of that [...] value category.
6330b57cec5SDimitry Andric   // C++ [expr.cond]p5: Otherwise, the result is a prvalue.
6340b57cec5SDimitry Andric   Cl::Kinds LCl = ClassifyInternal(Ctx, True),
6350b57cec5SDimitry Andric             RCl = ClassifyInternal(Ctx, False);
6360b57cec5SDimitry Andric   return LCl == RCl ? LCl : Cl::CL_PRValue;
6370b57cec5SDimitry Andric }
6380b57cec5SDimitry Andric 
IsModifiable(ASTContext & Ctx,const Expr * E,Cl::Kinds Kind,SourceLocation & Loc)6390b57cec5SDimitry Andric static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
6400b57cec5SDimitry Andric                                        Cl::Kinds Kind, SourceLocation &Loc) {
6410b57cec5SDimitry Andric   // As a general rule, we only care about lvalues. But there are some rvalues
6420b57cec5SDimitry Andric   // for which we want to generate special results.
6430b57cec5SDimitry Andric   if (Kind == Cl::CL_PRValue) {
6440b57cec5SDimitry Andric     // For the sake of better diagnostics, we want to specifically recognize
6450b57cec5SDimitry Andric     // use of the GCC cast-as-lvalue extension.
6460b57cec5SDimitry Andric     if (const auto *CE = dyn_cast<ExplicitCastExpr>(E->IgnoreParens())) {
6470b57cec5SDimitry Andric       if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) {
6480b57cec5SDimitry Andric         Loc = CE->getExprLoc();
6490b57cec5SDimitry Andric         return Cl::CM_LValueCast;
6500b57cec5SDimitry Andric       }
6510b57cec5SDimitry Andric     }
6520b57cec5SDimitry Andric   }
6530b57cec5SDimitry Andric   if (Kind != Cl::CL_LValue)
6540b57cec5SDimitry Andric     return Cl::CM_RValue;
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric   // This is the lvalue case.
6570b57cec5SDimitry Andric   // Functions are lvalues in C++, but not modifiable. (C++ [basic.lval]p6)
6580b57cec5SDimitry Andric   if (Ctx.getLangOpts().CPlusPlus && E->getType()->isFunctionType())
6590b57cec5SDimitry Andric     return Cl::CM_Function;
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric   // Assignment to a property in ObjC is an implicit setter access. But a
6620b57cec5SDimitry Andric   // setter might not exist.
6630b57cec5SDimitry Andric   if (const auto *Expr = dyn_cast<ObjCPropertyRefExpr>(E)) {
6640b57cec5SDimitry Andric     if (Expr->isImplicitProperty() &&
6650b57cec5SDimitry Andric         Expr->getImplicitPropertySetter() == nullptr)
6660b57cec5SDimitry Andric       return Cl::CM_NoSetterProperty;
6670b57cec5SDimitry Andric   }
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric   CanQualType CT = Ctx.getCanonicalType(E->getType());
6700b57cec5SDimitry Andric   // Const stuff is obviously not modifiable.
6710b57cec5SDimitry Andric   if (CT.isConstQualified())
6720b57cec5SDimitry Andric     return Cl::CM_ConstQualified;
6730b57cec5SDimitry Andric   if (Ctx.getLangOpts().OpenCL &&
6740b57cec5SDimitry Andric       CT.getQualifiers().getAddressSpace() == LangAS::opencl_constant)
6750b57cec5SDimitry Andric     return Cl::CM_ConstAddrSpace;
6760b57cec5SDimitry Andric 
6770b57cec5SDimitry Andric   // Arrays are not modifiable, only their elements are.
6780b57cec5SDimitry Andric   if (CT->isArrayType())
6790b57cec5SDimitry Andric     return Cl::CM_ArrayType;
6800b57cec5SDimitry Andric   // Incomplete types are not modifiable.
6810b57cec5SDimitry Andric   if (CT->isIncompleteType())
6820b57cec5SDimitry Andric     return Cl::CM_IncompleteType;
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric   // Records with any const fields (recursively) are not modifiable.
6850b57cec5SDimitry Andric   if (const RecordType *R = CT->getAs<RecordType>())
6860b57cec5SDimitry Andric     if (R->hasConstFields())
6870b57cec5SDimitry Andric       return Cl::CM_ConstQualifiedField;
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric   return Cl::CM_Modifiable;
6900b57cec5SDimitry Andric }
6910b57cec5SDimitry Andric 
ClassifyLValue(ASTContext & Ctx) const6920b57cec5SDimitry Andric Expr::LValueClassification Expr::ClassifyLValue(ASTContext &Ctx) const {
6930b57cec5SDimitry Andric   Classification VC = Classify(Ctx);
6940b57cec5SDimitry Andric   switch (VC.getKind()) {
6950b57cec5SDimitry Andric   case Cl::CL_LValue: return LV_Valid;
6960b57cec5SDimitry Andric   case Cl::CL_XValue: return LV_InvalidExpression;
6970b57cec5SDimitry Andric   case Cl::CL_Function: return LV_NotObjectType;
6980b57cec5SDimitry Andric   case Cl::CL_Void: return LV_InvalidExpression;
6990b57cec5SDimitry Andric   case Cl::CL_AddressableVoid: return LV_IncompleteVoidType;
7000b57cec5SDimitry Andric   case Cl::CL_DuplicateVectorComponents: return LV_DuplicateVectorComponents;
7010b57cec5SDimitry Andric   case Cl::CL_MemberFunction: return LV_MemberFunction;
7020b57cec5SDimitry Andric   case Cl::CL_SubObjCPropertySetting: return LV_SubObjCPropertySetting;
7030b57cec5SDimitry Andric   case Cl::CL_ClassTemporary: return LV_ClassTemporary;
7040b57cec5SDimitry Andric   case Cl::CL_ArrayTemporary: return LV_ArrayTemporary;
7050b57cec5SDimitry Andric   case Cl::CL_ObjCMessageRValue: return LV_InvalidMessageExpression;
7060b57cec5SDimitry Andric   case Cl::CL_PRValue: return LV_InvalidExpression;
7070b57cec5SDimitry Andric   }
7080b57cec5SDimitry Andric   llvm_unreachable("Unhandled kind");
7090b57cec5SDimitry Andric }
7100b57cec5SDimitry Andric 
7110b57cec5SDimitry Andric Expr::isModifiableLvalueResult
isModifiableLvalue(ASTContext & Ctx,SourceLocation * Loc) const7120b57cec5SDimitry Andric Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const {
7130b57cec5SDimitry Andric   SourceLocation dummy;
7140b57cec5SDimitry Andric   Classification VC = ClassifyModifiable(Ctx, Loc ? *Loc : dummy);
7150b57cec5SDimitry Andric   switch (VC.getKind()) {
7160b57cec5SDimitry Andric   case Cl::CL_LValue: break;
7170b57cec5SDimitry Andric   case Cl::CL_XValue: return MLV_InvalidExpression;
7180b57cec5SDimitry Andric   case Cl::CL_Function: return MLV_NotObjectType;
7190b57cec5SDimitry Andric   case Cl::CL_Void: return MLV_InvalidExpression;
7200b57cec5SDimitry Andric   case Cl::CL_AddressableVoid: return MLV_IncompleteVoidType;
7210b57cec5SDimitry Andric   case Cl::CL_DuplicateVectorComponents: return MLV_DuplicateVectorComponents;
7220b57cec5SDimitry Andric   case Cl::CL_MemberFunction: return MLV_MemberFunction;
7230b57cec5SDimitry Andric   case Cl::CL_SubObjCPropertySetting: return MLV_SubObjCPropertySetting;
7240b57cec5SDimitry Andric   case Cl::CL_ClassTemporary: return MLV_ClassTemporary;
7250b57cec5SDimitry Andric   case Cl::CL_ArrayTemporary: return MLV_ArrayTemporary;
7260b57cec5SDimitry Andric   case Cl::CL_ObjCMessageRValue: return MLV_InvalidMessageExpression;
7270b57cec5SDimitry Andric   case Cl::CL_PRValue:
7280b57cec5SDimitry Andric     return VC.getModifiable() == Cl::CM_LValueCast ?
7290b57cec5SDimitry Andric       MLV_LValueCast : MLV_InvalidExpression;
7300b57cec5SDimitry Andric   }
7310b57cec5SDimitry Andric   assert(VC.getKind() == Cl::CL_LValue && "Unhandled kind");
7320b57cec5SDimitry Andric   switch (VC.getModifiable()) {
7330b57cec5SDimitry Andric   case Cl::CM_Untested: llvm_unreachable("Did not test modifiability");
7340b57cec5SDimitry Andric   case Cl::CM_Modifiable: return MLV_Valid;
7350b57cec5SDimitry Andric   case Cl::CM_RValue: llvm_unreachable("CM_RValue and CL_LValue don't match");
7360b57cec5SDimitry Andric   case Cl::CM_Function: return MLV_NotObjectType;
7370b57cec5SDimitry Andric   case Cl::CM_LValueCast:
7380b57cec5SDimitry Andric     llvm_unreachable("CM_LValueCast and CL_LValue don't match");
7390b57cec5SDimitry Andric   case Cl::CM_NoSetterProperty: return MLV_NoSetterProperty;
7400b57cec5SDimitry Andric   case Cl::CM_ConstQualified: return MLV_ConstQualified;
7410b57cec5SDimitry Andric   case Cl::CM_ConstQualifiedField: return MLV_ConstQualifiedField;
7420b57cec5SDimitry Andric   case Cl::CM_ConstAddrSpace: return MLV_ConstAddrSpace;
7430b57cec5SDimitry Andric   case Cl::CM_ArrayType: return MLV_ArrayType;
7440b57cec5SDimitry Andric   case Cl::CM_IncompleteType: return MLV_IncompleteType;
7450b57cec5SDimitry Andric   }
7460b57cec5SDimitry Andric   llvm_unreachable("Unhandled modifiable type");
7470b57cec5SDimitry Andric }
748