xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/AST/ExprClassification.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===- ExprClassification.cpp - Expression AST Node Implementation --------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements Expr::classify.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #include "clang/AST/Expr.h"
147330f729Sjoerg #include "clang/AST/ASTContext.h"
157330f729Sjoerg #include "clang/AST/DeclCXX.h"
167330f729Sjoerg #include "clang/AST/DeclObjC.h"
177330f729Sjoerg #include "clang/AST/DeclTemplate.h"
187330f729Sjoerg #include "clang/AST/ExprCXX.h"
197330f729Sjoerg #include "clang/AST/ExprObjC.h"
207330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
217330f729Sjoerg 
227330f729Sjoerg using namespace clang;
237330f729Sjoerg 
247330f729Sjoerg using Cl = Expr::Classification;
257330f729Sjoerg 
267330f729Sjoerg static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E);
277330f729Sjoerg static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D);
287330f729Sjoerg static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T);
297330f729Sjoerg static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E);
307330f729Sjoerg static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E);
317330f729Sjoerg static Cl::Kinds ClassifyConditional(ASTContext &Ctx,
327330f729Sjoerg                                      const Expr *trueExpr,
337330f729Sjoerg                                      const Expr *falseExpr);
347330f729Sjoerg static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
357330f729Sjoerg                                        Cl::Kinds Kind, SourceLocation &Loc);
367330f729Sjoerg 
ClassifyImpl(ASTContext & Ctx,SourceLocation * Loc) const377330f729Sjoerg Cl Expr::ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const {
387330f729Sjoerg   assert(!TR->isReferenceType() && "Expressions can't have reference type.");
397330f729Sjoerg 
407330f729Sjoerg   Cl::Kinds kind = ClassifyInternal(Ctx, this);
417330f729Sjoerg   // C99 6.3.2.1: An lvalue is an expression with an object type or an
427330f729Sjoerg   //   incomplete type other than void.
437330f729Sjoerg   if (!Ctx.getLangOpts().CPlusPlus) {
447330f729Sjoerg     // Thus, no functions.
457330f729Sjoerg     if (TR->isFunctionType() || TR == Ctx.OverloadTy)
467330f729Sjoerg       kind = Cl::CL_Function;
477330f729Sjoerg     // No void either, but qualified void is OK because it is "other than void".
487330f729Sjoerg     // Void "lvalues" are classified as addressable void values, which are void
497330f729Sjoerg     // expressions whose address can be taken.
507330f729Sjoerg     else if (TR->isVoidType() && !TR.hasQualifiers())
517330f729Sjoerg       kind = (kind == Cl::CL_LValue ? Cl::CL_AddressableVoid : Cl::CL_Void);
527330f729Sjoerg   }
537330f729Sjoerg 
547330f729Sjoerg   // Enable this assertion for testing.
557330f729Sjoerg   switch (kind) {
567330f729Sjoerg   case Cl::CL_LValue: assert(getValueKind() == VK_LValue); break;
577330f729Sjoerg   case Cl::CL_XValue: assert(getValueKind() == VK_XValue); break;
587330f729Sjoerg   case Cl::CL_Function:
597330f729Sjoerg   case Cl::CL_Void:
607330f729Sjoerg   case Cl::CL_AddressableVoid:
617330f729Sjoerg   case Cl::CL_DuplicateVectorComponents:
627330f729Sjoerg   case Cl::CL_MemberFunction:
637330f729Sjoerg   case Cl::CL_SubObjCPropertySetting:
647330f729Sjoerg   case Cl::CL_ClassTemporary:
657330f729Sjoerg   case Cl::CL_ArrayTemporary:
667330f729Sjoerg   case Cl::CL_ObjCMessageRValue:
677330f729Sjoerg   case Cl::CL_PRValue: assert(getValueKind() == VK_RValue); break;
687330f729Sjoerg   }
697330f729Sjoerg 
707330f729Sjoerg   Cl::ModifiableType modifiable = Cl::CM_Untested;
717330f729Sjoerg   if (Loc)
727330f729Sjoerg     modifiable = IsModifiable(Ctx, this, kind, *Loc);
737330f729Sjoerg   return Classification(kind, modifiable);
747330f729Sjoerg }
757330f729Sjoerg 
767330f729Sjoerg /// Classify an expression which creates a temporary, based on its type.
ClassifyTemporary(QualType T)777330f729Sjoerg static Cl::Kinds ClassifyTemporary(QualType T) {
787330f729Sjoerg   if (T->isRecordType())
797330f729Sjoerg     return Cl::CL_ClassTemporary;
807330f729Sjoerg   if (T->isArrayType())
817330f729Sjoerg     return Cl::CL_ArrayTemporary;
827330f729Sjoerg 
837330f729Sjoerg   // No special classification: these don't behave differently from normal
847330f729Sjoerg   // prvalues.
857330f729Sjoerg   return Cl::CL_PRValue;
867330f729Sjoerg }
877330f729Sjoerg 
ClassifyExprValueKind(const LangOptions & Lang,const Expr * E,ExprValueKind Kind)887330f729Sjoerg static Cl::Kinds ClassifyExprValueKind(const LangOptions &Lang,
897330f729Sjoerg                                        const Expr *E,
907330f729Sjoerg                                        ExprValueKind Kind) {
917330f729Sjoerg   switch (Kind) {
927330f729Sjoerg   case VK_RValue:
937330f729Sjoerg     return Lang.CPlusPlus ? ClassifyTemporary(E->getType()) : Cl::CL_PRValue;
947330f729Sjoerg   case VK_LValue:
957330f729Sjoerg     return Cl::CL_LValue;
967330f729Sjoerg   case VK_XValue:
977330f729Sjoerg     return Cl::CL_XValue;
987330f729Sjoerg   }
997330f729Sjoerg   llvm_unreachable("Invalid value category of implicit cast.");
1007330f729Sjoerg }
1017330f729Sjoerg 
ClassifyInternal(ASTContext & Ctx,const Expr * E)1027330f729Sjoerg static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
1037330f729Sjoerg   // This function takes the first stab at classifying expressions.
1047330f729Sjoerg   const LangOptions &Lang = Ctx.getLangOpts();
1057330f729Sjoerg 
1067330f729Sjoerg   switch (E->getStmtClass()) {
1077330f729Sjoerg   case Stmt::NoStmtClass:
1087330f729Sjoerg #define ABSTRACT_STMT(Kind)
1097330f729Sjoerg #define STMT(Kind, Base) case Expr::Kind##Class:
1107330f729Sjoerg #define EXPR(Kind, Base)
1117330f729Sjoerg #include "clang/AST/StmtNodes.inc"
1127330f729Sjoerg     llvm_unreachable("cannot classify a statement");
1137330f729Sjoerg 
1147330f729Sjoerg     // First come the expressions that are always lvalues, unconditionally.
1157330f729Sjoerg   case Expr::ObjCIsaExprClass:
1167330f729Sjoerg     // C++ [expr.prim.general]p1: A string literal is an lvalue.
1177330f729Sjoerg   case Expr::StringLiteralClass:
1187330f729Sjoerg     // @encode is equivalent to its string
1197330f729Sjoerg   case Expr::ObjCEncodeExprClass:
1207330f729Sjoerg     // __func__ and friends are too.
1217330f729Sjoerg   case Expr::PredefinedExprClass:
1227330f729Sjoerg     // Property references are lvalues
1237330f729Sjoerg   case Expr::ObjCSubscriptRefExprClass:
1247330f729Sjoerg   case Expr::ObjCPropertyRefExprClass:
1257330f729Sjoerg     // C++ [expr.typeid]p1: The result of a typeid expression is an lvalue of...
1267330f729Sjoerg   case Expr::CXXTypeidExprClass:
127*e038c9c4Sjoerg   case Expr::CXXUuidofExprClass:
1287330f729Sjoerg     // Unresolved lookups and uncorrected typos get classified as lvalues.
1297330f729Sjoerg     // FIXME: Is this wise? Should they get their own kind?
1307330f729Sjoerg   case Expr::UnresolvedLookupExprClass:
1317330f729Sjoerg   case Expr::UnresolvedMemberExprClass:
1327330f729Sjoerg   case Expr::TypoExprClass:
1337330f729Sjoerg   case Expr::DependentCoawaitExprClass:
1347330f729Sjoerg   case Expr::CXXDependentScopeMemberExprClass:
1357330f729Sjoerg   case Expr::DependentScopeDeclRefExprClass:
1367330f729Sjoerg     // ObjC instance variables are lvalues
1377330f729Sjoerg     // FIXME: ObjC++0x might have different rules
1387330f729Sjoerg   case Expr::ObjCIvarRefExprClass:
1397330f729Sjoerg   case Expr::FunctionParmPackExprClass:
1407330f729Sjoerg   case Expr::MSPropertyRefExprClass:
1417330f729Sjoerg   case Expr::MSPropertySubscriptExprClass:
1427330f729Sjoerg   case Expr::OMPArraySectionExprClass:
143*e038c9c4Sjoerg   case Expr::OMPArrayShapingExprClass:
144*e038c9c4Sjoerg   case Expr::OMPIteratorExprClass:
1457330f729Sjoerg     return Cl::CL_LValue;
1467330f729Sjoerg 
1477330f729Sjoerg     // C99 6.5.2.5p5 says that compound literals are lvalues.
1487330f729Sjoerg     // In C++, they're prvalue temporaries, except for file-scope arrays.
1497330f729Sjoerg   case Expr::CompoundLiteralExprClass:
1507330f729Sjoerg     return !E->isLValue() ? ClassifyTemporary(E->getType()) : Cl::CL_LValue;
1517330f729Sjoerg 
1527330f729Sjoerg     // Expressions that are prvalues.
1537330f729Sjoerg   case Expr::CXXBoolLiteralExprClass:
1547330f729Sjoerg   case Expr::CXXPseudoDestructorExprClass:
1557330f729Sjoerg   case Expr::UnaryExprOrTypeTraitExprClass:
1567330f729Sjoerg   case Expr::CXXNewExprClass:
1577330f729Sjoerg   case Expr::CXXThisExprClass:
1587330f729Sjoerg   case Expr::CXXNullPtrLiteralExprClass:
1597330f729Sjoerg   case Expr::ImaginaryLiteralClass:
1607330f729Sjoerg   case Expr::GNUNullExprClass:
1617330f729Sjoerg   case Expr::OffsetOfExprClass:
1627330f729Sjoerg   case Expr::CXXThrowExprClass:
1637330f729Sjoerg   case Expr::ShuffleVectorExprClass:
1647330f729Sjoerg   case Expr::ConvertVectorExprClass:
1657330f729Sjoerg   case Expr::IntegerLiteralClass:
1667330f729Sjoerg   case Expr::FixedPointLiteralClass:
1677330f729Sjoerg   case Expr::CharacterLiteralClass:
1687330f729Sjoerg   case Expr::AddrLabelExprClass:
1697330f729Sjoerg   case Expr::CXXDeleteExprClass:
1707330f729Sjoerg   case Expr::ImplicitValueInitExprClass:
1717330f729Sjoerg   case Expr::BlockExprClass:
1727330f729Sjoerg   case Expr::FloatingLiteralClass:
1737330f729Sjoerg   case Expr::CXXNoexceptExprClass:
1747330f729Sjoerg   case Expr::CXXScalarValueInitExprClass:
1757330f729Sjoerg   case Expr::TypeTraitExprClass:
1767330f729Sjoerg   case Expr::ArrayTypeTraitExprClass:
1777330f729Sjoerg   case Expr::ExpressionTraitExprClass:
1787330f729Sjoerg   case Expr::ObjCSelectorExprClass:
1797330f729Sjoerg   case Expr::ObjCProtocolExprClass:
1807330f729Sjoerg   case Expr::ObjCStringLiteralClass:
1817330f729Sjoerg   case Expr::ObjCBoxedExprClass:
1827330f729Sjoerg   case Expr::ObjCArrayLiteralClass:
1837330f729Sjoerg   case Expr::ObjCDictionaryLiteralClass:
1847330f729Sjoerg   case Expr::ObjCBoolLiteralExprClass:
1857330f729Sjoerg   case Expr::ObjCAvailabilityCheckExprClass:
1867330f729Sjoerg   case Expr::ParenListExprClass:
1877330f729Sjoerg   case Expr::SizeOfPackExprClass:
1887330f729Sjoerg   case Expr::SubstNonTypeTemplateParmPackExprClass:
1897330f729Sjoerg   case Expr::AsTypeExprClass:
1907330f729Sjoerg   case Expr::ObjCIndirectCopyRestoreExprClass:
1917330f729Sjoerg   case Expr::AtomicExprClass:
1927330f729Sjoerg   case Expr::CXXFoldExprClass:
1937330f729Sjoerg   case Expr::ArrayInitLoopExprClass:
1947330f729Sjoerg   case Expr::ArrayInitIndexExprClass:
1957330f729Sjoerg   case Expr::NoInitExprClass:
1967330f729Sjoerg   case Expr::DesignatedInitUpdateExprClass:
1977330f729Sjoerg   case Expr::SourceLocExprClass:
1987330f729Sjoerg   case Expr::ConceptSpecializationExprClass:
199*e038c9c4Sjoerg   case Expr::RequiresExprClass:
2007330f729Sjoerg     return Cl::CL_PRValue;
2017330f729Sjoerg 
2027330f729Sjoerg   case Expr::ConstantExprClass:
2037330f729Sjoerg     return ClassifyInternal(Ctx, cast<ConstantExpr>(E)->getSubExpr());
2047330f729Sjoerg 
2057330f729Sjoerg     // Next come the complicated cases.
2067330f729Sjoerg   case Expr::SubstNonTypeTemplateParmExprClass:
2077330f729Sjoerg     return ClassifyInternal(Ctx,
2087330f729Sjoerg                  cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement());
2097330f729Sjoerg 
2107330f729Sjoerg     // C, C++98 [expr.sub]p1: The result is an lvalue of type "T".
2117330f729Sjoerg     // C++11 (DR1213): in the case of an array operand, the result is an lvalue
2127330f729Sjoerg     //                 if that operand is an lvalue and an xvalue otherwise.
2137330f729Sjoerg     // Subscripting vector types is more like member access.
2147330f729Sjoerg   case Expr::ArraySubscriptExprClass:
2157330f729Sjoerg     if (cast<ArraySubscriptExpr>(E)->getBase()->getType()->isVectorType())
2167330f729Sjoerg       return ClassifyInternal(Ctx, cast<ArraySubscriptExpr>(E)->getBase());
2177330f729Sjoerg     if (Lang.CPlusPlus11) {
2187330f729Sjoerg       // Step over the array-to-pointer decay if present, but not over the
2197330f729Sjoerg       // temporary materialization.
2207330f729Sjoerg       auto *Base = cast<ArraySubscriptExpr>(E)->getBase()->IgnoreImpCasts();
2217330f729Sjoerg       if (Base->getType()->isArrayType())
2227330f729Sjoerg         return ClassifyInternal(Ctx, Base);
2237330f729Sjoerg     }
2247330f729Sjoerg     return Cl::CL_LValue;
2257330f729Sjoerg 
226*e038c9c4Sjoerg   // Subscripting matrix types behaves like member accesses.
227*e038c9c4Sjoerg   case Expr::MatrixSubscriptExprClass:
228*e038c9c4Sjoerg     return ClassifyInternal(Ctx, cast<MatrixSubscriptExpr>(E)->getBase());
229*e038c9c4Sjoerg 
2307330f729Sjoerg     // C++ [expr.prim.general]p3: The result is an lvalue if the entity is a
2317330f729Sjoerg     //   function or variable and a prvalue otherwise.
2327330f729Sjoerg   case Expr::DeclRefExprClass:
2337330f729Sjoerg     if (E->getType() == Ctx.UnknownAnyTy)
2347330f729Sjoerg       return isa<FunctionDecl>(cast<DeclRefExpr>(E)->getDecl())
2357330f729Sjoerg                ? Cl::CL_PRValue : Cl::CL_LValue;
2367330f729Sjoerg     return ClassifyDecl(Ctx, cast<DeclRefExpr>(E)->getDecl());
2377330f729Sjoerg 
2387330f729Sjoerg     // Member access is complex.
2397330f729Sjoerg   case Expr::MemberExprClass:
2407330f729Sjoerg     return ClassifyMemberExpr(Ctx, cast<MemberExpr>(E));
2417330f729Sjoerg 
2427330f729Sjoerg   case Expr::UnaryOperatorClass:
2437330f729Sjoerg     switch (cast<UnaryOperator>(E)->getOpcode()) {
2447330f729Sjoerg       // C++ [expr.unary.op]p1: The unary * operator performs indirection:
2457330f729Sjoerg       //   [...] the result is an lvalue referring to the object or function
2467330f729Sjoerg       //   to which the expression points.
2477330f729Sjoerg     case UO_Deref:
2487330f729Sjoerg       return Cl::CL_LValue;
2497330f729Sjoerg 
2507330f729Sjoerg       // GNU extensions, simply look through them.
2517330f729Sjoerg     case UO_Extension:
2527330f729Sjoerg       return ClassifyInternal(Ctx, cast<UnaryOperator>(E)->getSubExpr());
2537330f729Sjoerg 
2547330f729Sjoerg     // Treat _Real and _Imag basically as if they were member
2557330f729Sjoerg     // expressions:  l-value only if the operand is a true l-value.
2567330f729Sjoerg     case UO_Real:
2577330f729Sjoerg     case UO_Imag: {
2587330f729Sjoerg       const Expr *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
2597330f729Sjoerg       Cl::Kinds K = ClassifyInternal(Ctx, Op);
2607330f729Sjoerg       if (K != Cl::CL_LValue) return K;
2617330f729Sjoerg 
2627330f729Sjoerg       if (isa<ObjCPropertyRefExpr>(Op))
2637330f729Sjoerg         return Cl::CL_SubObjCPropertySetting;
2647330f729Sjoerg       return Cl::CL_LValue;
2657330f729Sjoerg     }
2667330f729Sjoerg 
2677330f729Sjoerg       // C++ [expr.pre.incr]p1: The result is the updated operand; it is an
2687330f729Sjoerg       //   lvalue, [...]
2697330f729Sjoerg       // Not so in C.
2707330f729Sjoerg     case UO_PreInc:
2717330f729Sjoerg     case UO_PreDec:
2727330f729Sjoerg       return Lang.CPlusPlus ? Cl::CL_LValue : Cl::CL_PRValue;
2737330f729Sjoerg 
2747330f729Sjoerg     default:
2757330f729Sjoerg       return Cl::CL_PRValue;
2767330f729Sjoerg     }
2777330f729Sjoerg 
278*e038c9c4Sjoerg   case Expr::RecoveryExprClass:
2797330f729Sjoerg   case Expr::OpaqueValueExprClass:
2807330f729Sjoerg     return ClassifyExprValueKind(Lang, E, E->getValueKind());
2817330f729Sjoerg 
2827330f729Sjoerg     // Pseudo-object expressions can produce l-values with reference magic.
2837330f729Sjoerg   case Expr::PseudoObjectExprClass:
2847330f729Sjoerg     return ClassifyExprValueKind(Lang, E,
2857330f729Sjoerg                                  cast<PseudoObjectExpr>(E)->getValueKind());
2867330f729Sjoerg 
2877330f729Sjoerg     // Implicit casts are lvalues if they're lvalue casts. Other than that, we
2887330f729Sjoerg     // only specifically record class temporaries.
2897330f729Sjoerg   case Expr::ImplicitCastExprClass:
2907330f729Sjoerg     return ClassifyExprValueKind(Lang, E, E->getValueKind());
2917330f729Sjoerg 
2927330f729Sjoerg     // C++ [expr.prim.general]p4: The presence of parentheses does not affect
2937330f729Sjoerg     //   whether the expression is an lvalue.
2947330f729Sjoerg   case Expr::ParenExprClass:
2957330f729Sjoerg     return ClassifyInternal(Ctx, cast<ParenExpr>(E)->getSubExpr());
2967330f729Sjoerg 
2977330f729Sjoerg     // C11 6.5.1.1p4: [A generic selection] is an lvalue, a function designator,
2987330f729Sjoerg     // or a void expression if its result expression is, respectively, an
2997330f729Sjoerg     // lvalue, a function designator, or a void expression.
3007330f729Sjoerg   case Expr::GenericSelectionExprClass:
3017330f729Sjoerg     if (cast<GenericSelectionExpr>(E)->isResultDependent())
3027330f729Sjoerg       return Cl::CL_PRValue;
3037330f729Sjoerg     return ClassifyInternal(Ctx,cast<GenericSelectionExpr>(E)->getResultExpr());
3047330f729Sjoerg 
3057330f729Sjoerg   case Expr::BinaryOperatorClass:
3067330f729Sjoerg   case Expr::CompoundAssignOperatorClass:
3077330f729Sjoerg     // C doesn't have any binary expressions that are lvalues.
3087330f729Sjoerg     if (Lang.CPlusPlus)
3097330f729Sjoerg       return ClassifyBinaryOp(Ctx, cast<BinaryOperator>(E));
3107330f729Sjoerg     return Cl::CL_PRValue;
3117330f729Sjoerg 
3127330f729Sjoerg   case Expr::CallExprClass:
3137330f729Sjoerg   case Expr::CXXOperatorCallExprClass:
3147330f729Sjoerg   case Expr::CXXMemberCallExprClass:
3157330f729Sjoerg   case Expr::UserDefinedLiteralClass:
3167330f729Sjoerg   case Expr::CUDAKernelCallExprClass:
3177330f729Sjoerg     return ClassifyUnnamed(Ctx, cast<CallExpr>(E)->getCallReturnType(Ctx));
3187330f729Sjoerg 
3197330f729Sjoerg   case Expr::CXXRewrittenBinaryOperatorClass:
3207330f729Sjoerg     return ClassifyInternal(
3217330f729Sjoerg         Ctx, cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm());
3227330f729Sjoerg 
3237330f729Sjoerg     // __builtin_choose_expr is equivalent to the chosen expression.
3247330f729Sjoerg   case Expr::ChooseExprClass:
3257330f729Sjoerg     return ClassifyInternal(Ctx, cast<ChooseExpr>(E)->getChosenSubExpr());
3267330f729Sjoerg 
3277330f729Sjoerg     // Extended vector element access is an lvalue unless there are duplicates
3287330f729Sjoerg     // in the shuffle expression.
3297330f729Sjoerg   case Expr::ExtVectorElementExprClass:
3307330f729Sjoerg     if (cast<ExtVectorElementExpr>(E)->containsDuplicateElements())
3317330f729Sjoerg       return Cl::CL_DuplicateVectorComponents;
3327330f729Sjoerg     if (cast<ExtVectorElementExpr>(E)->isArrow())
3337330f729Sjoerg       return Cl::CL_LValue;
3347330f729Sjoerg     return ClassifyInternal(Ctx, cast<ExtVectorElementExpr>(E)->getBase());
3357330f729Sjoerg 
3367330f729Sjoerg     // Simply look at the actual default argument.
3377330f729Sjoerg   case Expr::CXXDefaultArgExprClass:
3387330f729Sjoerg     return ClassifyInternal(Ctx, cast<CXXDefaultArgExpr>(E)->getExpr());
3397330f729Sjoerg 
3407330f729Sjoerg     // Same idea for default initializers.
3417330f729Sjoerg   case Expr::CXXDefaultInitExprClass:
3427330f729Sjoerg     return ClassifyInternal(Ctx, cast<CXXDefaultInitExpr>(E)->getExpr());
3437330f729Sjoerg 
3447330f729Sjoerg     // Same idea for temporary binding.
3457330f729Sjoerg   case Expr::CXXBindTemporaryExprClass:
3467330f729Sjoerg     return ClassifyInternal(Ctx, cast<CXXBindTemporaryExpr>(E)->getSubExpr());
3477330f729Sjoerg 
3487330f729Sjoerg     // And the cleanups guard.
3497330f729Sjoerg   case Expr::ExprWithCleanupsClass:
3507330f729Sjoerg     return ClassifyInternal(Ctx, cast<ExprWithCleanups>(E)->getSubExpr());
3517330f729Sjoerg 
3527330f729Sjoerg     // Casts depend completely on the target type. All casts work the same.
3537330f729Sjoerg   case Expr::CStyleCastExprClass:
3547330f729Sjoerg   case Expr::CXXFunctionalCastExprClass:
3557330f729Sjoerg   case Expr::CXXStaticCastExprClass:
3567330f729Sjoerg   case Expr::CXXDynamicCastExprClass:
3577330f729Sjoerg   case Expr::CXXReinterpretCastExprClass:
3587330f729Sjoerg   case Expr::CXXConstCastExprClass:
359*e038c9c4Sjoerg   case Expr::CXXAddrspaceCastExprClass:
3607330f729Sjoerg   case Expr::ObjCBridgedCastExprClass:
3617330f729Sjoerg   case Expr::BuiltinBitCastExprClass:
3627330f729Sjoerg     // Only in C++ can casts be interesting at all.
3637330f729Sjoerg     if (!Lang.CPlusPlus) return Cl::CL_PRValue;
3647330f729Sjoerg     return ClassifyUnnamed(Ctx, cast<ExplicitCastExpr>(E)->getTypeAsWritten());
3657330f729Sjoerg 
3667330f729Sjoerg   case Expr::CXXUnresolvedConstructExprClass:
3677330f729Sjoerg     return ClassifyUnnamed(Ctx,
3687330f729Sjoerg                       cast<CXXUnresolvedConstructExpr>(E)->getTypeAsWritten());
3697330f729Sjoerg 
3707330f729Sjoerg   case Expr::BinaryConditionalOperatorClass: {
3717330f729Sjoerg     if (!Lang.CPlusPlus) return Cl::CL_PRValue;
3727330f729Sjoerg     const auto *co = cast<BinaryConditionalOperator>(E);
3737330f729Sjoerg     return ClassifyConditional(Ctx, co->getTrueExpr(), co->getFalseExpr());
3747330f729Sjoerg   }
3757330f729Sjoerg 
3767330f729Sjoerg   case Expr::ConditionalOperatorClass: {
3777330f729Sjoerg     // Once again, only C++ is interesting.
3787330f729Sjoerg     if (!Lang.CPlusPlus) return Cl::CL_PRValue;
3797330f729Sjoerg     const auto *co = cast<ConditionalOperator>(E);
3807330f729Sjoerg     return ClassifyConditional(Ctx, co->getTrueExpr(), co->getFalseExpr());
3817330f729Sjoerg   }
3827330f729Sjoerg 
3837330f729Sjoerg     // ObjC message sends are effectively function calls, if the target function
3847330f729Sjoerg     // is known.
3857330f729Sjoerg   case Expr::ObjCMessageExprClass:
3867330f729Sjoerg     if (const ObjCMethodDecl *Method =
3877330f729Sjoerg           cast<ObjCMessageExpr>(E)->getMethodDecl()) {
3887330f729Sjoerg       Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getReturnType());
3897330f729Sjoerg       return (kind == Cl::CL_PRValue) ? Cl::CL_ObjCMessageRValue : kind;
3907330f729Sjoerg     }
3917330f729Sjoerg     return Cl::CL_PRValue;
3927330f729Sjoerg 
3937330f729Sjoerg     // Some C++ expressions are always class temporaries.
3947330f729Sjoerg   case Expr::CXXConstructExprClass:
3957330f729Sjoerg   case Expr::CXXInheritedCtorInitExprClass:
3967330f729Sjoerg   case Expr::CXXTemporaryObjectExprClass:
3977330f729Sjoerg   case Expr::LambdaExprClass:
3987330f729Sjoerg   case Expr::CXXStdInitializerListExprClass:
3997330f729Sjoerg     return Cl::CL_ClassTemporary;
4007330f729Sjoerg 
4017330f729Sjoerg   case Expr::VAArgExprClass:
4027330f729Sjoerg     return ClassifyUnnamed(Ctx, E->getType());
4037330f729Sjoerg 
4047330f729Sjoerg   case Expr::DesignatedInitExprClass:
4057330f729Sjoerg     return ClassifyInternal(Ctx, cast<DesignatedInitExpr>(E)->getInit());
4067330f729Sjoerg 
4077330f729Sjoerg   case Expr::StmtExprClass: {
4087330f729Sjoerg     const CompoundStmt *S = cast<StmtExpr>(E)->getSubStmt();
4097330f729Sjoerg     if (const auto *LastExpr = dyn_cast_or_null<Expr>(S->body_back()))
4107330f729Sjoerg       return ClassifyUnnamed(Ctx, LastExpr->getType());
4117330f729Sjoerg     return Cl::CL_PRValue;
4127330f729Sjoerg   }
4137330f729Sjoerg 
4147330f729Sjoerg   case Expr::PackExpansionExprClass:
4157330f729Sjoerg     return ClassifyInternal(Ctx, cast<PackExpansionExpr>(E)->getPattern());
4167330f729Sjoerg 
4177330f729Sjoerg   case Expr::MaterializeTemporaryExprClass:
4187330f729Sjoerg     return cast<MaterializeTemporaryExpr>(E)->isBoundToLvalueReference()
4197330f729Sjoerg               ? Cl::CL_LValue
4207330f729Sjoerg               : Cl::CL_XValue;
4217330f729Sjoerg 
4227330f729Sjoerg   case Expr::InitListExprClass:
4237330f729Sjoerg     // An init list can be an lvalue if it is bound to a reference and
4247330f729Sjoerg     // contains only one element. In that case, we look at that element
4257330f729Sjoerg     // for an exact classification. Init list creation takes care of the
4267330f729Sjoerg     // value kind for us, so we only need to fine-tune.
4277330f729Sjoerg     if (E->isRValue())
4287330f729Sjoerg       return ClassifyExprValueKind(Lang, E, E->getValueKind());
4297330f729Sjoerg     assert(cast<InitListExpr>(E)->getNumInits() == 1 &&
4307330f729Sjoerg            "Only 1-element init lists can be glvalues.");
4317330f729Sjoerg     return ClassifyInternal(Ctx, cast<InitListExpr>(E)->getInit(0));
4327330f729Sjoerg 
4337330f729Sjoerg   case Expr::CoawaitExprClass:
4347330f729Sjoerg   case Expr::CoyieldExprClass:
4357330f729Sjoerg     return ClassifyInternal(Ctx, cast<CoroutineSuspendExpr>(E)->getResumeExpr());
4367330f729Sjoerg   }
4377330f729Sjoerg 
4387330f729Sjoerg   llvm_unreachable("unhandled expression kind in classification");
4397330f729Sjoerg }
4407330f729Sjoerg 
4417330f729Sjoerg /// ClassifyDecl - Return the classification of an expression referencing the
4427330f729Sjoerg /// given declaration.
ClassifyDecl(ASTContext & Ctx,const Decl * D)4437330f729Sjoerg static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D) {
4447330f729Sjoerg   // C++ [expr.prim.general]p6: The result is an lvalue if the entity is a
4457330f729Sjoerg   //   function, variable, or data member and a prvalue otherwise.
4467330f729Sjoerg   // In C, functions are not lvalues.
4477330f729Sjoerg   // In addition, NonTypeTemplateParmDecl derives from VarDecl but isn't an
4487330f729Sjoerg   // lvalue unless it's a reference type (C++ [temp.param]p6), so we need to
4497330f729Sjoerg   // special-case this.
4507330f729Sjoerg 
4517330f729Sjoerg   if (isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance())
4527330f729Sjoerg     return Cl::CL_MemberFunction;
4537330f729Sjoerg 
4547330f729Sjoerg   bool islvalue;
4557330f729Sjoerg   if (const auto *NTTParm = dyn_cast<NonTypeTemplateParmDecl>(D))
456*e038c9c4Sjoerg     islvalue = NTTParm->getType()->isReferenceType() ||
457*e038c9c4Sjoerg                NTTParm->getType()->isRecordType();
4587330f729Sjoerg   else
4597330f729Sjoerg     islvalue = isa<VarDecl>(D) || isa<FieldDecl>(D) ||
4607330f729Sjoerg                isa<IndirectFieldDecl>(D) ||
4617330f729Sjoerg                isa<BindingDecl>(D) ||
462*e038c9c4Sjoerg                isa<MSGuidDecl>(D) ||
463*e038c9c4Sjoerg                isa<TemplateParamObjectDecl>(D) ||
4647330f729Sjoerg                (Ctx.getLangOpts().CPlusPlus &&
4657330f729Sjoerg                 (isa<FunctionDecl>(D) || isa<MSPropertyDecl>(D) ||
4667330f729Sjoerg                  isa<FunctionTemplateDecl>(D)));
4677330f729Sjoerg 
4687330f729Sjoerg   return islvalue ? Cl::CL_LValue : Cl::CL_PRValue;
4697330f729Sjoerg }
4707330f729Sjoerg 
4717330f729Sjoerg /// ClassifyUnnamed - Return the classification of an expression yielding an
4727330f729Sjoerg /// unnamed value of the given type. This applies in particular to function
4737330f729Sjoerg /// calls and casts.
ClassifyUnnamed(ASTContext & Ctx,QualType T)4747330f729Sjoerg static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T) {
4757330f729Sjoerg   // In C, function calls are always rvalues.
4767330f729Sjoerg   if (!Ctx.getLangOpts().CPlusPlus) return Cl::CL_PRValue;
4777330f729Sjoerg 
4787330f729Sjoerg   // C++ [expr.call]p10: A function call is an lvalue if the result type is an
4797330f729Sjoerg   //   lvalue reference type or an rvalue reference to function type, an xvalue
4807330f729Sjoerg   //   if the result type is an rvalue reference to object type, and a prvalue
4817330f729Sjoerg   //   otherwise.
4827330f729Sjoerg   if (T->isLValueReferenceType())
4837330f729Sjoerg     return Cl::CL_LValue;
4847330f729Sjoerg   const auto *RV = T->getAs<RValueReferenceType>();
4857330f729Sjoerg   if (!RV) // Could still be a class temporary, though.
4867330f729Sjoerg     return ClassifyTemporary(T);
4877330f729Sjoerg 
4887330f729Sjoerg   return RV->getPointeeType()->isFunctionType() ? Cl::CL_LValue : Cl::CL_XValue;
4897330f729Sjoerg }
4907330f729Sjoerg 
ClassifyMemberExpr(ASTContext & Ctx,const MemberExpr * E)4917330f729Sjoerg static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E) {
4927330f729Sjoerg   if (E->getType() == Ctx.UnknownAnyTy)
4937330f729Sjoerg     return (isa<FunctionDecl>(E->getMemberDecl())
4947330f729Sjoerg               ? Cl::CL_PRValue : Cl::CL_LValue);
4957330f729Sjoerg 
4967330f729Sjoerg   // Handle C first, it's easier.
4977330f729Sjoerg   if (!Ctx.getLangOpts().CPlusPlus) {
4987330f729Sjoerg     // C99 6.5.2.3p3
4997330f729Sjoerg     // For dot access, the expression is an lvalue if the first part is. For
5007330f729Sjoerg     // arrow access, it always is an lvalue.
5017330f729Sjoerg     if (E->isArrow())
5027330f729Sjoerg       return Cl::CL_LValue;
5037330f729Sjoerg     // ObjC property accesses are not lvalues, but get special treatment.
5047330f729Sjoerg     Expr *Base = E->getBase()->IgnoreParens();
5057330f729Sjoerg     if (isa<ObjCPropertyRefExpr>(Base))
5067330f729Sjoerg       return Cl::CL_SubObjCPropertySetting;
5077330f729Sjoerg     return ClassifyInternal(Ctx, Base);
5087330f729Sjoerg   }
5097330f729Sjoerg 
5107330f729Sjoerg   NamedDecl *Member = E->getMemberDecl();
5117330f729Sjoerg   // C++ [expr.ref]p3: E1->E2 is converted to the equivalent form (*(E1)).E2.
5127330f729Sjoerg   // C++ [expr.ref]p4: If E2 is declared to have type "reference to T", then
5137330f729Sjoerg   //   E1.E2 is an lvalue.
5147330f729Sjoerg   if (const auto *Value = dyn_cast<ValueDecl>(Member))
5157330f729Sjoerg     if (Value->getType()->isReferenceType())
5167330f729Sjoerg       return Cl::CL_LValue;
5177330f729Sjoerg 
5187330f729Sjoerg   //   Otherwise, one of the following rules applies.
5197330f729Sjoerg   //   -- If E2 is a static member [...] then E1.E2 is an lvalue.
5207330f729Sjoerg   if (isa<VarDecl>(Member) && Member->getDeclContext()->isRecord())
5217330f729Sjoerg     return Cl::CL_LValue;
5227330f729Sjoerg 
5237330f729Sjoerg   //   -- If E2 is a non-static data member [...]. If E1 is an lvalue, then
5247330f729Sjoerg   //      E1.E2 is an lvalue; if E1 is an xvalue, then E1.E2 is an xvalue;
5257330f729Sjoerg   //      otherwise, it is a prvalue.
5267330f729Sjoerg   if (isa<FieldDecl>(Member)) {
5277330f729Sjoerg     // *E1 is an lvalue
5287330f729Sjoerg     if (E->isArrow())
5297330f729Sjoerg       return Cl::CL_LValue;
5307330f729Sjoerg     Expr *Base = E->getBase()->IgnoreParenImpCasts();
5317330f729Sjoerg     if (isa<ObjCPropertyRefExpr>(Base))
5327330f729Sjoerg       return Cl::CL_SubObjCPropertySetting;
5337330f729Sjoerg     return ClassifyInternal(Ctx, E->getBase());
5347330f729Sjoerg   }
5357330f729Sjoerg 
5367330f729Sjoerg   //   -- If E2 is a [...] member function, [...]
5377330f729Sjoerg   //      -- If it refers to a static member function [...], then E1.E2 is an
5387330f729Sjoerg   //         lvalue; [...]
5397330f729Sjoerg   //      -- Otherwise [...] E1.E2 is a prvalue.
5407330f729Sjoerg   if (const auto *Method = dyn_cast<CXXMethodDecl>(Member))
5417330f729Sjoerg     return Method->isStatic() ? Cl::CL_LValue : Cl::CL_MemberFunction;
5427330f729Sjoerg 
5437330f729Sjoerg   //   -- If E2 is a member enumerator [...], the expression E1.E2 is a prvalue.
5447330f729Sjoerg   // So is everything else we haven't handled yet.
5457330f729Sjoerg   return Cl::CL_PRValue;
5467330f729Sjoerg }
5477330f729Sjoerg 
ClassifyBinaryOp(ASTContext & Ctx,const BinaryOperator * E)5487330f729Sjoerg static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E) {
5497330f729Sjoerg   assert(Ctx.getLangOpts().CPlusPlus &&
5507330f729Sjoerg          "This is only relevant for C++.");
5517330f729Sjoerg   // C++ [expr.ass]p1: All [...] return an lvalue referring to the left operand.
5527330f729Sjoerg   // Except we override this for writes to ObjC properties.
5537330f729Sjoerg   if (E->isAssignmentOp())
5547330f729Sjoerg     return (E->getLHS()->getObjectKind() == OK_ObjCProperty
5557330f729Sjoerg               ? Cl::CL_PRValue : Cl::CL_LValue);
5567330f729Sjoerg 
5577330f729Sjoerg   // C++ [expr.comma]p1: the result is of the same value category as its right
5587330f729Sjoerg   //   operand, [...].
5597330f729Sjoerg   if (E->getOpcode() == BO_Comma)
5607330f729Sjoerg     return ClassifyInternal(Ctx, E->getRHS());
5617330f729Sjoerg 
5627330f729Sjoerg   // C++ [expr.mptr.oper]p6: The result of a .* expression whose second operand
5637330f729Sjoerg   //   is a pointer to a data member is of the same value category as its first
5647330f729Sjoerg   //   operand.
5657330f729Sjoerg   if (E->getOpcode() == BO_PtrMemD)
5667330f729Sjoerg     return (E->getType()->isFunctionType() ||
5677330f729Sjoerg             E->hasPlaceholderType(BuiltinType::BoundMember))
5687330f729Sjoerg              ? Cl::CL_MemberFunction
5697330f729Sjoerg              : ClassifyInternal(Ctx, E->getLHS());
5707330f729Sjoerg 
5717330f729Sjoerg   // C++ [expr.mptr.oper]p6: The result of an ->* expression is an lvalue if its
5727330f729Sjoerg   //   second operand is a pointer to data member and a prvalue otherwise.
5737330f729Sjoerg   if (E->getOpcode() == BO_PtrMemI)
5747330f729Sjoerg     return (E->getType()->isFunctionType() ||
5757330f729Sjoerg             E->hasPlaceholderType(BuiltinType::BoundMember))
5767330f729Sjoerg              ? Cl::CL_MemberFunction
5777330f729Sjoerg              : Cl::CL_LValue;
5787330f729Sjoerg 
5797330f729Sjoerg   // All other binary operations are prvalues.
5807330f729Sjoerg   return Cl::CL_PRValue;
5817330f729Sjoerg }
5827330f729Sjoerg 
ClassifyConditional(ASTContext & Ctx,const Expr * True,const Expr * False)5837330f729Sjoerg static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *True,
5847330f729Sjoerg                                      const Expr *False) {
5857330f729Sjoerg   assert(Ctx.getLangOpts().CPlusPlus &&
5867330f729Sjoerg          "This is only relevant for C++.");
5877330f729Sjoerg 
5887330f729Sjoerg   // C++ [expr.cond]p2
5897330f729Sjoerg   //   If either the second or the third operand has type (cv) void,
5907330f729Sjoerg   //   one of the following shall hold:
5917330f729Sjoerg   if (True->getType()->isVoidType() || False->getType()->isVoidType()) {
5927330f729Sjoerg     // The second or the third operand (but not both) is a (possibly
5937330f729Sjoerg     // parenthesized) throw-expression; the result is of the [...] value
5947330f729Sjoerg     // category of the other.
5957330f729Sjoerg     bool TrueIsThrow = isa<CXXThrowExpr>(True->IgnoreParenImpCasts());
5967330f729Sjoerg     bool FalseIsThrow = isa<CXXThrowExpr>(False->IgnoreParenImpCasts());
5977330f729Sjoerg     if (const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ? nullptr : False)
5987330f729Sjoerg                                            : (FalseIsThrow ? True : nullptr))
5997330f729Sjoerg       return ClassifyInternal(Ctx, NonThrow);
6007330f729Sjoerg 
6017330f729Sjoerg     //   [Otherwise] the result [...] is a prvalue.
6027330f729Sjoerg     return Cl::CL_PRValue;
6037330f729Sjoerg   }
6047330f729Sjoerg 
6057330f729Sjoerg   // Note that at this point, we have already performed all conversions
6067330f729Sjoerg   // according to [expr.cond]p3.
6077330f729Sjoerg   // C++ [expr.cond]p4: If the second and third operands are glvalues of the
6087330f729Sjoerg   //   same value category [...], the result is of that [...] value category.
6097330f729Sjoerg   // C++ [expr.cond]p5: Otherwise, the result is a prvalue.
6107330f729Sjoerg   Cl::Kinds LCl = ClassifyInternal(Ctx, True),
6117330f729Sjoerg             RCl = ClassifyInternal(Ctx, False);
6127330f729Sjoerg   return LCl == RCl ? LCl : Cl::CL_PRValue;
6137330f729Sjoerg }
6147330f729Sjoerg 
IsModifiable(ASTContext & Ctx,const Expr * E,Cl::Kinds Kind,SourceLocation & Loc)6157330f729Sjoerg static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
6167330f729Sjoerg                                        Cl::Kinds Kind, SourceLocation &Loc) {
6177330f729Sjoerg   // As a general rule, we only care about lvalues. But there are some rvalues
6187330f729Sjoerg   // for which we want to generate special results.
6197330f729Sjoerg   if (Kind == Cl::CL_PRValue) {
6207330f729Sjoerg     // For the sake of better diagnostics, we want to specifically recognize
6217330f729Sjoerg     // use of the GCC cast-as-lvalue extension.
6227330f729Sjoerg     if (const auto *CE = dyn_cast<ExplicitCastExpr>(E->IgnoreParens())) {
6237330f729Sjoerg       if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) {
6247330f729Sjoerg         Loc = CE->getExprLoc();
6257330f729Sjoerg         return Cl::CM_LValueCast;
6267330f729Sjoerg       }
6277330f729Sjoerg     }
6287330f729Sjoerg   }
6297330f729Sjoerg   if (Kind != Cl::CL_LValue)
6307330f729Sjoerg     return Cl::CM_RValue;
6317330f729Sjoerg 
6327330f729Sjoerg   // This is the lvalue case.
6337330f729Sjoerg   // Functions are lvalues in C++, but not modifiable. (C++ [basic.lval]p6)
6347330f729Sjoerg   if (Ctx.getLangOpts().CPlusPlus && E->getType()->isFunctionType())
6357330f729Sjoerg     return Cl::CM_Function;
6367330f729Sjoerg 
6377330f729Sjoerg   // Assignment to a property in ObjC is an implicit setter access. But a
6387330f729Sjoerg   // setter might not exist.
6397330f729Sjoerg   if (const auto *Expr = dyn_cast<ObjCPropertyRefExpr>(E)) {
6407330f729Sjoerg     if (Expr->isImplicitProperty() &&
6417330f729Sjoerg         Expr->getImplicitPropertySetter() == nullptr)
6427330f729Sjoerg       return Cl::CM_NoSetterProperty;
6437330f729Sjoerg   }
6447330f729Sjoerg 
6457330f729Sjoerg   CanQualType CT = Ctx.getCanonicalType(E->getType());
6467330f729Sjoerg   // Const stuff is obviously not modifiable.
6477330f729Sjoerg   if (CT.isConstQualified())
6487330f729Sjoerg     return Cl::CM_ConstQualified;
6497330f729Sjoerg   if (Ctx.getLangOpts().OpenCL &&
6507330f729Sjoerg       CT.getQualifiers().getAddressSpace() == LangAS::opencl_constant)
6517330f729Sjoerg     return Cl::CM_ConstAddrSpace;
6527330f729Sjoerg 
6537330f729Sjoerg   // Arrays are not modifiable, only their elements are.
6547330f729Sjoerg   if (CT->isArrayType())
6557330f729Sjoerg     return Cl::CM_ArrayType;
6567330f729Sjoerg   // Incomplete types are not modifiable.
6577330f729Sjoerg   if (CT->isIncompleteType())
6587330f729Sjoerg     return Cl::CM_IncompleteType;
6597330f729Sjoerg 
6607330f729Sjoerg   // Records with any const fields (recursively) are not modifiable.
6617330f729Sjoerg   if (const RecordType *R = CT->getAs<RecordType>())
6627330f729Sjoerg     if (R->hasConstFields())
6637330f729Sjoerg       return Cl::CM_ConstQualifiedField;
6647330f729Sjoerg 
6657330f729Sjoerg   return Cl::CM_Modifiable;
6667330f729Sjoerg }
6677330f729Sjoerg 
ClassifyLValue(ASTContext & Ctx) const6687330f729Sjoerg Expr::LValueClassification Expr::ClassifyLValue(ASTContext &Ctx) const {
6697330f729Sjoerg   Classification VC = Classify(Ctx);
6707330f729Sjoerg   switch (VC.getKind()) {
6717330f729Sjoerg   case Cl::CL_LValue: return LV_Valid;
6727330f729Sjoerg   case Cl::CL_XValue: return LV_InvalidExpression;
6737330f729Sjoerg   case Cl::CL_Function: return LV_NotObjectType;
6747330f729Sjoerg   case Cl::CL_Void: return LV_InvalidExpression;
6757330f729Sjoerg   case Cl::CL_AddressableVoid: return LV_IncompleteVoidType;
6767330f729Sjoerg   case Cl::CL_DuplicateVectorComponents: return LV_DuplicateVectorComponents;
6777330f729Sjoerg   case Cl::CL_MemberFunction: return LV_MemberFunction;
6787330f729Sjoerg   case Cl::CL_SubObjCPropertySetting: return LV_SubObjCPropertySetting;
6797330f729Sjoerg   case Cl::CL_ClassTemporary: return LV_ClassTemporary;
6807330f729Sjoerg   case Cl::CL_ArrayTemporary: return LV_ArrayTemporary;
6817330f729Sjoerg   case Cl::CL_ObjCMessageRValue: return LV_InvalidMessageExpression;
6827330f729Sjoerg   case Cl::CL_PRValue: return LV_InvalidExpression;
6837330f729Sjoerg   }
6847330f729Sjoerg   llvm_unreachable("Unhandled kind");
6857330f729Sjoerg }
6867330f729Sjoerg 
6877330f729Sjoerg Expr::isModifiableLvalueResult
isModifiableLvalue(ASTContext & Ctx,SourceLocation * Loc) const6887330f729Sjoerg Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const {
6897330f729Sjoerg   SourceLocation dummy;
6907330f729Sjoerg   Classification VC = ClassifyModifiable(Ctx, Loc ? *Loc : dummy);
6917330f729Sjoerg   switch (VC.getKind()) {
6927330f729Sjoerg   case Cl::CL_LValue: break;
6937330f729Sjoerg   case Cl::CL_XValue: return MLV_InvalidExpression;
6947330f729Sjoerg   case Cl::CL_Function: return MLV_NotObjectType;
6957330f729Sjoerg   case Cl::CL_Void: return MLV_InvalidExpression;
6967330f729Sjoerg   case Cl::CL_AddressableVoid: return MLV_IncompleteVoidType;
6977330f729Sjoerg   case Cl::CL_DuplicateVectorComponents: return MLV_DuplicateVectorComponents;
6987330f729Sjoerg   case Cl::CL_MemberFunction: return MLV_MemberFunction;
6997330f729Sjoerg   case Cl::CL_SubObjCPropertySetting: return MLV_SubObjCPropertySetting;
7007330f729Sjoerg   case Cl::CL_ClassTemporary: return MLV_ClassTemporary;
7017330f729Sjoerg   case Cl::CL_ArrayTemporary: return MLV_ArrayTemporary;
7027330f729Sjoerg   case Cl::CL_ObjCMessageRValue: return MLV_InvalidMessageExpression;
7037330f729Sjoerg   case Cl::CL_PRValue:
7047330f729Sjoerg     return VC.getModifiable() == Cl::CM_LValueCast ?
7057330f729Sjoerg       MLV_LValueCast : MLV_InvalidExpression;
7067330f729Sjoerg   }
7077330f729Sjoerg   assert(VC.getKind() == Cl::CL_LValue && "Unhandled kind");
7087330f729Sjoerg   switch (VC.getModifiable()) {
7097330f729Sjoerg   case Cl::CM_Untested: llvm_unreachable("Did not test modifiability");
7107330f729Sjoerg   case Cl::CM_Modifiable: return MLV_Valid;
7117330f729Sjoerg   case Cl::CM_RValue: llvm_unreachable("CM_RValue and CL_LValue don't match");
7127330f729Sjoerg   case Cl::CM_Function: return MLV_NotObjectType;
7137330f729Sjoerg   case Cl::CM_LValueCast:
7147330f729Sjoerg     llvm_unreachable("CM_LValueCast and CL_LValue don't match");
7157330f729Sjoerg   case Cl::CM_NoSetterProperty: return MLV_NoSetterProperty;
7167330f729Sjoerg   case Cl::CM_ConstQualified: return MLV_ConstQualified;
7177330f729Sjoerg   case Cl::CM_ConstQualifiedField: return MLV_ConstQualifiedField;
7187330f729Sjoerg   case Cl::CM_ConstAddrSpace: return MLV_ConstAddrSpace;
7197330f729Sjoerg   case Cl::CM_ArrayType: return MLV_ArrayType;
7207330f729Sjoerg   case Cl::CM_IncompleteType: return MLV_IncompleteType;
7217330f729Sjoerg   }
7227330f729Sjoerg   llvm_unreachable("Unhandled modifiable type");
7237330f729Sjoerg }
724