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 370b57cec5SDimitry 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. 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 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 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: 148*0fca6ea1SDimitry Andric case Expr::ArraySectionExprClass: 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 207*0fca6ea1SDimitry Andric case Expr::EmbedExprClass: 208*0fca6ea1SDimitry Andric // Nominally, this just goes through as a PRValue until we actually expand 209*0fca6ea1SDimitry Andric // it and check it. 210*0fca6ea1SDimitry Andric return Cl::CL_PRValue; 211*0fca6ea1SDimitry Andric 212bdd1243dSDimitry Andric // Make HLSL this reference-like 213bdd1243dSDimitry Andric case Expr::CXXThisExprClass: 214bdd1243dSDimitry Andric return Lang.HLSL ? Cl::CL_LValue : Cl::CL_PRValue; 215bdd1243dSDimitry Andric 2160b57cec5SDimitry Andric case Expr::ConstantExprClass: 2170b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<ConstantExpr>(E)->getSubExpr()); 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric // Next come the complicated cases. 2200b57cec5SDimitry Andric case Expr::SubstNonTypeTemplateParmExprClass: 2210b57cec5SDimitry Andric return ClassifyInternal(Ctx, 2220b57cec5SDimitry Andric cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement()); 2230b57cec5SDimitry Andric 224*0fca6ea1SDimitry Andric case Expr::PackIndexingExprClass: { 225*0fca6ea1SDimitry Andric // A pack-index-expression always expands to an id-expression. 226*0fca6ea1SDimitry Andric // Consider it as an LValue expression. 227*0fca6ea1SDimitry Andric if (cast<PackIndexingExpr>(E)->isInstantiationDependent()) 228*0fca6ea1SDimitry Andric return Cl::CL_LValue; 229*0fca6ea1SDimitry Andric return ClassifyInternal(Ctx, cast<PackIndexingExpr>(E)->getSelectedExpr()); 230*0fca6ea1SDimitry Andric } 231*0fca6ea1SDimitry Andric 2320b57cec5SDimitry Andric // C, C++98 [expr.sub]p1: The result is an lvalue of type "T". 2330b57cec5SDimitry Andric // C++11 (DR1213): in the case of an array operand, the result is an lvalue 2340b57cec5SDimitry Andric // if that operand is an lvalue and an xvalue otherwise. 2350b57cec5SDimitry Andric // Subscripting vector types is more like member access. 2360b57cec5SDimitry Andric case Expr::ArraySubscriptExprClass: 2370b57cec5SDimitry Andric if (cast<ArraySubscriptExpr>(E)->getBase()->getType()->isVectorType()) 2380b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<ArraySubscriptExpr>(E)->getBase()); 2390b57cec5SDimitry Andric if (Lang.CPlusPlus11) { 2400b57cec5SDimitry Andric // Step over the array-to-pointer decay if present, but not over the 2410b57cec5SDimitry Andric // temporary materialization. 2420b57cec5SDimitry Andric auto *Base = cast<ArraySubscriptExpr>(E)->getBase()->IgnoreImpCasts(); 2430b57cec5SDimitry Andric if (Base->getType()->isArrayType()) 2440b57cec5SDimitry Andric return ClassifyInternal(Ctx, Base); 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric return Cl::CL_LValue; 2470b57cec5SDimitry Andric 2485ffd83dbSDimitry Andric // Subscripting matrix types behaves like member accesses. 2495ffd83dbSDimitry Andric case Expr::MatrixSubscriptExprClass: 2505ffd83dbSDimitry Andric return ClassifyInternal(Ctx, cast<MatrixSubscriptExpr>(E)->getBase()); 2515ffd83dbSDimitry Andric 2520b57cec5SDimitry Andric // C++ [expr.prim.general]p3: The result is an lvalue if the entity is a 2530b57cec5SDimitry Andric // function or variable and a prvalue otherwise. 2540b57cec5SDimitry Andric case Expr::DeclRefExprClass: 2550b57cec5SDimitry Andric if (E->getType() == Ctx.UnknownAnyTy) 2560b57cec5SDimitry Andric return isa<FunctionDecl>(cast<DeclRefExpr>(E)->getDecl()) 2570b57cec5SDimitry Andric ? Cl::CL_PRValue : Cl::CL_LValue; 2580b57cec5SDimitry Andric return ClassifyDecl(Ctx, cast<DeclRefExpr>(E)->getDecl()); 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric // Member access is complex. 2610b57cec5SDimitry Andric case Expr::MemberExprClass: 2620b57cec5SDimitry Andric return ClassifyMemberExpr(Ctx, cast<MemberExpr>(E)); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric case Expr::UnaryOperatorClass: 2650b57cec5SDimitry Andric switch (cast<UnaryOperator>(E)->getOpcode()) { 2660b57cec5SDimitry Andric // C++ [expr.unary.op]p1: The unary * operator performs indirection: 2670b57cec5SDimitry Andric // [...] the result is an lvalue referring to the object or function 2680b57cec5SDimitry Andric // to which the expression points. 2690b57cec5SDimitry Andric case UO_Deref: 2700b57cec5SDimitry Andric return Cl::CL_LValue; 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric // GNU extensions, simply look through them. 2730b57cec5SDimitry Andric case UO_Extension: 2740b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<UnaryOperator>(E)->getSubExpr()); 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric // Treat _Real and _Imag basically as if they were member 2770b57cec5SDimitry Andric // expressions: l-value only if the operand is a true l-value. 2780b57cec5SDimitry Andric case UO_Real: 2790b57cec5SDimitry Andric case UO_Imag: { 2800b57cec5SDimitry Andric const Expr *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens(); 2810b57cec5SDimitry Andric Cl::Kinds K = ClassifyInternal(Ctx, Op); 2820b57cec5SDimitry Andric if (K != Cl::CL_LValue) return K; 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric if (isa<ObjCPropertyRefExpr>(Op)) 2850b57cec5SDimitry Andric return Cl::CL_SubObjCPropertySetting; 2860b57cec5SDimitry Andric return Cl::CL_LValue; 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric // C++ [expr.pre.incr]p1: The result is the updated operand; it is an 2900b57cec5SDimitry Andric // lvalue, [...] 2910b57cec5SDimitry Andric // Not so in C. 2920b57cec5SDimitry Andric case UO_PreInc: 2930b57cec5SDimitry Andric case UO_PreDec: 2940b57cec5SDimitry Andric return Lang.CPlusPlus ? Cl::CL_LValue : Cl::CL_PRValue; 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric default: 2970b57cec5SDimitry Andric return Cl::CL_PRValue; 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric 3005ffd83dbSDimitry Andric case Expr::RecoveryExprClass: 3010b57cec5SDimitry Andric case Expr::OpaqueValueExprClass: 3020b57cec5SDimitry Andric return ClassifyExprValueKind(Lang, E, E->getValueKind()); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric // Pseudo-object expressions can produce l-values with reference magic. 3050b57cec5SDimitry Andric case Expr::PseudoObjectExprClass: 3060b57cec5SDimitry Andric return ClassifyExprValueKind(Lang, E, 3070b57cec5SDimitry Andric cast<PseudoObjectExpr>(E)->getValueKind()); 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric // Implicit casts are lvalues if they're lvalue casts. Other than that, we 3100b57cec5SDimitry Andric // only specifically record class temporaries. 3110b57cec5SDimitry Andric case Expr::ImplicitCastExprClass: 3120b57cec5SDimitry Andric return ClassifyExprValueKind(Lang, E, E->getValueKind()); 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric // C++ [expr.prim.general]p4: The presence of parentheses does not affect 3150b57cec5SDimitry Andric // whether the expression is an lvalue. 3160b57cec5SDimitry Andric case Expr::ParenExprClass: 3170b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<ParenExpr>(E)->getSubExpr()); 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric // C11 6.5.1.1p4: [A generic selection] is an lvalue, a function designator, 3200b57cec5SDimitry Andric // or a void expression if its result expression is, respectively, an 3210b57cec5SDimitry Andric // lvalue, a function designator, or a void expression. 3220b57cec5SDimitry Andric case Expr::GenericSelectionExprClass: 3230b57cec5SDimitry Andric if (cast<GenericSelectionExpr>(E)->isResultDependent()) 3240b57cec5SDimitry Andric return Cl::CL_PRValue; 3250b57cec5SDimitry Andric return ClassifyInternal(Ctx,cast<GenericSelectionExpr>(E)->getResultExpr()); 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric case Expr::BinaryOperatorClass: 3280b57cec5SDimitry Andric case Expr::CompoundAssignOperatorClass: 3290b57cec5SDimitry Andric // C doesn't have any binary expressions that are lvalues. 3300b57cec5SDimitry Andric if (Lang.CPlusPlus) 3310b57cec5SDimitry Andric return ClassifyBinaryOp(Ctx, cast<BinaryOperator>(E)); 3320b57cec5SDimitry Andric return Cl::CL_PRValue; 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric case Expr::CallExprClass: 3350b57cec5SDimitry Andric case Expr::CXXOperatorCallExprClass: 3360b57cec5SDimitry Andric case Expr::CXXMemberCallExprClass: 3370b57cec5SDimitry Andric case Expr::UserDefinedLiteralClass: 3380b57cec5SDimitry Andric case Expr::CUDAKernelCallExprClass: 3390b57cec5SDimitry Andric return ClassifyUnnamed(Ctx, cast<CallExpr>(E)->getCallReturnType(Ctx)); 3400b57cec5SDimitry Andric 341a7dea167SDimitry Andric case Expr::CXXRewrittenBinaryOperatorClass: 342a7dea167SDimitry Andric return ClassifyInternal( 343a7dea167SDimitry Andric Ctx, cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm()); 344a7dea167SDimitry Andric 3450b57cec5SDimitry Andric // __builtin_choose_expr is equivalent to the chosen expression. 3460b57cec5SDimitry Andric case Expr::ChooseExprClass: 3470b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<ChooseExpr>(E)->getChosenSubExpr()); 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric // Extended vector element access is an lvalue unless there are duplicates 3500b57cec5SDimitry Andric // in the shuffle expression. 3510b57cec5SDimitry Andric case Expr::ExtVectorElementExprClass: 3520b57cec5SDimitry Andric if (cast<ExtVectorElementExpr>(E)->containsDuplicateElements()) 3530b57cec5SDimitry Andric return Cl::CL_DuplicateVectorComponents; 3540b57cec5SDimitry Andric if (cast<ExtVectorElementExpr>(E)->isArrow()) 3550b57cec5SDimitry Andric return Cl::CL_LValue; 3560b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<ExtVectorElementExpr>(E)->getBase()); 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric // Simply look at the actual default argument. 3590b57cec5SDimitry Andric case Expr::CXXDefaultArgExprClass: 3600b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<CXXDefaultArgExpr>(E)->getExpr()); 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric // Same idea for default initializers. 3630b57cec5SDimitry Andric case Expr::CXXDefaultInitExprClass: 3640b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<CXXDefaultInitExpr>(E)->getExpr()); 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric // Same idea for temporary binding. 3670b57cec5SDimitry Andric case Expr::CXXBindTemporaryExprClass: 3680b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<CXXBindTemporaryExpr>(E)->getSubExpr()); 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric // And the cleanups guard. 3710b57cec5SDimitry Andric case Expr::ExprWithCleanupsClass: 3720b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<ExprWithCleanups>(E)->getSubExpr()); 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric // Casts depend completely on the target type. All casts work the same. 3750b57cec5SDimitry Andric case Expr::CStyleCastExprClass: 3760b57cec5SDimitry Andric case Expr::CXXFunctionalCastExprClass: 3770b57cec5SDimitry Andric case Expr::CXXStaticCastExprClass: 3780b57cec5SDimitry Andric case Expr::CXXDynamicCastExprClass: 3790b57cec5SDimitry Andric case Expr::CXXReinterpretCastExprClass: 3800b57cec5SDimitry Andric case Expr::CXXConstCastExprClass: 3815ffd83dbSDimitry Andric case Expr::CXXAddrspaceCastExprClass: 3820b57cec5SDimitry Andric case Expr::ObjCBridgedCastExprClass: 3830b57cec5SDimitry Andric case Expr::BuiltinBitCastExprClass: 3840b57cec5SDimitry Andric // Only in C++ can casts be interesting at all. 3850b57cec5SDimitry Andric if (!Lang.CPlusPlus) return Cl::CL_PRValue; 3860b57cec5SDimitry Andric return ClassifyUnnamed(Ctx, cast<ExplicitCastExpr>(E)->getTypeAsWritten()); 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric case Expr::CXXUnresolvedConstructExprClass: 3890b57cec5SDimitry Andric return ClassifyUnnamed(Ctx, 3900b57cec5SDimitry Andric cast<CXXUnresolvedConstructExpr>(E)->getTypeAsWritten()); 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric case Expr::BinaryConditionalOperatorClass: { 3930b57cec5SDimitry Andric if (!Lang.CPlusPlus) return Cl::CL_PRValue; 3940b57cec5SDimitry Andric const auto *co = cast<BinaryConditionalOperator>(E); 3950b57cec5SDimitry Andric return ClassifyConditional(Ctx, co->getTrueExpr(), co->getFalseExpr()); 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric case Expr::ConditionalOperatorClass: { 3990b57cec5SDimitry Andric // Once again, only C++ is interesting. 4000b57cec5SDimitry Andric if (!Lang.CPlusPlus) return Cl::CL_PRValue; 4010b57cec5SDimitry Andric const auto *co = cast<ConditionalOperator>(E); 4020b57cec5SDimitry Andric return ClassifyConditional(Ctx, co->getTrueExpr(), co->getFalseExpr()); 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric // ObjC message sends are effectively function calls, if the target function 4060b57cec5SDimitry Andric // is known. 4070b57cec5SDimitry Andric case Expr::ObjCMessageExprClass: 4080b57cec5SDimitry Andric if (const ObjCMethodDecl *Method = 4090b57cec5SDimitry Andric cast<ObjCMessageExpr>(E)->getMethodDecl()) { 4100b57cec5SDimitry Andric Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getReturnType()); 4110b57cec5SDimitry Andric return (kind == Cl::CL_PRValue) ? Cl::CL_ObjCMessageRValue : kind; 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric return Cl::CL_PRValue; 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric // Some C++ expressions are always class temporaries. 4160b57cec5SDimitry Andric case Expr::CXXConstructExprClass: 4170b57cec5SDimitry Andric case Expr::CXXInheritedCtorInitExprClass: 4180b57cec5SDimitry Andric case Expr::CXXTemporaryObjectExprClass: 4190b57cec5SDimitry Andric case Expr::LambdaExprClass: 4200b57cec5SDimitry Andric case Expr::CXXStdInitializerListExprClass: 4210b57cec5SDimitry Andric return Cl::CL_ClassTemporary; 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric case Expr::VAArgExprClass: 4240b57cec5SDimitry Andric return ClassifyUnnamed(Ctx, E->getType()); 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric case Expr::DesignatedInitExprClass: 4270b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<DesignatedInitExpr>(E)->getInit()); 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric case Expr::StmtExprClass: { 4300b57cec5SDimitry Andric const CompoundStmt *S = cast<StmtExpr>(E)->getSubStmt(); 4310b57cec5SDimitry Andric if (const auto *LastExpr = dyn_cast_or_null<Expr>(S->body_back())) 4320b57cec5SDimitry Andric return ClassifyUnnamed(Ctx, LastExpr->getType()); 4330b57cec5SDimitry Andric return Cl::CL_PRValue; 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric case Expr::PackExpansionExprClass: 4370b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<PackExpansionExpr>(E)->getPattern()); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric case Expr::MaterializeTemporaryExprClass: 4400b57cec5SDimitry Andric return cast<MaterializeTemporaryExpr>(E)->isBoundToLvalueReference() 4410b57cec5SDimitry Andric ? Cl::CL_LValue 4420b57cec5SDimitry Andric : Cl::CL_XValue; 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric case Expr::InitListExprClass: 4450b57cec5SDimitry Andric // An init list can be an lvalue if it is bound to a reference and 4460b57cec5SDimitry Andric // contains only one element. In that case, we look at that element 4470b57cec5SDimitry Andric // for an exact classification. Init list creation takes care of the 4480b57cec5SDimitry Andric // value kind for us, so we only need to fine-tune. 449fe6060f1SDimitry Andric if (E->isPRValue()) 4500b57cec5SDimitry Andric return ClassifyExprValueKind(Lang, E, E->getValueKind()); 4510b57cec5SDimitry Andric assert(cast<InitListExpr>(E)->getNumInits() == 1 && 4520b57cec5SDimitry Andric "Only 1-element init lists can be glvalues."); 4530b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<InitListExpr>(E)->getInit(0)); 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric case Expr::CoawaitExprClass: 4560b57cec5SDimitry Andric case Expr::CoyieldExprClass: 4570b57cec5SDimitry Andric return ClassifyInternal(Ctx, cast<CoroutineSuspendExpr>(E)->getResumeExpr()); 458fe6060f1SDimitry Andric case Expr::SYCLUniqueStableNameExprClass: 459fe6060f1SDimitry Andric return Cl::CL_PRValue; 460fe6060f1SDimitry Andric break; 461bdd1243dSDimitry Andric 462bdd1243dSDimitry Andric case Expr::CXXParenListInitExprClass: 463bdd1243dSDimitry Andric if (isa<ArrayType>(E->getType())) 464bdd1243dSDimitry Andric return Cl::CL_ArrayTemporary; 465bdd1243dSDimitry Andric return Cl::CL_ClassTemporary; 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric llvm_unreachable("unhandled expression kind in classification"); 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric /// ClassifyDecl - Return the classification of an expression referencing the 4720b57cec5SDimitry Andric /// given declaration. 4730b57cec5SDimitry Andric static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D) { 4740b57cec5SDimitry Andric // C++ [expr.prim.general]p6: The result is an lvalue if the entity is a 4750b57cec5SDimitry Andric // function, variable, or data member and a prvalue otherwise. 4760b57cec5SDimitry Andric // In C, functions are not lvalues. 4770b57cec5SDimitry Andric // In addition, NonTypeTemplateParmDecl derives from VarDecl but isn't an 4780b57cec5SDimitry Andric // lvalue unless it's a reference type (C++ [temp.param]p6), so we need to 4790b57cec5SDimitry Andric // special-case this. 4800b57cec5SDimitry Andric 4815f757f3fSDimitry Andric if (const auto *M = dyn_cast<CXXMethodDecl>(D)) { 4825f757f3fSDimitry Andric if (M->isImplicitObjectMemberFunction()) 4830b57cec5SDimitry Andric return Cl::CL_MemberFunction; 4845f757f3fSDimitry Andric if (M->isStatic()) 4855f757f3fSDimitry Andric return Cl::CL_LValue; 4865f757f3fSDimitry Andric return Cl::CL_PRValue; 4875f757f3fSDimitry Andric } 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric bool islvalue; 4900b57cec5SDimitry Andric if (const auto *NTTParm = dyn_cast<NonTypeTemplateParmDecl>(D)) 491e8d8bef9SDimitry Andric islvalue = NTTParm->getType()->isReferenceType() || 492e8d8bef9SDimitry Andric NTTParm->getType()->isRecordType(); 4930b57cec5SDimitry Andric else 49481ad6265SDimitry Andric islvalue = 49581ad6265SDimitry Andric isa<VarDecl, FieldDecl, IndirectFieldDecl, BindingDecl, MSGuidDecl, 49681ad6265SDimitry Andric UnnamedGlobalConstantDecl, TemplateParamObjectDecl>(D) || 4970b57cec5SDimitry Andric (Ctx.getLangOpts().CPlusPlus && 49881ad6265SDimitry Andric (isa<FunctionDecl, MSPropertyDecl, FunctionTemplateDecl>(D))); 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric return islvalue ? Cl::CL_LValue : Cl::CL_PRValue; 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric /// ClassifyUnnamed - Return the classification of an expression yielding an 5040b57cec5SDimitry Andric /// unnamed value of the given type. This applies in particular to function 5050b57cec5SDimitry Andric /// calls and casts. 5060b57cec5SDimitry Andric static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T) { 5070b57cec5SDimitry Andric // In C, function calls are always rvalues. 5080b57cec5SDimitry Andric if (!Ctx.getLangOpts().CPlusPlus) return Cl::CL_PRValue; 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric // C++ [expr.call]p10: A function call is an lvalue if the result type is an 5110b57cec5SDimitry Andric // lvalue reference type or an rvalue reference to function type, an xvalue 5120b57cec5SDimitry Andric // if the result type is an rvalue reference to object type, and a prvalue 5130b57cec5SDimitry Andric // otherwise. 5140b57cec5SDimitry Andric if (T->isLValueReferenceType()) 5150b57cec5SDimitry Andric return Cl::CL_LValue; 5160b57cec5SDimitry Andric const auto *RV = T->getAs<RValueReferenceType>(); 5170b57cec5SDimitry Andric if (!RV) // Could still be a class temporary, though. 5180b57cec5SDimitry Andric return ClassifyTemporary(T); 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric return RV->getPointeeType()->isFunctionType() ? Cl::CL_LValue : Cl::CL_XValue; 5210b57cec5SDimitry Andric } 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E) { 5240b57cec5SDimitry Andric if (E->getType() == Ctx.UnknownAnyTy) 5250b57cec5SDimitry Andric return (isa<FunctionDecl>(E->getMemberDecl()) 5260b57cec5SDimitry Andric ? Cl::CL_PRValue : Cl::CL_LValue); 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andric // Handle C first, it's easier. 5290b57cec5SDimitry Andric if (!Ctx.getLangOpts().CPlusPlus) { 5300b57cec5SDimitry Andric // C99 6.5.2.3p3 5310b57cec5SDimitry Andric // For dot access, the expression is an lvalue if the first part is. For 5320b57cec5SDimitry Andric // arrow access, it always is an lvalue. 5330b57cec5SDimitry Andric if (E->isArrow()) 5340b57cec5SDimitry Andric return Cl::CL_LValue; 5350b57cec5SDimitry Andric // ObjC property accesses are not lvalues, but get special treatment. 5360b57cec5SDimitry Andric Expr *Base = E->getBase()->IgnoreParens(); 5370b57cec5SDimitry Andric if (isa<ObjCPropertyRefExpr>(Base)) 5380b57cec5SDimitry Andric return Cl::CL_SubObjCPropertySetting; 5390b57cec5SDimitry Andric return ClassifyInternal(Ctx, Base); 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric NamedDecl *Member = E->getMemberDecl(); 5430b57cec5SDimitry Andric // C++ [expr.ref]p3: E1->E2 is converted to the equivalent form (*(E1)).E2. 5440b57cec5SDimitry Andric // C++ [expr.ref]p4: If E2 is declared to have type "reference to T", then 5450b57cec5SDimitry Andric // E1.E2 is an lvalue. 5460b57cec5SDimitry Andric if (const auto *Value = dyn_cast<ValueDecl>(Member)) 5470b57cec5SDimitry Andric if (Value->getType()->isReferenceType()) 5480b57cec5SDimitry Andric return Cl::CL_LValue; 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric // Otherwise, one of the following rules applies. 5510b57cec5SDimitry Andric // -- If E2 is a static member [...] then E1.E2 is an lvalue. 5520b57cec5SDimitry Andric if (isa<VarDecl>(Member) && Member->getDeclContext()->isRecord()) 5530b57cec5SDimitry Andric return Cl::CL_LValue; 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric // -- If E2 is a non-static data member [...]. If E1 is an lvalue, then 5560b57cec5SDimitry Andric // E1.E2 is an lvalue; if E1 is an xvalue, then E1.E2 is an xvalue; 5570b57cec5SDimitry Andric // otherwise, it is a prvalue. 5580b57cec5SDimitry Andric if (isa<FieldDecl>(Member)) { 5590b57cec5SDimitry Andric // *E1 is an lvalue 5600b57cec5SDimitry Andric if (E->isArrow()) 5610b57cec5SDimitry Andric return Cl::CL_LValue; 5620b57cec5SDimitry Andric Expr *Base = E->getBase()->IgnoreParenImpCasts(); 5630b57cec5SDimitry Andric if (isa<ObjCPropertyRefExpr>(Base)) 5640b57cec5SDimitry Andric return Cl::CL_SubObjCPropertySetting; 5650b57cec5SDimitry Andric return ClassifyInternal(Ctx, E->getBase()); 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric // -- If E2 is a [...] member function, [...] 5690b57cec5SDimitry Andric // -- If it refers to a static member function [...], then E1.E2 is an 5700b57cec5SDimitry Andric // lvalue; [...] 5710b57cec5SDimitry Andric // -- Otherwise [...] E1.E2 is a prvalue. 5725f757f3fSDimitry Andric if (const auto *Method = dyn_cast<CXXMethodDecl>(Member)) { 5735f757f3fSDimitry Andric if (Method->isStatic()) 5745f757f3fSDimitry Andric return Cl::CL_LValue; 5755f757f3fSDimitry Andric if (Method->isImplicitObjectMemberFunction()) 5765f757f3fSDimitry Andric return Cl::CL_MemberFunction; 5775f757f3fSDimitry Andric return Cl::CL_PRValue; 5785f757f3fSDimitry Andric } 5790b57cec5SDimitry Andric 5800b57cec5SDimitry Andric // -- If E2 is a member enumerator [...], the expression E1.E2 is a prvalue. 5810b57cec5SDimitry Andric // So is everything else we haven't handled yet. 5820b57cec5SDimitry Andric return Cl::CL_PRValue; 5830b57cec5SDimitry Andric } 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E) { 5860b57cec5SDimitry Andric assert(Ctx.getLangOpts().CPlusPlus && 5870b57cec5SDimitry Andric "This is only relevant for C++."); 5880b57cec5SDimitry Andric // C++ [expr.ass]p1: All [...] return an lvalue referring to the left operand. 5890b57cec5SDimitry Andric // Except we override this for writes to ObjC properties. 5900b57cec5SDimitry Andric if (E->isAssignmentOp()) 5910b57cec5SDimitry Andric return (E->getLHS()->getObjectKind() == OK_ObjCProperty 5920b57cec5SDimitry Andric ? Cl::CL_PRValue : Cl::CL_LValue); 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric // C++ [expr.comma]p1: the result is of the same value category as its right 5950b57cec5SDimitry Andric // operand, [...]. 5960b57cec5SDimitry Andric if (E->getOpcode() == BO_Comma) 5970b57cec5SDimitry Andric return ClassifyInternal(Ctx, E->getRHS()); 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric // C++ [expr.mptr.oper]p6: The result of a .* expression whose second operand 6000b57cec5SDimitry Andric // is a pointer to a data member is of the same value category as its first 6010b57cec5SDimitry Andric // operand. 6020b57cec5SDimitry Andric if (E->getOpcode() == BO_PtrMemD) 6030b57cec5SDimitry Andric return (E->getType()->isFunctionType() || 6040b57cec5SDimitry Andric E->hasPlaceholderType(BuiltinType::BoundMember)) 6050b57cec5SDimitry Andric ? Cl::CL_MemberFunction 6060b57cec5SDimitry Andric : ClassifyInternal(Ctx, E->getLHS()); 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric // C++ [expr.mptr.oper]p6: The result of an ->* expression is an lvalue if its 6090b57cec5SDimitry Andric // second operand is a pointer to data member and a prvalue otherwise. 6100b57cec5SDimitry Andric if (E->getOpcode() == BO_PtrMemI) 6110b57cec5SDimitry Andric return (E->getType()->isFunctionType() || 6120b57cec5SDimitry Andric E->hasPlaceholderType(BuiltinType::BoundMember)) 6130b57cec5SDimitry Andric ? Cl::CL_MemberFunction 6140b57cec5SDimitry Andric : Cl::CL_LValue; 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric // All other binary operations are prvalues. 6170b57cec5SDimitry Andric return Cl::CL_PRValue; 6180b57cec5SDimitry Andric } 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *True, 6210b57cec5SDimitry Andric const Expr *False) { 6220b57cec5SDimitry Andric assert(Ctx.getLangOpts().CPlusPlus && 6230b57cec5SDimitry Andric "This is only relevant for C++."); 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric // C++ [expr.cond]p2 6260b57cec5SDimitry Andric // If either the second or the third operand has type (cv) void, 6270b57cec5SDimitry Andric // one of the following shall hold: 6280b57cec5SDimitry Andric if (True->getType()->isVoidType() || False->getType()->isVoidType()) { 6290b57cec5SDimitry Andric // The second or the third operand (but not both) is a (possibly 6300b57cec5SDimitry Andric // parenthesized) throw-expression; the result is of the [...] value 6310b57cec5SDimitry Andric // category of the other. 6320b57cec5SDimitry Andric bool TrueIsThrow = isa<CXXThrowExpr>(True->IgnoreParenImpCasts()); 6330b57cec5SDimitry Andric bool FalseIsThrow = isa<CXXThrowExpr>(False->IgnoreParenImpCasts()); 6340b57cec5SDimitry Andric if (const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ? nullptr : False) 6350b57cec5SDimitry Andric : (FalseIsThrow ? True : nullptr)) 6360b57cec5SDimitry Andric return ClassifyInternal(Ctx, NonThrow); 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andric // [Otherwise] the result [...] is a prvalue. 6390b57cec5SDimitry Andric return Cl::CL_PRValue; 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric // Note that at this point, we have already performed all conversions 6430b57cec5SDimitry Andric // according to [expr.cond]p3. 6440b57cec5SDimitry Andric // C++ [expr.cond]p4: If the second and third operands are glvalues of the 6450b57cec5SDimitry Andric // same value category [...], the result is of that [...] value category. 6460b57cec5SDimitry Andric // C++ [expr.cond]p5: Otherwise, the result is a prvalue. 6470b57cec5SDimitry Andric Cl::Kinds LCl = ClassifyInternal(Ctx, True), 6480b57cec5SDimitry Andric RCl = ClassifyInternal(Ctx, False); 6490b57cec5SDimitry Andric return LCl == RCl ? LCl : Cl::CL_PRValue; 6500b57cec5SDimitry Andric } 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E, 6530b57cec5SDimitry Andric Cl::Kinds Kind, SourceLocation &Loc) { 6540b57cec5SDimitry Andric // As a general rule, we only care about lvalues. But there are some rvalues 6550b57cec5SDimitry Andric // for which we want to generate special results. 6560b57cec5SDimitry Andric if (Kind == Cl::CL_PRValue) { 6570b57cec5SDimitry Andric // For the sake of better diagnostics, we want to specifically recognize 6580b57cec5SDimitry Andric // use of the GCC cast-as-lvalue extension. 6590b57cec5SDimitry Andric if (const auto *CE = dyn_cast<ExplicitCastExpr>(E->IgnoreParens())) { 6600b57cec5SDimitry Andric if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) { 6610b57cec5SDimitry Andric Loc = CE->getExprLoc(); 6620b57cec5SDimitry Andric return Cl::CM_LValueCast; 6630b57cec5SDimitry Andric } 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric } 6660b57cec5SDimitry Andric if (Kind != Cl::CL_LValue) 6670b57cec5SDimitry Andric return Cl::CM_RValue; 6680b57cec5SDimitry Andric 6690b57cec5SDimitry Andric // This is the lvalue case. 6700b57cec5SDimitry Andric // Functions are lvalues in C++, but not modifiable. (C++ [basic.lval]p6) 6710b57cec5SDimitry Andric if (Ctx.getLangOpts().CPlusPlus && E->getType()->isFunctionType()) 6720b57cec5SDimitry Andric return Cl::CM_Function; 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric // Assignment to a property in ObjC is an implicit setter access. But a 6750b57cec5SDimitry Andric // setter might not exist. 6760b57cec5SDimitry Andric if (const auto *Expr = dyn_cast<ObjCPropertyRefExpr>(E)) { 6770b57cec5SDimitry Andric if (Expr->isImplicitProperty() && 6780b57cec5SDimitry Andric Expr->getImplicitPropertySetter() == nullptr) 6790b57cec5SDimitry Andric return Cl::CM_NoSetterProperty; 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric CanQualType CT = Ctx.getCanonicalType(E->getType()); 6830b57cec5SDimitry Andric // Const stuff is obviously not modifiable. 6840b57cec5SDimitry Andric if (CT.isConstQualified()) 6850b57cec5SDimitry Andric return Cl::CM_ConstQualified; 6860b57cec5SDimitry Andric if (Ctx.getLangOpts().OpenCL && 6870b57cec5SDimitry Andric CT.getQualifiers().getAddressSpace() == LangAS::opencl_constant) 6880b57cec5SDimitry Andric return Cl::CM_ConstAddrSpace; 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric // Arrays are not modifiable, only their elements are. 6910b57cec5SDimitry Andric if (CT->isArrayType()) 6920b57cec5SDimitry Andric return Cl::CM_ArrayType; 6930b57cec5SDimitry Andric // Incomplete types are not modifiable. 6940b57cec5SDimitry Andric if (CT->isIncompleteType()) 6950b57cec5SDimitry Andric return Cl::CM_IncompleteType; 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric // Records with any const fields (recursively) are not modifiable. 6980b57cec5SDimitry Andric if (const RecordType *R = CT->getAs<RecordType>()) 6990b57cec5SDimitry Andric if (R->hasConstFields()) 7000b57cec5SDimitry Andric return Cl::CM_ConstQualifiedField; 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric return Cl::CM_Modifiable; 7030b57cec5SDimitry Andric } 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andric Expr::LValueClassification Expr::ClassifyLValue(ASTContext &Ctx) const { 7060b57cec5SDimitry Andric Classification VC = Classify(Ctx); 7070b57cec5SDimitry Andric switch (VC.getKind()) { 7080b57cec5SDimitry Andric case Cl::CL_LValue: return LV_Valid; 7090b57cec5SDimitry Andric case Cl::CL_XValue: return LV_InvalidExpression; 7100b57cec5SDimitry Andric case Cl::CL_Function: return LV_NotObjectType; 7110b57cec5SDimitry Andric case Cl::CL_Void: return LV_InvalidExpression; 7120b57cec5SDimitry Andric case Cl::CL_AddressableVoid: return LV_IncompleteVoidType; 7130b57cec5SDimitry Andric case Cl::CL_DuplicateVectorComponents: return LV_DuplicateVectorComponents; 7140b57cec5SDimitry Andric case Cl::CL_MemberFunction: return LV_MemberFunction; 7150b57cec5SDimitry Andric case Cl::CL_SubObjCPropertySetting: return LV_SubObjCPropertySetting; 7160b57cec5SDimitry Andric case Cl::CL_ClassTemporary: return LV_ClassTemporary; 7170b57cec5SDimitry Andric case Cl::CL_ArrayTemporary: return LV_ArrayTemporary; 7180b57cec5SDimitry Andric case Cl::CL_ObjCMessageRValue: return LV_InvalidMessageExpression; 7190b57cec5SDimitry Andric case Cl::CL_PRValue: return LV_InvalidExpression; 7200b57cec5SDimitry Andric } 7210b57cec5SDimitry Andric llvm_unreachable("Unhandled kind"); 7220b57cec5SDimitry Andric } 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric Expr::isModifiableLvalueResult 7250b57cec5SDimitry Andric Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const { 7260b57cec5SDimitry Andric SourceLocation dummy; 7270b57cec5SDimitry Andric Classification VC = ClassifyModifiable(Ctx, Loc ? *Loc : dummy); 7280b57cec5SDimitry Andric switch (VC.getKind()) { 7290b57cec5SDimitry Andric case Cl::CL_LValue: break; 7300b57cec5SDimitry Andric case Cl::CL_XValue: return MLV_InvalidExpression; 7310b57cec5SDimitry Andric case Cl::CL_Function: return MLV_NotObjectType; 7320b57cec5SDimitry Andric case Cl::CL_Void: return MLV_InvalidExpression; 7330b57cec5SDimitry Andric case Cl::CL_AddressableVoid: return MLV_IncompleteVoidType; 7340b57cec5SDimitry Andric case Cl::CL_DuplicateVectorComponents: return MLV_DuplicateVectorComponents; 7350b57cec5SDimitry Andric case Cl::CL_MemberFunction: return MLV_MemberFunction; 7360b57cec5SDimitry Andric case Cl::CL_SubObjCPropertySetting: return MLV_SubObjCPropertySetting; 7370b57cec5SDimitry Andric case Cl::CL_ClassTemporary: return MLV_ClassTemporary; 7380b57cec5SDimitry Andric case Cl::CL_ArrayTemporary: return MLV_ArrayTemporary; 7390b57cec5SDimitry Andric case Cl::CL_ObjCMessageRValue: return MLV_InvalidMessageExpression; 7400b57cec5SDimitry Andric case Cl::CL_PRValue: 7410b57cec5SDimitry Andric return VC.getModifiable() == Cl::CM_LValueCast ? 7420b57cec5SDimitry Andric MLV_LValueCast : MLV_InvalidExpression; 7430b57cec5SDimitry Andric } 7440b57cec5SDimitry Andric assert(VC.getKind() == Cl::CL_LValue && "Unhandled kind"); 7450b57cec5SDimitry Andric switch (VC.getModifiable()) { 7460b57cec5SDimitry Andric case Cl::CM_Untested: llvm_unreachable("Did not test modifiability"); 7470b57cec5SDimitry Andric case Cl::CM_Modifiable: return MLV_Valid; 7480b57cec5SDimitry Andric case Cl::CM_RValue: llvm_unreachable("CM_RValue and CL_LValue don't match"); 7490b57cec5SDimitry Andric case Cl::CM_Function: return MLV_NotObjectType; 7500b57cec5SDimitry Andric case Cl::CM_LValueCast: 7510b57cec5SDimitry Andric llvm_unreachable("CM_LValueCast and CL_LValue don't match"); 7520b57cec5SDimitry Andric case Cl::CM_NoSetterProperty: return MLV_NoSetterProperty; 7530b57cec5SDimitry Andric case Cl::CM_ConstQualified: return MLV_ConstQualified; 7540b57cec5SDimitry Andric case Cl::CM_ConstQualifiedField: return MLV_ConstQualifiedField; 7550b57cec5SDimitry Andric case Cl::CM_ConstAddrSpace: return MLV_ConstAddrSpace; 7560b57cec5SDimitry Andric case Cl::CM_ArrayType: return MLV_ArrayType; 7570b57cec5SDimitry Andric case Cl::CM_IncompleteType: return MLV_IncompleteType; 7580b57cec5SDimitry Andric } 7590b57cec5SDimitry Andric llvm_unreachable("Unhandled modifiable type"); 7600b57cec5SDimitry Andric } 761